[
  {
    "path": ".babelrc",
    "content": "{\n  \"presets\": [\n    [\n      \"@babel/preset-env\",\n      {\n        \"modules\": false\n      }\n    ]\n  ],\n  \"env\": {\n    \"test\": {\n      \"plugins\": [\n        \"istanbul\"\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_size = 2\nindent_style = space\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n"
  },
  {
    "path": ".eslintrc",
    "content": "{\n  \"extends\": \"airbnb-base\",\n  \"env\": {\n    \"browser\": true\n  },\n  \"root\": true,\n  \"rules\": {\n    \"no-param-reassign\": \"off\",\n    \"no-restricted-properties\": \"off\",\n    \"valid-jsdoc\": [\"error\", {\n      \"requireReturn\": false\n    }]\n  }\n}\n"
  },
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "content": "# Contributor Code of Conduct\n\nAs contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.\n\nWe are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.\n\nExamples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.\n\nProject maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.\n\nThis Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at https://www.contributor-covenant.org/version/1/0/0/code-of-conduct.html\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# Contributing to Picker.js\n\n> Based on [Angular's contributing guidelines](https://github.com/angular/angular/blob/master/CONTRIBUTING.md).\n\nWe would love for you to contribute to Picker.js and help make it even better than it is today! As a contributor, here are the guidelines we would like you to follow:\n\n- [Code of Conduct](#code-of-conduct)\n- [Question or Problem](#question-or-problem)\n- [Issues and Bugs](#issues-and-bugs)\n- [Feature Requests](#feature-requests)\n- [Submission Guidelines](#submission-guidelines)\n- [Coding Rules](#coding-rules)\n- [Commit Message Guidelines](#commit-message-guidelines)\n\n## Code of Conduct\n\nHelp us keep Picker.js open and inclusive. Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md).\n\n## Question or Problem\n\nDo not open issues for general support questions as we want to keep GitHub issues for bug reports and feature requests. You've got much better chances of getting your question answered on [Stack Overflow](https://stackoverflow.com/questions/tagged/pickerjs) where the questions should be tagged with tag `pickerjs`.\n\nStack Overflow is a much better place to ask questions since:\n\n- There are thousands of people willing to help on Stack Overflow.\n- Questions and answers stay available for public viewing so your question / answer might help someone else.\n- Stack Overflow's voting system assures that the best answers are prominently visible.\n\nTo save your and our time, we will systematically close all issues that are requests for general support and redirect people to Stack Overflow.\n\n## Issues and Bugs\n\nIf you find a bug in the source code, you can help us by [submitting an issue](#submitting-an-issue) to our [GitHub Repository](https://github.com/fengyuanchen/pickerjs). Even better, you can [submit a Pull Request](#submitting-a-pull-request-pr) with a fix.\n\n## Feature Requests\n\nYou can *request* a new feature by [submitting an issue](#submitting-an-issue) to our [GitHub Repository](https://github.com/fengyuanchen/pickerjs). If you would like to *implement* a new feature, please submit an issue with a proposal for your work first, to be sure that we can use it.\n\nPlease consider what kind of change it is:\n\n- For a **Major Feature**, first open an issue and outline your proposal so that it can be discussed. This will also allow us to better coordinate our efforts, prevent duplication of work, and help you to craft the change so that it is successfully accepted into the project.\n- **Small Features** can be crafted and directly [submitted as a Pull Request](#submitting-a-pull-request-pr).\n\n## Submission Guidelines\n\n### Submitting an Issue\n\nBefore you submit an issue, please search the [issue tracker](https://github.com/fengyuanchen/pickerjs/issues), maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available.\n\nWe want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it. In order to reproduce bugs we will systematically ask you to provide a minimal reproduction scenario using [CodePen](https://codepen.io/pen). Having a live, reproducible scenario gives us wealth of important information without going back & forth to you with additional questions like:\n\n- version of Picker.js used\n- 3rd-party libraries and their versions\n- and most importantly - a use-case that fails\n\nA minimal reproduce scenario using [CodePen](https://codepen.io/pen) allows us to quickly confirm a bug (or point out coding problem) as well as confirm that we are fixing the right problem. If [CodePen](https://codepen.io/pen) is not a suitable way to demonstrate the problem (for example for issues related to our npm packaging), please create a standalone git repository demonstrating the problem.\n\nWe will be insisting on a minimal reproduce scenario in order to save maintainers time and ultimately be able to fix more bugs. Interestingly, from our experience users often find coding problems themselves while preparing a minimal reproduce scenario. We understand that sometimes it might be hard to extract essentials bits of code from a larger code-base but we really need to isolate the problem before we can fix it.\n\nUnfortunately we are not able to investigate / fix bugs without a minimal reproduce scenario, so if we don't hear back from you we are going to close an issue that don't have enough info to be reproduced.\n\nYou can file new issues by filling out our [new issue form](https://github.com/fengyuanchen/pickerjs/issues/new).\n\n### Submitting a Pull Request (PR)\n\nBefore you submit your Pull Request (PR) consider the following guidelines:\n\n1. Search [GitHub](https://github.com/fengyuanchen/pickerjs/pulls) for an open or closed PR that relates to your submission. You don't want to duplicate effort.\n1. Fork the **fengyuanchen/pickerjs** repo.\n1. Make your changes in a new git branch:\n\n    ```shell\n    git checkout -b my-fix-branch master\n    ```\n\n1. Create your patch, **including appropriate test cases**.\n1. Follow our [Coding Rules](#coding-rules).\n1. Run the full Picker.js test suite, and ensure that all tests pass.\n1. Commit your changes using a descriptive commit message that follows our [Commit Message Guidelines](#commit-message-guidelines). Adherence to these guidelines is necessary because release notes are automatically generated from these messages.\n\n    ```shell\n    git commit -a\n    ```\n\n    Note: the optional commit `-a` command line option will automatically \"add\" and \"rm\" edited files.\n1. Push your branch to GitHub:\n\n    ```shell\n    git push origin my-fix-branch\n    ```\n\n1. In GitHub, send a pull request to `pickerjs:master`.\n1. If we suggest changes then:\n    - Make the required updates.\n    - Re-run the Picker.js test suites to ensure tests are still passing.\n    - Rebase your branch and force push to your GitHub repository (this will update your Pull Request):\n\n    ```shell\n    git rebase master -i\n    git push -f\n    ```\n\nThat's it! Thank you for your contribution!\n\n#### After your pull request is merged\n\nAfter your pull request is merged, you can safely delete your branch and pull the changes from the main (upstream) repository:\n\n1. Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:\n\n    ```shell\n    git push origin --delete my-fix-branch\n    ```\n\n1. Check out the master branch:\n\n    ```shell\n    git checkout master -f\n    ```\n\n1. Delete the local branch:\n\n    ```shell\n    git branch -D my-fix-branch\n    ```\n\n1. Update your master with the latest upstream version:\n\n    ```shell\n    git pull --ff upstream master\n    ```\n\n## Coding Rules\n\nTo ensure consistency throughout the source code, keep these rules in mind as you are working:\n\n- All features or bug fixes **must be tested** by one or more specs (unit-tests).\n- All public API methods **must be documented**.\n- We follow [Airbnb's JavaScript Style Guide](https://github.com/airbnb/javascript).\n\n## Commit Message Guidelines\n\n### Commit Message Format\n\nA commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:\n\n```\n<type>(<scope>): <subject>\n<BLANK LINE>\n<body>\n<BLANK LINE>\n<footer>\n```\n\nThe **header** is mandatory and the **scope** of the header is optional.\n\nAny line of the commit message cannot be longer 100 characters! This allows the message to be easier to read on GitHub as well as in various git tools.\n\nThe footer should contain a [closing reference to an issue](https://help.github.com/articles/closing-issues-via-commit-messages/) if any.\n\nHere are some [samples](https://github.com/fengyuanchen/pickerjs/commits/master).\n\n### Revert\n\nIf the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.\n\n### Type\n\nMust be one of the following:\n\n- **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)\n- **ci**: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)\n- **docs**: Documentation only changes\n- **feat**: A new feature\n- **fix**: A bug fix\n- **perf**: A code change that improves performance\n- **refactor**: A code change that neither fixes a bug nor adds a feature\n- **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)\n- **test**: Adding missing tests or correcting existing tests\n\n### Scope\n\nThe scope could be anything specifying place of the commit change. For example `move`, `zoom`, `rotate`, etc...\n\n### Subject\n\nThe subject contains succinct description of the change:\n\n- Use the imperative, present tense: \"change\" not \"changed\" nor \"changes\".\n- Don't capitalize first letter.\n- No dot (.) at the end.\n\n### Body\n\nJust as in the **subject**, use the imperative, present tense: \"change\" not \"changed\" nor \"changes\". The body should include the motivation for the change and contrast this with previous behavior.\n\n### Footer\n\nThe footer should contain any information about **Breaking Changes** and is also the place to reference GitHub issues that this commit **Closes**.\n\n**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n4. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Desktop (please complete the following information):**\n - OS: [e.g. iOS]\n - Browser [e.g. chrome, safari]\n - Version [e.g. 22]\n\n**Smartphone (please complete the following information):**\n - Device: [e.g. iPhone6]\n - OS: [e.g. iOS8.1]\n - Browser [e.g. stock browser, safari]\n - Version [e.g. 22]\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "<!--\nPLEASE HELP US PROCESS GITHUB ISSUES FASTER BY PROVIDING THE FOLLOWING INFORMATION.\n\nISSUES MISSING IMPORTANT INFORMATION MAY BE CLOSED WITHOUT INVESTIGATION.\n-->\n\n## I'm submitting a...\n\n<!-- Check one of the following options with \"x\" -->\n\n<pre><code>\n[ ] Regression (a behavior that used to work and stopped working in a new release)\n[ ] Bug report <!-- Please search GitHub for a similar issue or PR before submitting -->\n[ ] Feature request\n[ ] Documentation issue or request\n</code></pre>\n\n\n## Current behavior\n\n<!-- Describe how the issue manifests. -->\n\n\n## Expected behavior\n\n<!-- Describe what the desired behavior would be. -->\n\n\n## Minimal reproduction of the problem with instructions\n\n<!--\nFor bug reports please provide the *STEPS TO REPRODUCE* and if possible a *MINIMAL DEMO* of the problem via\nhttps://codepen.io/pen or similar.\n-->\n\n\n## What is the motivation / use case for changing the behavior?\n\n<!-- Describe the motivation or the concrete use case. -->\n\n\n## Environment\n\n<pre><code>\nPicker.js version: X.Y.Z\n<!-- Check whether this is still an issue in the most recent Picker.js version -->\n\nBrowser:\n- [ ] Chrome (desktop) version XX\n- [ ] Chrome (Android) version XX\n- [ ] Chrome (iOS) version XX\n- [ ] Firefox version XX\n- [ ] Safari (desktop) version XX\n- [ ] Safari (iOS) version XX\n- [ ] IE version XX\n- [ ] Edge version XX\n\nOthers:\n<!-- Anything else relevant? -->\n</code></pre>\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "## PR Checklist\n\nPlease check if your PR fulfills the following requirements:\n\n- [ ] The commit message follows our [guidelines](https://github.com/fengyuanchen/pickerjs/blob/master/.github/CONTRIBUTING.md#commit-message-guidelines).\n- [ ] Tests for the changes have been added (for bug fixes / features)\n- [ ] Docs have been added / updated (for bug fixes / features)\n\n\n## PR Type\n\nWhat kind of change does this PR introduce?\n\n<!-- Please check the one that applies to this PR using \"x\". -->\n\n```\n[ ] Bugfix\n[ ] Feature\n[ ] Code style update\n[ ] Refactor\n[ ] Build related changes\n[ ] Documentation content changes\n[ ] Other, Please describe:\n```\n\n\n## What is the current behavior?\n\n<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->\n\nIssue Number: N/A\n\n\n## What is the new behavior?\n\n\n## Does this PR introduce a breaking change?\n\n```\n[ ] Yes\n[ ] No\n```\n\n<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->\n\n\n## Other information\n"
  },
  {
    "path": ".gitignore",
    "content": "*.map\ncoverage\nnode_modules\n"
  },
  {
    "path": ".stylelintrc",
    "content": "{\n  \"extends\": \"stylelint-config-standard\",\n  \"plugins\": [\n    \"stylelint-order\"\n  ],\n  \"rules\": {\n    \"no-descending-specificity\": null,\n    \"order/properties-alphabetical-order\": true\n  }\n}\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js: node\ncache: npm\nscript:\n  - npm run lint\n  - npm run build\n  - npm test\nafter_success:\n  - npm run codecov\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\n## 1.2.1 (Feb 18, 2019)\n\n- Remove duplicate tokens (#22).\n- Use the latest date to calculate the max day (#23).\n\n## 1.2.0 (Dec 16, 2018)\n\n- Add the `controls` option.\n- Enhance the `text` option for defining the text content of the column headers.\n\n## 1.1.0 (Dec 15, 2018)\n\n- Add the `headers` option for customizing the column headers (#20).\n\n## 1.0.0 (Oct 25, 2018)\n\n- Fix wrong BC year detecting when the date string has a `-` before year digits (#17).\n\n## 1.0.0-rc (Oct 23, 2018)\n\n- Add polish localization (#13).\n- Fix wrong maximum day when month change (#15, #16).\n\n## 1.0.0-beta (Jun 18, 2018)\n\n- Refactor the core code.\n- Refactor the test code.\n- Add type definitions file for TypeScript.\n- Fix page scrolling issue in iOS browsers (#9).\n\n## 0.2.0 (Feb 11, 2018)\n\n- Enhance the `format` option to support no separator mode as `YYYYMMDD` (#7).\n\n## 0.1.2 (Mar 11, 2017)\n\n- Improved event handler for Pointer Events (#3).\n\n## 0.1.1 (Oct 22, 2016)\n\n- Fixed the issue of increment and decrement (#1).\n\n## 0.1.0 (Jul 16, 2016)\n\n- Supports 16 options: `container`, `date`, `format`, `increment`, `inline`, `language`, `months`, `monthsShort`, `translate`, `rows`, `text`, `show`, `shown`, `hide`, `hidden` and `pick`.\n- Supports 12 methods: `show`, `hide`, `prev`, `next`, `pick`, `getDate`, `setDate`, `update`, `reset`, `parseDate`, `formatDate` and `destroy`.\n- Supports 5 events: `show`, `shown`, `hide`, `hidden` and `pick`.\n\n## 0.0.1 (Jun 1, 2016)\n\n- Init.\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright 2016-present Chen Fengyuan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Picker.js\n\n[![Build Status](https://img.shields.io/travis/fengyuanchen/pickerjs.svg)](https://travis-ci.org/fengyuanchen/pickerjs) [![Coverage Status](https://img.shields.io/codecov/c/github/fengyuanchen/pickerjs.svg)](https://codecov.io/gh/fengyuanchen/pickerjs) [![Downloads](https://img.shields.io/npm/dm/pickerjs.svg)](https://www.npmjs.com/package/pickerjs) [![Version](https://img.shields.io/npm/v/pickerjs.svg)](https://www.npmjs.com/package/pickerjs)\n\n> JavaScript date time picker.\n\n- [Website](https://fengyuanchen.github.io/pickerjs)\n\n## Table of contents\n\n- [Main](#main)\n- [Getting started](#getting-started)\n- [Options](#options)\n- [Methods](#methods)\n- [Events](#events)\n- [No conflict](#no-conflict)\n- [Browser support](#browser-support)\n- [Versioning](#versioning)\n- [License](#license)\n\n## Main\n\n```text\ndist/\n├── picker.css\n├── picker.min.css   (compressed)\n├── picker.js        (UMD)\n├── picker.min.js    (UMD, compressed)\n├── picker.common.js (CommonJS, default)\n└── picker.esm.js    (ES Module)\n```\n\n## Getting started\n\n### Installation\n\n```shell\nnpm install pickerjs\n```\n\nInclude files:\n\n```html\n<link  href=\"/path/to/picker.css\" rel=\"stylesheet\">\n<script src=\"/path/to/picker.js\"></script>\n```\n\n### Usage\n\n#### Syntax\n\n```js\nnew Picker(element[, options])\n```\n\n- **element**\n  - Type: `HTMLElement`\n  - The target element for picking.\n\n- **options** (optional)\n  - Type: `Object`\n  - The options for picking. Check out the available [options](#options).\n\n#### Example\n\n```html\n<input type=\"text\" id=\"input\">\n```\n\n```js\nvar input = document.getElementById('input');\nvar picker = new Picker(input, {\n  format: 'YYYY/MM/DD HH:mm',\n});\n```\n\n[⬆ Back to top](#table-of-contents)\n\n## Options\n\nYou may set picker options with `new Picker(element, options)`.\nIf you want to change the global default options, You may use `Picker.setDefaults(options)`.\n\n### container\n\n- Type: `Element` or `Selector`\n- Default: `null`\n\nDefine the container for putting the picker. If not present, the picker will be appended to the `document.body`.\n\n```js\nnew Picker(element, {\n  container: document.querySelector('.picker-container'),\n});\n```\n\nOr\n\n```js\nnew Picker(element, {\n  container: '.picker-container',\n});\n```\n\n### controls\n\n- Type: `Boolean`\n- Default: `false`\n\nIndicate whether show the prev and next arrow controls on each column.\n\n### date\n\n- Type: `Date` or `String`\n- Default: `null`\n\nThe initial date. If not present, use the current date.\n\n```js\nnew Picker(element, {\n  date: new Date(2048, 9, 24, 5, 12),\n});\n```\n\nOr\n\n```js\nnew Picker(element, {\n  date: '2048-10-24 05:12',\n});\n```\n\n### format\n\n- Type: `String`\n- Default: `'YYYY-MM-DD HH:mm'`\n- Tokens:\n  - `YYYY`: 4 digits year with leading zero\n  - `YYY`: 3 digits year with leading zero\n  - `YY`: 2 digits year with leading zero and be converted to a year near 2000\n  - `Y`: Years with any number of digits and sign\n  - `MMMM`: Month name\n  - `MMM`: Short month name\n  - `MM`: Month number with leading zero\n  - `M`: Month number\n  - `DD`: Day of month with leading zero\n  - `D`: Day of month\n  - `HH`: Hours with leading zero\n  - `H`: Hours\n  - `mm`: Minutes with leading zero\n  - `m`: Minutes\n  - `ss`: Seconds with leading zero\n  - `s`: Seconds\n  - `SSS`: Milliseconds with leading zero\n  - `SS`: Milliseconds with leading zero\n  - `S`: Milliseconds\n\nThe date string format, also as the sorting order of date time columns.\n\n```js\nnew Picker(element, {\n  date: '2048-10-24 05:12:02.056',\n  format: 'YYYY-MM-DD HH:mm:ss.SSS',\n});\n```\n\nOr\n\n```js\nnew Picker(element, {\n  date: 'Oct 24, 2048',\n  format: 'MMM D, YYYY',\n});\n```\n\n### headers\n\n- Type: `Boolean`\n- Default: `false`\n\nIndicate whether show the column headers. The text content of each header is defined in the `text` option.\n\n### increment\n\n- Type: `Number` or `Object`\n- Default: `1`\n\nDefine the increment for each date time part.\n\n```js\nnew Picker(element, {\n  increment: 10,\n});\n```\n\nOr\n\n```js\nnew Picker(element, {\n  increment: {\n    year: 1,\n    month: 1,\n    day: 1,\n    hour: 1,\n    minute: 10,\n    second: 10,\n    millisecond: 100,\n  },\n});\n```\n\n### inline\n\n- Type: `Boolean`\n- Default: `false`\n\nEnable inline mode.\n\n### language\n\n- Type: `String` (ISO language code)\n- Default: `''`\n\nDefine the language.\n\n> You should define the language first. Check out the [i18n](i18n) folder for more information.\n\n### months\n\n- Type: `Array`\n- Default: `['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']`\n\nMonths' name.\n\n### monthsShort\n\n- Type: `Array`\n- Default: `['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']`\n\nShort months' name.\n\n### rows\n\n- Type: `Number`\n- Default: `5`\n\nDefine the number of rows for showing.\n\n### text\n\n- Type: `Object`\n- Default:\n\n  ```js\n  {\n    title: 'Pick a date and time',\n    cancel: 'Cancel',\n    confirm: 'OK',\n    year: 'Year',\n    month: 'Month',\n    day: 'Day',\n    hour: 'Hour',\n    minute: 'Minute',\n    second: 'Second',\n    millisecond: 'Millisecond',\n  }\n  ```\n\nDefine the title and button text of the picker.\n\n### translate\n\n- Type: `Function`\n- Default:\n\n  ```js\n  function (type, text) {\n    return text;\n  }\n  ```\n\nTranslate date time text.\n\n```js\nnew Picker(element, {\n  translate(type, text) {\n    const aliases = ['〇', '一', '二', '三', '四', '五', '六', '七', '八', '九'];\n\n    return String(text).split('').map((n) => aliases[Number(n)]).join('');\n  },\n});\n```\n\n### show\n\n- Type: `Function`\n- Default: `null`\n\nThe shortcut of the `show` event.\n\n### shown\n\n- Type: `Function`\n- Default: `null`\n\nThe shortcut of the `shown` event.\n\n### hide\n\n- Type: `Function`\n- Default: `null`\n\nThe shortcut of the `hide` event.\n\n### hidden\n\n- Type: `Function`\n- Default: `null`\n\nThe shortcut of the `hidden` event.\n\n### pick\n\n- Type: `Function`\n- Default: `null`\n\nThe shortcut of the `pick` event.\n\n[⬆ Back to top](#table-of-contents)\n\n## Methods\n\nIf a method doesn't need to return any value, it will return the picker instance (`this`) for chain composition.\n\n### show()\n\nShow the picker.\n\n### hide()\n\nHide the picker.\n\n### prev(type)\n\n- **type**:\n  - Type: `String`\n  - Options: `'year'`, `'month'`, `'day'`, `'hour'`, `'minute'`, `'second'`, `'millisecond'`\n  - Date time type.\n\nPick the previous item.\n\n### next(type)\n\n- **type**: (the same as the `prev` method)\n\nPick the next item.\n\n### pick()\n\nPick the current date to the target element.\n\n### getDate([formatted])\n\n- **formatted** (optional):\n  - Type: `Boolean`\n  - Format the date.\n- (return value):\n  - Type: `Date` or `String`\n\nGet the current date.\n\n```js\nconst picker = new Picker(element, {\n  date: new Date(2048, 9, 24, 5, 12),\n});\n\npicker.getDate();\n// > Sat Oct 24 2048 05:12:00 GMT+0800 (China Standard Time)\n\npicker.getDate(true);\n// > 2048-10-24 05:12\n```\n\n### setDate(date)\n\n- **date**:\n  - Type: `Date`\n  - The new date.\n\nOverride the current date with a new date.\n\n### update()\n\nUpdate the picker with the current the element value / text.\n\n### reset()\n\nReset the picker and the element value / text.\n\n### parseDate(date)\n\n- **date**:\n  - Type: `String`\n- (return value):\n  - Type: `Date`\n\nParse a date string with the set date format.\n\n```js\nconst picker = new Picker(element, options);\n\npicker.parseDate('2048-10-24 05:12');\n// > Sat Oct 24 2048 05:12:00 GMT+0800 (China Standard Time)\n```\n\n### formatDate(date)\n\n- **date**:\n  - Type: `Date`\n- (return value):\n  - Type: `String`\n  - The formatted date string.\n\nFormat a date object to a string with the set date format.\n\n```js\nconst picker = new Picker(element, options);\n\npicker.formatDate(new Date(2048, 9, 24, 5, 12));\n// > 2048-10-24 05:12\n```\n\n### destroy()\n\nDestroy the picker and remove the instance from the target element.\n\n[⬆ Back to top](#table-of-contents)\n\n## Events\n\n### show\n\nThis event fires when a picker modal starts to show.\n\n> Only available in non-inline mode.\n\n### shown\n\nThis event fires when a picker modal has shown.\n\n> Only available in non-inline mode.\n\n### hide\n\nThis event fires when a picker modal starts to hide.\n\n> Only available in non-inline mode.\n\n### hidden\n\nThis event fires when a picker modal has hidden.\n\n> Only available in non-inline mode.\n\n### pick\n\nThis event fires when pick the current date to the target element.\n\n> If the target element is an `<input>` or `<textarea>` element, then a `change` event will be triggered too.\n\n[⬆ Back to top](#table-of-contents)\n\n## No conflict\n\nIf you have to use other picker with the same namespace, just call the `Picker.noConflict` static method to revert to it.\n\n```html\n<script src=\"other-picker.js\"></script>\n<script src=\"picker.js\"></script>\n<script>\n  Picker.noConflict();\n  // Code that uses other `Picker` can follow here.\n</script>\n```\n\n## Browser support\n\n- Chrome (latest)\n- Firefox (latest)\n- Safari (latest)\n- Opera (latest)\n- Edge (latest)\n- Internet Explorer 9+\n\n## Versioning\n\nMaintained under the [Semantic Versioning guidelines](https://semver.org).\n\n## License\n\n[MIT](https://opensource.org/licenses/MIT) © [Chen Fengyuan](https://chenfengyuan.com)\n\n[⬆ Back to top](#table-of-contents)\n"
  },
  {
    "path": "dist/picker.common.js",
    "content": "/*!\n * Picker.js v1.2.1\n * https://fengyuanchen.github.io/pickerjs\n *\n * Copyright 2016-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2019-02-18T13:08:12.801Z\n */\n\n'use strict';\n\nfunction _typeof(obj) {\n  if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n    _typeof = function (obj) {\n      return typeof obj;\n    };\n  } else {\n    _typeof = function (obj) {\n      return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n    };\n  }\n\n  return _typeof(obj);\n}\n\nfunction _classCallCheck(instance, Constructor) {\n  if (!(instance instanceof Constructor)) {\n    throw new TypeError(\"Cannot call a class as a function\");\n  }\n}\n\nfunction _defineProperties(target, props) {\n  for (var i = 0; i < props.length; i++) {\n    var descriptor = props[i];\n    descriptor.enumerable = descriptor.enumerable || false;\n    descriptor.configurable = true;\n    if (\"value\" in descriptor) descriptor.writable = true;\n    Object.defineProperty(target, descriptor.key, descriptor);\n  }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n  if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n  if (staticProps) _defineProperties(Constructor, staticProps);\n  return Constructor;\n}\n\nfunction _toConsumableArray(arr) {\n  return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();\n}\n\nfunction _arrayWithoutHoles(arr) {\n  if (Array.isArray(arr)) {\n    for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];\n\n    return arr2;\n  }\n}\n\nfunction _iterableToArray(iter) {\n  if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter);\n}\n\nfunction _nonIterableSpread() {\n  throw new TypeError(\"Invalid attempt to spread non-iterable instance\");\n}\n\nvar DEFAULTS = {\n  // Define the container for putting the picker.\n  container: null,\n  // Indicate whether show the prev and next arrow controls on each column.\n  controls: false,\n  // The initial date. If not present, use the current date.\n  date: null,\n  // The date string format, also as the sorting order for columns.\n  format: 'YYYY-MM-DD HH:mm',\n  // Indicate whether show the column headers.\n  headers: false,\n  // Define the increment for each date / time part.\n  increment: 1,\n  // Enable inline mode.\n  inline: false,\n  // Define the language. (An ISO language code).\n  language: '',\n  // Months' name.\n  months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],\n  // Shorter months' name.\n  monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n  // Define the number of rows for showing.\n  rows: 5,\n  // Define the text of the picker.\n  text: {\n    title: 'Pick a date and time',\n    cancel: 'Cancel',\n    confirm: 'OK',\n    year: 'Year',\n    month: 'Month',\n    day: 'Day',\n    hour: 'Hour',\n    minute: 'Minute',\n    second: 'Second',\n    millisecond: 'Millisecond'\n  },\n  // Translate date / time text.\n  translate: function translate(type, text) {\n    return text;\n  },\n  // Shortcuts of custom events.\n  show: null,\n  shown: null,\n  hide: null,\n  hidden: null,\n  pick: null\n};\n\nvar TEMPLATE = '<div class=\"picker\" data-picker-action=\"hide\" touch-action=\"none\" tabindex=\"-1\" role=\"dialog\">' + '<div class=\"picker-dialog\" role=\"document\">' + '<div class=\"picker-header\">' + '<h4 class=\"picker-title\">{{ title }}</h4>' + '<button type=\"button\" class=\"picker-close\" data-picker-action=\"hide\" aria-label=\"Close\">&times;</button>' + '</div>' + '<div class=\"picker-body\">' + '<div class=\"picker-grid\"></div>' + '</div>' + '<div class=\"picker-footer\">' + '<button type=\"button\" class=\"picker-cancel\" data-picker-action=\"hide\">{{ cancel }}</button>' + '<button type=\"button\" class=\"picker-confirm\" data-picker-action=\"pick\">{{ confirm }}</button>' + '</div>' + '</div>' + '</div>';\n\nvar IS_BROWSER = typeof window !== 'undefined';\nvar WINDOW = IS_BROWSER ? window : {};\nvar IS_TOUCH_DEVICE = IS_BROWSER ? 'ontouchstart' in WINDOW.document.documentElement : false;\nvar HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;\nvar NAMESPACE = 'picker';\nvar LANGUAGES = {}; // Actions\n\nvar ACTION_HIDE = 'hide';\nvar ACTION_NEXT = 'next';\nvar ACTION_PICK = 'pick';\nvar ACTION_PREV = 'prev'; // Classes\n\nvar CLASS_OPEN = \"\".concat(NAMESPACE, \"-open\");\nvar CLASS_OPENED = \"\".concat(NAMESPACE, \"-opened\");\nvar CLASS_PICKED = \"\".concat(NAMESPACE, \"-picked\"); // Data keys\n// Add namespace to avoid to conflict to some other libraries.\n\nvar DATA_ACTION = \"\".concat(NAMESPACE, \"Action\");\nvar DATA_TOKEN = 'token';\nvar DATA_TYPE = 'type';\nvar DATA_NAME = 'name';\nvar DATA_VALUE = 'value'; // Events\n\nvar EVENT_CLICK = 'click';\nvar EVENT_FOCUS = 'focus';\nvar EVENT_HIDDEN = 'hidden';\nvar EVENT_HIDE = 'hide';\nvar EVENT_KEY_DOWN = 'keydown';\nvar EVENT_PICK = 'pick';\nvar EVENT_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown';\nvar EVENT_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'touchmove' : 'mousemove';\nvar EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup';\nvar EVENT_POINTER_DOWN = HAS_POINTER_EVENT ? 'pointerdown' : EVENT_TOUCH_START;\nvar EVENT_POINTER_MOVE = HAS_POINTER_EVENT ? 'pointermove' : EVENT_TOUCH_MOVE;\nvar EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END;\nvar EVENT_SHOW = 'show';\nvar EVENT_SHOWN = 'shown';\nvar EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll';\n\nvar _Object$prototype = Object.prototype,\n    hasOwnProperty = _Object$prototype.hasOwnProperty,\n    toString = _Object$prototype.toString;\n/**\n * Detect the type of the given value.\n * @param {*} value - The value to detect.\n * @returns {string} Returns the type.\n */\n\nfunction typeOf(value) {\n  return toString.call(value).slice(8, -1).toLowerCase();\n}\n/**\n * Check if the given value is a string.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a string, else `false`.\n */\n\nfunction isString(value) {\n  return typeof value === 'string';\n}\n/**\n * Check if the given value is finite.\n */\n\nvar isFinite = Number.isFinite || WINDOW.isFinite;\n/**\n * Check if the given value is not a number.\n */\n\nvar isNaN = Number.isNaN || WINDOW.isNaN;\n/**\n * Check if the given value is a number.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a number, else `false`.\n */\n\nfunction isNumber(value) {\n  return typeof value === 'number' && !isNaN(value);\n}\n/**\n * Check if the given value is an object.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is an object, else `false`.\n */\n\nfunction isObject(value) {\n  return _typeof(value) === 'object' && value !== null;\n}\n/**\n * Check if the given value is a plain object.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a plain object, else `false`.\n */\n\nfunction isPlainObject(value) {\n  if (!isObject(value)) {\n    return false;\n  }\n\n  try {\n    var _constructor = value.constructor;\n    var prototype = _constructor.prototype;\n    return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');\n  } catch (error) {\n    return false;\n  }\n}\n/**\n * Check if the given value is a function.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a function, else `false`.\n */\n\nfunction isFunction(value) {\n  return typeof value === 'function';\n}\n/**\n * Check if the given value is a date.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a date, else `false`.\n */\n\nfunction isDate(value) {\n  return typeOf(value) === 'date';\n}\n/**\n * Check if the given value is a valid date.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a valid date, else `false`.\n */\n\nfunction isValidDate(value) {\n  return isDate(value) && value.toString() !== 'Invalid Date';\n}\n/**\n * Iterate the given data.\n * @param {*} data - The data to iterate.\n * @param {Function} callback - The process function for each element.\n * @returns {*} The original data.\n */\n\nfunction forEach(data, callback) {\n  if (data && isFunction(callback)) {\n    if (Array.isArray(data) || isNumber(data.length)\n    /* array-like */\n    ) {\n        var length = data.length;\n        var i;\n\n        for (i = 0; i < length; i += 1) {\n          if (callback.call(data, data[i], i, data) === false) {\n            break;\n          }\n        }\n      } else if (isObject(data)) {\n      Object.keys(data).forEach(function (key) {\n        callback.call(data, data[key], key, data);\n      });\n    }\n  }\n\n  return data;\n}\n/**\n * Recursively assigns own enumerable properties of source objects to the target object.\n * @param {Object} target - The target object.\n * @param {Object[]} sources - The source objects.\n * @returns {Object} The target object.\n */\n\nfunction deepAssign(target) {\n  for (var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n    sources[_key - 1] = arguments[_key];\n  }\n\n  if (isObject(target) && sources.length > 0) {\n    sources.forEach(function (source) {\n      if (isObject(source)) {\n        Object.keys(source).forEach(function (key) {\n          if (isPlainObject(target[key]) && isPlainObject(source[key])) {\n            target[key] = deepAssign({}, target[key], source[key]);\n          } else {\n            target[key] = source[key];\n          }\n        });\n      }\n    });\n  }\n\n  return target;\n}\n/**\n * Add classes to the given element.\n * @param {Element} element - The target element.\n * @param {string} value - The classes to be added.\n */\n\nfunction addClass(element, value) {\n  if (!value) {\n    return;\n  }\n\n  if (isNumber(element.length)) {\n    forEach(element, function (elem) {\n      addClass(elem, value);\n    });\n    return;\n  }\n\n  if (element.classList) {\n    element.classList.add(value);\n    return;\n  }\n\n  var className = element.className.trim();\n\n  if (!className) {\n    element.className = value;\n  } else if (className.indexOf(value) < 0) {\n    element.className = \"\".concat(className, \" \").concat(value);\n  }\n}\n/**\n * Remove classes from the given element.\n * @param {Element} element - The target element.\n * @param {string} value - The classes to be removed.\n */\n\nfunction removeClass(element, value) {\n  if (!value) {\n    return;\n  }\n\n  if (isNumber(element.length)) {\n    forEach(element, function (elem) {\n      removeClass(elem, value);\n    });\n    return;\n  }\n\n  if (element.classList) {\n    element.classList.remove(value);\n    return;\n  }\n\n  if (element.className.indexOf(value) >= 0) {\n    element.className = element.className.replace(value, '');\n  }\n}\nvar REGEXP_HYPHENATE = /([a-z\\d])([A-Z])/g;\n/**\n * Transform the given string from camelCase to kebab-case\n * @param {string} value - The value to transform.\n * @returns {string} The transformed value.\n */\n\nfunction hyphenate(value) {\n  return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase();\n}\n/**\n * Get data from the given element.\n * @param {Element} element - The target element.\n * @param {string} name - The data key to get.\n * @returns {string} The data value.\n */\n\nfunction getData(element, name) {\n  if (isObject(element[name])) {\n    return element[name];\n  }\n\n  if (element.dataset) {\n    return element.dataset[name];\n  }\n\n  return element.getAttribute(\"data-\".concat(hyphenate(name)));\n}\n/**\n * Set data to the given element.\n * @param {Element} element - The target element.\n * @param {string} name - The data key to set.\n * @param {string} data - The data value.\n */\n\nfunction setData(element, name, data) {\n  if (isObject(data)) {\n    element[name] = data;\n  } else if (element.dataset) {\n    element.dataset[name] = data;\n  } else {\n    element.setAttribute(\"data-\".concat(hyphenate(name)), data);\n  }\n}\n/**\n * Remove data from the given element.\n * @param {Element} element - The target element.\n * @param {string} name - The data key to remove.\n */\n\nfunction removeData(element, name) {\n  if (isObject(element[name])) {\n    try {\n      delete element[name];\n    } catch (error) {\n      element[name] = undefined;\n    }\n  } else if (element.dataset) {\n    // #128 Safari not allows to delete dataset property\n    try {\n      delete element.dataset[name];\n    } catch (error) {\n      element.dataset[name] = undefined;\n    }\n  } else {\n    element.removeAttribute(\"data-\".concat(hyphenate(name)));\n  }\n}\nvar REGEXP_SPACES = /\\s\\s*/;\n\nvar onceSupported = function () {\n  var supported = false;\n\n  if (IS_BROWSER) {\n    var once = false;\n\n    var listener = function listener() {};\n\n    var options = Object.defineProperty({}, 'once', {\n      get: function get() {\n        supported = true;\n        return once;\n      },\n\n      /**\n       * This setter can fix a `TypeError` in strict mode\n       * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}\n       * @param {boolean} value - The value to set\n       */\n      set: function set(value) {\n        once = value;\n      }\n    });\n    WINDOW.addEventListener('test', listener, options);\n    WINDOW.removeEventListener('test', listener, options);\n  }\n\n  return supported;\n}();\n/**\n * Remove event listener from the target element.\n * @param {Element} element - The event target.\n * @param {string} type - The event type(s).\n * @param {Function} listener - The event listener.\n * @param {Object} options - The event options.\n */\n\n\nfunction removeListener(element, type, listener) {\n  var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n  var handler = listener;\n  type.trim().split(REGEXP_SPACES).forEach(function (event) {\n    if (!onceSupported) {\n      var listeners = element.listeners;\n\n      if (listeners && listeners[event] && listeners[event][listener]) {\n        handler = listeners[event][listener];\n        delete listeners[event][listener];\n\n        if (Object.keys(listeners[event]).length === 0) {\n          delete listeners[event];\n        }\n\n        if (Object.keys(listeners).length === 0) {\n          delete element.listeners;\n        }\n      }\n    }\n\n    element.removeEventListener(event, handler, options);\n  });\n}\n/**\n * Add event listener to the target element.\n * @param {Element} element - The event target.\n * @param {string} type - The event type(s).\n * @param {Function} listener - The event listener.\n * @param {Object} options - The event options.\n */\n\nfunction addListener(element, type, listener) {\n  var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n  var _handler = listener;\n  type.trim().split(REGEXP_SPACES).forEach(function (event) {\n    if (options.once && !onceSupported) {\n      var _element$listeners = element.listeners,\n          listeners = _element$listeners === void 0 ? {} : _element$listeners;\n\n      _handler = function handler() {\n        delete listeners[event][listener];\n        element.removeEventListener(event, _handler, options);\n\n        for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n          args[_key2] = arguments[_key2];\n        }\n\n        listener.apply(element, args);\n      };\n\n      if (!listeners[event]) {\n        listeners[event] = {};\n      }\n\n      if (listeners[event][listener]) {\n        element.removeEventListener(event, listeners[event][listener], options);\n      }\n\n      listeners[event][listener] = _handler;\n      element.listeners = listeners;\n    }\n\n    element.addEventListener(event, _handler, options);\n  });\n}\n/**\n * Dispatch event on the target element.\n * @param {Element} element - The event target.\n * @param {string} type - The event type(s).\n * @param {Object} data - The additional event data.\n * @returns {boolean} Indicate if the event is default prevented or not.\n */\n\nfunction dispatchEvent(element, type, data) {\n  var event; // Event and CustomEvent on IE9-11 are global objects, not constructors\n\n  if (isFunction(Event) && isFunction(CustomEvent)) {\n    event = new CustomEvent(type, {\n      detail: data,\n      bubbles: true,\n      cancelable: true\n    });\n  } else {\n    event = document.createEvent('CustomEvent');\n    event.initCustomEvent(type, true, true, data);\n  }\n\n  return element.dispatchEvent(event);\n}\n/**\n * Check if the given year is a leap year.\n * @param {number} year - The year to check.\n * @returns {boolean} Returns `true` if the given year is a leap year, else `false`.\n */\n\nfunction isLeapYear(year) {\n  return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;\n}\n/**\n * Get days number of the given month.\n * @param {number} year - The target year.\n * @param {number} month - The target month.\n * @returns {number} Returns days number.\n */\n\nfunction getDaysInMonth(year, month) {\n  return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];\n}\n/**\n * Add leading zeroes to the given value\n * @param {number} value - The value to add.\n * @param {number} [length=1] - The number of the leading zeroes.\n * @returns {string} Returns converted value.\n */\n\nfunction addLeadingZero(value) {\n  var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n  var str = String(Math.abs(value));\n  var i = str.length;\n  var result = '';\n\n  if (value < 0) {\n    result += '-';\n  }\n\n  while (i < length) {\n    i += 1;\n    result += '0';\n  }\n\n  return result + str;\n}\n/**\n * Map token to type name\n * @param {string} token - The token to map.\n * @returns {string} Returns mapped type name.\n */\n\nfunction tokenToType(token) {\n  return {\n    Y: 'year',\n    M: 'month',\n    D: 'day',\n    H: 'hour',\n    m: 'minute',\n    s: 'second',\n    S: 'millisecond'\n  }[token.charAt(0)];\n}\nvar REGEXP_TOKENS = /(Y|M|D|H|m|s|S)\\1*/g;\n/**\n * Parse date format.\n * @param {string} format - The format to parse.\n * @returns {Object} Returns parsed format data.\n */\n\nfunction parseFormat(format) {\n  var tokens = format.match(REGEXP_TOKENS);\n\n  if (!tokens) {\n    throw new Error('Invalid format.');\n  } // Remove duplicate tokens (#22)\n\n\n  tokens = tokens.filter(function (token, index) {\n    return tokens.indexOf(token) === index;\n  });\n  var result = {\n    tokens: tokens\n  };\n  tokens.forEach(function (token) {\n    result[tokenToType(token)] = token;\n  });\n  return result;\n}\n\nvar events = {\n  bind: function bind() {\n    var element = this.element,\n        options = this.options,\n        grid = this.grid;\n\n    if (isFunction(options.show)) {\n      addListener(element, EVENT_SHOW, options.show);\n    }\n\n    if (isFunction(options.shown)) {\n      addListener(element, EVENT_SHOWN, options.shown);\n    }\n\n    if (isFunction(options.hide)) {\n      addListener(element, EVENT_HIDE, options.hide);\n    }\n\n    if (isFunction(options.hidden)) {\n      addListener(element, EVENT_HIDDEN, options.hidden);\n    }\n\n    if (isFunction(options.pick)) {\n      addListener(element, EVENT_PICK, options.pick);\n    }\n\n    addListener(element, EVENT_FOCUS, this.onFocus = this.focus.bind(this));\n    addListener(element, EVENT_CLICK, this.onFocus);\n    addListener(this.picker, EVENT_CLICK, this.onClick = this.click.bind(this));\n    addListener(grid, EVENT_WHEEL, this.onWheel = this.wheel.bind(this));\n    addListener(grid, EVENT_POINTER_DOWN, this.onPointerDown = this.pointerdown.bind(this));\n    addListener(document, EVENT_POINTER_MOVE, this.onPointerMove = this.pointermove.bind(this));\n    addListener(document, EVENT_POINTER_UP, this.onPointerUp = this.pointerup.bind(this));\n    addListener(document, EVENT_KEY_DOWN, this.onKeyDown = this.keydown.bind(this));\n  },\n  unbind: function unbind() {\n    var element = this.element,\n        options = this.options,\n        grid = this.grid;\n\n    if (isFunction(options.show)) {\n      removeListener(element, EVENT_SHOW, options.show);\n    }\n\n    if (isFunction(options.shown)) {\n      removeListener(element, EVENT_SHOWN, options.shown);\n    }\n\n    if (isFunction(options.hide)) {\n      removeListener(element, EVENT_HIDE, options.hide);\n    }\n\n    if (isFunction(options.hidden)) {\n      removeListener(element, EVENT_HIDDEN, options.hidden);\n    }\n\n    if (isFunction(options.pick)) {\n      removeListener(element, EVENT_PICK, options.pick);\n    }\n\n    removeListener(element, EVENT_FOCUS, this.onFocus);\n    removeListener(element, EVENT_CLICK, this.onFocus);\n    removeListener(this.picker, EVENT_CLICK, this.onClick);\n    removeListener(grid, EVENT_WHEEL, this.onWheel);\n    removeListener(grid, EVENT_POINTER_DOWN, this.onPointerDown);\n    removeListener(document, EVENT_POINTER_MOVE, this.onPointerMove);\n    removeListener(document, EVENT_POINTER_UP, this.onPointerUp);\n    removeListener(document, EVENT_KEY_DOWN, this.onKeyDown);\n  }\n};\n\nvar handlers = {\n  focus: function focus(event) {\n    event.target.blur();\n    this.show();\n  },\n  click: function click(event) {\n    var target = event.target;\n    var action = getData(target, DATA_ACTION);\n\n    switch (action) {\n      case ACTION_HIDE:\n        this.hide();\n        break;\n\n      case ACTION_PICK:\n        this.pick();\n        break;\n\n      case ACTION_PREV:\n      case ACTION_NEXT:\n        this[action](getData(target.parentElement, DATA_TYPE));\n        break;\n\n      default:\n    }\n  },\n  wheel: function wheel(event) {\n    var target = event.target;\n\n    if (target === this.grid) {\n      return;\n    }\n\n    event.preventDefault();\n\n    while (target.parentElement && target.parentElement !== this.grid) {\n      target = target.parentElement;\n    }\n\n    var type = getData(target, DATA_TYPE);\n\n    if (event.deltaY < 0) {\n      this.prev(type);\n    } else {\n      this.next(type);\n    }\n  },\n  pointerdown: function pointerdown(event) {\n    var target = event.target;\n\n    if (target === this.grid || getData(target, DATA_ACTION)) {\n      return;\n    } // This line is required for preventing page scrolling in iOS browsers\n\n\n    event.preventDefault();\n\n    while (target.parentElement && target.parentElement !== this.grid) {\n      target = target.parentElement;\n    }\n\n    var list = target.querySelector(\".\".concat(NAMESPACE, \"-list\"));\n    var itemHeight = list.firstElementChild.offsetHeight;\n    this.cell = {\n      elem: target,\n      list: list,\n      moveY: 0,\n      maxMoveY: itemHeight,\n      minMoveY: itemHeight / 2,\n      startY: event.changedTouches ? event.changedTouches[0].pageY : event.pageY,\n      type: getData(target, DATA_TYPE)\n    };\n  },\n  pointermove: function pointermove(event) {\n    var cell = this.cell;\n\n    if (!cell) {\n      return;\n    }\n\n    event.preventDefault();\n    var endY = event.changedTouches ? event.changedTouches[0].pageY : event.pageY;\n    var moveY = cell.moveY + (endY - cell.startY);\n    cell.startY = endY;\n    cell.moveY = moveY;\n\n    if (Math.abs(moveY) < cell.maxMoveY) {\n      cell.list.style.top = \"\".concat(moveY, \"px\");\n      return;\n    }\n\n    cell.list.style.top = 0;\n    cell.moveY = 0;\n\n    if (moveY >= cell.maxMoveY) {\n      this.prev(cell.type);\n    } else if (moveY <= -cell.maxMoveY) {\n      this.next(cell.type);\n    }\n  },\n  pointerup: function pointerup(event) {\n    var cell = this.cell;\n\n    if (!cell) {\n      return;\n    }\n\n    event.preventDefault();\n    cell.list.style.top = 0;\n\n    if (cell.moveY >= cell.minMoveY) {\n      this.prev(cell.type);\n    } else if (cell.moveY <= -cell.minMoveY) {\n      this.next(cell.type);\n    }\n\n    this.cell = null;\n  },\n  keydown: function keydown(event) {\n    if (this.shown && (event.key === 'Escape' || event.keyCode === 27)) {\n      this.hide();\n    }\n  }\n};\n\nvar helpers = {\n  render: function render(type) {\n    var _this = this;\n\n    if (!type) {\n      this.format.tokens.forEach(function (token) {\n        return _this.render(tokenToType(token));\n      });\n      return;\n    }\n\n    var options = this.options;\n    var data = this.data[type];\n    var current = this.current(type);\n    var max = isFunction(data.max) ? data.max() : data.max;\n    var min = isFunction(data.min) ? data.min() : data.min;\n    var base = 0;\n\n    if (isFinite(max)) {\n      base = min > 0 ? max : max + 1;\n    }\n\n    data.list.innerHTML = '';\n    data.current = current;\n\n    for (var i = 0; i < options.rows + 2; i += 1) {\n      var item = document.createElement('li');\n      var position = i - data.index;\n      var newValue = current + position * data.increment;\n\n      if (base) {\n        newValue %= base;\n\n        if (newValue < min) {\n          newValue += base;\n        }\n      }\n\n      item.textContent = options.translate(type, data.aliases ? data.aliases[newValue] : addLeadingZero(newValue + data.offset, data.digit));\n      setData(item, DATA_NAME, type);\n      setData(item, DATA_VALUE, newValue);\n      addClass(item, \"\".concat(NAMESPACE, \"-item\"));\n\n      if (position === 0) {\n        addClass(item, CLASS_PICKED);\n        data.item = item;\n      }\n\n      data.list.appendChild(item);\n    }\n  },\n  current: function current(type, value) {\n    var date = this.date;\n    var format = this.format;\n    var token = format[type];\n\n    switch (token.charAt(0)) {\n      case 'Y':\n        if (isNumber(value)) {\n          date.setFullYear(token.length === 2 ? 2000 + value : value);\n\n          if (format.month) {\n            this.render(tokenToType(format.month));\n          }\n\n          if (format.day) {\n            this.render(tokenToType(format.day));\n          }\n        }\n\n        return date.getFullYear();\n\n      case 'M':\n        if (isNumber(value)) {\n          date.setMonth(value, // The current day should not exceed its maximum day in current month\n          Math.min(date.getDate(), getDaysInMonth(date.getFullYear(), value)));\n\n          if (format.day) {\n            this.render(tokenToType(format.day));\n          }\n        }\n\n        return date.getMonth();\n\n      case 'D':\n        if (isNumber(value)) {\n          date.setDate(value);\n        }\n\n        return date.getDate();\n\n      case 'H':\n        if (isNumber(value)) {\n          date.setHours(value);\n        }\n\n        return date.getHours();\n\n      case 'm':\n        if (isNumber(value)) {\n          date.setMinutes(value);\n        }\n\n        return date.getMinutes();\n\n      case 's':\n        if (isNumber(value)) {\n          date.setSeconds(value);\n        }\n\n        return date.getSeconds();\n\n      case 'S':\n        if (isNumber(value)) {\n          date.setMilliseconds(value);\n        }\n\n        return date.getMilliseconds();\n\n      default:\n    }\n\n    return date;\n  },\n  getValue: function getValue() {\n    var element = this.element;\n    return this.isInput ? element.value : element.textContent;\n  },\n  setValue: function setValue(value) {\n    var element = this.element;\n\n    if (this.isInput) {\n      element.value = value;\n    } else if (this.options.container) {\n      element.textContent = value;\n    }\n  },\n  open: function open() {\n    var body = this.body;\n    body.style.overflow = 'hidden';\n    body.style.paddingRight = \"\".concat(this.scrollBarWidth + (parseFloat(this.initialBodyPaddingRight) || 0), \"px\");\n  },\n  close: function close() {\n    var body = this.body;\n    body.style.overflow = '';\n    body.style.paddingRight = this.initialBodyPaddingRight;\n  }\n};\n\nvar methods = {\n  /**\n   * Show the picker.\n   * @param {boolean} [immediate=false] - Indicate if show the picker immediately or not.\n   * @returns {Picker} this\n   */\n  show: function show() {\n    var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n    var element = this.element,\n        picker = this.picker;\n\n    if (this.inline || this.shown) {\n      return this;\n    }\n\n    if (dispatchEvent(element, EVENT_SHOW) === false) {\n      return this;\n    }\n\n    this.shown = true;\n    this.open();\n    addClass(picker, CLASS_OPEN);\n\n    var done = function done() {\n      dispatchEvent(element, EVENT_SHOWN);\n    };\n\n    if (!immediate) {\n      // Reflow to enable transition\n      // eslint-disable-next-line\n      picker.offsetWidth;\n    }\n\n    addClass(picker, CLASS_OPENED);\n\n    if (immediate) {\n      done();\n    } else {\n      setTimeout(done, 300);\n    }\n\n    return this;\n  },\n\n  /**\n   * Hide the picker.\n   * @param {boolean} [immediate=false] - Indicate if hide the picker immediately or not.\n   * @returns {Picker} this\n   */\n  hide: function hide() {\n    var _this = this;\n\n    var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n    var element = this.element,\n        picker = this.picker;\n\n    if (this.inline || !this.shown) {\n      return this;\n    }\n\n    if (dispatchEvent(element, EVENT_HIDE) === false) {\n      return this;\n    }\n\n    this.shown = false;\n    removeClass(picker, CLASS_OPENED);\n\n    var done = function done() {\n      _this.close();\n\n      removeClass(picker, CLASS_OPEN);\n      dispatchEvent(element, EVENT_HIDDEN);\n    };\n\n    if (immediate) {\n      done();\n    } else {\n      setTimeout(done, 300);\n    }\n\n    return this;\n  },\n\n  /**\n   * Pick to the previous item.\n   * @param {string} type - The column type.\n   * @returns {Picker} this\n   */\n  prev: function prev(type) {\n    var options = this.options;\n    var token = this.format[type];\n    var data = this.data[type];\n    var list = data.list;\n    var item = list.lastElementChild;\n    var max = isFunction(data.max) ? data.max() : data.max;\n    var min = isFunction(data.min) ? data.min() : data.min;\n    var prev = data.item.previousElementSibling;\n    var value = Number(getData(list.firstElementChild, DATA_VALUE)) - data.increment;\n\n    if (value < min) {\n      value += max - min + 1;\n    }\n\n    item.textContent = options.translate(type, data.aliases ? data.aliases[value] : addLeadingZero(value + data.offset, token.length));\n    setData(item, DATA_VALUE, value);\n\n    if (prev) {\n      removeClass(data.item, CLASS_PICKED);\n      addClass(prev, CLASS_PICKED);\n      data.item = prev;\n    }\n\n    list.insertBefore(item, list.firstElementChild);\n    data.current = Number(getData(data.item, DATA_VALUE));\n    this.current(type, data.current);\n\n    if (this.inline && options.container) {\n      this.pick();\n    }\n\n    return this;\n  },\n\n  /**\n   * Pick to the next item.\n   * @param {String} type - The column type.\n   * @returns {Picker} this\n   */\n  next: function next(type) {\n    var options = this.options;\n    var token = this.format[type];\n    var data = this.data[type];\n    var list = data.list;\n    var item = list.firstElementChild;\n    var max = isFunction(data.max) ? data.max() : data.max;\n    var min = isFunction(data.min) ? data.min() : data.min;\n    var next = data.item.nextElementSibling;\n    var value = Number(getData(list.lastElementChild, DATA_VALUE)) + data.increment;\n\n    if (value > max) {\n      value -= max - min + 1;\n    }\n\n    item.textContent = options.translate(type, data.aliases ? data.aliases[value] : addLeadingZero(value + data.offset, token.length));\n    setData(item, DATA_VALUE, value);\n    list.appendChild(item);\n\n    if (next) {\n      removeClass(data.item, CLASS_PICKED);\n      addClass(next, CLASS_PICKED);\n      data.item = next;\n    }\n\n    data.current = Number(getData(data.item, DATA_VALUE));\n    this.current(type, data.current);\n\n    if (this.inline && options.container) {\n      this.pick();\n    }\n\n    return this;\n  },\n  // Pick the current date to the target element.\n  pick: function pick() {\n    var element = this.element;\n\n    if (dispatchEvent(element, EVENT_PICK) === false) {\n      return this;\n    }\n\n    var value = this.formatDate(this.date);\n    this.setValue(value);\n\n    if (this.isInput && dispatchEvent(element, 'change') === false) {\n      this.reset();\n    }\n\n    this.hide();\n    return this;\n  },\n\n  /**\n   * Get the current date.\n   * @param {boolean} [formatted=false] - Indicate if format the date or not.\n   * @return {Date|string} The output date.\n   */\n  getDate: function getDate() {\n    var formatted = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n    var date = this.date;\n    return formatted ? this.formatDate(date) : new Date(date);\n  },\n\n  /**\n   * Override the current date with a new date.\n   * @param {Date|string} date - The date to set.\n   * @returns {Picker} this\n   */\n  setDate: function setDate(date) {\n    if (date) {\n      this.date = this.parseDate(date);\n      this.render();\n    }\n\n    return this;\n  },\n  // Update the picker with the current element value / text.\n  update: function update() {\n    this.date = this.parseDate(this.getValue());\n    this.render();\n    return this;\n  },\n  // Reset the picker and element value / text.\n  reset: function reset() {\n    this.setValue(this.initialValue);\n    this.date = new Date(this.initialDate);\n    this.render();\n    return this;\n  },\n\n  /**\n   * Parse a date with the set date format.\n   * @param {Date|string} date - The date to parse.\n   * @returns {Date} The parsed date object.\n   */\n  parseDate: function parseDate(date) {\n    var options = this.options,\n        format = this.format;\n    var digits = [];\n\n    if (isDate(date)) {\n      return new Date(date);\n    }\n\n    if (isString(date)) {\n      var groups = [].concat(_toConsumableArray(options.months), _toConsumableArray(options.monthsShort), ['\\\\d+']);\n      digits = date.match(new RegExp(\"(\".concat(groups.join('|'), \")\"), 'g')); // Parse `11111111` (YYYYMMDD) to ['1111', '11', '11']\n\n      if (digits && date.length === options.format.length && digits.length !== format.tokens.length) {\n        digits = format.tokens.map(function (token) {\n          return date.substr(options.format.indexOf(token), token.length);\n        });\n      }\n\n      if (!digits || digits.length !== format.tokens.length) {\n        return new Date();\n      }\n    }\n\n    var parsedDate = new Date();\n    digits.forEach(function (digit, i) {\n      var token = format.tokens[i];\n      var n = Number(digit);\n\n      switch (token) {\n        case 'YYYY':\n        case 'YYY':\n        case 'Y':\n          {\n            var index = date.indexOf(digit);\n            var isHyphen = date.substr(index - 1, 1) === '-';\n            var isBC = index > 1 && isHyphen && /\\S/.test(date.substr(index - 2, 1)) || index === 1 && isHyphen;\n            parsedDate.setFullYear(isBC ? -n : n);\n            break;\n          }\n\n        case 'YY':\n          parsedDate.setFullYear(2000 + n);\n          break;\n\n        case 'MMMM':\n          parsedDate.setMonth(options.months.indexOf(digit));\n          break;\n\n        case 'MMM':\n          parsedDate.setMonth(options.monthsShort.indexOf(digit));\n          break;\n\n        case 'MM':\n        case 'M':\n          parsedDate.setMonth(n - 1);\n          break;\n\n        case 'DD':\n        case 'D':\n          parsedDate.setDate(n);\n          break;\n\n        case 'HH':\n        case 'H':\n          parsedDate.setHours(n);\n          break;\n\n        case 'mm':\n        case 'm':\n          parsedDate.setMinutes(n);\n          break;\n\n        case 'ss':\n        case 's':\n          parsedDate.setSeconds(n);\n          break;\n\n        case 'SSS':\n        case 'SS':\n        case 'S':\n          parsedDate.setMilliseconds(n);\n          break;\n\n        default:\n      }\n    });\n    return parsedDate;\n  },\n\n  /**\n   * Format a date object to a string with the set date format.\n   * @param {Date} date - The date to format.\n   * @return {string} THe formatted date.\n   */\n  formatDate: function formatDate(date) {\n    var options = this.options,\n        format = this.format;\n    var formatted = '';\n\n    if (isValidDate(date)) {\n      var year = date.getFullYear();\n      var month = date.getMonth();\n      var day = date.getDate();\n      var hours = date.getHours();\n      var minutes = date.getMinutes();\n      var seconds = date.getSeconds();\n      var milliseconds = date.getMilliseconds();\n      formatted = options.format;\n      format.tokens.forEach(function (token) {\n        var replacement = '';\n\n        switch (token) {\n          case 'YYYY':\n          case 'YYY':\n          case 'Y':\n            replacement = addLeadingZero(year, token.length);\n            break;\n\n          case 'YY':\n            replacement = addLeadingZero(year % 100, 2);\n            break;\n\n          case 'MMMM':\n            replacement = options.months[month];\n            break;\n\n          case 'MMM':\n            replacement = options.monthsShort[month];\n            break;\n\n          case 'MM':\n          case 'M':\n            replacement = addLeadingZero(month + 1, token.length);\n            break;\n\n          case 'DD':\n          case 'D':\n            replacement = addLeadingZero(day, token.length);\n            break;\n\n          case 'HH':\n          case 'H':\n            replacement = addLeadingZero(hours, token.length);\n            break;\n\n          case 'mm':\n          case 'm':\n            replacement = addLeadingZero(minutes, token.length);\n            break;\n\n          case 'ss':\n          case 's':\n            replacement = addLeadingZero(seconds, token.length);\n            break;\n\n          case 'SSS':\n          case 'SS':\n          case 'S':\n            replacement = addLeadingZero(milliseconds, token.length);\n            break;\n\n          default:\n        }\n\n        formatted = formatted.replace(token, replacement);\n      });\n    }\n\n    return formatted;\n  },\n  // Destroy the picker and remove the instance from the target element.\n  destroy: function destroy() {\n    var element = this.element,\n        picker = this.picker;\n\n    if (!getData(element, NAMESPACE)) {\n      return this;\n    }\n\n    this.hide(true);\n    this.unbind();\n    removeData(element, NAMESPACE);\n    picker.parentNode.removeChild(picker);\n    return this;\n  }\n};\n\nvar REGEXP_DELIMITER = /\\{\\{\\s*(\\w+)\\s*\\}\\}/g;\nvar REGEXP_INPUTS = /input|textarea/i;\nvar AnotherPicker = WINDOW.Picker;\n\nvar Picker =\n/*#__PURE__*/\nfunction () {\n  /**\n   * Create a new Picker.\n   * @param {Element} element - The target element for picking.\n   * @param {Object} [options={}] - The configuration options.\n   */\n  function Picker(element) {\n    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n    _classCallCheck(this, Picker);\n\n    if (!element || element.nodeType !== 1) {\n      throw new Error('The first argument is required and must be an element.');\n    }\n\n    this.element = element;\n    this.options = deepAssign({}, DEFAULTS, LANGUAGES[options.language], isPlainObject(options) && options);\n    this.shown = false;\n    this.init();\n  }\n\n  _createClass(Picker, [{\n    key: \"init\",\n    value: function init() {\n      var _this = this;\n\n      var element = this.element;\n\n      if (getData(element, NAMESPACE)) {\n        return;\n      }\n\n      setData(element, NAMESPACE, this);\n      var options = this.options;\n      var isInput = REGEXP_INPUTS.test(element.tagName);\n      var inline = options.inline && (options.container || !isInput);\n      var template = document.createElement('div');\n      template.insertAdjacentHTML('afterbegin', TEMPLATE.replace(REGEXP_DELIMITER, function () {\n        for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n          args[_key] = arguments[_key];\n        }\n\n        return options.text[args[1]];\n      }));\n      var picker = template.getElementsByClassName(NAMESPACE)[0];\n      var grid = picker.getElementsByClassName(\"\".concat(NAMESPACE, \"-grid\"))[0];\n      var container = options.container;\n\n      if (isString(container)) {\n        container = document.querySelector(container);\n      }\n\n      if (inline) {\n        addClass(picker, CLASS_OPEN);\n        addClass(picker, CLASS_OPENED);\n\n        if (!container) {\n          container = element;\n        }\n      } else {\n        var ownerDocument = element.ownerDocument;\n        var body = ownerDocument.body || ownerDocument.documentElement;\n        this.body = body;\n        this.scrollBarWidth = WINDOW.innerWidth - ownerDocument.documentElement.clientWidth;\n        this.initialBodyPaddingRight = WINDOW.getComputedStyle(body).paddingRight;\n        addClass(picker, \"\".concat(NAMESPACE, \"-fixed\"));\n\n        if (!container) {\n          container = document.body;\n        }\n      }\n\n      this.isInput = isInput;\n      this.inline = inline;\n      this.container = container;\n      this.picker = picker;\n      this.grid = grid;\n      this.cell = null;\n      this.format = parseFormat(options.format);\n      var initialValue = this.getValue();\n      var date = this.parseDate(options.date || initialValue);\n      this.date = date;\n      this.initialDate = new Date(date);\n      this.initialValue = initialValue;\n      this.data = {};\n      var rows = Number(options.rows);\n\n      if (!(rows % 2)) {\n        rows += 1;\n      }\n\n      options.rows = rows || 5;\n      addClass(grid, \"\".concat(NAMESPACE, \"-\").concat(options.rows > 1 ? 'multiple' : 'single'));\n\n      if (options.controls) {\n        addClass(grid, \"\".concat(NAMESPACE, \"-controls\"));\n      }\n\n      var headers = options.headers,\n          increment = options.increment;\n\n      if (headers) {\n        addClass(grid, \"\".concat(NAMESPACE, \"-headers\")); // TODO: Drop the `headers` option's object support in v2.\n\n        headers = isPlainObject(headers) ? headers : options.text;\n      }\n\n      if (!isPlainObject(increment)) {\n        increment = {\n          year: increment,\n          month: increment,\n          day: increment,\n          hour: increment,\n          minute: increment,\n          second: increment,\n          millisecond: increment\n        };\n      }\n\n      this.format.tokens.forEach(function (token) {\n        var type = tokenToType(token);\n        var cell = document.createElement('div');\n        var cellBody = document.createElement('div');\n        var list = document.createElement('ul');\n        var data = {\n          digit: token.length,\n          increment: Math.abs(Number(increment[type])) || 1,\n          list: list,\n          max: Infinity,\n          min: -Infinity,\n          index: Math.floor((options.rows + 2) / 2),\n          offset: 0\n        };\n\n        switch (token.charAt(0)) {\n          case 'Y':\n            if (data.digit === 2) {\n              data.max = 99;\n              data.min = 0;\n            }\n\n            break;\n\n          case 'M':\n            data.max = 11;\n            data.min = 0;\n            data.offset = 1;\n\n            if (data.digit === 3) {\n              data.aliases = options.monthsShort;\n            } else if (data.digit === 4) {\n              data.aliases = options.months;\n            }\n\n            break;\n\n          case 'D':\n            // XXX: Use the latest date to calculate the max day (#23)\n            data.max = function () {\n              return getDaysInMonth(_this.date.getFullYear(), _this.date.getMonth());\n            };\n\n            data.min = 1;\n            break;\n\n          case 'H':\n            data.max = 23;\n            data.min = 0;\n            break;\n\n          case 'm':\n            data.max = 59;\n            data.min = 0;\n            break;\n\n          case 's':\n            data.max = 59;\n            data.min = 0;\n            break;\n\n          case 'S':\n            data.max = 999;\n            data.min = 0;\n            break;\n\n          default:\n        }\n\n        setData(cell, DATA_TYPE, type);\n        setData(cell, DATA_TOKEN, token);\n\n        if (headers) {\n          var cellHeader = document.createElement('div');\n          addClass(cellHeader, \"\".concat(NAMESPACE, \"-cell__header\"));\n          cellHeader.textContent = headers[type] || type[0].toUpperCase() + type.substr(1);\n          cell.appendChild(cellHeader);\n        }\n\n        if (options.controls) {\n          var prev = document.createElement('div');\n          addClass(prev, \"\".concat(NAMESPACE, \"-cell__control\"));\n          addClass(prev, \"\".concat(NAMESPACE, \"-cell__control--prev\"));\n          setData(prev, DATA_ACTION, ACTION_PREV);\n          cell.appendChild(prev);\n        }\n\n        addClass(list, \"\".concat(NAMESPACE, \"-list\"));\n        addClass(cellBody, \"\".concat(NAMESPACE, \"-cell__body\"));\n        addClass(cell, \"\".concat(NAMESPACE, \"-cell\"));\n        addClass(cell, \"\".concat(NAMESPACE, \"-\").concat(type, \"s\"));\n        cellBody.appendChild(list);\n        cell.appendChild(cellBody);\n\n        if (options.controls) {\n          var next = document.createElement('div');\n          addClass(next, \"\".concat(NAMESPACE, \"-cell__control\"));\n          addClass(next, \"\".concat(NAMESPACE, \"-cell__control--next\"));\n          setData(next, DATA_ACTION, ACTION_NEXT);\n          cell.appendChild(next);\n        }\n\n        grid.appendChild(cell);\n        _this.data[type] = data;\n\n        _this.render(type);\n      });\n\n      if (inline) {\n        container.innerHTML = '';\n      }\n\n      container.appendChild(picker);\n      this.bind();\n    }\n    /**\n     * Get the no conflict picker class.\n     * @returns {Picker} The picker class.\n     */\n\n  }], [{\n    key: \"noConflict\",\n    value: function noConflict() {\n      WINDOW.Picker = AnotherPicker;\n      return Picker;\n    }\n    /**\n     * Change the default options.\n     * @param {Object} options - The new default options.\n     */\n\n  }, {\n    key: \"setDefaults\",\n    value: function setDefaults(options) {\n      deepAssign(DEFAULTS, LANGUAGES[options.language], isPlainObject(options) && options);\n    }\n  }]);\n\n  return Picker;\n}();\n\ndeepAssign(Picker.prototype, events, handlers, helpers, methods);\nPicker.languages = LANGUAGES;\n\nmodule.exports = Picker;\n"
  },
  {
    "path": "dist/picker.css",
    "content": "/*!\n * Picker.js v1.2.1\n * https://fengyuanchen.github.io/pickerjs\n *\n * Copyright 2016-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2019-02-18T13:08:09.658Z\n */\n\n:root {\n  --gray: #999;\n  --blue: #0074d9;\n  --color: #333;\n  --background-color: #fff;\n  --border: 1px solid #eee;\n}\n\n.picker {\n  background-color: rgba(0, 0, 0, 0.5);\n  color: #333;\n  color: var(--color);\n  direction: ltr;\n  display: none;\n  font-size: 1rem;\n  line-height: 1.5;\n  overflow: hidden;\n  -ms-touch-action: none;\n  touch-action: none;\n  -webkit-transition: opacity 0.15s;\n  transition: opacity 0.15s;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n\n.picker-fixed {\n  bottom: 0;\n  left: 0;\n  position: fixed;\n  right: 0;\n  top: 0;\n  z-index: 1986;\n}\n\n.picker-fixed > .picker-dialog {\n  bottom: -100%;\n  left: 0;\n  max-height: 100%;\n  position: absolute;\n  right: 0;\n  -webkit-transition: bottom 0.3s;\n  transition: bottom 0.3s;\n}\n\n.picker-fixed .picker-header {\n  display: block;\n}\n\n.picker-fixed .picker-footer {\n  display: table;\n}\n\n.picker-open {\n  display: block;\n  opacity: 0;\n}\n\n.picker-opened {\n  opacity: 1;\n}\n\n.picker-opened > .picker-dialog {\n  bottom: 0;\n}\n\n.picker-dialog {\n  background-color: #fff;\n  background-color: var(--background-color);\n  border: 1px solid #eee;\n  border: var(--border);\n}\n\n.picker-header {\n  border-bottom: 1px solid #eee;\n  border-bottom: var(--border);\n  display: none;\n  padding: 0.875rem 1.25rem;\n  position: relative;\n}\n\n.picker-title {\n  font-size: 1.125rem;\n  font-weight: 500;\n  line-height: 1.25rem;\n  margin: 0;\n}\n\n.picker-close {\n  background-color: transparent;\n  border-width: 0;\n  color: #999;\n  color: var(--gray);\n  cursor: pointer;\n  font-size: 1.75rem;\n  height: 3rem;\n  opacity: 0.75;\n  padding: 0;\n  position: absolute;\n  right: 0;\n  top: 0;\n  width: 3rem;\n}\n\n.picker-close:focus,\n.picker-close:hover {\n  opacity: 1;\n  outline: none;\n}\n\n.picker-body {\n  overflow: hidden;\n}\n\n.picker-grid {\n  display: table;\n  table-layout: fixed;\n  width: 100%;\n}\n\n.picker-cell {\n  display: table-cell;\n  position: relative;\n}\n\n.picker-cell::before,\n.picker-cell::after {\n  content: '';\n  display: block;\n  left: 0;\n  position: absolute;\n  right: 0;\n  z-index: 3;\n}\n\n.picker-cell::before {\n  background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(0, 0, 0, 0)), to(rgba(0, 0, 0, 0.05)));\n  background-image: linear-gradient(to top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.05));\n  bottom: 50%;\n  margin-bottom: 1rem;\n  top: 0;\n}\n\n.picker-cell::after {\n  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), to(rgba(0, 0, 0, 0.05)));\n  background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.05));\n  bottom: 0;\n  margin-top: 1rem;\n  top: 50%;\n}\n\n.picker-cell + .picker-cell {\n  border-left: 1px solid #eee;\n  border-left: var(--border);\n}\n\n.picker-headers .picker-cell::before {\n  margin-bottom: 0;\n}\n\n.picker-headers .picker-cell::after {\n  margin-top: 2rem;\n}\n\n.picker-single:not(.picker-controls):not(.picker-headers) .picker-cell::before,\n.picker-single:not(.picker-controls):not(.picker-headers) .picker-cell::after {\n  display: none;\n}\n\n.picker-cell__header {\n  color: #999;\n  color: var(--gray);\n  font-size: 0.875rem;\n  font-weight: 500;\n  line-height: 1.5rem;\n  margin: 0;\n  overflow: hidden;\n  padding: 0.25rem 0.5rem;\n  text-align: center;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.picker-cell__control {\n  cursor: pointer;\n  height: 2rem;\n  padding: 0.25rem 0.5rem;\n  position: relative;\n  z-index: 4;\n}\n\n.picker-cell__control::before {\n  border: 0 solid #ccc;\n  content: '';\n  display: block;\n  height: 0.5rem;\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  -webkit-transform: translate(-50%, -50%) rotate(-45deg);\n  -ms-transform: translate(-50%, -50%) rotate(-45deg);\n  transform: translate(-50%, -50%) rotate(-45deg);\n  width: 0.5rem;\n}\n\n.picker-cell__control:hover::before {\n  border-color: var(--primary);\n}\n\n.picker-cell__control--prev::before {\n  border-right-width: 1px;\n  border-top-width: 1px;\n  margin-top: 2px;\n}\n\n.picker-cell__control--next::before {\n  border-bottom-width: 1px;\n  border-left-width: 1px;\n  margin-bottom: 2px;\n}\n\n.picker-cell__body {\n  overflow: hidden;\n  position: relative;\n}\n\n.picker-cell__body::before,\n.picker-cell__body::after {\n  content: '';\n  height: 2rem;\n  left: 0;\n  position: absolute;\n  right: 0;\n  z-index: 1;\n}\n\n.picker-cell__body::before {\n  background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(255, 255, 255, 0)), to(rgba(255, 255, 255, 1)));\n  background-image: linear-gradient(to top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));\n  top: 0;\n}\n\n.picker-cell__body::after {\n  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0)), to(rgba(255, 255, 255, 1)));\n  background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));\n  bottom: 0;\n}\n\n.picker-single .picker-cell__body::before,\n.picker-single .picker-cell__body::after {\n  display: none;\n}\n\n.picker-list {\n  list-style: none;\n  margin: -2rem 0;\n  padding: 0;\n  position: relative;\n}\n\n.picker-item {\n  color: #999;\n  color: var(--gray);\n  padding: 0.25rem 0.5rem;\n  text-align: center;\n  white-space: nowrap;\n}\n\n.picker-picked {\n  color: #0074d9;\n  color: var(--blue);\n  font-size: 1.125em;\n  line-height: 1.5rem;\n}\n\n.picker-footer {\n  border-top: 1px solid #eee;\n  border-top: var(--border);\n  display: none;\n  width: 100%;\n}\n\n.picker-cancel,\n.picker-confirm {\n  background-color: transparent;\n  border-width: 0;\n  cursor: pointer;\n  display: table-cell;\n  font-size: 1rem;\n  padding: 0.75rem 1rem;\n  width: 50%;\n}\n\n.picker-cancel:focus,\n.picker-cancel:hover,\n.picker-confirm:focus,\n.picker-confirm:hover {\n  background-color: #fcfcfc;\n  outline: none;\n}\n\n.picker-confirm {\n  color: #0074d9;\n  color: var(--blue);\n}\n"
  },
  {
    "path": "dist/picker.esm.js",
    "content": "/*!\n * Picker.js v1.2.1\n * https://fengyuanchen.github.io/pickerjs\n *\n * Copyright 2016-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2019-02-18T13:08:12.801Z\n */\n\nfunction _typeof(obj) {\n  if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n    _typeof = function (obj) {\n      return typeof obj;\n    };\n  } else {\n    _typeof = function (obj) {\n      return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n    };\n  }\n\n  return _typeof(obj);\n}\n\nfunction _classCallCheck(instance, Constructor) {\n  if (!(instance instanceof Constructor)) {\n    throw new TypeError(\"Cannot call a class as a function\");\n  }\n}\n\nfunction _defineProperties(target, props) {\n  for (var i = 0; i < props.length; i++) {\n    var descriptor = props[i];\n    descriptor.enumerable = descriptor.enumerable || false;\n    descriptor.configurable = true;\n    if (\"value\" in descriptor) descriptor.writable = true;\n    Object.defineProperty(target, descriptor.key, descriptor);\n  }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n  if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n  if (staticProps) _defineProperties(Constructor, staticProps);\n  return Constructor;\n}\n\nfunction _toConsumableArray(arr) {\n  return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();\n}\n\nfunction _arrayWithoutHoles(arr) {\n  if (Array.isArray(arr)) {\n    for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];\n\n    return arr2;\n  }\n}\n\nfunction _iterableToArray(iter) {\n  if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter);\n}\n\nfunction _nonIterableSpread() {\n  throw new TypeError(\"Invalid attempt to spread non-iterable instance\");\n}\n\nvar DEFAULTS = {\n  // Define the container for putting the picker.\n  container: null,\n  // Indicate whether show the prev and next arrow controls on each column.\n  controls: false,\n  // The initial date. If not present, use the current date.\n  date: null,\n  // The date string format, also as the sorting order for columns.\n  format: 'YYYY-MM-DD HH:mm',\n  // Indicate whether show the column headers.\n  headers: false,\n  // Define the increment for each date / time part.\n  increment: 1,\n  // Enable inline mode.\n  inline: false,\n  // Define the language. (An ISO language code).\n  language: '',\n  // Months' name.\n  months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],\n  // Shorter months' name.\n  monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n  // Define the number of rows for showing.\n  rows: 5,\n  // Define the text of the picker.\n  text: {\n    title: 'Pick a date and time',\n    cancel: 'Cancel',\n    confirm: 'OK',\n    year: 'Year',\n    month: 'Month',\n    day: 'Day',\n    hour: 'Hour',\n    minute: 'Minute',\n    second: 'Second',\n    millisecond: 'Millisecond'\n  },\n  // Translate date / time text.\n  translate: function translate(type, text) {\n    return text;\n  },\n  // Shortcuts of custom events.\n  show: null,\n  shown: null,\n  hide: null,\n  hidden: null,\n  pick: null\n};\n\nvar TEMPLATE = '<div class=\"picker\" data-picker-action=\"hide\" touch-action=\"none\" tabindex=\"-1\" role=\"dialog\">' + '<div class=\"picker-dialog\" role=\"document\">' + '<div class=\"picker-header\">' + '<h4 class=\"picker-title\">{{ title }}</h4>' + '<button type=\"button\" class=\"picker-close\" data-picker-action=\"hide\" aria-label=\"Close\">&times;</button>' + '</div>' + '<div class=\"picker-body\">' + '<div class=\"picker-grid\"></div>' + '</div>' + '<div class=\"picker-footer\">' + '<button type=\"button\" class=\"picker-cancel\" data-picker-action=\"hide\">{{ cancel }}</button>' + '<button type=\"button\" class=\"picker-confirm\" data-picker-action=\"pick\">{{ confirm }}</button>' + '</div>' + '</div>' + '</div>';\n\nvar IS_BROWSER = typeof window !== 'undefined';\nvar WINDOW = IS_BROWSER ? window : {};\nvar IS_TOUCH_DEVICE = IS_BROWSER ? 'ontouchstart' in WINDOW.document.documentElement : false;\nvar HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;\nvar NAMESPACE = 'picker';\nvar LANGUAGES = {}; // Actions\n\nvar ACTION_HIDE = 'hide';\nvar ACTION_NEXT = 'next';\nvar ACTION_PICK = 'pick';\nvar ACTION_PREV = 'prev'; // Classes\n\nvar CLASS_OPEN = \"\".concat(NAMESPACE, \"-open\");\nvar CLASS_OPENED = \"\".concat(NAMESPACE, \"-opened\");\nvar CLASS_PICKED = \"\".concat(NAMESPACE, \"-picked\"); // Data keys\n// Add namespace to avoid to conflict to some other libraries.\n\nvar DATA_ACTION = \"\".concat(NAMESPACE, \"Action\");\nvar DATA_TOKEN = 'token';\nvar DATA_TYPE = 'type';\nvar DATA_NAME = 'name';\nvar DATA_VALUE = 'value'; // Events\n\nvar EVENT_CLICK = 'click';\nvar EVENT_FOCUS = 'focus';\nvar EVENT_HIDDEN = 'hidden';\nvar EVENT_HIDE = 'hide';\nvar EVENT_KEY_DOWN = 'keydown';\nvar EVENT_PICK = 'pick';\nvar EVENT_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown';\nvar EVENT_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'touchmove' : 'mousemove';\nvar EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup';\nvar EVENT_POINTER_DOWN = HAS_POINTER_EVENT ? 'pointerdown' : EVENT_TOUCH_START;\nvar EVENT_POINTER_MOVE = HAS_POINTER_EVENT ? 'pointermove' : EVENT_TOUCH_MOVE;\nvar EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END;\nvar EVENT_SHOW = 'show';\nvar EVENT_SHOWN = 'shown';\nvar EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll';\n\nvar _Object$prototype = Object.prototype,\n    hasOwnProperty = _Object$prototype.hasOwnProperty,\n    toString = _Object$prototype.toString;\n/**\n * Detect the type of the given value.\n * @param {*} value - The value to detect.\n * @returns {string} Returns the type.\n */\n\nfunction typeOf(value) {\n  return toString.call(value).slice(8, -1).toLowerCase();\n}\n/**\n * Check if the given value is a string.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a string, else `false`.\n */\n\nfunction isString(value) {\n  return typeof value === 'string';\n}\n/**\n * Check if the given value is finite.\n */\n\nvar isFinite = Number.isFinite || WINDOW.isFinite;\n/**\n * Check if the given value is not a number.\n */\n\nvar isNaN = Number.isNaN || WINDOW.isNaN;\n/**\n * Check if the given value is a number.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a number, else `false`.\n */\n\nfunction isNumber(value) {\n  return typeof value === 'number' && !isNaN(value);\n}\n/**\n * Check if the given value is an object.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is an object, else `false`.\n */\n\nfunction isObject(value) {\n  return _typeof(value) === 'object' && value !== null;\n}\n/**\n * Check if the given value is a plain object.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a plain object, else `false`.\n */\n\nfunction isPlainObject(value) {\n  if (!isObject(value)) {\n    return false;\n  }\n\n  try {\n    var _constructor = value.constructor;\n    var prototype = _constructor.prototype;\n    return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');\n  } catch (error) {\n    return false;\n  }\n}\n/**\n * Check if the given value is a function.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a function, else `false`.\n */\n\nfunction isFunction(value) {\n  return typeof value === 'function';\n}\n/**\n * Check if the given value is a date.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a date, else `false`.\n */\n\nfunction isDate(value) {\n  return typeOf(value) === 'date';\n}\n/**\n * Check if the given value is a valid date.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a valid date, else `false`.\n */\n\nfunction isValidDate(value) {\n  return isDate(value) && value.toString() !== 'Invalid Date';\n}\n/**\n * Iterate the given data.\n * @param {*} data - The data to iterate.\n * @param {Function} callback - The process function for each element.\n * @returns {*} The original data.\n */\n\nfunction forEach(data, callback) {\n  if (data && isFunction(callback)) {\n    if (Array.isArray(data) || isNumber(data.length)\n    /* array-like */\n    ) {\n        var length = data.length;\n        var i;\n\n        for (i = 0; i < length; i += 1) {\n          if (callback.call(data, data[i], i, data) === false) {\n            break;\n          }\n        }\n      } else if (isObject(data)) {\n      Object.keys(data).forEach(function (key) {\n        callback.call(data, data[key], key, data);\n      });\n    }\n  }\n\n  return data;\n}\n/**\n * Recursively assigns own enumerable properties of source objects to the target object.\n * @param {Object} target - The target object.\n * @param {Object[]} sources - The source objects.\n * @returns {Object} The target object.\n */\n\nfunction deepAssign(target) {\n  for (var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n    sources[_key - 1] = arguments[_key];\n  }\n\n  if (isObject(target) && sources.length > 0) {\n    sources.forEach(function (source) {\n      if (isObject(source)) {\n        Object.keys(source).forEach(function (key) {\n          if (isPlainObject(target[key]) && isPlainObject(source[key])) {\n            target[key] = deepAssign({}, target[key], source[key]);\n          } else {\n            target[key] = source[key];\n          }\n        });\n      }\n    });\n  }\n\n  return target;\n}\n/**\n * Add classes to the given element.\n * @param {Element} element - The target element.\n * @param {string} value - The classes to be added.\n */\n\nfunction addClass(element, value) {\n  if (!value) {\n    return;\n  }\n\n  if (isNumber(element.length)) {\n    forEach(element, function (elem) {\n      addClass(elem, value);\n    });\n    return;\n  }\n\n  if (element.classList) {\n    element.classList.add(value);\n    return;\n  }\n\n  var className = element.className.trim();\n\n  if (!className) {\n    element.className = value;\n  } else if (className.indexOf(value) < 0) {\n    element.className = \"\".concat(className, \" \").concat(value);\n  }\n}\n/**\n * Remove classes from the given element.\n * @param {Element} element - The target element.\n * @param {string} value - The classes to be removed.\n */\n\nfunction removeClass(element, value) {\n  if (!value) {\n    return;\n  }\n\n  if (isNumber(element.length)) {\n    forEach(element, function (elem) {\n      removeClass(elem, value);\n    });\n    return;\n  }\n\n  if (element.classList) {\n    element.classList.remove(value);\n    return;\n  }\n\n  if (element.className.indexOf(value) >= 0) {\n    element.className = element.className.replace(value, '');\n  }\n}\nvar REGEXP_HYPHENATE = /([a-z\\d])([A-Z])/g;\n/**\n * Transform the given string from camelCase to kebab-case\n * @param {string} value - The value to transform.\n * @returns {string} The transformed value.\n */\n\nfunction hyphenate(value) {\n  return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase();\n}\n/**\n * Get data from the given element.\n * @param {Element} element - The target element.\n * @param {string} name - The data key to get.\n * @returns {string} The data value.\n */\n\nfunction getData(element, name) {\n  if (isObject(element[name])) {\n    return element[name];\n  }\n\n  if (element.dataset) {\n    return element.dataset[name];\n  }\n\n  return element.getAttribute(\"data-\".concat(hyphenate(name)));\n}\n/**\n * Set data to the given element.\n * @param {Element} element - The target element.\n * @param {string} name - The data key to set.\n * @param {string} data - The data value.\n */\n\nfunction setData(element, name, data) {\n  if (isObject(data)) {\n    element[name] = data;\n  } else if (element.dataset) {\n    element.dataset[name] = data;\n  } else {\n    element.setAttribute(\"data-\".concat(hyphenate(name)), data);\n  }\n}\n/**\n * Remove data from the given element.\n * @param {Element} element - The target element.\n * @param {string} name - The data key to remove.\n */\n\nfunction removeData(element, name) {\n  if (isObject(element[name])) {\n    try {\n      delete element[name];\n    } catch (error) {\n      element[name] = undefined;\n    }\n  } else if (element.dataset) {\n    // #128 Safari not allows to delete dataset property\n    try {\n      delete element.dataset[name];\n    } catch (error) {\n      element.dataset[name] = undefined;\n    }\n  } else {\n    element.removeAttribute(\"data-\".concat(hyphenate(name)));\n  }\n}\nvar REGEXP_SPACES = /\\s\\s*/;\n\nvar onceSupported = function () {\n  var supported = false;\n\n  if (IS_BROWSER) {\n    var once = false;\n\n    var listener = function listener() {};\n\n    var options = Object.defineProperty({}, 'once', {\n      get: function get() {\n        supported = true;\n        return once;\n      },\n\n      /**\n       * This setter can fix a `TypeError` in strict mode\n       * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}\n       * @param {boolean} value - The value to set\n       */\n      set: function set(value) {\n        once = value;\n      }\n    });\n    WINDOW.addEventListener('test', listener, options);\n    WINDOW.removeEventListener('test', listener, options);\n  }\n\n  return supported;\n}();\n/**\n * Remove event listener from the target element.\n * @param {Element} element - The event target.\n * @param {string} type - The event type(s).\n * @param {Function} listener - The event listener.\n * @param {Object} options - The event options.\n */\n\n\nfunction removeListener(element, type, listener) {\n  var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n  var handler = listener;\n  type.trim().split(REGEXP_SPACES).forEach(function (event) {\n    if (!onceSupported) {\n      var listeners = element.listeners;\n\n      if (listeners && listeners[event] && listeners[event][listener]) {\n        handler = listeners[event][listener];\n        delete listeners[event][listener];\n\n        if (Object.keys(listeners[event]).length === 0) {\n          delete listeners[event];\n        }\n\n        if (Object.keys(listeners).length === 0) {\n          delete element.listeners;\n        }\n      }\n    }\n\n    element.removeEventListener(event, handler, options);\n  });\n}\n/**\n * Add event listener to the target element.\n * @param {Element} element - The event target.\n * @param {string} type - The event type(s).\n * @param {Function} listener - The event listener.\n * @param {Object} options - The event options.\n */\n\nfunction addListener(element, type, listener) {\n  var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n  var _handler = listener;\n  type.trim().split(REGEXP_SPACES).forEach(function (event) {\n    if (options.once && !onceSupported) {\n      var _element$listeners = element.listeners,\n          listeners = _element$listeners === void 0 ? {} : _element$listeners;\n\n      _handler = function handler() {\n        delete listeners[event][listener];\n        element.removeEventListener(event, _handler, options);\n\n        for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n          args[_key2] = arguments[_key2];\n        }\n\n        listener.apply(element, args);\n      };\n\n      if (!listeners[event]) {\n        listeners[event] = {};\n      }\n\n      if (listeners[event][listener]) {\n        element.removeEventListener(event, listeners[event][listener], options);\n      }\n\n      listeners[event][listener] = _handler;\n      element.listeners = listeners;\n    }\n\n    element.addEventListener(event, _handler, options);\n  });\n}\n/**\n * Dispatch event on the target element.\n * @param {Element} element - The event target.\n * @param {string} type - The event type(s).\n * @param {Object} data - The additional event data.\n * @returns {boolean} Indicate if the event is default prevented or not.\n */\n\nfunction dispatchEvent(element, type, data) {\n  var event; // Event and CustomEvent on IE9-11 are global objects, not constructors\n\n  if (isFunction(Event) && isFunction(CustomEvent)) {\n    event = new CustomEvent(type, {\n      detail: data,\n      bubbles: true,\n      cancelable: true\n    });\n  } else {\n    event = document.createEvent('CustomEvent');\n    event.initCustomEvent(type, true, true, data);\n  }\n\n  return element.dispatchEvent(event);\n}\n/**\n * Check if the given year is a leap year.\n * @param {number} year - The year to check.\n * @returns {boolean} Returns `true` if the given year is a leap year, else `false`.\n */\n\nfunction isLeapYear(year) {\n  return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;\n}\n/**\n * Get days number of the given month.\n * @param {number} year - The target year.\n * @param {number} month - The target month.\n * @returns {number} Returns days number.\n */\n\nfunction getDaysInMonth(year, month) {\n  return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];\n}\n/**\n * Add leading zeroes to the given value\n * @param {number} value - The value to add.\n * @param {number} [length=1] - The number of the leading zeroes.\n * @returns {string} Returns converted value.\n */\n\nfunction addLeadingZero(value) {\n  var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n  var str = String(Math.abs(value));\n  var i = str.length;\n  var result = '';\n\n  if (value < 0) {\n    result += '-';\n  }\n\n  while (i < length) {\n    i += 1;\n    result += '0';\n  }\n\n  return result + str;\n}\n/**\n * Map token to type name\n * @param {string} token - The token to map.\n * @returns {string} Returns mapped type name.\n */\n\nfunction tokenToType(token) {\n  return {\n    Y: 'year',\n    M: 'month',\n    D: 'day',\n    H: 'hour',\n    m: 'minute',\n    s: 'second',\n    S: 'millisecond'\n  }[token.charAt(0)];\n}\nvar REGEXP_TOKENS = /(Y|M|D|H|m|s|S)\\1*/g;\n/**\n * Parse date format.\n * @param {string} format - The format to parse.\n * @returns {Object} Returns parsed format data.\n */\n\nfunction parseFormat(format) {\n  var tokens = format.match(REGEXP_TOKENS);\n\n  if (!tokens) {\n    throw new Error('Invalid format.');\n  } // Remove duplicate tokens (#22)\n\n\n  tokens = tokens.filter(function (token, index) {\n    return tokens.indexOf(token) === index;\n  });\n  var result = {\n    tokens: tokens\n  };\n  tokens.forEach(function (token) {\n    result[tokenToType(token)] = token;\n  });\n  return result;\n}\n\nvar events = {\n  bind: function bind() {\n    var element = this.element,\n        options = this.options,\n        grid = this.grid;\n\n    if (isFunction(options.show)) {\n      addListener(element, EVENT_SHOW, options.show);\n    }\n\n    if (isFunction(options.shown)) {\n      addListener(element, EVENT_SHOWN, options.shown);\n    }\n\n    if (isFunction(options.hide)) {\n      addListener(element, EVENT_HIDE, options.hide);\n    }\n\n    if (isFunction(options.hidden)) {\n      addListener(element, EVENT_HIDDEN, options.hidden);\n    }\n\n    if (isFunction(options.pick)) {\n      addListener(element, EVENT_PICK, options.pick);\n    }\n\n    addListener(element, EVENT_FOCUS, this.onFocus = this.focus.bind(this));\n    addListener(element, EVENT_CLICK, this.onFocus);\n    addListener(this.picker, EVENT_CLICK, this.onClick = this.click.bind(this));\n    addListener(grid, EVENT_WHEEL, this.onWheel = this.wheel.bind(this));\n    addListener(grid, EVENT_POINTER_DOWN, this.onPointerDown = this.pointerdown.bind(this));\n    addListener(document, EVENT_POINTER_MOVE, this.onPointerMove = this.pointermove.bind(this));\n    addListener(document, EVENT_POINTER_UP, this.onPointerUp = this.pointerup.bind(this));\n    addListener(document, EVENT_KEY_DOWN, this.onKeyDown = this.keydown.bind(this));\n  },\n  unbind: function unbind() {\n    var element = this.element,\n        options = this.options,\n        grid = this.grid;\n\n    if (isFunction(options.show)) {\n      removeListener(element, EVENT_SHOW, options.show);\n    }\n\n    if (isFunction(options.shown)) {\n      removeListener(element, EVENT_SHOWN, options.shown);\n    }\n\n    if (isFunction(options.hide)) {\n      removeListener(element, EVENT_HIDE, options.hide);\n    }\n\n    if (isFunction(options.hidden)) {\n      removeListener(element, EVENT_HIDDEN, options.hidden);\n    }\n\n    if (isFunction(options.pick)) {\n      removeListener(element, EVENT_PICK, options.pick);\n    }\n\n    removeListener(element, EVENT_FOCUS, this.onFocus);\n    removeListener(element, EVENT_CLICK, this.onFocus);\n    removeListener(this.picker, EVENT_CLICK, this.onClick);\n    removeListener(grid, EVENT_WHEEL, this.onWheel);\n    removeListener(grid, EVENT_POINTER_DOWN, this.onPointerDown);\n    removeListener(document, EVENT_POINTER_MOVE, this.onPointerMove);\n    removeListener(document, EVENT_POINTER_UP, this.onPointerUp);\n    removeListener(document, EVENT_KEY_DOWN, this.onKeyDown);\n  }\n};\n\nvar handlers = {\n  focus: function focus(event) {\n    event.target.blur();\n    this.show();\n  },\n  click: function click(event) {\n    var target = event.target;\n    var action = getData(target, DATA_ACTION);\n\n    switch (action) {\n      case ACTION_HIDE:\n        this.hide();\n        break;\n\n      case ACTION_PICK:\n        this.pick();\n        break;\n\n      case ACTION_PREV:\n      case ACTION_NEXT:\n        this[action](getData(target.parentElement, DATA_TYPE));\n        break;\n\n      default:\n    }\n  },\n  wheel: function wheel(event) {\n    var target = event.target;\n\n    if (target === this.grid) {\n      return;\n    }\n\n    event.preventDefault();\n\n    while (target.parentElement && target.parentElement !== this.grid) {\n      target = target.parentElement;\n    }\n\n    var type = getData(target, DATA_TYPE);\n\n    if (event.deltaY < 0) {\n      this.prev(type);\n    } else {\n      this.next(type);\n    }\n  },\n  pointerdown: function pointerdown(event) {\n    var target = event.target;\n\n    if (target === this.grid || getData(target, DATA_ACTION)) {\n      return;\n    } // This line is required for preventing page scrolling in iOS browsers\n\n\n    event.preventDefault();\n\n    while (target.parentElement && target.parentElement !== this.grid) {\n      target = target.parentElement;\n    }\n\n    var list = target.querySelector(\".\".concat(NAMESPACE, \"-list\"));\n    var itemHeight = list.firstElementChild.offsetHeight;\n    this.cell = {\n      elem: target,\n      list: list,\n      moveY: 0,\n      maxMoveY: itemHeight,\n      minMoveY: itemHeight / 2,\n      startY: event.changedTouches ? event.changedTouches[0].pageY : event.pageY,\n      type: getData(target, DATA_TYPE)\n    };\n  },\n  pointermove: function pointermove(event) {\n    var cell = this.cell;\n\n    if (!cell) {\n      return;\n    }\n\n    event.preventDefault();\n    var endY = event.changedTouches ? event.changedTouches[0].pageY : event.pageY;\n    var moveY = cell.moveY + (endY - cell.startY);\n    cell.startY = endY;\n    cell.moveY = moveY;\n\n    if (Math.abs(moveY) < cell.maxMoveY) {\n      cell.list.style.top = \"\".concat(moveY, \"px\");\n      return;\n    }\n\n    cell.list.style.top = 0;\n    cell.moveY = 0;\n\n    if (moveY >= cell.maxMoveY) {\n      this.prev(cell.type);\n    } else if (moveY <= -cell.maxMoveY) {\n      this.next(cell.type);\n    }\n  },\n  pointerup: function pointerup(event) {\n    var cell = this.cell;\n\n    if (!cell) {\n      return;\n    }\n\n    event.preventDefault();\n    cell.list.style.top = 0;\n\n    if (cell.moveY >= cell.minMoveY) {\n      this.prev(cell.type);\n    } else if (cell.moveY <= -cell.minMoveY) {\n      this.next(cell.type);\n    }\n\n    this.cell = null;\n  },\n  keydown: function keydown(event) {\n    if (this.shown && (event.key === 'Escape' || event.keyCode === 27)) {\n      this.hide();\n    }\n  }\n};\n\nvar helpers = {\n  render: function render(type) {\n    var _this = this;\n\n    if (!type) {\n      this.format.tokens.forEach(function (token) {\n        return _this.render(tokenToType(token));\n      });\n      return;\n    }\n\n    var options = this.options;\n    var data = this.data[type];\n    var current = this.current(type);\n    var max = isFunction(data.max) ? data.max() : data.max;\n    var min = isFunction(data.min) ? data.min() : data.min;\n    var base = 0;\n\n    if (isFinite(max)) {\n      base = min > 0 ? max : max + 1;\n    }\n\n    data.list.innerHTML = '';\n    data.current = current;\n\n    for (var i = 0; i < options.rows + 2; i += 1) {\n      var item = document.createElement('li');\n      var position = i - data.index;\n      var newValue = current + position * data.increment;\n\n      if (base) {\n        newValue %= base;\n\n        if (newValue < min) {\n          newValue += base;\n        }\n      }\n\n      item.textContent = options.translate(type, data.aliases ? data.aliases[newValue] : addLeadingZero(newValue + data.offset, data.digit));\n      setData(item, DATA_NAME, type);\n      setData(item, DATA_VALUE, newValue);\n      addClass(item, \"\".concat(NAMESPACE, \"-item\"));\n\n      if (position === 0) {\n        addClass(item, CLASS_PICKED);\n        data.item = item;\n      }\n\n      data.list.appendChild(item);\n    }\n  },\n  current: function current(type, value) {\n    var date = this.date;\n    var format = this.format;\n    var token = format[type];\n\n    switch (token.charAt(0)) {\n      case 'Y':\n        if (isNumber(value)) {\n          date.setFullYear(token.length === 2 ? 2000 + value : value);\n\n          if (format.month) {\n            this.render(tokenToType(format.month));\n          }\n\n          if (format.day) {\n            this.render(tokenToType(format.day));\n          }\n        }\n\n        return date.getFullYear();\n\n      case 'M':\n        if (isNumber(value)) {\n          date.setMonth(value, // The current day should not exceed its maximum day in current month\n          Math.min(date.getDate(), getDaysInMonth(date.getFullYear(), value)));\n\n          if (format.day) {\n            this.render(tokenToType(format.day));\n          }\n        }\n\n        return date.getMonth();\n\n      case 'D':\n        if (isNumber(value)) {\n          date.setDate(value);\n        }\n\n        return date.getDate();\n\n      case 'H':\n        if (isNumber(value)) {\n          date.setHours(value);\n        }\n\n        return date.getHours();\n\n      case 'm':\n        if (isNumber(value)) {\n          date.setMinutes(value);\n        }\n\n        return date.getMinutes();\n\n      case 's':\n        if (isNumber(value)) {\n          date.setSeconds(value);\n        }\n\n        return date.getSeconds();\n\n      case 'S':\n        if (isNumber(value)) {\n          date.setMilliseconds(value);\n        }\n\n        return date.getMilliseconds();\n\n      default:\n    }\n\n    return date;\n  },\n  getValue: function getValue() {\n    var element = this.element;\n    return this.isInput ? element.value : element.textContent;\n  },\n  setValue: function setValue(value) {\n    var element = this.element;\n\n    if (this.isInput) {\n      element.value = value;\n    } else if (this.options.container) {\n      element.textContent = value;\n    }\n  },\n  open: function open() {\n    var body = this.body;\n    body.style.overflow = 'hidden';\n    body.style.paddingRight = \"\".concat(this.scrollBarWidth + (parseFloat(this.initialBodyPaddingRight) || 0), \"px\");\n  },\n  close: function close() {\n    var body = this.body;\n    body.style.overflow = '';\n    body.style.paddingRight = this.initialBodyPaddingRight;\n  }\n};\n\nvar methods = {\n  /**\n   * Show the picker.\n   * @param {boolean} [immediate=false] - Indicate if show the picker immediately or not.\n   * @returns {Picker} this\n   */\n  show: function show() {\n    var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n    var element = this.element,\n        picker = this.picker;\n\n    if (this.inline || this.shown) {\n      return this;\n    }\n\n    if (dispatchEvent(element, EVENT_SHOW) === false) {\n      return this;\n    }\n\n    this.shown = true;\n    this.open();\n    addClass(picker, CLASS_OPEN);\n\n    var done = function done() {\n      dispatchEvent(element, EVENT_SHOWN);\n    };\n\n    if (!immediate) {\n      // Reflow to enable transition\n      // eslint-disable-next-line\n      picker.offsetWidth;\n    }\n\n    addClass(picker, CLASS_OPENED);\n\n    if (immediate) {\n      done();\n    } else {\n      setTimeout(done, 300);\n    }\n\n    return this;\n  },\n\n  /**\n   * Hide the picker.\n   * @param {boolean} [immediate=false] - Indicate if hide the picker immediately or not.\n   * @returns {Picker} this\n   */\n  hide: function hide() {\n    var _this = this;\n\n    var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n    var element = this.element,\n        picker = this.picker;\n\n    if (this.inline || !this.shown) {\n      return this;\n    }\n\n    if (dispatchEvent(element, EVENT_HIDE) === false) {\n      return this;\n    }\n\n    this.shown = false;\n    removeClass(picker, CLASS_OPENED);\n\n    var done = function done() {\n      _this.close();\n\n      removeClass(picker, CLASS_OPEN);\n      dispatchEvent(element, EVENT_HIDDEN);\n    };\n\n    if (immediate) {\n      done();\n    } else {\n      setTimeout(done, 300);\n    }\n\n    return this;\n  },\n\n  /**\n   * Pick to the previous item.\n   * @param {string} type - The column type.\n   * @returns {Picker} this\n   */\n  prev: function prev(type) {\n    var options = this.options;\n    var token = this.format[type];\n    var data = this.data[type];\n    var list = data.list;\n    var item = list.lastElementChild;\n    var max = isFunction(data.max) ? data.max() : data.max;\n    var min = isFunction(data.min) ? data.min() : data.min;\n    var prev = data.item.previousElementSibling;\n    var value = Number(getData(list.firstElementChild, DATA_VALUE)) - data.increment;\n\n    if (value < min) {\n      value += max - min + 1;\n    }\n\n    item.textContent = options.translate(type, data.aliases ? data.aliases[value] : addLeadingZero(value + data.offset, token.length));\n    setData(item, DATA_VALUE, value);\n\n    if (prev) {\n      removeClass(data.item, CLASS_PICKED);\n      addClass(prev, CLASS_PICKED);\n      data.item = prev;\n    }\n\n    list.insertBefore(item, list.firstElementChild);\n    data.current = Number(getData(data.item, DATA_VALUE));\n    this.current(type, data.current);\n\n    if (this.inline && options.container) {\n      this.pick();\n    }\n\n    return this;\n  },\n\n  /**\n   * Pick to the next item.\n   * @param {String} type - The column type.\n   * @returns {Picker} this\n   */\n  next: function next(type) {\n    var options = this.options;\n    var token = this.format[type];\n    var data = this.data[type];\n    var list = data.list;\n    var item = list.firstElementChild;\n    var max = isFunction(data.max) ? data.max() : data.max;\n    var min = isFunction(data.min) ? data.min() : data.min;\n    var next = data.item.nextElementSibling;\n    var value = Number(getData(list.lastElementChild, DATA_VALUE)) + data.increment;\n\n    if (value > max) {\n      value -= max - min + 1;\n    }\n\n    item.textContent = options.translate(type, data.aliases ? data.aliases[value] : addLeadingZero(value + data.offset, token.length));\n    setData(item, DATA_VALUE, value);\n    list.appendChild(item);\n\n    if (next) {\n      removeClass(data.item, CLASS_PICKED);\n      addClass(next, CLASS_PICKED);\n      data.item = next;\n    }\n\n    data.current = Number(getData(data.item, DATA_VALUE));\n    this.current(type, data.current);\n\n    if (this.inline && options.container) {\n      this.pick();\n    }\n\n    return this;\n  },\n  // Pick the current date to the target element.\n  pick: function pick() {\n    var element = this.element;\n\n    if (dispatchEvent(element, EVENT_PICK) === false) {\n      return this;\n    }\n\n    var value = this.formatDate(this.date);\n    this.setValue(value);\n\n    if (this.isInput && dispatchEvent(element, 'change') === false) {\n      this.reset();\n    }\n\n    this.hide();\n    return this;\n  },\n\n  /**\n   * Get the current date.\n   * @param {boolean} [formatted=false] - Indicate if format the date or not.\n   * @return {Date|string} The output date.\n   */\n  getDate: function getDate() {\n    var formatted = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n    var date = this.date;\n    return formatted ? this.formatDate(date) : new Date(date);\n  },\n\n  /**\n   * Override the current date with a new date.\n   * @param {Date|string} date - The date to set.\n   * @returns {Picker} this\n   */\n  setDate: function setDate(date) {\n    if (date) {\n      this.date = this.parseDate(date);\n      this.render();\n    }\n\n    return this;\n  },\n  // Update the picker with the current element value / text.\n  update: function update() {\n    this.date = this.parseDate(this.getValue());\n    this.render();\n    return this;\n  },\n  // Reset the picker and element value / text.\n  reset: function reset() {\n    this.setValue(this.initialValue);\n    this.date = new Date(this.initialDate);\n    this.render();\n    return this;\n  },\n\n  /**\n   * Parse a date with the set date format.\n   * @param {Date|string} date - The date to parse.\n   * @returns {Date} The parsed date object.\n   */\n  parseDate: function parseDate(date) {\n    var options = this.options,\n        format = this.format;\n    var digits = [];\n\n    if (isDate(date)) {\n      return new Date(date);\n    }\n\n    if (isString(date)) {\n      var groups = [].concat(_toConsumableArray(options.months), _toConsumableArray(options.monthsShort), ['\\\\d+']);\n      digits = date.match(new RegExp(\"(\".concat(groups.join('|'), \")\"), 'g')); // Parse `11111111` (YYYYMMDD) to ['1111', '11', '11']\n\n      if (digits && date.length === options.format.length && digits.length !== format.tokens.length) {\n        digits = format.tokens.map(function (token) {\n          return date.substr(options.format.indexOf(token), token.length);\n        });\n      }\n\n      if (!digits || digits.length !== format.tokens.length) {\n        return new Date();\n      }\n    }\n\n    var parsedDate = new Date();\n    digits.forEach(function (digit, i) {\n      var token = format.tokens[i];\n      var n = Number(digit);\n\n      switch (token) {\n        case 'YYYY':\n        case 'YYY':\n        case 'Y':\n          {\n            var index = date.indexOf(digit);\n            var isHyphen = date.substr(index - 1, 1) === '-';\n            var isBC = index > 1 && isHyphen && /\\S/.test(date.substr(index - 2, 1)) || index === 1 && isHyphen;\n            parsedDate.setFullYear(isBC ? -n : n);\n            break;\n          }\n\n        case 'YY':\n          parsedDate.setFullYear(2000 + n);\n          break;\n\n        case 'MMMM':\n          parsedDate.setMonth(options.months.indexOf(digit));\n          break;\n\n        case 'MMM':\n          parsedDate.setMonth(options.monthsShort.indexOf(digit));\n          break;\n\n        case 'MM':\n        case 'M':\n          parsedDate.setMonth(n - 1);\n          break;\n\n        case 'DD':\n        case 'D':\n          parsedDate.setDate(n);\n          break;\n\n        case 'HH':\n        case 'H':\n          parsedDate.setHours(n);\n          break;\n\n        case 'mm':\n        case 'm':\n          parsedDate.setMinutes(n);\n          break;\n\n        case 'ss':\n        case 's':\n          parsedDate.setSeconds(n);\n          break;\n\n        case 'SSS':\n        case 'SS':\n        case 'S':\n          parsedDate.setMilliseconds(n);\n          break;\n\n        default:\n      }\n    });\n    return parsedDate;\n  },\n\n  /**\n   * Format a date object to a string with the set date format.\n   * @param {Date} date - The date to format.\n   * @return {string} THe formatted date.\n   */\n  formatDate: function formatDate(date) {\n    var options = this.options,\n        format = this.format;\n    var formatted = '';\n\n    if (isValidDate(date)) {\n      var year = date.getFullYear();\n      var month = date.getMonth();\n      var day = date.getDate();\n      var hours = date.getHours();\n      var minutes = date.getMinutes();\n      var seconds = date.getSeconds();\n      var milliseconds = date.getMilliseconds();\n      formatted = options.format;\n      format.tokens.forEach(function (token) {\n        var replacement = '';\n\n        switch (token) {\n          case 'YYYY':\n          case 'YYY':\n          case 'Y':\n            replacement = addLeadingZero(year, token.length);\n            break;\n\n          case 'YY':\n            replacement = addLeadingZero(year % 100, 2);\n            break;\n\n          case 'MMMM':\n            replacement = options.months[month];\n            break;\n\n          case 'MMM':\n            replacement = options.monthsShort[month];\n            break;\n\n          case 'MM':\n          case 'M':\n            replacement = addLeadingZero(month + 1, token.length);\n            break;\n\n          case 'DD':\n          case 'D':\n            replacement = addLeadingZero(day, token.length);\n            break;\n\n          case 'HH':\n          case 'H':\n            replacement = addLeadingZero(hours, token.length);\n            break;\n\n          case 'mm':\n          case 'm':\n            replacement = addLeadingZero(minutes, token.length);\n            break;\n\n          case 'ss':\n          case 's':\n            replacement = addLeadingZero(seconds, token.length);\n            break;\n\n          case 'SSS':\n          case 'SS':\n          case 'S':\n            replacement = addLeadingZero(milliseconds, token.length);\n            break;\n\n          default:\n        }\n\n        formatted = formatted.replace(token, replacement);\n      });\n    }\n\n    return formatted;\n  },\n  // Destroy the picker and remove the instance from the target element.\n  destroy: function destroy() {\n    var element = this.element,\n        picker = this.picker;\n\n    if (!getData(element, NAMESPACE)) {\n      return this;\n    }\n\n    this.hide(true);\n    this.unbind();\n    removeData(element, NAMESPACE);\n    picker.parentNode.removeChild(picker);\n    return this;\n  }\n};\n\nvar REGEXP_DELIMITER = /\\{\\{\\s*(\\w+)\\s*\\}\\}/g;\nvar REGEXP_INPUTS = /input|textarea/i;\nvar AnotherPicker = WINDOW.Picker;\n\nvar Picker =\n/*#__PURE__*/\nfunction () {\n  /**\n   * Create a new Picker.\n   * @param {Element} element - The target element for picking.\n   * @param {Object} [options={}] - The configuration options.\n   */\n  function Picker(element) {\n    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n    _classCallCheck(this, Picker);\n\n    if (!element || element.nodeType !== 1) {\n      throw new Error('The first argument is required and must be an element.');\n    }\n\n    this.element = element;\n    this.options = deepAssign({}, DEFAULTS, LANGUAGES[options.language], isPlainObject(options) && options);\n    this.shown = false;\n    this.init();\n  }\n\n  _createClass(Picker, [{\n    key: \"init\",\n    value: function init() {\n      var _this = this;\n\n      var element = this.element;\n\n      if (getData(element, NAMESPACE)) {\n        return;\n      }\n\n      setData(element, NAMESPACE, this);\n      var options = this.options;\n      var isInput = REGEXP_INPUTS.test(element.tagName);\n      var inline = options.inline && (options.container || !isInput);\n      var template = document.createElement('div');\n      template.insertAdjacentHTML('afterbegin', TEMPLATE.replace(REGEXP_DELIMITER, function () {\n        for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n          args[_key] = arguments[_key];\n        }\n\n        return options.text[args[1]];\n      }));\n      var picker = template.getElementsByClassName(NAMESPACE)[0];\n      var grid = picker.getElementsByClassName(\"\".concat(NAMESPACE, \"-grid\"))[0];\n      var container = options.container;\n\n      if (isString(container)) {\n        container = document.querySelector(container);\n      }\n\n      if (inline) {\n        addClass(picker, CLASS_OPEN);\n        addClass(picker, CLASS_OPENED);\n\n        if (!container) {\n          container = element;\n        }\n      } else {\n        var ownerDocument = element.ownerDocument;\n        var body = ownerDocument.body || ownerDocument.documentElement;\n        this.body = body;\n        this.scrollBarWidth = WINDOW.innerWidth - ownerDocument.documentElement.clientWidth;\n        this.initialBodyPaddingRight = WINDOW.getComputedStyle(body).paddingRight;\n        addClass(picker, \"\".concat(NAMESPACE, \"-fixed\"));\n\n        if (!container) {\n          container = document.body;\n        }\n      }\n\n      this.isInput = isInput;\n      this.inline = inline;\n      this.container = container;\n      this.picker = picker;\n      this.grid = grid;\n      this.cell = null;\n      this.format = parseFormat(options.format);\n      var initialValue = this.getValue();\n      var date = this.parseDate(options.date || initialValue);\n      this.date = date;\n      this.initialDate = new Date(date);\n      this.initialValue = initialValue;\n      this.data = {};\n      var rows = Number(options.rows);\n\n      if (!(rows % 2)) {\n        rows += 1;\n      }\n\n      options.rows = rows || 5;\n      addClass(grid, \"\".concat(NAMESPACE, \"-\").concat(options.rows > 1 ? 'multiple' : 'single'));\n\n      if (options.controls) {\n        addClass(grid, \"\".concat(NAMESPACE, \"-controls\"));\n      }\n\n      var headers = options.headers,\n          increment = options.increment;\n\n      if (headers) {\n        addClass(grid, \"\".concat(NAMESPACE, \"-headers\")); // TODO: Drop the `headers` option's object support in v2.\n\n        headers = isPlainObject(headers) ? headers : options.text;\n      }\n\n      if (!isPlainObject(increment)) {\n        increment = {\n          year: increment,\n          month: increment,\n          day: increment,\n          hour: increment,\n          minute: increment,\n          second: increment,\n          millisecond: increment\n        };\n      }\n\n      this.format.tokens.forEach(function (token) {\n        var type = tokenToType(token);\n        var cell = document.createElement('div');\n        var cellBody = document.createElement('div');\n        var list = document.createElement('ul');\n        var data = {\n          digit: token.length,\n          increment: Math.abs(Number(increment[type])) || 1,\n          list: list,\n          max: Infinity,\n          min: -Infinity,\n          index: Math.floor((options.rows + 2) / 2),\n          offset: 0\n        };\n\n        switch (token.charAt(0)) {\n          case 'Y':\n            if (data.digit === 2) {\n              data.max = 99;\n              data.min = 0;\n            }\n\n            break;\n\n          case 'M':\n            data.max = 11;\n            data.min = 0;\n            data.offset = 1;\n\n            if (data.digit === 3) {\n              data.aliases = options.monthsShort;\n            } else if (data.digit === 4) {\n              data.aliases = options.months;\n            }\n\n            break;\n\n          case 'D':\n            // XXX: Use the latest date to calculate the max day (#23)\n            data.max = function () {\n              return getDaysInMonth(_this.date.getFullYear(), _this.date.getMonth());\n            };\n\n            data.min = 1;\n            break;\n\n          case 'H':\n            data.max = 23;\n            data.min = 0;\n            break;\n\n          case 'm':\n            data.max = 59;\n            data.min = 0;\n            break;\n\n          case 's':\n            data.max = 59;\n            data.min = 0;\n            break;\n\n          case 'S':\n            data.max = 999;\n            data.min = 0;\n            break;\n\n          default:\n        }\n\n        setData(cell, DATA_TYPE, type);\n        setData(cell, DATA_TOKEN, token);\n\n        if (headers) {\n          var cellHeader = document.createElement('div');\n          addClass(cellHeader, \"\".concat(NAMESPACE, \"-cell__header\"));\n          cellHeader.textContent = headers[type] || type[0].toUpperCase() + type.substr(1);\n          cell.appendChild(cellHeader);\n        }\n\n        if (options.controls) {\n          var prev = document.createElement('div');\n          addClass(prev, \"\".concat(NAMESPACE, \"-cell__control\"));\n          addClass(prev, \"\".concat(NAMESPACE, \"-cell__control--prev\"));\n          setData(prev, DATA_ACTION, ACTION_PREV);\n          cell.appendChild(prev);\n        }\n\n        addClass(list, \"\".concat(NAMESPACE, \"-list\"));\n        addClass(cellBody, \"\".concat(NAMESPACE, \"-cell__body\"));\n        addClass(cell, \"\".concat(NAMESPACE, \"-cell\"));\n        addClass(cell, \"\".concat(NAMESPACE, \"-\").concat(type, \"s\"));\n        cellBody.appendChild(list);\n        cell.appendChild(cellBody);\n\n        if (options.controls) {\n          var next = document.createElement('div');\n          addClass(next, \"\".concat(NAMESPACE, \"-cell__control\"));\n          addClass(next, \"\".concat(NAMESPACE, \"-cell__control--next\"));\n          setData(next, DATA_ACTION, ACTION_NEXT);\n          cell.appendChild(next);\n        }\n\n        grid.appendChild(cell);\n        _this.data[type] = data;\n\n        _this.render(type);\n      });\n\n      if (inline) {\n        container.innerHTML = '';\n      }\n\n      container.appendChild(picker);\n      this.bind();\n    }\n    /**\n     * Get the no conflict picker class.\n     * @returns {Picker} The picker class.\n     */\n\n  }], [{\n    key: \"noConflict\",\n    value: function noConflict() {\n      WINDOW.Picker = AnotherPicker;\n      return Picker;\n    }\n    /**\n     * Change the default options.\n     * @param {Object} options - The new default options.\n     */\n\n  }, {\n    key: \"setDefaults\",\n    value: function setDefaults(options) {\n      deepAssign(DEFAULTS, LANGUAGES[options.language], isPlainObject(options) && options);\n    }\n  }]);\n\n  return Picker;\n}();\n\ndeepAssign(Picker.prototype, events, handlers, helpers, methods);\nPicker.languages = LANGUAGES;\n\nexport default Picker;\n"
  },
  {
    "path": "dist/picker.js",
    "content": "/*!\n * Picker.js v1.2.1\n * https://fengyuanchen.github.io/pickerjs\n *\n * Copyright 2016-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2019-02-18T13:08:12.801Z\n */\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) :\n  (global = global || self, global.Picker = factory());\n}(this, function () { 'use strict';\n\n  function _typeof(obj) {\n    if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n      _typeof = function (obj) {\n        return typeof obj;\n      };\n    } else {\n      _typeof = function (obj) {\n        return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n      };\n    }\n\n    return _typeof(obj);\n  }\n\n  function _classCallCheck(instance, Constructor) {\n    if (!(instance instanceof Constructor)) {\n      throw new TypeError(\"Cannot call a class as a function\");\n    }\n  }\n\n  function _defineProperties(target, props) {\n    for (var i = 0; i < props.length; i++) {\n      var descriptor = props[i];\n      descriptor.enumerable = descriptor.enumerable || false;\n      descriptor.configurable = true;\n      if (\"value\" in descriptor) descriptor.writable = true;\n      Object.defineProperty(target, descriptor.key, descriptor);\n    }\n  }\n\n  function _createClass(Constructor, protoProps, staticProps) {\n    if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n    if (staticProps) _defineProperties(Constructor, staticProps);\n    return Constructor;\n  }\n\n  function _toConsumableArray(arr) {\n    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();\n  }\n\n  function _arrayWithoutHoles(arr) {\n    if (Array.isArray(arr)) {\n      for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];\n\n      return arr2;\n    }\n  }\n\n  function _iterableToArray(iter) {\n    if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter);\n  }\n\n  function _nonIterableSpread() {\n    throw new TypeError(\"Invalid attempt to spread non-iterable instance\");\n  }\n\n  var DEFAULTS = {\n    // Define the container for putting the picker.\n    container: null,\n    // Indicate whether show the prev and next arrow controls on each column.\n    controls: false,\n    // The initial date. If not present, use the current date.\n    date: null,\n    // The date string format, also as the sorting order for columns.\n    format: 'YYYY-MM-DD HH:mm',\n    // Indicate whether show the column headers.\n    headers: false,\n    // Define the increment for each date / time part.\n    increment: 1,\n    // Enable inline mode.\n    inline: false,\n    // Define the language. (An ISO language code).\n    language: '',\n    // Months' name.\n    months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],\n    // Shorter months' name.\n    monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n    // Define the number of rows for showing.\n    rows: 5,\n    // Define the text of the picker.\n    text: {\n      title: 'Pick a date and time',\n      cancel: 'Cancel',\n      confirm: 'OK',\n      year: 'Year',\n      month: 'Month',\n      day: 'Day',\n      hour: 'Hour',\n      minute: 'Minute',\n      second: 'Second',\n      millisecond: 'Millisecond'\n    },\n    // Translate date / time text.\n    translate: function translate(type, text) {\n      return text;\n    },\n    // Shortcuts of custom events.\n    show: null,\n    shown: null,\n    hide: null,\n    hidden: null,\n    pick: null\n  };\n\n  var TEMPLATE = '<div class=\"picker\" data-picker-action=\"hide\" touch-action=\"none\" tabindex=\"-1\" role=\"dialog\">' + '<div class=\"picker-dialog\" role=\"document\">' + '<div class=\"picker-header\">' + '<h4 class=\"picker-title\">{{ title }}</h4>' + '<button type=\"button\" class=\"picker-close\" data-picker-action=\"hide\" aria-label=\"Close\">&times;</button>' + '</div>' + '<div class=\"picker-body\">' + '<div class=\"picker-grid\"></div>' + '</div>' + '<div class=\"picker-footer\">' + '<button type=\"button\" class=\"picker-cancel\" data-picker-action=\"hide\">{{ cancel }}</button>' + '<button type=\"button\" class=\"picker-confirm\" data-picker-action=\"pick\">{{ confirm }}</button>' + '</div>' + '</div>' + '</div>';\n\n  var IS_BROWSER = typeof window !== 'undefined';\n  var WINDOW = IS_BROWSER ? window : {};\n  var IS_TOUCH_DEVICE = IS_BROWSER ? 'ontouchstart' in WINDOW.document.documentElement : false;\n  var HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;\n  var NAMESPACE = 'picker';\n  var LANGUAGES = {}; // Actions\n\n  var ACTION_HIDE = 'hide';\n  var ACTION_NEXT = 'next';\n  var ACTION_PICK = 'pick';\n  var ACTION_PREV = 'prev'; // Classes\n\n  var CLASS_OPEN = \"\".concat(NAMESPACE, \"-open\");\n  var CLASS_OPENED = \"\".concat(NAMESPACE, \"-opened\");\n  var CLASS_PICKED = \"\".concat(NAMESPACE, \"-picked\"); // Data keys\n  // Add namespace to avoid to conflict to some other libraries.\n\n  var DATA_ACTION = \"\".concat(NAMESPACE, \"Action\");\n  var DATA_TOKEN = 'token';\n  var DATA_TYPE = 'type';\n  var DATA_NAME = 'name';\n  var DATA_VALUE = 'value'; // Events\n\n  var EVENT_CLICK = 'click';\n  var EVENT_FOCUS = 'focus';\n  var EVENT_HIDDEN = 'hidden';\n  var EVENT_HIDE = 'hide';\n  var EVENT_KEY_DOWN = 'keydown';\n  var EVENT_PICK = 'pick';\n  var EVENT_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown';\n  var EVENT_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'touchmove' : 'mousemove';\n  var EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup';\n  var EVENT_POINTER_DOWN = HAS_POINTER_EVENT ? 'pointerdown' : EVENT_TOUCH_START;\n  var EVENT_POINTER_MOVE = HAS_POINTER_EVENT ? 'pointermove' : EVENT_TOUCH_MOVE;\n  var EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END;\n  var EVENT_SHOW = 'show';\n  var EVENT_SHOWN = 'shown';\n  var EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll';\n\n  var _Object$prototype = Object.prototype,\n      hasOwnProperty = _Object$prototype.hasOwnProperty,\n      toString = _Object$prototype.toString;\n  /**\n   * Detect the type of the given value.\n   * @param {*} value - The value to detect.\n   * @returns {string} Returns the type.\n   */\n\n  function typeOf(value) {\n    return toString.call(value).slice(8, -1).toLowerCase();\n  }\n  /**\n   * Check if the given value is a string.\n   * @param {*} value - The value to check.\n   * @returns {boolean} Returns `true` if the given value is a string, else `false`.\n   */\n\n  function isString(value) {\n    return typeof value === 'string';\n  }\n  /**\n   * Check if the given value is finite.\n   */\n\n  var isFinite = Number.isFinite || WINDOW.isFinite;\n  /**\n   * Check if the given value is not a number.\n   */\n\n  var isNaN = Number.isNaN || WINDOW.isNaN;\n  /**\n   * Check if the given value is a number.\n   * @param {*} value - The value to check.\n   * @returns {boolean} Returns `true` if the given value is a number, else `false`.\n   */\n\n  function isNumber(value) {\n    return typeof value === 'number' && !isNaN(value);\n  }\n  /**\n   * Check if the given value is an object.\n   * @param {*} value - The value to check.\n   * @returns {boolean} Returns `true` if the given value is an object, else `false`.\n   */\n\n  function isObject(value) {\n    return _typeof(value) === 'object' && value !== null;\n  }\n  /**\n   * Check if the given value is a plain object.\n   * @param {*} value - The value to check.\n   * @returns {boolean} Returns `true` if the given value is a plain object, else `false`.\n   */\n\n  function isPlainObject(value) {\n    if (!isObject(value)) {\n      return false;\n    }\n\n    try {\n      var _constructor = value.constructor;\n      var prototype = _constructor.prototype;\n      return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');\n    } catch (error) {\n      return false;\n    }\n  }\n  /**\n   * Check if the given value is a function.\n   * @param {*} value - The value to check.\n   * @returns {boolean} Returns `true` if the given value is a function, else `false`.\n   */\n\n  function isFunction(value) {\n    return typeof value === 'function';\n  }\n  /**\n   * Check if the given value is a date.\n   * @param {*} value - The value to check.\n   * @returns {boolean} Returns `true` if the given value is a date, else `false`.\n   */\n\n  function isDate(value) {\n    return typeOf(value) === 'date';\n  }\n  /**\n   * Check if the given value is a valid date.\n   * @param {*} value - The value to check.\n   * @returns {boolean} Returns `true` if the given value is a valid date, else `false`.\n   */\n\n  function isValidDate(value) {\n    return isDate(value) && value.toString() !== 'Invalid Date';\n  }\n  /**\n   * Iterate the given data.\n   * @param {*} data - The data to iterate.\n   * @param {Function} callback - The process function for each element.\n   * @returns {*} The original data.\n   */\n\n  function forEach(data, callback) {\n    if (data && isFunction(callback)) {\n      if (Array.isArray(data) || isNumber(data.length)\n      /* array-like */\n      ) {\n          var length = data.length;\n          var i;\n\n          for (i = 0; i < length; i += 1) {\n            if (callback.call(data, data[i], i, data) === false) {\n              break;\n            }\n          }\n        } else if (isObject(data)) {\n        Object.keys(data).forEach(function (key) {\n          callback.call(data, data[key], key, data);\n        });\n      }\n    }\n\n    return data;\n  }\n  /**\n   * Recursively assigns own enumerable properties of source objects to the target object.\n   * @param {Object} target - The target object.\n   * @param {Object[]} sources - The source objects.\n   * @returns {Object} The target object.\n   */\n\n  function deepAssign(target) {\n    for (var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n      sources[_key - 1] = arguments[_key];\n    }\n\n    if (isObject(target) && sources.length > 0) {\n      sources.forEach(function (source) {\n        if (isObject(source)) {\n          Object.keys(source).forEach(function (key) {\n            if (isPlainObject(target[key]) && isPlainObject(source[key])) {\n              target[key] = deepAssign({}, target[key], source[key]);\n            } else {\n              target[key] = source[key];\n            }\n          });\n        }\n      });\n    }\n\n    return target;\n  }\n  /**\n   * Add classes to the given element.\n   * @param {Element} element - The target element.\n   * @param {string} value - The classes to be added.\n   */\n\n  function addClass(element, value) {\n    if (!value) {\n      return;\n    }\n\n    if (isNumber(element.length)) {\n      forEach(element, function (elem) {\n        addClass(elem, value);\n      });\n      return;\n    }\n\n    if (element.classList) {\n      element.classList.add(value);\n      return;\n    }\n\n    var className = element.className.trim();\n\n    if (!className) {\n      element.className = value;\n    } else if (className.indexOf(value) < 0) {\n      element.className = \"\".concat(className, \" \").concat(value);\n    }\n  }\n  /**\n   * Remove classes from the given element.\n   * @param {Element} element - The target element.\n   * @param {string} value - The classes to be removed.\n   */\n\n  function removeClass(element, value) {\n    if (!value) {\n      return;\n    }\n\n    if (isNumber(element.length)) {\n      forEach(element, function (elem) {\n        removeClass(elem, value);\n      });\n      return;\n    }\n\n    if (element.classList) {\n      element.classList.remove(value);\n      return;\n    }\n\n    if (element.className.indexOf(value) >= 0) {\n      element.className = element.className.replace(value, '');\n    }\n  }\n  var REGEXP_HYPHENATE = /([a-z\\d])([A-Z])/g;\n  /**\n   * Transform the given string from camelCase to kebab-case\n   * @param {string} value - The value to transform.\n   * @returns {string} The transformed value.\n   */\n\n  function hyphenate(value) {\n    return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase();\n  }\n  /**\n   * Get data from the given element.\n   * @param {Element} element - The target element.\n   * @param {string} name - The data key to get.\n   * @returns {string} The data value.\n   */\n\n  function getData(element, name) {\n    if (isObject(element[name])) {\n      return element[name];\n    }\n\n    if (element.dataset) {\n      return element.dataset[name];\n    }\n\n    return element.getAttribute(\"data-\".concat(hyphenate(name)));\n  }\n  /**\n   * Set data to the given element.\n   * @param {Element} element - The target element.\n   * @param {string} name - The data key to set.\n   * @param {string} data - The data value.\n   */\n\n  function setData(element, name, data) {\n    if (isObject(data)) {\n      element[name] = data;\n    } else if (element.dataset) {\n      element.dataset[name] = data;\n    } else {\n      element.setAttribute(\"data-\".concat(hyphenate(name)), data);\n    }\n  }\n  /**\n   * Remove data from the given element.\n   * @param {Element} element - The target element.\n   * @param {string} name - The data key to remove.\n   */\n\n  function removeData(element, name) {\n    if (isObject(element[name])) {\n      try {\n        delete element[name];\n      } catch (error) {\n        element[name] = undefined;\n      }\n    } else if (element.dataset) {\n      // #128 Safari not allows to delete dataset property\n      try {\n        delete element.dataset[name];\n      } catch (error) {\n        element.dataset[name] = undefined;\n      }\n    } else {\n      element.removeAttribute(\"data-\".concat(hyphenate(name)));\n    }\n  }\n  var REGEXP_SPACES = /\\s\\s*/;\n\n  var onceSupported = function () {\n    var supported = false;\n\n    if (IS_BROWSER) {\n      var once = false;\n\n      var listener = function listener() {};\n\n      var options = Object.defineProperty({}, 'once', {\n        get: function get() {\n          supported = true;\n          return once;\n        },\n\n        /**\n         * This setter can fix a `TypeError` in strict mode\n         * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}\n         * @param {boolean} value - The value to set\n         */\n        set: function set(value) {\n          once = value;\n        }\n      });\n      WINDOW.addEventListener('test', listener, options);\n      WINDOW.removeEventListener('test', listener, options);\n    }\n\n    return supported;\n  }();\n  /**\n   * Remove event listener from the target element.\n   * @param {Element} element - The event target.\n   * @param {string} type - The event type(s).\n   * @param {Function} listener - The event listener.\n   * @param {Object} options - The event options.\n   */\n\n\n  function removeListener(element, type, listener) {\n    var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n    var handler = listener;\n    type.trim().split(REGEXP_SPACES).forEach(function (event) {\n      if (!onceSupported) {\n        var listeners = element.listeners;\n\n        if (listeners && listeners[event] && listeners[event][listener]) {\n          handler = listeners[event][listener];\n          delete listeners[event][listener];\n\n          if (Object.keys(listeners[event]).length === 0) {\n            delete listeners[event];\n          }\n\n          if (Object.keys(listeners).length === 0) {\n            delete element.listeners;\n          }\n        }\n      }\n\n      element.removeEventListener(event, handler, options);\n    });\n  }\n  /**\n   * Add event listener to the target element.\n   * @param {Element} element - The event target.\n   * @param {string} type - The event type(s).\n   * @param {Function} listener - The event listener.\n   * @param {Object} options - The event options.\n   */\n\n  function addListener(element, type, listener) {\n    var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n    var _handler = listener;\n    type.trim().split(REGEXP_SPACES).forEach(function (event) {\n      if (options.once && !onceSupported) {\n        var _element$listeners = element.listeners,\n            listeners = _element$listeners === void 0 ? {} : _element$listeners;\n\n        _handler = function handler() {\n          delete listeners[event][listener];\n          element.removeEventListener(event, _handler, options);\n\n          for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n            args[_key2] = arguments[_key2];\n          }\n\n          listener.apply(element, args);\n        };\n\n        if (!listeners[event]) {\n          listeners[event] = {};\n        }\n\n        if (listeners[event][listener]) {\n          element.removeEventListener(event, listeners[event][listener], options);\n        }\n\n        listeners[event][listener] = _handler;\n        element.listeners = listeners;\n      }\n\n      element.addEventListener(event, _handler, options);\n    });\n  }\n  /**\n   * Dispatch event on the target element.\n   * @param {Element} element - The event target.\n   * @param {string} type - The event type(s).\n   * @param {Object} data - The additional event data.\n   * @returns {boolean} Indicate if the event is default prevented or not.\n   */\n\n  function dispatchEvent(element, type, data) {\n    var event; // Event and CustomEvent on IE9-11 are global objects, not constructors\n\n    if (isFunction(Event) && isFunction(CustomEvent)) {\n      event = new CustomEvent(type, {\n        detail: data,\n        bubbles: true,\n        cancelable: true\n      });\n    } else {\n      event = document.createEvent('CustomEvent');\n      event.initCustomEvent(type, true, true, data);\n    }\n\n    return element.dispatchEvent(event);\n  }\n  /**\n   * Check if the given year is a leap year.\n   * @param {number} year - The year to check.\n   * @returns {boolean} Returns `true` if the given year is a leap year, else `false`.\n   */\n\n  function isLeapYear(year) {\n    return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;\n  }\n  /**\n   * Get days number of the given month.\n   * @param {number} year - The target year.\n   * @param {number} month - The target month.\n   * @returns {number} Returns days number.\n   */\n\n  function getDaysInMonth(year, month) {\n    return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];\n  }\n  /**\n   * Add leading zeroes to the given value\n   * @param {number} value - The value to add.\n   * @param {number} [length=1] - The number of the leading zeroes.\n   * @returns {string} Returns converted value.\n   */\n\n  function addLeadingZero(value) {\n    var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n    var str = String(Math.abs(value));\n    var i = str.length;\n    var result = '';\n\n    if (value < 0) {\n      result += '-';\n    }\n\n    while (i < length) {\n      i += 1;\n      result += '0';\n    }\n\n    return result + str;\n  }\n  /**\n   * Map token to type name\n   * @param {string} token - The token to map.\n   * @returns {string} Returns mapped type name.\n   */\n\n  function tokenToType(token) {\n    return {\n      Y: 'year',\n      M: 'month',\n      D: 'day',\n      H: 'hour',\n      m: 'minute',\n      s: 'second',\n      S: 'millisecond'\n    }[token.charAt(0)];\n  }\n  var REGEXP_TOKENS = /(Y|M|D|H|m|s|S)\\1*/g;\n  /**\n   * Parse date format.\n   * @param {string} format - The format to parse.\n   * @returns {Object} Returns parsed format data.\n   */\n\n  function parseFormat(format) {\n    var tokens = format.match(REGEXP_TOKENS);\n\n    if (!tokens) {\n      throw new Error('Invalid format.');\n    } // Remove duplicate tokens (#22)\n\n\n    tokens = tokens.filter(function (token, index) {\n      return tokens.indexOf(token) === index;\n    });\n    var result = {\n      tokens: tokens\n    };\n    tokens.forEach(function (token) {\n      result[tokenToType(token)] = token;\n    });\n    return result;\n  }\n\n  var events = {\n    bind: function bind() {\n      var element = this.element,\n          options = this.options,\n          grid = this.grid;\n\n      if (isFunction(options.show)) {\n        addListener(element, EVENT_SHOW, options.show);\n      }\n\n      if (isFunction(options.shown)) {\n        addListener(element, EVENT_SHOWN, options.shown);\n      }\n\n      if (isFunction(options.hide)) {\n        addListener(element, EVENT_HIDE, options.hide);\n      }\n\n      if (isFunction(options.hidden)) {\n        addListener(element, EVENT_HIDDEN, options.hidden);\n      }\n\n      if (isFunction(options.pick)) {\n        addListener(element, EVENT_PICK, options.pick);\n      }\n\n      addListener(element, EVENT_FOCUS, this.onFocus = this.focus.bind(this));\n      addListener(element, EVENT_CLICK, this.onFocus);\n      addListener(this.picker, EVENT_CLICK, this.onClick = this.click.bind(this));\n      addListener(grid, EVENT_WHEEL, this.onWheel = this.wheel.bind(this));\n      addListener(grid, EVENT_POINTER_DOWN, this.onPointerDown = this.pointerdown.bind(this));\n      addListener(document, EVENT_POINTER_MOVE, this.onPointerMove = this.pointermove.bind(this));\n      addListener(document, EVENT_POINTER_UP, this.onPointerUp = this.pointerup.bind(this));\n      addListener(document, EVENT_KEY_DOWN, this.onKeyDown = this.keydown.bind(this));\n    },\n    unbind: function unbind() {\n      var element = this.element,\n          options = this.options,\n          grid = this.grid;\n\n      if (isFunction(options.show)) {\n        removeListener(element, EVENT_SHOW, options.show);\n      }\n\n      if (isFunction(options.shown)) {\n        removeListener(element, EVENT_SHOWN, options.shown);\n      }\n\n      if (isFunction(options.hide)) {\n        removeListener(element, EVENT_HIDE, options.hide);\n      }\n\n      if (isFunction(options.hidden)) {\n        removeListener(element, EVENT_HIDDEN, options.hidden);\n      }\n\n      if (isFunction(options.pick)) {\n        removeListener(element, EVENT_PICK, options.pick);\n      }\n\n      removeListener(element, EVENT_FOCUS, this.onFocus);\n      removeListener(element, EVENT_CLICK, this.onFocus);\n      removeListener(this.picker, EVENT_CLICK, this.onClick);\n      removeListener(grid, EVENT_WHEEL, this.onWheel);\n      removeListener(grid, EVENT_POINTER_DOWN, this.onPointerDown);\n      removeListener(document, EVENT_POINTER_MOVE, this.onPointerMove);\n      removeListener(document, EVENT_POINTER_UP, this.onPointerUp);\n      removeListener(document, EVENT_KEY_DOWN, this.onKeyDown);\n    }\n  };\n\n  var handlers = {\n    focus: function focus(event) {\n      event.target.blur();\n      this.show();\n    },\n    click: function click(event) {\n      var target = event.target;\n      var action = getData(target, DATA_ACTION);\n\n      switch (action) {\n        case ACTION_HIDE:\n          this.hide();\n          break;\n\n        case ACTION_PICK:\n          this.pick();\n          break;\n\n        case ACTION_PREV:\n        case ACTION_NEXT:\n          this[action](getData(target.parentElement, DATA_TYPE));\n          break;\n\n        default:\n      }\n    },\n    wheel: function wheel(event) {\n      var target = event.target;\n\n      if (target === this.grid) {\n        return;\n      }\n\n      event.preventDefault();\n\n      while (target.parentElement && target.parentElement !== this.grid) {\n        target = target.parentElement;\n      }\n\n      var type = getData(target, DATA_TYPE);\n\n      if (event.deltaY < 0) {\n        this.prev(type);\n      } else {\n        this.next(type);\n      }\n    },\n    pointerdown: function pointerdown(event) {\n      var target = event.target;\n\n      if (target === this.grid || getData(target, DATA_ACTION)) {\n        return;\n      } // This line is required for preventing page scrolling in iOS browsers\n\n\n      event.preventDefault();\n\n      while (target.parentElement && target.parentElement !== this.grid) {\n        target = target.parentElement;\n      }\n\n      var list = target.querySelector(\".\".concat(NAMESPACE, \"-list\"));\n      var itemHeight = list.firstElementChild.offsetHeight;\n      this.cell = {\n        elem: target,\n        list: list,\n        moveY: 0,\n        maxMoveY: itemHeight,\n        minMoveY: itemHeight / 2,\n        startY: event.changedTouches ? event.changedTouches[0].pageY : event.pageY,\n        type: getData(target, DATA_TYPE)\n      };\n    },\n    pointermove: function pointermove(event) {\n      var cell = this.cell;\n\n      if (!cell) {\n        return;\n      }\n\n      event.preventDefault();\n      var endY = event.changedTouches ? event.changedTouches[0].pageY : event.pageY;\n      var moveY = cell.moveY + (endY - cell.startY);\n      cell.startY = endY;\n      cell.moveY = moveY;\n\n      if (Math.abs(moveY) < cell.maxMoveY) {\n        cell.list.style.top = \"\".concat(moveY, \"px\");\n        return;\n      }\n\n      cell.list.style.top = 0;\n      cell.moveY = 0;\n\n      if (moveY >= cell.maxMoveY) {\n        this.prev(cell.type);\n      } else if (moveY <= -cell.maxMoveY) {\n        this.next(cell.type);\n      }\n    },\n    pointerup: function pointerup(event) {\n      var cell = this.cell;\n\n      if (!cell) {\n        return;\n      }\n\n      event.preventDefault();\n      cell.list.style.top = 0;\n\n      if (cell.moveY >= cell.minMoveY) {\n        this.prev(cell.type);\n      } else if (cell.moveY <= -cell.minMoveY) {\n        this.next(cell.type);\n      }\n\n      this.cell = null;\n    },\n    keydown: function keydown(event) {\n      if (this.shown && (event.key === 'Escape' || event.keyCode === 27)) {\n        this.hide();\n      }\n    }\n  };\n\n  var helpers = {\n    render: function render(type) {\n      var _this = this;\n\n      if (!type) {\n        this.format.tokens.forEach(function (token) {\n          return _this.render(tokenToType(token));\n        });\n        return;\n      }\n\n      var options = this.options;\n      var data = this.data[type];\n      var current = this.current(type);\n      var max = isFunction(data.max) ? data.max() : data.max;\n      var min = isFunction(data.min) ? data.min() : data.min;\n      var base = 0;\n\n      if (isFinite(max)) {\n        base = min > 0 ? max : max + 1;\n      }\n\n      data.list.innerHTML = '';\n      data.current = current;\n\n      for (var i = 0; i < options.rows + 2; i += 1) {\n        var item = document.createElement('li');\n        var position = i - data.index;\n        var newValue = current + position * data.increment;\n\n        if (base) {\n          newValue %= base;\n\n          if (newValue < min) {\n            newValue += base;\n          }\n        }\n\n        item.textContent = options.translate(type, data.aliases ? data.aliases[newValue] : addLeadingZero(newValue + data.offset, data.digit));\n        setData(item, DATA_NAME, type);\n        setData(item, DATA_VALUE, newValue);\n        addClass(item, \"\".concat(NAMESPACE, \"-item\"));\n\n        if (position === 0) {\n          addClass(item, CLASS_PICKED);\n          data.item = item;\n        }\n\n        data.list.appendChild(item);\n      }\n    },\n    current: function current(type, value) {\n      var date = this.date;\n      var format = this.format;\n      var token = format[type];\n\n      switch (token.charAt(0)) {\n        case 'Y':\n          if (isNumber(value)) {\n            date.setFullYear(token.length === 2 ? 2000 + value : value);\n\n            if (format.month) {\n              this.render(tokenToType(format.month));\n            }\n\n            if (format.day) {\n              this.render(tokenToType(format.day));\n            }\n          }\n\n          return date.getFullYear();\n\n        case 'M':\n          if (isNumber(value)) {\n            date.setMonth(value, // The current day should not exceed its maximum day in current month\n            Math.min(date.getDate(), getDaysInMonth(date.getFullYear(), value)));\n\n            if (format.day) {\n              this.render(tokenToType(format.day));\n            }\n          }\n\n          return date.getMonth();\n\n        case 'D':\n          if (isNumber(value)) {\n            date.setDate(value);\n          }\n\n          return date.getDate();\n\n        case 'H':\n          if (isNumber(value)) {\n            date.setHours(value);\n          }\n\n          return date.getHours();\n\n        case 'm':\n          if (isNumber(value)) {\n            date.setMinutes(value);\n          }\n\n          return date.getMinutes();\n\n        case 's':\n          if (isNumber(value)) {\n            date.setSeconds(value);\n          }\n\n          return date.getSeconds();\n\n        case 'S':\n          if (isNumber(value)) {\n            date.setMilliseconds(value);\n          }\n\n          return date.getMilliseconds();\n\n        default:\n      }\n\n      return date;\n    },\n    getValue: function getValue() {\n      var element = this.element;\n      return this.isInput ? element.value : element.textContent;\n    },\n    setValue: function setValue(value) {\n      var element = this.element;\n\n      if (this.isInput) {\n        element.value = value;\n      } else if (this.options.container) {\n        element.textContent = value;\n      }\n    },\n    open: function open() {\n      var body = this.body;\n      body.style.overflow = 'hidden';\n      body.style.paddingRight = \"\".concat(this.scrollBarWidth + (parseFloat(this.initialBodyPaddingRight) || 0), \"px\");\n    },\n    close: function close() {\n      var body = this.body;\n      body.style.overflow = '';\n      body.style.paddingRight = this.initialBodyPaddingRight;\n    }\n  };\n\n  var methods = {\n    /**\n     * Show the picker.\n     * @param {boolean} [immediate=false] - Indicate if show the picker immediately or not.\n     * @returns {Picker} this\n     */\n    show: function show() {\n      var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n      var element = this.element,\n          picker = this.picker;\n\n      if (this.inline || this.shown) {\n        return this;\n      }\n\n      if (dispatchEvent(element, EVENT_SHOW) === false) {\n        return this;\n      }\n\n      this.shown = true;\n      this.open();\n      addClass(picker, CLASS_OPEN);\n\n      var done = function done() {\n        dispatchEvent(element, EVENT_SHOWN);\n      };\n\n      if (!immediate) {\n        // Reflow to enable transition\n        // eslint-disable-next-line\n        picker.offsetWidth;\n      }\n\n      addClass(picker, CLASS_OPENED);\n\n      if (immediate) {\n        done();\n      } else {\n        setTimeout(done, 300);\n      }\n\n      return this;\n    },\n\n    /**\n     * Hide the picker.\n     * @param {boolean} [immediate=false] - Indicate if hide the picker immediately or not.\n     * @returns {Picker} this\n     */\n    hide: function hide() {\n      var _this = this;\n\n      var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n      var element = this.element,\n          picker = this.picker;\n\n      if (this.inline || !this.shown) {\n        return this;\n      }\n\n      if (dispatchEvent(element, EVENT_HIDE) === false) {\n        return this;\n      }\n\n      this.shown = false;\n      removeClass(picker, CLASS_OPENED);\n\n      var done = function done() {\n        _this.close();\n\n        removeClass(picker, CLASS_OPEN);\n        dispatchEvent(element, EVENT_HIDDEN);\n      };\n\n      if (immediate) {\n        done();\n      } else {\n        setTimeout(done, 300);\n      }\n\n      return this;\n    },\n\n    /**\n     * Pick to the previous item.\n     * @param {string} type - The column type.\n     * @returns {Picker} this\n     */\n    prev: function prev(type) {\n      var options = this.options;\n      var token = this.format[type];\n      var data = this.data[type];\n      var list = data.list;\n      var item = list.lastElementChild;\n      var max = isFunction(data.max) ? data.max() : data.max;\n      var min = isFunction(data.min) ? data.min() : data.min;\n      var prev = data.item.previousElementSibling;\n      var value = Number(getData(list.firstElementChild, DATA_VALUE)) - data.increment;\n\n      if (value < min) {\n        value += max - min + 1;\n      }\n\n      item.textContent = options.translate(type, data.aliases ? data.aliases[value] : addLeadingZero(value + data.offset, token.length));\n      setData(item, DATA_VALUE, value);\n\n      if (prev) {\n        removeClass(data.item, CLASS_PICKED);\n        addClass(prev, CLASS_PICKED);\n        data.item = prev;\n      }\n\n      list.insertBefore(item, list.firstElementChild);\n      data.current = Number(getData(data.item, DATA_VALUE));\n      this.current(type, data.current);\n\n      if (this.inline && options.container) {\n        this.pick();\n      }\n\n      return this;\n    },\n\n    /**\n     * Pick to the next item.\n     * @param {String} type - The column type.\n     * @returns {Picker} this\n     */\n    next: function next(type) {\n      var options = this.options;\n      var token = this.format[type];\n      var data = this.data[type];\n      var list = data.list;\n      var item = list.firstElementChild;\n      var max = isFunction(data.max) ? data.max() : data.max;\n      var min = isFunction(data.min) ? data.min() : data.min;\n      var next = data.item.nextElementSibling;\n      var value = Number(getData(list.lastElementChild, DATA_VALUE)) + data.increment;\n\n      if (value > max) {\n        value -= max - min + 1;\n      }\n\n      item.textContent = options.translate(type, data.aliases ? data.aliases[value] : addLeadingZero(value + data.offset, token.length));\n      setData(item, DATA_VALUE, value);\n      list.appendChild(item);\n\n      if (next) {\n        removeClass(data.item, CLASS_PICKED);\n        addClass(next, CLASS_PICKED);\n        data.item = next;\n      }\n\n      data.current = Number(getData(data.item, DATA_VALUE));\n      this.current(type, data.current);\n\n      if (this.inline && options.container) {\n        this.pick();\n      }\n\n      return this;\n    },\n    // Pick the current date to the target element.\n    pick: function pick() {\n      var element = this.element;\n\n      if (dispatchEvent(element, EVENT_PICK) === false) {\n        return this;\n      }\n\n      var value = this.formatDate(this.date);\n      this.setValue(value);\n\n      if (this.isInput && dispatchEvent(element, 'change') === false) {\n        this.reset();\n      }\n\n      this.hide();\n      return this;\n    },\n\n    /**\n     * Get the current date.\n     * @param {boolean} [formatted=false] - Indicate if format the date or not.\n     * @return {Date|string} The output date.\n     */\n    getDate: function getDate() {\n      var formatted = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n      var date = this.date;\n      return formatted ? this.formatDate(date) : new Date(date);\n    },\n\n    /**\n     * Override the current date with a new date.\n     * @param {Date|string} date - The date to set.\n     * @returns {Picker} this\n     */\n    setDate: function setDate(date) {\n      if (date) {\n        this.date = this.parseDate(date);\n        this.render();\n      }\n\n      return this;\n    },\n    // Update the picker with the current element value / text.\n    update: function update() {\n      this.date = this.parseDate(this.getValue());\n      this.render();\n      return this;\n    },\n    // Reset the picker and element value / text.\n    reset: function reset() {\n      this.setValue(this.initialValue);\n      this.date = new Date(this.initialDate);\n      this.render();\n      return this;\n    },\n\n    /**\n     * Parse a date with the set date format.\n     * @param {Date|string} date - The date to parse.\n     * @returns {Date} The parsed date object.\n     */\n    parseDate: function parseDate(date) {\n      var options = this.options,\n          format = this.format;\n      var digits = [];\n\n      if (isDate(date)) {\n        return new Date(date);\n      }\n\n      if (isString(date)) {\n        var groups = [].concat(_toConsumableArray(options.months), _toConsumableArray(options.monthsShort), ['\\\\d+']);\n        digits = date.match(new RegExp(\"(\".concat(groups.join('|'), \")\"), 'g')); // Parse `11111111` (YYYYMMDD) to ['1111', '11', '11']\n\n        if (digits && date.length === options.format.length && digits.length !== format.tokens.length) {\n          digits = format.tokens.map(function (token) {\n            return date.substr(options.format.indexOf(token), token.length);\n          });\n        }\n\n        if (!digits || digits.length !== format.tokens.length) {\n          return new Date();\n        }\n      }\n\n      var parsedDate = new Date();\n      digits.forEach(function (digit, i) {\n        var token = format.tokens[i];\n        var n = Number(digit);\n\n        switch (token) {\n          case 'YYYY':\n          case 'YYY':\n          case 'Y':\n            {\n              var index = date.indexOf(digit);\n              var isHyphen = date.substr(index - 1, 1) === '-';\n              var isBC = index > 1 && isHyphen && /\\S/.test(date.substr(index - 2, 1)) || index === 1 && isHyphen;\n              parsedDate.setFullYear(isBC ? -n : n);\n              break;\n            }\n\n          case 'YY':\n            parsedDate.setFullYear(2000 + n);\n            break;\n\n          case 'MMMM':\n            parsedDate.setMonth(options.months.indexOf(digit));\n            break;\n\n          case 'MMM':\n            parsedDate.setMonth(options.monthsShort.indexOf(digit));\n            break;\n\n          case 'MM':\n          case 'M':\n            parsedDate.setMonth(n - 1);\n            break;\n\n          case 'DD':\n          case 'D':\n            parsedDate.setDate(n);\n            break;\n\n          case 'HH':\n          case 'H':\n            parsedDate.setHours(n);\n            break;\n\n          case 'mm':\n          case 'm':\n            parsedDate.setMinutes(n);\n            break;\n\n          case 'ss':\n          case 's':\n            parsedDate.setSeconds(n);\n            break;\n\n          case 'SSS':\n          case 'SS':\n          case 'S':\n            parsedDate.setMilliseconds(n);\n            break;\n\n          default:\n        }\n      });\n      return parsedDate;\n    },\n\n    /**\n     * Format a date object to a string with the set date format.\n     * @param {Date} date - The date to format.\n     * @return {string} THe formatted date.\n     */\n    formatDate: function formatDate(date) {\n      var options = this.options,\n          format = this.format;\n      var formatted = '';\n\n      if (isValidDate(date)) {\n        var year = date.getFullYear();\n        var month = date.getMonth();\n        var day = date.getDate();\n        var hours = date.getHours();\n        var minutes = date.getMinutes();\n        var seconds = date.getSeconds();\n        var milliseconds = date.getMilliseconds();\n        formatted = options.format;\n        format.tokens.forEach(function (token) {\n          var replacement = '';\n\n          switch (token) {\n            case 'YYYY':\n            case 'YYY':\n            case 'Y':\n              replacement = addLeadingZero(year, token.length);\n              break;\n\n            case 'YY':\n              replacement = addLeadingZero(year % 100, 2);\n              break;\n\n            case 'MMMM':\n              replacement = options.months[month];\n              break;\n\n            case 'MMM':\n              replacement = options.monthsShort[month];\n              break;\n\n            case 'MM':\n            case 'M':\n              replacement = addLeadingZero(month + 1, token.length);\n              break;\n\n            case 'DD':\n            case 'D':\n              replacement = addLeadingZero(day, token.length);\n              break;\n\n            case 'HH':\n            case 'H':\n              replacement = addLeadingZero(hours, token.length);\n              break;\n\n            case 'mm':\n            case 'm':\n              replacement = addLeadingZero(minutes, token.length);\n              break;\n\n            case 'ss':\n            case 's':\n              replacement = addLeadingZero(seconds, token.length);\n              break;\n\n            case 'SSS':\n            case 'SS':\n            case 'S':\n              replacement = addLeadingZero(milliseconds, token.length);\n              break;\n\n            default:\n          }\n\n          formatted = formatted.replace(token, replacement);\n        });\n      }\n\n      return formatted;\n    },\n    // Destroy the picker and remove the instance from the target element.\n    destroy: function destroy() {\n      var element = this.element,\n          picker = this.picker;\n\n      if (!getData(element, NAMESPACE)) {\n        return this;\n      }\n\n      this.hide(true);\n      this.unbind();\n      removeData(element, NAMESPACE);\n      picker.parentNode.removeChild(picker);\n      return this;\n    }\n  };\n\n  var REGEXP_DELIMITER = /\\{\\{\\s*(\\w+)\\s*\\}\\}/g;\n  var REGEXP_INPUTS = /input|textarea/i;\n  var AnotherPicker = WINDOW.Picker;\n\n  var Picker =\n  /*#__PURE__*/\n  function () {\n    /**\n     * Create a new Picker.\n     * @param {Element} element - The target element for picking.\n     * @param {Object} [options={}] - The configuration options.\n     */\n    function Picker(element) {\n      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n      _classCallCheck(this, Picker);\n\n      if (!element || element.nodeType !== 1) {\n        throw new Error('The first argument is required and must be an element.');\n      }\n\n      this.element = element;\n      this.options = deepAssign({}, DEFAULTS, LANGUAGES[options.language], isPlainObject(options) && options);\n      this.shown = false;\n      this.init();\n    }\n\n    _createClass(Picker, [{\n      key: \"init\",\n      value: function init() {\n        var _this = this;\n\n        var element = this.element;\n\n        if (getData(element, NAMESPACE)) {\n          return;\n        }\n\n        setData(element, NAMESPACE, this);\n        var options = this.options;\n        var isInput = REGEXP_INPUTS.test(element.tagName);\n        var inline = options.inline && (options.container || !isInput);\n        var template = document.createElement('div');\n        template.insertAdjacentHTML('afterbegin', TEMPLATE.replace(REGEXP_DELIMITER, function () {\n          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n            args[_key] = arguments[_key];\n          }\n\n          return options.text[args[1]];\n        }));\n        var picker = template.getElementsByClassName(NAMESPACE)[0];\n        var grid = picker.getElementsByClassName(\"\".concat(NAMESPACE, \"-grid\"))[0];\n        var container = options.container;\n\n        if (isString(container)) {\n          container = document.querySelector(container);\n        }\n\n        if (inline) {\n          addClass(picker, CLASS_OPEN);\n          addClass(picker, CLASS_OPENED);\n\n          if (!container) {\n            container = element;\n          }\n        } else {\n          var ownerDocument = element.ownerDocument;\n          var body = ownerDocument.body || ownerDocument.documentElement;\n          this.body = body;\n          this.scrollBarWidth = WINDOW.innerWidth - ownerDocument.documentElement.clientWidth;\n          this.initialBodyPaddingRight = WINDOW.getComputedStyle(body).paddingRight;\n          addClass(picker, \"\".concat(NAMESPACE, \"-fixed\"));\n\n          if (!container) {\n            container = document.body;\n          }\n        }\n\n        this.isInput = isInput;\n        this.inline = inline;\n        this.container = container;\n        this.picker = picker;\n        this.grid = grid;\n        this.cell = null;\n        this.format = parseFormat(options.format);\n        var initialValue = this.getValue();\n        var date = this.parseDate(options.date || initialValue);\n        this.date = date;\n        this.initialDate = new Date(date);\n        this.initialValue = initialValue;\n        this.data = {};\n        var rows = Number(options.rows);\n\n        if (!(rows % 2)) {\n          rows += 1;\n        }\n\n        options.rows = rows || 5;\n        addClass(grid, \"\".concat(NAMESPACE, \"-\").concat(options.rows > 1 ? 'multiple' : 'single'));\n\n        if (options.controls) {\n          addClass(grid, \"\".concat(NAMESPACE, \"-controls\"));\n        }\n\n        var headers = options.headers,\n            increment = options.increment;\n\n        if (headers) {\n          addClass(grid, \"\".concat(NAMESPACE, \"-headers\")); // TODO: Drop the `headers` option's object support in v2.\n\n          headers = isPlainObject(headers) ? headers : options.text;\n        }\n\n        if (!isPlainObject(increment)) {\n          increment = {\n            year: increment,\n            month: increment,\n            day: increment,\n            hour: increment,\n            minute: increment,\n            second: increment,\n            millisecond: increment\n          };\n        }\n\n        this.format.tokens.forEach(function (token) {\n          var type = tokenToType(token);\n          var cell = document.createElement('div');\n          var cellBody = document.createElement('div');\n          var list = document.createElement('ul');\n          var data = {\n            digit: token.length,\n            increment: Math.abs(Number(increment[type])) || 1,\n            list: list,\n            max: Infinity,\n            min: -Infinity,\n            index: Math.floor((options.rows + 2) / 2),\n            offset: 0\n          };\n\n          switch (token.charAt(0)) {\n            case 'Y':\n              if (data.digit === 2) {\n                data.max = 99;\n                data.min = 0;\n              }\n\n              break;\n\n            case 'M':\n              data.max = 11;\n              data.min = 0;\n              data.offset = 1;\n\n              if (data.digit === 3) {\n                data.aliases = options.monthsShort;\n              } else if (data.digit === 4) {\n                data.aliases = options.months;\n              }\n\n              break;\n\n            case 'D':\n              // XXX: Use the latest date to calculate the max day (#23)\n              data.max = function () {\n                return getDaysInMonth(_this.date.getFullYear(), _this.date.getMonth());\n              };\n\n              data.min = 1;\n              break;\n\n            case 'H':\n              data.max = 23;\n              data.min = 0;\n              break;\n\n            case 'm':\n              data.max = 59;\n              data.min = 0;\n              break;\n\n            case 's':\n              data.max = 59;\n              data.min = 0;\n              break;\n\n            case 'S':\n              data.max = 999;\n              data.min = 0;\n              break;\n\n            default:\n          }\n\n          setData(cell, DATA_TYPE, type);\n          setData(cell, DATA_TOKEN, token);\n\n          if (headers) {\n            var cellHeader = document.createElement('div');\n            addClass(cellHeader, \"\".concat(NAMESPACE, \"-cell__header\"));\n            cellHeader.textContent = headers[type] || type[0].toUpperCase() + type.substr(1);\n            cell.appendChild(cellHeader);\n          }\n\n          if (options.controls) {\n            var prev = document.createElement('div');\n            addClass(prev, \"\".concat(NAMESPACE, \"-cell__control\"));\n            addClass(prev, \"\".concat(NAMESPACE, \"-cell__control--prev\"));\n            setData(prev, DATA_ACTION, ACTION_PREV);\n            cell.appendChild(prev);\n          }\n\n          addClass(list, \"\".concat(NAMESPACE, \"-list\"));\n          addClass(cellBody, \"\".concat(NAMESPACE, \"-cell__body\"));\n          addClass(cell, \"\".concat(NAMESPACE, \"-cell\"));\n          addClass(cell, \"\".concat(NAMESPACE, \"-\").concat(type, \"s\"));\n          cellBody.appendChild(list);\n          cell.appendChild(cellBody);\n\n          if (options.controls) {\n            var next = document.createElement('div');\n            addClass(next, \"\".concat(NAMESPACE, \"-cell__control\"));\n            addClass(next, \"\".concat(NAMESPACE, \"-cell__control--next\"));\n            setData(next, DATA_ACTION, ACTION_NEXT);\n            cell.appendChild(next);\n          }\n\n          grid.appendChild(cell);\n          _this.data[type] = data;\n\n          _this.render(type);\n        });\n\n        if (inline) {\n          container.innerHTML = '';\n        }\n\n        container.appendChild(picker);\n        this.bind();\n      }\n      /**\n       * Get the no conflict picker class.\n       * @returns {Picker} The picker class.\n       */\n\n    }], [{\n      key: \"noConflict\",\n      value: function noConflict() {\n        WINDOW.Picker = AnotherPicker;\n        return Picker;\n      }\n      /**\n       * Change the default options.\n       * @param {Object} options - The new default options.\n       */\n\n    }, {\n      key: \"setDefaults\",\n      value: function setDefaults(options) {\n        deepAssign(DEFAULTS, LANGUAGES[options.language], isPlainObject(options) && options);\n      }\n    }]);\n\n    return Picker;\n  }();\n\n  deepAssign(Picker.prototype, events, handlers, helpers, methods);\n  Picker.languages = LANGUAGES;\n\n  return Picker;\n\n}));\n"
  },
  {
    "path": "docs/css/main.css",
    "content": ".carbonads {\n  border: 1px solid #ccc;\n  border-radius: 0.25rem;\n  font-size: 0.875rem;\n  overflow: hidden;\n  padding: 1rem;\n}\n\n.carbon-wrap {\n  overflow: hidden;\n}\n\n.carbon-img {\n  clear: left;\n  display: block;\n  float: left;\n}\n\n.carbon-text,\n.carbon-poweredby {\n  display: block;\n  margin-left: 140px;\n}\n\n.carbon-text,\n.carbon-text:hover,\n.carbon-text:focus {\n  color: #fff;\n  text-decoration: none;\n}\n\n.carbon-poweredby,\n.carbon-poweredby:hover,\n.carbon-poweredby:focus {\n  color: #ddd;\n  text-decoration: none;\n}\n\n@media (min-width: 768px) {\n  .carbonads {\n    float: right;\n    margin-bottom: -1rem;\n    margin-top: -1rem;\n    max-width: 360px;\n  }\n}\n\n.footer {\n  font-size: 0.875rem;\n}\n\n.heart {\n  color: #ddd;\n  display: block;\n  height: 2rem;\n  line-height: 2rem;\n  margin-bottom: 0;\n  margin-top: 1rem;\n  position: relative;\n  text-align: center;\n  width: 100%;\n}\n\n.heart:hover {\n  color: #ff4136;\n}\n\n.heart::before {\n  border-top: 1px solid #eee;\n  content: \" \";\n  display: block;\n  height: 0;\n  left: 0;\n  position: absolute;\n  right: 0;\n  top: 50%;\n}\n\n.heart::after {\n  background-color: #fff;\n  content: \"♥\";\n  padding-left: 0.5rem;\n  padding-right: 0.5rem;\n  position: relative;\n  z-index: 1;\n}\n\n.docs-picker-container {\n  border: 1px dashed #eee;\n  display: none;\n  margin: 0.5rem auto;\n  min-height: 40px;\n  position: relative;\n}\n\n.docs-picker-container::before {\n  color: #ccc;\n  content: 'Container for inline picker';\n  font-size: 12px;\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translate(-50%, -50%);\n  z-index: -1;\n}\n\n.docs-options .form-check {\n  margin-bottom: 0;\n}\n\n.docs-options .input-group {\n  margin-bottom: 0.5rem;\n}\n\n.docs-options .input-group-prepend .input-group-text {\n  min-width: 6rem;\n}\n\n.docs-methods > .input-group,\n.docs-methods > .btn-group,\n.docs-methods > .btn {\n  margin-bottom: 0.5rem;\n}\n\n.js-super-picker-container .picker-years {\n  width: 28%;\n}\n"
  },
  {
    "path": "docs/css/picker.css",
    "content": "/*!\n * Picker.js v1.2.1\n * https://fengyuanchen.github.io/pickerjs\n *\n * Copyright 2016-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2019-02-18T13:08:09.658Z\n */\n\n:root {\n  --gray: #999;\n  --blue: #0074d9;\n  --color: #333;\n  --background-color: #fff;\n  --border: 1px solid #eee;\n}\n\n.picker {\n  background-color: rgba(0, 0, 0, 0.5);\n  color: #333;\n  color: var(--color);\n  direction: ltr;\n  display: none;\n  font-size: 1rem;\n  line-height: 1.5;\n  overflow: hidden;\n  -ms-touch-action: none;\n  touch-action: none;\n  -webkit-transition: opacity 0.15s;\n  transition: opacity 0.15s;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n\n.picker-fixed {\n  bottom: 0;\n  left: 0;\n  position: fixed;\n  right: 0;\n  top: 0;\n  z-index: 1986;\n}\n\n.picker-fixed > .picker-dialog {\n  bottom: -100%;\n  left: 0;\n  max-height: 100%;\n  position: absolute;\n  right: 0;\n  -webkit-transition: bottom 0.3s;\n  transition: bottom 0.3s;\n}\n\n.picker-fixed .picker-header {\n  display: block;\n}\n\n.picker-fixed .picker-footer {\n  display: table;\n}\n\n.picker-open {\n  display: block;\n  opacity: 0;\n}\n\n.picker-opened {\n  opacity: 1;\n}\n\n.picker-opened > .picker-dialog {\n  bottom: 0;\n}\n\n.picker-dialog {\n  background-color: #fff;\n  background-color: var(--background-color);\n  border: 1px solid #eee;\n  border: var(--border);\n}\n\n.picker-header {\n  border-bottom: 1px solid #eee;\n  border-bottom: var(--border);\n  display: none;\n  padding: 0.875rem 1.25rem;\n  position: relative;\n}\n\n.picker-title {\n  font-size: 1.125rem;\n  font-weight: 500;\n  line-height: 1.25rem;\n  margin: 0;\n}\n\n.picker-close {\n  background-color: transparent;\n  border-width: 0;\n  color: #999;\n  color: var(--gray);\n  cursor: pointer;\n  font-size: 1.75rem;\n  height: 3rem;\n  opacity: 0.75;\n  padding: 0;\n  position: absolute;\n  right: 0;\n  top: 0;\n  width: 3rem;\n}\n\n.picker-close:focus,\n.picker-close:hover {\n  opacity: 1;\n  outline: none;\n}\n\n.picker-body {\n  overflow: hidden;\n}\n\n.picker-grid {\n  display: table;\n  table-layout: fixed;\n  width: 100%;\n}\n\n.picker-cell {\n  display: table-cell;\n  position: relative;\n}\n\n.picker-cell::before,\n.picker-cell::after {\n  content: '';\n  display: block;\n  left: 0;\n  position: absolute;\n  right: 0;\n  z-index: 3;\n}\n\n.picker-cell::before {\n  background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(0, 0, 0, 0)), to(rgba(0, 0, 0, 0.05)));\n  background-image: linear-gradient(to top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.05));\n  bottom: 50%;\n  margin-bottom: 1rem;\n  top: 0;\n}\n\n.picker-cell::after {\n  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), to(rgba(0, 0, 0, 0.05)));\n  background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.05));\n  bottom: 0;\n  margin-top: 1rem;\n  top: 50%;\n}\n\n.picker-cell + .picker-cell {\n  border-left: 1px solid #eee;\n  border-left: var(--border);\n}\n\n.picker-headers .picker-cell::before {\n  margin-bottom: 0;\n}\n\n.picker-headers .picker-cell::after {\n  margin-top: 2rem;\n}\n\n.picker-single:not(.picker-controls):not(.picker-headers) .picker-cell::before,\n.picker-single:not(.picker-controls):not(.picker-headers) .picker-cell::after {\n  display: none;\n}\n\n.picker-cell__header {\n  color: #999;\n  color: var(--gray);\n  font-size: 0.875rem;\n  font-weight: 500;\n  line-height: 1.5rem;\n  margin: 0;\n  overflow: hidden;\n  padding: 0.25rem 0.5rem;\n  text-align: center;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.picker-cell__control {\n  cursor: pointer;\n  height: 2rem;\n  padding: 0.25rem 0.5rem;\n  position: relative;\n  z-index: 4;\n}\n\n.picker-cell__control::before {\n  border: 0 solid #ccc;\n  content: '';\n  display: block;\n  height: 0.5rem;\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  -webkit-transform: translate(-50%, -50%) rotate(-45deg);\n  -ms-transform: translate(-50%, -50%) rotate(-45deg);\n  transform: translate(-50%, -50%) rotate(-45deg);\n  width: 0.5rem;\n}\n\n.picker-cell__control:hover::before {\n  border-color: var(--primary);\n}\n\n.picker-cell__control--prev::before {\n  border-right-width: 1px;\n  border-top-width: 1px;\n  margin-top: 2px;\n}\n\n.picker-cell__control--next::before {\n  border-bottom-width: 1px;\n  border-left-width: 1px;\n  margin-bottom: 2px;\n}\n\n.picker-cell__body {\n  overflow: hidden;\n  position: relative;\n}\n\n.picker-cell__body::before,\n.picker-cell__body::after {\n  content: '';\n  height: 2rem;\n  left: 0;\n  position: absolute;\n  right: 0;\n  z-index: 1;\n}\n\n.picker-cell__body::before {\n  background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(255, 255, 255, 0)), to(rgba(255, 255, 255, 1)));\n  background-image: linear-gradient(to top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));\n  top: 0;\n}\n\n.picker-cell__body::after {\n  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0)), to(rgba(255, 255, 255, 1)));\n  background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));\n  bottom: 0;\n}\n\n.picker-single .picker-cell__body::before,\n.picker-single .picker-cell__body::after {\n  display: none;\n}\n\n.picker-list {\n  list-style: none;\n  margin: -2rem 0;\n  padding: 0;\n  position: relative;\n}\n\n.picker-item {\n  color: #999;\n  color: var(--gray);\n  padding: 0.25rem 0.5rem;\n  text-align: center;\n  white-space: nowrap;\n}\n\n.picker-picked {\n  color: #0074d9;\n  color: var(--blue);\n  font-size: 1.125em;\n  line-height: 1.5rem;\n}\n\n.picker-footer {\n  border-top: 1px solid #eee;\n  border-top: var(--border);\n  display: none;\n  width: 100%;\n}\n\n.picker-cancel,\n.picker-confirm {\n  background-color: transparent;\n  border-width: 0;\n  cursor: pointer;\n  display: table-cell;\n  font-size: 1rem;\n  padding: 0.75rem 1rem;\n  width: 50%;\n}\n\n.picker-cancel:focus,\n.picker-cancel:hover,\n.picker-confirm:focus,\n.picker-confirm:hover {\n  background-color: #fcfcfc;\n  outline: none;\n}\n\n.picker-confirm {\n  color: #0074d9;\n  color: var(--blue);\n}\n"
  },
  {
    "path": "docs/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta http-equiv=\"x-ua-compatible\" content=\"ie=edge\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n  <meta name=\"description\" content=\"JavaScript date time picker.\">\n  <meta name=\"author\" content=\"Chen Fengyuan\">\n  <title>Picker.js</title>\n  <link rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css\">\n  <link rel=\"stylesheet\" href=\"https://unpkg.com/highlightjs@9.12.0/styles/github.css\">\n  <link rel=\"stylesheet\" href=\"css/picker.css\">\n  <link rel=\"stylesheet\" href=\"css/main.css\">\n</head>\n<body>\n  <!--[if lt IE 9]>\n  <div class=\"alert alert-warning alert-dismissible fade show m-0 rounded-0\" role=\"alert\">\n    You are using an <strong>outdated</strong> browser. Please <a href=\"http://browsehappy.com/\">upgrade your browser</a> to improve your experience.\n    <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-label=\"Close\">\n      <span aria-hidden=\"true\">&times;</span>\n    </button>\n  </div>\n  <![endif]-->\n\n  <!-- Header -->\n  <header class=\"navbar navbar-light navbar-expand-md\">\n    <div class=\"container\">\n      <a class=\"navbar-brand\" href=\"./\">Picker.js</a>\n      <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\"#navbar-collapse\" aria-controls=\"navbar-collapse\" aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n        <span class=\"navbar-toggler-icon\"></span>\n      </button>\n      <div class=\"collapse navbar-collapse justify-content-end\" id=\"navbar-collapse\" role=\"navigation\">\n        <nav class=\"nav navbar-nav\">\n          <a class=\"nav-link\" href=\"https://github.com/fengyuanchen/pickerjs/blob/master/README.md\">Docs</a>\n          <a class=\"nav-link\" href=\"https://github.com/fengyuanchen/pickerjs\">GitHub</a>\n          <a class=\"nav-link\" href=\"https://fengyuanchen.github.io\">Explore</a>\n          <a class=\"nav-link\" href=\"https://chenfengyuan.com\">About</a>\n        </nav>\n      </div>\n    </nav>\n  </header>\n\n  <!-- Jumbotron -->\n  <div class=\"jumbotron bg-primary text-white rounded-0\">\n    <div class=\"container\">\n      <div class=\"row\">\n        <div class=\"col-md\">\n          <h1>Picker.js <small class=\"h6\">v1.2.1</small></h1>\n          <p class=\"lead\">JavaScript date time picker.</p>\n        </div>\n        <div class=\"col-md\">\n          <div class=\"carbonads\">\n            <script id=\"_carbonads_js\" src=\"https://cdn.carbonads.com/carbon.js?serve=CKYI55Q7&placement=fengyuanchengithubio\" async></script>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n\n  <!-- Content -->\n  <div class=\"container\">\n    <h1>Overview</h1>\n    <hr>\n    <div class=\"row\">\n      <div class=\"col-sm-6 col-md-4\">\n        <h3>Demo</h3>\n        <hr>\n        <div class=\"docs-picker\">\n          <input type=\"text\" class=\"form-control docs-date\" name=\"date\" placeholder=\"Pick a date and time\">\n          <div class=\"docs-picker-container\"></div>\n        </div>\n        <br>\n      </div>\n      <div class=\"col-sm-6 col-md-4\">\n        <h3>Options</h3>\n        <hr>\n        <div class=\"docs-options\">\n          <ul class=\"list-group mb-2\">\n            <li class=\"list-group-item\">\n              <div class=\"form-check\">\n                <input type=\"checkbox\" class=\"form-check-input\" id=\"container\" name=\"container\">\n                <label class=\"form-check-label\" for=\"container\">container</label>\n              </div>\n            </li>\n            <li class=\"list-group-item\">\n              <div class=\"form-check\">\n                <input type=\"checkbox\" class=\"form-check-input\" id=\"controls\" name=\"controls\">\n                <label class=\"form-check-label\" for=\"controls\">controls</label>\n              </div>\n            </li>\n            <li class=\"list-group-item\">\n              <div class=\"form-check\">\n                <input type=\"checkbox\" class=\"form-check-input\" id=\"headers\" name=\"headers\">\n                <label class=\"form-check-label\" for=\"headers\">headers</label>\n              </div>\n            </li>\n            <li class=\"list-group-item\">\n              <div class=\"form-check\">\n                <input type=\"checkbox\" class=\"form-check-input\" id=\"inline\" name=\"inline\">\n                <label class=\"form-check-label\" for=\"inline\">inline</label>\n              </div>\n            </li>\n          </ul>\n          <div class=\"input-group\">\n            <span class=\"input-group-prepend\">\n              <label class=\"input-group-text\" for=\"date\">date</label>\n            </span>\n            <input type=\"text\" class=\"form-control\" id=\"date\" name=\"date\" placeholder=\"null\">\n          </div>\n          <div class=\"input-group\">\n            <span class=\"input-group-prepend\">\n              <label class=\"input-group-text\" for=\"format\">format</label>\n            </span>\n            <input type=\"text\" class=\"form-control\" id=\"format\" name=\"format\" value=\"YYYY-MM-DD HH:mm\" placeholder=\"YYYY-MM-DD HH:mm\">\n          </div>\n          <div class=\"input-group\">\n            <span class=\"input-group-prepend\">\n              <label class=\"input-group-text\" for=\"language\">language</label>\n            </span>\n            <select class=\"form-control\" id=\"language\" name=\"language\">\n              <option value=\"\">(Default)</option>\n              <option value=\"en-US\">en-US</option>\n              <option value=\"en-GB\">en-GB</option>\n              <option value=\"pl-PL\">pl-PL</option>\n              <option value=\"zh-CN\">zh-CN</option>\n            </select>\n          </div>\n          <div class=\"input-group\">\n            <span class=\"input-group-prepend\">\n              <label class=\"input-group-text\" for=\"rows\">rows</label>\n            </span>\n            <select class=\"form-control\" id=\"rows\" name=\"rows\">\n              <option value=\"1\">1</option>\n              <option value=\"3\">3</option>\n              <option value=\"5\" selected>5</option>\n              <option value=\"7\">7</option>\n              <option value=\"9\">9</option>\n            </select>\n          </div>\n        </div>\n        <br>\n      </div>\n      <div class=\"col-sm-6 col-md-4\">\n        <h3>Methods</h3>\n        <hr>\n        <div class=\"docs-methods\">\n          <div class=\"input-group\">\n            <div class=\"input-group-prepend\">\n              <button type=\"button\" class=\"btn btn-primary\" data-method=\"getDate\" data-related-target=\"#putDate\">Get Date</button>\n            </div>\n            <input type=\"text\" class=\"form-control\" id=\"putDate\">\n          </div>\n          <div class=\"input-group\">\n            <div class=\"input-group-prepend\">\n              <button type=\"button\" class=\"btn btn-primary\" data-args=\"[true]\" data-method=\"getDate\" data-related-target=\"#putDateFormatted\">Get Date (formatted)</button>\n            </div>\n            <input type=\"text\" class=\"form-control\" id=\"putDateFormatted\">\n          </div>\n          <button type=\"button\" class=\"btn btn-block btn-primary\" data-method=\"show\">Show</button>\n          <button type=\"button\" class=\"btn btn-block btn-primary\" data-method=\"pick\">Pick</button>\n          <button type=\"button\" class=\"btn btn-block btn-primary\" data-method=\"update\">Update</button>\n          <button type=\"button\" class=\"btn btn-block btn-primary\" data-method=\"reset\">Reset</button>\n          <button type=\"button\" class=\"btn btn-block btn-danger\" data-method=\"destroy\">Destroy</button>\n        </div>\n      </div>\n    </div>\n\n    <h1>Examples</h1>\n    <hr>\n\n    <div class=\"card mb-4\">\n      <h4 class=\"card-header\">Date Picker</h4>\n      <div class=\"card-body\">\n        <h6>Demo</h6>\n        <input type=\"text\" class=\"form-control js-date-picker\" value=\"Oct 24, 2048\">\n        <br>\n        <h6>HTML</h6>\n        <pre class=\"html\"><code>\n&lt;input type=&quot;text&quot; class=&quot;form-control js-date-picker&quot; value=&quot;Oct 24, 2048&quot;&gt;\n</code></pre>\n        <h6>JavaScript</h6>\n        <pre class=\"js\"><code>new Picker(document.querySelector('.js-date-picker'), {\n  format: 'MMM D, YYYY',\n  text: {\n    title: 'Pick a date',\n  },\n});</code></pre>\n      </div>\n    </div>\n\n    <div class=\"card mb-4\">\n      <h4 class=\"card-header\">Time Picker</h4>\n      <div class=\"card-body\">\n        <h6>Demo</h6>\n        <input type=\"text\" class=\"form-control js-time-picker\" value=\"02:56\">\n        <br>\n        <h6>HTML</h6>\n        <pre class=\"html\"><code>\n&lt;input type=&quot;text&quot; class=&quot;form-control js-time-picker&quot; value=&quot;02:56&quot;&gt;\n</code></pre>\n        <h6>JavaScript</h6>\n        <pre class=\"js\"><code>new Picker(document.querySelector('.js-time-picker'), {\n  format: 'HH:mm',\n  headers: true,\n  text: {\n    title: 'Pick a time',\n  },\n});</code></pre>\n      </div>\n    </div>\n\n    <div class=\"card mb-4\">\n      <h4 class=\"card-header\">Full Picker</h4>\n      <div class=\"card-body\">\n        <h6>Demo</h6>\n        <input type=\"text\" class=\"form-control js-full-picker\" value=\"2048-10-24 05:12:02.056\">\n        <br>\n        <h6>HTML</h6>\n        <pre class=\"html\"><code>\n&lt;input type=&quot;text&quot; class=&quot;form-control js-full-picker&quot; value=&quot;2048-10-24 05:12:02.056&quot;&gt;\n</code></pre>\n        <h6>JavaScript</h6>\n        <pre class=\"js\"><code>new Picker(document.querySelector('.js-full-picker'), {\n  controls: true,\n  format: 'YYYY-MM-DD HH:mm:ss.SSS',\n  headers: true,\n});</code></pre>\n      </div>\n    </div>\n\n    <div class=\"card mb-4\">\n      <h4 class=\"card-header\">Month Picker</h4>\n      <div class=\"card-body\">\n        <h6>Demo</h6>\n        <input type=\"text\" class=\"form-control js-month-picker\" value=\"November\">\n        <br>\n        <h6>HTML</h6>\n        <pre class=\"html\"><code>\n&lt;input type=&quot;text&quot; class=&quot;form-control js-month-picker&quot; value=&quot;November&quot;&gt;\n</code></pre>\n        <h6>JavaScript</h6>\n        <pre class=\"js\"><code>new Picker(document.querySelector('.js-month-picker'), {\n  format: 'MMMM',\n  text: {\n    title: 'Pick a month',\n  },\n});</code></pre>\n      </div>\n    </div>\n\n    <div class=\"card mb-4\">\n      <h4 class=\"card-header\">Inline Picker</h4>\n      <div class=\"card-body\">\n        <h6>Demo</h6>\n        <div class=\"js-inline-picker\">2048-10-24 05:12</div>\n        <br>\n        <h6>HTML</h6>\n        <pre class=\"html\"><code>\n&lt;div class=&quot;js-inline-picker&quot;&gt;2048-10-24 05:12&lt;/div&gt;\n</code></pre>\n        <h6>JavaScript</h6>\n        <pre class=\"js\"><code>new Picker(document.querySelector('.js-inline-picker'), {\n  controls: true,\n  inline: true,\n});</code></pre>\n      </div>\n    </div>\n\n    <div class=\"card mb-4\">\n      <h4 class=\"card-header\">Mini Picker</h4>\n      <div class=\"card-body\">\n        <h6>Demo</h6>\n        <input type=\"text\" class=\"form-control sr-only js-mini-picker\">\n        <div class=\"js-mini-picker-container\"></div>\n        <br>\n        <h6>HTML</h6>\n        <pre class=\"html\"><code>\n&lt;input type=&quot;text&quot; class=&quot;form-control sr-only js-mini-picker&quot;&gt;\n&lt;div class=&quot;js-mini-picker-container&quot;&gt;&lt;/div&gt;\n</code></pre>\n        <h6>JavaScript</h6>\n        <pre class=\"js\"><code>new Picker(document.querySelector('.js-mini-picker'), {\n  container: '.js-mini-picker-container',\n  inline: true,\n  rows: 1,\n});</code></pre>\n      </div>\n    </div>\n\n    <div class=\"card mb-4\">\n      <h4 class=\"card-header\">Super Picker / I18n</h4>\n      <div class=\"card-body\">\n        <h6>Demo</h6>\n        <input type=\"text\" class=\"form-control js-super-picker\" value=\"2020年2月20日2时20分\">\n        <div class=\"js-super-picker-container\"></div>\n        <br>\n        <h6>HTML</h6>\n        <pre class=\"html\"><code>\n&lt;input type=&quot;text&quot; class=&quot;form-control js-super-picker&quot; value=&quot;2020年2月20日2时20分&quot;&gt;\n&lt;div class=&quot;js-super-picker-container&quot;&gt;&lt;/div&gt;\n</code></pre>\n        <h6>CSS</h6>\n        <pre class=\"css\"><code>.js-super-picker-container .picker-years {\n  width: 28%;\n}</code></pre>\n        <h6>JavaScript</h6>\n        <pre class=\"js\"><code>new Picker(document.querySelector('.js-super-picker'), {\n  container: '.js-super-picker-container',\n  format: 'YYYY年M月D日H时m分',\n  increment: {\n    minute: 10,\n  },\n  text: {\n    title: '选择日期时间',\n    cancel: '取消',\n    confirm: '确认',\n  },\n  translate(type, text) {\n    const suffixes = {\n      year: '年',\n      month: '月',\n      day: '日',\n      hour: '时',\n      minute: '分',\n    };\n\n    return Number(text) + suffixes[type];\n  },\n});</code></pre>\n      </div>\n    </div>\n\n  </div>\n\n  <!-- Footer -->\n  <footer class=\"footer\">\n    <div class=\"container\">\n      <p class=\"heart\"></p>\n      <nav class=\"nav flex-wrap justify-content-center mb-3\">\n        <a class=\"nav-link\" href=\"https://github.com/fengyuanchen/pickerjs\">GitHub</a>\n        <a class=\"nav-link\" href=\"https://github.com/fengyuanchen/pickerjs/releases\">Releases</a>\n        <a class=\"nav-link\" href=\"https://github.com/fengyuanchen/pickerjs/blob/master/LICENSE\">License</a>\n        <a class=\"nav-link\" href=\"https://chenfengyuan.com\">About</a>\n      </nav>\n    </div>\n  </footer>\n\n  <!-- Scripts -->\n  <script src=\"https://code.jquery.com/jquery-3.3.1.slim.min.js\"></script>\n  <script src=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js\"></script>\n  <script src=\"https://unpkg.com/highlightjs@9.12.0/highlight.pack.js\"></script>\n  <script src=\"https://fengyuanchen.github.io/shared/google-analytics.js\"></script>\n  <script src=\"js/picker.js\"></script>\n  <script src=\"js/picker.en-US.js\"></script>\n  <script src=\"js/picker.en-GB.js\"></script>\n  <script src=\"js/picker.pl-PL.js\"></script>\n  <script src=\"js/picker.zh-CN.js\"></script>\n  <script src=\"js/main.js\"></script>\n  <script>hljs.initHighlightingOnLoad();</script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/js/main.js",
    "content": "window.onload = function () {\n  'use strict';\n\n  var Picker = window.Picker;\n  var input = document.querySelector('.docs-date');\n  var pickerContainer = document.querySelector('.docs-picker-container');\n  var options = {\n    show: function (e) {\n      console.log(e.type);\n    },\n    shown: function (e) {\n      console.log(e.type);\n    },\n    hide: function (e) {\n      console.log(e.type);\n    },\n    hidden: function (e) {\n      console.log(e.type);\n    },\n    pick: function (e) {\n      console.log(e.type);\n    }\n  };\n  var picker = new Picker(input, options);\n\n  console.log(picker);\n\n  input.addEventListener('change', function (e) {\n    console.log(e.type);\n  }, false);\n\n  input.addEventListener('show', function (e) {\n    console.log(e.type);\n  }, false);\n\n  input.addEventListener('shown', function (e) {\n    console.log(e.type);\n  }, false);\n\n  input.addEventListener('hide', function (e) {\n    console.log(e.type);\n  }, false);\n\n  input.addEventListener('hidden', function (e) {\n    console.log(e.type);\n  }, false);\n\n  input.addEventListener('pick', function (e) {\n    console.log(e.type);\n  }, false);\n\n  document.querySelector('.docs-options').addEventListener('change', function (e) {\n    if (!picker) {\n      return;\n    }\n\n    var target = e.target;\n    var type = target.type;\n    var name = target.name;\n    var value = type === 'checkbox' ? target.checked : target.value;\n    var relatedElement;\n\n    switch (name) {\n      case 'container':\n        if (value) {\n          value = pickerContainer;\n          pickerContainer.style.display = 'block';\n        } else {\n          pickerContainer.style.display = 'none';\n        }\n\n        break;\n\n      case 'inline':\n        relatedElement = document.querySelector('input[name=\"container\"]');\n\n        if (!relatedElement.checked) {\n          relatedElement.click();\n        }\n\n        break;\n\n      case 'language':\n        relatedElement = document.querySelector('input[name=\"format\"]');\n\n        setTimeout(function () {\n          relatedElement.placeholder = relatedElement.value = picker.options.format;\n        }, 0);\n        break;\n\n      // No default\n    }\n\n    options[name] = value;\n    picker.destroy();\n    picker = new Picker(input, options);\n  }, false);\n\n  document.querySelector('.docs-methods').addEventListener('click', function (e) {\n    if (!picker) {\n      return;\n    }\n\n    var target = e.target;\n    var method = target.getAttribute('data-method');\n    var relatedTarget;\n    var result;\n\n    if (method) {\n      result = picker[method].apply(picker, JSON.parse(target.getAttribute('data-args')));\n      relatedTarget = target.getAttribute('data-related-target');\n\n      if (relatedTarget) {\n        document.querySelector(relatedTarget).value = result;\n      }\n\n      if (method === 'destroy') {\n        picker = null;\n      }\n    }\n  });\n\n\n  // Examples\n  // --------------------------------------------------\n\n  new Picker(document.querySelector('.js-date-picker'), {\n    format: 'MMM D, YYYY',\n    text: {\n      title: 'Pick a date',\n    },\n  });\n\n  new Picker(document.querySelector('.js-time-picker'), {\n    format: 'HH:mm',\n    headers: true,\n    text: {\n      title: 'Pick a time',\n    },\n  });\n\n  new Picker(document.querySelector('.js-full-picker'), {\n    controls: true,\n    format: 'YYYY-MM-DD HH:mm:ss.SSS',\n    headers: true,\n  });\n\n  new Picker(document.querySelector('.js-month-picker'), {\n    format: 'MMMM',\n    text: {\n      title: 'Pick a month',\n    },\n  });\n\n  new Picker(document.querySelector('.js-inline-picker'), {\n    controls: true,\n    inline: true,\n  });\n\n  new Picker(document.querySelector('.js-mini-picker'), {\n    container: '.js-mini-picker-container',\n    inline: true,\n    rows: 1,\n  });\n\n  new Picker(document.querySelector('.js-super-picker'), {\n    container: '.js-super-picker-container',\n    format: 'YYYY年M月D日H时m分',\n    increment: {\n      minute: 10,\n    },\n    text: {\n      title: '选择日期时间',\n      cancel: '取消',\n      confirm: '确认',\n    },\n    translate(type, text) {\n      const suffixes = {\n        year: '年',\n        month: '月',\n        day: '日',\n        hour: '时',\n        minute: '分',\n      };\n\n      return Number(text) + suffixes[type];\n    },\n  });\n};\n"
  },
  {
    "path": "docs/js/picker.en-GB.js",
    "content": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) : factory(global.Picker);\n}(typeof self !== 'undefined' ? self : this, function (Picker) {\n  'use strict';\n\n  Picker.languages['en-GB'] = {\n    format: 'DD/MM/YYYY HH:mm'\n  };\n}));\n"
  },
  {
    "path": "docs/js/picker.en-US.js",
    "content": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) : factory(global.Picker);\n}(typeof self !== 'undefined' ? self : this, function (Picker) {\n  'use strict';\n\n  Picker.languages['en-US'] = {\n    format: 'MM/DD/YYYY HH:mm'\n  };\n}));\n"
  },
  {
    "path": "docs/js/picker.js",
    "content": "/*!\n * Picker.js v1.2.1\n * https://fengyuanchen.github.io/pickerjs\n *\n * Copyright 2016-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2019-02-18T13:08:12.801Z\n */\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) :\n  (global = global || self, global.Picker = factory());\n}(this, function () { 'use strict';\n\n  function _typeof(obj) {\n    if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n      _typeof = function (obj) {\n        return typeof obj;\n      };\n    } else {\n      _typeof = function (obj) {\n        return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n      };\n    }\n\n    return _typeof(obj);\n  }\n\n  function _classCallCheck(instance, Constructor) {\n    if (!(instance instanceof Constructor)) {\n      throw new TypeError(\"Cannot call a class as a function\");\n    }\n  }\n\n  function _defineProperties(target, props) {\n    for (var i = 0; i < props.length; i++) {\n      var descriptor = props[i];\n      descriptor.enumerable = descriptor.enumerable || false;\n      descriptor.configurable = true;\n      if (\"value\" in descriptor) descriptor.writable = true;\n      Object.defineProperty(target, descriptor.key, descriptor);\n    }\n  }\n\n  function _createClass(Constructor, protoProps, staticProps) {\n    if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n    if (staticProps) _defineProperties(Constructor, staticProps);\n    return Constructor;\n  }\n\n  function _toConsumableArray(arr) {\n    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();\n  }\n\n  function _arrayWithoutHoles(arr) {\n    if (Array.isArray(arr)) {\n      for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];\n\n      return arr2;\n    }\n  }\n\n  function _iterableToArray(iter) {\n    if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter);\n  }\n\n  function _nonIterableSpread() {\n    throw new TypeError(\"Invalid attempt to spread non-iterable instance\");\n  }\n\n  var DEFAULTS = {\n    // Define the container for putting the picker.\n    container: null,\n    // Indicate whether show the prev and next arrow controls on each column.\n    controls: false,\n    // The initial date. If not present, use the current date.\n    date: null,\n    // The date string format, also as the sorting order for columns.\n    format: 'YYYY-MM-DD HH:mm',\n    // Indicate whether show the column headers.\n    headers: false,\n    // Define the increment for each date / time part.\n    increment: 1,\n    // Enable inline mode.\n    inline: false,\n    // Define the language. (An ISO language code).\n    language: '',\n    // Months' name.\n    months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],\n    // Shorter months' name.\n    monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n    // Define the number of rows for showing.\n    rows: 5,\n    // Define the text of the picker.\n    text: {\n      title: 'Pick a date and time',\n      cancel: 'Cancel',\n      confirm: 'OK',\n      year: 'Year',\n      month: 'Month',\n      day: 'Day',\n      hour: 'Hour',\n      minute: 'Minute',\n      second: 'Second',\n      millisecond: 'Millisecond'\n    },\n    // Translate date / time text.\n    translate: function translate(type, text) {\n      return text;\n    },\n    // Shortcuts of custom events.\n    show: null,\n    shown: null,\n    hide: null,\n    hidden: null,\n    pick: null\n  };\n\n  var TEMPLATE = '<div class=\"picker\" data-picker-action=\"hide\" touch-action=\"none\" tabindex=\"-1\" role=\"dialog\">' + '<div class=\"picker-dialog\" role=\"document\">' + '<div class=\"picker-header\">' + '<h4 class=\"picker-title\">{{ title }}</h4>' + '<button type=\"button\" class=\"picker-close\" data-picker-action=\"hide\" aria-label=\"Close\">&times;</button>' + '</div>' + '<div class=\"picker-body\">' + '<div class=\"picker-grid\"></div>' + '</div>' + '<div class=\"picker-footer\">' + '<button type=\"button\" class=\"picker-cancel\" data-picker-action=\"hide\">{{ cancel }}</button>' + '<button type=\"button\" class=\"picker-confirm\" data-picker-action=\"pick\">{{ confirm }}</button>' + '</div>' + '</div>' + '</div>';\n\n  var IS_BROWSER = typeof window !== 'undefined';\n  var WINDOW = IS_BROWSER ? window : {};\n  var IS_TOUCH_DEVICE = IS_BROWSER ? 'ontouchstart' in WINDOW.document.documentElement : false;\n  var HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;\n  var NAMESPACE = 'picker';\n  var LANGUAGES = {}; // Actions\n\n  var ACTION_HIDE = 'hide';\n  var ACTION_NEXT = 'next';\n  var ACTION_PICK = 'pick';\n  var ACTION_PREV = 'prev'; // Classes\n\n  var CLASS_OPEN = \"\".concat(NAMESPACE, \"-open\");\n  var CLASS_OPENED = \"\".concat(NAMESPACE, \"-opened\");\n  var CLASS_PICKED = \"\".concat(NAMESPACE, \"-picked\"); // Data keys\n  // Add namespace to avoid to conflict to some other libraries.\n\n  var DATA_ACTION = \"\".concat(NAMESPACE, \"Action\");\n  var DATA_TOKEN = 'token';\n  var DATA_TYPE = 'type';\n  var DATA_NAME = 'name';\n  var DATA_VALUE = 'value'; // Events\n\n  var EVENT_CLICK = 'click';\n  var EVENT_FOCUS = 'focus';\n  var EVENT_HIDDEN = 'hidden';\n  var EVENT_HIDE = 'hide';\n  var EVENT_KEY_DOWN = 'keydown';\n  var EVENT_PICK = 'pick';\n  var EVENT_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown';\n  var EVENT_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'touchmove' : 'mousemove';\n  var EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup';\n  var EVENT_POINTER_DOWN = HAS_POINTER_EVENT ? 'pointerdown' : EVENT_TOUCH_START;\n  var EVENT_POINTER_MOVE = HAS_POINTER_EVENT ? 'pointermove' : EVENT_TOUCH_MOVE;\n  var EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END;\n  var EVENT_SHOW = 'show';\n  var EVENT_SHOWN = 'shown';\n  var EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll';\n\n  var _Object$prototype = Object.prototype,\n      hasOwnProperty = _Object$prototype.hasOwnProperty,\n      toString = _Object$prototype.toString;\n  /**\n   * Detect the type of the given value.\n   * @param {*} value - The value to detect.\n   * @returns {string} Returns the type.\n   */\n\n  function typeOf(value) {\n    return toString.call(value).slice(8, -1).toLowerCase();\n  }\n  /**\n   * Check if the given value is a string.\n   * @param {*} value - The value to check.\n   * @returns {boolean} Returns `true` if the given value is a string, else `false`.\n   */\n\n  function isString(value) {\n    return typeof value === 'string';\n  }\n  /**\n   * Check if the given value is finite.\n   */\n\n  var isFinite = Number.isFinite || WINDOW.isFinite;\n  /**\n   * Check if the given value is not a number.\n   */\n\n  var isNaN = Number.isNaN || WINDOW.isNaN;\n  /**\n   * Check if the given value is a number.\n   * @param {*} value - The value to check.\n   * @returns {boolean} Returns `true` if the given value is a number, else `false`.\n   */\n\n  function isNumber(value) {\n    return typeof value === 'number' && !isNaN(value);\n  }\n  /**\n   * Check if the given value is an object.\n   * @param {*} value - The value to check.\n   * @returns {boolean} Returns `true` if the given value is an object, else `false`.\n   */\n\n  function isObject(value) {\n    return _typeof(value) === 'object' && value !== null;\n  }\n  /**\n   * Check if the given value is a plain object.\n   * @param {*} value - The value to check.\n   * @returns {boolean} Returns `true` if the given value is a plain object, else `false`.\n   */\n\n  function isPlainObject(value) {\n    if (!isObject(value)) {\n      return false;\n    }\n\n    try {\n      var _constructor = value.constructor;\n      var prototype = _constructor.prototype;\n      return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');\n    } catch (error) {\n      return false;\n    }\n  }\n  /**\n   * Check if the given value is a function.\n   * @param {*} value - The value to check.\n   * @returns {boolean} Returns `true` if the given value is a function, else `false`.\n   */\n\n  function isFunction(value) {\n    return typeof value === 'function';\n  }\n  /**\n   * Check if the given value is a date.\n   * @param {*} value - The value to check.\n   * @returns {boolean} Returns `true` if the given value is a date, else `false`.\n   */\n\n  function isDate(value) {\n    return typeOf(value) === 'date';\n  }\n  /**\n   * Check if the given value is a valid date.\n   * @param {*} value - The value to check.\n   * @returns {boolean} Returns `true` if the given value is a valid date, else `false`.\n   */\n\n  function isValidDate(value) {\n    return isDate(value) && value.toString() !== 'Invalid Date';\n  }\n  /**\n   * Iterate the given data.\n   * @param {*} data - The data to iterate.\n   * @param {Function} callback - The process function for each element.\n   * @returns {*} The original data.\n   */\n\n  function forEach(data, callback) {\n    if (data && isFunction(callback)) {\n      if (Array.isArray(data) || isNumber(data.length)\n      /* array-like */\n      ) {\n          var length = data.length;\n          var i;\n\n          for (i = 0; i < length; i += 1) {\n            if (callback.call(data, data[i], i, data) === false) {\n              break;\n            }\n          }\n        } else if (isObject(data)) {\n        Object.keys(data).forEach(function (key) {\n          callback.call(data, data[key], key, data);\n        });\n      }\n    }\n\n    return data;\n  }\n  /**\n   * Recursively assigns own enumerable properties of source objects to the target object.\n   * @param {Object} target - The target object.\n   * @param {Object[]} sources - The source objects.\n   * @returns {Object} The target object.\n   */\n\n  function deepAssign(target) {\n    for (var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n      sources[_key - 1] = arguments[_key];\n    }\n\n    if (isObject(target) && sources.length > 0) {\n      sources.forEach(function (source) {\n        if (isObject(source)) {\n          Object.keys(source).forEach(function (key) {\n            if (isPlainObject(target[key]) && isPlainObject(source[key])) {\n              target[key] = deepAssign({}, target[key], source[key]);\n            } else {\n              target[key] = source[key];\n            }\n          });\n        }\n      });\n    }\n\n    return target;\n  }\n  /**\n   * Add classes to the given element.\n   * @param {Element} element - The target element.\n   * @param {string} value - The classes to be added.\n   */\n\n  function addClass(element, value) {\n    if (!value) {\n      return;\n    }\n\n    if (isNumber(element.length)) {\n      forEach(element, function (elem) {\n        addClass(elem, value);\n      });\n      return;\n    }\n\n    if (element.classList) {\n      element.classList.add(value);\n      return;\n    }\n\n    var className = element.className.trim();\n\n    if (!className) {\n      element.className = value;\n    } else if (className.indexOf(value) < 0) {\n      element.className = \"\".concat(className, \" \").concat(value);\n    }\n  }\n  /**\n   * Remove classes from the given element.\n   * @param {Element} element - The target element.\n   * @param {string} value - The classes to be removed.\n   */\n\n  function removeClass(element, value) {\n    if (!value) {\n      return;\n    }\n\n    if (isNumber(element.length)) {\n      forEach(element, function (elem) {\n        removeClass(elem, value);\n      });\n      return;\n    }\n\n    if (element.classList) {\n      element.classList.remove(value);\n      return;\n    }\n\n    if (element.className.indexOf(value) >= 0) {\n      element.className = element.className.replace(value, '');\n    }\n  }\n  var REGEXP_HYPHENATE = /([a-z\\d])([A-Z])/g;\n  /**\n   * Transform the given string from camelCase to kebab-case\n   * @param {string} value - The value to transform.\n   * @returns {string} The transformed value.\n   */\n\n  function hyphenate(value) {\n    return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase();\n  }\n  /**\n   * Get data from the given element.\n   * @param {Element} element - The target element.\n   * @param {string} name - The data key to get.\n   * @returns {string} The data value.\n   */\n\n  function getData(element, name) {\n    if (isObject(element[name])) {\n      return element[name];\n    }\n\n    if (element.dataset) {\n      return element.dataset[name];\n    }\n\n    return element.getAttribute(\"data-\".concat(hyphenate(name)));\n  }\n  /**\n   * Set data to the given element.\n   * @param {Element} element - The target element.\n   * @param {string} name - The data key to set.\n   * @param {string} data - The data value.\n   */\n\n  function setData(element, name, data) {\n    if (isObject(data)) {\n      element[name] = data;\n    } else if (element.dataset) {\n      element.dataset[name] = data;\n    } else {\n      element.setAttribute(\"data-\".concat(hyphenate(name)), data);\n    }\n  }\n  /**\n   * Remove data from the given element.\n   * @param {Element} element - The target element.\n   * @param {string} name - The data key to remove.\n   */\n\n  function removeData(element, name) {\n    if (isObject(element[name])) {\n      try {\n        delete element[name];\n      } catch (error) {\n        element[name] = undefined;\n      }\n    } else if (element.dataset) {\n      // #128 Safari not allows to delete dataset property\n      try {\n        delete element.dataset[name];\n      } catch (error) {\n        element.dataset[name] = undefined;\n      }\n    } else {\n      element.removeAttribute(\"data-\".concat(hyphenate(name)));\n    }\n  }\n  var REGEXP_SPACES = /\\s\\s*/;\n\n  var onceSupported = function () {\n    var supported = false;\n\n    if (IS_BROWSER) {\n      var once = false;\n\n      var listener = function listener() {};\n\n      var options = Object.defineProperty({}, 'once', {\n        get: function get() {\n          supported = true;\n          return once;\n        },\n\n        /**\n         * This setter can fix a `TypeError` in strict mode\n         * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}\n         * @param {boolean} value - The value to set\n         */\n        set: function set(value) {\n          once = value;\n        }\n      });\n      WINDOW.addEventListener('test', listener, options);\n      WINDOW.removeEventListener('test', listener, options);\n    }\n\n    return supported;\n  }();\n  /**\n   * Remove event listener from the target element.\n   * @param {Element} element - The event target.\n   * @param {string} type - The event type(s).\n   * @param {Function} listener - The event listener.\n   * @param {Object} options - The event options.\n   */\n\n\n  function removeListener(element, type, listener) {\n    var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n    var handler = listener;\n    type.trim().split(REGEXP_SPACES).forEach(function (event) {\n      if (!onceSupported) {\n        var listeners = element.listeners;\n\n        if (listeners && listeners[event] && listeners[event][listener]) {\n          handler = listeners[event][listener];\n          delete listeners[event][listener];\n\n          if (Object.keys(listeners[event]).length === 0) {\n            delete listeners[event];\n          }\n\n          if (Object.keys(listeners).length === 0) {\n            delete element.listeners;\n          }\n        }\n      }\n\n      element.removeEventListener(event, handler, options);\n    });\n  }\n  /**\n   * Add event listener to the target element.\n   * @param {Element} element - The event target.\n   * @param {string} type - The event type(s).\n   * @param {Function} listener - The event listener.\n   * @param {Object} options - The event options.\n   */\n\n  function addListener(element, type, listener) {\n    var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n    var _handler = listener;\n    type.trim().split(REGEXP_SPACES).forEach(function (event) {\n      if (options.once && !onceSupported) {\n        var _element$listeners = element.listeners,\n            listeners = _element$listeners === void 0 ? {} : _element$listeners;\n\n        _handler = function handler() {\n          delete listeners[event][listener];\n          element.removeEventListener(event, _handler, options);\n\n          for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n            args[_key2] = arguments[_key2];\n          }\n\n          listener.apply(element, args);\n        };\n\n        if (!listeners[event]) {\n          listeners[event] = {};\n        }\n\n        if (listeners[event][listener]) {\n          element.removeEventListener(event, listeners[event][listener], options);\n        }\n\n        listeners[event][listener] = _handler;\n        element.listeners = listeners;\n      }\n\n      element.addEventListener(event, _handler, options);\n    });\n  }\n  /**\n   * Dispatch event on the target element.\n   * @param {Element} element - The event target.\n   * @param {string} type - The event type(s).\n   * @param {Object} data - The additional event data.\n   * @returns {boolean} Indicate if the event is default prevented or not.\n   */\n\n  function dispatchEvent(element, type, data) {\n    var event; // Event and CustomEvent on IE9-11 are global objects, not constructors\n\n    if (isFunction(Event) && isFunction(CustomEvent)) {\n      event = new CustomEvent(type, {\n        detail: data,\n        bubbles: true,\n        cancelable: true\n      });\n    } else {\n      event = document.createEvent('CustomEvent');\n      event.initCustomEvent(type, true, true, data);\n    }\n\n    return element.dispatchEvent(event);\n  }\n  /**\n   * Check if the given year is a leap year.\n   * @param {number} year - The year to check.\n   * @returns {boolean} Returns `true` if the given year is a leap year, else `false`.\n   */\n\n  function isLeapYear(year) {\n    return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;\n  }\n  /**\n   * Get days number of the given month.\n   * @param {number} year - The target year.\n   * @param {number} month - The target month.\n   * @returns {number} Returns days number.\n   */\n\n  function getDaysInMonth(year, month) {\n    return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];\n  }\n  /**\n   * Add leading zeroes to the given value\n   * @param {number} value - The value to add.\n   * @param {number} [length=1] - The number of the leading zeroes.\n   * @returns {string} Returns converted value.\n   */\n\n  function addLeadingZero(value) {\n    var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n    var str = String(Math.abs(value));\n    var i = str.length;\n    var result = '';\n\n    if (value < 0) {\n      result += '-';\n    }\n\n    while (i < length) {\n      i += 1;\n      result += '0';\n    }\n\n    return result + str;\n  }\n  /**\n   * Map token to type name\n   * @param {string} token - The token to map.\n   * @returns {string} Returns mapped type name.\n   */\n\n  function tokenToType(token) {\n    return {\n      Y: 'year',\n      M: 'month',\n      D: 'day',\n      H: 'hour',\n      m: 'minute',\n      s: 'second',\n      S: 'millisecond'\n    }[token.charAt(0)];\n  }\n  var REGEXP_TOKENS = /(Y|M|D|H|m|s|S)\\1*/g;\n  /**\n   * Parse date format.\n   * @param {string} format - The format to parse.\n   * @returns {Object} Returns parsed format data.\n   */\n\n  function parseFormat(format) {\n    var tokens = format.match(REGEXP_TOKENS);\n\n    if (!tokens) {\n      throw new Error('Invalid format.');\n    } // Remove duplicate tokens (#22)\n\n\n    tokens = tokens.filter(function (token, index) {\n      return tokens.indexOf(token) === index;\n    });\n    var result = {\n      tokens: tokens\n    };\n    tokens.forEach(function (token) {\n      result[tokenToType(token)] = token;\n    });\n    return result;\n  }\n\n  var events = {\n    bind: function bind() {\n      var element = this.element,\n          options = this.options,\n          grid = this.grid;\n\n      if (isFunction(options.show)) {\n        addListener(element, EVENT_SHOW, options.show);\n      }\n\n      if (isFunction(options.shown)) {\n        addListener(element, EVENT_SHOWN, options.shown);\n      }\n\n      if (isFunction(options.hide)) {\n        addListener(element, EVENT_HIDE, options.hide);\n      }\n\n      if (isFunction(options.hidden)) {\n        addListener(element, EVENT_HIDDEN, options.hidden);\n      }\n\n      if (isFunction(options.pick)) {\n        addListener(element, EVENT_PICK, options.pick);\n      }\n\n      addListener(element, EVENT_FOCUS, this.onFocus = this.focus.bind(this));\n      addListener(element, EVENT_CLICK, this.onFocus);\n      addListener(this.picker, EVENT_CLICK, this.onClick = this.click.bind(this));\n      addListener(grid, EVENT_WHEEL, this.onWheel = this.wheel.bind(this));\n      addListener(grid, EVENT_POINTER_DOWN, this.onPointerDown = this.pointerdown.bind(this));\n      addListener(document, EVENT_POINTER_MOVE, this.onPointerMove = this.pointermove.bind(this));\n      addListener(document, EVENT_POINTER_UP, this.onPointerUp = this.pointerup.bind(this));\n      addListener(document, EVENT_KEY_DOWN, this.onKeyDown = this.keydown.bind(this));\n    },\n    unbind: function unbind() {\n      var element = this.element,\n          options = this.options,\n          grid = this.grid;\n\n      if (isFunction(options.show)) {\n        removeListener(element, EVENT_SHOW, options.show);\n      }\n\n      if (isFunction(options.shown)) {\n        removeListener(element, EVENT_SHOWN, options.shown);\n      }\n\n      if (isFunction(options.hide)) {\n        removeListener(element, EVENT_HIDE, options.hide);\n      }\n\n      if (isFunction(options.hidden)) {\n        removeListener(element, EVENT_HIDDEN, options.hidden);\n      }\n\n      if (isFunction(options.pick)) {\n        removeListener(element, EVENT_PICK, options.pick);\n      }\n\n      removeListener(element, EVENT_FOCUS, this.onFocus);\n      removeListener(element, EVENT_CLICK, this.onFocus);\n      removeListener(this.picker, EVENT_CLICK, this.onClick);\n      removeListener(grid, EVENT_WHEEL, this.onWheel);\n      removeListener(grid, EVENT_POINTER_DOWN, this.onPointerDown);\n      removeListener(document, EVENT_POINTER_MOVE, this.onPointerMove);\n      removeListener(document, EVENT_POINTER_UP, this.onPointerUp);\n      removeListener(document, EVENT_KEY_DOWN, this.onKeyDown);\n    }\n  };\n\n  var handlers = {\n    focus: function focus(event) {\n      event.target.blur();\n      this.show();\n    },\n    click: function click(event) {\n      var target = event.target;\n      var action = getData(target, DATA_ACTION);\n\n      switch (action) {\n        case ACTION_HIDE:\n          this.hide();\n          break;\n\n        case ACTION_PICK:\n          this.pick();\n          break;\n\n        case ACTION_PREV:\n        case ACTION_NEXT:\n          this[action](getData(target.parentElement, DATA_TYPE));\n          break;\n\n        default:\n      }\n    },\n    wheel: function wheel(event) {\n      var target = event.target;\n\n      if (target === this.grid) {\n        return;\n      }\n\n      event.preventDefault();\n\n      while (target.parentElement && target.parentElement !== this.grid) {\n        target = target.parentElement;\n      }\n\n      var type = getData(target, DATA_TYPE);\n\n      if (event.deltaY < 0) {\n        this.prev(type);\n      } else {\n        this.next(type);\n      }\n    },\n    pointerdown: function pointerdown(event) {\n      var target = event.target;\n\n      if (target === this.grid || getData(target, DATA_ACTION)) {\n        return;\n      } // This line is required for preventing page scrolling in iOS browsers\n\n\n      event.preventDefault();\n\n      while (target.parentElement && target.parentElement !== this.grid) {\n        target = target.parentElement;\n      }\n\n      var list = target.querySelector(\".\".concat(NAMESPACE, \"-list\"));\n      var itemHeight = list.firstElementChild.offsetHeight;\n      this.cell = {\n        elem: target,\n        list: list,\n        moveY: 0,\n        maxMoveY: itemHeight,\n        minMoveY: itemHeight / 2,\n        startY: event.changedTouches ? event.changedTouches[0].pageY : event.pageY,\n        type: getData(target, DATA_TYPE)\n      };\n    },\n    pointermove: function pointermove(event) {\n      var cell = this.cell;\n\n      if (!cell) {\n        return;\n      }\n\n      event.preventDefault();\n      var endY = event.changedTouches ? event.changedTouches[0].pageY : event.pageY;\n      var moveY = cell.moveY + (endY - cell.startY);\n      cell.startY = endY;\n      cell.moveY = moveY;\n\n      if (Math.abs(moveY) < cell.maxMoveY) {\n        cell.list.style.top = \"\".concat(moveY, \"px\");\n        return;\n      }\n\n      cell.list.style.top = 0;\n      cell.moveY = 0;\n\n      if (moveY >= cell.maxMoveY) {\n        this.prev(cell.type);\n      } else if (moveY <= -cell.maxMoveY) {\n        this.next(cell.type);\n      }\n    },\n    pointerup: function pointerup(event) {\n      var cell = this.cell;\n\n      if (!cell) {\n        return;\n      }\n\n      event.preventDefault();\n      cell.list.style.top = 0;\n\n      if (cell.moveY >= cell.minMoveY) {\n        this.prev(cell.type);\n      } else if (cell.moveY <= -cell.minMoveY) {\n        this.next(cell.type);\n      }\n\n      this.cell = null;\n    },\n    keydown: function keydown(event) {\n      if (this.shown && (event.key === 'Escape' || event.keyCode === 27)) {\n        this.hide();\n      }\n    }\n  };\n\n  var helpers = {\n    render: function render(type) {\n      var _this = this;\n\n      if (!type) {\n        this.format.tokens.forEach(function (token) {\n          return _this.render(tokenToType(token));\n        });\n        return;\n      }\n\n      var options = this.options;\n      var data = this.data[type];\n      var current = this.current(type);\n      var max = isFunction(data.max) ? data.max() : data.max;\n      var min = isFunction(data.min) ? data.min() : data.min;\n      var base = 0;\n\n      if (isFinite(max)) {\n        base = min > 0 ? max : max + 1;\n      }\n\n      data.list.innerHTML = '';\n      data.current = current;\n\n      for (var i = 0; i < options.rows + 2; i += 1) {\n        var item = document.createElement('li');\n        var position = i - data.index;\n        var newValue = current + position * data.increment;\n\n        if (base) {\n          newValue %= base;\n\n          if (newValue < min) {\n            newValue += base;\n          }\n        }\n\n        item.textContent = options.translate(type, data.aliases ? data.aliases[newValue] : addLeadingZero(newValue + data.offset, data.digit));\n        setData(item, DATA_NAME, type);\n        setData(item, DATA_VALUE, newValue);\n        addClass(item, \"\".concat(NAMESPACE, \"-item\"));\n\n        if (position === 0) {\n          addClass(item, CLASS_PICKED);\n          data.item = item;\n        }\n\n        data.list.appendChild(item);\n      }\n    },\n    current: function current(type, value) {\n      var date = this.date;\n      var format = this.format;\n      var token = format[type];\n\n      switch (token.charAt(0)) {\n        case 'Y':\n          if (isNumber(value)) {\n            date.setFullYear(token.length === 2 ? 2000 + value : value);\n\n            if (format.month) {\n              this.render(tokenToType(format.month));\n            }\n\n            if (format.day) {\n              this.render(tokenToType(format.day));\n            }\n          }\n\n          return date.getFullYear();\n\n        case 'M':\n          if (isNumber(value)) {\n            date.setMonth(value, // The current day should not exceed its maximum day in current month\n            Math.min(date.getDate(), getDaysInMonth(date.getFullYear(), value)));\n\n            if (format.day) {\n              this.render(tokenToType(format.day));\n            }\n          }\n\n          return date.getMonth();\n\n        case 'D':\n          if (isNumber(value)) {\n            date.setDate(value);\n          }\n\n          return date.getDate();\n\n        case 'H':\n          if (isNumber(value)) {\n            date.setHours(value);\n          }\n\n          return date.getHours();\n\n        case 'm':\n          if (isNumber(value)) {\n            date.setMinutes(value);\n          }\n\n          return date.getMinutes();\n\n        case 's':\n          if (isNumber(value)) {\n            date.setSeconds(value);\n          }\n\n          return date.getSeconds();\n\n        case 'S':\n          if (isNumber(value)) {\n            date.setMilliseconds(value);\n          }\n\n          return date.getMilliseconds();\n\n        default:\n      }\n\n      return date;\n    },\n    getValue: function getValue() {\n      var element = this.element;\n      return this.isInput ? element.value : element.textContent;\n    },\n    setValue: function setValue(value) {\n      var element = this.element;\n\n      if (this.isInput) {\n        element.value = value;\n      } else if (this.options.container) {\n        element.textContent = value;\n      }\n    },\n    open: function open() {\n      var body = this.body;\n      body.style.overflow = 'hidden';\n      body.style.paddingRight = \"\".concat(this.scrollBarWidth + (parseFloat(this.initialBodyPaddingRight) || 0), \"px\");\n    },\n    close: function close() {\n      var body = this.body;\n      body.style.overflow = '';\n      body.style.paddingRight = this.initialBodyPaddingRight;\n    }\n  };\n\n  var methods = {\n    /**\n     * Show the picker.\n     * @param {boolean} [immediate=false] - Indicate if show the picker immediately or not.\n     * @returns {Picker} this\n     */\n    show: function show() {\n      var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n      var element = this.element,\n          picker = this.picker;\n\n      if (this.inline || this.shown) {\n        return this;\n      }\n\n      if (dispatchEvent(element, EVENT_SHOW) === false) {\n        return this;\n      }\n\n      this.shown = true;\n      this.open();\n      addClass(picker, CLASS_OPEN);\n\n      var done = function done() {\n        dispatchEvent(element, EVENT_SHOWN);\n      };\n\n      if (!immediate) {\n        // Reflow to enable transition\n        // eslint-disable-next-line\n        picker.offsetWidth;\n      }\n\n      addClass(picker, CLASS_OPENED);\n\n      if (immediate) {\n        done();\n      } else {\n        setTimeout(done, 300);\n      }\n\n      return this;\n    },\n\n    /**\n     * Hide the picker.\n     * @param {boolean} [immediate=false] - Indicate if hide the picker immediately or not.\n     * @returns {Picker} this\n     */\n    hide: function hide() {\n      var _this = this;\n\n      var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n      var element = this.element,\n          picker = this.picker;\n\n      if (this.inline || !this.shown) {\n        return this;\n      }\n\n      if (dispatchEvent(element, EVENT_HIDE) === false) {\n        return this;\n      }\n\n      this.shown = false;\n      removeClass(picker, CLASS_OPENED);\n\n      var done = function done() {\n        _this.close();\n\n        removeClass(picker, CLASS_OPEN);\n        dispatchEvent(element, EVENT_HIDDEN);\n      };\n\n      if (immediate) {\n        done();\n      } else {\n        setTimeout(done, 300);\n      }\n\n      return this;\n    },\n\n    /**\n     * Pick to the previous item.\n     * @param {string} type - The column type.\n     * @returns {Picker} this\n     */\n    prev: function prev(type) {\n      var options = this.options;\n      var token = this.format[type];\n      var data = this.data[type];\n      var list = data.list;\n      var item = list.lastElementChild;\n      var max = isFunction(data.max) ? data.max() : data.max;\n      var min = isFunction(data.min) ? data.min() : data.min;\n      var prev = data.item.previousElementSibling;\n      var value = Number(getData(list.firstElementChild, DATA_VALUE)) - data.increment;\n\n      if (value < min) {\n        value += max - min + 1;\n      }\n\n      item.textContent = options.translate(type, data.aliases ? data.aliases[value] : addLeadingZero(value + data.offset, token.length));\n      setData(item, DATA_VALUE, value);\n\n      if (prev) {\n        removeClass(data.item, CLASS_PICKED);\n        addClass(prev, CLASS_PICKED);\n        data.item = prev;\n      }\n\n      list.insertBefore(item, list.firstElementChild);\n      data.current = Number(getData(data.item, DATA_VALUE));\n      this.current(type, data.current);\n\n      if (this.inline && options.container) {\n        this.pick();\n      }\n\n      return this;\n    },\n\n    /**\n     * Pick to the next item.\n     * @param {String} type - The column type.\n     * @returns {Picker} this\n     */\n    next: function next(type) {\n      var options = this.options;\n      var token = this.format[type];\n      var data = this.data[type];\n      var list = data.list;\n      var item = list.firstElementChild;\n      var max = isFunction(data.max) ? data.max() : data.max;\n      var min = isFunction(data.min) ? data.min() : data.min;\n      var next = data.item.nextElementSibling;\n      var value = Number(getData(list.lastElementChild, DATA_VALUE)) + data.increment;\n\n      if (value > max) {\n        value -= max - min + 1;\n      }\n\n      item.textContent = options.translate(type, data.aliases ? data.aliases[value] : addLeadingZero(value + data.offset, token.length));\n      setData(item, DATA_VALUE, value);\n      list.appendChild(item);\n\n      if (next) {\n        removeClass(data.item, CLASS_PICKED);\n        addClass(next, CLASS_PICKED);\n        data.item = next;\n      }\n\n      data.current = Number(getData(data.item, DATA_VALUE));\n      this.current(type, data.current);\n\n      if (this.inline && options.container) {\n        this.pick();\n      }\n\n      return this;\n    },\n    // Pick the current date to the target element.\n    pick: function pick() {\n      var element = this.element;\n\n      if (dispatchEvent(element, EVENT_PICK) === false) {\n        return this;\n      }\n\n      var value = this.formatDate(this.date);\n      this.setValue(value);\n\n      if (this.isInput && dispatchEvent(element, 'change') === false) {\n        this.reset();\n      }\n\n      this.hide();\n      return this;\n    },\n\n    /**\n     * Get the current date.\n     * @param {boolean} [formatted=false] - Indicate if format the date or not.\n     * @return {Date|string} The output date.\n     */\n    getDate: function getDate() {\n      var formatted = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n      var date = this.date;\n      return formatted ? this.formatDate(date) : new Date(date);\n    },\n\n    /**\n     * Override the current date with a new date.\n     * @param {Date|string} date - The date to set.\n     * @returns {Picker} this\n     */\n    setDate: function setDate(date) {\n      if (date) {\n        this.date = this.parseDate(date);\n        this.render();\n      }\n\n      return this;\n    },\n    // Update the picker with the current element value / text.\n    update: function update() {\n      this.date = this.parseDate(this.getValue());\n      this.render();\n      return this;\n    },\n    // Reset the picker and element value / text.\n    reset: function reset() {\n      this.setValue(this.initialValue);\n      this.date = new Date(this.initialDate);\n      this.render();\n      return this;\n    },\n\n    /**\n     * Parse a date with the set date format.\n     * @param {Date|string} date - The date to parse.\n     * @returns {Date} The parsed date object.\n     */\n    parseDate: function parseDate(date) {\n      var options = this.options,\n          format = this.format;\n      var digits = [];\n\n      if (isDate(date)) {\n        return new Date(date);\n      }\n\n      if (isString(date)) {\n        var groups = [].concat(_toConsumableArray(options.months), _toConsumableArray(options.monthsShort), ['\\\\d+']);\n        digits = date.match(new RegExp(\"(\".concat(groups.join('|'), \")\"), 'g')); // Parse `11111111` (YYYYMMDD) to ['1111', '11', '11']\n\n        if (digits && date.length === options.format.length && digits.length !== format.tokens.length) {\n          digits = format.tokens.map(function (token) {\n            return date.substr(options.format.indexOf(token), token.length);\n          });\n        }\n\n        if (!digits || digits.length !== format.tokens.length) {\n          return new Date();\n        }\n      }\n\n      var parsedDate = new Date();\n      digits.forEach(function (digit, i) {\n        var token = format.tokens[i];\n        var n = Number(digit);\n\n        switch (token) {\n          case 'YYYY':\n          case 'YYY':\n          case 'Y':\n            {\n              var index = date.indexOf(digit);\n              var isHyphen = date.substr(index - 1, 1) === '-';\n              var isBC = index > 1 && isHyphen && /\\S/.test(date.substr(index - 2, 1)) || index === 1 && isHyphen;\n              parsedDate.setFullYear(isBC ? -n : n);\n              break;\n            }\n\n          case 'YY':\n            parsedDate.setFullYear(2000 + n);\n            break;\n\n          case 'MMMM':\n            parsedDate.setMonth(options.months.indexOf(digit));\n            break;\n\n          case 'MMM':\n            parsedDate.setMonth(options.monthsShort.indexOf(digit));\n            break;\n\n          case 'MM':\n          case 'M':\n            parsedDate.setMonth(n - 1);\n            break;\n\n          case 'DD':\n          case 'D':\n            parsedDate.setDate(n);\n            break;\n\n          case 'HH':\n          case 'H':\n            parsedDate.setHours(n);\n            break;\n\n          case 'mm':\n          case 'm':\n            parsedDate.setMinutes(n);\n            break;\n\n          case 'ss':\n          case 's':\n            parsedDate.setSeconds(n);\n            break;\n\n          case 'SSS':\n          case 'SS':\n          case 'S':\n            parsedDate.setMilliseconds(n);\n            break;\n\n          default:\n        }\n      });\n      return parsedDate;\n    },\n\n    /**\n     * Format a date object to a string with the set date format.\n     * @param {Date} date - The date to format.\n     * @return {string} THe formatted date.\n     */\n    formatDate: function formatDate(date) {\n      var options = this.options,\n          format = this.format;\n      var formatted = '';\n\n      if (isValidDate(date)) {\n        var year = date.getFullYear();\n        var month = date.getMonth();\n        var day = date.getDate();\n        var hours = date.getHours();\n        var minutes = date.getMinutes();\n        var seconds = date.getSeconds();\n        var milliseconds = date.getMilliseconds();\n        formatted = options.format;\n        format.tokens.forEach(function (token) {\n          var replacement = '';\n\n          switch (token) {\n            case 'YYYY':\n            case 'YYY':\n            case 'Y':\n              replacement = addLeadingZero(year, token.length);\n              break;\n\n            case 'YY':\n              replacement = addLeadingZero(year % 100, 2);\n              break;\n\n            case 'MMMM':\n              replacement = options.months[month];\n              break;\n\n            case 'MMM':\n              replacement = options.monthsShort[month];\n              break;\n\n            case 'MM':\n            case 'M':\n              replacement = addLeadingZero(month + 1, token.length);\n              break;\n\n            case 'DD':\n            case 'D':\n              replacement = addLeadingZero(day, token.length);\n              break;\n\n            case 'HH':\n            case 'H':\n              replacement = addLeadingZero(hours, token.length);\n              break;\n\n            case 'mm':\n            case 'm':\n              replacement = addLeadingZero(minutes, token.length);\n              break;\n\n            case 'ss':\n            case 's':\n              replacement = addLeadingZero(seconds, token.length);\n              break;\n\n            case 'SSS':\n            case 'SS':\n            case 'S':\n              replacement = addLeadingZero(milliseconds, token.length);\n              break;\n\n            default:\n          }\n\n          formatted = formatted.replace(token, replacement);\n        });\n      }\n\n      return formatted;\n    },\n    // Destroy the picker and remove the instance from the target element.\n    destroy: function destroy() {\n      var element = this.element,\n          picker = this.picker;\n\n      if (!getData(element, NAMESPACE)) {\n        return this;\n      }\n\n      this.hide(true);\n      this.unbind();\n      removeData(element, NAMESPACE);\n      picker.parentNode.removeChild(picker);\n      return this;\n    }\n  };\n\n  var REGEXP_DELIMITER = /\\{\\{\\s*(\\w+)\\s*\\}\\}/g;\n  var REGEXP_INPUTS = /input|textarea/i;\n  var AnotherPicker = WINDOW.Picker;\n\n  var Picker =\n  /*#__PURE__*/\n  function () {\n    /**\n     * Create a new Picker.\n     * @param {Element} element - The target element for picking.\n     * @param {Object} [options={}] - The configuration options.\n     */\n    function Picker(element) {\n      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n      _classCallCheck(this, Picker);\n\n      if (!element || element.nodeType !== 1) {\n        throw new Error('The first argument is required and must be an element.');\n      }\n\n      this.element = element;\n      this.options = deepAssign({}, DEFAULTS, LANGUAGES[options.language], isPlainObject(options) && options);\n      this.shown = false;\n      this.init();\n    }\n\n    _createClass(Picker, [{\n      key: \"init\",\n      value: function init() {\n        var _this = this;\n\n        var element = this.element;\n\n        if (getData(element, NAMESPACE)) {\n          return;\n        }\n\n        setData(element, NAMESPACE, this);\n        var options = this.options;\n        var isInput = REGEXP_INPUTS.test(element.tagName);\n        var inline = options.inline && (options.container || !isInput);\n        var template = document.createElement('div');\n        template.insertAdjacentHTML('afterbegin', TEMPLATE.replace(REGEXP_DELIMITER, function () {\n          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n            args[_key] = arguments[_key];\n          }\n\n          return options.text[args[1]];\n        }));\n        var picker = template.getElementsByClassName(NAMESPACE)[0];\n        var grid = picker.getElementsByClassName(\"\".concat(NAMESPACE, \"-grid\"))[0];\n        var container = options.container;\n\n        if (isString(container)) {\n          container = document.querySelector(container);\n        }\n\n        if (inline) {\n          addClass(picker, CLASS_OPEN);\n          addClass(picker, CLASS_OPENED);\n\n          if (!container) {\n            container = element;\n          }\n        } else {\n          var ownerDocument = element.ownerDocument;\n          var body = ownerDocument.body || ownerDocument.documentElement;\n          this.body = body;\n          this.scrollBarWidth = WINDOW.innerWidth - ownerDocument.documentElement.clientWidth;\n          this.initialBodyPaddingRight = WINDOW.getComputedStyle(body).paddingRight;\n          addClass(picker, \"\".concat(NAMESPACE, \"-fixed\"));\n\n          if (!container) {\n            container = document.body;\n          }\n        }\n\n        this.isInput = isInput;\n        this.inline = inline;\n        this.container = container;\n        this.picker = picker;\n        this.grid = grid;\n        this.cell = null;\n        this.format = parseFormat(options.format);\n        var initialValue = this.getValue();\n        var date = this.parseDate(options.date || initialValue);\n        this.date = date;\n        this.initialDate = new Date(date);\n        this.initialValue = initialValue;\n        this.data = {};\n        var rows = Number(options.rows);\n\n        if (!(rows % 2)) {\n          rows += 1;\n        }\n\n        options.rows = rows || 5;\n        addClass(grid, \"\".concat(NAMESPACE, \"-\").concat(options.rows > 1 ? 'multiple' : 'single'));\n\n        if (options.controls) {\n          addClass(grid, \"\".concat(NAMESPACE, \"-controls\"));\n        }\n\n        var headers = options.headers,\n            increment = options.increment;\n\n        if (headers) {\n          addClass(grid, \"\".concat(NAMESPACE, \"-headers\")); // TODO: Drop the `headers` option's object support in v2.\n\n          headers = isPlainObject(headers) ? headers : options.text;\n        }\n\n        if (!isPlainObject(increment)) {\n          increment = {\n            year: increment,\n            month: increment,\n            day: increment,\n            hour: increment,\n            minute: increment,\n            second: increment,\n            millisecond: increment\n          };\n        }\n\n        this.format.tokens.forEach(function (token) {\n          var type = tokenToType(token);\n          var cell = document.createElement('div');\n          var cellBody = document.createElement('div');\n          var list = document.createElement('ul');\n          var data = {\n            digit: token.length,\n            increment: Math.abs(Number(increment[type])) || 1,\n            list: list,\n            max: Infinity,\n            min: -Infinity,\n            index: Math.floor((options.rows + 2) / 2),\n            offset: 0\n          };\n\n          switch (token.charAt(0)) {\n            case 'Y':\n              if (data.digit === 2) {\n                data.max = 99;\n                data.min = 0;\n              }\n\n              break;\n\n            case 'M':\n              data.max = 11;\n              data.min = 0;\n              data.offset = 1;\n\n              if (data.digit === 3) {\n                data.aliases = options.monthsShort;\n              } else if (data.digit === 4) {\n                data.aliases = options.months;\n              }\n\n              break;\n\n            case 'D':\n              // XXX: Use the latest date to calculate the max day (#23)\n              data.max = function () {\n                return getDaysInMonth(_this.date.getFullYear(), _this.date.getMonth());\n              };\n\n              data.min = 1;\n              break;\n\n            case 'H':\n              data.max = 23;\n              data.min = 0;\n              break;\n\n            case 'm':\n              data.max = 59;\n              data.min = 0;\n              break;\n\n            case 's':\n              data.max = 59;\n              data.min = 0;\n              break;\n\n            case 'S':\n              data.max = 999;\n              data.min = 0;\n              break;\n\n            default:\n          }\n\n          setData(cell, DATA_TYPE, type);\n          setData(cell, DATA_TOKEN, token);\n\n          if (headers) {\n            var cellHeader = document.createElement('div');\n            addClass(cellHeader, \"\".concat(NAMESPACE, \"-cell__header\"));\n            cellHeader.textContent = headers[type] || type[0].toUpperCase() + type.substr(1);\n            cell.appendChild(cellHeader);\n          }\n\n          if (options.controls) {\n            var prev = document.createElement('div');\n            addClass(prev, \"\".concat(NAMESPACE, \"-cell__control\"));\n            addClass(prev, \"\".concat(NAMESPACE, \"-cell__control--prev\"));\n            setData(prev, DATA_ACTION, ACTION_PREV);\n            cell.appendChild(prev);\n          }\n\n          addClass(list, \"\".concat(NAMESPACE, \"-list\"));\n          addClass(cellBody, \"\".concat(NAMESPACE, \"-cell__body\"));\n          addClass(cell, \"\".concat(NAMESPACE, \"-cell\"));\n          addClass(cell, \"\".concat(NAMESPACE, \"-\").concat(type, \"s\"));\n          cellBody.appendChild(list);\n          cell.appendChild(cellBody);\n\n          if (options.controls) {\n            var next = document.createElement('div');\n            addClass(next, \"\".concat(NAMESPACE, \"-cell__control\"));\n            addClass(next, \"\".concat(NAMESPACE, \"-cell__control--next\"));\n            setData(next, DATA_ACTION, ACTION_NEXT);\n            cell.appendChild(next);\n          }\n\n          grid.appendChild(cell);\n          _this.data[type] = data;\n\n          _this.render(type);\n        });\n\n        if (inline) {\n          container.innerHTML = '';\n        }\n\n        container.appendChild(picker);\n        this.bind();\n      }\n      /**\n       * Get the no conflict picker class.\n       * @returns {Picker} The picker class.\n       */\n\n    }], [{\n      key: \"noConflict\",\n      value: function noConflict() {\n        WINDOW.Picker = AnotherPicker;\n        return Picker;\n      }\n      /**\n       * Change the default options.\n       * @param {Object} options - The new default options.\n       */\n\n    }, {\n      key: \"setDefaults\",\n      value: function setDefaults(options) {\n        deepAssign(DEFAULTS, LANGUAGES[options.language], isPlainObject(options) && options);\n      }\n    }]);\n\n    return Picker;\n  }();\n\n  deepAssign(Picker.prototype, events, handlers, helpers, methods);\n  Picker.languages = LANGUAGES;\n\n  return Picker;\n\n}));\n"
  },
  {
    "path": "docs/js/picker.pl-PL.js",
    "content": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) : factory(global.Picker);\n}(typeof self !== 'undefined' ? self : this, function (Picker) {\n  'use strict';\n\n  Picker.languages['pl-PL'] = {\n    months: [\n      'Styczeń',\n      'Luty',\n      'Marzec',\n      'Kwiecień',\n      'Maj',\n      'Czerwiec',\n      'Lipiec',\n      'Sierpień',\n      'Wrzesień',\n      'Październik',\n      'Listopad',\n      'Grudzień'\n    ],\n    monthsShort: [\n      'Stycz',\n      'Luty',\n      'Mar',\n      'Kwie',\n      'Maj',\n      'Czerw',\n      'Lip',\n      'Sierp',\n      'Wrzes',\n      'Paźdz',\n      'List',\n      'Grudz',\n    ],\n    text: {\n      title: 'Wybierz dzień',\n      cancel: 'Anuluj',\n      confirm: 'OK'\n    }\n  };\n}));\n"
  },
  {
    "path": "docs/js/picker.zh-CN.js",
    "content": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) : factory(global.Picker);\n}(typeof self !== 'undefined' ? self : this, function (Picker) {\n  'use strict';\n\n  Picker.languages['zh-CN'] = {\n    months: [\n      '一月',\n      '二月',\n      '三月',\n      '四月',\n      '五月',\n      '六月',\n      '七月',\n      '八月',\n      '九月',\n      '十月',\n      '十一月',\n      '十二月'\n    ],\n    monthsShort: [\n      '1月',\n      '2月',\n      '3月',\n      '4月',\n      '5月',\n      '6月',\n      '7月',\n      '8月',\n      '9月',\n      '10月',\n      '11月',\n      '12月'\n    ],\n    text: {\n      title: '选择日期时间',\n      cancel: '取消',\n      confirm: '确认',\n      year: '年',\n      month: '月',\n      day: '日',\n      hour: '时',\n      minute: '分',\n      second: '秒',\n      millisecond: '毫秒'\n    }\n  };\n}));\n"
  },
  {
    "path": "i18n/picker.en-GB.js",
    "content": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) : factory(global.Picker);\n}(typeof self !== 'undefined' ? self : this, function (Picker) {\n  'use strict';\n\n  Picker.languages['en-GB'] = {\n    format: 'DD/MM/YYYY HH:mm'\n  };\n}));\n"
  },
  {
    "path": "i18n/picker.en-US.js",
    "content": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) : factory(global.Picker);\n}(typeof self !== 'undefined' ? self : this, function (Picker) {\n  'use strict';\n\n  Picker.languages['en-US'] = {\n    format: 'MM/DD/YYYY HH:mm'\n  };\n}));\n"
  },
  {
    "path": "i18n/picker.pl-PL.js",
    "content": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) : factory(global.Picker);\n}(typeof self !== 'undefined' ? self : this, function (Picker) {\n  'use strict';\n\n  Picker.languages['pl-PL'] = {\n    months: [\n      'Styczeń',\n      'Luty',\n      'Marzec',\n      'Kwiecień',\n      'Maj',\n      'Czerwiec',\n      'Lipiec',\n      'Sierpień',\n      'Wrzesień',\n      'Październik',\n      'Listopad',\n      'Grudzień'\n    ],\n    monthsShort: [\n      'Stycz',\n      'Luty',\n      'Mar',\n      'Kwie',\n      'Maj',\n      'Czerw',\n      'Lip',\n      'Sierp',\n      'Wrzes',\n      'Paźdz',\n      'List',\n      'Grudz',\n    ],\n    text: {\n      title: 'Wybierz dzień',\n      cancel: 'Anuluj',\n      confirm: 'OK'\n    }\n  };\n}));\n"
  },
  {
    "path": "i18n/picker.pt-BR.js",
    "content": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) : factory(global.Picker);\n}(typeof self !== 'undefined' ? self : this, function (Picker) {\n  'use strict';\n\n  Picker.languages['pt-BR'] = {\n    months: [\n      'Janeiro',\n      'Fevereiro',\n      'Março',\n      'Abril',\n      'Maio',\n      'Junho',\n      'Julho',\n      'Agosto',\n      'Setembro',\n      'Outubro',\n      'Novembro',\n      'Dezembro'\n    ],\n    monthsShort: [\n      'Jan',\n      'Fev',\n      'Mar',\n      'Abr',\n      'Maio',\n      'Jun',\n      'Jul',\n      'Ago',\n      'Set',\n      'Out',\n      'Nov',\n      'Dez'\n    ],\n    text: {\n      title: 'Escolha uma data e hora',\n      cancel: 'Cancelar',\n      confirm: 'Confirmar',\n      year: 'Ano',\n      month: 'Mês',\n      day: 'Dia',\n      hour: 'Hora',\n      minute: 'Minutos',\n      second: 'Segundos',\n      millisecond: 'Milissegundos'\n    }\n  };\n}));\n"
  },
  {
    "path": "i18n/picker.zh-CN.js",
    "content": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) : factory(global.Picker);\n}(typeof self !== 'undefined' ? self : this, function (Picker) {\n  'use strict';\n\n  Picker.languages['zh-CN'] = {\n    months: [\n      '一月',\n      '二月',\n      '三月',\n      '四月',\n      '五月',\n      '六月',\n      '七月',\n      '八月',\n      '九月',\n      '十月',\n      '十一月',\n      '十二月'\n    ],\n    monthsShort: [\n      '1月',\n      '2月',\n      '3月',\n      '4月',\n      '5月',\n      '6月',\n      '7月',\n      '8月',\n      '9月',\n      '10月',\n      '11月',\n      '12月'\n    ],\n    text: {\n      title: '选择日期时间',\n      cancel: '取消',\n      confirm: '确认',\n      year: '年',\n      month: '月',\n      day: '日',\n      hour: '时',\n      minute: '分',\n      second: '秒',\n      millisecond: '毫秒'\n    }\n  };\n}));\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"pickerjs\",\n  \"version\": \"1.2.1\",\n  \"description\": \"JavaScript date time picker.\",\n  \"main\": \"dist/picker.common.js\",\n  \"module\": \"dist/picker.esm.js\",\n  \"browser\": \"dist/picker.js\",\n  \"types\": \"types/index.d.ts\",\n  \"style\": \"dist/picker.css\",\n  \"files\": [\n    \"src\",\n    \"dist\",\n    \"types\"\n  ],\n  \"scripts\": {\n    \"build\": \"npm run build:css && npm run build:js\",\n    \"build:css\": \"postcss src/index.css -o dist/picker.css --no-map\",\n    \"build:js\": \"rollup -c\",\n    \"clear\": \"del-cli dist\",\n    \"codecov\": \"cat coverage/lcov.info | codecov\",\n    \"compress\": \"npm run compress:css && npm run compress:js\",\n    \"compress:css\": \"postcss dist/picker.css -u cssnano -o dist/picker.min.css --no-map\",\n    \"compress:js\": \"uglifyjs dist/picker.js -o dist/picker.min.js -c -m --comments /^!/\",\n    \"copy\": \"npm run copy:css && npm run copy:i18n\",\n    \"copy:css\": \"cpy dist/picker.css docs/css\",\n    \"copy:i18n\": \"cpy i18n/* docs/js\",\n    \"lint\": \"npm run lint:js && npm run lint:css\",\n    \"lint:css\": \"stylelint {src,docs,examples}/**/*.{css,scss,html} --fix\",\n    \"lint:js\": \"eslint src test *.js --fix\",\n    \"release\": \"npm run clear && npm run lint && npm run build && npm run compress && npm run copy && npm test\",\n    \"start\": \"npm-run-all --parallel watch:*\",\n    \"test\": \"cross-env NODE_ENV=test karma start test/karma.conf.js\",\n    \"watch:css\": \"postcss src/index.css -o docs/css/picker.css -m -w\",\n    \"watch:js\": \"rollup -c -m -w\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/fengyuanchen/pickerjs.git\"\n  },\n  \"keywords\": [\n    \"date\",\n    \"time\",\n    \"picker\",\n    \"datepicker\",\n    \"timepicker\",\n    \"html\",\n    \"css\",\n    \"javascript\",\n    \"front-end\",\n    \"web\"\n  ],\n  \"author\": {\n    \"name\": \"Chen Fengyuan\",\n    \"url\": \"https://chenfengyuan.com\"\n  },\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/fengyuanchen/pickerjs/issues\"\n  },\n  \"homepage\": \"https://fengyuanchen.github.io/pickerjs\",\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.3.3\",\n    \"@babel/preset-env\": \"^7.3.1\",\n    \"@commitlint/cli\": \"^7.5.2\",\n    \"@commitlint/config-conventional\": \"^7.5.0\",\n    \"babel-plugin-istanbul\": \"^5.1.1\",\n    \"chai\": \"^4.2.0\",\n    \"change-case\": \"^3.1.0\",\n    \"codecov\": \"^3.2.0\",\n    \"cpy-cli\": \"^2.0.0\",\n    \"create-banner\": \"^1.0.0\",\n    \"cross-env\": \"^5.2.0\",\n    \"cssnano\": \"^4.1.10\",\n    \"del-cli\": \"^1.1.0\",\n    \"eslint\": \"^5.14.0\",\n    \"eslint-config-airbnb-base\": \"^13.1.0\",\n    \"eslint-plugin-import\": \"^2.16.0\",\n    \"husky\": \"^1.3.1\",\n    \"karma\": \"^4.0.0\",\n    \"karma-chai\": \"^0.1.0\",\n    \"karma-chrome-launcher\": \"^2.2.0\",\n    \"karma-coverage-istanbul-reporter\": \"^2.0.5\",\n    \"karma-mocha\": \"^1.3.0\",\n    \"karma-mocha-reporter\": \"^2.2.5\",\n    \"karma-rollup-preprocessor\": \"^7.0.0\",\n    \"lint-staged\": \"^8.1.4\",\n    \"mocha\": \"^5.2.0\",\n    \"npm-run-all\": \"^4.1.5\",\n    \"postcss-cli\": \"^6.1.1\",\n    \"postcss-header\": \"^1.0.0\",\n    \"postcss-import\": \"^12.0.1\",\n    \"postcss-preset-env\": \"^6.5.0\",\n    \"postcss-url\": \"^8.0.0\",\n    \"puppeteer\": \"^1.12.2\",\n    \"rollup\": \"^1.2.1\",\n    \"rollup-plugin-babel\": \"^4.3.2\",\n    \"rollup-watch\": \"^4.3.1\",\n    \"stylelint\": \"^9.10.1\",\n    \"stylelint-config-standard\": \"^18.2.0\",\n    \"stylelint-order\": \"^2.0.0\",\n    \"uglify-js\": \"^3.4.9\"\n  },\n  \"browserslist\": [\n    \"last 2 versions\",\n    \"> 1%\",\n    \"not ie <= 8\"\n  ],\n  \"commitlint\": {\n    \"extends\": [\n      \"@commitlint/config-conventional\"\n    ]\n  },\n  \"husky\": {\n    \"hooks\": {\n      \"pre-commit\": \"lint-staged\",\n      \"commit-msg\": \"commitlint -E HUSKY_GIT_PARAMS\"\n    }\n  },\n  \"lint-staged\": {\n    \"linters\": {\n      \"*.js\": [\n        \"eslint --fix\",\n        \"git add\"\n      ],\n      \"*.{css,scss,html}\": [\n        \"stylelint --fix\",\n        \"git add\"\n      ]\n    },\n    \"ignore\": [\n      \"{dist,docs,i18n}/**/*.js\",\n      \"*.min.*\"\n    ]\n  }\n}\n"
  },
  {
    "path": "postcss.config.js",
    "content": "const rollupConfig = require('./rollup.config');\n\nmodule.exports = {\n  plugins: {\n    'postcss-import': {},\n    'postcss-preset-env': {\n      stage: 3,\n      features: {\n        'nesting-rules': true,\n      },\n    },\n    'postcss-header': {\n      header: rollupConfig.output[0].banner,\n    },\n    stylelint: {\n      fix: true,\n    },\n  },\n};\n"
  },
  {
    "path": "rollup.config.js",
    "content": "const babel = require('rollup-plugin-babel');\nconst changeCase = require('change-case');\nconst createBanner = require('create-banner');\nconst pkg = require('./package');\n\npkg.name = pkg.name.replace('js', '');\n\nconst name = changeCase.pascalCase(pkg.name);\nconst banner = createBanner({\n  data: {\n    name: `${name}.js`,\n    year: '2016-present',\n  },\n});\n\nmodule.exports = {\n  input: 'src/index.js',\n  output: [\n    {\n      banner,\n      name,\n      file: `dist/${pkg.name}.js`,\n      format: 'umd',\n    },\n    {\n      banner,\n      file: `dist/${pkg.name}.common.js`,\n      format: 'cjs',\n    },\n    {\n      banner,\n      file: `dist/${pkg.name}.esm.js`,\n      format: 'esm',\n    },\n    {\n      banner,\n      name,\n      file: `docs/js/${pkg.name}.js`,\n      format: 'umd',\n    },\n  ],\n  plugins: [\n    babel(),\n  ],\n};\n"
  },
  {
    "path": "src/css/picker.css",
    "content": ":root {\n  --gray: #999;\n  --blue: #0074d9;\n  --color: #333;\n  --background-color: #fff;\n  --border: 1px solid #eee;\n}\n\n.picker {\n  background-color: rgba(0, 0, 0, 0.5);\n  color: var(--color);\n  direction: ltr;\n  display: none;\n  font-size: 1rem;\n  line-height: 1.5;\n  overflow: hidden;\n  touch-action: none;\n  transition: opacity 0.15s;\n  user-select: none;\n}\n\n.picker-fixed {\n  bottom: 0;\n  left: 0;\n  position: fixed;\n  right: 0;\n  top: 0;\n  z-index: 1986;\n\n  & > .picker-dialog {\n    bottom: -100%;\n    left: 0;\n    max-height: 100%;\n    position: absolute;\n    right: 0;\n    transition: bottom 0.3s;\n  }\n\n  & .picker-header {\n    display: block;\n  }\n\n  & .picker-footer {\n    display: table;\n  }\n}\n\n.picker-open {\n  display: block;\n  opacity: 0;\n}\n\n.picker-opened {\n  opacity: 1;\n\n  & > .picker-dialog {\n    bottom: 0;\n  }\n}\n\n.picker-dialog {\n  background-color: var(--background-color);\n  border: var(--border);\n}\n\n.picker-header {\n  border-bottom: var(--border);\n  display: none;\n  padding: 0.875rem 1.25rem;\n  position: relative;\n}\n\n.picker-title {\n  font-size: 1.125rem;\n  font-weight: 500;\n  line-height: 1.25rem;\n  margin: 0;\n}\n\n.picker-close {\n  background-color: transparent;\n  border-width: 0;\n  color: var(--gray);\n  cursor: pointer;\n  font-size: 1.75rem;\n  height: 3rem;\n  opacity: 0.75;\n  padding: 0;\n  position: absolute;\n  right: 0;\n  top: 0;\n  width: 3rem;\n\n  &:focus,\n  &:hover {\n    opacity: 1;\n    outline: none;\n  }\n}\n\n.picker-body {\n  overflow: hidden;\n}\n\n.picker-grid {\n  display: table;\n  table-layout: fixed;\n  width: 100%;\n}\n\n.picker-cell {\n  display: table-cell;\n  position: relative;\n\n  &::before,\n  &::after {\n    content: '';\n    display: block;\n    left: 0;\n    position: absolute;\n    right: 0;\n    z-index: 3;\n  }\n\n  &::before {\n    background-image: linear-gradient(to top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.05));\n    bottom: 50%;\n    margin-bottom: 1rem;\n    top: 0;\n  }\n\n  &::after {\n    background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.05));\n    bottom: 0;\n    margin-top: 1rem;\n    top: 50%;\n  }\n\n  & + .picker-cell {\n    border-left: var(--border);\n  }\n\n  @nest .picker-headers & {\n    &::before {\n      margin-bottom: 0;\n    }\n\n    &::after {\n      margin-top: 2rem;\n    }\n  }\n\n  @nest .picker-single:not(.picker-controls):not(.picker-headers) & {\n    &::before,\n    &::after {\n      display: none;\n    }\n  }\n}\n\n.picker-cell__header {\n  color: var(--gray);\n  font-size: 0.875rem;\n  font-weight: 500;\n  line-height: 1.5rem;\n  margin: 0;\n  overflow: hidden;\n  padding: 0.25rem 0.5rem;\n  text-align: center;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.picker-cell__control {\n  cursor: pointer;\n  height: 2rem;\n  padding: 0.25rem 0.5rem;\n  position: relative;\n  z-index: 4;\n\n  &::before {\n    border: 0 solid #ccc;\n    content: '';\n    display: block;\n    height: 0.5rem;\n    left: 50%;\n    position: absolute;\n    top: 50%;\n    transform: translate(-50%, -50%) rotate(-45deg);\n    width: 0.5rem;\n  }\n\n  &:hover::before {\n    border-color: var(--primary);\n  }\n}\n\n.picker-cell__control--prev {\n  &::before {\n    border-right-width: 1px;\n    border-top-width: 1px;\n    margin-top: 2px;\n  }\n}\n\n.picker-cell__control--next {\n  &::before {\n    border-bottom-width: 1px;\n    border-left-width: 1px;\n    margin-bottom: 2px;\n  }\n}\n\n.picker-cell__body {\n  overflow: hidden;\n  position: relative;\n\n  &::before,\n  &::after {\n    content: '';\n    height: 2rem;\n    left: 0;\n    position: absolute;\n    right: 0;\n    z-index: 1;\n  }\n\n  &::before {\n    background-image: linear-gradient(to top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));\n    top: 0;\n  }\n\n  &::after {\n    background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));\n    bottom: 0;\n  }\n\n  @nest .picker-single & {\n    &::before,\n    &::after {\n      display: none;\n    }\n  }\n}\n\n.picker-list {\n  list-style: none;\n  margin: -2rem 0;\n  padding: 0;\n  position: relative;\n}\n\n.picker-item {\n  color: var(--gray);\n  padding: 0.25rem 0.5rem;\n  text-align: center;\n  white-space: nowrap;\n}\n\n.picker-picked {\n  color: var(--blue);\n  font-size: 1.125em;\n  line-height: 1.5rem;\n}\n\n.picker-footer {\n  border-top: var(--border);\n  display: none;\n  width: 100%;\n}\n\n.picker-cancel,\n.picker-confirm {\n  background-color: transparent;\n  border-width: 0;\n  cursor: pointer;\n  display: table-cell;\n  font-size: 1rem;\n  padding: 0.75rem 1rem;\n  width: 50%;\n\n  &:focus,\n  &:hover {\n    background-color: #fcfcfc;\n    outline: none;\n  }\n}\n\n.picker-confirm {\n  color: var(--blue);\n}\n"
  },
  {
    "path": "src/index.css",
    "content": "@import './css/picker.css';\n"
  },
  {
    "path": "src/index.js",
    "content": "import Picker from './js/picker';\n\nexport default Picker;\n"
  },
  {
    "path": "src/js/constants.js",
    "content": "export const IS_BROWSER = typeof window !== 'undefined';\nexport const WINDOW = IS_BROWSER ? window : {};\nexport const IS_TOUCH_DEVICE = IS_BROWSER ? 'ontouchstart' in WINDOW.document.documentElement : false;\nexport const HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;\nexport const NAMESPACE = 'picker';\nexport const LANGUAGES = {};\n\n// Actions\nexport const ACTION_HIDE = 'hide';\nexport const ACTION_NEXT = 'next';\nexport const ACTION_PICK = 'pick';\nexport const ACTION_PREV = 'prev';\n\n// Classes\nexport const CLASS_OPEN = `${NAMESPACE}-open`;\nexport const CLASS_OPENED = `${NAMESPACE}-opened`;\nexport const CLASS_PICKED = `${NAMESPACE}-picked`;\n\n// Data keys\n// Add namespace to avoid to conflict to some other libraries.\nexport const DATA_ACTION = `${NAMESPACE}Action`;\nexport const DATA_TOKEN = 'token';\nexport const DATA_TYPE = 'type';\nexport const DATA_NAME = 'name';\nexport const DATA_VALUE = 'value';\n\n// Events\nexport const EVENT_CLICK = 'click';\nexport const EVENT_FOCUS = 'focus';\nexport const EVENT_HIDDEN = 'hidden';\nexport const EVENT_HIDE = 'hide';\nexport const EVENT_KEY_DOWN = 'keydown';\nexport const EVENT_PICK = 'pick';\nexport const EVENT_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown';\nexport const EVENT_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'touchmove' : 'mousemove';\nexport const EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup';\nexport const EVENT_POINTER_DOWN = HAS_POINTER_EVENT ? 'pointerdown' : EVENT_TOUCH_START;\nexport const EVENT_POINTER_MOVE = HAS_POINTER_EVENT ? 'pointermove' : EVENT_TOUCH_MOVE;\nexport const EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END;\nexport const EVENT_SHOW = 'show';\nexport const EVENT_SHOWN = 'shown';\nexport const EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll';\n"
  },
  {
    "path": "src/js/defaults.js",
    "content": "export default {\n  // Define the container for putting the picker.\n  container: null,\n\n  // Indicate whether show the prev and next arrow controls on each column.\n  controls: false,\n\n  // The initial date. If not present, use the current date.\n  date: null,\n\n  // The date string format, also as the sorting order for columns.\n  format: 'YYYY-MM-DD HH:mm',\n\n  // Indicate whether show the column headers.\n  headers: false,\n\n  // Define the increment for each date / time part.\n  increment: 1,\n\n  // Enable inline mode.\n  inline: false,\n\n  // Define the language. (An ISO language code).\n  language: '',\n\n  // Months' name.\n  months: [\n    'January',\n    'February',\n    'March',\n    'April',\n    'May',\n    'June',\n    'July',\n    'August',\n    'September',\n    'October',\n    'November',\n    'December',\n  ],\n\n  // Shorter months' name.\n  monthsShort: [\n    'Jan',\n    'Feb',\n    'Mar',\n    'Apr',\n    'May',\n    'Jun',\n    'Jul',\n    'Aug',\n    'Sep',\n    'Oct',\n    'Nov',\n    'Dec',\n  ],\n\n  // Define the number of rows for showing.\n  rows: 5,\n\n  // Define the text of the picker.\n  text: {\n    title: 'Pick a date and time',\n    cancel: 'Cancel',\n    confirm: 'OK',\n    year: 'Year',\n    month: 'Month',\n    day: 'Day',\n    hour: 'Hour',\n    minute: 'Minute',\n    second: 'Second',\n    millisecond: 'Millisecond',\n  },\n\n  // Translate date / time text.\n  translate(type, text) {\n    return text;\n  },\n\n  // Shortcuts of custom events.\n  show: null,\n  shown: null,\n  hide: null,\n  hidden: null,\n  pick: null,\n};\n"
  },
  {
    "path": "src/js/events.js",
    "content": "import {\n  EVENT_CLICK,\n  EVENT_FOCUS,\n  EVENT_HIDDEN,\n  EVENT_HIDE,\n  EVENT_KEY_DOWN,\n  EVENT_PICK,\n  EVENT_POINTER_DOWN,\n  EVENT_POINTER_MOVE,\n  EVENT_POINTER_UP,\n  EVENT_SHOW,\n  EVENT_SHOWN,\n  EVENT_WHEEL,\n} from './constants';\nimport {\n  addListener,\n  isFunction,\n  removeListener,\n} from './utilities';\n\nexport default {\n  bind() {\n    const { element, options, grid } = this;\n\n    if (isFunction(options.show)) {\n      addListener(element, EVENT_SHOW, options.show);\n    }\n\n    if (isFunction(options.shown)) {\n      addListener(element, EVENT_SHOWN, options.shown);\n    }\n\n    if (isFunction(options.hide)) {\n      addListener(element, EVENT_HIDE, options.hide);\n    }\n\n    if (isFunction(options.hidden)) {\n      addListener(element, EVENT_HIDDEN, options.hidden);\n    }\n\n    if (isFunction(options.pick)) {\n      addListener(element, EVENT_PICK, options.pick);\n    }\n\n    addListener(element, EVENT_FOCUS, (this.onFocus = this.focus.bind(this)));\n    addListener(element, EVENT_CLICK, this.onFocus);\n    addListener(this.picker, EVENT_CLICK, (this.onClick = this.click.bind(this)));\n    addListener(grid, EVENT_WHEEL, (this.onWheel = this.wheel.bind(this)));\n    addListener(grid, EVENT_POINTER_DOWN, (this.onPointerDown = this.pointerdown.bind(this)));\n    addListener(document, EVENT_POINTER_MOVE, (this.onPointerMove = this.pointermove.bind(this)));\n    addListener(document, EVENT_POINTER_UP, (this.onPointerUp = this.pointerup.bind(this)));\n    addListener(document, EVENT_KEY_DOWN, (this.onKeyDown = this.keydown.bind(this)));\n  },\n\n  unbind() {\n    const { element, options, grid } = this;\n\n    if (isFunction(options.show)) {\n      removeListener(element, EVENT_SHOW, options.show);\n    }\n\n    if (isFunction(options.shown)) {\n      removeListener(element, EVENT_SHOWN, options.shown);\n    }\n\n    if (isFunction(options.hide)) {\n      removeListener(element, EVENT_HIDE, options.hide);\n    }\n\n    if (isFunction(options.hidden)) {\n      removeListener(element, EVENT_HIDDEN, options.hidden);\n    }\n\n    if (isFunction(options.pick)) {\n      removeListener(element, EVENT_PICK, options.pick);\n    }\n\n    removeListener(element, EVENT_FOCUS, this.onFocus);\n    removeListener(element, EVENT_CLICK, this.onFocus);\n    removeListener(this.picker, EVENT_CLICK, this.onClick);\n    removeListener(grid, EVENT_WHEEL, this.onWheel);\n    removeListener(grid, EVENT_POINTER_DOWN, this.onPointerDown);\n    removeListener(document, EVENT_POINTER_MOVE, this.onPointerMove);\n    removeListener(document, EVENT_POINTER_UP, this.onPointerUp);\n    removeListener(document, EVENT_KEY_DOWN, this.onKeyDown);\n  },\n};\n"
  },
  {
    "path": "src/js/handlers.js",
    "content": "import {\n  ACTION_HIDE,\n  ACTION_NEXT,\n  ACTION_PICK,\n  ACTION_PREV,\n  DATA_ACTION,\n  DATA_TYPE,\n  NAMESPACE,\n} from './constants';\nimport { getData } from './utilities';\n\nexport default {\n  focus(event) {\n    event.target.blur();\n    this.show();\n  },\n\n  click(event) {\n    const { target } = event;\n    const action = getData(target, DATA_ACTION);\n\n    switch (action) {\n      case ACTION_HIDE:\n        this.hide();\n        break;\n\n      case ACTION_PICK:\n        this.pick();\n        break;\n\n      case ACTION_PREV:\n      case ACTION_NEXT:\n        this[action](getData(target.parentElement, DATA_TYPE));\n        break;\n\n      default:\n    }\n  },\n\n  wheel(event) {\n    let { target } = event;\n\n    if (target === this.grid) {\n      return;\n    }\n\n    event.preventDefault();\n\n    while (target.parentElement && target.parentElement !== this.grid) {\n      target = target.parentElement;\n    }\n\n    const type = getData(target, DATA_TYPE);\n\n    if (event.deltaY < 0) {\n      this.prev(type);\n    } else {\n      this.next(type);\n    }\n  },\n\n  pointerdown(event) {\n    let { target } = event;\n\n    if (target === this.grid || getData(target, DATA_ACTION)) {\n      return;\n    }\n\n    // This line is required for preventing page scrolling in iOS browsers\n    event.preventDefault();\n\n    while (target.parentElement && target.parentElement !== this.grid) {\n      target = target.parentElement;\n    }\n\n    const list = target.querySelector(`.${NAMESPACE}-list`);\n    const itemHeight = list.firstElementChild.offsetHeight;\n\n    this.cell = {\n      elem: target,\n      list,\n      moveY: 0,\n      maxMoveY: itemHeight,\n      minMoveY: itemHeight / 2,\n      startY: event.changedTouches ? event.changedTouches[0].pageY : event.pageY,\n      type: getData(target, DATA_TYPE),\n    };\n  },\n\n  pointermove(event) {\n    const { cell } = this;\n\n    if (!cell) {\n      return;\n    }\n\n    event.preventDefault();\n\n    const endY = event.changedTouches ? event.changedTouches[0].pageY : event.pageY;\n    const moveY = cell.moveY + (endY - cell.startY);\n\n    cell.startY = endY;\n    cell.moveY = moveY;\n\n    if (Math.abs(moveY) < cell.maxMoveY) {\n      cell.list.style.top = `${moveY}px`;\n      return;\n    }\n\n    cell.list.style.top = 0;\n    cell.moveY = 0;\n\n    if (moveY >= cell.maxMoveY) {\n      this.prev(cell.type);\n    } else if (moveY <= -cell.maxMoveY) {\n      this.next(cell.type);\n    }\n  },\n\n  pointerup(event) {\n    const { cell } = this;\n\n    if (!cell) {\n      return;\n    }\n\n    event.preventDefault();\n    cell.list.style.top = 0;\n\n    if (cell.moveY >= cell.minMoveY) {\n      this.prev(cell.type);\n    } else if (cell.moveY <= -cell.minMoveY) {\n      this.next(cell.type);\n    }\n\n    this.cell = null;\n  },\n\n  keydown(event) {\n    if (this.shown && (event.key === 'Escape' || event.keyCode === 27)) {\n      this.hide();\n    }\n  },\n};\n"
  },
  {
    "path": "src/js/helpers.js",
    "content": "import {\n  CLASS_PICKED,\n  DATA_NAME,\n  DATA_VALUE,\n  NAMESPACE,\n} from './constants';\nimport {\n  addClass,\n  addLeadingZero,\n  getDaysInMonth,\n  isFinite,\n  isFunction,\n  isNumber,\n  setData,\n  tokenToType,\n} from './utilities';\n\nexport default {\n  render(type) {\n    if (!type) {\n      this.format.tokens.forEach(token => this.render(tokenToType(token)));\n      return;\n    }\n\n    const { options } = this;\n    const data = this.data[type];\n    const current = this.current(type);\n    const max = isFunction(data.max) ? data.max() : data.max;\n    const min = isFunction(data.min) ? data.min() : data.min;\n    let base = 0;\n\n    if (isFinite(max)) {\n      base = min > 0 ? max : max + 1;\n    }\n\n    data.list.innerHTML = '';\n    data.current = current;\n\n    for (let i = 0; i < options.rows + 2; i += 1) {\n      const item = document.createElement('li');\n      const position = i - data.index;\n      let newValue = current + (position * data.increment);\n\n      if (base) {\n        newValue %= base;\n\n        if (newValue < min) {\n          newValue += base;\n        }\n      }\n\n      item.textContent = options.translate(type, data.aliases ? data.aliases[newValue]\n        : addLeadingZero(newValue + data.offset, data.digit));\n\n      setData(item, DATA_NAME, type);\n      setData(item, DATA_VALUE, newValue);\n      addClass(item, `${NAMESPACE}-item`);\n\n      if (position === 0) {\n        addClass(item, CLASS_PICKED);\n        data.item = item;\n      }\n\n      data.list.appendChild(item);\n    }\n  },\n\n  current(type, value) {\n    const { date } = this;\n    const { format } = this;\n    const token = format[type];\n\n    switch (token.charAt(0)) {\n      case 'Y':\n        if (isNumber(value)) {\n          date.setFullYear(token.length === 2 ? (2000 + value) : value);\n\n          if (format.month) {\n            this.render(tokenToType(format.month));\n          }\n\n          if (format.day) {\n            this.render(tokenToType(format.day));\n          }\n        }\n\n        return date.getFullYear();\n\n      case 'M':\n        if (isNumber(value)) {\n          date.setMonth(\n            value,\n\n            // The current day should not exceed its maximum day in current month\n            Math.min(date.getDate(), getDaysInMonth(date.getFullYear(), value)),\n          );\n\n          if (format.day) {\n            this.render(tokenToType(format.day));\n          }\n        }\n\n        return date.getMonth();\n\n      case 'D':\n        if (isNumber(value)) {\n          date.setDate(value);\n        }\n\n        return date.getDate();\n\n      case 'H':\n        if (isNumber(value)) {\n          date.setHours(value);\n        }\n\n        return date.getHours();\n\n      case 'm':\n        if (isNumber(value)) {\n          date.setMinutes(value);\n        }\n\n        return date.getMinutes();\n\n      case 's':\n        if (isNumber(value)) {\n          date.setSeconds(value);\n        }\n\n        return date.getSeconds();\n\n      case 'S':\n        if (isNumber(value)) {\n          date.setMilliseconds(value);\n        }\n\n        return date.getMilliseconds();\n\n      default:\n    }\n\n    return date;\n  },\n\n  getValue() {\n    const { element } = this;\n\n    return this.isInput ? element.value : element.textContent;\n  },\n\n  setValue(value) {\n    const { element } = this;\n\n    if (this.isInput) {\n      element.value = value;\n    } else if (this.options.container) {\n      element.textContent = value;\n    }\n  },\n\n  open() {\n    const { body } = this;\n\n    body.style.overflow = 'hidden';\n    body.style.paddingRight = `${this.scrollBarWidth + (parseFloat(this.initialBodyPaddingRight) || 0)}px`;\n  },\n\n  close() {\n    const { body } = this;\n\n    body.style.overflow = '';\n    body.style.paddingRight = this.initialBodyPaddingRight;\n  },\n};\n"
  },
  {
    "path": "src/js/methods.js",
    "content": "import {\n  CLASS_OPEN,\n  CLASS_OPENED,\n  CLASS_PICKED,\n  DATA_VALUE,\n  EVENT_HIDDEN,\n  EVENT_HIDE,\n  EVENT_PICK,\n  EVENT_SHOW,\n  EVENT_SHOWN,\n  NAMESPACE,\n} from './constants';\nimport {\n  addClass,\n  addLeadingZero,\n  dispatchEvent,\n  getData,\n  isDate,\n  isFunction,\n  isString,\n  isValidDate,\n  removeClass,\n  removeData,\n  setData,\n} from './utilities';\n\nexport default {\n  /**\n   * Show the picker.\n   * @param {boolean} [immediate=false] - Indicate if show the picker immediately or not.\n   * @returns {Picker} this\n   */\n  show(immediate = false) {\n    const { element, picker } = this;\n\n    if (this.inline || this.shown) {\n      return this;\n    }\n\n    if (dispatchEvent(element, EVENT_SHOW) === false) {\n      return this;\n    }\n\n    this.shown = true;\n    this.open();\n    addClass(picker, CLASS_OPEN);\n\n    const done = () => {\n      dispatchEvent(element, EVENT_SHOWN);\n    };\n\n    if (!immediate) {\n      // Reflow to enable transition\n      // eslint-disable-next-line\n      picker.offsetWidth;\n    }\n\n    addClass(picker, CLASS_OPENED);\n\n    if (immediate) {\n      done();\n    } else {\n      setTimeout(done, 300);\n    }\n\n    return this;\n  },\n\n  /**\n   * Hide the picker.\n   * @param {boolean} [immediate=false] - Indicate if hide the picker immediately or not.\n   * @returns {Picker} this\n   */\n  hide(immediate = false) {\n    const { element, picker } = this;\n\n    if (this.inline || !this.shown) {\n      return this;\n    }\n\n    if (dispatchEvent(element, EVENT_HIDE) === false) {\n      return this;\n    }\n\n    this.shown = false;\n    removeClass(picker, CLASS_OPENED);\n\n    const done = () => {\n      this.close();\n      removeClass(picker, CLASS_OPEN);\n      dispatchEvent(element, EVENT_HIDDEN);\n    };\n\n    if (immediate) {\n      done();\n    } else {\n      setTimeout(done, 300);\n    }\n\n    return this;\n  },\n\n  /**\n   * Pick to the previous item.\n   * @param {string} type - The column type.\n   * @returns {Picker} this\n   */\n  prev(type) {\n    const { options } = this;\n    const token = this.format[type];\n    const data = this.data[type];\n    const { list } = data;\n    const item = list.lastElementChild;\n    const max = isFunction(data.max) ? data.max() : data.max;\n    const min = isFunction(data.min) ? data.min() : data.min;\n    const prev = data.item.previousElementSibling;\n    let value = Number(getData(list.firstElementChild, DATA_VALUE)) - data.increment;\n\n    if (value < min) {\n      value += (max - min) + 1;\n    }\n\n    item.textContent = options.translate(type, data.aliases ? data.aliases[value]\n      : addLeadingZero(value + data.offset, token.length));\n\n    setData(item, DATA_VALUE, value);\n\n    if (prev) {\n      removeClass(data.item, CLASS_PICKED);\n      addClass(prev, CLASS_PICKED);\n      data.item = prev;\n    }\n\n    list.insertBefore(item, list.firstElementChild);\n    data.current = Number(getData(data.item, DATA_VALUE));\n    this.current(type, data.current);\n\n    if (this.inline && options.container) {\n      this.pick();\n    }\n\n    return this;\n  },\n\n  /**\n   * Pick to the next item.\n   * @param {String} type - The column type.\n   * @returns {Picker} this\n   */\n  next(type) {\n    const { options } = this;\n    const token = this.format[type];\n    const data = this.data[type];\n    const { list } = data;\n    const item = list.firstElementChild;\n    const max = isFunction(data.max) ? data.max() : data.max;\n    const min = isFunction(data.min) ? data.min() : data.min;\n    const next = data.item.nextElementSibling;\n    let value = Number(getData(list.lastElementChild, DATA_VALUE)) + data.increment;\n\n    if (value > max) {\n      value -= (max - min) + 1;\n    }\n\n    item.textContent = options.translate(type, data.aliases ? data.aliases[value]\n      : addLeadingZero(value + data.offset, token.length));\n\n    setData(item, DATA_VALUE, value);\n    list.appendChild(item);\n\n    if (next) {\n      removeClass(data.item, CLASS_PICKED);\n      addClass(next, CLASS_PICKED);\n      data.item = next;\n    }\n\n    data.current = Number(getData(data.item, DATA_VALUE));\n    this.current(type, data.current);\n\n    if (this.inline && options.container) {\n      this.pick();\n    }\n\n    return this;\n  },\n\n  // Pick the current date to the target element.\n  pick() {\n    const { element } = this;\n\n    if (dispatchEvent(element, EVENT_PICK) === false) {\n      return this;\n    }\n\n    const value = this.formatDate(this.date);\n\n    this.setValue(value);\n\n    if (this.isInput && dispatchEvent(element, 'change') === false) {\n      this.reset();\n    }\n\n    this.hide();\n\n    return this;\n  },\n\n  /**\n   * Get the current date.\n   * @param {boolean} [formatted=false] - Indicate if format the date or not.\n   * @return {Date|string} The output date.\n   */\n  getDate(formatted = false) {\n    const { date } = this;\n\n    return formatted ? this.formatDate(date) : new Date(date);\n  },\n\n  /**\n   * Override the current date with a new date.\n   * @param {Date|string} date - The date to set.\n   * @returns {Picker} this\n   */\n  setDate(date) {\n    if (date) {\n      this.date = this.parseDate(date);\n      this.render();\n    }\n\n    return this;\n  },\n\n  // Update the picker with the current element value / text.\n  update() {\n    this.date = this.parseDate(this.getValue());\n    this.render();\n\n    return this;\n  },\n\n  // Reset the picker and element value / text.\n  reset() {\n    this.setValue(this.initialValue);\n    this.date = new Date(this.initialDate);\n    this.render();\n\n    return this;\n  },\n\n  /**\n   * Parse a date with the set date format.\n   * @param {Date|string} date - The date to parse.\n   * @returns {Date} The parsed date object.\n   */\n  parseDate(date) {\n    const { options, format } = this;\n    let digits = [];\n\n    if (isDate(date)) {\n      return new Date(date);\n    }\n\n    if (isString(date)) {\n      const groups = [\n        ...options.months,\n        ...options.monthsShort,\n        '\\\\d+',\n      ];\n\n      digits = date.match(new RegExp(`(${groups.join('|')})`, 'g'));\n\n      // Parse `11111111` (YYYYMMDD) to ['1111', '11', '11']\n      if (digits && (date.length === options.format.length\n        && digits.length !== format.tokens.length)) {\n        digits = format.tokens.map(token => date.substr(\n          options.format.indexOf(token),\n          token.length,\n        ));\n      }\n\n      if (!digits || digits.length !== format.tokens.length) {\n        return new Date();\n      }\n    }\n\n    const parsedDate = new Date();\n\n    digits.forEach((digit, i) => {\n      const token = format.tokens[i];\n      const n = Number(digit);\n\n      switch (token) {\n        case 'YYYY':\n        case 'YYY':\n        case 'Y': {\n          const index = date.indexOf(digit);\n          const isHyphen = date.substr(index - 1, 1) === '-';\n          const isBC = (index > 1 && isHyphen && /\\S/.test(date.substr(index - 2, 1)))\n            || (index === 1 && isHyphen);\n\n          parsedDate.setFullYear(isBC ? -n : n);\n          break;\n        }\n\n        case 'YY':\n          parsedDate.setFullYear(2000 + n);\n          break;\n\n        case 'MMMM':\n          parsedDate.setMonth(options.months.indexOf(digit));\n          break;\n\n        case 'MMM':\n          parsedDate.setMonth(options.monthsShort.indexOf(digit));\n          break;\n\n        case 'MM':\n        case 'M':\n          parsedDate.setMonth(n - 1);\n          break;\n\n        case 'DD':\n        case 'D':\n          parsedDate.setDate(n);\n          break;\n\n        case 'HH':\n        case 'H':\n          parsedDate.setHours(n);\n          break;\n\n        case 'mm':\n        case 'm':\n          parsedDate.setMinutes(n);\n          break;\n\n        case 'ss':\n        case 's':\n          parsedDate.setSeconds(n);\n          break;\n\n        case 'SSS':\n        case 'SS':\n        case 'S':\n          parsedDate.setMilliseconds(n);\n          break;\n\n        default:\n      }\n    });\n\n    return parsedDate;\n  },\n\n  /**\n   * Format a date object to a string with the set date format.\n   * @param {Date} date - The date to format.\n   * @return {string} THe formatted date.\n   */\n  formatDate(date) {\n    const { options, format } = this;\n    let formatted = '';\n\n    if (isValidDate(date)) {\n      const year = date.getFullYear();\n      const month = date.getMonth();\n      const day = date.getDate();\n      const hours = date.getHours();\n      const minutes = date.getMinutes();\n      const seconds = date.getSeconds();\n      const milliseconds = date.getMilliseconds();\n\n      formatted = options.format;\n\n      format.tokens.forEach((token) => {\n        let replacement = '';\n\n        switch (token) {\n          case 'YYYY':\n          case 'YYY':\n          case 'Y':\n            replacement = addLeadingZero(year, token.length);\n            break;\n\n          case 'YY':\n            replacement = addLeadingZero(year % 100, 2);\n            break;\n\n          case 'MMMM':\n            replacement = options.months[month];\n            break;\n\n          case 'MMM':\n            replacement = options.monthsShort[month];\n            break;\n\n          case 'MM':\n          case 'M':\n            replacement = addLeadingZero(month + 1, token.length);\n            break;\n\n          case 'DD':\n          case 'D':\n            replacement = addLeadingZero(day, token.length);\n            break;\n\n          case 'HH':\n          case 'H':\n            replacement = addLeadingZero(hours, token.length);\n            break;\n\n          case 'mm':\n          case 'm':\n            replacement = addLeadingZero(minutes, token.length);\n            break;\n\n          case 'ss':\n          case 's':\n            replacement = addLeadingZero(seconds, token.length);\n            break;\n\n          case 'SSS':\n          case 'SS':\n          case 'S':\n            replacement = addLeadingZero(milliseconds, token.length);\n            break;\n\n          default:\n        }\n\n        formatted = formatted.replace(token, replacement);\n      });\n    }\n\n    return formatted;\n  },\n\n  // Destroy the picker and remove the instance from the target element.\n  destroy() {\n    const { element, picker } = this;\n\n    if (!getData(element, NAMESPACE)) {\n      return this;\n    }\n\n    this.hide(true);\n    this.unbind();\n    removeData(element, NAMESPACE);\n    picker.parentNode.removeChild(picker);\n    return this;\n  },\n};\n"
  },
  {
    "path": "src/js/picker.js",
    "content": "import DEFAULTS from './defaults';\nimport TEMPLATE from './template';\nimport events from './events';\nimport handlers from './handlers';\nimport helpers from './helpers';\nimport methods from './methods';\nimport {\n  ACTION_NEXT,\n  ACTION_PREV,\n  CLASS_OPEN,\n  CLASS_OPENED,\n  DATA_ACTION,\n  DATA_TOKEN,\n  DATA_TYPE,\n  LANGUAGES,\n  NAMESPACE,\n  WINDOW,\n} from './constants';\nimport {\n  addClass,\n  deepAssign,\n  getData,\n  getDaysInMonth,\n  isPlainObject,\n  isString,\n  parseFormat,\n  setData,\n  tokenToType,\n} from './utilities';\n\nconst REGEXP_DELIMITER = /\\{\\{\\s*(\\w+)\\s*\\}\\}/g;\nconst REGEXP_INPUTS = /input|textarea/i;\nconst AnotherPicker = WINDOW.Picker;\n\nclass Picker {\n  /**\n   * Create a new Picker.\n   * @param {Element} element - The target element for picking.\n   * @param {Object} [options={}] - The configuration options.\n   */\n  constructor(element, options = {}) {\n    if (!element || element.nodeType !== 1) {\n      throw new Error('The first argument is required and must be an element.');\n    }\n\n    this.element = element;\n    this.options = deepAssign(\n      {},\n      DEFAULTS,\n      LANGUAGES[options.language],\n      isPlainObject(options) && options,\n    );\n    this.shown = false;\n    this.init();\n  }\n\n  init() {\n    const { element } = this;\n\n    if (getData(element, NAMESPACE)) {\n      return;\n    }\n\n    setData(element, NAMESPACE, this);\n\n    const { options } = this;\n    const isInput = REGEXP_INPUTS.test(element.tagName);\n    const inline = options.inline && (options.container || !isInput);\n    const template = document.createElement('div');\n\n    template.insertAdjacentHTML(\n      'afterbegin',\n      TEMPLATE.replace(REGEXP_DELIMITER, (...args) => options.text[args[1]]),\n    );\n\n    const picker = template.getElementsByClassName(NAMESPACE)[0];\n    const grid = picker.getElementsByClassName(`${NAMESPACE}-grid`)[0];\n    let { container } = options;\n\n    if (isString(container)) {\n      container = document.querySelector(container);\n    }\n\n    if (inline) {\n      addClass(picker, CLASS_OPEN);\n      addClass(picker, CLASS_OPENED);\n\n      if (!container) {\n        container = element;\n      }\n    } else {\n      const { ownerDocument } = element;\n      const body = ownerDocument.body || ownerDocument.documentElement;\n\n      this.body = body;\n      this.scrollBarWidth = WINDOW.innerWidth - ownerDocument.documentElement.clientWidth;\n      this.initialBodyPaddingRight = WINDOW.getComputedStyle(body).paddingRight;\n      addClass(picker, `${NAMESPACE}-fixed`);\n\n      if (!container) {\n        container = document.body;\n      }\n    }\n\n    this.isInput = isInput;\n    this.inline = inline;\n    this.container = container;\n    this.picker = picker;\n    this.grid = grid;\n    this.cell = null;\n    this.format = parseFormat(options.format);\n\n    const initialValue = this.getValue();\n    const date = this.parseDate(options.date || initialValue);\n\n    this.date = date;\n    this.initialDate = new Date(date);\n    this.initialValue = initialValue;\n    this.data = {};\n\n    let rows = Number(options.rows);\n\n    if (!(rows % 2)) {\n      rows += 1;\n    }\n\n    options.rows = rows || 5;\n    addClass(grid, `${NAMESPACE}-${options.rows > 1 ? 'multiple' : 'single'}`);\n\n    if (options.controls) {\n      addClass(grid, `${NAMESPACE}-controls`);\n    }\n\n    let { headers, increment } = options;\n\n    if (headers) {\n      addClass(grid, `${NAMESPACE}-headers`);\n\n      // TODO: Drop the `headers` option's object support in v2.\n      headers = isPlainObject(headers) ? headers : options.text;\n    }\n\n    if (!isPlainObject(increment)) {\n      increment = {\n        year: increment,\n        month: increment,\n        day: increment,\n        hour: increment,\n        minute: increment,\n        second: increment,\n        millisecond: increment,\n      };\n    }\n\n    this.format.tokens.forEach((token) => {\n      const type = tokenToType(token);\n      const cell = document.createElement('div');\n      const cellBody = document.createElement('div');\n      const list = document.createElement('ul');\n      const data = {\n        digit: token.length,\n        increment: Math.abs(Number(increment[type])) || 1,\n        list,\n        max: Infinity,\n        min: -Infinity,\n        index: Math.floor((options.rows + 2) / 2),\n        offset: 0,\n      };\n\n      switch (token.charAt(0)) {\n        case 'Y':\n          if (data.digit === 2) {\n            data.max = 99;\n            data.min = 0;\n          }\n\n          break;\n\n        case 'M':\n          data.max = 11;\n          data.min = 0;\n          data.offset = 1;\n\n          if (data.digit === 3) {\n            data.aliases = options.monthsShort;\n          } else if (data.digit === 4) {\n            data.aliases = options.months;\n          }\n\n          break;\n\n        case 'D':\n          // XXX: Use the latest date to calculate the max day (#23)\n          data.max = () => getDaysInMonth(this.date.getFullYear(), this.date.getMonth());\n          data.min = 1;\n          break;\n\n        case 'H':\n          data.max = 23;\n          data.min = 0;\n          break;\n\n        case 'm':\n          data.max = 59;\n          data.min = 0;\n          break;\n\n        case 's':\n          data.max = 59;\n          data.min = 0;\n          break;\n\n        case 'S':\n          data.max = 999;\n          data.min = 0;\n          break;\n\n        default:\n      }\n\n      setData(cell, DATA_TYPE, type);\n      setData(cell, DATA_TOKEN, token);\n\n      if (headers) {\n        const cellHeader = document.createElement('div');\n\n        addClass(cellHeader, `${NAMESPACE}-cell__header`);\n        cellHeader.textContent = headers[type] || (type[0].toUpperCase() + type.substr(1));\n        cell.appendChild(cellHeader);\n      }\n\n      if (options.controls) {\n        const prev = document.createElement('div');\n\n        addClass(prev, `${NAMESPACE}-cell__control`);\n        addClass(prev, `${NAMESPACE}-cell__control--prev`);\n        setData(prev, DATA_ACTION, ACTION_PREV);\n        cell.appendChild(prev);\n      }\n\n      addClass(list, `${NAMESPACE}-list`);\n      addClass(cellBody, `${NAMESPACE}-cell__body`);\n      addClass(cell, `${NAMESPACE}-cell`);\n      addClass(cell, `${NAMESPACE}-${type}s`);\n      cellBody.appendChild(list);\n      cell.appendChild(cellBody);\n\n      if (options.controls) {\n        const next = document.createElement('div');\n\n        addClass(next, `${NAMESPACE}-cell__control`);\n        addClass(next, `${NAMESPACE}-cell__control--next`);\n        setData(next, DATA_ACTION, ACTION_NEXT);\n        cell.appendChild(next);\n      }\n\n      grid.appendChild(cell);\n      this.data[type] = data;\n      this.render(type);\n    });\n\n    if (inline) {\n      container.innerHTML = '';\n    }\n\n    container.appendChild(picker);\n    this.bind();\n  }\n\n  /**\n   * Get the no conflict picker class.\n   * @returns {Picker} The picker class.\n   */\n  static noConflict() {\n    WINDOW.Picker = AnotherPicker;\n    return Picker;\n  }\n\n  /**\n   * Change the default options.\n   * @param {Object} options - The new default options.\n   */\n  static setDefaults(options) {\n    deepAssign(DEFAULTS, LANGUAGES[options.language], isPlainObject(options) && options);\n  }\n}\n\ndeepAssign(Picker.prototype, events, handlers, helpers, methods);\nPicker.languages = LANGUAGES;\n\nexport default Picker;\n"
  },
  {
    "path": "src/js/template.js",
    "content": "export default (\n  '<div class=\"picker\" data-picker-action=\"hide\" touch-action=\"none\" tabindex=\"-1\" role=\"dialog\">'\n    + '<div class=\"picker-dialog\" role=\"document\">'\n      + '<div class=\"picker-header\">'\n        + '<h4 class=\"picker-title\">{{ title }}</h4>'\n        + '<button type=\"button\" class=\"picker-close\" data-picker-action=\"hide\" aria-label=\"Close\">&times;</button>'\n      + '</div>'\n      + '<div class=\"picker-body\">'\n        + '<div class=\"picker-grid\"></div>'\n      + '</div>'\n      + '<div class=\"picker-footer\">'\n        + '<button type=\"button\" class=\"picker-cancel\" data-picker-action=\"hide\">{{ cancel }}</button>'\n        + '<button type=\"button\" class=\"picker-confirm\" data-picker-action=\"pick\">{{ confirm }}</button>'\n      + '</div>'\n    + '</div>'\n  + '</div>'\n);\n"
  },
  {
    "path": "src/js/utilities.js",
    "content": "import {\n  IS_BROWSER,\n  WINDOW,\n} from './constants';\n\nconst { hasOwnProperty, toString } = Object.prototype;\n\n/**\n * Detect the type of the given value.\n * @param {*} value - The value to detect.\n * @returns {string} Returns the type.\n */\nexport function typeOf(value) {\n  return toString.call(value).slice(8, -1).toLowerCase();\n}\n\n/**\n * Check if the given value is a string.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a string, else `false`.\n */\nexport function isString(value) {\n  return typeof value === 'string';\n}\n\n/**\n * Check if the given value is finite.\n */\nexport const isFinite = Number.isFinite || WINDOW.isFinite;\n\n/**\n * Check if the given value is not a number.\n */\nexport const isNaN = Number.isNaN || WINDOW.isNaN;\n\n/**\n * Check if the given value is a number.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a number, else `false`.\n */\nexport function isNumber(value) {\n  return typeof value === 'number' && !isNaN(value);\n}\n\n/**\n * Check if the given value is an object.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is an object, else `false`.\n */\nexport function isObject(value) {\n  return typeof value === 'object' && value !== null;\n}\n\n/**\n * Check if the given value is a plain object.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a plain object, else `false`.\n */\nexport function isPlainObject(value) {\n  if (!isObject(value)) {\n    return false;\n  }\n\n  try {\n    const { constructor } = value;\n    const { prototype } = constructor;\n\n    return constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');\n  } catch (error) {\n    return false;\n  }\n}\n\n/**\n * Check if the given value is a function.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a function, else `false`.\n */\nexport function isFunction(value) {\n  return typeof value === 'function';\n}\n\n/**\n * Check if the given value is a date.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a date, else `false`.\n */\nexport function isDate(value) {\n  return typeOf(value) === 'date';\n}\n\n/**\n * Check if the given value is a valid date.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the given value is a valid date, else `false`.\n */\nexport function isValidDate(value) {\n  return isDate(value) && value.toString() !== 'Invalid Date';\n}\n\n/**\n * Iterate the given data.\n * @param {*} data - The data to iterate.\n * @param {Function} callback - The process function for each element.\n * @returns {*} The original data.\n */\nexport function forEach(data, callback) {\n  if (data && isFunction(callback)) {\n    if (Array.isArray(data) || isNumber(data.length)/* array-like */) {\n      const { length } = data;\n      let i;\n\n      for (i = 0; i < length; i += 1) {\n        if (callback.call(data, data[i], i, data) === false) {\n          break;\n        }\n      }\n    } else if (isObject(data)) {\n      Object.keys(data).forEach((key) => {\n        callback.call(data, data[key], key, data);\n      });\n    }\n  }\n\n  return data;\n}\n\n/**\n * Recursively assigns own enumerable properties of source objects to the target object.\n * @param {Object} target - The target object.\n * @param {Object[]} sources - The source objects.\n * @returns {Object} The target object.\n */\nexport function deepAssign(target, ...sources) {\n  if (isObject(target) && sources.length > 0) {\n    sources.forEach((source) => {\n      if (isObject(source)) {\n        Object.keys(source).forEach((key) => {\n          if (isPlainObject(target[key]) && isPlainObject(source[key])) {\n            target[key] = deepAssign({}, target[key], source[key]);\n          } else {\n            target[key] = source[key];\n          }\n        });\n      }\n    });\n  }\n\n  return target;\n}\n\n/**\n * Check if the given element has a special class.\n * @param {Element} element - The element to check.\n * @param {string} value - The class to search.\n * @returns {boolean} Returns `true` if the special class was found.\n */\nexport function hasClass(element, value) {\n  return element.classList\n    ? element.classList.contains(value)\n    : element.className.indexOf(value) > -1;\n}\n\n/**\n * Add classes to the given element.\n * @param {Element} element - The target element.\n * @param {string} value - The classes to be added.\n */\nexport function addClass(element, value) {\n  if (!value) {\n    return;\n  }\n\n  if (isNumber(element.length)) {\n    forEach(element, (elem) => {\n      addClass(elem, value);\n    });\n    return;\n  }\n\n  if (element.classList) {\n    element.classList.add(value);\n    return;\n  }\n\n  const className = element.className.trim();\n\n  if (!className) {\n    element.className = value;\n  } else if (className.indexOf(value) < 0) {\n    element.className = `${className} ${value}`;\n  }\n}\n\n/**\n * Remove classes from the given element.\n * @param {Element} element - The target element.\n * @param {string} value - The classes to be removed.\n */\nexport function removeClass(element, value) {\n  if (!value) {\n    return;\n  }\n\n  if (isNumber(element.length)) {\n    forEach(element, (elem) => {\n      removeClass(elem, value);\n    });\n    return;\n  }\n\n  if (element.classList) {\n    element.classList.remove(value);\n    return;\n  }\n\n  if (element.className.indexOf(value) >= 0) {\n    element.className = element.className.replace(value, '');\n  }\n}\n\n/**\n * Add or remove classes from the given element.\n * @param {Element} element - The target element.\n * @param {string} value - The classes to be toggled.\n * @param {boolean} added - Add only.\n */\nexport function toggleClass(element, value, added) {\n  if (!value) {\n    return;\n  }\n\n  if (isNumber(element.length)) {\n    forEach(element, (elem) => {\n      toggleClass(elem, value, added);\n    });\n    return;\n  }\n\n  // IE10-11 doesn't support the second parameter of `classList.toggle`\n  if (added) {\n    addClass(element, value);\n  } else {\n    removeClass(element, value);\n  }\n}\n\nconst REGEXP_HYPHENATE = /([a-z\\d])([A-Z])/g;\n\n/**\n * Transform the given string from camelCase to kebab-case\n * @param {string} value - The value to transform.\n * @returns {string} The transformed value.\n */\nexport function hyphenate(value) {\n  return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase();\n}\n\n/**\n * Get data from the given element.\n * @param {Element} element - The target element.\n * @param {string} name - The data key to get.\n * @returns {string} The data value.\n */\nexport function getData(element, name) {\n  if (isObject(element[name])) {\n    return element[name];\n  }\n\n  if (element.dataset) {\n    return element.dataset[name];\n  }\n\n  return element.getAttribute(`data-${hyphenate(name)}`);\n}\n\n/**\n * Set data to the given element.\n * @param {Element} element - The target element.\n * @param {string} name - The data key to set.\n * @param {string} data - The data value.\n */\nexport function setData(element, name, data) {\n  if (isObject(data)) {\n    element[name] = data;\n  } else if (element.dataset) {\n    element.dataset[name] = data;\n  } else {\n    element.setAttribute(`data-${hyphenate(name)}`, data);\n  }\n}\n\n/**\n * Remove data from the given element.\n * @param {Element} element - The target element.\n * @param {string} name - The data key to remove.\n */\nexport function removeData(element, name) {\n  if (isObject(element[name])) {\n    try {\n      delete element[name];\n    } catch (error) {\n      element[name] = undefined;\n    }\n  } else if (element.dataset) {\n    // #128 Safari not allows to delete dataset property\n    try {\n      delete element.dataset[name];\n    } catch (error) {\n      element.dataset[name] = undefined;\n    }\n  } else {\n    element.removeAttribute(`data-${hyphenate(name)}`);\n  }\n}\n\nconst REGEXP_SPACES = /\\s\\s*/;\nconst onceSupported = (() => {\n  let supported = false;\n\n  if (IS_BROWSER) {\n    let once = false;\n    const listener = () => {};\n    const options = Object.defineProperty({}, 'once', {\n      get() {\n        supported = true;\n        return once;\n      },\n\n      /**\n       * This setter can fix a `TypeError` in strict mode\n       * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}\n       * @param {boolean} value - The value to set\n       */\n      set(value) {\n        once = value;\n      },\n    });\n\n    WINDOW.addEventListener('test', listener, options);\n    WINDOW.removeEventListener('test', listener, options);\n  }\n\n  return supported;\n})();\n\n/**\n * Remove event listener from the target element.\n * @param {Element} element - The event target.\n * @param {string} type - The event type(s).\n * @param {Function} listener - The event listener.\n * @param {Object} options - The event options.\n */\nexport function removeListener(element, type, listener, options = {}) {\n  let handler = listener;\n\n  type.trim().split(REGEXP_SPACES).forEach((event) => {\n    if (!onceSupported) {\n      const { listeners } = element;\n\n      if (listeners && listeners[event] && listeners[event][listener]) {\n        handler = listeners[event][listener];\n        delete listeners[event][listener];\n\n        if (Object.keys(listeners[event]).length === 0) {\n          delete listeners[event];\n        }\n\n        if (Object.keys(listeners).length === 0) {\n          delete element.listeners;\n        }\n      }\n    }\n\n    element.removeEventListener(event, handler, options);\n  });\n}\n\n/**\n * Add event listener to the target element.\n * @param {Element} element - The event target.\n * @param {string} type - The event type(s).\n * @param {Function} listener - The event listener.\n * @param {Object} options - The event options.\n */\nexport function addListener(element, type, listener, options = {}) {\n  let handler = listener;\n\n  type.trim().split(REGEXP_SPACES).forEach((event) => {\n    if (options.once && !onceSupported) {\n      const { listeners = {} } = element;\n\n      handler = (...args) => {\n        delete listeners[event][listener];\n        element.removeEventListener(event, handler, options);\n        listener.apply(element, args);\n      };\n\n      if (!listeners[event]) {\n        listeners[event] = {};\n      }\n\n      if (listeners[event][listener]) {\n        element.removeEventListener(event, listeners[event][listener], options);\n      }\n\n      listeners[event][listener] = handler;\n      element.listeners = listeners;\n    }\n\n    element.addEventListener(event, handler, options);\n  });\n}\n\n/**\n * Dispatch event on the target element.\n * @param {Element} element - The event target.\n * @param {string} type - The event type(s).\n * @param {Object} data - The additional event data.\n * @returns {boolean} Indicate if the event is default prevented or not.\n */\nexport function dispatchEvent(element, type, data) {\n  let event;\n\n  // Event and CustomEvent on IE9-11 are global objects, not constructors\n  if (isFunction(Event) && isFunction(CustomEvent)) {\n    event = new CustomEvent(type, {\n      detail: data,\n      bubbles: true,\n      cancelable: true,\n    });\n  } else {\n    event = document.createEvent('CustomEvent');\n    event.initCustomEvent(type, true, true, data);\n  }\n\n  return element.dispatchEvent(event);\n}\n\n/**\n * Check if the given year is a leap year.\n * @param {number} year - The year to check.\n * @returns {boolean} Returns `true` if the given year is a leap year, else `false`.\n */\nexport function isLeapYear(year) {\n  return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\n/**\n * Get days number of the given month.\n * @param {number} year - The target year.\n * @param {number} month - The target month.\n * @returns {number} Returns days number.\n */\nexport function getDaysInMonth(year, month) {\n  return [31, (isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];\n}\n\n/**\n * Add leading zeroes to the given value\n * @param {number} value - The value to add.\n * @param {number} [length=1] - The number of the leading zeroes.\n * @returns {string} Returns converted value.\n */\nexport function addLeadingZero(value, length = 1) {\n  const str = String(Math.abs(value));\n  let i = str.length;\n  let result = '';\n\n  if (value < 0) {\n    result += '-';\n  }\n\n  while (i < length) {\n    i += 1;\n    result += '0';\n  }\n\n  return result + str;\n}\n\n/**\n * Map token to type name\n * @param {string} token - The token to map.\n * @returns {string} Returns mapped type name.\n */\nexport function tokenToType(token) {\n  return {\n    Y: 'year',\n    M: 'month',\n    D: 'day',\n    H: 'hour',\n    m: 'minute',\n    s: 'second',\n    S: 'millisecond',\n  }[token.charAt(0)];\n}\n\nexport const REGEXP_TOKENS = /(Y|M|D|H|m|s|S)\\1*/g;\n\n/**\n * Parse date format.\n * @param {string} format - The format to parse.\n * @returns {Object} Returns parsed format data.\n */\nexport function parseFormat(format) {\n  let tokens = format.match(REGEXP_TOKENS);\n\n  if (!tokens) {\n    throw new Error('Invalid format.');\n  }\n\n  // Remove duplicate tokens (#22)\n  tokens = tokens.filter((token, index) => tokens.indexOf(token) === index);\n\n  const result = {\n    tokens,\n  };\n\n  tokens.forEach((token) => {\n    result[tokenToType(token)] = token;\n  });\n\n  return result;\n}\n"
  },
  {
    "path": "test/.eslintrc",
    "content": "{\n  \"env\": {\n    \"mocha\": true\n  },\n  \"globals\": {\n    \"Picker\": true,\n    \"expect\": true\n  },\n  \"rules\": {\n    \"no-new\": \"off\",\n    \"no-unused-expressions\": \"off\"\n  }\n}\n"
  },
  {
    "path": "test/helpers.js",
    "content": "window.createContainer = () => {\n  const container = document.createElement('div');\n\n  document.body.appendChild(container);\n\n  return container;\n};\n\nwindow.createInput = () => {\n  const input = document.createElement('input');\n  const container = window.createContainer();\n\n  container.appendChild(input);\n\n  return input;\n};\n"
  },
  {
    "path": "test/karma.conf.js",
    "content": "const puppeteer = require('puppeteer');\nconst rollupConfig = require('../rollup.config');\n\nprocess.env.CHROME_BIN = puppeteer.executablePath();\n\nmodule.exports = (config) => {\n  config.set({\n    autoWatch: false,\n    basePath: '..',\n    browsers: ['ChromeHeadless'],\n    coverageIstanbulReporter: {\n      reports: ['html', 'lcovonly', 'text-summary'],\n    },\n    files: [\n      'src/index.js',\n      'dist/picker.css',\n      'i18n/picker.en-US.js',\n      'i18n/picker.zh-CN.js',\n      'test/helpers.js',\n      'test/specs/**/*.spec.js',\n    ],\n    frameworks: ['mocha', 'chai'],\n    preprocessors: {\n      'src/index.js': ['rollup'],\n      'test/helpers.js': ['rollup'],\n      'test/specs/**/*.spec.js': ['rollup'],\n    },\n    reporters: ['mocha', 'coverage-istanbul'],\n    rollupPreprocessor: {\n      plugins: rollupConfig.plugins,\n      output: {\n        format: 'iife',\n        name: rollupConfig.output[0].name,\n        sourcemap: 'inline',\n      },\n    },\n    singleRun: true,\n  });\n};\n"
  },
  {
    "path": "test/specs/Picker.spec.js",
    "content": "describe('Picker', () => {\n  it('should be a class (function)', () => {\n    expect(Picker).to.be.a('function');\n  });\n\n  it('should throw error when the first argument is not an element', () => {\n    expect(() => {\n      new Picker(document);\n    }).to.throw('The first argument is required and must be an element.');\n  });\n});\n"
  },
  {
    "path": "test/specs/events/hidden.spec.js",
    "content": "describe('hidden (event)', () => {\n  it('should trigger the `hidden` event', (done) => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      shown() {\n        picker.hide();\n      },\n    });\n\n    input.addEventListener('hidden', (event) => {\n      expect(event.type).to.equal('hidden');\n      done();\n    });\n\n    picker.show();\n  });\n});\n"
  },
  {
    "path": "test/specs/events/hide.spec.js",
    "content": "describe('hide (event)', () => {\n  it('should trigger the `hide` event', (done) => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      shown() {\n        picker.hide();\n      },\n    });\n\n    input.addEventListener('hide', (event) => {\n      expect(event.type).to.equal('hide');\n      done();\n    });\n\n    picker.show();\n  });\n\n  it('should not trigger the `hidden` event when default prevented', (done) => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      shown() {\n        picker.hide();\n\n        setTimeout(() => {\n          expect(picker.shown).to.be.true;\n          done();\n\n          picker.destroy();\n        }, 1000);\n      },\n\n      hidden() {\n        expect.fain(1, 0);\n      },\n    });\n\n    input.addEventListener('hide', (event) => {\n      event.preventDefault();\n    });\n    picker.show();\n  });\n});\n"
  },
  {
    "path": "test/specs/events/pick.spec.js",
    "content": "describe('pick (event)', () => {\n  it('should trigger the `pick` event', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    input.addEventListener('pick', (event) => {\n      expect(event.type).to.equal('pick');\n    });\n    input.addEventListener('change', (event) => {\n      expect(event.type).to.equal('change');\n    });\n    expect(input.value).to.be.empty;\n    picker.pick();\n    expect(input.value).to.not.be.empty;\n  });\n});\n"
  },
  {
    "path": "test/specs/events/show.spec.js",
    "content": "describe('show (event)', () => {\n  it('should trigger the `show` event', () => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      shown() {\n        picker.hide();\n      },\n    });\n\n    input.addEventListener('show', (event) => {\n      expect(event.type).to.equal('show');\n    });\n\n    picker.show();\n  });\n\n  it('should not trigger the `shown` event when default prevented', (done) => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      shown() {\n        expect.fail(1, 0);\n      },\n    });\n\n    input.addEventListener('show', (event) => {\n      event.preventDefault();\n      setTimeout(() => {\n        expect(picker.shown).to.be.false;\n        done();\n      }, 1000);\n    });\n\n    picker.show();\n  });\n});\n"
  },
  {
    "path": "test/specs/events/shown.spec.js",
    "content": "describe('shown (event)', () => {\n  it('should trigger the `shown` event', (done) => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    input.addEventListener('shown', (event) => {\n      expect(event.type).to.equal('shown');\n      done();\n      picker.hide();\n    });\n    picker.show();\n  });\n});\n"
  },
  {
    "path": "test/specs/methods/destroy.spec.js",
    "content": "describe('destroy (method)', () => {\n  it('should destroy the picker correctly', () => {\n    const container = window.createContainer();\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      container,\n      inline: true,\n    });\n\n    expect(input.picker).to.equal(picker);\n    expect(container.childElementCount).to.equal(1);\n    picker.destroy();\n    expect(input.picker).to.be.undefined;\n    expect(container.childElementCount).to.equal(0);\n  });\n});\n"
  },
  {
    "path": "test/specs/methods/formatDate.spec.js",
    "content": "describe('formatDate (method)', () => {\n  it('should format the given date correctly', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    expect(picker.formatDate('Invalid Date')).to.equal('');\n    expect(picker.formatDate(new Date(2048, 9, 24, 5, 12))).to.equal('2048-10-24 05:12');\n  });\n});\n"
  },
  {
    "path": "test/specs/methods/getDate.spec.js",
    "content": "describe('getDate (method)', () => {\n  it('should get a date object', () => {\n    const input = window.createInput();\n    const date = new Date(2048, 9, 24, 5, 12);\n    const picker = new Picker(input, {\n      date,\n    });\n\n    expect(picker.getDate().getTime()).to.equal(date.getTime());\n  });\n\n  it('should get a formatted date', () => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      date: new Date(2048, 9, 24, 5, 12),\n    });\n\n    expect(picker.getDate(true)).to.equal('2048-10-24 05:12');\n  });\n});\n"
  },
  {
    "path": "test/specs/methods/hide.spec.js",
    "content": "describe('hide (method)', () => {\n  it('should hide the picker', (done) => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      shown() {\n        expect(picker.shown).to.be.true;\n        picker.hide();\n        expect(picker.shown).to.be.false;\n        done();\n      },\n    });\n\n    picker.show();\n  });\n\n  it('should hide the picker immediately', (done) => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      shown() {\n        expect(picker.shown).to.be.true;\n        picker.hide(true);\n        expect(picker.shown).to.be.false;\n        done();\n      },\n    });\n\n    picker.show();\n  });\n});\n"
  },
  {
    "path": "test/specs/methods/next.spec.js",
    "content": "describe('next (method)', () => {\n  it('should switch to the next date item', () => {\n    const input = window.createInput();\n    const date = '2048-10-24 5:12:2.56';\n    const picker = new Picker(input, {\n      date,\n      format: 'YYYY-M-D H:m:s.S',\n    });\n\n    picker.next('year');\n    expect(picker.getDate().getFullYear()).to.equal(2049);\n    picker.next('month');\n    expect(picker.getDate().getMonth()).to.equal(10);\n    picker.next('day');\n    expect(picker.getDate().getDate()).to.equal(25);\n    picker.next('hour');\n    expect(picker.getDate().getHours()).to.equal(6);\n    picker.next('minute');\n    expect(picker.getDate().getMinutes()).to.equal(13);\n    picker.next('second');\n    expect(picker.getDate().getSeconds()).to.equal(3);\n    picker.next('millisecond');\n    expect(picker.getDate().getMilliseconds()).to.equal(57);\n  });\n});\n"
  },
  {
    "path": "test/specs/methods/noConflict.spec.js",
    "content": "describe('noConflict', () => {\n  it('should be a static method', () => {\n    expect(Picker.noConflict).to.be.a('function');\n  });\n\n  it('should return the Picker class itself', () => {\n    const { Picker } = window;\n    const ImagePicker = Picker.noConflict();\n\n    expect(ImagePicker).to.equal(Picker);\n    expect(window.Picker).to.be.undefined;\n\n    // Reverts it for the rest test suites\n    window.Picker = ImagePicker;\n  });\n});\n"
  },
  {
    "path": "test/specs/methods/parseDate.spec.js",
    "content": "describe('parseDate (method)', () => {\n  it('should parse date correctly', () => {\n    const input = window.createInput();\n    const date = '2048-10-24 05:12';\n    const picker = new Picker(input);\n\n    expect(picker.formatDate(picker.parseDate(date))).to.equal(date);\n  });\n});\n"
  },
  {
    "path": "test/specs/methods/pick.spec.js",
    "content": "describe('pick (method)', () => {\n  it('should pick the date to the input element', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    expect(input.value).to.equal('');\n    picker.pick();\n    expect(input.value).to.equal(picker.getDate(true));\n  });\n});\n"
  },
  {
    "path": "test/specs/methods/prev.spec.js",
    "content": "describe('prev (method)', () => {\n  it('should switch to the previous date item', () => {\n    const input = window.createInput();\n    const date = '2048-10-24 5:12:2.56';\n    const picker = new Picker(input, {\n      date,\n      format: 'YYYY-M-D H:m:s.S',\n    });\n\n    picker.prev('year');\n    expect(picker.getDate().getFullYear()).to.equal(2047);\n    picker.prev('month');\n    expect(picker.getDate().getMonth()).to.equal(8);\n    picker.prev('day');\n    expect(picker.getDate().getDate()).to.equal(23);\n    picker.prev('hour');\n    expect(picker.getDate().getHours()).to.equal(4);\n    picker.prev('minute');\n    expect(picker.getDate().getMinutes()).to.equal(11);\n    picker.prev('second');\n    expect(picker.getDate().getSeconds()).to.equal(1);\n    picker.prev('millisecond');\n    expect(picker.getDate().getMilliseconds()).to.equal(55);\n  });\n});\n"
  },
  {
    "path": "test/specs/methods/reset.spec.js",
    "content": "describe('reset (method)', () => {\n  it('should reset the value of the input element', () => {\n    const input = window.createInput();\n    const initialValue = '1024-05-12 02:56';\n\n    input.value = initialValue;\n\n    const value = '2048-10-24 05:12';\n    const picker = new Picker(input);\n\n    picker.setDate(value).pick();\n    expect(picker.getDate(true)).to.equal(value);\n    expect(input.value).to.equal(value);\n    picker.reset();\n    expect(picker.getDate(true)).to.equal(initialValue);\n    expect(input.value).to.equal(initialValue);\n  });\n});\n"
  },
  {
    "path": "test/specs/methods/setDate.spec.js",
    "content": "describe('setDate (method)', () => {\n  it('should set date correctly', () => {\n    const input = window.createInput();\n    const date = new Date(2048, 9, 24, 5, 12);\n    const picker = new Picker(input, {\n      date,\n    });\n\n    picker.setDate(date);\n    expect(picker.getDate().getTime()).to.equal(date.getTime());\n\n    const date2 = '1024-05-12 02:56';\n\n    picker.setDate(date2);\n    expect(picker.getDate(true)).to.equal(date2);\n  });\n});\n"
  },
  {
    "path": "test/specs/methods/setDefaults.spec.js",
    "content": "describe('setDefaults', () => {\n  it('should be a static method', () => {\n    expect(Picker.setDefaults).to.be.a('function');\n  });\n\n  it('should change the global default options', () => {\n    Picker.setDefaults({\n      controls: true,\n    });\n\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      controls: true,\n    });\n\n    expect(picker.picker.querySelectorAll('.picker-cell__control--prev').length).to.equal(5);\n    expect(picker.picker.querySelectorAll('.picker-cell__control--next').length).to.equal(5);\n\n    // Reverts it for the rest test suites\n    Picker.setDefaults({\n      controls: false,\n    });\n  });\n});\n"
  },
  {
    "path": "test/specs/methods/show.spec.js",
    "content": "describe('show (method)', () => {\n  it('should show the picker', (done) => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      shown() {\n        picker.hide();\n        done();\n      },\n    });\n\n    expect(picker.shown).to.be.false;\n    picker.show();\n    expect(picker.shown).to.be.true;\n  });\n\n  it('should show the picker immediately', () => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      shown() {\n        picker.hide();\n      },\n    });\n\n    expect(picker.shown).to.be.false;\n    picker.show(true);\n    expect(picker.shown).to.be.false;\n  });\n});\n"
  },
  {
    "path": "test/specs/methods/update.spec.js",
    "content": "describe('update (method)', () => {\n  it('should update the picker when the value of the input element changed', () => {\n    const input = window.createInput();\n    const value = '2048-10-24 05:12';\n    const picker = new Picker(input);\n\n    input.value = value;\n    picker.update();\n    expect(picker.getDate(true)).to.equal(value);\n  });\n});\n"
  },
  {
    "path": "test/specs/options/container.spec.js",
    "content": "describe('container (option)', () => {\n  it('should be `null` by default', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    expect(picker.options.container).to.be.null;\n  });\n\n  it('should support element', () => {\n    const container = window.createContainer();\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      container,\n      inline: true,\n    });\n\n    expect(picker.picker.parentElement).to.equal(container);\n  });\n\n  it('should support selector', () => {\n    const container = window.createContainer();\n\n    container.className = 'js-option-container';\n\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      container: '.js-option-container',\n      inline: true,\n    });\n\n    expect(picker.picker.parentElement).to.equal(container);\n  });\n\n  it('should use self as container', () => {\n    const container = window.createContainer();\n    const picker = new Picker(container, {\n      inline: true,\n    });\n\n    expect(picker.picker.parentElement).to.equal(container);\n  });\n});\n"
  },
  {
    "path": "test/specs/options/controls.spec.js",
    "content": "describe('controls (option)', () => {\n  it('should be `false` by default', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    expect(picker.options.controls).to.be.false;\n  });\n\n  it('should show the controls', () => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      controls: true,\n    });\n\n    expect(picker.picker.querySelectorAll('.picker-cell__control--prev').length).to.equal(5);\n    expect(picker.picker.querySelectorAll('.picker-cell__control--next').length).to.equal(5);\n  });\n\n  it('should move to the previous year once click the prev control', () => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      controls: true,\n    });\n\n    const year = picker.getDate().getFullYear();\n\n    picker.picker.querySelector('.picker-years .picker-cell__control--prev').click();\n    expect(picker.getDate().getFullYear()).to.equal(year - 1);\n  });\n\n  it('should move to the next year once click the next control', () => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      controls: true,\n    });\n\n    const year = picker.getDate().getFullYear();\n\n    picker.picker.querySelector('.picker-years .picker-cell__control--next').click();\n    expect(picker.getDate().getFullYear()).to.equal(year + 1);\n  });\n});\n"
  },
  {
    "path": "test/specs/options/date.spec.js",
    "content": "describe('date (option)', () => {\n  it('should be `null` by default', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    expect(picker.options.date).to.be.null;\n  });\n\n  it('should support object value', () => {\n    const input = window.createInput();\n    const time = Date.now() + 3600000;\n    const picker = new Picker(input, {\n      date: new Date(time),\n    });\n\n    expect(picker.getDate().getTime()).to.equal(time);\n  });\n\n  it('should support string value', () => {\n    const input = window.createInput();\n    const date = '2222-02-22 22:22';\n    const picker = new Picker(input, {\n      date,\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n  });\n});\n"
  },
  {
    "path": "test/specs/options/format.spec.js",
    "content": "describe('format (option)', () => {\n  it('should match the given format', () => {\n    const input = window.createInput();\n    const date = '1111/1/1 1:1:1.1';\n    const picker = new Picker(input, {\n      date,\n      format: 'YYYY/M/D H:m:s.S',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n  });\n\n  it('should support \"YYYYMMDD\"', () => {\n    const input = window.createInput();\n    const date = '11111111';\n    const picker = new Picker(input, {\n      date,\n      format: 'YYYYMMDD',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n  });\n\n  it('should support \"YYYY\"', () => {\n    const input = window.createInput();\n    const date = '1111';\n    const picker = new Picker(input, {\n      date,\n      format: 'YYYY',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('111');\n    expect(picker.getDate(true)).to.equal('0111');\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('0011');\n    picker.setDate('1');\n    expect(picker.getDate(true)).to.equal('0001');\n    picker.setDate('11111');\n    expect(picker.getDate(true)).to.equal('11111');\n  });\n\n  it('should support \"YYY\"', () => {\n    const input = window.createInput();\n    const date = '111';\n    const picker = new Picker(input, {\n      date,\n      format: 'YYY',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('011');\n    picker.setDate('1');\n    expect(picker.getDate(true)).to.equal('001');\n    picker.setDate('1111');\n    expect(picker.getDate(true)).to.equal('1111');\n  });\n\n  it('should support \"YY\"', () => {\n    const input = window.createInput();\n    const date = '11';\n    const picker = new Picker(input, {\n      date,\n      format: 'YY',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    expect(picker.getDate().getFullYear()).to.equal(2011);\n    picker.setDate('1');\n    expect(picker.getDate(true)).to.equal('01');\n    expect(picker.getDate().getFullYear()).to.equal(2001);\n    picker.setDate('111');\n    expect(picker.getDate(true)).to.equal('11');\n  });\n\n  it('should support \"Y\"', () => {\n    const input = window.createInput();\n    const date = '1';\n    const picker = new Picker(input, {\n      date,\n      format: 'Y',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('11');\n\n    // 1000 BC\n    picker.setDate('-1000');\n    expect(picker.getDate(true)).to.equal('-1000');\n  });\n\n  it('should support \"MMMM\"', () => {\n    const input = window.createInput();\n    const date = 'December';\n    const picker = new Picker(input, {\n      date,\n      format: 'MMMM',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n  });\n\n  it('should support \"MMM\"', () => {\n    const input = window.createInput();\n    const date = 'Dec';\n    const picker = new Picker(input, {\n      date,\n      format: 'MMM',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n  });\n\n  it('should support \"MM\"', () => {\n    const input = window.createInput();\n    const date = '01';\n    const picker = new Picker(input, {\n      date,\n      format: 'MM',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('11');\n  });\n\n  it('should support \"M\"', () => {\n    const input = window.createInput();\n    const date = '1';\n    const picker = new Picker(input, {\n      date,\n      format: 'M',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('11');\n  });\n\n  it('should support \"DD\"', () => {\n    const input = window.createInput();\n    const date = '01';\n    const picker = new Picker(input, {\n      date,\n      format: 'DD',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('11');\n  });\n\n  it('should support \"D\"', () => {\n    const input = window.createInput();\n    const date = '1';\n    const picker = new Picker(input, {\n      date,\n      format: 'D',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('11');\n  });\n\n  it('should support \"HH\"', () => {\n    const input = window.createInput();\n    const date = '01';\n    const picker = new Picker(input, {\n      date,\n      format: 'HH',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('11');\n  });\n\n  it('should support \"H\"', () => {\n    const input = window.createInput();\n    const date = '1';\n    const picker = new Picker(input, {\n      date,\n      format: 'H',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('11');\n  });\n\n  it('should support \"mm\"', () => {\n    const input = window.createInput();\n    const date = '01';\n    const picker = new Picker(input, {\n      date,\n      format: 'mm',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('11');\n  });\n\n  it('should support \"m\"', () => {\n    const input = window.createInput();\n    const date = '1';\n    const picker = new Picker(input, {\n      date,\n      format: 'm',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('11');\n  });\n\n  it('should support \"ss\"', () => {\n    const input = window.createInput();\n    const date = '01';\n    const picker = new Picker(input, {\n      date,\n      format: 'ss',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('11');\n  });\n\n  it('should support \"s\"', () => {\n    const input = window.createInput();\n    const date = '1';\n    const picker = new Picker(input, {\n      date,\n      format: 's',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('11');\n  });\n\n  it('should support \"SSS\"', () => {\n    const input = window.createInput();\n    const date = '001';\n    const picker = new Picker(input, {\n      date,\n      format: 'SSS',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('011');\n    picker.setDate('1');\n    expect(picker.getDate(true)).to.equal('001');\n  });\n\n  it('should support \"SS\"', () => {\n    const input = window.createInput();\n    const date = '01';\n    const picker = new Picker(input, {\n      date,\n      format: 'SS',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('11');\n  });\n\n  it('should support \"S\"', () => {\n    const input = window.createInput();\n    const date = '1';\n    const picker = new Picker(input, {\n      date,\n      format: 'S',\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n    picker.setDate('11');\n    expect(picker.getDate(true)).to.equal('11');\n  });\n\n  it('should throw error when the format is invalid', () => {\n    const input = window.createInput();\n\n    expect(() => {\n      new Picker(input, {\n        format: '',\n      });\n    }).to.throw('Invalid format.');\n  });\n});\n"
  },
  {
    "path": "test/specs/options/headers.spec.js",
    "content": "describe('headers (option)', () => {\n  it('should be `false` by default', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    expect(picker.options.headers).to.be.false;\n  });\n\n  it('should show the column headers', () => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      headers: true,\n    });\n\n    expect(picker.picker.querySelector('.picker-years .picker-cell__header').textContent).to.equal('Year');\n    expect(picker.picker.querySelector('.picker-months .picker-cell__header').textContent).to.equal('Month');\n    expect(picker.picker.querySelector('.picker-days .picker-cell__header').textContent).to.equal('Day');\n  });\n\n  it('should show the custom column headers', () => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      headers: true,\n      text: {\n        year: '年',\n        month: '月',\n      },\n    });\n\n    expect(picker.picker.querySelector('.picker-years .picker-cell__header').textContent).to.equal('年');\n    expect(picker.picker.querySelector('.picker-months .picker-cell__header').textContent).to.equal('月');\n    expect(picker.picker.querySelector('.picker-days .picker-cell__header').textContent).to.equal('Day');\n  });\n\n  it('should fall back to default headers even though the values are undefined', () => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      headers: true,\n      text: {\n        year: undefined,\n        month: undefined,\n        day: undefined,\n      },\n    });\n\n    expect(picker.picker.querySelector('.picker-years .picker-cell__header').textContent).to.equal('Year');\n    expect(picker.picker.querySelector('.picker-months .picker-cell__header').textContent).to.equal('Month');\n    expect(picker.picker.querySelector('.picker-days .picker-cell__header').textContent).to.equal('Day');\n  });\n});\n"
  },
  {
    "path": "test/specs/options/hidden.spec.js",
    "content": "describe('hidden (option)', () => {\n  it('should be `null` be default', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    expect(picker.options.hidden).to.be.null;\n  });\n\n  it('should execute the `hidden` hook function', (done) => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      shown() {\n        picker.hide();\n      },\n\n      hidden(event) {\n        expect(event.type).to.equal('hidden');\n        done();\n      },\n    });\n\n    picker.show();\n  });\n});\n"
  },
  {
    "path": "test/specs/options/hide.spec.js",
    "content": "describe('hide (option)', () => {\n  it('should be `null` be default', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    expect(picker.options.hide).to.be.null;\n  });\n\n  it('should execute the `hide` hook function', (done) => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      shown() {\n        picker.hide();\n      },\n\n      hide(event) {\n        expect(event.type).to.equal('hide');\n        done();\n      },\n    });\n\n    picker.show();\n  });\n\n  it('should not execute the `hidden` hook function when default prevented', (done) => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      shown() {\n        picker.hide();\n\n        setTimeout(() => {\n          expect(picker.shown).to.be.true;\n          done();\n          picker.destroy();\n        }, 1000);\n      },\n\n      hide(event) {\n        event.preventDefault();\n      },\n\n      hidden() {\n        expect.fail(1, 0);\n      },\n    });\n\n    picker.show();\n  });\n});\n"
  },
  {
    "path": "test/specs/options/increment.spec.js",
    "content": "describe('increment (option)', () => {\n  it('should be `1` by default', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    expect(picker.options.increment).to.equal(1);\n  });\n\n  it('should support number value', () => {\n    const input = window.createInput();\n\n    // Be sure that `date.getMonth() + increment` should less than `12` and so on.\n    const date = new Date(2048, 1, 1, 1, 1, 1, 1, 1);\n    const increment = 2;\n    const picker = new Picker(input, {\n      date,\n      format: 'YYYY-M-D H:m:s.S',\n      increment,\n    });\n\n    expect(Number(picker.picker.querySelector('.picker-picked[data-name=\"year\"]').nextElementSibling.dataset.value)).to.equal(date.getFullYear() + increment);\n    expect(Number(picker.picker.querySelector('.picker-picked[data-name=\"month\"]').nextElementSibling.dataset.value)).to.equal(date.getMonth() + increment);\n    expect(Number(picker.picker.querySelector('.picker-picked[data-name=\"day\"]').nextElementSibling.dataset.value)).to.equal(date.getDate() + increment);\n    expect(Number(picker.picker.querySelector('.picker-picked[data-name=\"hour\"]').nextElementSibling.dataset.value)).to.equal(date.getHours() + increment);\n    expect(Number(picker.picker.querySelector('.picker-picked[data-name=\"minute\"]').nextElementSibling.dataset.value)).to.equal(date.getMinutes() + increment);\n    expect(Number(picker.picker.querySelector('.picker-picked[data-name=\"second\"]').nextElementSibling.dataset.value)).to.equal(date.getSeconds() + increment);\n    expect(Number(picker.picker.querySelector('.picker-picked[data-name=\"millisecond\"]').nextElementSibling.dataset.value)).to.equal(date.getMilliseconds() + increment);\n  });\n\n  it('should support object value', () => {\n    const input = window.createInput();\n\n    // Be sure that `date.getMonth() + increment` should less than `12` and so on.\n    const date = new Date(2048, 1, 1, 1, 1, 1, 1, 1);\n    const increment = 2;\n    const picker = new Picker(input, {\n      date,\n      format: 'YYYY-M-D H:m:s.S',\n      increment: {\n        year: increment,\n        month: increment,\n        day: increment,\n        hour: increment,\n        minute: increment,\n        second: increment,\n        millisecond: increment,\n      },\n    });\n\n    expect(Number(picker.picker.querySelector('.picker-picked[data-name=\"year\"]').nextElementSibling.dataset.value)).to.equal(date.getFullYear() + increment);\n    expect(Number(picker.picker.querySelector('.picker-picked[data-name=\"month\"]').nextElementSibling.dataset.value)).to.equal(date.getMonth() + increment);\n    expect(Number(picker.picker.querySelector('.picker-picked[data-name=\"day\"]').nextElementSibling.dataset.value)).to.equal(date.getDate() + increment);\n    expect(Number(picker.picker.querySelector('.picker-picked[data-name=\"hour\"]').nextElementSibling.dataset.value)).to.equal(date.getHours() + increment);\n    expect(Number(picker.picker.querySelector('.picker-picked[data-name=\"minute\"]').nextElementSibling.dataset.value)).to.equal(date.getMinutes() + increment);\n    expect(Number(picker.picker.querySelector('.picker-picked[data-name=\"second\"]').nextElementSibling.dataset.value)).to.equal(date.getSeconds() + increment);\n    expect(Number(picker.picker.querySelector('.picker-picked[data-name=\"millisecond\"]').nextElementSibling.dataset.value)).to.equal(date.getMilliseconds() + increment);\n  });\n});\n"
  },
  {
    "path": "test/specs/options/inline.spec.js",
    "content": "describe('inline (option)', () => {\n  it('should be `false` by default', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    expect(picker.options.inline).to.be.false;\n  });\n\n  it('should be inline', () => {\n    const container = window.createContainer();\n    const picker = new Picker(container, {\n      inline: true,\n    });\n\n    expect(picker.picker.parentElement).to.equal(container);\n  });\n\n  it('should work with the `container` option', () => {\n    const container = window.createContainer();\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      container,\n      inline: true,\n    });\n\n    expect(picker.picker.parentElement).to.equal(container);\n  });\n});\n"
  },
  {
    "path": "test/specs/options/language.spec.js",
    "content": "describe('language (option)', () => {\n  it('should be empty by default', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    expect(picker.options.language).to.be.empty;\n  });\n\n  it('should use the given language', () => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      language: 'en-US',\n    });\n\n    expect(picker.options.format).to.equal(Picker.languages['en-US'].format);\n  });\n});\n"
  },
  {
    "path": "test/specs/options/months.spec.js",
    "content": "describe('months (option)', () => {\n  it('should use the given months', () => {\n    const input = window.createInput();\n    const date = '十一月';\n    const picker = new Picker(input, {\n      date,\n      format: 'MMMM',\n      months: [\n        '一月',\n        '二月',\n        '三月',\n        '四月',\n        '五月',\n        '六月',\n        '七月',\n        '八月',\n        '九月',\n        '十月',\n        '十一月',\n        '十二月',\n      ],\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n  });\n});\n"
  },
  {
    "path": "test/specs/options/monthsShort.spec.js",
    "content": "describe('monthsShort (option)', () => {\n  it('should use the given short months', () => {\n    const input = window.createInput();\n    const date = '6月';\n    const picker = new Picker(input, {\n      date,\n      format: 'MMM',\n      monthsShort: [\n        '1月',\n        '2月',\n        '3月',\n        '4月',\n        '5月',\n        '6月',\n        '7月',\n        '8月',\n        '9月',\n        '10月',\n        '11月',\n        '12月',\n      ],\n    });\n\n    expect(picker.getDate(true)).to.equal(date);\n  });\n});\n"
  },
  {
    "path": "test/specs/options/pick.spec.js",
    "content": "describe('pick (option)', () => {\n  it('should be `null` be default', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    expect(picker.options.pick).to.be.null;\n  });\n\n  it('should execute the `pick` hook function', () => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      pick(event) {\n        expect(event.type).to.equal('pick');\n      },\n    });\n\n    expect(input.value).to.be.empty;\n    picker.pick();\n    expect(input.value).to.not.be.empty;\n    picker.destroy();\n  });\n});\n"
  },
  {
    "path": "test/specs/options/rows.spec.js",
    "content": "describe('rows (option)', () => {\n  it('should be `5` by default', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    expect(picker.options.rows).to.equal(5);\n  });\n\n  it('should match the given rows', () => {\n    const input = window.createInput();\n    const rows = 7;\n    const picker = new Picker(input, {\n      rows,\n    });\n\n    expect(picker.picker.querySelectorAll('.picker-item[data-name=\"year\"]').length - 2).to.equal(rows);\n  });\n\n  it('should plus 1 when the rows is even', () => {\n    const input = window.createInput();\n    const rows = 6;\n    const picker = new Picker(input, {\n      rows,\n    });\n\n    expect(picker.picker.querySelectorAll('.picker-item[data-name=\"year\"]').length - 2).to.equal(rows + 1);\n  });\n\n  it('should support one row', () => {\n    const input = window.createInput();\n    const rows = 1;\n    const picker = new Picker(input, {\n      rows,\n    });\n\n    expect(picker.picker.querySelectorAll('.picker-item[data-name=\"year\"]').length - 2).to.equal(rows);\n  });\n\n  it('should fall back to 5 if the value is NaN', () => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      rows: NaN,\n    });\n\n    expect(picker.picker.querySelectorAll('.picker-item[data-name=\"year\"]').length - 2).to.equal(5);\n  });\n});\n"
  },
  {
    "path": "test/specs/options/show.spec.js",
    "content": "describe('show (option)', () => {\n  it('should be `null` be default', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    expect(picker.options.show).to.be.null;\n  });\n\n  it('should execute the `show` hook function', () => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      show(event) {\n        expect(event.type).to.equal('show');\n      },\n\n      shown() {\n        picker.hide();\n      },\n\n      hidden() {\n        picker.destroy();\n      },\n    });\n\n    picker.show();\n  });\n\n  it('should not execute the `shown` hook function when default prevented', (done) => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      show(event) {\n        event.preventDefault();\n\n        setTimeout(() => {\n          expect(picker.shown).to.be.false;\n          done();\n        }, 1000);\n      },\n\n      shown() {\n        expect.fail(1, 0);\n      },\n    });\n\n    picker.show();\n  });\n});\n"
  },
  {
    "path": "test/specs/options/shown.spec.js",
    "content": "describe('shown (option)', () => {\n  it('should be `null` be default', () => {\n    const input = window.createInput();\n    const picker = new Picker(input);\n\n    expect(picker.options.shown).to.be.null;\n  });\n\n  it('should execute the `shown` hook function', (done) => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      shown(event) {\n        expect(event.type).to.equal('shown');\n        done();\n        picker.hide();\n      },\n    });\n\n    picker.show();\n  });\n});\n"
  },
  {
    "path": "test/specs/options/text.spec.js",
    "content": "describe('text (option)', () => {\n  it('should match the given text', () => {\n    const input = window.createInput();\n    const text = {\n      title: '选择日期时间',\n      cancel: '取消',\n      confirm: '确认',\n    };\n    const picker = new Picker(input, {\n      text,\n    });\n\n    expect(picker.picker.querySelector('.picker-title').textContent).to.equal(text.title);\n    expect(picker.picker.querySelector('.picker-cancel').textContent).to.equal(text.cancel);\n    expect(picker.picker.querySelector('.picker-confirm').textContent).to.equal(text.confirm);\n  });\n\n  it('should support partial properties', () => {\n    const input = window.createInput();\n    const text = {\n      title: '选择日期时间',\n    };\n    const picker = new Picker(input, {\n      text,\n    });\n\n    expect(picker.picker.querySelector('.picker-title').textContent).to.equal(text.title);\n    expect(picker.picker.querySelector('.picker-cancel').textContent).to.equal('Cancel');\n    expect(picker.picker.querySelector('.picker-confirm').textContent).to.equal('OK');\n  });\n});\n"
  },
  {
    "path": "test/specs/options/translate.spec.js",
    "content": "describe('translate (option)', () => {\n  it('should translate the date correctly', () => {\n    const input = window.createInput();\n    const picker = new Picker(input, {\n      translate(type, text) {\n        const suffixes = {\n          year: '年',\n          month: '月',\n          day: '日',\n          hour: '时',\n          minute: '分',\n        };\n\n        return Number(text) + suffixes[type];\n      },\n    });\n\n    expect(picker.picker.querySelector('.picker-picked[data-name=\"year\"]').textContent).to.equal(`${picker.getDate().getFullYear()}年`);\n  });\n});\n"
  },
  {
    "path": "types/index.d.ts",
    "content": "declare namespace Picker {\n  export interface HeadersOptions {\n    year?: string;\n    month?: string;\n    day?: string;\n    hour?: string;\n    minute?: string;\n    second?: string;\n    millisecond?: string;\n  }\n\n  export interface IncrementOptions {\n    year?: number;\n    month?: number;\n    day?: number;\n    hour?: number;\n    minute?: number;\n    second?: number;\n    millisecond?: number;\n  }\n\n  export interface TextOptions extends HeadersOptions {\n    title?: string;\n    cancel?: string;\n    confirm?: string;\n  }\n\n  export interface Options {\n    container?: string | Element;\n    controls?: boolean;\n    date?: string | Date;\n    format?: string;\n    headers?: boolean | HeadersOptions;\n    hidden?(event: CustomEvent): void;\n    hide?(event: CustomEvent): void;\n    increment?: number | IncrementOptions;\n    inline?: boolean;\n    language?: string;\n    months?: string[];\n    monthsShort?: string[];\n    pick?(event: CustomEvent): void;\n    rows?: number;\n    show?(event: CustomEvent): void;\n    shown?(event: CustomEvent): void;\n    text?: TextOptions;\n    translate?(type: string, text: string): string;\n  }\n}\n\ndeclare class Picker {\n  constructor(element: HTMLElement, options?: Picker.Options);\n  destroy(): Picker;\n  formatDate(date: Date): string;\n  getDate(formatted?: boolean): Date | string;\n  hide(): Picker;\n  next(type: string): Picker;\n  parseDate(date: string): Date;\n  pick(): Picker;\n  prev(type: string): Picker;\n  reset(): Picker;\n  setDate(date: Date): Picker;\n  show(): Picker;\n  update(): Picker;\n  static noConflict(): Picker;\n  static setDefaults(options: Picker.Options): void;\n}\n\ndeclare module 'pickerjs' {\n  export default Picker;\n}\n"
  }
]