Full Code of phoenixwong/vue2-timepicker for AI

master 8f9371f9d8ce cached
29 files
694.3 KB
183.2k tokens
20 symbols
3 requests
Download .txt
Showing preview only (716K chars total). Download the full file or copy to clipboard to get everything.
Repository: phoenixwong/vue2-timepicker
Branch: master
Commit: 8f9371f9d8ce
Files: 29
Total size: 694.3 KB

Directory structure:
gitextract_knz350g7/

├── .gitignore
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.md
├── MIGRATION.md
├── README.md
├── babel.config.js
├── demo/
│   ├── .gitignore
│   ├── README.md
│   ├── babel.config.js
│   ├── package.json
│   ├── public/
│   │   └── index.html
│   ├── src/
│   │   ├── App.vue
│   │   ├── assets/
│   │   │   ├── _variables.styl
│   │   │   └── demo.styl
│   │   ├── components/
│   │   │   ├── ConfigRow.vue
│   │   │   ├── OverlayPanel.vue
│   │   │   ├── Playground.vue
│   │   │   ├── SampleBlock.vue
│   │   │   └── Samples.vue
│   │   └── main.js
│   └── vue.config.js
├── dist/
│   ├── VueTimepicker.common.js
│   ├── VueTimepicker.css
│   ├── VueTimepicker.umd.js
│   └── demo.html
├── package.json
└── src/
    ├── index.js
    └── vue-timepicker.vue

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so

# Packages #
############
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip

# Cache and logs #
##################
Application/Runtime/Cache/
Application/Runtime/Logs/
Application/Runtime/Temp/
*.log

# OS generated files #
######################
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
~$*
.editorconfig

# NodeJS Packages #
###################
node_modules
yarn.lock*
package.lock*

# Bower Packages #
###################
bower
bower_components

# Test and Logs #
#################
npm-debug.log
yarn-debug.log*
yarn-error.log*
selenium-debug.log
test/unit/coverage
test/e2e/reports

# local env files #
###################
.env.local
.env.*.local

# Editor directories and files #
################################
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

# Others  #
###########
gh-pages


================================================
FILE: CHANGELOG.md
================================================
# CHANGELOG

> The Change Log of Vue2 Timepicker `vue2-timepicker`

## v 1.1.6

### New

- Support appending the dropdown menu to the document body with `append-to-body`

### Improvements

- In Manual Input mode, support jumping to the next token slot with a colon (`:`) or space (` `) key.
- Return full data on `blur` and `close` events as per the `change` event.

## v 1.1.5

### New

- Support changing dropdown direction with the `drop-direction` property. It accepts three string values: `"up"`, `"auto"` and `"down"` _(default)_.
- Additional `container-id` and `drop-offset-height` as helpers for the **"auto"** drop direction. Please check the documentation for more info.

## v 1.1.4

### New

- Support customized clear button and dropdown button with the `clearButton` and `dropdownButton` **v-slot** (Thanks to @jost-s).
- Added new `icon` **v-slot** for displaying an extra input icon.
- Added new `fixed-dropdown-button` property, to make the dropdown button always visible.

## v 1.1.3

### Improvements

- Enhanced `hide-dropdown` feature -- When the dropdown is hidden by default, users can choose to open the dropdown by clicking the triangle button "▾" (Thanks to @jost-s).
- Refined `focus` and `blur` event.
- Minor fixes for the Advanced Keyboard mode.

## v 1.1.2

### New

More powerful `format` string parameter. E.g., you can hide the "hour" column by setting `format="mm:ss"`, or make AM/PM the first column by `format="A hh:ss"`, no extra CSS hacking needed. Please check the Demo page for more examples.

### Improvements

- Support `shift+tab` to navigate to the previous token slot in the Manual Input mode (Thanks to @jost-s).
- Other minor keyboard navigation enhancements for Manual Input mode

## v 1.1.1

### Improvements

Instant feedback after manual input. Plus, add a new `manual-input-timeout` property to help set up the timeout for continuous input (Thanks to @jost-s).

#### Notes for Contributors

We've upgraded to use vue-cli **v4** in this version. Please check the CONTRIBUTING.md for more info.


## v 1.1.0

### New

- Support manually input values with the `manual-input` toggle.
- Enable to hide the dropdown menu with `hide-dropdown` in Manual Input (`manual-input`) mode.
- Added conditional helper classes `is-empty`, `invalid` and `all-selected` to the `<input>` element.
- Change the `<input>` border to red color when user input is invalid. E.g., when it contains a disabled hour value. You can mute this auto-styling by adding `"skip-error-style"` to `input-class`.
- Add support to the `autocomplete` attribute.
- Emit `error` event when the input value becomes invalid.
- Emit `focus` and `blur` events to help to identify the focus/blur state. Useful when the dropdown is force hidden by `hide-dropdown`.

### Improvements

Enable seamless loop from the start or end of a column in `advanced-keyboard` mode.

## v 1.0.8

### Improvements

Keep the dropdown menu open when mouse drag on the hour/minute/second list's scrollbar handler.

## v 1.0.7

### Fixes

Fixes `placeholder` not dynamically updated issue in some cases (Thanks to @ObsidianTech).

### Improvements

Vertical alignment refined for the clear button across different browsers.

## v 1.0.6

### New

Added `auto-scroll` feature.

### Improvements

On Advanced Keyboard mode, auto-focus on the selected value (if any) in priority.

## v 1.0.5

### Fixes

Fixes the Advanced Keyboard tab navigating feature on Firefox

## v 1.0.4

### Improvements

- Adjust the default value of `blur-delay` to 300ms. (Thanks to @rjurado01).
- Added _Array_ and _Object_ types support to `input-class`.

## v 1.0.3

### New

Added `lazy` event mode. (Thanks to @VictorCazanave)

## v 1.0.2

### New

- Support customized labels for the hour, minute, second, and APM pickers (Thanks to @maritaria).
- Support setting customized text to replace the `am`/`pm` (`AM`/`PM`) string in the UI.
- Added `input-width` property to help to adjust Timepicker's width with ease.

### Improvements

Added more guiding notes for SSR usage. (Thanks to @oj-recit)

## v 1.0.1

### Fixes

Fixes the _String_ form `v-model` support on Edge and Safari

## v 1.0.0

### Breaking Changes

**⚠️ IMPORTANT:** The default **import** source in `v1.0.0+` is different from the `v0.x` versions.

From `v1.0.0+`, CSS is excluded from the main source. Please import the CSS file separately.

```javascript
// v1.0.0+
//
import VueTimepicker from 'vue2-timepicker'
// -> Imports JS file in UMD form

// CSS
import 'vue2-timepicker/dist/VueTimepicker.css'
```

Comparing to:

```javascript
// While in the v0.x versions
import VueTimepicker from 'vue2-timepicker'
// -> Imports the *.vue Single File Component together with CSS
```

Please check the [Documentation](https://github.com/phoenixwong/vue2-timepicker/blob/master/README.md#get-started) for more available import formats.

### New

- Support using _String_ value in `v-model`.
- New `minute-range` and `second-range` support. Companioned with `hide-disabled-minutes` and `hide-disabled-seconds`.
- New `hide-disabled-items` property for hiding **all** excluded items (hour, minute and seconds) at a time.
- New `close-on-complete` for automatically close the dropdown when the user finishes selecting **all** of the required fields.
- Added `advanced-keyboard` support for Arrow Keys navigation and Space/Enter key selection.
- New `tabindex` property support, which will be assigned to the `<input type="text">` within the component.
- Added `debug-mode` to help developers investigating the input -> output process.

### Fixes

Added ES "module" and other version fields in _package.json_ to resolving more loader issues. (Thanks to @Trainmaster)

### Improvements

When `hour-range` is set in a 12-hour format Timepicker, recheck the selected hour's validity after user switching "AM/PM" from the dropdown.

## v 0.2.2

### Fixes

Fixes `v-model` watcher for cases like changing the input value programmatically (non-user behavior).

### Improvements

Added `displayTime` in the return data of `change` event.

## v 0.2.1

### New

- New `input-class` support. The custom input class will be assigned to the `<input type="text">` within the component. (Thanks to @marufmax)
- Add support to `placeholder`, just like other regular form elements

### Improvements

Refined `@click.stop` logic

### Fixes

Fixes possible loader issue in some Webpack configs (Thanks to @RaphaelJ)

## v 0.2.0

### Breaking Changes

- Upgraded to support more current **vue** (2.6.10) and **vue-cli** (3.9.0) with Webpack 4.

### New

- New `hour-range` support. Added capability to show which hours are available and disabled the rest.
- New `hide-disabled-hours`. The best companion of `hour-range`, for you to hide unwanted hours in the hour picker.
- New `disabled` parameter. To disable dropdown picker and clear button in the UI.
- Emit `open` and `close` events to help tracking the dropdown toggle status. (Thanks to @tprashan)

### Improvements

- Put `12` before `1` in the hour select for 12-hour format (`hh` and `h`). It will be more natural, especially when paired with `hour-range`.
- Support `name` parameter as regular form inputs. (Thanks to @dilipgurung)

## v 0.1.4

### Fixes

Added stop propagation `.stop` to click events

## v 0.1.3

### Improvements

Add support to `<label for="...">` (Thanks to @Reached)

```html
<!-- Sample -->
<label for="yourID">Your Label Text</label>
<vue-timepicker id="yourID"></vue-timepicker>
```

## v 0.1.2

Release the `dist` files

## v 0.1.1

The first notable release of Vue2 Timepicker


================================================
FILE: CONTRIBUTING.md
================================================
# Contribution

Please feel free to fork and help developing.

```bash
# Install dependencies
yarn install

# Init development dependencies
yarn dev:init

# Start developing. Serve with hot reload at localhost:8080
yarn dev
```

For detailed explanation on how things work, checkout the [Vue Cli Guide](https://cli.vuejs.org/guide/).

**BREAKING CHANGES**

- Start from `^0.2.0`, we develop Demo pages with [**Yarn**](
https://yarnpkg.com/), [**Pug**](https://pugjs.org/), and [**Stylus**](http://stylus-lang.com/)
- Upgraded to **@vue/cli v4** from `^1.1.1`.

**NOTE**

If you have trouble running `yarn dev` after the _^1.1.1_ upgrade, please try the following process:

1. Remove the existing `node_modules` folder and the `yarn.lock` in this repository's **root** directory.
2. Next, remove the `node_modules` folder and the `yarn.lock` in the **/demo** directory as well.
3. Go back to the repository's root, run `yarn install`, and `yarn dev:init` again.

---

### Watchdogs

![Libraries.io dependency status for GitHub repo](https://img.shields.io/librariesio/github/phoenixwong/vue2-timepicker?style=flat-square)
![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/phoenixwong/vue2-timepicker?style=flat-square)
![GitHub Release Date](https://img.shields.io/github/release-date/phoenixwong/vue2-timepicker?style=flat-square)
![npm](https://img.shields.io/npm/dw/vue2-timepicker?style=flat-square)


================================================
FILE: LICENSE.md
================================================
MIT License

Copyright (c) 2019 Phoenix Wong

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: MIGRATION.md
================================================
# Table of Contents

- [Migrating from Vue 1.x vue-timepicker](https://github.com/phoenixwong/vue2-timepicker/blob/master/MIGRATION.md#migrating-from-vue-1x-vue-timepicker)
- [Migrating from Bower to Yarn or NPM](https://github.com/phoenixwong/vue2-timepicker/blob/master/MIGRATION.md#migrating-from-bower-to-yarn-or-npm)

# Migrating from Vue 1.x vue-timepicker

There are bunch of [notable changes in Vue2](http://vuejs.org/guide/migration.html), and quite some of the key features our original `vue-timepicker` has been relying on, got deprecated since 2.0. So here we are, a brand new version compatible with Vue 2.x.

## Crucial changes

### Use `v-model` Instead of `:time-value.sync`

The `.sync` modifier on `v-bind` has been deprecated ([source](http://vuejs.org/guide/migration.html#once-and-sync-Modifiers-on-v-bind-removed)), hence the original `:time-value.sync` binding is not going to work anymore.

However, thanks to the awesome Vue2.0 feature, which now has great support for `v-model` on custom components, you can simply replace those sync properties with `v-model`.

```html
<!-- Vue 1.x -->
<vue-timepicker :time-value.sync="yourTimeValue"></vue-timepicker>

<!-- Vue 2.x version -->
<vue-timepicker v-model="yourTimeValue"></vue-timepicker>
```

### No More `vue-timepicker-update` Event

The `$dispatch` event `vue-timepicker-update` been depending on, together with the `events` option, got removed in Vue2 either ([source 1](http://vuejs.org/guide/migration.html#dispatch-and-broadcast-replaced), [source 2](http://vuejs.org/guide/migration.html#events-option-removed)). Please switch to `@change` event handler instead -- check the [Documentation](https://github.com/phoenixwong/vue2-timepicker#method-2-add-change-event-handler) for detail example.

## Minor Changes

### Replace `$arguments` with `$event` in the `change` event handler

If you're using `change` event handler **with** custom arguments, please replace the old `$arguments` parameter with `$event`

```html
<!-- Vue 1.x -->
<vue-timepicker :time-value.sync="yourTimeValue" @change="changeHandler($arguments, 'foo', 'bar')"></vue-timepicker>

<!-- Vue 2.x version -->
<vue-timepicker :time-value.sync="yourTimeValue" @change="changeHandler($event, 'foo', 'bar')"></vue-timepicker>
```

Whereas the `change` event handler *without* custom arguments is intact.

### Get Rid of the Array Wrapper `[]` in `change` Event Data

In the example above, when reading event data from the `changeHandler` in 1.x, the data structure will be --

```javascript
// Vue 1.x
[
  {
    data: {
      HH:...,
      mm:...,
      ...
    }
  }
]
```

In the 2.x version, we can say goodbye to the `[]` wrapper --

```javascript
// Vue 2.x version
{
  data: {
    HH:...,
    mm:...,
    ...
  }
}
```

### The `change` event now returns full values

In the Vue 1.x version, if you have `time-value` in sync, `change` event will only return values from your predefined tokens. Whereas the new 2.x version will always return a full value package containing all supported tokens.

For example, if you have a binding value defined in the form of "HH:mm:ss"

```javascript
// predefined data sample
data: function () {
  return {
    yourTimeValue: {
      HH: "10",
      mm: "05",
      ss: "00"
    },
    ...
  }
}
```

When the picker is set to "14:30:15" later --

```javascript
// Vue 1.x
// - only returns predefined tokens ('HH', 'mm' and 'ss')
{
  HH: "14",
  mm: "30",
  ss: "15"
}

// Vue 2.x version
// - returns All supported tokens
{
  HH: "14",
  H: "14",
  hh: "14",
  a: "am",
  A: "AM",
  h: "14",
  kk: "14",
  k: "14",
  m: "30",
  mm: "30",
  s: "15",
  ss: "15"
}
```

## Miscellaneous

There will be **no** standalone ES5 script in the 2.x version.

---

# Migrating from Bower to Yarn or NPM

Because [Bower](https://bower.io/) itself stopped maintaining since 2017, VueTimepicker drops support for Bower from version `0.2.0+`.

Please check Bower's official guidelines for [How to migrate away from Bower?](https://bower.io/blog/2017/how-to-migrate-away-from-bower/)


================================================
FILE: README.md
================================================
# Vue2 Timepicker  

![GitHub version](https://img.shields.io/github/package-json/v/phoenixwong/vue2-timepicker?color=success&style=flat-square)
![npm version](https://img.shields.io/npm/v/vue2-timepicker?style=flat-square)
![GitHub release](https://img.shields.io/github/release/phoenixwong/vue2-timepicker?label=github&style=flat-square)
![npm downloads](https://img.shields.io/npm/dm/vue2-timepicker?style=flat-square)

---

💡 Dead repo recharged 🔋

---

A dropdown time picker (hour|minute|second) for **Vue 2.x**, with flexible time format support.

## Demo

You can see the **Vue2 Timepicker** in action in the [Demo Page](https://phoenixwong.github.io/vue2-timepicker/)

## Migration

Please check [MIGRATION.md](https://github.com/phoenixwong/vue2-timepicker/blob/master/MIGRATION.md) for basic guidelines if you are about to:

- Migrate from the Vue 1.x version **[vue-time-picker](https://github.com/phoenixwong/vue-timepicker)**
- Migrate from Bower to Yarn or NPM (Vue2 Timepicker `v0.1.x` -> `v0.2.0+`)


## Dependencies

[Vue.js](http://vuejs.org/)&nbsp;&nbsp;&nbsp;![npm peer dependency version](https://img.shields.io/npm/dependency-version/vue2-timepicker/peer/vue?style=flat-square)

## Installation

```bash
yarn add vue2-timepicker
```

```bash
npm install vue2-timepicker --save
```

> NOTE: We stop Bower support from `0.2.0+`, please check [MIGRATION.md](https://github.com/phoenixwong/vue2-timepicker/blob/master/MIGRATION.md#migrating-from-bower-to-yarn-or-npm) for migration guidelines.

## Get Started

### **Step 1:** Import VueTimepicker

#### **Option A:** Import component JS and CSS

```javascript
// Main JS (in UMD format)
import VueTimepicker from 'vue2-timepicker'

// CSS
import 'vue2-timepicker/dist/VueTimepicker.css'
```

#### **Option B:** Choose any bundle version base on your needs

**Javascript**

```javascript
// CommonJS
import VueTimepicker from 'vue2-timepicker/dist/VueTimepicker.common.js'
// UMD
import VueTimepicker from 'vue2-timepicker/dist/VueTimepicker.umd.js'
// UMD Minified
import VueTimepicker from 'vue2-timepicker/dist/VueTimepicker.umd.min.js'
```

**CSS**

```css
@import 'vue2-timepicker/dist/VueTimepicker.css';

/* Or, with node_module alias path like: */
@import '~vue2-timepicker/dist/VueTimepicker.css';

/*
  NOTE: the path alias to `node_modules` differs between bundlers.
  Please change the `~` to any alias that works with your environment.
 */
```

**Single File Component**

```javascript
// The *.vue file with CSS included
import VueTimepicker from 'vue2-timepicker/src/vue-timepicker.vue'
// NOTE: In some cases, it requires additional workarounds in the bundler's config
```

#### **SSR Usage**

```javascript
// Import the *.vue file (CSS included)
import VueTimepicker from 'vue2-timepicker/sfc'
// Note the `/sfc` suffix here
```

If your server-side renderer cannot recognize the `/sfc` alias, please try --

```javascript
// Manually point to the `/src` folder
import VueTimepicker from 'vue2-timepicker/src'
// Or, to the specific file name
import VueTimepicker from 'vue2-timepicker/src/vue-timepicker.vue'
```

### **Step 2**: Include VueTimepicker in your component

```javascript
var yourComponent = new Vue({
  components: { VueTimepicker },
  ...
})
```

### **Step 3**: Put `vue-timepicker` in your component's template

Then, you can introduce the `vue-timepicker` tag anywhere you like in your component's template

```html
<vue-timepicker></vue-timepicker>
```


## Basic Usage

### Base

```html
<!-- Default to 24-Hour format HH:mm -->
<vue-timepicker></vue-timepicker>
```

### Customized Time Format

```html
<!-- Show seconds picker -->
<vue-timepicker format="HH:mm:ss"></vue-timepicker>

<!-- 12-hour format, with AM/PM picker -->
<vue-timepicker format="hh:mm A"></vue-timepicker>

<!-- 12-hour format, with seconds picker and am/pm picker -->
<vue-timepicker format="hh:mm:ss a"></vue-timepicker>
```

VueTimepicker recognizes the following tokens in the format string

Section    | Token | Output
---------- | ----- | ---------------
**AM/PM**  | A     | AM PM
&nbsp;     | a     | am pm
**Hour**   | H     | 0 1 ... 22 23
&nbsp;     | HH    | 00 01 ... 22 23
&nbsp;     | h     | 1 2 ... 11 12
&nbsp;     | hh    | 01 02 ... 11 12
&nbsp;     | k     | 1 2 ... 23 24
&nbsp;     | kk    | 01 02 ... 23 24
**Minute** | m     | 0 1 ... 58 59
&nbsp;     | mm    | 00 01 ... 58 59
**Second** | s     | 0 1 ... 58 59
&nbsp;     | ss    | 00 01 ... 58 59

> If not set, the `format` string is default to "HH:mm"

### Customized Picker Interval

```html
<!-- Show minute picker's value in the form of 0, 5, 10, ... 55, 60 -->
<vue-timepicker :minute-interval="5"></vue-timepicker>

<!-- Show second picker's value in the form of 0, 10, 20, ... 50, 60 -->
<vue-timepicker :second-interval="10"></vue-timepicker>

<!-- Bind interval config with your own data variable -->
<vue-timepicker :minute-interval="yourMinuteInterval"></vue-timepicker>
```


## Data Binding

### Bind Value with `v-model`

From `v1.0.0+`, timepicker's `v-model` accepts value in both _Object_ (default) and _String_ format. The `v0.x` versions only support _Object_ form.

#### Set Initial Value

For example, if you want to set "10:05:00" ("HH:mm:ss" format) as the initial value of vue-timepicker:

```javascript
const yourComponent = new Vue({
  components: { VueTimepicker },
  data () {
    return {
      // Object form
      yourTimeValue: {
        HH: '10',
        mm: '05',
        ss: '00'
      },
      // String form
      yourStringTimeValue: '10:05:00',
      ...
    }
  },
  ...
})
```

Both forms lead to the same result.

```html
<!-- Object form -->
<vue-timepicker v-model="yourTimeValue" format="HH:mm:ss"></vue-timepicker>

<!-- String form -->
<vue-timepicker v-model="yourStringTimeValue" format="HH:mm:ss"></vue-timepicker>
```

#### Set Empty Initial Value

When the initial value is completely unknown:

```javascript
data () {
  return {
    // Will be rendered as Object form
    yourEmptyValue: {},
    emptyValueToo: undefined,
    emptyValueAsWell: null,

    // Will be taken into String form
    yourEmptyStringValue: ''
  }
}
```

#### Set Partially-Known Initial Value

For instance, if you want to set the initial hour value to **8 pm** and leave the rest slots empty:

```javascript
data () {
  return {
    // OBJECT FORM
    // Default 24-Hour
    timeValue: {
      HH: '20',
      mm: ''
    },
    // 12-Hour with seconds
    timeValueWithSec: {
      h: '8',
      mm: '',
      ss: '',
      A: 'PM'
    },

    // STRING FORM
    // Default 24-Hour + String value
    stringTimeValue: '20:mm',
    // 12-Hour with seconds + String value
    stringTimeValueWithSec: '8:mm:ss PM'
  }
}
```

```html
<!-- OBJECT FORM -->
<!-- Default 24-Hour -->
<vue-timepicker v-model="timeValue"></vue-timepicker>
<!-- 12-Hour with seconds -->
<vue-timepicker v-model="timeValueWithSec" format="h:mm:ss A"></vue-timepicker>

<!-- STRING FORM -->
<!-- Default 24-Hour + String value -->
<vue-timepicker v-model="stringTimeValue"></vue-timepicker>
<!-- 12-Hour with seconds + String value -->
<vue-timepicker v-model="stringTimeValueWithSec" format="h:mm:ss A"></vue-timepicker>
```

### Get Time Picker's Current Value

#### Get value from `v-model`

You can either read the binding `v-model` value anytime or add a handler to deal with the `input` event from vue-timepicker.

```html
<vue-timepicker v-model="yourTimeValue" format="HH:mm:ss" @input="inputHandler"></vue-timepicker>
```

```javascript
{
  data () {
    return {
      yourTimeValue: {
        HH: '10',
        mm: '05',
        ss: '00'
      },
      ...
    }
  },

  methods: {
    inputHandler (eventData) {
      console.log(eventData)
    }
  }
}

```

In this case, we set the initial value (_yourTimeValue_) to "10:05:00". Then, open the dropdown picker and pick a new time, like setting it to "14:30:15" for example.

```javascript
// In `inputHandler`:
// console.log outputs -> {HH: "14", mm: "30", ss: "15"}
```

### Read Data From `change` Event

```html
<!-- A: No argument -->
<vue-timepicker v-model="yourTimeValue" @change="changeHandler"></vue-timepicker>

<!-- B: Custom arguments -->
<vue-timepicker v-model="yourTimeValue" @change="otherChangeHandler($event, 'foo', 42)"></vue-timepicker>
```

```javascript
// A: No argument
changeHandler (eventData) {
  console.log(eventData)
  // -> {data: {HH:..., mm:... }, displayTime: "HH:mm"}
}

// B: Custom arguments
otherChangeHandler (eventData, yourArg1, yourArg2) {
  console.log(eventData)
  // -> {data: {HH:..., mm:... }, displayTime: "HH:mm"}
  console.log(yourArg1)
  // -> 'foo'
  console.log(yourArg2)
  // -> 42
}
```

Unlike `v-model` and `input` event, which only return the defined time tokens you provided in the binding variable, the `change` event delivers **all** supported formats.

In the example above, after the user set values to "14:30:15" in the picker, `change` event returns the following data:

```javascript
// `@change` event data
{
  data: {
    HH: "14",
    H: "14",
    hh: "14",
    a: "am",
    A: "AM",
    h: "14",
    kk: "14",
    k: "14",
    m: "30",
    mm: "30",
    s: "15",
    ss: "15"
  },
  // extra `displayTime` added since v0.2.2
  displayTime: "14:30:15"
}
```

Whereas the `v-model` / `input` only return the data with defined tokens

```javascript
// Previously defined variable (`yourTimeValue` in this case) as {HH:..., mm:..., ss:...}
// Hence, the `v-model` returns:
{
  HH: "14",
  mm: "30",
  ss: "15"
}
```

## Advance Usage

### Hide Clear Button

```html
<vue-timepicker hide-clear-button></vue-timepicker>
```

Enable to hide the "&times;" clear button on the right-hand side. Users can still pick new values from the dropdown, but they cannot erase any selected data.

### Disable Picker

```html
<vue-timepicker disabled></vue-timepicker>
```

Fully disable both dropdown picker and the "&times;" clear button in the UI, to prevent users from changing any values again.

### Close on Complete

Automatically close the dropdown when the user finishes selecting **all** of the required fields.

```html
<vue-timepicker close-on-complete></vue-timepicker>
```

### Auto-Scroll

```html
<vue-timepicker auto-scroll></vue-timepicker>
```

Auto-scroll to selected values on dropdown open. It works with both:

- Programmatically defined value. E.g., the initial value from `v-model`
- Values manually picked by the user.

### Define Hour Range

Sometimes you may want to limit hours picker to a specific range. The `hour-range` parameter is here to help.

```html
<!-- 24-Hour Format -->
<vue-timepicker :hour-range="[5, [8, 12], [14, 17], 19]"></vue-timepicker>
<!-- >> Equals to :hour-range="[5, 8, 9, 10, 11, 12, 14, 15, 16, 17, 19]" -->

<!-- 12-Hour Format -->
<vue-timepicker :hour-range="['7a', '9a', '11a', '1p', ['3p', '5p'], '7p']" format="hh:mm a">
<!-- >> Equals to :hour-range="['7a', '9a', '11a', '1p', '3p', '4p', '5p', '7p']" -->
```

### Set Minute and Second Range

Similar to `hour-range`, you can determine values in the minutes and seconds dropdown by using `minute-range` and `second-range`.

```html
<!-- Minute range -->
<vue-timepicker :minute-range="[0, 6, [10, 30], 42, 50]"></vue-timepicker>
<!-- >> Active Items: 00, 06, 10, 11, 12, 13, ..., 27, 28, 29, 30, 42, 50 -->

<!-- Second range -->
<vue-timepicker format="H:m:s" :second-range="[0, 6, [10, 30], 42, 50]"></vue-timepicker>
<!-- >> Active Items: 0, 6, 10, 11, 12, 13, ..., 27, 28, 29, 30, 42, 50 -->
```

When implemented together with `minute-interval` and `second-interval`, the customized intervals take the priority.

```html
<!-- Minute range + 5-minute interval -->
<vue-timepicker :minute-range="[0, 6, [10, 30], 42, 50]" :minute-interval="5"></vue-timepicker>
<!-- >> Active Items: 00, 10, 15, 20, 25, 30, 50 -->

<!-- Second range + 10-second interval-->
<vue-timepicker format="H:m:s" :second-range="[0, 6, [10, 30], 42, 50]" :second-interval="10"></vue-timepicker>
<!-- >> Active Items: 0, 10, 20, 30, 50 -->
```

### Hide Disabled Items

There're four kinds of helper properties to let you hide the values excluded by `hour-range`, `minute-range`, and `second-range`.

- **hide-disabled-items**: Hide **all** disabled items - hour, minute, and seconds.
- **hide-disabled-hours**: Hide disabled **hour** values only.
- **hide-disabled-minutes**: Hide disabled **minute** values only.
- **hide-disabled-seconds**: Hide disabled **second** values only.

```html
<!-- `hide-disabled-hours` sample -->
<vue-timepicker :hour-range="[5, [8, 12], [14, 17], 19]" hide-disabled-hours></vue-timepicker>
```

Here we take the `hide-disabled-hours` as an example. It's a pair with the `hour-range` parameter. In this case, the hour picker hides the invalid hours (_0, 1, 2, 3, 4, 6, 7, 13, 18, 20, 21, 22, 23_) and display the valid hours (_5, 8, 9, ..._) only.

### Advanced Keyboard Support

Basic keyboard support includes:

- **Tab**: Focus or blur the Timepicker
- **Esc**: Close the dropdown

Advance Keyboard support (enabled with `advanced-keyboard`):

- **Arrow Keys**: Navigate between valid (non-disabled) values and columns
- **Space** or **Enter**: Select the focusing item

```html
<vue-timepicker advanced-keyboard></vue-timepicker>
```

Please be aware that after putting the `advanced-keyboard` on, hundreds of additional keyboard event listeners are going to be attached to the component. The amount of listeners depends on how many hours, minutes, and seconds value you enabled in the current Timepicker.

### Blur Delay

```html
<!-- Unit: million second -->
<vue-timepicker :blur-delay="500"></vue-timepicker>
```

Sets the blur delay time for the dropdown. Defaults to `300` if not set.

### Manual Input Support

```html
<vue-timepicker manual-input></vue-timepicker>
```
Let users add or change values through the `<input>` box besides the dropdown picker.

### Manual Input Timeout

```html
<!-- Unit: million second -->
<vue-timepicker :manual-input-timeout="1500"></vue-timepicker>
```

Works with **manual-input** mode. It sets the timeout for continuous input. Defaults to `1000` if not set.

**How It Works?**

For example, when a user focuses on the **hour** slot (`HH`) of a `"HH:mm"` formatted Timepicker (with the default value `1000`):

- **Case 1:** User first inputs `1`, and then inputs `2` _500ms_ later -> Timepicker takes `12` as the final value and set it to the `"HH"` slot.
- **Case 2:** User inputs `1`, and then presses the key `2` _1200ms_ later -> Timepicker takes `2` as the final value and set it to `02` for the `"HH"` slot.

### Hide Dropdown

> **NOTE:** To use this feature, you MUST ENABLE the `manual-input` mode _(v.1.1.0+)_ in the first place.

It makes the dropdown picker hidden by default.

```html
<vue-timepicker manual-input hide-dropdown></vue-timepicker>
```

Users can still choose to open the dropdown by clicking the triangle ("&dtrif;") button on the right. _(v.1.1.3+)_

### Fixed Dropdown Button

```html
<vue-timepicker fixed-dropdown-button></vue-timepicker>
```

Make the dropdown button always visible in the UI. _(v.1.1.4+)_

### Drop Direction

Change dropdown direction when needed _(v.1.1.5+)_. Accepting values:

- **down**: Default value.
- **up**: Force open the dropdown above the input.
- **auto**: Auto detects available height and opens the dropdown on top if there are not enough spaces below the input.

```html
<!-- Force drop up -->
<vue-timepicker drop-direction="up"></vue-timepicker>

<!-- Auto drop direction  -->
<vue-timepicker drop-direction="auto"></vue-timepicker>
```

#### Container ID

Works with `drop-direction="auto"`. It defines the parent container where the timepicker should calculate the free spaces from. If this value is not set, timepicker will watch `document.body` instead.

```html
<!-- Parent Container ID: "auto-dropdown-containter" -->
<div id="auto-dropdown-containter">
  <!-- Defined Container -->
  <vue-timepicker drop-direction="auto" container-id="auto-dropdown-containter"></vue-timepicker>

  <!-- Default (document body) -->
  <vue-timepicker drop-direction="auto"></vue-timepicker>
</div>
```

#### Drop Offset Height

Works with `drop-direction="auto"` either. Defaults to `160` (unit: _px_) if the value is not set.

```html
<!--
  When the available bottom space is less than 200px,
  open the dropdown above the input.
-->
<vue-timepicker drop-direction="auto" :drop-offset-height="200"></vue-timepicker>
```

### Lazy Event Mode

```html
<vue-timepicker lazy></vue-timepicker>
```

When `lazy` event mode is toggled on, only an actual user behavior can trigger the `input` and `change` events. Which are:

- The user opened the dropdown and picked a new value
- The user clicked the ("&times;") clear button
- The user inputted a new value or clear the existing value in the Manual Input mode

In other words, on `lazy` mode, Timepicker won't emit `input` and `change` events on mounted, nor after the value got modified programmatically.


### Append To Body

Append the dropdown menu to the end of the document `<body>`. Try this if you have `z-index` or `overflow` layout issue with the dropdown.

```html
<vue-timepicker append-to-body></vue-timepicker>
```

The body-appended dropdown's CSS class is `vue__time-picker-dropdown`. Its default `z-index` is `100`. You can change the value by adding the following style in your app -- 

```css
/* E.g. set the z-index to 5000 */
.vue__time-picker-dropdown {
  z-index: 5000;
}
```

**NOTE**: If you have to override some of the CSS styles within the dropdown, you will need to update their selectors' class names as well. Simply change any `.vue__time-picker .dropdown` selector to `.vue__time-picker-dropdown`.

For example, when you have a customized background color set for selected values:

```css
/* Default override (not using "append-to-body") */
.vue__time-picker .dropdown ul li:not([disabled]).active {
  background: steelblue;
}

/* When using "append-to-body" */
.vue__time-picker-dropdown ul li:not([disabled]).active {
  background: steelblue;
}
```

### Enable Debug Mode

```html
<vue-timepicker debug-mode></vue-timepicker>
```

It's aimed to help developers to investigate the input -> output process. When debug mode is toggled **on**, you can see extra `DEBUG: ...` logs coming through the console window as you interact with the vue-timepicker.

Let's create a "bug" here as an example --

```html
<!-- Manual Bug Sample: Define timepicker with format "h:mm:ss A" -->
<vue-timepicker v-model="yourStringValue" format="h:mm:ss A" debug-mode></vue-timepicker>
```

```javascript
{
  data () {
    return {
      // Manual Bug Sample:
      // Should be '3:mm:05 A' but oops.. the finger slipped
      yourStringValue: 'e:mm:05 A'
    }
  }
}
```

Then, in the console window, you should see a debug log saying:

```console
DEBUG: The input string in "v-model" does NOT match the "format" pattern
format: h:mm:ss A
v-model: e:mm:05 A
```

## Main Props API Overview

Prop                      | Type               | Required | Default Value
------------------------- | ------------------ | -------- | -------------
**v-model**               | _Object_, _String_ | no       | _undefined_
**format**                | _String_           | no       | "HH:mm"
**minute-interval**       | _Number_           | no       | _undefined_
**second-interval**       | _Number_           | no       | _undefined_
**hide-clear-button**     | _Boolean_          | no       | false
**disabled**              | _Boolean_          | no       | false
**close-on-complete**     | _Boolean_          | no       | false
**auto-scroll**           | _Boolean_          | no       | false
**hour-range**            | _Array_            | no       | _undefined_
**minute-range**          | _Array_            | no       | _undefined_
**second-range**          | _Array_            | no       | _undefined_
**hide-disabled-hours**   | _Boolean_          | no       | false
**hide-disabled-minutes** | _Boolean_          | no       | false
**hide-disabled-seconds** | _Boolean_          | no       | false
**hide-disabled-items**   | _Boolean_          | no       | false
**advanced-keyboard**     | _Boolean_          | no       | false
**blur-delay**            | _Number_           | no       | 300
**manual-input**          | _Boolean_          | no       | false
**manual-input-timeout**  | _Number_           | no       | 1000
**hide-dropdown**         | _Boolean_          | no       | false
**fixed-dropdown-button** | _Boolean_          | no       | false
**drop-direction**        | _String_           | no       | "down"
**container-id**          | _String_           | no       | _undefined_
**drop-offset-height**    | _Number_           | no       | 160
**lazy**                  | _Boolean_          | no       | false
**append-to-body**        | _Boolean_          | no       | false
**debug-mode**            | _Boolean_          | no       | false


## Input Props API

Prop              | Type                        | Required | Default Value
------------------| --------------------------- | -------- | -------------
**id**            | _String_                    | no       | _undefined_
**name**          | _String_                    | no       | _undefined_
**placeholder**   | _String_                    | no       | _undefined_
**tabindex**      | _Number_                    | no       | 0
**autocomplete**  | _String_                    | no       | 'off'
**input-class**   | _String_, _Array_, _Object_ | no       | _undefined_
**input-width**   | _String_                    | no       | '10em'

Timepicker supports `id`, `name`, `placeholder`, and `tabindex` like common form elements. These values are assigned to the `<input type="text" class="display-time">` within the component.

### Input `id`, `name` and `tabindex`

```html
<!-- id -->
<vue-timepicker id="myFirstPicker"></vue-timepicker>

<!-- name -->
<vue-timepicker name="nameInForm"></vue-timepicker>

<!-- tabindex -->
<vue-timepicker :tabindex="5"></vue-timepicker>
```

### Input `placeholder`

When `placeholder` is undefined, timepicker takes the determined format string instead.

```html
<!-- placeholder is set -->
<vue-timepicker placeholder="Start Time"></vue-timepicker>
<!-- -> "Start Time" -->

<!-- placeholder not set -->
<vue-timepicker format="hh:mm A"></vue-timepicker>
<!-- -> "hh:mm A" -->

<!-- both placeholder and format are not set -->
<vue-timepicker></vue-timepicker>
<!-- -> "HH:mm" -->
```

### Input `autocomplete` Attribute

> **NOTE:** To use this property, you MUST ENABLE the `manual-input` mode _(v.1.1.0+)_ in the first place.

```html
<!-- In Vue Template -->
<vue-timepicker name="starttime" autocomplete="on" manual-input></vue-timepicker>
```

```html
<!-- HTML result -->
<span class="vue__time-picker time-picker">
  <input class="display-time" name="starttime" type="text" autocomplete="on">
  <!-- ... -->
</span>
```

When enabled, it accepts any string value supported by the HTML input `autocomplete` attribute. The value is assigned to the embedding text `<input>`, which means it follows form autofill rules and configs set in the browser level. For example, most of the browsers require the input to have a `name` and/or `id` attribute. Some browsers, like Firefox, demand the input to be a descendant of a `<form>` element.

Please refer to the [HTML documentation](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill) and the developer guideline of each browser for more information (i.e., [MDN docs here](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete)).


### The `input-class`

The `input-class` is assigned to the text input within the component as well.

```html
<!-- Set your own `input-class` in the Vue template -->
<vue-timepicker input-class="my-awesome-picker"></vue-timepicker>
```

```html
<!-- HTML result -->
<span class="vue__time-picker time-picker">
  <input class="display-time my-awesome-picker" type="text" readonly="readonly">
  <!-- ... -->
</span>
```

Start from `v1.0.4`, besides _String_ format, `input-class` accepts value in _Array_ and _Object_ type as well.

```html
<!-- String type -->
<vue-timepicker input-class="your-awesome-timepicker i-am-vue2-timepicker"></vue-timepicker>

<!-- Array type -->
<vue-timepicker :input-class="['your-awesome-timepicker', 'i-am-vue2-timepicker']"></vue-timepicker>

<!-- Object type -->
<vue-timepicker :input-class="{
  'your-awesome-timepicker': true,
  'foo': false,
  'i-am-vue2-timepicker': true,
  'bar': false
}"></vue-timepicker>
```

```html
<!-- All of the three samples above return the same result in rendered HTML -->
<span class="vue__time-picker time-picker">
  <input class="display-time your-awesome-timepicker i-am-vue2-timepicker" type="text" readonly="readonly">
  <!-- ... -->
</span>
```

### The `input-width`

The `input-width` helps you to adjust both the `<input>` and the dropdown picker's width without overriding the CSS style on your own. It accepts any valid CSS width values like `8em`, `200px`, etc.

```html
<!-- In `px` -->
<vue-timepicker input-width="100px"></vue-timepicker>

<!-- In `em` -->
<vue-timepicker input-width="12em" format="HH:mm:ss"></vue-timepicker>
```


## Events API

Event          | Arguments      | Description
-------------- | -------------- | ----------------------
**input**      | (_value_)      | Emit after value changes
**change**     | (_eventData_)  | Emit after value changes
**open**       | &nbsp;         | Emit when the dropdown opens
**close**      | (_eventData_)  | Emit when the dropdown closes
**focus**      | &nbsp;         | Emit when the user start focusing on the `<input>`
**blur**       | (_eventData_)  | Emit when the user blurs the `<input>`
**error**      | (_eventData_)  | Emit when the input value becomes invalid

### The `open` and `close` Event of the Dropdown Picker

Help to identify the current status of the dropdown picker

```javascript
data () {
  return {
    dropdownStatus: 'closed'
  }
}
```

```html
<p>Dropdown Status: I'm {{dropdownStatus}}!</p>

<vue-timepicker @open="dropdownStatus = 'opened'" @close="dropdownStatus = 'closed'"></vue-timepicker>
```

### The `focus` and `blur` Event

It works with the Manual Input mode, aimed to identify the focus/blur state of the `<input>` box. Specially useful in cases where the dropdown is force hidden by `hide-dropdown`.

```javascript
data () {
  return {
    focusState: 'blurred'
  }
}
```

```html
<p>Focus State: {{focusState}}</p>

<vue-timepicker manual-input hide-dropdown @focus="focusState = 'focused'" @blur="focusState = 'blurred'"></vue-timepicker>
```

### The `error` event

Starts from `v.1.1.0+`, Timepicker will emit an `error` event when the current input value becomes invalid. E.g., when it contains an hour value that is not in the `hour-range` list or a minute value that doesn't fit in the `minute-interval`.

```html
<!-- Got the `hour-range` and `minute-interval` set -->
<!-- And add a hanlder to pick up the "error" event -->
<vue-timepicker format="H:mm:ss" v-model="erroredInputSample" :hour-range="[8, 9, 10, 11]" :minute-interval="5" @error="errorHanlder"></vue-timepicker>
```

```javascript
data () {
  return {
    erroredInputSample: { H: '5', mm: '03', ss: '00' }
    // NOTE:
    // H: '5' -> invalid. Value is not in the `hour-range` list
    // mm: '03' -> invalid. Value does not fit in the `minute-interval`
    // ss: '00' -> valid.
  }
},

methods: {
  errorHanlder (eventData) {
    console.log(eventData)
    // console.log outputs -> ["hour", "minute"]
  }
}
```

The `error` event returns an _Array_ of invalid fields' names. When it returns an empty array `[]`, it means the current input is valid, and all previous errors are gone

> NOTE: Empty value will **not** be marked as invalid.


## Helper CSS Class Names

Started from `v.1.1.0+`, Vue Timepicker will add additional CSS classes to the `<input>` element base on the state of the current input value.

- **invalid**: One or more fields containing an invalid or disabled value.
  - Additional CSS Style: The `<input>` border turns red.
  - If you want to mute this red border style, add `"skip-error-style"` to `input-class`
- **is-empty**: The input value (_v-model_) is empty. No additional style.
- **all-selected**: All fields (hour/minute/second/apm) required by the `format` string are not empty. No additional style.

```html
<!-- To mute the red border style of "invalid" state -->
<timepicker input-class="skip-error-style"></timepicker>
<timepicker :input-class="['skip-error-style', 'your-other-class-names']"></timepicker>
```


## Miscellaneous Props API

Prop                    | Type      | Required | Default Value
----------------------- | --------- | -------- | -------------
**hour-label**          | _String_  | no       | _undefined_
**minute-label**        | _String_  | no       | _undefined_
**second-label**        | _String_  | no       | _undefined_
**apm-label**           | _String_  | no       | _undefined_
**am-text**             | _String_  | no       | _undefined_
**pm-text**             | _String_  | no       | _undefined_

### Customized Picker Labels

You can define customized labels on top of the hour, minute, second, and APM pickers with the following properties: `hour-label`, `minute-label`, `second-label`, and `apm-label`. 

Furthermore, you can replace those _am/pm_ (or _AM/PM_) string by setting the `am-text` and `pm-text` parameters.

> Please note that these two parameters only change the labels expose to the users (the UI level). The `v-model` value and `displayTime` value returned by the `change` event (the data level) still use the standard _am_/_pm_ (_AM_/_PM_) format.

```html
<!-- 24-hour format with customized hour and minute label -->
<vue-timepicker hour-label="heure" minute-label="minute"></vue-timepicker>

<!-- 12-hour format with customized am/pm text -->
<vue-timepicker hour-label="時" minute-label="分" second-label="秒" apm-label="午" am-text="上午" pm-text="下午" format="h:mm:ss a"></vue-timepicker>
```


## Slots

We introduce three slots in `v.1.1.4` to help you customize the clear button, the dropdown button, and the input icon with your own icon/image.

Slot Name          | Position | Description   
------------------ | -------- | --------------
**icon**           | _left_   | On the lefthand side of the `<input>`
**clearButton**    | _right_  | In the same spot of the default clear button
**dropdownButton** | _right_  | In the same spot of the default dropdown button

> Please note that Vue v2.6.0+ introduces a significant update of the Named Slots syntax. Check the [official documentation](https://vuejs.org/v2/guide/components-slots.html#Named-Slots) for more information.

```html
<!-- For Vue 2.6.0+ -->

<!-- Input icon (image) -->
<vue-timepicker>
  <template v-slot:icon>
    <img src="$YOUR_ICON_SRC" />
  </template>
</vue-timepicker>

<!-- Customized clear button (image) -->
<vue-timepicker>
  <template v-slot:clearButton>
    <img src="$YOUR_CUSTOM_IMAGE_SRC" />
  </template>
</vue-timepicker>

<!-- Customized dropdown button (character entity) -->
<vue-timepicker manual-input hide-dropdown>
  <template v-slot:dropdownButton>&#x02263;</template>
</vue-timepicker>
```

## Contribution

Please feel free to fork and help developing. Check [CONTRIBUTING.md](https://github.com/phoenixwong/vue2-timepicker/blob/master/CONTRIBUTING.md) for more details.

## Change Log

Detail changes of each release: [CHANGELOG.md](https://github.com/phoenixwong/vue2-timepicker/blob/master/CHANGELOG.md)

## License

[MIT](https://github.com/phoenixwong/vue2-timepicker/blob/master/LICENSE.md)


================================================
FILE: babel.config.js
================================================
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ]
}


================================================
FILE: demo/.gitignore
================================================
.DS_Store
node_modules
/dist
yarn.lock*
package.lock*

# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?


================================================
FILE: demo/README.md
================================================
# Vue2 Timepicker Demo

## Project setup
```
yarn install
```

### Compiles and hot-reloads for development
```
yarn run serve
```

### Compiles and minifies for production
```
yarn run build
```

### Lints and fixes files
```
yarn run lint
```

### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).


================================================
FILE: demo/babel.config.js
================================================
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ]
}


================================================
FILE: demo/package.json
================================================
{
  "name": "vue2-timepicker-demo",
  "version": "1.1.6",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "core-js": "^3.6.5",
    "highlight.js": "^9.18.5",
    "vue": "^2.6.11",
    "vue-highlight.js": "^3.1.0"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^4.3.1",
    "@vue/cli-plugin-eslint": "^4.3.1",
    "@vue/cli-service": "^4.3.1",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.8.0",
    "eslint-plugin-vue": "^6.2.2",
    "stylus": "^0.54.7",
    "stylus-loader": "^3.0.2",
    "vue-cli-plugin-pug": "^1.0.7",
    "vue-template-compiler": "^2.6.11"
  },
  "eslintConfig": {
    "root": false,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "rules": {},
    "parserOptions": {
      "parser": "babel-eslint"
    }
  },
  "postcss": {
    "plugins": {
      "autoprefixer": {}
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ]
}


================================================
FILE: demo/public/index.html
================================================
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimal-ui, maximum-scale=1.0, minimum-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title>Vue2 Timepicker Demo</title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but vue2-timepicker-3 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    <a href="https://github.com/phoenixwong/vue2-timepicker" target="_blank"><img style="position: absolute; top: 0; left: 0; border: 0;" src="https://camo.githubusercontent.com/567c3a48d796e2fc06ea80409cc9dd82bf714434/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f6c6566745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_left_darkblue_121621.png"></a>
  </body>
</html>


================================================
FILE: demo/src/App.vue
================================================
<script>
import Samples from './components/Samples'
import Playground from './components/Playground'

export default {
  name: 'VueTimepickerDemo',

  components: {
    Samples,
    Playground
  },

  data () {
    return {
      currentView: 'samples',
      stickyNav: false,

      scrollTop: 0
    }
  },

  methods: {
    switchView (target) {
      try {
        history.replaceState(null, null, ' ')
      } catch (e) {
        // Failsafe for outdated browsers. Do nothing here.
      }
      this.currentView = target
      this.$nextTick(() => {
        if (document.documentElement && document.documentElement.scrollTop) {
          document.documentElement.scrollTop = 0
        } else if (document.body.parentNode && document.body.parentNode.scrollTop) {
          document.body.parentNode.scrollTop = 0
        } else {
          document.body.scrollTop = 0
        }
      })
    },

    scrollHandler (evt) {
      this.scrollTop = (evt.target.scrollingElement || (document.documentElement || document.body.parentNode)).scrollTop || 0
      if (this.scrollTop > 150) {
        if (!this.stickyNav) {
          this.stickyNav = true
        }
      } else {
        if (this.stickyNav) {
          this.stickyNav = false
        }
      }
    }
  },

  mounted () {
    window.addEventListener('scroll', this.scrollHandler)
  },

  beforeDestroy () {
    window.removeEventListener('scroll', this.scrollHandler)
  }
}
</script>

<template lang="pug">
#app.main-wrapper

  header(v-cloak)
    h1
      | Vue
      span.version 2
      | Timepicker

  nav.top-nav(:class="{stick: stickyNav}")
    span.title
      | Vue
      i 2
      | &nbsp;Timepicker

    ul
      li
        a(:class="{active: currentView === 'samples'}" @click="switchView('samples')") Common Usage
      li
        a(:class="{active: currentView === 'playground'}" @click="switchView('playground')") Playground
      li
        a(href="https://github.com/phoenixwong/vue2-timepicker/blob/master/README.md" target="_blank") Documentation

    span.version
      a(href="https://www.npmjs.com/package/vue2-timepicker" target="_blank")
        img(alt="NPM latest version" src="https://img.shields.io/npm/v/vue2-timepicker?style=flat-square")
    span.downloads
      a(href="https://www.npmjs.com/package/vue2-timepicker" target="_blank")
        img(alt="NPM downloads" src="https://img.shields.io/npm/dm/vue2-timepicker?style=flat-square")

  main.content(:class="{'nav-affixed': stickyNav}")
    transition(name="fade" mode="out-in")
      component(:is="currentView")

        //- Footer
        template(slot="footer-links")
          h3.title
            a#more.anchor #
            | More complex usage
          .description
            p
              | Didn't find what you need? Please check the&nbsp;
              a(@click="switchView('playground')") Playground
              | &nbsp;or&nbsp;
              a(href="https://github.com/phoenixwong/vue2-timepicker/blob/master/README.md" target="_blank" title="Vue2-Timepicker Documentation") Documentation
              | &nbsp;for more inspiration.
</template>

<style lang="stylus">
@import './assets/demo.styl';
</style>


================================================
FILE: demo/src/assets/_variables.styl
================================================
$vue-green = #41B883
$vue-green-light = lighten($vue-green, 5%)
$vue-dark = #35495E
$vue-darker = darken($vue-dark, 25%)
$body-color = #555
$dark-grey = #777

-black($alpha)
  rgba(0, 0, 0, $alpha)

-white($alpha)
  rgba(255, 255, 255, $alpha)


================================================
FILE: demo/src/assets/demo.styl
================================================
@import './_variables.styl'

body,
html
  margin: 0
  padding: 0
  font-family: sans-serif
  color: $body-color
  -webkit-font-smoothing: antialiased
  -moz-osx-font-smoothing: grayscale

body
  font-size: 16px

h2,
h3,
h4
  color: $vue-dark

h2
  margin: 2em 0 1.5em 0

h3
  margin: 0 0 1em 0

h4
  margin-bottom: 0.5em

section
  width: 80%
  max-width: 1000px
  margin: 0 auto 2em auto

a
  color: $vue-green
  text-decoration: none

header
  background: $vue-darker
  color: #fff
  text-align: center
  height: 150px
  display: flex
  flex-flow: column nowrap
  justify-content: center
  align-items: center
  position: relative

  h1
    margin: 0
    color: $vue-green-light
    .version
      font-weight: 300
      margin: 0 .2em 0 .1em

  p
    margin-bottom: 0
    color: -white(0.3)
    font-size: 300

    .version
      font-weight: 100
      background-color: alpha($vue-dark, 0.7)
      padding: .1em .5em
      border-radius: 3px

button
  display: inline-block
  outline: 0
  background: $vue-green
  border: 1px solid $vue-green
  color: #fff
  border-radius: 4px
  font-size: 0.9em
  vertical-align: baseline
  padding: 0.3em 0.5em
  transition: opacity 0.3s
  cursor: pointer
  &:hover
    opacity: 0.7

button.common
  background: #fff
  border: 1px solid $vue-green
  color: $vue-green

button.secondary
  background: #fff
  border: 1px solid $vue-darker
  color: $vue-darker

button.size-small
  font-size 0.8em;
  padding: 0.2em 0.4em;

nav.top-nav
  background: $vue-darker
  position: relative

  .title
    display: none

  span.version,
  span.downloads
    a
      border: 0
      text-decoration: none

  span.version
    position: absolute
    z-index: 301
    right: 1em
    bottom: .5em

  span.downloads
    position: absolute
    z-index: 301
    left: .8em
    bottom: .5em

  &.stick
    position: fixed
    top: 0
    left: 0
    right: 0
    z-index: 300

    .title
      display: inline-block
      color: -white(0.7)
      position: absolute
      z-index: 301
      left: 1em
      top: .8em

    span.downloads
      display: none

  ul
    list-style: none
    padding: 0
    margin: 0
    display: flex
    flex-flow: row nowrap
    justify-content: center
    align-items: stretch

    li
      margin: 0 1em
      overflow: hidden
      a
        color: -white(0.5)
        display: block
        padding: .8em .5em
        border-radius: 5px

        -webkit-transition: color .3s
        transition: color .3s

        position: relative
        overflow: hidden
        z-index: 1

        &:hover
          color: alpha($vue-green, 0.7)
          cursor: pointer

        &.active
          color: $vue-green-light

          &:after
            content: ''
            display: block
            width: 0
            height: 0
            border: 10px solid transparent
            border-bottom-color: #fff
            position: absolute
            bottom: -3px
            left: calc(50% - 10px)
            z-index: 3

main.content
  &.nav-affixed
    padding-top: 44px

.fade
  transition: opacity .5s ease

.fade-enter-active, .fade-leave-active
  opacity: 0

.description
  p
    line-height: 1.5em
  code
    color: $vue-dark
    background: -black(0.03)
    border-radius: 3px
    padding: 0.2em 0.5em
    margin: 0 0.2em
    vertical-align: baseline

.preview
  padding: 2em 1.5em
  border: 1px solid -black(0.07)
  border-radius: 3px
  b
    font-size: 0.9em
    color: $dark-grey
  p
    margin: 0
    padding: .5em 0 1.5em 0
    &:last-of-type
      padding-bottom: 0

.codes
  pre
    position: relative
    font-size: 0.8em
    code
      padding: 2em
      border-radius: 3px

    &:after
      content: attr(data-title)
      position: absolute
      top: 0.3em
      right: 0.8em
      font-size: 0.8em
      color: alpha($vue-dark, 0.6)

.capitailized
  text-transform: uppercase


================================================
FILE: demo/src/components/ConfigRow.vue
================================================
<script>
export default {
  name: 'ConfigRow',
  props: {
    label: { type: String },
    isGroup: { type: Boolean, default: false }
  }
}
</script>

<template lang="pug">
.config-row(:class="{'group': isGroup }")
  label.row-label(v-if="this.label && this.label.length") {{ label }}
  slot
</template>

<style lang="stylus">
.config-row
  padding: 0.5em 0
  display: flex
  flex-flow: row wrap
  justify-content: flex-start
  align-items: center
  align-content: flex-start

  .row-label
    display: inline-block
    font-weight: bold
    width: 5em
    text-align: right
    margin-right: 0.5em

  label.options
    min-width: 3em
    margin-right: 0.5em
    display: inline-flex
    flex-flow: row wrap
    justify-content: flex-start
    align-items: center
    position: relative
    input[type=radio],
    input[type=checkbox]
      position: relative
      top: -0.1em

  .range-wrapper
    display: inline-flex
    flex-flow: row nowrap
    justify-content: flex-start
    align-items: center
    input[type=range]
      margin-right: 0.8em

  &.group
    padding-left: 1em
    display: flex
    flex-flow: row wrap
    justify-content: flex-start
    align-items: center
</style>


================================================
FILE: demo/src/components/OverlayPanel.vue
================================================
<script>
export default {
  name: 'OverlayPanel',
  props: {
    title: { type: String }
  },
  methods: {
    closePanel () {
      this.$emit('close')
    }
  }
}
</script>

<template lang="pug">
.overlay-panel(@click="closePanel")
  .panel-body(@click.stop="")
    .panel-title
      .title-text(v-if="title" v-text="title")
      .close-btn(@click="closePanel") &times;
    .panel-content
      slot
    .panel-footer
      .footer-left
        slot(name="footerLeft")
      .footer-right
        slot(name="footerRight")
</template>

<style lang="stylus">
@import '../assets/_variables.styl'

.overlay-panel
  position: fixed
  top: 0
  left: 0
  bottom: 0
  right: 0
  background: -black(0.7)
  z-index: 5000

  display: flex
  flex-flow: column nowrap
  justify-content: center
  align-items: center

  .panel-body
    width: 500px
    max-width: 80vw
    max-height: 70vh
    min-height: 200px
    background: #fff
    border-radius: 6px
    box-shadow: 0 .1em 0.5em -black(0.35)

    display: flex
    flex-flow: column nowrap
    justify-content: flex-start
    align-items: stretch

    .panel-title
      display: flex
      flex-flow: row nowrap
      justify-content: flex-end
      align-items: center
      padding: 0.6em 0.8em 0.5em 0.8em
      border-bottom: 1px solid -black(0.1)

      .title-text
        flex: 1 1 0.00001px
        color: $vue-dark
        line-height: 120%
        font-weight: bold
        font-size: 1.2em
      
      .close-btn
        margin-left: 1em
        font-size: 1.2em
        line-height: 100%
        position: relative
        top: -.2em
        cursor: pointer
        transition: opacity .3s
        &:hover
          opacity: 0.4

    .panel-content
      flex: 1 1 0.00001px
      padding: 1em 0.8em
    
    .panel-footer
      border-top: 1px solid -black(0.1)
      padding: 0.5em 0.6em 0.5em 0.8em
      display: flex
      flex-flow: row nowrap
      justify-content: flex-start
      align-items: center

      .footer-left
        flex: 1 1 0.00001px
        button:not(:first-of-type)
          margin-left: 0.6em
</style>


================================================
FILE: demo/src/components/Playground.vue
================================================
<script>
import VueTimepicker from '../../../src/vue-timepicker'
import ConfigRow from './ConfigRow'
import OverlayPanel from './OverlayPanel'

export default {
  name: 'Playground',
  components: {
    VueTimepicker,
    ConfigRow,
    OverlayPanel
  },

  data () {
    return {
      tokens: {
        hour: ['HH', 'H', 'hh', 'h', 'kk', 'k'],
        minute: ['mm', 'm'],
        second: ['ss', 's', 'none'],
        apm: ['A', 'a']
      },

      type: {
        hour: 'hh',
        minute: 'mm',
        second: 'ss',
        apm: 'A'
      },

      selected: {
        hour: 1,
        minute: 0,
        second: 0,
        apm: 'am'
      },

      hourBoundary: {
        min: 1,
        max: 12
      },

      interval: {
        minute: 1,
        second: 1
      },

      customInterval: {
        minute: false,
        second: false
      },

      customRange: {
        hour: false,
        minute: false,
        second: false
      },
      showRangePanel: false,
      rangeList: undefined,
      editingRange: '',
      selectedRanges: [],
      rangeTitle: '',

      hourRange: [],
      minuteRange: [],
      secondRange: [],

      hideClearBtn: false,
      disablePicker: false,
      closeOnComplete: false,
      advancedKeyboard: false,
      manualInput: false,
      hideDropdown: false,
      fixedDropdownBtn: false,
      lazyMode: false,
      autoScroll: false,
      skipErrorStyle: false,
      appendToBody: false,
      debugMode: false,

      customBlurDelay: false,
      blurDelay: 300,

      customManualInputTimeout: false,
      manualInputTimeout: 1000,

      playgroundData: {},
      playgroundFullValue: {},
      playgroundErroredData: undefined,

      scrollTop: 0,

      muteChange: false
    }
  },

  computed: {
    formatString () {
      let formatString = `${this.type.hour}:${this.type.minute}`
      if (this.showSeconds) {
        formatString += (`:${this.type.second}`)
      }
      if (this.type.apm) {
        formatString += (` ${this.type.apm}`)
      }
      return formatString
    },

    needApm () {
      return this.type.hour === 'h' || this.type.hour === 'hh'
    },

    showSeconds () {
      return this.type.second !== 'none'
    },

    yourTimeValue () {
      let code = 'yourTimeValue: {\n'
      code += this.listTimeValue()
      code += '\n}'
      return code
    },

    asideStyle () {
      const initPaddingTop = 220
      const minPaddingTop = 50
      return {
        paddingTop: (Math.max(initPaddingTop - this.scrollTop, minPaddingTop)) + 'px'
      }
    },

    filteredOutValues () {
      if (!this.showRangePanel || !this.rangeList || !this.selectedRanges.length) { return }
      const result = []
      this.selectedRanges.forEach(selected => {
        if (selected && !this.rangeList.includes(selected)) {
          result.push(selected)
        }
      })
      return result
    },

    toHideDropdown () {
      if (!this.manualInput) { return false }
      return this.hideDropdown
    },

    showErroredData () {
      return Boolean(this.playgroundErroredData && this.playgroundErroredData.length)
    },

    htmlCodeWithVar () {
      let start = '<vue-timepicker'
      let end = '\n  v-model="yourTimeValue">\n</vue-timepicker>'

      start += (`\n  format="${this.formatString}"`)

      if (this.skipErrorStyle) {
        start += ('\n  input-class="skip-error-style"')
      }

      if (this.customInterval.minute) {
        start += (`\n  :minute-interval="${this.interval.minute}"`)
      }

      if (this.showSeconds && this.customInterval.second) {
        start += (`\n  :second-interval="${this.interval.second}"`)
      }

      if (this.customRange.hour && this.hourRange) {
        const hrRange = this.sortAndStringify(this.hourRange, this.needApm)
        start += (`\n  :hour-range="${hrRange}"`)
      }

      if (this.customRange.minute && this.minuteRange) {
        const minRange = this.sortAndStringify(this.minuteRange)
        start += (`\n  :minute-range="${minRange}"`)
      }

      if (this.showSeconds && this.customRange.second && this.secondRange) {
        const secRange = this.sortAndStringify(this.secondRange)
        start += (`\n  :second-range="${secRange}"`)
      }

      if (this.customBlurDelay) {
        start += (`\n  :blur-delay="${this.blurDelay}"`)
      }

      if (this.customManualInputTimeout) {
        start += (`\n  :manual-input-timeout="${this.manualInputTimeout}"`)
      }

      if (this.lazyMode) {
        start += ('\n  lazy')
      }

      if (this.closeOnComplete) {
        start += ('\n  close-on-complete')
      }

      if (this.manualInput) {
        start += ('\n  manual-input')
      }

      if (this.toHideDropdown) {
        start += ('\n  hide-dropdown')
      }

      if (this.advancedKeyboard) {
        start += ('\n  advanced-keyboard')
      }

      if (this.fixedDropdownBtn) {
        start += ('\n  fixed-dropdown-button')
      }

      if (this.hideClearBtn) {
        start += ('\n  hide-clear-button')
      }

      if (this.autoScroll) {
        start += ('\n  auto-scroll')
      }

      if (this.appendToBody) {
        start += ('\n  append-to-body')
      }

      if (this.disablePicker) {
        start += ('\n  disabled')
      }

      if (this.debugMode) {
        start += ('\n  debug-mode')
      }

      const htmlCode = start + end

      return htmlCode
    }
  },

  watch: {
    selected: {
      deep: true,
      handler () {
        this.updatePlaygroundData()
      }
    },

    type: {
      deep: true,
      handler () {
        this.updatePlaygroundData()
      }
    },

    'type.hour' (newType, oldType) {
      if (this.customRange.hour && this.hourRange.length) {
        const newRangeList = this.hourRange.map(item => {
          return this.transformHourRange(item, oldType, newType)
        })
        this.hourRange = newRangeList
      }
    },

    'type.minute' (newType) {
      if (this.customRange.minute && this.minuteRange.length) {
        const newRangeList = this.minuteRange.map(item => {
          return this.formatValue(newType, +item)
        })
        this.minuteRange = newRangeList
      }
    },

    'type.second' (newType) {
      if (newType !== 'none' && this.customRange.second && this.secondRange.length) {
        const newRangeList = this.secondRange.map(item => {
          return this.formatValue(newType, +item)
        })
        this.secondRange = newRangeList
      }
    },

    needApm (isNeeded) {
      if (isNeeded) {
        if (!this.selected.apm) {
          this.$set(this.type, 'apm', 'A')
          this.$set(this.selected, 'apm', 'am')
        }
      } else {
        this.$set(this.type, 'apm', '')
        this.$set(this.selected, 'apm', '')
      }
    },

    customInterval: {
      deep: true,
      handler (custom) {
        if (!custom.minute) {
          this.$set(this.interval, 'minute', 1)
        }
        if (!custom.second) {
          this.$set(this.interval, 'second', 1)
        }
      }
    }
  },

  methods: {
    updateHourRange (hourType) {
      hourType = hourType || this.type.hour
      let hourBoundary = {}
      switch (hourType) {
        case 'h':
        case 'hh':
          hourBoundary.min = 1
          hourBoundary.max = 12
          break
        case 'H':
        case 'HH':
          hourBoundary.min = 0
          hourBoundary.max = 23
          break
        case 'k':
        case 'kk':
          hourBoundary.min = 1
          hourBoundary.max = 24
          break
      }
      this.hourBoundary = hourBoundary
      this.handleOutRangeData()
    },

    handleOutRangeData () {
      if (this.selected.hour > this.hourBoundary.max) {
        this.$set(this.selected, 'hour', this.hourBoundary.max)
      } else if (this.selected.hour < this.hourBoundary.min) {
        this.$set(this.selected, 'hour', this.hourBoundary.min)
      }
    },

    isNumber (value) {
      return !isNaN(parseFloat(value)) && isFinite(value)
    },

    formatValue (type, value) {
      switch (type) {
        case 'H':
        case 'h':
        case 'k':
        case 'm':
        case 's':
          if (type === 'h' && value === 0) {
            return '12'
          }
          return String(value)
        case 'HH':
        case 'hh':
        case 'kk':
        case 'mm':
        case 'ss':
          if (type === 'hh' && value === 0) {
            return '12'
          }
          return value < 10 ? `0${value}` : String(value)
        default:
          return ''
      }
    },

    translate12hRange (value) {
      const valueT = value.match(/^(\d{1,2})(a|p|A|P)$/)
      if (+valueT[1] === 12) {
        return +valueT[1] + (valueT[2].toLowerCase() === 'p' ? 0 : 12)
      }
      return +valueT[1] + (valueT[2].toLowerCase() === 'p' ? 12 : 0)
    },

    interpretKtoRangeType (kValue, toType) {
      if (!toType || toType === 'k') { return String(kValue) }
      let value
      switch (toType) {
        case 'H':
        case 'HH':
          value = (kValue === 24) ? 0 : kValue
          if (toType === 'HH') {
            return value < 10 ? `0${value}` : String(value)
          }
          return String(value)
        case 'h':
        case 'hh':
          if (kValue === 24) {
            return `12a`
          } else if (kValue === 12) {
            return `12p`
          }
          value = kValue % 12
          if (toType === 'hh') {
            const valueStr = value < 10 ? `0${value}` : String(value)
            return kValue < 12 ? `${valueStr}a` : `${valueStr}p`
          }
          return kValue < 12 ? `${value}a` : `${value}p`
        case 'kk':
          return kValue < 10 ? `0${kValue}` : String(kValue)
      }
    },

    transformHourRange (value, fromType, toType) {
      if (!fromType || !toType) { return value }
      let valueInK
      if (fromType === 'hh' || fromType === 'h') {
        valueInK = this.translate12hRange(value)
      } else if (fromType === 'HH' || fromType === 'H') {
        valueInK = +value === 0 ? 24 : +value
      } else {
        valueInK = +value
      }
      return this.interpretKtoRangeType(valueInK, toType)
    },

    updatePlaygroundData () {
      let data = {}

      if (this.isNumber(this.selected.hour)) {
        data[this.type.hour] = this.formatValue(this.type.hour, this.selected.hour)
      } else {
        data[this.type.hour] = ''
      }

      if (this.isNumber(this.selected.minute)) {
        data[this.type.minute] = this.formatValue(this.type.minute, this.selected.minute)
      } else {
        data[this.type.minute] = ''
      }

      if (this.showSeconds) {
        if (this.isNumber(this.selected.second)) {
          data[this.type.second] = this.formatValue(this.type.second, this.selected.second)
        } else {
          data[this.type.second] = ''
        }
      }

      if (this.type.apm) {
        if (this.selected.apm) {
          data[this.type.apm] = this.type.apm === 'A' ? (this.selected.apm).toUpperCase() : this.selected.apm
        } else {
          data[this.type.apm] = ''
        }
      }

      this.playgroundData = data
    },

    listTimeValue () {
      const data = this.playgroundData
      const len = Object.keys(data).length
      let string = ''
      Object.keys(data).forEach((k, i) => {
        string += `  ${k}: "${data[k]}"`
        if (i < len - 1) {
          string += '\n'
        }
      })
      return string
    },

    updateRangeValue (data) {
      this.muteChange = true
      this.$set(this.selected, 'hour', this.isNumber(data[this.type.hour]) ? Number(data[this.type.hour]) : '')
      this.$set(this.selected, 'minute', this.isNumber(data[this.type.minute]) ? Number(data[this.type.minute]) : '')
      this.$set(this.selected, 'second', this.isNumber(data[this.type.second]) ? Number(data[this.type.second]) : '')
      this.$set(this.selected, 'apm', data[this.type.apm] ? (data[this.type.apm] || '').toLowerCase() : '')
      this.muteChange = false
    },

    changeHandler (eventData) {
      this.playgroundFullValue = eventData
      this.updateRangeValue(eventData.data)
    },

    errorHandler (eventData) {
      this.playgroundErroredData = eventData
    },

    scrollHandler (evt) {
      this.scrollTop = (evt.target.scrollingElement || (document.documentElement || document.body.parentNode)).scrollTop || 0
    },

    sortAndStringify (arrayList, is12Hour) {
      if (!arrayList || !arrayList.length) { return JSON.stringify([]) }
      let newList = [].concat([], arrayList)
      if (is12Hour) {
        newList.sort((l, r) => {
          const lPart = l.match(/^(\d{1,2})(a|p)$/)
          const rPart = r.match(/^(\d{1,2})(a|p)$/)
          const lApm = lPart[2]
          const rApm = rPart[2]
          if (lApm === 'a' && rApm === 'p') { return -1 }
          if (lApm === 'p' && rApm === 'a') { return 1 }
          const lNum = +lPart[1]
          const rNum = +rPart[1]
          if (lNum === 12) { return -1 }
          if (rNum === 12) { return 1 }
          return lNum < rNum ? -1 : 1
        })
        const uniStrList = newList.map(item => {
          const itemP = item.match(/^(\d{1,2})(a|p)$/)
          return `${+itemP[1]}${itemP[2]}`
        })
        return JSON.stringify(uniStrList).replace(/"/g, '\'')
      } else {
        newList.sort((l, r) => (+l < +r) ? -1 : 1)
        const numericList = newList.map(item => +item)
        return JSON.stringify(numericList).replace(/"/g, '')
      }
    },

    genHourRangeList () {
      const result = []
      for (let i = 0; i < 24; i++) {
        // 12-Hour format
        if (this.type.hour === 'h' || this.type.hour === 'hh') {
          let value = this.formatValue(this.type.hour, i % 12)
          value = `${value}${i < 12 ? 'a' : 'p'}`
          result.push(value)
        } else {
          if (this.type.hour === 'k' || this.type.hour === 'kk') {
            result.push(this.formatValue(this.type.hour, i + 1))
          } else {
            result.push(this.formatValue(this.type.hour, i))
          }
        }
      }
      return result
    },

    genMinuteRangeList () {
      const result = []
      const step = +this.interval.minute
      for (let i = 0; i <= 59; i += step) {
        result.push(this.formatValue(this.type.minute, i))
      }
      return result
    },

    genSecondRangeList () {
      const result = []
      const step = +this.interval.second
      for (let i = 0; i <= 59; i += step) {
        result.push(this.formatValue(this.type.second, i))
      }
      return result
    },

    openRangePanel (section) {
      if (!section) { return }

      this.rangeTitle = `Choose ${section}-range Values`
      this.editingRange = section

      if (section === 'minute') {
        this.rangeList = this.genMinuteRangeList()
        this.selectedRanges = [].concat([], this.minuteRange)
      } else if (section === 'second') {
        this.rangeList = this.genSecondRangeList()
        this.selectedRanges = [].concat([], this.secondRange)
      } else if (section === 'hour') {
        this.rangeList = this.genHourRangeList()
        this.selectedRanges = [].concat([], this.hourRange)
      }

      this.showRangePanel = true
    },

    confirmRange () {
      if (this.editingRange === 'minute') {
        this.minuteRange = [].concat([], this.selectedRanges || [])
      } else if (this.editingRange === 'second') {
        this.secondRange = [].concat([], this.selectedRanges || [])
      } else if (this.editingRange === 'hour') {
        this.hourRange = [].concat([], this.selectedRanges || [])
      }
      this.$nextTick(() => {
        this.closeRangePanel()
      })
    },

    closeRangePanel () {
      this.rangeTitle = ''
      this.editingRange = ''
      this.rangeList = undefined
      this.selectedRanges = []
      this.showRangePanel = false
    },

    selectAllRangeItems () {
      this.selectedRanges = [].concat([], this.rangeList || [])
    },

    unselectAllRangeItems () {
      this.selectedRanges = []
    },

    toggleBlurDelay () {
      this.blurDelay = 300
    },

    toggleManualInputTimeout () {
      this.manualInputTimeout = 1000
    }
  },

  mounted () {
    window.addEventListener('scroll', this.scrollHandler)

    this.$nextTick(() => {
      this.updateHourRange()
      this.updatePlaygroundData()
    })
  },

  beforeDestroy () {
    window.removeEventListener('scroll', this.scrollHandler)
  }
}
</script>

<template lang="pug">
section#playground
  main
    h2.section-title Timepicker Playground

    #configPanel
      #typesSelection.config-block
        h3.subtitle
          a.anchor #
          | Generate&nbsp;
          code format
          | &nbsp;string
        config-row(label="Hour:")
          label.options(v-for="(htype, index) in tokens.hour", :key="index", :for="'hour_type' + index" @mouseup.stop="updateHourRange(htype)")
            input(v-model="type.hour", :value="htype", :id="'hour_type' + index" type="radio" name="hour_type")
            | &nbsp;{{ htype }}
        config-row(label="Minute:")
          label.options(v-for="(mtype, index) in tokens.minute", :key="index", :for="'minute_type' + index")
            input(v-model="type.minute", :value="mtype", :id="'minute_type' + index" type="radio" name="minute_type")
            | &nbsp;{{ mtype }}
        config-row(label="Second:")
          label.options(v-for="(stype, index) in tokens.second", :key="index", :for="'second_type' + index")
            input(v-model="type.second", :value="stype", :id="'second_type' + index" type="radio" name="second_type")
            | &nbsp;{{ stype }}
        config-row(v-if="needApm" label="AM/PM:")
          label.options(v-for="(atype, index) in tokens.apm", :key="index", :for="'apm_type' + index")
            input(v-model="type.apm", :value="atype", :id="'apm_type' + index" type="radio" name="apm_type")
            | &nbsp;{{ atype }}

      #valuesSelection.config-block
        h3.subtitle
          a.anchor #
          | Set&nbsp;
          code v-model
          | &nbsp;data
        config-row(label="Hour:")
          label.range-wrapper
            input(v-model="selected.hour" type="range", :min="hourBoundary.min", :max="hourBoundary.max" step="1")
            span(v-text="selected.hour")
        config-row(label="Minute:")
          label.range-wrapper
            input(v-model="selected.minute" type="range" min="0" max="59", :step="interval.minute")
            span(v-text="selected.minute")
        config-row(v-if="showSeconds" label="Second:")
          label.range-wrapper
            input(v-model="selected.second" type="range" min="0" max="59", :step="interval.second")
            span(v-text="selected.second")
        config-row(v-if="needApm" label="AM/PM:", :class="{'capitailized': type.apm === 'A'}")
          label.options(for="selected_apm_am")
            input(v-model="selected.apm" type="radio" id="selected_apm_am" name="selected_apm" value="am")
            | &nbsp;am
          label.options(for="selected_apm_pm")
            input(v-model="selected.apm" type="radio" id="selected_apm_pm" name="selected_apm" value="pm")
            | &nbsp;pm

      .codes
        highlight-code(lang="javascript" data-title="v-model value") {{ yourTimeValue }}

      #intervalSelection.config-block
        h3.subtitle
          a.anchor #
          | Customized Intervals
        config-row(is-group)
          label.options
            input(v-model="customInterval.minute" type="checkbox")
            | &nbsp;Set Minute Interval
          label.range-wrapper(v-if="customInterval.minute")
            input(v-model.number="interval.minute" type="range" min="0" max="60" step="1")
            span(v-text="interval.minute")
        config-row(is-group v-if="showSeconds")
          label.options
            input(v-model="customInterval.second" type="checkbox")
            | &nbsp;Set Second Interval
          label.range-wrapper(v-if="customInterval.second")
            input(v-model.number="interval.second" type="range" min="0" max="60" step="1")
            span(v-text="interval.second")

      #customRanges.config-block
        h3.subtitle
          a.anchor #
          | Customized Ranges
        config-row(is-group)
          label.options
            input(v-model="customRange.hour" type="checkbox")
            | &nbsp;Set Hour Range
          .button-wrapper(v-if="customRange.hour" )
            button.common.size-small(@click="openRangePanel('hour')") Config
            span.item-count {{ hourRange.length }} value{{hourRange.length > 1 ? 's' : ''}} selected
        config-row(is-group)
          label.options
            input(v-model="customRange.minute" type="checkbox")
            | &nbsp;Set Minute Range
          .button-wrapper(v-if="customRange.minute" )
            button.common.size-small(@click="openRangePanel('minute')") Config
            span.item-count {{ minuteRange.length }} value{{minuteRange.length > 1 ? 's' : ''}} selected
        config-row(is-group v-if="showSeconds")
          label.options
            input(v-model="customRange.second" type="checkbox")
            | &nbsp;Set Second Range
          .button-wrapper(v-if="customRange.second" )
            button.common.size-small(@click="openRangePanel('second')") Config
            span.item-count {{ secondRange.length }} value{{secondRange.length > 1 ? 's' : ''}} selected

      #closeOnComplete.config-block
        h3.subtitle
          a.anchor #
          | Close on Complete
        config-row(is-group)
          label.options(for="close_on_complete_true")
            input(v-model="closeOnComplete" type="radio" id="close_on_complete_true" name="close_on_complete", :value="true")
            | &nbsp;Enable
          label.options(for="close_on_complete_false")
            input(v-model="closeOnComplete" type="radio" id="close_on_complete_false" name="close_on_complete", :value="false")
            | &nbsp;Disable

      #clearButton.config-block
        h3.subtitle
          a.anchor #
          | Clear Button
        config-row(is-group)
          label.options(for="hide_clear_btn_false")
            input(v-model="hideClearBtn" type="radio" id="hide_clear_btn_false" name="hide_clear_btn", :value="false")
            | &nbsp;Enable
          label.options(for="hide_clear_btn_true")
            input(v-model="hideClearBtn" type="radio" id="hide_clear_btn_true" name="hide_clear_btn", :value="true")
            | &nbsp;Disable

      #disablePicker.config-block
        h3.subtitle
          a.anchor #
          | Disable Picker
        config-row(is-group)
          label.options
            input(v-model="disablePicker" type="checkbox")
            | &nbsp;Disable

      #lazyMode.config-block
        h3.subtitle
          a.anchor #
          | Lazy Event Mode
        config-row(is-group)
          label.options(for="lazy_mode_true")
            input(v-model="lazyMode" type="radio" id="lazy_mode_true" name="lazy_mode", :value="true")
            | &nbsp;Enable
          label.options(for="lazy_mode_false")
            input(v-model="lazyMode" type="radio" id="lazy_mode_false" name="lazy_mode", :value="false")
            | &nbsp;Disable

      #autoScroll.config-block
        h3.subtitle
          a.anchor #
          | Auto Scroll
        config-row(is-group)
          label.options(for="auto_scroll_true")
            input(v-model="autoScroll" type="radio" id="auto_scroll_true" name="auto_scroll", :value="true")
            | &nbsp;Enable
          label.options(for="auto_scroll_false")
            input(v-model="autoScroll" type="radio" id="auto_scroll_false" name="auto_scroll", :value="false")
            | &nbsp;Disable

      #manualInput.config-block
        h3.subtitle
          a.anchor #
          | Manually Input Support
        config-row(is-group)
          label.options(for="manual_input_true")
            input(v-model="manualInput" type="radio" id="manual_input_true" name="manual_input", :value="true")
            | &nbsp;Enable
          label.options(for="manual_input_false")
            input(v-model="manualInput" type="radio" id="manual_input_false" name="manual_input", :value="false")
            | &nbsp;Disable

      #hideDropdown.config-block(v-if="manualInput")
        h3.subtitle
          a.anchor #
          | Hide Dropdown
        config-row(is-group)
          label.options(for="hide_dropdown_true")
            input(v-model="hideDropdown" type="radio" id="hide_dropdown_true" name="hide_dropdown", :value="true")
            | &nbsp;Enable
          label.options(for="hide_dropdown_false")
            input(v-model="hideDropdown" type="radio" id="hide_dropdown_false" name="hide_dropdown", :value="false")
            | &nbsp;Disable

      #manualInputTimeout.config-block(v-if="manualInput")
        h3.subtitle
          a.anchor #
          | Customized Manual Input Timeout
        config-row(is-group)
          label.options
            input(v-model="customManualInputTimeout" type="checkbox" @input="toggleManualInputTimeout")
            | &nbsp;Set Manual Input Timeout
          label.range-wrapper(v-if="customManualInputTimeout")
            input(v-model.number="manualInputTimeout" type="range" min="50" max="5000" step="50")
            span(v-text="manualInputTimeout")

      #advancedKeyboard.config-block
        h3.subtitle
          a.anchor #
          | Advanced Keyboard Support
        config-row(is-group)
          label.options(for="advanced_kb_true")
            input(v-model="advancedKeyboard" type="radio" id="advanced_kb_true" name="advanced_kb", :value="true")
            | &nbsp;Enable
          label.options(for="advanced_kb_false")
            input(v-model="advancedKeyboard" type="radio" id="advanced_kb_false" name="advanced_kb", :value="false")
            | &nbsp;Disable

      #blurDelay.config-block
        h3.subtitle
          a.anchor #
          | Customized Blur Delay
        config-row(is-group)
          label.options
            input(v-model="customBlurDelay" type="checkbox" @input="toggleBlurDelay")
            | &nbsp;Set Blur Delay
          label.range-wrapper(v-if="customBlurDelay")
            input(v-model.number="blurDelay" type="range" min="50" max="1500" step="50")
            span(v-text="blurDelay")

      #fixedDropdownBtn.config-block
        h3.subtitle
          a.anchor #
          | Fixed Dropdown Button
        config-row(is-group)
          label.options(for="fixed_dd_btn_true")
            input(v-model="fixedDropdownBtn" type="radio" id="fixed_dd_btn_true" name="fixed_dd_btn", :value="true")
            | &nbsp;Enable
          label.options(for="fixed_dd_btn_false")
            input(v-model="fixedDropdownBtn" type="radio" id="fixed_dd_btn_false" name="fixed_dd_btn", :value="false")
            | &nbsp;Disable

      #skipErrorStyle.config-block
        h3.subtitle
          a.anchor #
          | Skip Error Style
        config-row(is-group)
          label.options(for="skip_error_true")
            input(v-model="skipErrorStyle" type="radio" id="skip_error_true" name="skip_error", :value="true")
            | &nbsp;Enable
          label.options(for="skip_error_false")
            input(v-model="skipErrorStyle" type="radio" id="skip_error_false" name="skip_error", :value="false")
            | &nbsp;Disable

      #appendToBody.config-block
        h3.subtitle
          a.anchor #
          | Append To Body
        config-row(is-group)
          label.options(for="append_to_body_true")
            input(v-model="appendToBody" type="radio" id="append_to_body_true" name="append_to_body", :value="true")
            | &nbsp;Enable
          label.options(for="append_to_body_false")
            input(v-model="appendToBody" type="radio" id="append_to_body_false" name="append_to_body", :value="false")
            | &nbsp;Disable

      #debugMode.config-block
        h3.subtitle
          a.anchor #
          | Debug Mode
        config-row(is-group)
          label.options(for="debug_mode_true")
            input(v-model="debugMode" type="radio" id="debug_mode_true" name="debug_mode", :value="true")
            | &nbsp;Enable
          label.options(for="debug_mode_false")
            input(v-model="debugMode" type="radio" id="debug_mode_false" name="debug_mode", :value="false")
            | &nbsp;Disable

  //-
  //- Live preview on the left panel
  //-
  aside.previews(:style="asideStyle")
    #playgroundPreview.preview
      label(for="vueTimepickerInPlayground")
        b Format string:&nbsp;
        span(v-text="formatString")
      p
        vue-timepicker(v-model="playgroundData"
                       id="vueTimepickerInPlayground"
                       :format="formatString"
                       :minute-interval="interval.minute"
                       :second-interval="showSeconds ? interval.second : null"
                       :hour-range="customRange.hour ? hourRange : null"
                       :minute-range="customRange.minute ? minuteRange : null"
                       :second-range="(showSeconds && customRange.second) ? secondRange : null"
                       :close-on-complete="closeOnComplete"
                       :advanced-keyboard="advancedKeyboard"
                       :manual-input="manualInput"
                       :hide-dropdown="toHideDropdown"
                       :blur-delay="blurDelay"
                       :manual-input-timeout="manualInputTimeout"
                       :hide-clear-button="hideClearBtn"
                       :fixed-dropdown-button="fixedDropdownBtn"
                       :disabled="disablePicker"
                       :lazy="lazyMode"
                       :auto-scroll="autoScroll"
                       :append-to-body="appendToBody"
                       :debug-mode="debugMode"
                       :input-class="skipErrorStyle ? 'skip-error-style' : null"
                       @change="changeHandler"
                       @error="errorHandler")

    #htmlCodePreview.codes
      highlight-code(lang="html" data-title="HTML") {{ htmlCodeWithVar }}

    #dispatchedValue.codes
      highlight-code(lang="json" data-title="@change event data") {{ playgroundFullValue }}
      highlight-code(v-if="showErroredData" lang="json" data-title="@error event data") {{ playgroundErroredData }}

  //-
  //- Customized Range Panels
  //-
  overlay-panel(v-if="showRangePanel" :title="rangeTitle" @close="closeRangePanel")
    template(v-slot:footerLeft)
      button.secondary(@click="selectAllRangeItems") Select All
      button.secondary(@click="unselectAllRangeItems") Unselect All
    template(v-slot:footerRight)
      button(@click="confirmRange") Confirm

    .valid-items
      label.range-item(v-for="(rangeItem, rIndex) in rangeList")
        input(type="checkbox" name="selected_ranges" v-model="selectedRanges" :value="rangeItem")
        | {{ rangeItem }}

    .invalid-items(v-if="filteredOutValues && filteredOutValues.length")
      b Values selected but filtered out by the&nbsp;
        template(v-if="editingRange !== 'hour'") {{editingRange}}-interval:
        template(v-else) current hour type
      .items-list
        span.invalid-range(v-for="oItem in filteredOutValues" :key="oItem" v-text="oItem")

</template>

<style lang="stylus">
@import '../assets/_variables.styl'

section#playground
  main
    padding-left: 420px
    .codes
      pre,
      code
        overflow-x: auto

  .config-block
    .subtitle
      margin: 0
      padding: 1em 0 0.5em 0
      position: relative

      a.anchor
        position: absolute
        left: -1em

    &:first-of-type
      .subtitle
        padding-top: 0

    .button-wrapper
      display: flex
      flex-flow: row wrap
      justify-content: flex-start
      align-items: center
      padding: 0.3em 0.5em
      border-radius: 4px
      background: -black(0.05)

  aside.previews
    position: fixed
    width: 320px
    left:10%
    top: 0
    z-index: 10
    padding-top: 220px

  #playgroundPreview
    box-sizing: border-box
    background: #fff
    padding: 1em 1.5em

  .range-item,
  .invalid-range
    display: inline-block
    margin-right: 1em
    margin-bottom: 0.5em
  
  .range-item
    min-width: 3em

  .invalid-range
    opacity: 0.7

  .invalid-items
    margin-top: 1em
    padding: 0.8em 0.8em 0.3em 0.8em
    background: -black(0.05)
    border-radius: 6px

    .items-list
      padding-top: 0.8em

  .item-count
    font-size: 0.85em
    padding-left: 0.5em
    opacity: 0.7
</style>


================================================
FILE: demo/src/components/SampleBlock.vue
================================================
<script>
export default {
  name: 'SampleBlock',
  props: {
    id: { type: String }
  },
  computed: {
    blockHerf () {
      if (this.id && this.id.length) {
        return `#${this.id}`
      }
      return null
    }
  }
}
</script>

<template lang="pug">
.sample-block(:id="id")
  h3.title
    a.anchor(:href="blockHerf") #
    slot(name="title")
  .description
    slot(name="description")
  .codes
    slot(name="codes")
  .preview
    slot(name="preview")
  .codes(v-if="$slots.data")
    slot(name="data")
</template>

<style lang="stylus">
.sample-block
  padding: 5em 0 0 20%
  &:first-of-type
    padding-top: 0

  .title
    position: relative
    margin-bottom: 1.5em

    a.anchor
      position: absolute
      left: -1em

  .description,
  .preview,
  .codes
    margin-left: 1.5em

  .inline-data-preview
    display: inline-block
    margin-left: 1em
    font-size: 0.9em
  
  ul
    margin: 0 0 1em 0
    padding: 0 0 0 1.2em
    li
      list-style: circle
      line-height: 150%
</style>


================================================
FILE: demo/src/components/Samples.vue
================================================
<script>
import VueTimepicker from '../../../src/vue-timepicker'
import SampleBlock from './SampleBlock'

export default {
  name: 'Samples',
  components: {
    VueTimepicker,
    SampleBlock
  },
  data () {
    return {
      yourData: {
        hh: '03',
        mm: '05',
        ss: '00',
        a: 'am'
      },
      yourFormat: 'hh:mm:ss a',
      yourDaysArray: [
        {start_time: {HH: '08', mm: '00'}, end_time: {HH: '09', mm: '00'}},
        {start_time: {HH: '15', mm: '00'}, end_time: {HH: '', mm: ''}},
        {start_time: {HH: '', mm: ''}, end_time: {HH: '13', mm: '30'}},
        {start_time: {HH: '', mm: ''}, end_time: {HH: '', mm: ''}}
      ],

      simpleStringValue: '02:30',
      yourStringValue: '3:mm:05 A',
      unsetStringValue: '',

      muteFlowListener: true,
      latestDataFlow: undefined,
      demoData1: {HH: '08', mm: '30'},
      demoData2: {HH: '10', mm: '45'},
      demoArgs: undefined,

      dropdownStatus: 'closed',
      
      focusState: 'blurred',
      dropdownState: 'closed',

      lazyData: {
        hh: '06',
        mm: '50',
        ss: '00',
        a: 'am'
      },
      lazyChangeData: undefined,
      lazyInputData: undefined,
      lazyEventTs: undefined,

      manualStringValue: '8:15 pm',

      customCloseBtnValue: '10:05',

      autoScrollData1: '08:40',
      autoScrollData2: '5:30:20 pm',

      apmFirst1: 'AM 03:15',
      apmFirst2: 'pm9時6分',

      sideNav: [
        { title: 'Default', anchor: 'default' },
        { title: '12 Hours', anchor: 'format12hours' },
        { title: 'Seconds Picker', anchor: 'seconds' },
        { title: 'Customized Interval', anchor: 'interval' },
        { title: 'Using v-model', anchor: 'vModel' },
        { title: 'v-model with String Value', anchor: 'vModelWithString' },
        { title: 'Work with v-for', anchor: 'vForSample' },
        { title: 'Hour Range', anchor: 'hourRange' },
        { title: 'Minute and Second Range', anchor: 'minuteAndSecondRange' },
        { title: 'Hide Disabled Items', anchor: 'hideDisabledItems' },
        { title: 'Close on Complete', anchor: 'closeOnComplete' },
        { title: 'Hide Clear Button', anchor: 'hideClearButton' },
        { title: 'Disable Picker', anchor: 'disablePicker' },
        { title: 'The @change Event', anchor: 'onChangeSample' },
        { title: 'Lazy Event Mode', anchor: 'lazyEvents' },
        { title: 'Keyboard Support', anchor: 'kbSupport' },
        { title: 'Manual Input', anchor: 'manualInput'},
        { title: '@open and @close event', anchor: 'openAndClose' },
        { title: '@focus and @blur event', anchor: 'focusAndBlur' },
        { title: 'Customized Picker Labels', anchor: 'customPickerLabels' },
        { title: 'Adjust Input Width', anchor: 'inputWidth' },
        { title: 'Auto-Scroll', anchor: 'autoScroll' },
        { title: 'More Powerful format String', anchor: 'morePowerfulFormat' },
        { title: 'Customized Buttons And Icon', anchor: 'customButtonIcon' },
        { title: 'Fixed Dropdown Button', anchor: 'fixedDropdownButton' },
        { title: 'Drop Direction', anchor: 'dropDirection' }
      ]
    }
  },

  methods: {
    changeHandler (eventData) {
      if (this.muteFlowListener) { return }
      this.latestDataFlow = eventData
      this.demoArgs = undefined
    },

    otherChangeHandler (eventData, arg1, arg2) {
      if (this.muteFlowListener) { return }
      this.latestDataFlow = eventData
      this.demoArgs = {
        arg1: arg1,
        arg2: arg2
      }
    },

    lazyChangeHandler (eventData) {
      this.lazyChangeData = eventData
      this.lazyEventTs = new Date().toLocaleString()
    },

    lazyInputHandler (eventData) {
      this.lazyInputData = eventData
    }
  },

  mounted () {
    window.setTimeout(() => {
      this.muteFlowListener = false
    }, 1000)
  }
}
</script>

<template lang="pug">
section#mostlyUsedSamples
  h2.section-title Common Usage

  //- Default
  sample-block#default
    template(v-slot:title) Default
    p(slot="description")
      | Default to 24-hour format
      code HH:mm
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        | &lt;vue-timepicker&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      vue-timepicker

  //- 12 Hours
  sample-block#format12hours
    template(v-slot:title) 12 Hours
    p(slot="description")
      | By properly define the
      code format
      | string, you can set timepicker in form of 12 hours
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- 12-hour sample 1 --&gt;
          | &lt;vue-timepicker format="hh:mm A"&gt;&lt;/vue-timepicker&gt;
          | &nbsp;
          | &lt;!-- 12-hour sample 2 --&gt;
          | &lt;vue-timepicker format="h:m a"&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      b 12-hour sample 1
      p
        vue-timepicker(format="hh:mm A")
      b 12-hour sample 2
      p
        vue-timepicker(format="h:m a")

  //- Seconds Picker
  sample-block#seconds
    template(v-slot:title) Seconds Picker
    p(slot="description")
      | You can trigger the seconds picker by adding
      code ss
      | or
      code s
      | in your format string.
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        | &lt;vue-timepicker format="HH:mm:ss"&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      vue-timepicker(format="HH:mm:ss")

  //- Customized Interval
  sample-block#interval
    template(v-slot:title) Customized Interval
    p(slot="description")
      | Timepicker also allows you to display minutes or seconds picker with certain interval, like a 10-minute interval
      code 0, 10, 20, ... 50, 60
      | for example
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- 10-minute interval --&gt;
          | &lt;vue-timepicker :minute-interval="10"&gt;&lt;/vue-timepicker&gt;
          | &nbsp;
          | &lt;!-- 15-second interval --&gt;
          | &lt;vue-timepicker format="HH:mm:ss" :second-interval="15"&gt;&lt;/vue-timepicker&gt;
          | &nbsp;
          | &lt;!-- 5-minute interval plus 10-second interval --&gt;
          | &lt;vue-timepicker format="hh:mm:ss" :minute-interval="5" :second-interval="10"&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      b 10-minute interval
      p
        vue-timepicker(:minute-interval="10")
      b 15-second interval
      p
        vue-timepicker(format="HH:mm:ss" :second-interval="15")
      b 5-minute interval plus 10-second interval
      p
        vue-timepicker(format="hh:mm:ss" :minute-interval="5" :second-interval="10")

  //- Using v-model
  sample-block#vModel
    template(v-slot:title)
      | Using&nbsp;
      code v-model
    p(slot="description")
      | Timepicker takes <code>v-model</code> value in object format by default.
    template(v-slot:codes)
      highlight-code(lang="javascript" data-title="JS")
        pre
          | // Define format and initial data
          | data () {
          |   return {
          |     yourFormat: 'hh:mm:ss a',
          |     yourData: {
          |       hh: '03',
          |       mm: '05',
          |       ss: '00',
          |       a: 'am'
          |     }
          |   }
          | }
      highlight-code(lang="html" data-title="HTML")
        | &lt;vue-timepicker :format="yourFormat" v-model="yourData"&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      vue-timepicker(:format="yourFormat" v-model="yourData")
    template(v-slot:data)
      highlight-code(lang="json" data-title="`yourData` in live (JSON)") {{ yourData }}

  //- String format `v-model`
  sample-block#vModelWithString
    template(v-slot:title)
      code v-model
      | &nbsp;with String Value
    p(slot="description")
      | From <code>v1.0.0+</code>, timepicker also supports <code>v-model</code> value in string format.
    template(v-slot:codes)
      highlight-code(lang="javascript" data-title="JS")
        pre
          | // Set initial data in string format
          | data () {
          |   return {
          |     simpleStringValue: '02:30',
          |
          |     // paired with format 'h:mm:ss A'
          |     yourStringValue: '3:mm:05 A',
          |
          |     unsetStringValue: ''
          |   }
          | }
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- default 24-hour sample --&gt;
          | &lt;vue-timepicker v-model="simpleStringValue"&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;!-- 12-hour format with partial value set --&gt;
          | &lt;vue-timepicker v-model="yourStringValue" format="h:mm:ss A"&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;!-- unset/unknown initial value --&gt;
          | &lt;vue-timepicker v-model="unsetStringValue"&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      b default 24-hour sample
      p
        vue-timepicker(v-model="simpleStringValue")
        span.inline-data-preview
          | simpleStringValue&nbsp;
          code "{{ simpleStringValue }}"
      b 12-hour format with partial value set
      p
        vue-timepicker(v-model="yourStringValue" format="h:mm:ss A")
        span.inline-data-preview
          | yourStringValue:&nbsp;
          code "{{ yourStringValue }}"
      b unset/unknown initial value
      p
        vue-timepicker(v-model="unsetStringValue")
        span.inline-data-preview
          | unsetStringValue:&nbsp;
          code "{{ unsetStringValue }}"

  //- v-for Example
  sample-block#vForSample
    template(v-slot:title)
      | Work with&nbsp;
      code v-for
    p(slot="description")
      | Here's a quick sample of
      code v-for
      | usage
    template(v-slot:codes)
      highlight-code(lang="javascript" data-title="JS")
        pre
          | data () {
          |   return {
          |     yourDaysArray: [
          |       {start_time: {HH: '08', mm: '00'}, end_time: {HH: '09', mm: '00'}},
          |       {start_time: {HH: '15', mm: '00'}, end_time: {HH: '', mm: ''}},
          |       {start_time: {HH: '', mm: ''}, end_time: {HH: '13', mm: '30'}},
          |       {start_time: {HH: '', mm: ''}, end_time: {HH: '', mm: ''}}
          |     ]
          |   }
          | }
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;p v-for="(day, index) in yourDaysArray"&gt;
          |   &lt;label&gt;Day <span>{{</span> index + 1 <span>}}</span>: &lt;/label&gt;
          |   &lt;vue-timepicker v-model="day.start_time" placeholder="Start Time"&gt;&lt;/vue-timepicker&gt;
          |   &lt;span&gt; to &lt;/span&gt;
          |   &lt;vue-timepicker v-model="day.end_time" placeholder="End Time"&gt;&lt;/vue-timepicker&gt;
          | &lt;/p&gt;
    template(v-slot:preview)
      p(v-for="(day, index) in yourDaysArray")
        label Day {{ index + 1 }}:&nbsp;
        vue-timepicker(v-model="day.start_time" placeholder="Start Time")
        span &nbsp;to&nbsp;
        vue-timepicker(v-model="day.end_time" placeholder="End Time")
    template(v-slot:data)
      highlight-code(lang="json" data-title="`yourDaysArray` JSON in live") {{ yourDaysArray }}

  //- Hour Range
  sample-block#hourRange
    template(v-slot:title) Hour Range
    p(slot="description") Define the hour values you want and disable the rest
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- Hour Range Sample 1 --&gt;
          | &lt;vue-timepicker :hour-range="[5, [8, 12], [14, 17], 19]"&gt;&lt;/vue-timepicker&gt;
          | &lt;!-- >> Equals to :hour-range="[5, 8, 9, 10, 11, 12, 14, 15, 16, 17, 19]" --&gt;
          | &nbsp;
          | &lt;!-- Hour Range Sample 2 (12-hour format) --&gt;
          | &lt;vue-timepicker :hour-range="['7a', '9a', '11a', '1p', ['3p', '5p'], '7p']" format="hh:mm a"&gt;&lt;/vue-timepicker&gt;
          | &lt;!-- >> Equals to :hour-range="['7a', '9a', '11a', '1p', '3p', '4p', '5p', '7p']" --&gt;
    template(v-slot:preview)
      b Hour Range Sample 1
      p
        vue-timepicker(:hour-range="[5, [8, 12], [14, 17], 19]")
      b Hour Range Sample 2 (12-hour format)
      p
        vue-timepicker(:hour-range="['7a', '9a', '11a', '1p', ['3p', '5p'], '7p']" format="hh:mm a")

  //- Minute Range
  sample-block#minuteAndSecondRange
    template(v-slot:title) Minute and Second Range
    template(v-slot:description)
      p Similar to Hour Range, you can set available minute/second values base on your needs.
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- Minute range only --&gt;
          | &lt;vue-timepicker :minute-range="[0, 6, [10, 30], 42, 50]"&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;!-- Minute range + 5-minute interval --&gt;
          | &lt;vue-timepicker :minute-range="[0, 6, [10, 30], 42, 50]" :minute-interval="5"&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;!-- Second range only --&gt;
          | &lt;vue-timepicker format="H:m:s" :second-range="[0, 6, [10, 30], 42, 50]"&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;!-- Second range + 10-second interval --&gt;
          | &lt;vue-timepicker format="H:m:s" :second-range="[0, 6, [10, 30], 42, 50]" :second-interval="10"&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;!-- Minute and Second ranges + 10-minute interval + 5-second interval --&gt;
          | &lt;vue-timepicker format="HH:mm:ss" :minute-range="[0, 6, [10, 30], 42, 50]" :second-range="[0, 6, [10, 30], 42, 50]" :minute-interval="10" :second-interval="5"&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      b Minute range only
      p
        vue-timepicker(:minute-range="[0, 6, [10, 30], 42, 50]")
      b Minute range + 5-minute interval
      p
        vue-timepicker(:minute-range="[0, 6, [10, 30], 42, 50]" :minute-interval="5")
      b Second range only
      p
        vue-timepicker(format="H:m:s" :second-range="[0, 6, [10, 30], 42, 50]")
      b Second range + 10-second interval
      p
        vue-timepicker(format="H:m:s" :second-range="[0, 6, [10, 30], 42, 50]" :second-interval="10")
      b Minute and Second ranges + 10-minute interval + 5-second interval
      p
        vue-timepicker(format="HH:mm:ss" :minute-range="[0, 6, [10, 30], 42, 50]" :second-range="[0, 6, [10, 30], 42, 50]" :minute-interval="10" :second-interval="5")

  //- Hide Disabled Items
  sample-block#hideDisabledItems
    template(v-slot:title) Hide Disabled Items
    template(v-slot:description)
      p Here're four kinds of helper properties to let you hide the values excluded by the <code>hour-range</code>, <code>minute-range</code>, and <code>second-range</code>.
      ul
        li
          b hide-disabled-items
          | : Hide <b>all</b> disabled items - hour, minute, and seconds.
        li
          b hide-disabled-hours
          | : Hide disabled <b>hour</b> valus only.
        li
          b hide-disabled-minutes
          | : Hide disabled <b>minute</b> values only.
        li
          b hide-disabled-seconds
          | : Hide disabled <b>second</b> values only.
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- hide-disabled-items --&gt;
          | &lt;vue-timepicker hide-disabled-items format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]"&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;!-- hide-disabled-hours --&gt;
          | &lt;vue-timepicker hide-disabled-hours format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]"&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;!-- hide-disabled-minutes --&gt;
          | &lt;vue-timepicker hide-disabled-minutes format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]"&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;!-- hide-disabled-seconds --&gt;
          | &lt;vue-timepicker hide-disabled-seconds format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]"&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      b hide-disabled-items
      p
        vue-timepicker(hide-disabled-items format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]")
      b hide-disabled-hours
      p
        vue-timepicker(hide-disabled-hours format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]")
      b hide-disabled-minutes
      p
        vue-timepicker(hide-disabled-minutes format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]")
      b hide-disabled-seconds
      p
        vue-timepicker(hide-disabled-seconds format="HH:mm:ss" :hour-range="[[9, 17]]" :minute-range="[0, 10, 15, 30, 50]" :second-range="[5, 15, 25, 45]")

  //- Close on Complete
  sample-block#closeOnComplete
    template(v-slot:title) Close on Complete
    p(slot="description")
      | Automatically close the dropdown when user finish selecting <b>all</b> of the required fields.
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- Auto-close on complete --&gt;
          | &lt;vue-timepicker format="hh:mm A" close-on-complete&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;!-- Default - close by clicking anywhere outside of the dropdown --&gt;
          | &lt;vue-timepicker format="hh:mm A"&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      b Auto-close on complete
      p
        vue-timepicker(format="hh:mm A" close-on-complete)
      b Default - close by clicking anywhere outside of the dropdown
      p
        vue-timepicker(format="hh:mm A")

  //- Hide Clear Button
  sample-block#hideClearButton
    template(v-slot:title) Hide Clear Button
    p(slot="description")
      | If you don't want to expose the clear button in the UI,
      code hide-clear-button
      | property will do the trick.
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        | &lt;vue-timepicker hide-clear-button&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      vue-timepicker(hide-clear-button)


  //- Disable Picker
  sample-block#disablePicker
    template(v-slot:title) Disable Picker
    p(slot="description")
      | Completely disable the picker.
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        | &lt;vue-timepicker disabled&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      vue-timepicker(disabled)

  //- @change Sample
  sample-block#onChangeSample
    template(v-slot:title)
      | The&nbsp;
      code change
      | &nbsp;Event
    template(v-slot:description)
      p A <code>change</code> event will be triggered every time the user alters timepicker's value.
      p Unlike the <code>v-model</code>, which only returns data in your predefined format, <code>change</code> event will return a full package of all supported time tokens.
      p Started from <code>v0.2.2</code>, a <code>displayTime</code> string value is also included in the return data of <code>change</code> event.
      p Play around with the two pickers below to see their data changes in live.
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- No argument --&gt;
          | &lt;vue-timepicker v-model="demoData1" @change="changeHandler"&gt;&lt;/vue-timepicker&gt;
          | &nbsp;
          | &lt;!-- Custom argument --&gt;
          | &lt;vue-timepicker v-model="demoData2" @change="otherChangeHandler($event, 'foo', 42)"&gt;&lt;/vue-timepicker&gt;
      highlight-code(lang="javascript" data-title="JS")
        pre
          | methods: {
          |   // No argument
          |   changeHandler (eventData) {
          |     // eventData -&gt; {data: {HH:..., mm:...}, displayTime: 'HH:mm'}
          |   },
          |
          |   // Customized arguments
          |   otherChangeHandler (eventData, arg1, arg2) {
          |     // eventData -&gt; {data: {HH:..., mm:...}, displayTime: 'HH:mm'}
          |     // arg1 -&gt; 'foo'
          |     // arg2 -&gt; 42
          |   }
          | }
    template(v-slot:preview)
      b No argument
      p
        vue-timepicker(v-model="demoData1" @change="changeHandler")
      b With Custom arguments ('foo', 42)
      p
        vue-timepicker(v-model="demoData2" @change="otherChangeHandler($event, 'foo', 42)")
    template(v-if="latestDataFlow || demoArgs" slot="data")
      highlight-code(v-if="latestDataFlow" lang="json" data-title="The `@change` event data") {{ latestDataFlow }}
      highlight-code(v-if="demoArgs" lang="json" data-title="Received Custom Arguments") {{ demoArgs }}
      highlight-code(v-if="latestDataFlow" lang="json" data-title="`v-model` value") {{ demoArgs ? demoData2 : demoData1 }}

  //- Lazy Event Mode
  sample-block#lazyEvents
    template(v-slot:title) Lazy Event Mode
    template(v-slot:description)
      p When <code>lazy</code> event mode is toggled on, only an actual user behavior can trigger the <code>input</code> and <code>change</code> events. Which are:
      ul
        li The user opened the dropdown and picked a new value
        li The user clicked the ("x") clear button
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        | &lt;vue-timepicker lazy format="hh:mm:ss a"&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      p
        vue-timepicker(v-model="lazyData" lazy format="hh:mm:ss a" @input="lazyInputHandler" @change="lazyChangeHandler")
        span.inline-data-preview(v-if="lazyEventTs")
          b Last <code>change</code> event timestamp:
          | &nbsp;{{ lazyEventTs }}

    template(v-slot:data)
      highlight-code(v-if="lazyInputData" lang="json" data-title="The lazy `input` event data") {{ lazyInputData }}
      highlight-code(v-if="lazyChangeData" lang="json" data-title="The lazy `change` event data") {{ lazyChangeData }}

  //- Keyboard Support
  sample-block#kbSupport
    template(v-slot:title) Keyboard Support
    template(v-slot:description)
      p
        b Basic Keyboard Support:
      ul
        li
          b Tab
          | : Focus or blur the Timepicker
        li
          b Esc
          | : Close the dropdown
      p
        b Advance Keyboard Support:
      ul
        li
          b Arrow Keys
          | : Navigate between valid (non-disabled) values and columns
        li
          b Space
          | &nbsp;or&nbsp;
          b Enter
          | : Select the focusing item
      p Try tabbing through the following inputs to see the difference between the <b>Default Timepicker</b> and the <b>Timepicker with Advanced Keyboard support</b>.

    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;label for="otherInput"&gt;Text Input&lt;label/&gt;
          | &lt;input id="otherInput" type="text" placeholder="Text" /&gt;
          |
          | &lt;!-- Default, with minimal keyboard support --&gt;
          | &lt;label for="simplePicker"&gt;Default Vue Timepicker&lt;label/&gt;
          | &lt;vue-timepicker id="simplePicker"&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;label for="moreInput"&gt;Number Input&lt;label/&gt;
          | &lt;input id="moreInput" type="number" placeholder="Number" /&gt;
          |
          | &lt;!-- Advanced Keyboard Support Enabled --&gt;
          | &lt;label for="pickerKB"&gt;Vue Timepicker with Advanced Keyboard support&lt;label/&gt;
          | &lt;vue-timepicker advanced-keyboard format="h:mm:ss A" :hour-range="[['7a', '5p']]" id="pickerKB"&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;label for="oneMoreInput"&gt;One More Text Input&lt;label/&gt;
          | &lt;input id="oneMoreInput" type="text" placeholder="More Text" /&gt;
    template(v-slot:preview)
      b
        label(for="otherInput") Text Input
      p
        input#otherInput.native-input(type="text" placeholder="Text")
      b
        label(for="simplePicker") Default Vue Timepicker
      p
        vue-timepicker(id="simplePicker")
      b
        label(for="moreInput") Number Input
      p
        input#moreInput.native-input(type="number" placeholder="Number")
      b
        label(for="pickerKB") Vue Timepicker with Advanced Keyboard support
      p
        vue-timepicker(id="pickerKB" format="h:mm:ss A" :hour-range="[['7a', '5p']]" advanced-keyboard)
      b
        label(for="oneMoreInput") One More Text Input
      p
        input#oneMoreInput.native-input(type="text" placeholder="More Text")

  //- Manual Input
  sample-block#manualInput
    template(v-slot:title) Manual Input
    p(slot="description")
      | Allow users to input values manually. Please note that the additional <code>hide-dropdown</code> option works with <code>manual-input</code> mode only.
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- 24-hour format with empty init value --&gt;
          | &lt;vue-timepicker manual-input&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;!-- 12-hour format with a predefined value --&gt;
          | &lt;vue-timepicker format="h:mm a" v-model="manualStringValue" manual-input&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;!-- Manual input + hide dropdown --&gt;
          | &lt;vue-timepicker manual-input hide-dropdown&gt;&lt;/vue-timepicker&gt;
      highlight-code(lang="javascript" data-title="JS")
        pre
          | data () {
          |   return {
          |     manualStringValue: '8:15 pm'
          |   }
          | }
    template(v-slot:preview)
      b 24-hour format with empty init value
      p
        vue-timepicker(manual-input)
      b 12-hour format with a predefined value
      p
        vue-timepicker(format="h:mm a" v-model="manualStringValue" manual-input)
      b Manual input + hide dropdown
      p
        vue-timepicker(manual-input hide-dropdown)

  //- Open And Close Event
  sample-block#openAndClose
    template(v-slot:title)
      code open
      | &nbsp;and&nbsp;
      code close
      | &nbsp;event
    p(slot="description")
      | Help to identify the current state of the dropdown picker.
    template(v-slot:codes)
      highlight-code(lang="javascript" data-title="JS")
        pre
          | // Define a variable for logging the status
          | data () {
          |   return {
          |     dropdownStatus: 'closed'
          |   }
          | }
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;p&gt;Dropdown Status: I'm <span>{{</span>dropdownStatus<span>}}</span>!&lt;/p&gt;
          | &nbsp;
          | &lt;vue-timepicker @open="dropdownStatus = 'opened'" @close="dropdownStatus = 'closed'"&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      b Dropdown Status: I'm {{dropdownStatus}}!
      p
        vue-timepicker(@open="dropdownStatus = 'opened'" @close="dropdownStatus = 'closed'")

  //- Focus And Blur Event
  sample-block#focusAndBlur
    template(v-slot:title)
      code focus
      | &nbsp;and&nbsp;
      code blur
      | &nbsp;event
    p(slot="description")
      | It works with Manual Input mode. Helps to identify the focus/blur state of the Timepicker's input. Especially useful when the dropdown is force hidden by <code>hide-dropdown</code>.
    template(v-slot:codes)
      highlight-code(lang="javascript" data-title="JS")
        pre
          | data () {
          |   return {
          |     // variable for the input state
          |     focusState: 'blurred',
          |
          |     // variable for the dropdown state
          |     dropdownState: 'closed'
          |   }
          | }
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;span&gt;Focus State: <span>{{</span>focusState<span>}}</span>&lt;/span&gt;
          | &lt;span&gt;Dropdown State: <span>{{</span>dropdownState<span>}}</span>&lt;/span&gt;
          | &nbsp;
          | &lt;vue-timepicker manual-input hide-dropdown @focus="focusState = 'focused'" @blur="focusState = 'blurred'" @open="dropdownState = 'opened'" @close="dropdownState = 'closed'"&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      b Focus State: {{focusState}}
      span &emsp;/&emsp;
      b Dropdown State: {{ dropdownState }}
      p
        vue-timepicker(manual-input hide-dropdown @focus="focusState = 'focused'" @blur="focusState = 'blurred'" @open="dropdownState = 'opened'" @close="dropdownState = 'closed'")

  //- Custom Labels
  sample-block#customPickerLabels
    template(v-slot:title) Customized Picker Labels
    p(slot="description")
      | Define customized labels for hour, minute, second, and APM pickers.
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- 24-hour format with customized hour and minute labels --&gt;
          | &lt;vue-timepicker hour-label="heure" minute-label="minute"&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;!-- 12-hour format with customized am/pm text --&gt;
          | &lt;vue-timepicker hour-label="时" minute-label="分" second-label="秒" apm-label="午" am-text="上午" pm-text="下午" format="h:mm:ss a"&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      b 24-hour format with customized hour and minute label
      p
        vue-timepicker(hour-label="heure" minute-label="minute")
      b 12-hour format with customized am/pm text
      p
        vue-timepicker(hour-label="时" minute-label="分" second-label="秒" apm-label="午" am-text="上午" pm-text="下午" format="h:mm:ss a")

  //- Adjust Input Width
  sample-block#inputWidth
    template(v-slot:title) Adjust Input Width
    p(slot="description")
      | Helps you to adjust both the
      code &lt;input&gt;
      | and the dropdown picker's width
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- In `px` --&gt;
          | &lt;vue-timepicker input-width="100px"&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;!-- In `em` --&gt;
          | &lt;vue-timepicker input-width="12em" format="HH:mm:ss"&gt;&lt;/vue-timepicker&gt;
    template(v-slot:preview)
      b In `px`
      p
        vue-timepicker(input-width="100px")
      b In `em`
      p
        vue-timepicker(input-width="12em" format="HH:mm:ss")

  //- Auto Scroll
  sample-block#autoScroll
    template(v-slot:title) Auto-Scroll
    p(slot="description") Auto-scroll to selected value on dropdown open.
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- Default format --&gt;
          | &lt;vue-timepicker auto-scroll v-model="autoScrollData1"&gt;&lt;/vue-timepicker&gt;
          | &nbsp;
          | &lt;!-- 12-hour format --&gt;
          | &lt;vue-timepicker auto-scroll format="h:mm:ss a" v-model="autoScrollData2"&gt;&lt;/vue-timepicker&gt;
      highlight-code(lang="javascript" data-title="JS")
        pre
          | // Initial values
          | data () {
          |   return {
          |     autoScrollData1: '08:40',
          |     autoScrollData2: '5:30:20 pm'
          |   }
          | }
    template(v-slot:preview)
      b Default format
      p
        vue-timepicker(auto-scroll v-model="autoScrollData1")
      b 12-hour format
      p
        vue-timepicker(auto-scroll format="h:mm:ss a" v-model="autoScrollData2")

  //- More Powerful format String
  sample-block#morePowerfulFormat
    template(v-slot:title) More Powerful <code>format</code> String
    template(slot="description")
      p The <code>format</code> parameter becomes even more powerful started from <code>v1.1.2</code>.
    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- Use without "hour" --&gt;
          | &lt;vue-timepicker format="mm:ss"&gt;&lt;/vue-timepicker&gt;
          | &lt;vue-timepicker format="m:s"&gt;&lt;/vue-timepicker&gt;
          | &nbsp;
          | &lt;!-- Make AM/PM the first column in the dropdown --&gt;
          | &lt;vue-timepicker format="A hh:mm" v-model="apmFirst1"&gt;&lt;/vue-timepicker&gt;
          | &lt;vue-timepicker format="ah時m分" v-model="apmFirst2" am-text="午前" pm-text="午後"&gt;&lt;/vue-timepicker&gt;
          | &nbsp;
          | &lt;!-- Hour + APM only --&gt;
          | &lt;vue-timepicker format="ha"&gt;&lt;/vue-timepicker&gt;
          | &lt;vue-timepicker format="hh A"&gt;&lt;/vue-timepicker&gt;
          | &nbsp;
          | &lt;!-- One slot only --&gt;
          | &lt;!-- Not recommended, though :) --&gt;
          | &lt;vue-timepicker format="h" input-width="60px"&gt;&lt;/vue-timepicker&gt;
          | &lt;vue-timepicker format="mm" input-width="60px"&gt;&lt;/vue-timepicker&gt;
          | &lt;vue-timepicker format="ss" input-width="60px"&gt;&lt;/vue-timepicker&gt;
          | &lt;vue-timepicker format="a" input-width="60px"&gt;&lt;/vue-timepicker&gt;
      highlight-code(lang="javascript" data-title="JS")
        pre
          | // Initial values
          | data () {
          |   return {
          |     apmFirst1: 'AM 03:15',
          |     // -> Equivalent to:
          |     // apmFirst1: {
          |     //   A: 'AM',
          |     //   hh: '03',
          |     //   mm: '15'
          |     // }
          |
          |     apmFirst2: 'pm9時6分'
          |     // -> Equivalent to:
          |     // apmFirst2: {
          |     //   a: 'pm',
          |     //   h: '9',
          |     //   m: '6'
          |     // }
          |   }
          | }
    template(v-slot:preview)
      b Use without "hour"
      p
        vue-timepicker(format="mm:ss")
        | &nbsp;
        vue-timepicker(format="m:s")
      b Make AM/PM the first column in the dropdown
      p
        vue-timepicker(format="A hh:mm" v-model="apmFirst1")
        | &nbsp;
        vue-timepicker(format="ah時m分" v-model="apmFirst2" am-text="午前" pm-text="午後")
      b Hour + APM only
      p
        vue-timepicker(format="ha")
        | &nbsp;
        vue-timepicker(format="hh A")
      b One slot only
      p
        vue-timepicker(format="h" input-width="60px")
        | &nbsp;
        vue-timepicker(format="mm" input-width="60px")
        | &nbsp;
        vue-timepicker(format="ss" input-width="60px")
        | &nbsp;
        vue-timepicker(format="a" input-width="60px")

  //- Custom Button And Icon
  sample-block#customButtonIcon
    template(v-slot:title) Customized Buttons And Input Icon
    template(v-slot:description)
      p You can customize the clear button, and the dropdown button with your own icon/image starts from <code>v1.1.4+</code>. There's an additional slot for the input icon as well.
      p Please note that Vue v2.6.0+ introduces a significant update of the <b>Named Slots</b> syntax. Check the <a href="https://vuejs.org/v2/guide/components-slots.html#Named-Slots" target="_black">official documentation</a> for more information.

    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- For Vue 2.6.0+ --&gt;
          |
          | &lt;!-- Input icon (image) --&gt;
          | &lt;vue-timepicker&gt;
          |   &lt;template v-slot:icon&gt;
          |     &lt;img src="$YOUR_ICON_SRC" /&gt;
          |   &lt;/template&gt;
          | &lt;/vue-timepicker&gt;
          |
          | &lt;!-- Customized clear button (image) --&gt;
          | &lt;vue-timepicker&gt;
          |   &lt;template v-slot:clearButton&gt;
          |     &lt;img src="$YOUR_CUSTOM_IMAGE_SRC" /&gt;
          |   &lt;/template&gt;
          | &lt;/vue-timepicker&gt;
          |
          | &lt;!-- Customized dropdown button (character entity) --&gt;
          | &lt;vue-timepicker manual-input hide-dropdown&gt;
          |   &lt;template v-slot:dropdownButton&gt;&amp;#x02263;&lt;/template&gt;
          | &lt;/vue-timepicker&gt;

    template(v-slot:preview)
      b Input icon (image)
      p
        vue-timepicker
          template(v-slot:icon)
            img(src="https://i.postimg.cc/CLkZcW46/custom-clock.png")
      b Customized clear button (image)
      p
        vue-timepicker(v-model="customCloseBtnValue")
          template(v-slot:clearButton)
            img(src="https://i.postimg.cc/Y0f6RHF8/custom-close.png")
      b Customized dropdown button (character entity)
      p
        vue-timepicker(manual-input hide-dropdown)
          template(v-slot:dropdownButton) &#x02263;


  //- Fixed Dropdown Button
  sample-block#fixedDropdownButton
    template(v-slot:title) Fixed Dropdown Button
    template(v-slot:description)
      p You can make the dropdown button always visible in the UI with <code>fixed-dropdown-button</code>.
      p When paired with a customized dropdown button, it's similar to an input icon on the righthand side.

    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- Default dropdown button --&gt;
          | &lt;vue-timepicker fixed-dropdown-button&gt;&lt;/vue-timepicker&gt;
          |
          | &lt;!-- Customized + fixed dropdown button --&gt;
          | &lt;vue-timepicker fixed-dropdown-button&gt;
          |   &lt;template v-slot:dropdownButton&gt;
          |     &lt;img src="$YOUR_BUTTON_IMAGE_SRC" /&gt; 
          |   &lt;/template&gt;
          | &lt;/vue-timepicker&gt;
          |
          | &lt;!-- To display only one button on the right --&gt;
          | &lt;!-- Customized + fixed dropdown button + hide clear button --&gt;
          | &lt;vue-timepicker fixed-dropdown-button hide-clear-button&gt;
          |   &lt;template v-slot:dropdownButton&gt;
          |     &lt;img src="$YOUR_BUTTON_IMAGE_SRC" /&gt; 
          |   &lt;/template&gt;
          | &lt;/vue-timepicker&gt;

    template(v-slot:preview)
      b Default dropdown button
      p
        vue-timepicker(fixed-dropdown-button)
      b Customized + fixed dropdown button
      p
        vue-timepicker(fixed-dropdown-button)
          template(v-slot:dropdownButton)
            img(src="https://i.postimg.cc/CLkZcW46/custom-clock.png")
      b Customized + fixed dropdown button + hide clear button
      p
        vue-timepicker(fixed-dropdown-button hide-clear-button)
          template(v-slot:dropdownButton)
            img(src="https://i.postimg.cc/CLkZcW46/custom-clock.png")

  //- Drop Direction
  sample-block#dropDirection
    template(v-slot:title) Drop Direction
    template(v-slot:description)
      p Change dropdown direction when needed (<code>v1.1.5+</code>).  Accepting values:
      ul
        li
          b down
          | : Default value.
        li
          b up
          | : Force open the dropdown above the input.
        li
          b auto
          | : Auto detects available height and opens the dropdown on top if there are not enough spaces below the input.

    template(v-slot:codes)
      highlight-code(lang="html" data-title="HTML")
        pre
          | &lt;!-- Drop Direction Up --&gt;
          | &lt;vue-timepicker drop-direction="up"&gt;&lt;/vue-timepicker&gt;
          | &nbsp;
          | &lt;!-- Auto Drop Direction --&gt;
          | &lt;div id="auto-dropdown-containter"&gt;
          |   &lt;!-- Defined Container --&gt;
          |   &lt;vue-timepicker drop-direction="auto" container-id="auto-dropdown-containter"&gt;&lt;/vue-timepicker&gt;
          |   &lt;!-- Default (document body) --&gt;
          |   &lt;vue-timepicker drop-direction="auto"&gt;&lt;/vue-timepicker&gt;
          | &lt;/div&gt;
    template(v-slot:preview)
      b Drop Direction Up
      p
        vue-timepicker(drop-direction="up")
      #auto-dropdown-containter
        .demo-title
          b Auto Drop Direction
        .demo-body
          .inner
            b Defined Container
            p
              vue-timepicker(drop-direction="auto" container-id="auto-dropdown-containter")
          .inner
            b Default (document body)
            p
              vue-timepicker(drop-direction="auto")

  //- Footer Links
  .footer-links
    slot(name="footer-links")

  //- Side Nav
  .sidenav
    nav
      ul
        li(v-for="(nav, navIdx) in sideNav" :key="navIdx")
          a(:href="'#' + nav.anchor" v-text="nav.title")
</template>

<style lang="stylus">
@import '../assets/_variables.styl'

section#mostlyUsedSamples
  .section-title
    padding-left: 20%

  .footer-links
    padding: 5em 0 0 20%
    a
      cursor: pointer
    .title
      position: relative
      margin-bottom: 1.5em
      a.anchor
        position: absolute
        left: -1em

    .description
      margin-left: 1.5em

  .sidenav
    position: fixed
    width: 20%
    bottom: 0
    left: 0
    max-height: calc(100vh - 50px)
    overflow-y: auto

    ul
      padding: 0 0 0.5em 1.5em
      margin: 0
      list-style: square

      li
        padding: 0.15em 0
        font-size: 0.8em
        color: alpha($body-color, 0.4)

  // Browser Native Input
  input.native-input
    box-sizing: border-box
    border: 1px solid #d2d2d2
    width: 10em
    height: 2.2em
    padding: 0.3em 0.5em
    font-size: 1em
  
  // Drop Direction Demo
  #auto-dropdown-containter
    margin-top: 1em
    padding: 1em
    background: rgba(0, 0, 0, 0.05)
    border-radius: 5px
    .demo-title
      font-weight: 600
      padding: 0 0 0.5em 0

    .demo-body
      display: flex
      flex-flow: row nowrap
      justify-content: flex-start
      align-items: flex-start
      .inner
        margin-right: 0.5em
      b
        font-weight: normal
</style>


================================================
FILE: demo/src/main.js
================================================
import Vue from 'vue'

import VueHighlightJS from 'vue-highlight.js'
import javascript from 'highlight.js/lib/languages/javascript'
import json from 'highlight.js/lib/languages/json'
import vue from 'vue-highlight.js/lib/languages/vue'
import 'highlight.js/styles/docco.css'

import App from './App.vue'

Vue.config.productionTip = false

/*
* Use Vue Highlight.js
*/
Vue.use(VueHighlightJS, {
  // Register only languages that you want
  languages: {
    javascript,
    json,
    vue
  }
})

new Vue({
  render: h => h(App),
}).$mount('#app')


================================================
FILE: demo/vue.config.js
================================================
module.exports = {
  outputDir: '../gh-pages',
  publicPath: process.env.NODE_ENV === 'production'
    ? '/vue2-timepicker/'
    : '/'
}


================================================
FILE: dist/VueTimepicker.common.js
================================================
module.exports =
/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// create a fake namespace object
/******/ 	// mode & 1: value is a module id, require it
/******/ 	// mode & 2: merge all properties of value into the ns
/******/ 	// mode & 4: return value when already ns object
/******/ 	// mode & 8|1: behave like require
/******/ 	__webpack_require__.t = function(value, mode) {
/******/ 		if(mode & 1) value = __webpack_require__(value);
/******/ 		if(mode & 8) return value;
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ 		var ns = Object.create(null);
/******/ 		__webpack_require__.r(ns);
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ 		return ns;
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = "fb15");
/******/ })
/************************************************************************/
/******/ ({

/***/ "00ee":
/***/ (function(module, exports, __webpack_require__) {

var wellKnownSymbol = __webpack_require__("b622");

var TO_STRING_TAG = wellKnownSymbol('toStringTag');
var test = {};

test[TO_STRING_TAG] = 'z';

module.exports = String(test) === '[object z]';


/***/ }),

/***/ "0366":
/***/ (function(module, exports, __webpack_require__) {

var aFunction = __webpack_require__("1c0b");

// optional / simple context binding
module.exports = function (fn, that, length) {
  aFunction(fn);
  if (that === undefined) return fn;
  switch (length) {
    case 0: return function () {
      return fn.call(that);
    };
    case 1: return function (a) {
      return fn.call(that, a);
    };
    case 2: return function (a, b) {
      return fn.call(that, a, b);
    };
    case 3: return function (a, b, c) {
      return fn.call(that, a, b, c);
    };
  }
  return function (/* ...args */) {
    return fn.apply(that, arguments);
  };
};


/***/ }),

/***/ "057f":
/***/ (function(module, exports, __webpack_require__) {

var toIndexedObject = __webpack_require__("fc6a");
var nativeGetOwnPropertyNames = __webpack_require__("241c").f;

var toString = {}.toString;

var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames
  ? Object.getOwnPropertyNames(window) : [];

var getWindowNames = function (it) {
  try {
    return nativeGetOwnPropertyNames(it);
  } catch (error) {
    return windowNames.slice();
  }
};

// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
module.exports.f = function getOwnPropertyNames(it) {
  return windowNames && toString.call(it) == '[object Window]'
    ? getWindowNames(it)
    : nativeGetOwnPropertyNames(toIndexedObject(it));
};


/***/ }),

/***/ "06cf":
/***/ (function(module, exports, __webpack_require__) {

var DESCRIPTORS = __webpack_require__("83ab");
var propertyIsEnumerableModule = __webpack_require__("d1e7");
var createPropertyDescriptor = __webpack_require__("5c6c");
var toIndexedObject = __webpack_require__("fc6a");
var toPrimitive = __webpack_require__("c04e");
var has = __webpack_require__("5135");
var IE8_DOM_DEFINE = __webpack_require__("0cfb");

var nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;

// `Object.getOwnPropertyDescriptor` method
// https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptor
exports.f = DESCRIPTORS ? nativeGetOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
  O = toIndexedObject(O);
  P = toPrimitive(P, true);
  if (IE8_DOM_DEFINE) try {
    return nativeGetOwnPropertyDescriptor(O, P);
  } catch (error) { /* empty */ }
  if (has(O, P)) return createPropertyDescriptor(!propertyIsEnumerableModule.f.call(O, P), O[P]);
};


/***/ }),

/***/ "0cfb":
/***/ (function(module, exports, __webpack_require__) {

var DESCRIPTORS = __webpack_require__("83ab");
var fails = __webpack_require__("d039");
var createElement = __webpack_require__("cc12");

// Thank's IE8 for his funny defineProperty
module.exports = !DESCRIPTORS && !fails(function () {
  return Object.defineProperty(createElement('div'), 'a', {
    get: function () { return 7; }
  }).a != 7;
});


/***/ }),

/***/ "1276":
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var fixRegExpWellKnownSymbolLogic = __webpack_require__("d784");
var isRegExp = __webpack_require__("44e7");
var anObject = __webpack_require__("825a");
var requireObjectCoercible = __webpack_require__("1d80");
var speciesConstructor = __webpack_require__("4840");
var advanceStringIndex = __webpack_require__("8aa5");
var toLength = __webpack_require__("50c4");
var callRegExpExec = __webpack_require__("14c3");
var regexpExec = __webpack_require__("9263");
var fails = __webpack_require__("d039");

var arrayPush = [].push;
var min = Math.min;
var MAX_UINT32 = 0xFFFFFFFF;

// babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError
var SUPPORTS_Y = !fails(function () { return !RegExp(MAX_UINT32, 'y'); });

// @@split logic
fixRegExpWellKnownSymbolLogic('split', 2, function (SPLIT, nativeSplit, maybeCallNative) {
  var internalSplit;
  if (
    'abbc'.split(/(b)*/)[1] == 'c' ||
    'test'.split(/(?:)/, -1).length != 4 ||
    'ab'.split(/(?:ab)*/).length != 2 ||
    '.'.split(/(.?)(.?)/).length != 4 ||
    '.'.split(/()()/).length > 1 ||
    ''.split(/.?/).length
  ) {
    // based on es5-shim implementation, need to rework it
    internalSplit = function (separator, limit) {
      var string = String(requireObjectCoercible(this));
      var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
      if (lim === 0) return [];
      if (separator === undefined) return [string];
      // If `separator` is not a regex, use native split
      if (!isRegExp(separator)) {
        return nativeSplit.call(string, separator, lim);
      }
      var output = [];
      var flags = (separator.ignoreCase ? 'i' : '') +
                  (separator.multiline ? 'm' : '') +
                  (separator.unicode ? 'u' : '') +
                  (separator.sticky ? 'y' : '');
      var lastLastIndex = 0;
      // Make `global` and avoid `lastIndex` issues by working with a copy
      var separatorCopy = new RegExp(separator.source, flags + 'g');
      var match, lastIndex, lastLength;
      while (match = regexpExec.call(separatorCopy, string)) {
        lastIndex = separatorCopy.lastIndex;
        if (lastIndex > lastLastIndex) {
          output.push(string.slice(lastLastIndex, match.index));
          if (match.length > 1 && match.index < string.length) arrayPush.apply(output, match.slice(1));
          lastLength = match[0].length;
          lastLastIndex = lastIndex;
          if (output.length >= lim) break;
        }
        if (separatorCopy.lastIndex === match.index) separatorCopy.lastIndex++; // Avoid an infinite loop
      }
      if (lastLastIndex === string.length) {
        if (lastLength || !separatorCopy.test('')) output.push('');
      } else output.push(string.slice(lastLastIndex));
      return output.length > lim ? output.slice(0, lim) : output;
    };
  // Chakra, V8
  } else if ('0'.split(undefined, 0).length) {
    internalSplit = function (separator, limit) {
      return separator === undefined && limit === 0 ? [] : nativeSplit.call(this, separator, limit);
    };
  } else internalSplit = nativeSplit;

  return [
    // `String.prototype.split` method
    // https://tc39.github.io/ecma262/#sec-string.prototype.split
    function split(separator, limit) {
      var O = requireObjectCoercible(this);
      var splitter = separator == undefined ? undefined : separator[SPLIT];
      return splitter !== undefined
        ? splitter.call(separator, O, limit)
        : internalSplit.call(String(O), separator, limit);
    },
    // `RegExp.prototype[@@split]` method
    // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@split
    //
    // NOTE: This cannot be properly polyfilled in engines that don't support
    // the 'y' flag.
    function (regexp, limit) {
      var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== nativeSplit);
      if (res.done) return res.value;

      var rx = anObject(regexp);
      var S = String(this);
      var C = speciesConstructor(rx, RegExp);

      var unicodeMatching = rx.unicode;
      var flags = (rx.ignoreCase ? 'i' : '') +
                  (rx.multiline ? 'm' : '') +
                  (rx.unicode ? 'u' : '') +
                  (SUPPORTS_Y ? 'y' : 'g');

      // ^(? + rx + ) is needed, in combination with some S slicing, to
      // simulate the 'y' flag.
      var splitter = new C(SUPPORTS_Y ? rx : '^(?:' + rx.source + ')', flags);
      var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
      if (lim === 0) return [];
      if (S.length === 0) return callRegExpExec(splitter, S) === null ? [S] : [];
      var p = 0;
      var q = 0;
      var A = [];
      while (q < S.length) {
        splitter.lastIndex = SUPPORTS_Y ? q : 0;
        var z = callRegExpExec(splitter, SUPPORTS_Y ? S : S.slice(q));
        var e;
        if (
          z === null ||
          (e = min(toLength(splitter.lastIndex + (SUPPORTS_Y ? 0 : q)), S.length)) === p
        ) {
          q = advanceStringIndex(S, q, unicodeMatching);
        } else {
          A.push(S.slice(p, q));
          if (A.length === lim) return A;
          for (var i = 1; i <= z.length - 1; i++) {
            A.push(z[i]);
            if (A.length === lim) return A;
          }
          q = p = e;
        }
      }
      A.push(S.slice(p));
      return A;
    }
  ];
}, !SUPPORTS_Y);


/***/ }),

/***/ "14c3":
/***/ (function(module, exports, __webpack_require__) {

var classof = __webpack_require__("c6b6");
var regexpExec = __webpack_require__("9263");

// `RegExpExec` abstract operation
// https://tc39.github.io/ecma262/#sec-regexpexec
module.exports = function (R, S) {
  var exec = R.exec;
  if (typeof exec === 'function') {
    var result = exec.call(R, S);
    if (typeof result !== 'object') {
      throw TypeError('RegExp exec method returned something other than an Object or null');
    }
    return result;
  }

  if (classof(R) !== 'RegExp') {
    throw TypeError('RegExp#exec called on incompatible receiver');
  }

  return regexpExec.call(R, S);
};



/***/ }),

/***/ "159b":
/***/ (function(module, exports, __webpack_require__) {

var global = __webpack_require__("da84");
var DOMIterables = __webpack_require__("fdbc");
var forEach = __webpack_require__("17c2");
var createNonEnumerableProperty = __webpack_require__("9112");

for (var COLLECTION_NAME in DOMIterables) {
  var Collection = global[COLLECTION_NAME];
  var CollectionPrototype = Collection && Collection.prototype;
  // some Chrome versions have non-configurable methods on DOMTokenList
  if (CollectionPrototype && CollectionPrototype.forEach !== forEach) try {
    createNonEnumerableProperty(CollectionPrototype, 'forEach', forEach);
  } catch (error) {
    CollectionPrototype.forEach = forEach;
  }
}


/***/ }),

/***/ "17c2":
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $forEach = __webpack_require__("b727").forEach;
var arrayMethodIsStrict = __webpack_require__("a640");
var arrayMethodUsesToLength = __webpack_require__("ae40");

var STRICT_METHOD = arrayMethodIsStrict('forEach');
var USES_TO_LENGTH = arrayMethodUsesToLength('forEach');

// `Array.prototype.forEach` method implementation
// https://tc39.github.io/ecma262/#sec-array.prototype.foreach
module.exports = (!STRICT_METHOD || !USES_TO_LENGTH) ? function forEach(callbackfn /* , thisArg */) {
  return $forEach(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
} : [].forEach;


/***/ }),

/***/ "1be4":
/***/ (function(module, exports, __webpack_require__) {

var getBuiltIn = __webpack_require__("d066");

module.exports = getBuiltIn('document', 'documentElement');


/***/ }),

/***/ "1c0b":
/***/ (function(module, exports) {

module.exports = function (it) {
  if (typeof it != 'function') {
    throw TypeError(String(it) + ' is not a function');
  } return it;
};


/***/ }),

/***/ "1c7e":
/***/ (function(module, exports, __webpack_require__) {

var wellKnownSymbol = __webpack_require__("b622");

var ITERATOR = wellKnownSymbol('iterator');
var SAFE_CLOSING = false;

try {
  var called = 0;
  var iteratorWithReturn = {
    next: function () {
      return { done: !!called++ };
    },
    'return': function () {
      SAFE_CLOSING = true;
    }
  };
  iteratorWithReturn[ITERATOR] = function () {
    return this;
  };
  // eslint-disable-next-line no-throw-literal
  Array.from(iteratorWithReturn, function () { throw 2; });
} catch (error) { /* empty */ }

module.exports = function (exec, SKIP_CLOSING) {
  if (!SKIP_CLOSING && !SAFE_CLOSING) return false;
  var ITERATION_SUPPORT = false;
  try {
    var object = {};
    object[ITERATOR] = function () {
      return {
        next: function () {
          return { done: ITERATION_SUPPORT = true };
        }
      };
    };
    exec(object);
  } catch (error) { /* empty */ }
  return ITERATION_SUPPORT;
};


/***/ }),

/***/ "1d80":
/***/ (function(module, exports) {

// `RequireObjectCoercible` abstract operation
// https://tc39.github.io/ecma262/#sec-requireobjectcoercible
module.exports = function (it) {
  if (it == undefined) throw TypeError("Can't call method on " + it);
  return it;
};


/***/ }),

/***/ "1dde":
/***/ (function(module, exports, __webpack_require__) {

var fails = __webpack_require__("d039");
var wellKnownSymbol = __webpack_require__("b622");
var V8_VERSION = __webpack_require__("2d00");

var SPECIES = wellKnownSymbol('species');

module.exports = function (METHOD_NAME) {
  // We can't use this feature detection in V8 since it causes
  // deoptimization and serious performance degradation
  // https://github.com/zloirock/core-js/issues/677
  return V8_VERSION >= 51 || !fails(function () {
    var array = [];
    var constructor = array.constructor = {};
    constructor[SPECIES] = function () {
      return { foo: 1 };
    };
    return array[METHOD_NAME](Boolean).foo !== 1;
  });
};


/***/ }),

/***/ "23cb":
/***/ (function(module, exports, __webpack_require__) {

var toInteger = __webpack_require__("a691");

var max = Math.max;
var min = Math.min;

// Helper for a popular repeating case of the spec:
// Let integer be ? ToInteger(index).
// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).
module.exports = function (index, length) {
  var integer = toInteger(index);
  return integer < 0 ? max(integer + length, 0) : min(integer, length);
};


/***/ }),

/***/ "23e7":
/***/ (function(module, exports, __webpack_require__) {

var global = __webpack_require__("da84");
var getOwnPropertyDescriptor = __webpack_require__("06cf").f;
var createNonEnumerableProperty = __webpack_require__("9112");
var redefine = __webpack_require__("6eeb");
var setGlobal = __webpack_require__("ce4e");
var copyConstructorProperties = __webpack_require__("e893");
var isForced = __webpack_require__("94ca");

/*
  options.target      - name of the target object
  options.global      - target is the global object
  options.stat        - export as static methods of target
  options.proto       - export as prototype methods of target
  options.real        - real prototype method for the `pure` version
  options.forced      - export even if the native feature is available
  options.bind        - bind methods to the target, required for the `pure` version
  options.wrap        - wrap constructors to preventing global pollution, required for the `pure` version
  options.unsafe      - use the simple assignment of property instead of delete + defineProperty
  options.sham        - add a flag to not completely full polyfills
  options.enumerable  - export as enumerable property
  options.noTargetGet - prevent calling a getter on target
*/
module.exports = function (options, source) {
  var TARGET = options.target;
  var GLOBAL = options.global;
  var STATIC = options.stat;
  var FORCED, target, key, targetProperty, sourceProperty, descriptor;
  if (GLOBAL) {
    target = global;
  } else if (STATIC) {
    target = global[TARGET] || setGlobal(TARGET, {});
  } else {
    target = (global[TARGET] || {}).prototype;
  }
  if (target) for (key in source) {
    sourceProperty = source[key];
    if (options.noTargetGet) {
      descriptor = getOwnPropertyDescriptor(target, key);
      targetProperty = descriptor && descriptor.value;
    } else targetProperty = target[key];
    FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
    // contained in target
    if (!FORCED && targetProperty !== undefined) {
      if (typeof sourceProperty === typeof targetProperty) continue;
      copyConstructorProperties(sourceProperty, targetProperty);
    }
    // add a flag to not completely full polyfills
    if (options.sham || (targetProperty && targetProperty.sham)) {
      createNonEnumerableProperty(sourceProperty, 'sham', true);
    }
    // extend global
    redefine(target, key, sourceProperty, options);
  }
};


/***/ }),

/***/ "241c":
/***/ (function(module, exports, __webpack_require__) {

var internalObjectKeys = __webpack_require__("ca84");
var enumBugKeys = __webpack_require__("7839");

var hiddenKeys = enumBugKeys.concat('length', 'prototype');

// `Object.getOwnPropertyNames` method
// https://tc39.github.io/ecma262/#sec-object.getownpropertynames
exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
  return internalObjectKeys(O, hiddenKeys);
};


/***/ }),

/***/ "2532":
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $ = __webpack_require__("23e7");
var notARegExp = __webpack_require__("5a34");
var requireObjectCoercible = __webpack_require__("1d80");
var correctIsRegExpLogic = __webpack_require__("ab13");

// `String.prototype.includes` method
// https://tc39.github.io/ecma262/#sec-string.prototype.includes
$({ target: 'String', proto: true, forced: !correctIsRegExpLogic('includes') }, {
  includes: function includes(searchString /* , position = 0 */) {
    return !!~String(requireObjectCoercible(this))
      .indexOf(notARegExp(searchString), arguments.length > 1 ? arguments[1] : undefined);
  }
});


/***/ }),

/***/ "25f0":
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var redefine = __webpack_require__("6eeb");
var anObject = __webpack_require__("825a");
var fails = __webpack_require__("d039");
var flags = __webpack_require__("ad6d");

var TO_STRING = 'toString';
var RegExpPrototype = RegExp.prototype;
var nativeToString = RegExpPrototype[TO_STRING];

var NOT_GENERIC = fails(function () { return nativeToString.call({ source: 'a', flags: 'b' }) != '/a/b'; });
// FF44- RegExp#toString has a wrong name
var INCORRECT_NAME = nativeToString.name != TO_STRING;

// `RegExp.prototype.toString` method
// https://tc39.github.io/ecma262/#sec-regexp.prototype.tostring
if (NOT_GENERIC || INCORRECT_NAME) {
  redefine(RegExp.prototype, TO_STRING, function toString() {
    var R = anObject(this);
    var p = String(R.source);
    var rf = R.flags;
    var f = String(rf === undefined && R instanceof RegExp && !('flags' in RegExpPrototype) ? flags.call(R) : rf);
    return '/' + p + '/' + f;
  }, { unsafe: true });
}


/***/ }),

/***/ "2626":
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var getBuiltIn = __webpack_require__("d066");
var definePropertyModule = __webpack_require__("9bf2");
var wellKnownSymbol = __webpack_require__("b622");
var DESCRIPTORS = __webpack_require__("83ab");

var SPECIES = wellKnownSymbol('species');

module.exports = function (CONSTRUCTOR_NAME) {
  var Constructor = getBuiltIn(CONSTRUCTOR_NAME);
  var defineProperty = definePropertyModule.f;

  if (DESCRIPTORS && Constructor && !Constructor[SPECIES]) {
    defineProperty(Constructor, SPECIES, {
      configurable: true,
      get: function () { return this; }
    });
  }
};


/***/ }),

/***/ "2d00":
/***/ (function(module, exports, __webpack_require__) {

var global = __webpack_require__("da84");
var userAgent = __webpack_require__("342f");

var process = global.process;
var versions = process && process.versions;
var v8 = versions && versions.v8;
var match, version;

if (v8) {
  match = v8.split('.');
  version = match[0] + match[1];
} else if (userAgent) {
  match = userAgent.match(/Edge\/(\d+)/);
  if (!match || match[1] >= 74) {
    match = userAgent.match(/Chrome\/(\d+)/);
    if (match) version = match[1];
  }
}

module.exports = version && +version;


/***/ }),

/***/ "342f":
/***/ (function(module, exports, __webpack_require__) {

var getBuiltIn = __webpack_require__("d066");

module.exports = getBuiltIn('navigator', 'userAgent') || '';


/***/ }),

/***/ "35a1":
/***/ (function(module, exports, __webpack_require__) {

var classof = __webpack_require__("f5df");
var Iterators = __webpack_require__("3f8c");
var wellKnownSymbol = __webpack_require__("b622");

var ITERATOR = wellKnownSymbol('iterator');

module.exports = function (it) {
  if (it != undefined) return it[ITERATOR]
    || it['@@iterator']
    || Iterators[classof(it)];
};


/***/ }),

/***/ "37e8":
/***/ (function(module, exports, __webpack_require__) {

var DESCRIPTORS = __webpack_require__("83ab");
var definePropertyModule = __webpack_require__("9bf2");
var anObject = __webpack_require__("825a");
var objectKeys = __webpack_require__("df75");

// `Object.defineProperties` method
// https://tc39.github.io/ecma262/#sec-object.defineproperties
module.exports = DESCRIPTORS ? Object.defineProperties : function defineProperties(O, Properties) {
  anObject(O);
  var keys = objectKeys(Properties);
  var length = keys.length;
  var index = 0;
  var key;
  while (length > index) definePropertyModule.f(O, key = keys[index++], Properties[key]);
  return O;
};


/***/ }),

/***/ "3bbe":
/***/ (function(module, exports, __webpack_require__) {

var isObject = __webpack_require__("861d");

module.exports = function (it) {
  if (!isObject(it) && it !== null) {
    throw TypeError("Can't set " + String(it) + ' as a prototype');
  } return it;
};


/***/ }),

/***/ "3ca3":
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var charAt = __webpack_require__("6547").charAt;
var InternalStateModule = __webpack_require__("69f3");
var defineIterator = __webpack_require__("7dd0");

var STRING_ITERATOR = 'String Iterator';
var setInternalState = InternalStateModule.set;
var getInternalState = InternalStateModule.getterFor(STRING_ITERATOR);

// `String.prototype[@@iterator]` method
// https://tc39.github.io/ecma262/#sec-string.prototype-@@iterator
defineIterator(String, 'String', function (iterated) {
  setInternalState(this, {
    type: STRING_ITERATOR,
    string: String(iterated),
    index: 0
  });
// `%StringIteratorPrototype%.next` method
// https://tc39.github.io/ecma262/#sec-%stringiteratorprototype%.next
}, function next() {
  var state = getInternalState(this);
  var string = state.string;
  var index = state.index;
  var point;
  if (index >= string.length) return { value: undefined, done: true };
  point = charAt(string, index);
  state.index += point.length;
  return { value: point, done: false };
});


/***/ }),

/***/ "3f8c":
/***/ (function(module, exports) {

module.exports = {};


/***/ }),

/***/ "4160":
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $ = __webpack_require__("23e7");
var forEach = __webpack_require__("17c2");

// `Array.prototype.forEach` method
// https://tc39.github.io/ecma262/#sec-array.prototype.foreach
$({ target: 'Array', proto: true, forced: [].forEach != forEach }, {
  forEach: forEach
});


/***/ }),

/***/ "428f":
/***/ (function(module, exports, __webpack_require__) {

var global = __webpack_require__("da84");

module.exports = global;


/***/ }),

/***/ "44ad":
/***/ (function(module, exports, __webpack_require__) {

var fails = __webpack_require__("d039");
var classof = __webpack_require__("c6b6");

var split = ''.split;

// fallback for non-array-like ES3 and non-enumerable old V8 strings
module.exports = fails(function () {
  // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
  // eslint-disable-next-line no-prototype-builtins
  return !Object('z').propertyIsEnumerable(0);
}) ? function (it) {
  return classof(it) == 'String' ? split.call(it, '') : Object(it);
} : Object;


/***/ }),

/***/ "44d2":
/***/ (function(module, exports, __webpack_require__) {

var wellKnownSymbol = __webpack_require__("b622");
var create = __webpack_require__("7c73");
var definePropertyModule = __webpack_require__("9bf2");

var UNSCOPABLES = wellKnownSymbol('unscopables');
var ArrayPrototype = Array.prototype;

// Array.prototype[@@unscopables]
// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
if (ArrayPrototype[UNSCOPABLES] == undefined) {
  definePropertyModule.f(ArrayPrototype, UNSCOPABLES, {
    configurable: true,
    value: create(null)
  });
}

// add a key to Array.prototype[@@unscopables]
module.exports = function (key) {
  ArrayPrototype[UNSCOPABLES][key] = true;
};


/***/ }),

/***/ "44e7":
/***/ (function(module, exports, __webpack_require__) {

var isObject = __webpack_require__("861d");
var classof = __webpack_require__("c6b6");
var wellKnownSymbol = __webpack_require__("b622");

var MATCH = wellKnownSymbol('match');

// `IsRegExp` abstract operation
// https://tc39.github.io/ecma262/#sec-isregexp
module.exports = function (it) {
  var isRegExp;
  return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : classof(it) == 'RegExp');
};


/***/ }),

/***/ "45fc":
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $ = __webpack_require__("23e7");
var $some = __webpack_require__("b727").some;
var arrayMethodIsStrict = __webpack_require__("a640");
var arrayMethodUsesToLength = __webpack_require__("ae40");

var STRICT_METHOD = arrayMethodIsStrict('some');
var USES_TO_LENGTH = arrayMethodUsesToLength('some');

// `Array.prototype.some` method
// https://tc39.github.io/ecma262/#sec-array.prototype.some
$({ target: 'Array', proto: true, forced: !STRICT_METHOD || !USES_TO_LENGTH }, {
  some: function some(callbackfn /* , thisArg */) {
    return $some(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
  }
});


/***/ }),

/***/ "466d":
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var fixRegExpWellKnownSymbolLogic = __webpack_require__("d784");
var anObject = __webpack_require__("825a");
var toLength = __webpack_require__("50c4");
var requireObjectCoercible = __webpack_require__("1d80");
var advanceStringIndex = __webpack_require__("8aa5");
var regExpExec = __webpack_require__("14c3");

// @@match logic
fixRegExpWellKnownSymbolLogic('match', 1, function (MATCH, nativeMatch, maybeCallNative) {
  return [
    // `String.prototype.match` method
    // https://tc39.github.io/ecma262/#sec-string.prototype.match
    function match(regexp) {
      var O = requireObjectCoercible(this);
      var matcher = regexp == undefined ? undefined : regexp[MATCH];
      return matcher !== undefined ? matcher.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
    },
    // `RegExp.prototype[@@match]` method
    // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@match
    function (regexp) {
      var res = maybeCallNative(nativeMatch, regexp, this);
      if (res.done) return res.value;

      var rx = anObject(regexp);
      var S = String(this);

      if (!rx.global) return regExpExec(rx, S);

      var fullUnicode = rx.unicode;
      rx.lastIndex = 0;
      var A = [];
      var n = 0;
      var result;
      while ((result = regExpExec(rx, S)) !== null) {
        var matchStr = String(result[0]);
        A[n] = matchStr;
        if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
        n++;
      }
      return n === 0 ? null : A;
    }
  ];
});


/***/ }),

/***/ "4840":
/***/ (function(module, exports, __webpack_require__) {

var anObject = __webpack_require__("825a");
var aFunction = __webpack_require__("1c0b");
var wellKnownSymbol = __webpack_require__("b622");

var SPECIES = wellKnownSymbol('species');

// `SpeciesConstructor` abstract operation
// https://tc39.github.io/ecma262/#sec-speciesconstructor
module.exports = function (O, defaultConstructor) {
  var C = anObject(O).constructor;
  var S;
  return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? defaultConstructor : aFunction(S);
};


/***/ }),

/***/ "4930":
/***/ (function(module, exports, __webpack_require__) {

var fails = __webpack_require__("d039");

module.exports = !!Object.getOwnPropertySymbols && !fails(function () {
  // Chrome 38 Symbol has incorrect toString conversion
  // eslint-disable-next-line no-undef
  return !String(Symbol());
});


/***/ }),

/***/ "498a":
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $ = __webpack_require__("23e7");
var $trim = __webpack_require__("58a8").trim;
var forcedStringTrimMethod = __webpack_require__("c8d2");

// `String.prototype.trim` method
// https://tc39.github.io/ecma262/#sec-string.prototype.trim
$({ target: 'String', proto: true, forced: forcedStringTrimMethod('trim') }, {
  trim: function trim() {
    return $trim(this);
  }
});


/***/ }),

/***/ "4d63":
/***/ (function(module, exports, __webpack_require__) {

var DESCRIPTORS = __webpack_require__("83ab");
var global = __webpack_require__("da84");
var isForced = __webpack_require__("94ca");
var inheritIfRequired = __webpack_require__("7156");
var defineProperty = __webpack_require__("9bf2").f;
var getOwnPropertyNames = __webpack_require__("241c").f;
var isRegExp = __webpack_require__("44e7");
var getFlags = __webpack_require__("ad6d");
var stickyHelpers = __webpack_require__("9f7f");
var redefine = __webpack_require__("6eeb");
var fails = __webpack_require__("d039");
var setInternalState = __webpack_require__("69f3").set;
var setSpecies = __webpack_require__("2626");
var wellKnownSymbol = __webpack_require__("b622");

var MATCH = wellKnownSymbol('match');
var NativeRegExp = global.RegExp;
var RegExpPrototype = NativeRegExp.prototype;
var re1 = /a/g;
var re2 = /a/g;

// "new" should create a new object, old webkit bug
var CORRECT_NEW = new NativeRegExp(re1) !== re1;

var UNSUPPORTED_Y = stickyHelpers.UNSUPPORTED_Y;

var FORCED = DESCRIPTORS && isForced('RegExp', (!CORRECT_NEW || UNSUPPORTED_Y || fails(function () {
  re2[MATCH] = false;
  // RegExp constructor can alter flags and IsRegExp works correct with @@match
  return NativeRegExp(re1) != re1 || NativeRegExp(re2) == re2 || NativeRegExp(re1, 'i') != '/a/i';
})));

// `RegExp` constructor
// https://tc39.github.io/ecma262/#sec-regexp-constructor
if (FORCED) {
  var RegExpWrapper = function RegExp(pattern, flags) {
    var thisIsRegExp = this instanceof RegExpWrapper;
    var patternIsRegExp = isRegExp(pattern);
    var flagsAreUndefined = flags === undefined;
    var sticky;

    if (!thisIsRegExp && patternIsRegExp && pattern.constructor === RegExpWrapper && flagsAreUndefined) {
      return pattern;
    }

    if (CORRECT_NEW) {
      if (patternIsRegExp && !flagsAreUndefined) pattern = pattern.source;
    } else if (pattern instanceof RegExpWrapper) {
      if (flagsAreUndefined) flags = getFlags.call(pattern);
      pattern = pattern.source;
    }

    if (UNSUPPORTED_Y) {
      sticky = !!flags && flags.indexOf('y') > -1;
      if (sticky) flags = flags.replace(/y/g, '');
    }

    var result = inheritIfRequired(
      CORRECT_NEW ? new NativeRegExp(pattern, flags) : NativeRegExp(pattern, flags),
      thisIsRegExp ? this : RegExpPrototype,
      RegExpWrapper
    );

    if (UNSUPPORTED_Y && sticky) setInternalState(result, { sticky: sticky });

    return result;
  };
  var proxy = function (key) {
    key in RegExpWrapper || defineProperty(RegExpWrapper, key, {
      configurable: true,
      get: function () { return NativeRegExp[key]; },
      set: function (it) { NativeRegExp[key] = it; }
    });
  };
  var keys = getOwnPropertyNames(NativeRegExp);
  var index = 0;
  while (keys.length > index) proxy(keys[index++]);
  RegExpPrototype.constructor = RegExpWrapper;
  RegExpWrapper.prototype = RegExpPrototype;
  redefine(global, 'RegExp', RegExpWrapper);
}

// https://tc39.github.io/ecma262/#sec-get-regexp-@@species
setSpecies('RegExp');


/***/ }),

/***/ "4d64":
/***/ (function(module, exports, __webpack_require__) {

var toIndexedObject = __webpack_require__("fc6a");
var toLength = __webpack_require__("50c4");
var toAbsoluteIndex = __webpack_require__("23cb");

// `Array.prototype.{ indexOf, includes }` methods implementation
var createMethod = function (IS_INCLUDES) {
  return function ($this, el, fromIndex) {
    var O = toIndexedObject($this);
    var length = toLength(O.length);
    var index = toAbsoluteIndex(fromIndex, length);
    var value;
    // Array#includes uses SameValueZero equality algorithm
    // eslint-disable-next-line no-self-compare
    if (IS_INCLUDES && el != el) while (length > index) {
      value = O[index++];
      // eslint-disable-next-line no-self-compare
      if (value != value) return true;
    // Array#indexOf ignores holes, Array#includes - not
    } else for (;length > index; index++) {
      if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
    } return !IS_INCLUDES && -1;
  };
};

module.exports = {
  // `Array.prototype.includes` method
  // https://tc39.github.io/ecma262/#sec-array.prototype.includes
  includes: createMethod(true),
  // `Array.prototype.indexOf` method
  // https://tc39.github.io/ecma262/#sec-array.prototype.indexof
  indexOf: createMethod(false)
};


/***/ }),

/***/ "4de4":
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $ = __webpack_require__("23e7");
var $filter = __webpack_require__("b727").filter;
var arrayMethodHasSpeciesSupport = __webpack_require__("1dde");
var arrayMethodUsesToLength = __webpack_require__("ae40");

var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('filter');
// Edge 14- issue
var USES_TO_LENGTH = arrayMethodUsesToLength('filter');

// `Array.prototype.filter` method
// https://tc39.github.io/ecma262/#sec-array.prototype.filter
// with adding support of @@species
$({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT || !USES_TO_LENGTH }, {
  filter: function filter(callbackfn /* , thisArg */) {
    return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
  }
});


/***/ }),

/***/ "4df4":
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var bind = __webpack_require__("0366");
var toObject = __webpack_require__("7b0b");
var callWithSafeIterationClosing = __webpack_require__("9bdd");
var isArrayIteratorMethod = __webpack_require__("e95a");
var toLength = __webpack_require__("50c4");
var createProperty = __webpack_require__("8418");
var getIteratorMethod = __webpack_require__("35a1");

// `Array.from` method implementation
// https://tc39.github.io/ecma262/#sec-array.from
module.exports = function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {
  var O = toObject(arrayLike);
  var C = typeof this == 'function' ? this : Array;
  var argumentsLength = arguments.length;
  var mapfn = argumentsLength > 1 ? arguments[1] : undefined;
  var mapping = mapfn !== undefined;
  var iteratorMethod = getIteratorMethod(O);
  var index = 0;
  var length, result, step, iterator, next, value;
  if (mapping) mapfn = bind(mapfn, argumentsLength > 2 ? arguments[2] : undefined, 2);
  // if the target is not iterable or it's an array with the default iterator - use a simple case
  if (iteratorMethod != undefined && !(C == Array && isArrayIteratorMethod(iteratorMethod))) {
    iterator = iteratorMethod.call(O);
    next = iterator.next;
    result = new C();
    for (;!(step = next.call(iterator)).done; index++) {
      value = mapping ? callWithSafeIterationClosing(iterator, mapfn, [step.value, index], true) : step.value;
      createProperty(result, index, value);
    }
  } else {
    length = toLength(O.length);
    result = new C(length);
    for (;length > index; index++) {
      value = mapping ? mapfn(O[index], index) : O[index];
      createProperty(result, index, value);
    }
  }
  result.length = index;
  return result;
};


/***/ }),

/***/ "50c4":
/***/ (function(module, exports, __webpack_require__) {

var toInteger = __webpack_require__("a691");

var min = Math.min;

// `ToLength` abstract operation
// https://tc39.github.io/ecma262/#sec-tolength
module.exports = function (argument) {
  return argument > 0 ? min(toInteger(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
};


/***/ }),

/***/ "5135":
/***/ (function(module, exports) {

var hasOwnProperty = {}.hasOwnProperty;

module.exports = function (it, key) {
  return hasOwnProperty.call(it, key);
};


/***/ }),

/***/ "5319":
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var fixRegExpWellKnownSymbolLogic = __webpack_require__("d784");
var anObject = __webpack_require__("825a");
var toObject = __webpack_require__("7b0b");
var toLength = __webpack_require__("50c4");
var toInteger = __webpack_require__("a691");
var requireObjectCoercible = __webpack_require__("1d80");
var advanceStringIndex = __webpack_require__("8aa5");
var regExpExec = __webpack_require__("14c3");

var max = Math.max;
var min = Math.min;
var floor = Math.floor;
var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d\d?|<[^>]*>)/g;
var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d\d?)/g;

var maybeToString = function (it) {
  return it === undefined ? it : String(it);
};

// @@replace logic
fixRegExpWellKnownSymbolLogic('replace', 2, function (REPLACE, nativeReplace, maybeCallNative, reason) {
  var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = reason.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE;
  var REPLACE_KEEPS_$0 = reason.REPLACE_KEEPS_$0;
  var UNSAFE_SUBSTITUTE = REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE ? '$' : '$0';

  return [
    // `String.prototype.replace` method
    // https://tc39.github.io/ecma262/#sec-string.prototype.replace
    function replace(searchValue, replaceValue) {
      var O = requireObjectCoercible(this);
      var replacer = searchValue == undefined ? undefined : searchValue[REPLACE];
      return replacer !== undefined
        ? replacer.call(searchValue, O, replaceValue)
        : nativeReplace.call(String(O), searchValue, replaceValue);
    },
    // `RegExp.prototype[@@replace]` method
    // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace
    function (regexp, replaceValue) {
      if (
        (!REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE && REPLACE_KEEPS_$0) ||
        (typeof replaceValue === 'string' && replaceValue.indexOf(UNSAFE_SUBSTITUTE) === -1)
      ) {
        var res = maybeCallNative(nativeReplace, regexp, this, replaceValue);
        if (res.done) return res.value;
      }

      var rx = anObject(regexp);
      var S = String(this);

      var functionalReplace = typeof replaceValue === 'function';
      if (!functionalReplace) replaceValue = String(replaceValue);

      var global = rx.global;
      if (global) {
        var fullUnicode = rx.unicode;
        rx.lastIndex = 0;
      }
      var results = [];
      while (true) {
        var result = regExpExec(rx, S);
        if (result === null) break;

        results.push(result);
        if (!global) break;

        var matchStr = String(result[0]);
        if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
      }

      var accumulatedResult = '';
      var nextSourcePosition = 0;
      for (var i = 0; i < results.length; i++) {
        result = results[i];

        var matched = String(result[0]);
        var position = max(min(toInteger(result.index), S.length), 0);
        var captures = [];
        // NOTE: This is equivalent to
        //   captures = result.slice(1).map(maybeToString)
        // but for some reason `nativeSlice.call(result, 1, result.length)` (called in
        // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and
        // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.
        for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));
        var namedCaptures = result.groups;
        if (functionalReplace) {
          var replacerArgs = [matched].concat(captures, position, S);
          if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
          var replacement = String(replaceValue.apply(undefined, replacerArgs));
        } else {
          replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
        }
        if (position >= nextSourcePosition) {
          accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
          nextSourcePosition = position + matched.length;
        }
      }
      return accumulatedResult + S.slice(nextSourcePosition);
    }
  ];

  // https://tc39.github.io/ecma262/#sec-getsubstitution
  function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {
    var tailPos = position + matched.length;
    var m = captures.length;
    var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
    if (namedCaptures !== undefined) {
      namedCaptures = toObject(namedCaptures);
      symbols = SUBSTITUTION_SYMBOLS;
    }
    return nativeReplace.call(replacement, symbols, function (match, ch) {
      var capture;
      switch (ch.charAt(0)) {
        case '$': return '$';
        case '&': return matched;
        case '`': return str.slice(0, position);
        case "'": return str.slice(tailPos);
        case '<':
          capture = namedCaptures[ch.slice(1, -1)];
          break;
        default: // \d\d?
          var n = +ch;
          if (n === 0) return match;
          if (n > m) {
            var f = floor(n / 10);
            if (f === 0) return match;
            if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
            return match;
          }
          capture = captures[n - 1];
      }
      return capture === undefined ? '' : capture;
    });
  }
});


/***/ }),

/***/ "5692":
/***/ (function(module, exports, __webpack_require__) {

var IS_PURE = __webpack_require__("c430");
var store = __webpack_require__("c6cd");

(module.exports = function (key, value) {
  return store[key] || (store[key] = value !== undefined ? value : {});
})('versions', []).push({
  version: '3.6.5',
  mode: IS_PURE ? 'pure' : 'global',
  copyright: '© 2020 Denis Pushkarev (zloirock.ru)'
});


/***/ }),

/***/ "56ef":
/***/ (function(module, exports, __webpack_require__) {

var getBuiltIn = __webpack_require__("d066");
var getOwnPropertyNamesModule = __webpack_require__("241c");
var getOwnPropertySymbolsModule = __webpack_require__("7418");
var anObject = __webpack_require__("825a");

// all object keys, includes non-enumerable and symbols
module.exports = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {
  var keys = getOwnPropertyNamesModule.f(anObject(it));
  var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;
  return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;
};


/***/ }),

/***/ "5899":
/***/ (function(module, exports) {

// a string of all valid unicode whitespaces
// eslint-disable-next-line max-len
module.exports = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';


/***/ }),

/***/ "58a8":
/***/ (function(module, exports, __webpack_require__) {

var requireObjectCoercible = __webpack_require__("1d80");
var whitespaces = __webpack_require__("5899");

var whitespace = '[' + whitespaces + ']';
var ltrim = RegExp('^' + whitespace + whitespace + '*');
var rtrim = RegExp(whitespace + whitespace + '*$');

// `String.prototype.{ trim, trimStart, trimEnd, trimLeft, trimRight }` methods implementation
var createMethod = function (TYPE) {
  return function ($this) {
    var string = String(requireObjectCoercible($this));
    if (TYPE & 1) string = string.replace(ltrim, '');
    if (TYPE & 2) string = string.replace(rtrim, '');
    return string;
  };
};

module.exports = {
  // `String.prototype.{ trimLeft, trimStart }` methods
  // https://tc39.github.io/ecma262/#sec-string.prototype.trimstart
  start: createMethod(1),
  // `String.prototype.{ trimRight, trimEnd }` methods
  // https://tc39.github.io/ecma262/#sec-string.prototype.trimend
  end: createMethod(2),
  // `String.prototype.trim` method
  // https://tc39.github.io/ecma262/#sec-string.prototype.trim
  trim: createMethod(3)
};


/***/ }),

/***/ "5a34":
/***/ (function(module, exports, __webpack_require__) {

var isRegExp = __webpack_require__("44e7");

module.exports = function (it) {
  if (isRegExp(it)) {
    throw TypeError("The method doesn't accept regular expressions");
  } return it;
};


/***/ }),

/***/ "5c6c":
/***/ (function(module, exports) {

module.exports = function (bitmap, value) {
  return {
    enumerable: !(bitmap & 1),
    configurable: !(bitmap & 2),
    writable: !(bitmap & 4),
    value: value
  };
};


/***/ }),

/***/ "60da":
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var DESCRIPTORS = __webpack_require__("83ab");
var fails = __webpack_require__("d039");
var objectKeys = __webpack_require__("df75");
var getOwnPropertySymbolsModule = __webpack_require__("7418");
var propertyIsEnumerableModule = __webpack_require__("d1e7");
var toObject = __webpack_require__("7b0b");
var IndexedObject = __webpack_require__("44ad");

var nativeAssign = Object.assign;
var defineProperty = Object.defineProperty;

// `Object.assign` method
// https://tc39.github.io/ecma262/#sec-object.assign
module.exports = !nativeAssign || fails(function () {
  // should have correct order of operations (Edge bug)
  if (DESCRIPTORS && nativeAssign({ b: 1 }, nativeAssign(defineProperty({}, 'a', {
    enumerable: true,
    get: function () {
      defineProperty(this, 'b', {
        value: 3,
        enumerable: false
      });
    }
  }), { b: 2 })).b !== 1) return true;
  // should work with symbols and should have deterministic property order (V8 bug)
  var A = {};
  var B = {};
  // eslint-disable-next-line no-undef
  var symbol = Symbol();
  var alphabet = 'abcdefghijklmnopqrst';
  A[symbol] = 7;
  alphabet.split('').forEach(function (chr) { B[chr] = chr; });
  return nativeAssign({}, A)[symbol] != 7 || objectKeys(nativeAssign({}, B)).join('') != alphabet;
}) ? function assign(target, source) { // eslint-disable-line no-unused-vars
  var T = toObject(target);
  var argumentsLength = arguments.length;
  var index = 1;
  var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;
  var propertyIsEnumerable = propertyIsEnumerableModule.f;
  while (argumentsLength > index) {
    var S = IndexedObject(arguments[index++]);
    var keys = getOwnPropertySymbols ? objectKeys(S).concat(getOwnPropertySymbols(S)) : objectKeys(S);
    var length = keys.length;
    var j = 0;
    var key;
    while (length > j) {
      key = keys[j++];
      if (!DESCRIPTORS || propertyIsEnumerable.call(S, key)) T[key] = S[key];
    }
  } return T;
} : nativeAssign;


/***/ }),

/***/ "6547":
/***/ (function(module, exports, __webpack_require__) {

var toInteger = __webpack_require__("a691");
var requireObjectCoercible = __webpack_require__("1d80");

// `String.prototype.{ codePointAt, at }` methods implementation
var createMethod = function (CONVERT_TO_STRING) {
  return function ($this, pos) {
    var S = String(requireObjectCoercible($this));
    var position = toInteger(pos);
    var size = S.length;
    var first, second;
    if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined;
    first = S.charCodeAt(position);
    return first < 0xD800 || first > 0xDBFF || position + 1 === size
      || (second = S.charCodeAt(position + 1)) < 0xDC00 || second > 0xDFFF
        ? CONVERT_TO_STRING ? S.charAt(position) : first
        : CONVERT_TO_STRING ? S.slice(position, position + 2) : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;
  };
};

module.exports = {
  // `String.prototype.codePointAt` method
  // https://tc39.github.io/ecma262/#sec-string.prototype.codepointat
  codeAt: createMethod(false),
  // `String.prototype.at` method
  // https://github.com/mathiasbynens/String.prototype.at
  charAt: createMethod(true)
};


/***/ }),

/***/ "65f0":
/***/ (function(module, exports, __webpack_require__) {

var isObject = __webpack_require__("861d");
var isArray = __webpack_require__("e8b5");
var wellKnownSymbol = __webpack_require__("b622");

var SPECIES = wellKnownSymbol('species');

// `ArraySpeciesCreate` abstract operation
// https://tc39.github.io/ecma262/#sec-arrayspeciescreate
module.exports = function (originalArray, length) {
  var C;
  if (isArray(originalArray)) {
    C = originalArray.constructor;
    // cross-realm fallback
    if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
    else if (isObject(C)) {
      C = C[SPECIES];
      if (C === null) C = undefined;
    }
  } return new (C === undefined ? Array : C)(length === 0 ? 0 : length);
};


/***/ }),

/***/ "69f3":
/***/ (function(module, exports, __webpack_require__) {

var NATIVE_WEAK_MAP = __webpack_require__("7f9a");
var global = __webpack_require__("da84");
var isObject = __webpack_require__("861d");
var createNonEnumerableProperty = __webpack_require__("9112");
var objectHas = __webpack_require__("5135");
var sharedKey = __webpack_require__("f772");
var hiddenKeys = __webpack_require__("d012");

var WeakMap = global.WeakMap;
var set, get, has;

var enforce = function (it) {
  return has(it) ? get(it) : set(it, {});
};

var getterFor = function (TYPE) {
  return function (it) {
    var state;
    if (!isObject(it) || (state = get(it)).type !== TYPE) {
      throw TypeError('Incompatible receiver, ' + TYPE + ' required');
    } return state;
  };
};

if (NATIVE_WEAK_MAP) {
  var store = new WeakMap();
  var wmget = store.get;
  var wmhas = store.has;
  var wmset = store.set;
  set = function (it, metadata) {
    wmset.call(store, it, metadata);
    return metadata;
  };
  get = function (it) {
    return wmget.call(store, it) || {};
  };
  has = function (it) {
    return wmhas.call(store, it);
  };
} else {
  var STATE = sharedKey('state');
  hiddenKeys[STATE] = true;
  set = function (it, metadata) {
    createNonEnumerableProperty(it, STATE, metadata);
    return metadata;
  };
  get = function (it) {
    return objectHas(it, STATE) ? it[STATE] : {};
  };
  has = function (it) {
    return objectHas(it, STATE);
  };
}

module.exports = {
  set: set,
  get: get,
  has: has,
  enforce: enforce,
  getterFor: getterFor
};


/***/ }),

/***/ "6eeb":
/***/ (function(module, exports, __webpack_require__) {

var global = __webpack_require__("da84");
var createNonEnumerableProperty = __webpack_require__("9112");
var has = __webpack_require__("5135");
var setGlobal = __webpack_require__("ce4e");
var inspectSource = __webpack_require__("8925");
var InternalStateModule = __webpack_require__("69f3");

var getInternalState = InternalStateModule.get;
var enforceInternalState = InternalStateModule.enforce;
var TEMPLATE = String(String).split('String');

(module.exports = function (O, key, value, options) {
  var unsafe = options ? !!options.unsafe : false;
  var simple = options ? !!options.enumerable : false;
  var noTargetGet = options ? !!options.noTargetGet : false;
  if (typeof value == 'function') {
    if (typeof key == 'string' && !has(value, 'name')) createNonEnumerableProperty(value, 'name', key);
    enforceInternalState(value).source = TEMPLATE.join(typeof key == 'string' ? key : '');
  }
  if (O === global) {
    if (simple) O[key] = value;
    else setGlobal(key, value);
    return;
  } else if (!unsafe) {
    delete O[key];
  } else if (!noTargetGet && O[key]) {
    simple = true;
  }
  if (simple) O[key] = value;
  else createNonEnumerableProperty(O, key, value);
// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
})(Function.prototype, 'toString', function toString() {
  return typeof this == 'function' && getInternalState(this).source || inspectSource(this);
});


/***/ }),

/***/ "7156":
/***/ (function(module, exports, __webpack_require__) {

var isObject = __webpack_require__("861d");
var setPrototypeOf = __webpack_require__("d2bb");

// makes subclassing work correct for wrapped built-ins
module.exports = function ($this, dummy, Wrapper) {
  var NewTarget, NewTargetPrototype;
  if (
    // it can work only with native `setPrototypeOf`
    setPrototypeOf &&
    // we haven't completely correct pre-ES6 way for getting `new.target`, so use this
    typeof (NewTarget = dummy.constructor) == 'function' &&
    NewTarget !== Wrapper &&
    isObject(NewTargetPrototype = NewTarget.prototype) &&
    NewTargetPrototype !== Wrapper.prototype
  ) setPrototypeOf($this, NewTargetPrototype);
  return $this;
};


/***/ }),

/***/ "7418":
/***/ (function(module, exports) {

exports.f = Object.getOwnPropertySymbols;


/***/ }),

/***/ "746f":
/***/ (function(module, exports, __webpack_require__) {

var path = __webpack_require__("428f");
var has = __webpack_require__("5135");
var wrappedWellKnownSymbolModule = __webpack_require__("e538");
var defineProperty = __webpack_require__("9bf2").f;

module.exports = function (NAME) {
  var Symbol = path.Symbol || (path.Symbol = {});
  if (!has(Symbol, NAME)) defineProperty(Symbol, NAME, {
    value: wrappedWellKnownSymbolModule.f(NAME)
  });
};


/***/ }),

/***/ "7839":
/***/ (function(module, exports) {

// IE8- don't enum bug keys
module.exports = [
  'constructor',
  'hasOwnProperty',
  'isPrototypeOf',
  'propertyIsEnumerable',
  'toLocaleString',
  'toString',
  'valueOf'
];


/***/ }),

/***/ "7b0b":
/***/ (function(module, exports, __webpack_require__) {

var requireObjectCoercible = __webpack_require__("1d80");

// `ToObject` abstract operation
// https://tc39.github.io/ecma262/#sec-toobject
module.exports = function (argument) {
  return Object(requireObjectCoercible(argument));
};


/***/ }),

/***/ "7c73":
/***/ (function(module, exports, __webpack_require__) {

var anObject = __webpack_require__("825a");
var defineProperties = __webpack_require__("37e8");
var enumBugKeys = __webpack_require__("7839");
var hiddenKeys = __webpack_require__("d012");
var html = __webpack_require__("1be4");
var documentCreateElement = __webpack_require__("cc12");
var sharedKey = __webpack_require__("f772");

var GT = '>';
var LT = '<';
var PROTOTYPE = 'prototype';
var SCRIPT = 'script';
var IE_PROTO = sharedKey('IE_PROTO');

var EmptyConstructor = function () { /* empty */ };

var scriptTag = function (content) {
  return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT;
};

// Create object with fake `null` prototype: use ActiveX Object with cleared prototype
var NullProtoObjectViaActiveX = function (activeXDocument) {
  activeXDocument.write(scriptTag(''));
  activeXDocument.close();
  var temp = activeXDocument.parentWindow.Object;
  activeXDocument = null; // avoid memory leak
  return temp;
};

// Create object with fake `null` prototype: use iframe Object with cleared prototype
var NullProtoObjectViaIFrame = function () {
  // Thrash, waste and sodomy: IE GC bug
  var iframe = documentCreateElement('iframe');
  var JS = 'java' + SCRIPT + ':';
  var iframeDocument;
  iframe.style.display = 'none';
  html.appendChild(iframe);
  // https://github.com/zloirock/core-js/issues/475
  iframe.src = String(JS);
  iframeDocument = iframe.contentWindow.document;
  iframeDocument.open();
  iframeDocument.write(scriptTag('document.F=Object'));
  iframeDocument.close();
  return iframeDocument.F;
};

// Check for document.domain and active x support
// No need to use active x approach when document.domain is not set
// see https://github.com/es-shims/es5-shim/issues/150
// variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346
// avoid IE GC bug
var activeXDocument;
var NullProtoObject = function () {
  try {
    /* global ActiveXObject */
    activeXDocument = document.domain && new ActiveXObject('htmlfile');
  } catch (error) { /* ignore */ }
  NullProtoObject = activeXDocument ? NullProtoObjectViaActiveX(activeXDocument) : NullProtoObjectViaIFrame();
  var length = enumBugKeys.length;
  while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]];
  return NullProtoObject();
};

hiddenKeys[IE_PROTO] = true;

// `Object.create` method
// https://tc39.github.io/ecma262/#sec-object.create
module.exports = Object.create || function create(O, Properties) {
  var result;
  if (O !== null) {
    EmptyConstructor[PROTOTYPE] = anObject(O);
    result = new EmptyConstructor();
    EmptyConstructor[PROTOTYPE] = null;
    // add "__proto__" for Object.getPrototypeOf polyfill
    result[IE_PROTO] = O;
  } else result = NullProtoObject();
  return Properties === undefined ? result : defineProperties(result, Properties);
};


/***/ }),

/***/ "7dd0":
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $ = __webpack_require__("23e7");
var createIteratorConstructor = __webpack_require__("9ed3");
var getPrototypeOf = __webpack_require__("e163");
var setPrototypeOf = __webpack_require__("d2bb");
var setToStringTag = __webpack_require__("d44e");
var createNonEnumerableProperty = __webpack_require__("9112");
var redefine = __webpack_require__("6eeb");
var wellKnownSymbol = __webpack_require__("b622");
var IS_PURE = __webpack_require__("c430");
var Iterators = __webpack_require__("3f8c");
var IteratorsCore = __webpack_require__("ae93");

var IteratorPrototype = IteratorsCore.IteratorPrototype;
var BUGGY_SAFARI_ITERATORS = IteratorsCore.BUGGY_SAFARI_ITERATORS;
var ITERATOR = wellKnownSymbol('iterator');
var KEYS = 'keys';
var VALUES = 'values';
var ENTRIES = 'entries';

var returnThis = function () { return this; };

modu
Download .txt
gitextract_knz350g7/

├── .gitignore
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.md
├── MIGRATION.md
├── README.md
├── babel.config.js
├── demo/
│   ├── .gitignore
│   ├── README.md
│   ├── babel.config.js
│   ├── package.json
│   ├── public/
│   │   └── index.html
│   ├── src/
│   │   ├── App.vue
│   │   ├── assets/
│   │   │   ├── _variables.styl
│   │   │   └── demo.styl
│   │   ├── components/
│   │   │   ├── ConfigRow.vue
│   │   │   ├── OverlayPanel.vue
│   │   │   ├── Playground.vue
│   │   │   ├── SampleBlock.vue
│   │   │   └── Samples.vue
│   │   └── main.js
│   └── vue.config.js
├── dist/
│   ├── VueTimepicker.common.js
│   ├── VueTimepicker.css
│   ├── VueTimepicker.umd.js
│   └── demo.html
├── package.json
└── src/
    ├── index.js
    └── vue-timepicker.vue
Download .txt
SYMBOL INDEX (20 symbols across 2 files)

FILE: dist/VueTimepicker.common.js
  function __webpack_require__ (line 7) | function __webpack_require__(moduleId) {
  function getSubstitution (line 1407) | function getSubstitution(matched, str, position, captures, namedCaptures...
  function getCurrentScript (line 2132) | function getCurrentScript () {
  function RE (line 2530) | function RE(s, f) {
  function F (line 4150) | function F() { /* empty */ }
  function _typeof (line 4468) | function _typeof(obj) {
  function _arrayLikeToArray (line 4487) | function _arrayLikeToArray(arr, len) {
  function _unsupportedIterableToArray (line 4504) | function _unsupportedIterableToArray(o, minLen) {
  function _createForOfIteratorHelper (line 4521) | function _createForOfIteratorHelper(o) {
  function normalizeComponent (line 7096) | function normalizeComponent (

FILE: dist/VueTimepicker.umd.js
  function __webpack_require__ (line 16) | function __webpack_require__(moduleId) {
  function getSubstitution (line 1416) | function getSubstitution(matched, str, position, captures, namedCaptures...
  function getCurrentScript (line 2141) | function getCurrentScript () {
  function RE (line 2539) | function RE(s, f) {
  function F (line 4159) | function F() { /* empty */ }
  function _typeof (line 4477) | function _typeof(obj) {
  function _arrayLikeToArray (line 4496) | function _arrayLikeToArray(arr, len) {
  function _unsupportedIterableToArray (line 4513) | function _unsupportedIterableToArray(o, minLen) {
  function _createForOfIteratorHelper (line 4530) | function _createForOfIteratorHelper(o) {
  function normalizeComponent (line 7105) | function normalizeComponent (
Condensed preview — 29 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (742K chars).
[
  {
    "path": ".gitignore",
    "chars": 905,
    "preview": "# Compiled source #\n###################\n*.com\n*.class\n*.dll\n*.exe\n*.o\n*.so\n\n# Packages #\n############\n*.7z\n*.dmg\n*.gz\n*."
  },
  {
    "path": "CHANGELOG.md",
    "chars": 7576,
    "preview": "# CHANGELOG\n\n> The Change Log of Vue2 Timepicker `vue2-timepicker`\n\n## v 1.1.6\n\n### New\n\n- Support appending the dropdow"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1432,
    "preview": "# Contribution\n\nPlease feel free to fork and help developing.\n\n```bash\n# Install dependencies\nyarn install\n\n# Init devel"
  },
  {
    "path": "LICENSE.md",
    "chars": 1069,
    "preview": "MIT License\n\nCopyright (c) 2019 Phoenix Wong\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
  },
  {
    "path": "MIGRATION.md",
    "chars": 4060,
    "preview": "# Table of Contents\n\n- [Migrating from Vue 1.x vue-timepicker](https://github.com/phoenixwong/vue2-timepicker/blob/maste"
  },
  {
    "path": "README.md",
    "chars": 31680,
    "preview": "# Vue2 Timepicker  \n\n![GitHub version](https://img.shields.io/github/package-json/v/phoenixwong/vue2-timepicker?color=su"
  },
  {
    "path": "babel.config.js",
    "chars": 73,
    "preview": "module.exports = {\n  presets: [\n    '@vue/cli-plugin-babel/preset'\n  ]\n}\n"
  },
  {
    "path": "demo/.gitignore",
    "chars": 239,
    "preview": ".DS_Store\nnode_modules\n/dist\nyarn.lock*\npackage.lock*\n\n# local env files\n.env.local\n.env.*.local\n\n# Log files\nnpm-debug."
  },
  {
    "path": "demo/README.md",
    "chars": 336,
    "preview": "# Vue2 Timepicker Demo\n\n## Project setup\n```\nyarn install\n```\n\n### Compiles and hot-reloads for development\n```\nyarn run"
  },
  {
    "path": "demo/babel.config.js",
    "chars": 73,
    "preview": "module.exports = {\n  presets: [\n    '@vue/cli-plugin-babel/preset'\n  ]\n}\n"
  },
  {
    "path": "demo/package.json",
    "chars": 1075,
    "preview": "{\n  \"name\": \"vue2-timepicker-demo\",\n  \"version\": \"1.1.6\",\n  \"private\": true,\n  \"scripts\": {\n    \"serve\": \"vue-cli-servic"
  },
  {
    "path": "demo/public/index.html",
    "chars": 1126,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
  },
  {
    "path": "demo/src/App.vue",
    "chars": 3170,
    "preview": "<script>\nimport Samples from './components/Samples'\nimport Playground from './components/Playground'\n\nexport default {\n "
  },
  {
    "path": "demo/src/assets/_variables.styl",
    "chars": 244,
    "preview": "$vue-green = #41B883\n$vue-green-light = lighten($vue-green, 5%)\n$vue-dark = #35495E\n$vue-darker = darken($vue-dark, 25%)"
  },
  {
    "path": "demo/src/assets/demo.styl",
    "chars": 3852,
    "preview": "@import './_variables.styl'\n\nbody,\nhtml\n  margin: 0\n  padding: 0\n  font-family: sans-serif\n  color: $body-color\n  -webki"
  },
  {
    "path": "demo/src/components/ConfigRow.vue",
    "chars": 1191,
    "preview": "<script>\nexport default {\n  name: 'ConfigRow',\n  props: {\n    label: { type: String },\n    isGroup: { type: Boolean, def"
  },
  {
    "path": "demo/src/components/OverlayPanel.vue",
    "chars": 2091,
    "preview": "<script>\nexport default {\n  name: 'OverlayPanel',\n  props: {\n    title: { type: String }\n  },\n  methods: {\n    closePane"
  },
  {
    "path": "demo/src/components/Playground.vue",
    "chars": 32501,
    "preview": "<script>\nimport VueTimepicker from '../../../src/vue-timepicker'\nimport ConfigRow from './ConfigRow'\nimport OverlayPanel"
  },
  {
    "path": "demo/src/components/SampleBlock.vue",
    "chars": 1013,
    "preview": "<script>\nexport default {\n  name: 'SampleBlock',\n  props: {\n    id: { type: String }\n  },\n  computed: {\n    blockHerf ()"
  },
  {
    "path": "demo/src/components/Samples.vue",
    "chars": 41789,
    "preview": "<script>\nimport VueTimepicker from '../../../src/vue-timepicker'\nimport SampleBlock from './SampleBlock'\n\nexport default"
  },
  {
    "path": "demo/src/main.js",
    "chars": 545,
    "preview": "import Vue from 'vue'\n\nimport VueHighlightJS from 'vue-highlight.js'\nimport javascript from 'highlight.js/lib/languages/"
  },
  {
    "path": "demo/vue.config.js",
    "chars": 137,
    "preview": "module.exports = {\n  outputDir: '../gh-pages',\n  publicPath: process.env.NODE_ENV === 'production'\n    ? '/vue2-timepick"
  },
  {
    "path": "dist/VueTimepicker.common.js",
    "chars": 242930,
    "preview": "module.exports =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installed"
  },
  {
    "path": "dist/VueTimepicker.css",
    "chars": 5102,
    "preview": ".vue__time-picker{display:inline-block;position:relative;font-size:1em;width:10em;font-family:sans-serif;vertical-align:"
  },
  {
    "path": "dist/VueTimepicker.umd.js",
    "chars": 243332,
    "preview": "(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object"
  },
  {
    "path": "dist/demo.html",
    "chars": 204,
    "preview": "<meta charset=\"utf-8\">\n<title>VueTimepicker demo</title>\n<script src=\"./VueTimepicker.umd.js\"></script>\n\n<link rel=\"styl"
  },
  {
    "path": "package.json",
    "chars": 1863,
    "preview": "{\n  \"name\": \"vue2-timepicker\",\n  \"version\": \"1.1.6\",\n  \"description\": \"A dropdown time picker (hour|minute|second) for V"
  },
  {
    "path": "src/index.js",
    "chars": 78,
    "preview": "import VueTimepicker from './vue-timepicker.vue'\nexport default VueTimepicker\n"
  },
  {
    "path": "src/vue-timepicker.vue",
    "chars": 81317,
    "preview": "<script>\nconst CONFIG = {\n  HOUR_TOKENS: ['HH', 'H', 'hh', 'h', 'kk', 'k'],\n  MINUTE_TOKENS: ['mm', 'm'],\n  SECOND_TOKEN"
  }
]

About this extraction

This page contains the full source code of the phoenixwong/vue2-timepicker GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 29 files (694.3 KB), approximately 183.2k tokens, and a symbol index with 20 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!