[
  {
    "path": ".gitignore",
    "content": ".DS_Store\nbower_components\nnode_modules\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js:\n  - 'node'\ninstall:\n  - npm install\nscript:\n  - npm test\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n\t\"typescript.tsdk\": \"node_modules/typescript/lib\"\n}"
  },
  {
    "path": ".vscode/tasks.json",
    "content": "{\n\t// See https://go.microsoft.com/fwlink/?LinkId=733558\n\t// for the documentation about the tasks.json format\n\t\"version\": \"0.1.0\",\n\t\"command\": \"npm\",\n\t\"isShellCommand\": true,\n\t\"args\": [\"run\", \"build\"]\n}"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 Indri Muska\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "README.md",
    "content": "# Angular Moment Picker\n\n[![Join the chat at https://gitter.im/indrimuska/angular-moment-picker](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/indrimuska/angular-moment-picker?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n[![Build Status](https://travis-ci.org/indrimuska/angular-moment-picker.svg)](https://travis-ci.org/indrimuska/angular-moment-picker)\n\n[![NPM version](http://img.shields.io/npm/v/angular-moment-picker.svg?style=flat)](https://npmjs.org/package/angular-moment-picker)\n[![NPM downloads](http://img.shields.io/npm/dm/angular-moment-picker.svg?style=flat)](https://npmjs.org/package/angular-moment-picker)\n[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)\n[![CDNJS](https://img.shields.io/cdnjs/v/angular-moment-picker.svg)](https://cdnjs.com/libraries/angular-moment-picker)\n\nCheck out the homepage at [http://indrimuska.github.io/angular-moment-picker/](http://indrimuska.github.io/angular-moment-picker/).\n\n*Angular Moment Picker* is a native AngularJS directive for date and time picker that uses *Moment.js* and **does not require jQuery**.\n\n<p align=\"center\">\n    <a href=\"http://indrimuska.github.io/angular-moment-picker/\">\n        <img src=\"http://indrimuska.github.io/angular-moment-picker/img/angular-moment-picker.gif\" alt=\"Angular Moment Picker demo\">\n    </a>\n</p>\n\n## Installation\n\nGet Angular Moment Picker from [**npm**](https://www.npmjs.com/), [**bower**](http://bower.io/) or [**git**](https://git-scm.com/):\n```\n  npm install angular-moment-picker\nbower install moment-picker\n  git clone   https://github.com/indrimuska/angular-moment-picker.git\n```\n\nInclude style and script in your page:\n```html\n<script src=\"//ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js\"></script>\n<script src=\"//cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment-with-locales.js\"></script>\n<script src=\"//cdn.rawgit.com/indrimuska/angular-moment-picker/master/dist/angular-moment-picker.min.js\"></script>\n<link href=\"//cdn.rawgit.com/indrimuska/angular-moment-picker/master/dist/angular-moment-picker.min.css\" rel=\"stylesheet\">\n```\n\nAdd *moment-picker* dependency to your module:\n```js\nvar myApp = angular.module('myApp', ['moment-picker']);\n```\n\nProvide the attribute to your element:\n```html\n<div moment-picker=\"myDate\"> {{ myDate }} </div>\n```\n\n## Demo\n\nCheck out the demo page at [http://indrimuska.github.io/angular-moment-picker/](http://indrimuska.github.io/angular-moment-picker/).\n\n## The views\n\n***Decade view*** | ***Year view*** | ***Month view***\n:---:|:---:|:---:\n![Decade view](http://indrimuska.github.io/angular-moment-picker/img/themes/default/decade-view.png?) | ![Year view](http://indrimuska.github.io/angular-moment-picker/img/themes/default/year-view.png?) | ![Month view](http://indrimuska.github.io/angular-moment-picker/img/themes/default/month-view.png?)\n***Day view*** | ***Hour view*** | ***Minute view***\n![Day view](http://indrimuska.github.io/angular-moment-picker/img/themes/default/day-view.png?) | ![Hour view](http://indrimuska.github.io/angular-moment-picker/img/themes/default/hour-view.png?) | ![Minute view](http://indrimuska.github.io/angular-moment-picker/img/themes/default/minute-view.png?)\n\n### Additional themes\n\nAngular Moment Picker provides the following additional themes. Each theme has a dedicate stylesheet to be included in the application the overrides the default style.\n\n - **Material UI** - [Plunker](https://embed.plnkr.co/P48UnN)\n   ```html\n   <link href=\"//cdn.rawgit.com/indrimuska/angular-moment-picker/master/dist/themes/material-ui.min.css\" rel=\"stylesheet\">\n   ```\n\nA preview of the each theme is available [here](dist/themes/).\n\n## Options\n\nTo configure Angular Moment Picker you have to add to your element or your input the attribute relative to the options you want to set.\n\n```html\n<div moment-picker=\"ctrl.birthday\" locale=\"fr\" format=\"LL\">\n    Mon anniversaire est le {{ ctrl.birthday }}\n</div>\n```\n\n```html\n<input moment-picker=\"ctrl.dateFormatted\" ng-model=\"ctrl.momentDate\" format=\"DD/MM/YYYY\">\n```\n\nProperty | Default | Description | Sample\n---|---|---|---\nmoment-picker | | Two-way bindable property as **formatted datetime string**. | [Plunker](https://embed.plnkr.co/nPGbO3KkmmPqf7mfN2PC/)\nng-model | | Two-way bindable property as **Moment.js object**. | [Plunker](https://embed.plnkr.co/hs10SM)\nlocale | `\"en\"` | Locale code. <sup>1</sup> | [Plunker](https://embed.plnkr.co/z3KSxy)\nformat | `\"L LTS\"` | Format of the output value and min/max date. <sup>1</sup> | [Plunker](https://embed.plnkr.co/rWtdhO)\nmin-view | `\"decade\"` | Minimum navigable view. | [Plunker](https://embed.plnkr.co/wAGqtl)\nmax-view | `\"minute\"` | Maximum navigable view. | [Plunker](https://embed.plnkr.co/GYRv7J)\nstart-view | `\"year\"` | Initial view when the picker is open. | [Plunker](https://embed.plnkr.co/wFXcGL)\nmin-date | | Two-way bindable property representing the minimum selectable date (as String in the same format of the value, or as a Moment.js object). | [Plunker](https://embed.plnkr.co/L9dOc4)\nmax-date | | Two-way bindable property representing the maximum selectable date (as String in the same format of the value, or as a Moment.js object). | [Plunker](https://embed.plnkr.co/OvvfAQ)\nstart-date | | Two-way bindable property representing the initial date to be shown in picker (as String in the same format of the value, or as a Moment.js object). | [Plunker](https://embed.plnkr.co/rjFk9d)\ndisable | `false` | Disables the picker if truly. | [Plunker](https://embed.plnkr.co/Zeaxd3)\nposition | | Sets a fixed position for the picker. Available values are `\"top left\"`, `\"top right\"`, `\"bottom left\"`, `\"bottom right\"`. | [Plunker](https://embed.plnkr.co/v9AZFu)\ninline | `false` | Views the picker inline. | [Plunker](https://embed.plnkr.co/5PhKOc)\nvalidate | `true` | Forces picker value between the range `minDate` and `maxDate`. | [Plunker](https://embed.plnkr.co/hFTyMV)\nautoclose | `true` | Closes the picker after selecting a date. | [Plunker](https://embed.plnkr.co/z7M6WK)\nset-on-select | `false` | Updates picker model after selecting a date in each view. | [Plunker](https://embed.plnkr.co/hJRNcT)\nis-open | | Open/closes the picker when set to `true` or `false`. | [Plunker](https://embed.plnkr.co/7T4sbs)\ntoday | `false` | Highlights the current day. | [Plunker](https://embed.plnkr.co/YYbV4C)\nkeyboard | `false` | Allows using the keyboard to navigate the picker. | [Plunker](https://embed.plnkr.co/OdUhHx)\nshow-header | `true` | Shows the header in the view. | [Plunker](https://embed.plnkr.co/PCL4mh)\nadditions | `{ top: undefined, bottom: undefined }` | Template url for custom contents above and below each picker views (inside the dialog). | [Plunker](https://embed.plnkr.co/CXOH5U)\n\n## Methods\n\nAppend your method to your element and define its behavior in the controller.\n\n```html\n<div moment-picker=\"ctrl.exhibition\" format=\"dddd D MMMM\" selectable=\"ctrl.isSelectable(date, type)\">\n    Next exhibition is on {{ ctrl.exhibition }}.\n</div>\n```\n\n```javascript\nctrl.isSelectable = function (date, type) {\n    // disable all Sundays in the Month View\n    return type != 'day' || date.format('dddd') != 'Sunday';\n};\n```\n\nMethod | Parameters | Description | Sample\n---|---|---|---\nselectable | `date`, `type` | Return `true` if the given date can be selected in the current view. **Please note** that this method is called for every date in the view, every time a view is rendered, so be careful, it may affect performances. | [Plunker](https://embed.plnkr.co/6wxtMn)\n\n## Events\n\nAs for methods, to bind an event you only need to attach the right property to your picker.\n\n```html\n<div moment-picker=\"ctrl.meeting\" format=\"HH:mm A\" change=\"ctrl.onChange(newValue, oldValue)\">\n    The meeting starts at {{ ctrl.meeting }}.\n</div>\n```\n\n```javascript\nctrl.onChange = function (newValue, oldValue) {\n    $log.log('Meeting changed from ' + oldValue + ' to ' + newValue);\n};\n```\n\nEvent | Parameters | Description | Sample\n---|---|---|---\nchange | `newValue`, `oldValue` | Function fired upon change in picker value. | [Plunker](https://embed.plnkr.co/IIhjjv)\n\n## momentPickerProvider\n\nAngular Moment Picker comes out with its own provider, in order to define your own configuration for all the pickers in your app.\n\n```javascript\nangular\n    .module('myApp', ['moment-picker'])\n    .config(['momentPickerProvider', function (momentPickerProvider) {\n        momentPickerProvider.options({\n            /* ... */\n        });\n    }]);\n```\n\nProperty | Default | Description\n---|---|---\nlocale | `\"en\"` | Locale code. <sup>1</sup>\nformat | `\"L LTS\"` | Format of the output value and min/max date. <sup>1</sup>\nmin-view | `\"decade\"` | Minimum navigable view.\nmax-view | `\"minute\"` | Maximum navigable view.\nstart-view | `\"year\"` | Initial view after picker opening.\nposition | | Sets a fixed position for the picker. Available values are `\"top left\"`, `\"top right\"`, `\"bottom left\"`, `\"bottom right\"`.\ninline | `false` | Views the picker inline.\nvalidate | `true` | Forces picker value between the range `minDate` and `maxDate`.\nautoclose | `true` | Closes the picker after selecting a date.\nset-on-select | `false` | Updates picker model after selecting a date in each view.\ntoday | `false` | Highlights the current day.\nkeyboard | `false` | Allows using the keyboard to navigate the picker.\nshow-header | `true` | Shows the header in the view.\nleft-arrow | `\"&larr;\"` | Left arrow string (HTML allowed).\nright-arrow | `\"&rarr;\"` | Right arrow string (HTML allowed).\nadditions | `{ top: undefined, bottom: undefined }` | Template url for custom contents above and below each picker views (inside the dialog).\nyears-format | `\"YYYY\"` | Years format in `decade` view.\nmonths-format | `\"MMM\"` | Months format in `year` view.\ndays-format | `\"D\"` | Days format in `month` view.\nhours-format | `\"HH:[00]\"` | Hours format in `day` view.\nhours-start | `0` | First rendered hour in `day` view (24h format).\nhours-end | `23` | Last rendered hour in `day` view (24h format).\nminutes-format | <sup>2</sub> | Minutes format in `hour` view.\nminutes-step | `5` | Step between each visible minute in `hour` view.\nminutes-start | `0` | First rendered minute in `hour` view.\nminutes-end | `59` | Last rendered minute in `hour` view.\nseconds-format | `\"ss\"` | Seconds format in `minute` view.\nseconds-step | `1` | Step between each visible second in `minute` view.\nseconds-start | `0` | First rendered second in `minute` view.\nseconds-end | `59` | Last rendered second in `minute` view.\n\n## Notes\n\n1. Locale codes and format tokens are available at http://momentjs.com/.\n2. Locale format `LT` without meridiem part (AM/PM, am/pm).\n\n## Builder\n\nTry the online [Angular Moment Picker Builder](http://indrimuska.github.io/angular-moment-picker/#builder):\n\n[http://indrimuska.github.io/angular-moment-picker/#builder](http://indrimuska.github.io/angular-moment-picker/#builder).\n\n## Dev scripts\n\n - `npm run build`: compile sources and generate built files in `dist` folder.\n - `npm run minify`: generate built files and minified ones.\n - `npm run release`: increase package version and compile the project.\n - `npm run test`: run all tests in the `tests` folder.\n\n## License\nCopyright (c) 2015 Indri Muska. Licensed under the MIT license.\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"angular-moment-picker\",\n  \"version\": \"0.10.2\",\n  \"authors\": [\n    \"Indri Muska <indrimuska@gmail.com>\"\n  ],\n  \"description\": \"Angular Moment Picker is an AngularJS directive for date and time picker using Moment.js\",\n  \"main\": [\n    \"dist/angular-moment-picker.min.js\",\n    \"dist/angular-moment-picker.min.css\"\n  ],\n  \"keywords\": [\n    \"datepicker\",\n    \"timepicker\",\n    \"datetime\",\n    \"picker\",\n    \"calendar\",\n    \"moment.js\",\n    \"angular\"\n  ],\n  \"license\": \"MIT\",\n  \"homepage\": \"http://indrimuska.github.io/angular-moment-picker\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"test\",\n    \"tests\"\n  ],\n  \"dependencies\": {\n    \"angular\": \"^1.3\",\n    \"moment\": \"^2.16.0\"\n  }\n}"
  },
  {
    "path": "dist/angular-moment-picker.css",
    "content": "/*! Angular Moment Picker - v0.10.2 - http://indrimuska.github.io/angular-moment-picker - (c) 2015 Indri Muska - MIT */\n.moment-picker-input {\n  cursor: pointer;\n}\n.moment-picker {\n  position: absolute;\n  z-index: 1060;\n}\n.moment-picker .moment-picker-container {\n  color: #404040;\n  min-width: 15em;\n  background: #fff;\n  padding: 4px;\n  border: 1px solid #f0f3f4;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n  position: absolute;\n  margin-top: 4px;\n  margin-left: -0.5em;\n  -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.075);\n     -moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.075);\n          box-shadow: 0 2px 4px rgba(0, 0, 0, 0.075);\n}\n.moment-picker .moment-picker-container:before,\n.moment-picker .moment-picker-container:after {\n  content: '';\n  display: block;\n  width: 0;\n  height: 0;\n  border: 8px solid transparent;\n  border-top: none;\n  position: absolute;\n  top: -9px;\n  left: 15px;\n}\n.moment-picker .moment-picker-container:before {\n  border-bottom-color: #f0f3f4;\n  border-width: 9px;\n}\n.moment-picker .moment-picker-container:after {\n  border-bottom-color: #fff;\n  margin-top: 1px;\n  margin-left: 1px;\n}\n.moment-picker.inline {\n  display: block;\n  position: relative;\n}\n.moment-picker.inline .moment-picker-container {\n  position: relative;\n  margin: 0;\n}\n.moment-picker.inline .moment-picker-container:before,\n.moment-picker.inline .moment-picker-container:after {\n  content: none;\n}\n.moment-picker.top .moment-picker-container {\n  bottom: 100%;\n  margin-top: auto;\n  margin-bottom: 4px;\n}\n.moment-picker.top .moment-picker-container:before,\n.moment-picker.top .moment-picker-container:after {\n  border: 8px solid transparent;\n  border-bottom: none;\n  top: auto;\n  bottom: -9px;\n}\n.moment-picker.top .moment-picker-container:before {\n  border-top-color: #f0f3f4;\n  border-width: 9px;\n}\n.moment-picker.top .moment-picker-container:after {\n  border-top-color: #fff;\n  margin-top: auto;\n  margin-bottom: 1px;\n}\n.moment-picker.right .moment-picker-container {\n  right: 0;\n  margin-left: auto;\n  margin-right: -0.5em;\n}\n.moment-picker.right .moment-picker-container:before,\n.moment-picker.right .moment-picker-container:after {\n  left: auto;\n  right: 15px;\n}\n.moment-picker.right .moment-picker-container:after {\n  margin-left: auto;\n  margin-right: 1px;\n}\n.moment-picker table {\n  border-collapse: collapse;\n  border-spacing: 0;\n  min-width: 100%;\n  table-layout: fixed;\n}\n.moment-picker th {\n  font-weight: bold;\n}\n.moment-picker th:first-child,\n.moment-picker th:last-child {\n  width: 2em;\n}\n.moment-picker th,\n.moment-picker td {\n  padding: 0;\n  text-align: center;\n  min-width: 2em;\n  height: 2em;\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.9);\n  cursor: pointer;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n}\n.moment-picker th:hover,\n.moment-picker td:hover {\n  background-color: #fafbfb;\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0f3f4), to(#fafbfb));\n  background-image: -webkit-linear-gradient(#f0f3f4, #fafbfb);\n  background-image: -moz-linear-gradient(#f0f3f4, #fafbfb);\n  background-image: -o-linear-gradient(#f0f3f4, #fafbfb);\n  background-image: linear-gradient(#f0f3f4, #fafbfb);\n}\n.moment-picker th.disabled,\n.moment-picker td.disabled,\n.moment-picker th.disabled:hover,\n.moment-picker td.disabled:hover {\n  color: #abbbc7;\n  background: none;\n  cursor: default;\n}\n.moment-picker td.today {\n  background: #e4eef5;\n  color: #404040;\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.9);\n}\n.moment-picker td.selected {\n  color: #fff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);\n  border-color: #3ca0dd;\n  background-color: #45b1e8;\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#45b1e8), to(#3097de));\n  background-image: -webkit-linear-gradient(#45b1e8, #3097de);\n  background-image: -moz-linear-gradient(#45b1e8, #3097de);\n  background-image: -o-linear-gradient(#45b1e8, #3097de);\n  background-image: linear-gradient(#45b1e8, #3097de);\n}\n.moment-picker td.highlighted {\n  background-image: -webkit-radial-gradient(transparent, rgba(0, 0, 0, 0.15));\n  background-image: -moz-radial-gradient(transparent, rgba(0, 0, 0, 0.15));\n  background-image: -o-radial-gradient(transparent, rgba(0, 0, 0, 0.15));\n  background-image: radial-gradient(transparent, rgba(0, 0, 0, 0.15));\n}\n.moment-picker .decade-view td,\n.moment-picker .year-view td {\n  height: 3.4em;\n}\n.moment-picker .month-view .moment-picker-specific-views th {\n  background: none;\n  cursor: default;\n}\n.moment-picker .month-view td {\n  width: 1.4285714286em;\n}\n.moment-picker .day-view td,\n.moment-picker .hour-view td {\n  height: 2.3333333333em;\n}\n.moment-picker .minute-view td {\n  height: 1.8em;\n}\n"
  },
  {
    "path": "dist/angular-moment-picker.js",
    "content": "/*! Angular Moment Picker - v0.10.2 - http://indrimuska.github.io/angular-moment-picker - (c) 2015 Indri Muska - MIT */\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// identity function for calling harmony imports with the correct context\n/******/ \t__webpack_require__.i = function(value) { return value; };\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 17);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nexports.__esModule = true;\nvar angular = __webpack_require__(1);\nvar moment = __webpack_require__(2);\nexports.KEYS = { up: 38, down: 40, left: 37, right: 39, escape: 27, enter: 13 };\nexports.isValidMoment = function (value) {\n    return moment.isMoment(value) && value.isValid();\n};\nexports.toValue = function (date, format, locale) {\n    var momentDate = date;\n    if (!exports.isValidMoment(date))\n        momentDate = exports.toMoment(date, format, locale);\n    return exports.momentToValue(momentDate, format);\n};\nexports.toMoment = function (date, format, locale) {\n    var momentDate = moment(date, format, locale);\n    if (!exports.isValidMoment(momentDate))\n        momentDate = undefined;\n    return momentDate;\n};\nexports.momentToValue = function (momentObject, format) {\n    if (!exports.isValidMoment(momentObject))\n        return undefined;\n    return !format ? momentObject.valueOf() : momentObject.format(format);\n};\nexports.valueToMoment = function (formattedValue, $scope) {\n    var momentValue;\n    if (!formattedValue)\n        return momentValue;\n    if (!$scope.format)\n        momentValue = moment(formattedValue);\n    else\n        momentValue = moment(formattedValue, $scope.format, $scope.locale);\n    if ($scope.model) {\n        // set value for each view precision (from Decade View to minView)\n        var views = $scope.views.all.slice(0, $scope.views.all.indexOf($scope.detectedMinView));\n        angular.forEach(views, function (view) {\n            var precision = $scope.views.precisions[view];\n            momentValue[precision]($scope.model[precision]());\n        });\n    }\n    return momentValue;\n};\nexports.setValue = function (value, $scope, $ctrl, $attrs) {\n    var modelValue = exports.isValidMoment(value) ? value.clone() : exports.valueToMoment(value, $scope), viewValue = exports.momentToValue(modelValue, $scope.format);\n    $scope.model = exports.updateMoment($scope.model, modelValue, $scope);\n    $ctrl.$modelValue = exports.updateMoment($ctrl.$modelValue, modelValue, $scope);\n    if ($attrs['ngModel'] != $attrs['momentPicker'])\n        $scope.value = viewValue;\n    if ($attrs['ngModel']) {\n        $ctrl.$setViewValue(viewValue);\n        $ctrl.$render(); // render input value\n    }\n};\nexports.updateMoment = function (model, value, $scope) {\n    if (!exports.isValidMoment(model) || !value)\n        model = value;\n    else {\n        if (!model.isSame(value)) {\n            // set value for each view precision (from Decade View to maxView)\n            var views = $scope.views.all.slice(0, $scope.views.all.indexOf($scope.detectedMaxView) + 1);\n            angular.forEach(views, function (view) {\n                var precision = $scope.views.precisions[view];\n                model[precision](value[precision]());\n            });\n        }\n    }\n    return model;\n};\n\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports) {\n\nmodule.exports = angular;\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports) {\n\nmodule.exports = moment;\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports) {\n\n// removed by extract-text-webpack-plugin\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports) {\n\n// removed by extract-text-webpack-plugin\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nexports.__esModule = true;\nvar angular = __webpack_require__(1);\nvar provider_1 = __webpack_require__(9);\nexports.Provider = provider_1[\"default\"];\nvar directive_1 = __webpack_require__(7);\nexports.Directive = directive_1[\"default\"];\nangular\n    .module('moment-picker', [])\n    .provider('momentPicker', [function () { return new provider_1[\"default\"](); }])\n    .directive('momentPicker', [\n    '$timeout', '$sce', '$log', '$window', 'momentPicker', '$compile', '$templateCache',\n    function ($timeout, $sce, $log, $window, momentPicker, $compile, $templateCache) {\n        return new directive_1[\"default\"]($timeout, $sce, $log, $window, momentPicker, $compile, $templateCache);\n    }\n]);\n\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports) {\n\nmodule.exports = \"<div class=moment-picker> <div class=\\\"moment-picker-container {{view.selected}}-view\\\" ng-class=\\\"{'moment-picker-disabled': disabled, open: view.isOpen}\\\"> <div ng-if=additions.top class=\\\"moment-picker-addition top\\\"></div> <table class=header-view ng-if=showHeader> <thead> <tr> <th ng-class=\\\"{disabled: !view.previous.selectable}\\\" ng-bind-html=view.previous.label ng-click=view.previous.set()></th> <th ng-bind=view.title ng-click=view.setParentView()></th> <th ng-class=\\\"{disabled: !view.next.selectable}\\\" ng-bind-html=view.next.label ng-click=view.next.set()></th> </tr> </thead> </table> <div class=moment-picker-specific-views> <table> <thead ng-if=views[view.selected].headers> <tr> <th ng-repeat=\\\"header in views[view.selected].headers\\\" ng-bind=header></th> </tr> </thead> <tbody> <tr ng-repeat=\\\"row in views[view.selected].rows\\\"> <td ng-repeat=\\\"item in row track by item.index\\\" ng-class=item.class ng-bind=item.label ng-click=\\\"!disabled && views[view.selected].set(item)\\\"></td> </tr> </tbody> </table> </div> <div ng-if=additions.bottom class=\\\"moment-picker-addition bottom\\\"></div> </div> </div>\";\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nexports.__esModule = true;\nvar angular = __webpack_require__(1);\nvar moment = __webpack_require__(2);\nvar helpers_1 = __webpack_require__(8);\nvar views_1 = __webpack_require__(13);\nvar utility_1 = __webpack_require__(0);\nvar templateHtml = __webpack_require__(6);\nvar Directive = (function () {\n    function Directive($timeout, $sce, $log, $window, provider, $compile, $templateCache) {\n        var _this = this;\n        this.$timeout = $timeout;\n        this.$sce = $sce;\n        this.$log = $log;\n        this.$window = $window;\n        this.provider = provider;\n        this.$compile = $compile;\n        this.$templateCache = $templateCache;\n        this.restrict = 'A';\n        this.require = '?ngModel';\n        this.transclude = true;\n        this.template = templateHtml;\n        this.scope = {\n            value: '=?momentPicker',\n            model: '=?ngModel',\n            locale: '@?',\n            format: '@?',\n            minView: '@?',\n            maxView: '@?',\n            startView: '@?',\n            minDate: '=?',\n            maxDate: '=?',\n            startDate: '=?',\n            disabled: '=?disable',\n            position: '@?',\n            inline: '@?',\n            validate: '=?',\n            autoclose: '=?',\n            setOnSelect: '=?',\n            isOpen: '=?',\n            today: '=?',\n            keyboard: '=?',\n            showHeader: '=?',\n            additions: '=?',\n            change: '&?',\n            selectable: '&?'\n        };\n        this.link = function ($scope, $element, $attrs, $ctrl, $transclude) {\n            $transclude(function ($transElement) {\n                // one-way binding attributes\n                angular.forEach([\n                    'locale', 'format', 'minView', 'maxView', 'startView', 'position', 'inline', 'validate', 'autoclose', 'setOnSelect', 'today',\n                    'keyboard', 'showHeader', 'leftArrow', 'rightArrow', 'additions'\n                ], function (attr) {\n                    if (!angular.isDefined($scope[attr]))\n                        $scope[attr] = _this.provider[attr];\n                    if (!angular.isDefined($attrs[attr]))\n                        $attrs[attr] = $scope[attr];\n                });\n                // check if ngModel has been set\n                if (!$attrs['ngModel'])\n                    $ctrl = {};\n                // limits\n                $scope.limits = {\n                    minDate: utility_1.toMoment($scope.minDate, $scope.format, $scope.locale),\n                    maxDate: utility_1.toMoment($scope.maxDate, $scope.format, $scope.locale),\n                    isAfterOrEqualMin: function (value, precision) {\n                        return !angular.isDefined($scope.limits.minDate) || value.isAfter($scope.limits.minDate, precision) || value.isSame($scope.limits.minDate, precision);\n                    },\n                    isBeforeOrEqualMax: function (value, precision) {\n                        return !angular.isDefined($scope.limits.maxDate) || value.isBefore($scope.limits.maxDate, precision) || value.isSame($scope.limits.maxDate, precision);\n                    },\n                    isSelectable: function (value, precision) {\n                        var selectable = true;\n                        try {\n                            if (angular.isFunction($scope.selectable) && $attrs['selectable'])\n                                selectable = $scope.selectable({ date: value, type: precision });\n                        }\n                        catch (e) {\n                            _this.$log.error(e);\n                        }\n                        return $scope.limits.isAfterOrEqualMin(value, precision) && $scope.limits.isBeforeOrEqualMax(value, precision) && selectable;\n                    },\n                    checkValue: function () {\n                        if (!utility_1.isValidMoment($ctrl.$modelValue) || !$scope.validate)\n                            return;\n                        if (!$scope.limits.isAfterOrEqualMin($ctrl.$modelValue))\n                            utility_1.setValue($scope.limits.minDate, $scope, $ctrl, $attrs);\n                        if (!$scope.limits.isBeforeOrEqualMax($ctrl.$modelValue))\n                            utility_1.setValue($scope.limits.maxDate, $scope, $ctrl, $attrs);\n                    },\n                    checkView: function () {\n                        if (!angular.isDefined($scope.view.moment))\n                            $scope.view.moment = moment().locale($scope.locale);\n                        if (!$scope.limits.isAfterOrEqualMin($scope.view.moment))\n                            $scope.view.moment = $scope.limits.minDate.clone();\n                        if (!$scope.limits.isBeforeOrEqualMax($scope.view.moment))\n                            $scope.view.moment = $scope.limits.maxDate.clone();\n                        $scope.view.update();\n                        $scope.view.render();\n                    }\n                };\n                $scope.views = {\n                    all: ['decade', 'year', 'month', 'day', 'hour', 'minute'],\n                    precisions: { decade: 'year', year: 'month', month: 'date', day: 'hour', hour: 'minute', minute: 'second' },\n                    // for each view, `$scope.views.formats` object contains the available moment formats\n                    // formats present in more views are used to perform min/max view detection (i.e. 'LTS', 'LT', ...)\n                    formats: {\n                        decade: 'Y{1,2}(?!Y)|YYYY|[Ll]{1,4}(?!T)',\n                        /* formats: Y,YY,YYYY,L,LL,LLL,LLLL,l,ll,lll,llll */\n                        year: 'M{1,4}(?![Mo])|Mo|Q',\n                        /* formats: M,MM,MMM,MMM,Mo,Q */\n                        month: '[Dd]{1,4}(?![Ddo])|DDDo|[Dd]o|[Ww]{1,2}(?![Wwo])|[Ww]o|[Ee]|L{1,2}(?!T)|l{1,2}',\n                        /* formats: D,DD,DDD,DDDD,d,dd,ddd,dddd,DDDo,Do,do,W,WW,w,ww,Wo,wo,E,e,L,LL,l,ll */\n                        day: '[Hh]{1,2}|LTS?',\n                        /* formats: H,HH,h,hh,LT,LTS */\n                        hour: 'm{1,2}|[Ll]{3,4}|LT(?!S)',\n                        /* formats: m,mm,LLL,LLLL,lll,llll,LT */\n                        minute: 's{1,2}|S{1,}|X|LTS'\n                        /* formats: s,ss,S,SS,SSS..,X,LTS */\n                    },\n                    detectMinMax: function () {\n                        $scope.detectedMinView = $scope.detectedMaxView = undefined;\n                        if (!$scope.format)\n                            return;\n                        var minView, maxView;\n                        angular.forEach($scope.views.formats, function (formats, view) {\n                            var regexp = new RegExp('(' + formats + ')(?![^\\[]*\\])', 'g');\n                            if (!$scope.format.match(regexp))\n                                return;\n                            if (!angular.isDefined(minView))\n                                minView = view;\n                            maxView = view;\n                        });\n                        if (!angular.isDefined(minView))\n                            minView = 0;\n                        else\n                            minView = Math.max(0, $scope.views.all.indexOf(minView));\n                        if (!angular.isDefined(maxView))\n                            maxView = $scope.views.all.length - 1;\n                        else\n                            maxView = Math.min($scope.views.all.length - 1, $scope.views.all.indexOf(maxView));\n                        if (minView > $scope.views.all.indexOf($scope.minView))\n                            $scope.minView = $scope.views.all[minView];\n                        if (maxView < $scope.views.all.indexOf($scope.maxView))\n                            $scope.maxView = $scope.views.all[maxView];\n                        // save detected min/max view to use them to update the model value properly\n                        $scope.detectedMinView = $scope.views.all[minView];\n                        $scope.detectedMaxView = $scope.views.all[maxView];\n                    },\n                    // specific views\n                    decade: new views_1.DecadeView($scope, $ctrl, _this.provider),\n                    year: new views_1.YearView($scope, $ctrl, _this.provider),\n                    month: new views_1.MonthView($scope, $ctrl, _this.provider),\n                    day: new views_1.DayView($scope, $ctrl, _this.provider),\n                    hour: new views_1.HourView($scope, $ctrl, _this.provider),\n                    minute: new views_1.MinuteView($scope, $ctrl, _this.provider)\n                };\n                $scope.view = {\n                    moment: undefined,\n                    value: undefined,\n                    isOpen: false,\n                    selected: $scope.startView,\n                    update: function () { $scope.view.value = utility_1.momentToValue($scope.view.moment, $scope.format); },\n                    toggle: function () { $scope.view.isOpen ? $scope.view.close() : $scope.view.open(); },\n                    open: function () {\n                        if ($scope.disabled || $scope.view.isOpen || $scope.inline)\n                            return;\n                        $scope.isOpen = true;\n                        $scope.view.isOpen = true;\n                        document.body.appendChild($scope.picker[0]);\n                        $scope.view.position();\n                    },\n                    close: function () {\n                        if (!$scope.view.isOpen || $scope.inline)\n                            return;\n                        $scope.isOpen = false;\n                        $scope.view.isOpen = false;\n                        $scope.view.selected = $scope.startView;\n                        $scope.picker[0].parentNode.removeChild($scope.picker[0]);\n                    },\n                    position: function () {\n                        if (!$scope.view.isOpen || $scope.position || $scope.inline)\n                            return;\n                        var element = $element[0], picker = $scope.picker.children()[0], hasClassTop = $scope.picker.hasClass('top'), hasClassRight = $scope.picker.hasClass('right'), offset = helpers_1.getOffset($element[0]), top = offset.top - _this.$window.pageYOffset, left = offset.left - _this.$window.pageXOffset, winWidth = _this.$window.innerWidth, winHeight = _this.$window.innerHeight, shouldHaveClassTop = top + _this.$window.pageYOffset - picker.offsetHeight > 0 && top > winHeight / 2, shouldHaveClassRight = left + picker.offsetWidth > winWidth, pickerTop = offset.top + (shouldHaveClassTop ? 0 : element.offsetHeight) + 'px', pickerLeft = offset.left + 'px', pickerWidth = element.offsetWidth + 'px';\n                        if (!hasClassTop && shouldHaveClassTop)\n                            $scope.picker.addClass('top');\n                        if (hasClassTop && !shouldHaveClassTop)\n                            $scope.picker.removeClass('top');\n                        if (!hasClassRight && shouldHaveClassRight)\n                            $scope.picker.addClass('right');\n                        if (hasClassRight && !shouldHaveClassRight)\n                            $scope.picker.removeClass('right');\n                        if ($scope.picker.css('top') !== pickerTop)\n                            $scope.picker.css('top', pickerTop);\n                        if ($scope.picker.css('left') !== pickerLeft)\n                            $scope.picker.css('left', pickerLeft);\n                        if ($scope.picker.css('width') !== pickerWidth)\n                            $scope.picker.css('width', pickerWidth);\n                    },\n                    keydown: function (e) {\n                        var view = $scope.views[$scope.view.selected], precision = $scope.views.precisions[$scope.view.selected].replace('date', 'day'), singleUnit = _this.provider[precision + 'sStep'] || 1, operation = [utility_1.KEYS.up, utility_1.KEYS.left].indexOf(e.keyCode) >= 0 ? 'subtract' : 'add', highlight = function (vertical) {\n                            var unitMultiplier = vertical ? view.perLine : 1, nextDate = $scope.view.moment.clone()[operation](singleUnit * unitMultiplier, precision);\n                            if ($scope.limits.isSelectable(nextDate, precision)) {\n                                $scope.view.moment = nextDate;\n                                $scope.view.update();\n                                $scope.view.render();\n                            }\n                        };\n                        switch (e.keyCode) {\n                            case utility_1.KEYS.up:\n                            case utility_1.KEYS.down:\n                                e.preventDefault();\n                                if (!$scope.view.isOpen)\n                                    $scope.view.open();\n                                else\n                                    highlight(true);\n                                break;\n                            case utility_1.KEYS.left:\n                            case utility_1.KEYS.right:\n                                if (!$scope.view.isOpen)\n                                    break;\n                                e.preventDefault();\n                                highlight();\n                                break;\n                            case utility_1.KEYS.enter:\n                                if (!$scope.view.isOpen)\n                                    break;\n                                $scope.view.change(precision);\n                                e.preventDefault();\n                                break;\n                            case utility_1.KEYS.escape:\n                                $scope.view.toggle();\n                                break;\n                        }\n                        $scope.$evalAsync();\n                    },\n                    // utility\n                    unit: function () { return $scope.view.selected == 'decade' ? 10 : 1; },\n                    precision: function () { return $scope.view.selected.replace('decade', 'year'); },\n                    // header\n                    title: '',\n                    previous: {\n                        label: _this.$sce.trustAsHtml($scope.leftArrow),\n                        selectable: true,\n                        set: function () {\n                            if ($scope.view.previous.selectable) {\n                                $scope.view.moment.subtract($scope.view.unit(), $scope.view.precision());\n                                $scope.view.update();\n                                $scope.view.render();\n                            }\n                        }\n                    },\n                    next: {\n                        selectable: true,\n                        label: _this.$sce.trustAsHtml($scope.rightArrow),\n                        set: function () {\n                            if ($scope.view.next.selectable) {\n                                $scope.view.moment.add($scope.view.unit(), $scope.view.precision());\n                                $scope.view.update();\n                                $scope.view.render();\n                            }\n                        }\n                    },\n                    setParentView: function () { $scope.view.change($scope.views.all[Math.max(0, $scope.views.all.indexOf($scope.view.selected) - 1)]); },\n                    // body\n                    render: function () {\n                        var momentPrevious = $scope.view.moment.clone().startOf($scope.view.precision()).subtract($scope.view.unit(), $scope.view.precision()), momentNext = $scope.view.moment.clone().endOf($scope.view.precision()).add($scope.view.unit(), $scope.view.precision());\n                        $scope.view.previous.selectable = $scope.limits.isAfterOrEqualMin(momentPrevious, $scope.view.precision());\n                        $scope.view.previous.label = _this.$sce.trustAsHtml($scope.view.previous.selectable ? $scope.leftArrow : '&nbsp;');\n                        $scope.view.next.selectable = $scope.limits.isBeforeOrEqualMax(momentNext, $scope.view.precision());\n                        $scope.view.next.label = _this.$sce.trustAsHtml($scope.view.next.selectable ? $scope.rightArrow : '&nbsp;');\n                        $scope.view.title = $scope.views[$scope.view.selected].render();\n                    },\n                    change: function (view) {\n                        var nextView = $scope.views.all.indexOf(view), minView = $scope.views.all.indexOf($scope.minView), maxView = $scope.views.all.indexOf($scope.maxView);\n                        var update = function () {\n                            utility_1.setValue($scope.view.moment, $scope, $ctrl, $attrs);\n                            $scope.view.update();\n                            if ($attrs['ngModel'])\n                                $ctrl.$commitViewValue();\n                        };\n                        if ($scope.setOnSelect)\n                            update();\n                        if (nextView < 0 || nextView > maxView) {\n                            if (!$scope.setOnSelect)\n                                update();\n                            if ($scope.autoclose)\n                                _this.$timeout($scope.view.close);\n                        }\n                        else if (nextView >= minView)\n                            $scope.view.selected = view;\n                    }\n                };\n                // creation\n                $element.prepend($transElement);\n                $scope.picker = angular.element($element[0].querySelectorAll('.moment-picker'));\n                $scope.container = angular.element($scope.picker[0].querySelectorAll('.moment-picker-container'));\n                $scope.input = $element[0].tagName.toLowerCase() != 'input' && $element[0].querySelectorAll('input').length > 0\n                    ? angular.element($element[0].querySelectorAll('input'))\n                    : angular.element($element[0]);\n                $scope.input.addClass('moment-picker-input').attr('tabindex', 0);\n                ($scope.position || '').split(' ').forEach(function (className) { return $scope.picker.addClass(className); });\n                if (!$scope.inline)\n                    $scope.picker[0].parentNode.removeChild($scope.picker[0]);\n                else {\n                    $element.after($scope.picker);\n                    $scope.picker.addClass('inline');\n                }\n                // transclude scope to template additions\n                _this.$timeout(function () {\n                    angular.forEach($scope.additions || {}, function (tempalteUrl, key) {\n                        var placeholder = angular.element($scope.container[0].querySelector('.moment-picker-addition.' + key));\n                        var template = _this.$templateCache.get(tempalteUrl);\n                        var compiled = _this.$compile(template)($scope.$parent);\n                        placeholder.append(compiled);\n                    });\n                });\n                // initialization\n                $scope.views.detectMinMax();\n                $scope.limits.checkView();\n                // model controller is initialized after linking function\n                _this.$timeout(function () {\n                    if ($attrs['ngModel']) {\n                        if (!$ctrl.$modelValue && $scope.value)\n                            $ctrl.$setViewValue($scope.value);\n                        $ctrl.$commitViewValue();\n                        $ctrl.$render();\n                    }\n                    else {\n                        if ($scope.value)\n                            $ctrl.$modelValue = utility_1.valueToMoment($scope.value, $scope);\n                    }\n                    // view initialization\n                    if ($scope.startDate)\n                        $scope.view.moment = utility_1.toMoment($scope.startDate, $scope.format, $scope.locale);\n                    else if (utility_1.isValidMoment($ctrl.$modelValue))\n                        $scope.view.moment = $ctrl.$modelValue.clone();\n                    $scope.view.update();\n                    $scope.view.render();\n                });\n                // model <-> view conversion\n                if ($attrs['ngModel']) {\n                    $ctrl.$parsers.push(function (viewValue) { return utility_1.updateMoment($ctrl.$modelValue, utility_1.valueToMoment(viewValue, $scope), $scope) || true; });\n                    $ctrl.$formatters.push(function (modelValue) { return utility_1.momentToValue(modelValue, $scope.format) || ''; });\n                    $ctrl.$viewChangeListeners.push(function () { if ($attrs['ngModel'] != $attrs['momentPicker'])\n                        $scope.value = $ctrl.$viewValue; });\n                    $ctrl.$validators.minDate = function (value) { return $scope.validate || !utility_1.isValidMoment(value) || $scope.limits.isAfterOrEqualMin(value); };\n                    $ctrl.$validators.maxDate = function (value) { return $scope.validate || !utility_1.isValidMoment(value) || $scope.limits.isBeforeOrEqualMax(value); };\n                }\n                // properties listeners\n                if ($attrs['ngModel'] != $attrs['momentPicker'])\n                    $scope.$watch('value', function (newValue, oldValue) {\n                        if (newValue !== oldValue)\n                            utility_1.setValue(newValue, $scope, $ctrl, $attrs);\n                    });\n                $scope.$watch(function () { return utility_1.momentToValue($ctrl.$modelValue, $scope.format); }, function (newViewValue, oldViewValue) {\n                    if (newViewValue == oldViewValue)\n                        return;\n                    var newModelValue = utility_1.valueToMoment(newViewValue, $scope);\n                    utility_1.setValue(newModelValue, $scope, $ctrl, $attrs);\n                    $scope.limits.checkValue();\n                    $scope.view.moment = (newModelValue || moment().locale($scope.locale)).clone();\n                    $scope.view.update();\n                    $scope.view.render();\n                    if (angular.isFunction($scope.change) && $attrs['change']) {\n                        var oldModelValue_1 = utility_1.valueToMoment(oldViewValue, $scope);\n                        $scope.$evalAsync(function () { return $scope.change({ newValue: newModelValue, oldValue: oldModelValue_1 }); });\n                    }\n                });\n                $scope.$watch(function () { return $ctrl.$modelValue && $ctrl.$modelValue.valueOf(); }, function () {\n                    var viewMoment = (utility_1.isValidMoment($ctrl.$modelValue) ? $ctrl.$modelValue : moment().locale($scope.locale)).clone();\n                    if (!viewMoment.isSame($scope.view.moment)) {\n                        $scope.view.moment = viewMoment;\n                        $scope.view.update();\n                        $scope.view.render();\n                    }\n                });\n                $scope.$watch('view.selected', function () { return $scope.view.render(); });\n                $scope.$watchGroup(['minView', 'maxView'], function () {\n                    // auto-detect minView/maxView\n                    $scope.views.detectMinMax();\n                    // limit startView\n                    $scope.startView = $scope.views.all[Math.max(Math.min($scope.views.all.indexOf($scope.startView), $scope.views.all.indexOf($scope.maxView)), $scope.views.all.indexOf($scope.minView))];\n                    $scope.view.selected = $scope.startView;\n                });\n                $scope.$watchGroup([\n                    function () { return utility_1.toValue($scope.minDate, $scope.format, $scope.locale); },\n                    function () { return utility_1.toValue($scope.maxDate, $scope.format, $scope.locale); }\n                ], function () {\n                    angular.forEach(['minDate', 'maxDate'], function (field) {\n                        $scope.limits[field] = utility_1.toMoment($scope[field], $scope.format, $scope.locale);\n                    });\n                    $scope.limits.checkValue();\n                    $scope.limits.checkView();\n                    $scope.view.render();\n                });\n                $scope.$watch(function () { return utility_1.toValue($scope.startDate, $scope.format, $scope.locale); }, function (newViewValue, oldViewValue) {\n                    if (newViewValue == oldViewValue)\n                        return;\n                    $scope.view.moment = utility_1.valueToMoment(newViewValue, $scope);\n                    $scope.view.update();\n                    $scope.view.render();\n                });\n                $attrs.$observe('locale', function (locale) { return $scope.locale = locale; });\n                $scope.$watch('locale', function (locale, previous) {\n                    if (!angular.isDefined(previous) || locale == previous)\n                        return;\n                    if (utility_1.isValidMoment($ctrl.$modelValue))\n                        utility_1.setValue($ctrl.$modelValue.locale(locale), $scope, $ctrl, $attrs);\n                    if (utility_1.isValidMoment($scope.view.moment))\n                        $scope.view.moment = $scope.view.moment.locale(locale);\n                    if (utility_1.isValidMoment($scope.limits.minDate))\n                        $scope.limits.minDate = $scope.limits.minDate.locale(locale);\n                    if (utility_1.isValidMoment($scope.limits.maxDate))\n                        $scope.limits.maxDate = $scope.limits.maxDate.locale(locale);\n                    $scope.view.render();\n                });\n                $scope.$watch('validate', $scope.limits.checkValue);\n                $scope.$watch('isOpen', function (isOpen) {\n                    if ($scope.inline)\n                        $scope.view.isOpen = true;\n                    else if (angular.isDefined(isOpen) && isOpen != $scope.view.isOpen)\n                        $scope.view.toggle();\n                });\n                // event listeners\n                var focusInput = function (e) {\n                    if (e)\n                        e.preventDefault();\n                    $scope.input[0].focus();\n                };\n                // use `touchstart` for iOS Safari, where click events aren't propogated under most circumstances.\n                $scope.input\n                    .on('focus click touchstart', function () { return $scope.$evalAsync($scope.view.open); })\n                    .on('blur', function () { return $scope.$evalAsync($scope.view.close); })\n                    .on('keydown', function (e) { if ($scope.keyboard)\n                    $scope.view.keydown(e); });\n                $element.on('click touchstart', function () { return focusInput(); });\n                $scope.container.on('mousedown', function (e) { return focusInput(e); });\n                angular.element(_this.$window).on('resize scroll', $scope.view.position);\n                // unbind events on destroy\n                $scope.$on('$destroy', function () {\n                    $scope.input.off('focus click touchstart blur keydown');\n                    $element.off('click touchstart');\n                    $scope.container.off('mousedown');\n                    $scope.picker.remove();\n                    angular.element(_this.$window).off('resize scroll', $scope.view.position);\n                });\n            });\n        };\n    }\n    return Directive;\n}());\nexports[\"default\"] = Directive;\n\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nexports.__esModule = true;\n/**\n * Offset getter method from jQuery: https://github.com/jquery/jquery/blob/3.1.1/src/offset.js#L78\n */\nexports.getOffset = function (element) {\n    if (!element)\n        return;\n    if (!element.getClientRects().length)\n        return { top: 0, left: 0 };\n    // https://github.com/jquery/jquery/blob/3.1.1/src/core.js#L220\n    var isWindow = function (obj) { return obj != null && obj === obj.window; };\n    var getWindow = function (elem) { return isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView; }; // tslint:disable-line:no-any\n    var rect = element.getBoundingClientRect();\n    if (!rect.width && !rect.height)\n        return rect;\n    var doc = element.ownerDocument;\n    var win = getWindow(doc);\n    var docElem = doc.documentElement;\n    return {\n        top: rect.top + win.pageYOffset - docElem.clientTop,\n        left: rect.left + win.pageXOffset - docElem.clientLeft\n    };\n};\n\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nexports.__esModule = true;\nvar angular = __webpack_require__(1);\nvar Provider = (function () {\n    function Provider() {\n        this.settings = {\n            locale: 'en',\n            format: 'L LTS',\n            minView: 'decade',\n            maxView: 'minute',\n            startView: 'year',\n            inline: false,\n            validate: true,\n            autoclose: true,\n            setOnSelect: false,\n            today: false,\n            keyboard: false,\n            showHeader: true,\n            leftArrow: '&larr;',\n            rightArrow: '&rarr;',\n            // Decade View\n            yearsFormat: 'YYYY',\n            // Year View\n            monthsFormat: 'MMM',\n            // Month View\n            daysFormat: 'D',\n            // Day View\n            hoursFormat: 'HH:[00]',\n            hoursStart: 0,\n            hoursEnd: 23,\n            // Hour View\n            minutesStep: 5,\n            minutesStart: 0,\n            minutesEnd: 59,\n            // Minute View\n            secondsFormat: 'ss',\n            secondsStep: 1,\n            secondsStart: 0,\n            secondsEnd: 59\n        };\n    }\n    Provider.prototype.options = function (options) {\n        angular.extend(this.settings, options);\n        return angular.copy(this.settings);\n    };\n    Provider.prototype.$get = function () {\n        return this.settings;\n    };\n    return Provider;\n}());\nexports[\"default\"] = Provider;\n\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nexports.__esModule = true;\nvar utility_1 = __webpack_require__(0);\nvar DayView = (function () {\n    function DayView($scope, $ctrl, provider) {\n        this.$scope = $scope;\n        this.$ctrl = $ctrl;\n        this.provider = provider;\n        this.perLine = 4;\n        this.rows = {};\n    }\n    DayView.prototype.render = function () {\n        var hour = this.$scope.view.moment.clone().startOf('day').hour(this.provider.hoursStart);\n        this.rows = {};\n        for (var h = 0; h <= this.provider.hoursEnd - this.provider.hoursStart; h++) {\n            var index = Math.floor(h / this.perLine), selectable = this.$scope.limits.isSelectable(hour, 'hour');\n            if (!this.rows[index])\n                this.rows[index] = [];\n            this.rows[index].push({\n                index: h,\n                label: hour.format(this.provider.hoursFormat),\n                year: hour.year(),\n                month: hour.month(),\n                date: hour.date(),\n                hour: hour.hour(),\n                \"class\": [\n                    this.$scope.keyboard && hour.isSame(this.$scope.view.moment, 'hour') ? 'highlighted' : '',\n                    !selectable ? 'disabled' : utility_1.isValidMoment(this.$ctrl.$modelValue) && hour.isSame(this.$ctrl.$modelValue, 'hour') ? 'selected' : ''\n                ].join(' ').trim(),\n                selectable: selectable\n            });\n            hour.add(1, 'hours');\n        }\n        // return title\n        return this.$scope.view.moment.format('LL');\n    };\n    DayView.prototype.set = function (hour) {\n        if (!hour.selectable)\n            return;\n        this.$scope.view.moment.year(hour.year).month(hour.month).date(hour.date).hour(hour.hour);\n        this.$scope.view.update();\n        this.$scope.view.change('hour');\n    };\n    return DayView;\n}());\nexports[\"default\"] = DayView;\n\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nexports.__esModule = true;\nvar utility_1 = __webpack_require__(0);\nvar DecadeView = (function () {\n    function DecadeView($scope, $ctrl, provider) {\n        this.$scope = $scope;\n        this.$ctrl = $ctrl;\n        this.provider = provider;\n        this.perLine = 4;\n        this.rows = {};\n    }\n    DecadeView.prototype.render = function () {\n        var year = this.$scope.view.moment.clone(), firstYear = Math.floor(year.year() / 10) * 10 - 1;\n        this.rows = {};\n        year.year(firstYear);\n        for (var y = 0; y < 12; y++) {\n            var index = Math.floor(y / this.perLine), selectable = this.$scope.limits.isSelectable(year, 'year');\n            if (!this.rows[index])\n                this.rows[index] = [];\n            this.rows[index].push({\n                index: year.year(),\n                label: year.format(this.provider.yearsFormat),\n                year: year.year(),\n                \"class\": [\n                    this.$scope.keyboard && year.isSame(this.$scope.view.moment, 'year') ? 'highlighted' : '',\n                    !selectable || [0, 11].indexOf(y) >= 0 ? 'disabled' : utility_1.isValidMoment(this.$ctrl.$modelValue) && year.isSame(this.$ctrl.$modelValue, 'year') ? 'selected' : ''\n                ].join(' ').trim(),\n                selectable: selectable\n            });\n            year.add(1, 'years');\n        }\n        // return title\n        return [year.subtract(2, 'years').format('YYYY'), year.subtract(9, 'years').format('YYYY')].reverse().join(' - ');\n    };\n    DecadeView.prototype.set = function (year) {\n        if (!year.selectable)\n            return;\n        this.$scope.view.moment.year(year.year);\n        this.$scope.view.update();\n        this.$scope.view.change('year');\n    };\n    return DecadeView;\n}());\nexports[\"default\"] = DecadeView;\n\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nexports.__esModule = true;\nvar angular = __webpack_require__(1);\nvar moment = __webpack_require__(2);\nvar utility_1 = __webpack_require__(0);\nvar HourView = (function () {\n    function HourView($scope, $ctrl, provider) {\n        this.$scope = $scope;\n        this.$ctrl = $ctrl;\n        this.provider = provider;\n        this.perLine = 4;\n        this.rows = {};\n    }\n    HourView.prototype.render = function () {\n        var i = 0, minute = this.$scope.view.moment.clone().startOf('hour').minute(this.provider.minutesStart), minutesFormat = this.provider.minutesFormat || moment.localeData(this.$scope.locale).longDateFormat('LT').replace(/[aA]/, '').trim();\n        this.rows = {};\n        for (var m = 0; m <= this.provider.minutesEnd - this.provider.minutesStart; m += this.provider.minutesStep) {\n            var index = Math.floor(i / this.perLine), selectable = this.$scope.limits.isSelectable(minute, 'minute');\n            if (!this.rows[index])\n                this.rows[index] = [];\n            this.rows[index].push({\n                index: minute.minute(),\n                label: minute.format(minutesFormat),\n                year: minute.year(),\n                month: minute.month(),\n                date: minute.date(),\n                hour: minute.hour(),\n                minute: minute.minute(),\n                \"class\": [\n                    this.$scope.keyboard && minute.isSame(this.$scope.view.moment, 'minute') ? 'highlighted' : '',\n                    !selectable ? 'disabled' : utility_1.isValidMoment(this.$ctrl.$modelValue) && minute.isSame(this.$ctrl.$modelValue, 'minute') ? 'selected' : ''\n                ].join(' ').trim(),\n                selectable: selectable\n            });\n            i++;\n            minute.add(this.provider.minutesStep, 'minutes');\n        }\n        if (this.$scope.keyboard)\n            this.highlightClosest();\n        // return title\n        return this.$scope.view.moment.clone().startOf('hour').format('lll');\n    };\n    HourView.prototype.set = function (minute) {\n        if (!minute.selectable)\n            return;\n        this.$scope.view.moment.year(minute.year).month(minute.month).date(minute.date).hour(minute.hour).minute(minute.minute);\n        this.$scope.view.update();\n        this.$scope.view.change('minute');\n    };\n    HourView.prototype.highlightClosest = function () {\n        var _this = this;\n        var minutes = [], minute;\n        angular.forEach(this.rows, function (row) {\n            angular.forEach(row, function (value) {\n                if (Math.abs(value.minute - _this.$scope.view.moment.minute()) < _this.provider.minutesStep)\n                    minutes.push(value);\n            });\n        });\n        minute = minutes.sort(function (value1, value2) {\n            return Math.abs(value1.minute - _this.$scope.view.moment.minute()) > Math.abs(value2.minute - _this.$scope.view.moment.minute()) ? 1 : 0;\n        })[0];\n        if (!minute || minute.minute - this.$scope.view.moment.minute() == 0)\n            return;\n        this.$scope.view.moment.year(minute.year).month(minute.month).date(minute.date).hour(minute.hour).minute(minute.minute);\n        this.$scope.view.update();\n        if (minute.selectable)\n            minute[\"class\"] = (minute[\"class\"] + ' highlighted').trim();\n    };\n    return HourView;\n}());\nexports[\"default\"] = HourView;\n\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nexports.__esModule = true;\nvar decadeView_1 = __webpack_require__(11);\nexports.DecadeView = decadeView_1[\"default\"];\nvar yearView_1 = __webpack_require__(16);\nexports.YearView = yearView_1[\"default\"];\nvar monthView_1 = __webpack_require__(15);\nexports.MonthView = monthView_1[\"default\"];\nvar dayView_1 = __webpack_require__(10);\nexports.DayView = dayView_1[\"default\"];\nvar hourView_1 = __webpack_require__(12);\nexports.HourView = hourView_1[\"default\"];\nvar minuteView_1 = __webpack_require__(14);\nexports.MinuteView = minuteView_1[\"default\"];\n\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nexports.__esModule = true;\nvar angular = __webpack_require__(1);\nvar utility_1 = __webpack_require__(0);\nvar MinuteView = (function () {\n    function MinuteView($scope, $ctrl, provider) {\n        this.$scope = $scope;\n        this.$ctrl = $ctrl;\n        this.provider = provider;\n        this.perLine = 6;\n        this.rows = {};\n    }\n    MinuteView.prototype.render = function () {\n        var i = 0, second = this.$scope.view.moment.clone().startOf('minute').second(this.provider.secondsStart);\n        this.rows = {};\n        for (var s = 0; s <= this.provider.secondsEnd - this.provider.secondsStart; s += this.provider.secondsStep) {\n            var index = Math.floor(i / this.perLine), selectable = this.$scope.limits.isSelectable(second, 'second');\n            if (!this.rows[index])\n                this.rows[index] = [];\n            this.rows[index].push({\n                index: second.second(),\n                label: second.format(this.provider.secondsFormat),\n                year: second.year(),\n                month: second.month(),\n                date: second.date(),\n                hour: second.hour(),\n                minute: second.minute(),\n                second: second.second(),\n                \"class\": [\n                    this.$scope.keyboard && second.isSame(this.$scope.view.moment, 'second') ? 'highlighted' : '',\n                    !selectable ? 'disabled' : utility_1.isValidMoment(this.$ctrl.$modelValue) && second.isSame(this.$ctrl.$modelValue, 'second') ? 'selected' : ''\n                ].join(' ').trim(),\n                selectable: selectable\n            });\n            i++;\n            second.add(this.provider.secondsStep, 'seconds');\n        }\n        if (this.$scope.keyboard)\n            this.highlightClosest();\n        // return title\n        return this.$scope.view.moment.clone().startOf('minute').format('lll');\n    };\n    MinuteView.prototype.set = function (second) {\n        if (!second.selectable)\n            return;\n        this.$scope.view.moment.year(second.year).month(second.month).date(second.date).hour(second.hour).minute(second.minute).second(second.second);\n        this.$scope.view.update();\n        this.$scope.view.change();\n    };\n    MinuteView.prototype.highlightClosest = function () {\n        var _this = this;\n        var seconds = [], second;\n        angular.forEach(this.rows, function (row) {\n            angular.forEach(row, function (value) {\n                if (Math.abs(value.second - _this.$scope.view.moment.second()) < _this.provider.secondsStep)\n                    seconds.push(value);\n            });\n        });\n        second = seconds.sort(function (value1, value2) {\n            return Math.abs(value1.second - _this.$scope.view.moment.second()) > Math.abs(value2.second - _this.$scope.view.moment.second()) ? 1 : 0;\n        })[0];\n        if (!second || second.second - this.$scope.view.moment.second() == 0)\n            return;\n        this.$scope.view.moment.year(second.year).month(second.month).date(second.date).hour(second.hour).minute(second.minute).second(second.second);\n        this.$scope.view.update();\n        if (second.selectable)\n            second[\"class\"] = (second[\"class\"] + ' highlighted').trim();\n    };\n    return MinuteView;\n}());\nexports[\"default\"] = MinuteView;\n\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nexports.__esModule = true;\nvar angular = __webpack_require__(1);\nvar moment = __webpack_require__(2);\nvar utility_1 = __webpack_require__(0);\nvar MonthView = (function () {\n    function MonthView($scope, $ctrl, provider) {\n        this.$scope = $scope;\n        this.$ctrl = $ctrl;\n        this.provider = provider;\n        this.perLine = moment.weekdays().length;\n        this.rows = [];\n    }\n    MonthView.prototype.render = function () {\n        var _this = this;\n        var month = this.$scope.view.moment.month(), day = this.$scope.view.moment.clone().startOf('month').startOf('week').hour(12), rows = {}, firstWeek = day.week(), lastWeek = firstWeek + 5;\n        this.rows = [];\n        for (var week = firstWeek; week <= lastWeek; week++)\n            rows[week] = Array.apply(null, Array(this.perLine)).map(function () {\n                var selectable = _this.$scope.limits.isSelectable(day, 'day');\n                var date = {\n                    index: day.date(),\n                    label: day.format(_this.provider.daysFormat),\n                    year: day.year(),\n                    month: day.month(),\n                    date: day.date(),\n                    \"class\": [\n                        _this.$scope.keyboard && day.isSame(_this.$scope.view.moment, 'day') ? 'highlighted' : '',\n                        !!_this.$scope.today && day.isSame(new Date(), 'day') ? 'today' : '',\n                        !selectable || day.month() != month ? 'disabled' : utility_1.isValidMoment(_this.$ctrl.$modelValue) && day.isSame(_this.$ctrl.$modelValue, 'day') ? 'selected' : ''\n                    ].join(' ').trim(),\n                    selectable: selectable\n                };\n                day.add(1, 'days');\n                return date;\n            });\n        // object to array - see https://github.com/indrimuska/angular-moment-picker/issues/9\n        angular.forEach(rows, function (row) { return _this.rows.push(row); });\n        // render headers\n        this.headers = moment.weekdays().map(function (d, i) { return moment().locale(_this.$scope.locale).startOf('week').add(i, 'day').format('dd'); });\n        // return title\n        return this.$scope.view.moment.format('MMMM YYYY');\n    };\n    MonthView.prototype.set = function (day) {\n        if (!day.selectable)\n            return;\n        this.$scope.view.moment.year(day.year).month(day.month).date(day.date);\n        this.$scope.view.update();\n        this.$scope.view.change('day');\n    };\n    return MonthView;\n}());\nexports[\"default\"] = MonthView;\n\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nexports.__esModule = true;\nvar moment = __webpack_require__(2);\nvar utility_1 = __webpack_require__(0);\nvar YearView = (function () {\n    function YearView($scope, $ctrl, provider) {\n        this.$scope = $scope;\n        this.$ctrl = $ctrl;\n        this.provider = provider;\n        this.perLine = 4;\n        this.rows = {};\n    }\n    YearView.prototype.render = function () {\n        var _this = this;\n        var month = this.$scope.view.moment.clone().startOf('year'), months = moment.monthsShort();\n        this.rows = {};\n        months.forEach(function (label, i) {\n            var index = Math.floor(i / _this.perLine), selectable = _this.$scope.limits.isSelectable(month, 'month');\n            if (!_this.rows[index])\n                _this.rows[index] = [];\n            _this.rows[index].push({\n                index: month.month(),\n                label: month.format(_this.provider.monthsFormat),\n                year: month.year(),\n                month: month.month(),\n                \"class\": [\n                    _this.$scope.keyboard && month.isSame(_this.$scope.view.moment, 'month') ? 'highlighted' : '',\n                    !selectable ? 'disabled' : utility_1.isValidMoment(_this.$ctrl.$modelValue) && month.isSame(_this.$ctrl.$modelValue, 'month') ? 'selected' : ''\n                ].join(' ').trim(),\n                selectable: selectable\n            });\n            month.add(1, 'months');\n        });\n        // return title\n        return this.$scope.view.moment.format('YYYY');\n    };\n    YearView.prototype.set = function (month) {\n        if (!month.selectable)\n            return;\n        this.$scope.view.moment.year(month.year).month(month.month);\n        this.$scope.view.update();\n        this.$scope.view.change('month');\n    };\n    return YearView;\n}());\nexports[\"default\"] = YearView;\n\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(5);\n__webpack_require__(3);\nmodule.exports = __webpack_require__(4);\n\n\n/***/ })\n/******/ ]);"
  },
  {
    "path": "dist/themes/README.md",
    "content": "# Themes\n\n## Default\n\n```html\n<link href=\"//cdn.rawgit.com/indrimuska/angular-moment-picker/master/dist/angular-moment-picker.min.css\" rel=\"stylesheet\">\n```\n\n***Decade view*** | ***Year view*** | ***Month view*** | ***Day view*** | ***Hour view*** | ***Minute view***\n:---:|:---:|:---:|:---:|:---:|:---:\n![Decade view](http://indrimuska.github.io/angular-moment-picker/img/themes/default/decade-view.png?) | ![Year view](http://indrimuska.github.io/angular-moment-picker/img/themes/default/year-view.png?) | ![Month view](http://indrimuska.github.io/angular-moment-picker/img/themes/default/month-view.png?) | ![Day view](http://indrimuska.github.io/angular-moment-picker/img/themes/default/day-view.png?) | ![Hour view](http://indrimuska.github.io/angular-moment-picker/img/themes/default/hour-view.png?) | ![Minute view](http://indrimuska.github.io/angular-moment-picker/img/themes/default/minute-view.png?)\n\n## Material UI\n\n```html\n<link href=\"//cdn.rawgit.com/indrimuska/angular-moment-picker/master/dist/angular-moment-picker.min.css\" rel=\"stylesheet\">\n<link href=\"//cdn.rawgit.com/indrimuska/angular-moment-picker/master/dist/themes/material-ui.min.css\" rel=\"stylesheet\">\n```\n\n***Decade view*** | ***Year view*** | ***Month view*** | ***Day view*** | ***Hour view*** | ***Minute view***\n:---:|:---:|:---:|:---:|:---:|:---:\n![Decade view](http://indrimuska.github.io/angular-moment-picker/img/themes/material-ui/decade-view.png?) | ![Year view](http://indrimuska.github.io/angular-moment-picker/img/themes/material-ui/year-view.png?) | ![Month view](http://indrimuska.github.io/angular-moment-picker/img/themes/material-ui/month-view.png?) | ![Day view](http://indrimuska.github.io/angular-moment-picker/img/themes/material-ui/day-view.png?) | ![Hour view](http://indrimuska.github.io/angular-moment-picker/img/themes/material-ui/hour-view.png?) | ![Minute view](http://indrimuska.github.io/angular-moment-picker/img/themes/material-ui/minute-view.png?)\n"
  },
  {
    "path": "dist/themes/material-ui.css",
    "content": "/*! Angular Moment Picker - v0.10.2 - http://indrimuska.github.io/angular-moment-picker - (c) 2015 Indri Muska - MIT */\n.moment-picker .moment-picker-container {\n  text-shadow: none;\n  -webkit-border-radius: 0;\n     -moz-border-radius: 0;\n          border-radius: 0;\n  padding: 0;\n}\n.moment-picker .header-view {\n  border: 1px solid #fff;\n}\n.moment-picker .header-view th {\n  background: #eee;\n  -webkit-border-radius: 0;\n     -moz-border-radius: 0;\n          border-radius: 0;\n  min-width: 40px;\n  height: 40px;\n}\n.moment-picker .header-view th:hover,\n.moment-picker td:hover {\n  background-color: #e0e0e0;\n}\n.moment-picker td {\n  -webkit-border-radius: 60px;\n     -moz-border-radius: 60px;\n          border-radius: 60px;\n}\n.moment-picker .moment-picker-specific-views {\n  padding: 4px 8px;\n}\n.moment-picker .moment-picker-specific-views table {\n  border-collapse: separate;\n  border-spacing: 3px;\n}\n.moment-picker .moment-picker-specific-views th {\n  background: none;\n  cursor: default;\n}\n.moment-picker .decade-view td,\n.moment-picker .year-view td {\n  min-width: 60px;\n  height: 60px;\n}\n.moment-picker .month-view td {\n  min-width: 33px;\n  height: 33px;\n}\n.moment-picker .day-view td,\n.moment-picker .hour-view td {\n  min-width: 60px;\n  height: 40px;\n}\n.moment-picker .minute-view table {\n  border-spacing: 2px;\n}\n.moment-picker .minute-view td {\n  min-width: 40px;\n  height: 40px;\n}\n"
  },
  {
    "path": "karma.conf.js",
    "content": "let webpackConfig = require('./webpack.config');\nlet generateJsonPlugin = require('generate-json-webpack-plugin');\n\nwebpackConfig.devtool = 'source-map';\nwebpackConfig.plugins = webpackConfig.plugins.filter(plugin => !(plugin instanceof generateJsonPlugin));\n\nmodule.exports = function (config) {\n\tconfig.set({\n\t\tfiles: [\n\t\t\t'node_modules/jquery/dist/jquery.js',\n\t\t\t'node_modules/angular/angular.js',\n\t\t\t'node_modules/angular-mocks/angular-mocks.js',\n\t\t\t'node_modules/moment/min/moment-with-locales.js',\n\t\t\t'src/index.ts',\n\t\t\t'tests/hacks.ts',\n\t\t\t'tests/**/!(hacks|utility).ts'\n\t\t],\n\t\tpreprocessors: {\n\t\t\t'**/*.ts': ['webpack']\n\t\t},\n\t\twebpack: webpackConfig,\n\t\twebpackMiddleware: {\n\t\t\tnoInfo: true,\n\t\t\tstats: 'errors-only'\n\t\t},\n\t\tmime: {\n\t\t\t'text/x-typescript': ['ts']\n\t\t},\n\t\tframeworks: ['jasmine'],\n\t\tbrowsers: ['PhantomJS'],\n\t\tsingleRun: true\n\t});\n};"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"angular-moment-picker\",\n  \"version\": \"0.10.2\",\n  \"description\": \"Angular Moment Picker is an AngularJS directive for date and time picker using Moment.js\",\n  \"main\": \"dist/angular-moment-picker.js\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/indrimuska/angular-moment-picker.git\"\n  },\n  \"keywords\": [\n    \"datepicker\",\n    \"timepicker\",\n    \"datetime\",\n    \"picker\",\n    \"calendar\",\n    \"moment.js\",\n    \"angular\"\n  ],\n  \"author\": \"Indri Muska <indrimuska@gmail.com>\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/indrimuska/angular-moment-picker/issues\"\n  },\n  \"homepage\": \"http://indrimuska.github.io/angular-moment-picker\",\n  \"scripts\": {\n    \"build\": \"webpack\",\n    \"minify\": \"webpack && webpack -p\",\n    \"release\": \"npm run test && webpack --define increase='patch' && webpack -p\",\n    \"test\": \"node ./node_modules/karma/bin/karma start\"\n  },\n  \"dependencies\": {\n    \"angular\": \"^1.3\",\n    \"moment\": \"^2.16.0\"\n  },\n  \"devDependencies\": {\n    \"@types/angular\": \"^1.5.21\",\n    \"@types/angular-mocks\": \"^1.5.8\",\n    \"@types/jasmine\": \"^2.5.38\",\n    \"@types/node\": \"^6.0.52\",\n    \"angular-mocks\": \"^1.6.1\",\n    \"autoprefixer\": \"^6.5.4\",\n    \"css-loader\": \"^0.28.1\",\n    \"extract-text-webpack-plugin\": \"^2.1.0\",\n    \"generate-json-webpack-plugin\": \"^0.2.1\",\n    \"html-loader\": \"^0.4.5\",\n    \"jasmine\": \"^2.6.0\",\n    \"jquery\": \"^3.1.1\",\n    \"karma\": \"^1.7.0\",\n    \"karma-jasmine\": \"^1.1.0\",\n    \"karma-phantomjs-launcher\": \"^1.0.4\",\n    \"karma-webpack\": \"^2.0.3\",\n    \"less\": \"^2.7.1\",\n    \"less-loader\": \"^4.0.3\",\n    \"postcss\": \"^5.2.6\",\n    \"postcss-loader\": \"^2.0.5\",\n    \"semver\": \"^5.3.0\",\n    \"style-loader\": \"^0.17.0\",\n    \"ts-loader\": \"^2.0.3\",\n    \"tslint\": \"^4.1.1\",\n    \"tslint-loader\": \"^3.5.3\",\n    \"typescript\": \"^2.1.4\",\n    \"webpack\": \"^2.5.1\"\n  }\n}"
  },
  {
    "path": "src/definitions.d.ts",
    "content": "import * as angular from 'angular';\nimport * as moment from 'moment';\nimport { IProviderOptions } from './provider';\n\nexport type ViewString = 'decade' | 'year' | 'month' | 'day' | 'hour' | 'minute';\n\nexport type Value = string | number;\n\nexport type Position = 'top left' | 'top right' | 'bottom left' | 'bottom right';\n\nexport interface IDirectiveScope extends ng.IScope {\n\tvalue?: Value;\n\tmodel?: moment.Moment;\n\tlocale?: string;\n\tformat?: string;\n\tminView?: ViewString;\n\tmaxView?: ViewString;\n\tstartView?: ViewString;\n\tminDate?: Value;\n\tmaxDate?: Value;\n\tstartDate?: Value;\n\tdisabled?: boolean;\n\tposition?: Position;\n\tinline?: boolean;\n\tvalidate?: boolean;\n\tautoclose?: boolean;\n\tsetOnSelect?: boolean;\n\tisOpen?: boolean;\n\ttoday?: boolean;\n\tkeyboard?: boolean;\n\tadditions?: {\n\t\ttop?: string;\n\t\tbottom?: string\n\t};\n\tchange?: (context: any) => boolean;\n\tselectable?: (context: any) => boolean;\n}\n\nexport interface IUtility {\n\tisValidMoment: (value: any) => boolean;\n\ttoValue: (date: any) => Value;\n\ttoMoment: (date: any) => moment.Moment;\n\tmomentToValue: (momentObject: moment.Moment) => Value;\n\tvalueToMoment: (formattedValue: Value) => moment.Moment;\n\tsetValue: (value: any) => void;\n}\n\nexport interface IViewItem {\n\tindex: number;\n\tlabel: string;\n\tyear?: number;\n\tmonth?: number;\n\tdate?: number;\n\thour?: number;\n\tminute?: number;\n\tsecond?: number;\n\tclass: string;\n\tselectable: boolean;\n}\n\nexport interface IView {\n\tperLine: number;\n\theaders?: string[];\n\trows: { [index: number]: IViewItem[] };\n\trender(): string; // return view title\n\tset(value: IViewItem): void;\n\thighlightClosest?(): void;\n}\n\nexport interface IViewHeaderButton {\n\tselectable: boolean;\n\tlabel: string;\n\tset: () => void;\n}\n\nexport interface IDirectiveScopeInternal extends IDirectiveScope, IProviderOptions {\n\t// utilities\n\tlimits: {\n\t\tminDate: moment.Moment;\n\t\tmaxDate: moment.Moment;\n\t\tisAfterOrEqualMin: (value: moment.Moment, precision?: moment.unitOfTime.StartOf) => boolean;\n\t\tisBeforeOrEqualMax: (value: moment.Moment, precision?: moment.unitOfTime.StartOf) => boolean;\n\t\tisSelectable: (value: moment.Moment, precision?: moment.unitOfTime.StartOf) => boolean;\n\t\tcheckValue: () => void;\n\t\tcheckView: () => void;\n\t};\n\n\t// views\n\tviews: {\n\t\tall: ViewString[];\n\t\tprecisions: { [viewString: string]: moment.unitOfTime.StartOf };\n\t\tformats: { [viewString: string]: string };\n\t\tdetectMinMax: () => void;\n\n\t\t// specific view controllers\n\t\tdecade: IView;\n\t\tyear: IView;\n\t\tmonth: IView;\n\t\tday: IView;\n\t\thour: IView;\n\t\tminute: IView;\n\t};\n\n\t// current view\n\tview: {\n\t\tmoment: moment.Moment;\n\t\tvalue: Value;\n\t\tisOpen: boolean;\n\t\tselected: ViewString;\n\t\tupdate: () => void;\n\t\ttoggle: () => void;\n\t\topen: () => void;\n\t\tclose: () => void;\n\t\tposition: () => void;\n\t\tkeydown: (e: JQueryEventObject) => void;\n\n\t\t// utility\n\t\tunit: () => number;\n\t\tprecision: () => moment.unitOfTime.DurationConstructor;\n\n\t\t// header\n\t\ttitle: string;\n\t\tprevious: IViewHeaderButton;\n\t\tnext: IViewHeaderButton;\n\t\tsetParentView: () => void;\n\n\t\t// body\n\t\trender: () => void;\n\t\tchange: (view?: ViewString) => void;\n\t};\n\n\t// limits detection\n\tdetectedMinView: ViewString;\n\tdetectedMaxView: ViewString;\n\n\t// elements\n\tpicker: ng.IAugmentedJQuery;\n\tcontainer: ng.IAugmentedJQuery;\n\tinput: ng.IAugmentedJQuery;\n}\n\nexport interface IModelValidators extends ng.IModelValidators {\n\tminDate: (modelValue: moment.Moment, viewValue: string) => boolean;\n\tmaxDate: (modelValue: moment.Moment, viewValue: string) => boolean;\n}\n\nexport interface IModelController extends ng.INgModelController {\n\t$validators: IModelValidators;\n\t$modelValue: moment.Moment;\n\t$viewValue: string;\n}"
  },
  {
    "path": "src/directive.ts",
    "content": "import * as angular from 'angular';\nimport * as moment from 'moment';\nimport { getOffset } from './helpers';\nimport { IProviderOptions } from './provider';\nimport { ViewString, IView, IViewItem, IDirectiveScopeInternal, IModelController } from './definitions';\nimport { DecadeView, YearView, MonthView, DayView, HourView, MinuteView } from './views';\nimport { isValidMoment, toValue, toMoment, momentToValue, valueToMoment, setValue, updateMoment, KEYS } from './utility';\n\nconst templateHtml = require('./template.tpl.html');\n\nexport default class Directive implements ng.IDirective {\n\tpublic restrict   = 'A';\n\tpublic require    = '?ngModel';\n\tpublic transclude = true;\n\tpublic template   = templateHtml;\n\tpublic scope      = {\n\t\tvalue:       '=?momentPicker',\n\t\tmodel:       '=?ngModel',\n\t\tlocale:      '@?',\n\t\tformat:      '@?',\n\t\tminView:     '@?',\n\t\tmaxView:     '@?',\n\t\tstartView:   '@?',\n\t\tminDate:     '=?',\n\t\tmaxDate:     '=?',\n\t\tstartDate:   '=?',\n\t\tdisabled:    '=?disable',\n\t\tposition:    '@?',\n\t\tinline:      '@?',\n\t\tvalidate:    '=?',\n\t\tautoclose:   '=?',\n\t\tsetOnSelect: '=?',\n\t\tisOpen:      '=?',\n\t\ttoday:       '=?',\n\t\tkeyboard:    '=?',\n\t\tshowHeader:  '=?',\n\t\tadditions:   '=?',\n\t\tchange:      '&?',\n\t\tselectable:  '&?'\n\t};\n\n\tconstructor(\n\t\tprivate $timeout: ng.ITimeoutService,\n\t\tprivate $sce: ng.ISCEService,\n\t\tprivate $log: ng.ILogService,\n\t\tprivate $window: ng.IWindowService,\n\t\tprivate provider: IProviderOptions,\n\t\tprivate $compile: ng.ICompileService,\n\t\tprivate $templateCache: ng.ITemplateCacheService) { }\n\n\tpublic link = ($scope: IDirectiveScopeInternal, $element: ng.IAugmentedJQuery, $attrs: ng.IAttributes, $ctrl: IModelController, $transclude: ng.ITranscludeFunction) => {\n\t\t$transclude(($transElement: ng.IAugmentedJQuery) => {\n\t\t\t// one-way binding attributes\n\t\t\tangular.forEach([\n\t\t\t\t'locale', 'format', 'minView', 'maxView', 'startView', 'position', 'inline', 'validate', 'autoclose', 'setOnSelect', 'today',\n\t\t\t\t'keyboard', 'showHeader', 'leftArrow', 'rightArrow', 'additions'\n\t\t\t], (attr: string) => {\n\t\t\t\tif (!angular.isDefined($scope[attr])) $scope[attr] = this.provider[attr];\n\t\t\t\tif (!angular.isDefined($attrs[attr])) $attrs[attr] = $scope[attr];\n\t\t\t});\n\n\t\t\t// check if ngModel has been set\n\t\t\tif (!$attrs['ngModel']) $ctrl = <IModelController>{};\n\n\t\t\t// limits\n\t\t\t$scope.limits = {\n\t\t\t\tminDate: toMoment($scope.minDate, $scope.format, $scope.locale),\n\t\t\t\tmaxDate: toMoment($scope.maxDate, $scope.format, $scope.locale),\n\t\t\t\tisAfterOrEqualMin: (value: moment.Moment, precision?: moment.unitOfTime.StartOf) => {\n\t\t\t\t\treturn !angular.isDefined($scope.limits.minDate) || value.isAfter($scope.limits.minDate, precision) || value.isSame($scope.limits.minDate, precision);\n\t\t\t\t},\n\t\t\t\tisBeforeOrEqualMax: (value: moment.Moment, precision?: moment.unitOfTime.StartOf) => {\n\t\t\t\t\treturn !angular.isDefined($scope.limits.maxDate) || value.isBefore($scope.limits.maxDate, precision) || value.isSame($scope.limits.maxDate, precision);\n\t\t\t\t},\n\t\t\t\tisSelectable: (value: moment.Moment, precision?: moment.unitOfTime.StartOf) => {\n\t\t\t\t\tlet selectable: boolean = true;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (angular.isFunction($scope.selectable) && $attrs['selectable']) selectable = $scope.selectable({ date: value, type: precision });\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tthis.$log.error(e);\n\t\t\t\t\t}\n\t\t\t\t\treturn $scope.limits.isAfterOrEqualMin(value, precision) && $scope.limits.isBeforeOrEqualMax(value, precision) && selectable;\n\t\t\t\t},\n\t\t\t\tcheckValue: () => {\n\t\t\t\t\tif (!isValidMoment($ctrl.$modelValue) || !$scope.validate) return;\n\t\t\t\t\tif (!$scope.limits.isAfterOrEqualMin($ctrl.$modelValue)) setValue($scope.limits.minDate, $scope, $ctrl, $attrs);\n\t\t\t\t\tif (!$scope.limits.isBeforeOrEqualMax($ctrl.$modelValue)) setValue($scope.limits.maxDate, $scope, $ctrl, $attrs);\n\t\t\t\t},\n\t\t\t\tcheckView: () => {\n\t\t\t\t\tif (!angular.isDefined($scope.view.moment)) $scope.view.moment = moment().locale($scope.locale);\n\t\t\t\t\tif (!$scope.limits.isAfterOrEqualMin($scope.view.moment)) $scope.view.moment = $scope.limits.minDate.clone();\n\t\t\t\t\tif (!$scope.limits.isBeforeOrEqualMax($scope.view.moment)) $scope.view.moment = $scope.limits.maxDate.clone();\n\t\t\t\t\t$scope.view.update();\n\t\t\t\t\t$scope.view.render();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t$scope.views = {\n\t\t\t\tall: ['decade', 'year', 'month', 'day', 'hour', 'minute'],\n\t\t\t\tprecisions: { decade: 'year', year: 'month', month: 'date', day: 'hour', hour: 'minute', minute: 'second' },\n\t\t\t\t// for each view, `$scope.views.formats` object contains the available moment formats\n\t\t\t\t// formats present in more views are used to perform min/max view detection (i.e. 'LTS', 'LT', ...)\n\t\t\t\tformats: {\n\t\t\t\t\tdecade:\t'Y{1,2}(?!Y)|YYYY|[Ll]{1,4}(?!T)',\n\t\t\t\t\t\t\t/* formats: Y,YY,YYYY,L,LL,LLL,LLLL,l,ll,lll,llll */\n\t\t\t\t\tyear:\t'M{1,4}(?![Mo])|Mo|Q',\n\t\t\t\t\t\t\t/* formats: M,MM,MMM,MMM,Mo,Q */\n\t\t\t\t\tmonth:\t'[Dd]{1,4}(?![Ddo])|DDDo|[Dd]o|[Ww]{1,2}(?![Wwo])|[Ww]o|[Ee]|L{1,2}(?!T)|l{1,2}',\n\t\t\t\t\t\t\t/* formats: D,DD,DDD,DDDD,d,dd,ddd,dddd,DDDo,Do,do,W,WW,w,ww,Wo,wo,E,e,L,LL,l,ll */\n\t\t\t\t\tday:\t'[Hh]{1,2}|LTS?',\n\t\t\t\t\t\t\t/* formats: H,HH,h,hh,LT,LTS */\n\t\t\t\t\thour:\t'm{1,2}|[Ll]{3,4}|LT(?!S)',\n\t\t\t\t\t\t\t/* formats: m,mm,LLL,LLLL,lll,llll,LT */\n\t\t\t\t\tminute:\t's{1,2}|S{1,}|X|LTS'\n\t\t\t\t\t\t\t/* formats: s,ss,S,SS,SSS..,X,LTS */\n\t\t\t\t},\n\t\t\t\tdetectMinMax: () => {\n\t\t\t\t\t$scope.detectedMinView = $scope.detectedMaxView = undefined;\n\t\t\t\t\tif (!$scope.format) return;\n\n\t\t\t\t\tlet minView, maxView;\n\t\t\t\t\tangular.forEach($scope.views.formats, (formats, view) => {\n\t\t\t\t\t\tlet regexp = new RegExp('(' + formats + ')(?![^\\[]*\\])', 'g');\n\t\t\t\t\t\tif (!$scope.format.match(regexp)) return;\n\t\t\t\t\t\tif (!angular.isDefined(minView)) minView = view;\n\t\t\t\t\t\tmaxView = view;\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!angular.isDefined(minView)) minView = 0;\n\t\t\t\t\telse minView = Math.max(0, $scope.views.all.indexOf(minView));\n\t\t\t\t\tif (!angular.isDefined(maxView)) maxView = $scope.views.all.length - 1;\n\t\t\t\t\telse maxView = Math.min($scope.views.all.length - 1, $scope.views.all.indexOf(maxView));\n\n\t\t\t\t\tif (minView > $scope.views.all.indexOf($scope.minView)) $scope.minView = $scope.views.all[minView];\n\t\t\t\t\tif (maxView < $scope.views.all.indexOf($scope.maxView)) $scope.maxView = $scope.views.all[maxView];\n\n\t\t\t\t\t// save detected min/max view to use them to update the model value properly\n\t\t\t\t\t$scope.detectedMinView = $scope.views.all[minView];\n\t\t\t\t\t$scope.detectedMaxView = $scope.views.all[maxView];\n\t\t\t\t},\n\t\t\t\t// specific views\n\t\t\t\tdecade:\tnew DecadeView\t($scope, $ctrl, this.provider),\n\t\t\t\tyear:\tnew YearView\t($scope, $ctrl, this.provider),\n\t\t\t\tmonth:\tnew MonthView\t($scope, $ctrl, this.provider),\n\t\t\t\tday:\tnew DayView\t\t($scope, $ctrl, this.provider),\n\t\t\t\thour:\tnew HourView\t($scope, $ctrl, this.provider),\n\t\t\t\tminute:\tnew MinuteView\t($scope, $ctrl, this.provider),\n\t\t\t};\n\t\t\t$scope.view = {\n\t\t\t\tmoment: undefined,\n\t\t\t\tvalue: undefined,\n\t\t\t\tisOpen: false,\n\t\t\t\tselected: $scope.startView,\n\t\t\t\tupdate: () => { $scope.view.value = momentToValue($scope.view.moment, $scope.format); },\n\t\t\t\ttoggle: () => { $scope.view.isOpen ? $scope.view.close() : $scope.view.open(); },\n\t\t\t\topen: () => {\n\t\t\t\t\tif ($scope.disabled || $scope.view.isOpen || $scope.inline) return;\n\n\t\t\t\t\t$scope.isOpen = true;\n\t\t\t\t\t$scope.view.isOpen = true;\n\t\t\t\t\tdocument.body.appendChild($scope.picker[0]);\n\t\t\t\t\t$scope.view.position();\n\t\t\t\t},\n\t\t\t\tclose: () => {\n\t\t\t\t\tif (!$scope.view.isOpen || $scope.inline) return;\n\n\t\t\t\t\t$scope.isOpen = false;\n\t\t\t\t\t$scope.view.isOpen = false;\n\t\t\t\t\t$scope.view.selected = $scope.startView;\n\t\t\t\t\t$scope.picker[0].parentNode.removeChild($scope.picker[0]);\n\t\t\t\t},\n\t\t\t\tposition: () => {\n\t\t\t\t\tif (!$scope.view.isOpen || $scope.position || $scope.inline) return;\n\n\t\t\t\t\tlet element = $element[0],\n\t\t\t\t\t\tpicker = $scope.picker.children()[0],\n\t\t\t\t\t\thasClassTop = $scope.picker.hasClass('top'),\n\t\t\t\t\t\thasClassRight = $scope.picker.hasClass('right'),\n\t\t\t\t\t\toffset = getOffset($element[0]),\n\t\t\t\t\t\ttop = offset.top - this.$window.pageYOffset,\n\t\t\t\t\t\tleft = offset.left - this.$window.pageXOffset,\n\t\t\t\t\t\twinWidth = this.$window.innerWidth,\n\t\t\t\t\t\twinHeight = this.$window.innerHeight,\n\t\t\t\t\t\tshouldHaveClassTop = top + this.$window.pageYOffset - picker.offsetHeight > 0 && top > winHeight / 2,\n\t\t\t\t\t\tshouldHaveClassRight = left + picker.offsetWidth > winWidth,\n\t\t\t\t\t\tpickerTop = offset.top + (shouldHaveClassTop ? 0 : element.offsetHeight) + 'px',\n\t\t\t\t\t\tpickerLeft = offset.left + 'px',\n\t\t\t\t\t\tpickerWidth = element.offsetWidth + 'px';\n\n\t\t\t\t\tif (!hasClassTop && shouldHaveClassTop) $scope.picker.addClass('top');\n\t\t\t\t\tif (hasClassTop && !shouldHaveClassTop) $scope.picker.removeClass('top');\n\t\t\t\t\tif (!hasClassRight && shouldHaveClassRight) $scope.picker.addClass('right');\n\t\t\t\t\tif (hasClassRight && !shouldHaveClassRight) $scope.picker.removeClass('right');\n\t\t\t\t\tif ($scope.picker.css('top') !== pickerTop) $scope.picker.css('top', pickerTop);\n\t\t\t\t\tif ($scope.picker.css('left') !== pickerLeft) $scope.picker.css('left', pickerLeft);\n\t\t\t\t\tif ($scope.picker.css('width') !== pickerWidth) $scope.picker.css('width', pickerWidth);\n\t\t\t\t},\n\t\t\t\tkeydown: (e) => {\n\t\t\t\t\tlet view: IView = $scope.views[$scope.view.selected],\n\t\t\t\t\t\tprecision   = $scope.views.precisions[$scope.view.selected].replace('date', 'day'),\n\t\t\t\t\t\tsingleUnit  = this.provider[precision + 'sStep'] || 1,\n\t\t\t\t\t\toperation   = [KEYS.up, KEYS.left].indexOf(e.keyCode) >= 0 ? 'subtract' : 'add',\n\t\t\t\t\t\thighlight   = (vertical?: boolean) => {\n\t\t\t\t\t\t\tlet unitMultiplier = vertical ? view.perLine : 1,\n\t\t\t\t\t\t\t\tnextDate = $scope.view.moment.clone()[operation](singleUnit * unitMultiplier, precision);\n\t\t\t\t\t\t\tif ($scope.limits.isSelectable(nextDate, <moment.unitOfTime.StartOf>precision)) {\n\t\t\t\t\t\t\t\t$scope.view.moment = nextDate;\n\t\t\t\t\t\t\t\t$scope.view.update();\n\t\t\t\t\t\t\t\t$scope.view.render();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\n\t\t\t\t\tswitch (e.keyCode) {\n\t\t\t\t\t\tcase KEYS.up:\n\t\t\t\t\t\tcase KEYS.down:\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tif (!$scope.view.isOpen) $scope.view.open();\n\t\t\t\t\t\t\telse highlight(true);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase KEYS.left:\n\t\t\t\t\t\tcase KEYS.right:\n\t\t\t\t\t\t\tif (!$scope.view.isOpen) break;\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\thighlight();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase KEYS.enter:\n\t\t\t\t\t\t\tif (!$scope.view.isOpen) break;\n\t\t\t\t\t\t\t$scope.view.change(<ViewString>precision);\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase KEYS.escape:\n\t\t\t\t\t\t\t$scope.view.toggle();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\t$scope.$evalAsync();\n\t\t\t\t},\n\t\t\t\t// utility\n\t\t\t\tunit: () => $scope.view.selected == 'decade' ? 10 : 1,\n\t\t\t\tprecision: () => <moment.unitOfTime.DurationConstructor>$scope.view.selected.replace('decade', 'year'),\n\t\t\t\t// header\n\t\t\t\ttitle: '',\n\t\t\t\tprevious: {\n\t\t\t\t\tlabel: this.$sce.trustAsHtml($scope.leftArrow),\n\t\t\t\t\tselectable: true,\n\t\t\t\t\tset: () => {\n\t\t\t\t\t\tif ($scope.view.previous.selectable) {\n\t\t\t\t\t\t\t$scope.view.moment.subtract($scope.view.unit(), $scope.view.precision());\n\t\t\t\t\t\t\t$scope.view.update();\n\t\t\t\t\t\t\t$scope.view.render();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tnext: {\n\t\t\t\t\tselectable: true,\n\t\t\t\t\tlabel: this.$sce.trustAsHtml($scope.rightArrow),\n\t\t\t\t\tset: () => {\n\t\t\t\t\t\tif ($scope.view.next.selectable) {\n\t\t\t\t\t\t\t$scope.view.moment.add($scope.view.unit(), $scope.view.precision());\n\t\t\t\t\t\t\t$scope.view.update();\n\t\t\t\t\t\t\t$scope.view.render();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tsetParentView: () => { $scope.view.change($scope.views.all[Math.max(0, $scope.views.all.indexOf($scope.view.selected) - 1)]); },\n\t\t\t\t// body\n\t\t\t\trender: () => {\n\t\t\t\t\tlet momentPrevious = $scope.view.moment.clone().startOf($scope.view.precision()).subtract($scope.view.unit(), $scope.view.precision()),\n\t\t\t\t\t\tmomentNext = $scope.view.moment.clone().endOf($scope.view.precision()).add($scope.view.unit(), $scope.view.precision());\n\n\t\t\t\t\t$scope.view.previous.selectable = $scope.limits.isAfterOrEqualMin(momentPrevious, $scope.view.precision());\n\t\t\t\t\t$scope.view.previous.label = this.$sce.trustAsHtml($scope.view.previous.selectable ? $scope.leftArrow : '&nbsp;');\n\t\t\t\t\t$scope.view.next.selectable = $scope.limits.isBeforeOrEqualMax(momentNext, $scope.view.precision());\n\t\t\t\t\t$scope.view.next.label = this.$sce.trustAsHtml($scope.view.next.selectable ? $scope.rightArrow : '&nbsp;');\n\t\t\t\t\t$scope.view.title = $scope.views[$scope.view.selected].render();\n\t\t\t\t},\n\t\t\t\tchange: (view) => {\n\t\t\t\t\tlet nextView = $scope.views.all.indexOf(view),\n\t\t\t\t\t\tminView  = $scope.views.all.indexOf($scope.minView),\n\t\t\t\t\t\tmaxView  = $scope.views.all.indexOf($scope.maxView);\n\t\t\t\t\t\n\t\t\t\t\tconst update = () => {\n\t\t\t\t\t\tsetValue($scope.view.moment, $scope, $ctrl, $attrs);\n\t\t\t\t\t\t$scope.view.update();\n\t\t\t\t\t\tif ($attrs['ngModel']) $ctrl.$commitViewValue();\n\t\t\t\t\t};\n\n\t\t\t\t\tif ($scope.setOnSelect) update();\n\t\t\t\t\tif (nextView < 0 || nextView > maxView) {\n\t\t\t\t\t\tif (!$scope.setOnSelect) update();\n\t\t\t\t\t\tif ($scope.autoclose) this.$timeout($scope.view.close);\n\t\t\t\t\t} else if (nextView >= minView) $scope.view.selected = view;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// creation\n\t\t\t$element.prepend($transElement);\n\t\t\t$scope.picker = angular.element($element[0].querySelectorAll('.moment-picker'));\n\t\t\t$scope.container = angular.element($scope.picker[0].querySelectorAll('.moment-picker-container'));\n\t\t\t$scope.input = $element[0].tagName.toLowerCase() != 'input' && $element[0].querySelectorAll('input').length > 0\n\t\t\t\t? angular.element($element[0].querySelectorAll('input'))\n\t\t\t\t: angular.element($element[0]);\n\t\t\t$scope.input.addClass('moment-picker-input').attr('tabindex', 0);\n\t\t\t($scope.position || '').split(' ').forEach((className: string) => $scope.picker.addClass(className));\n\t\t\tif (!$scope.inline) $scope.picker[0].parentNode.removeChild($scope.picker[0]);\n\t\t\telse {\n\t\t\t\t$element.after($scope.picker);\n\t\t\t\t$scope.picker.addClass('inline');\n\t\t\t}\n\n\t\t\t// transclude scope to template additions\n\t\t\tthis.$timeout(() => {\n\t\t\t\tangular.forEach($scope.additions || {}, (tempalteUrl: string, key: 'top' | 'bottom') => {\n\t\t\t\t\tlet placeholder = angular.element($scope.container[0].querySelector('.moment-picker-addition.' + key));\n\t\t\t\t\tlet template = this.$templateCache.get<string>(tempalteUrl);\n\t\t\t\t\tlet compiled = this.$compile(template)($scope.$parent);\n\t\t\t\t\tplaceholder.append(compiled);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// initialization\n\t\t\t$scope.views.detectMinMax();\n\t\t\t$scope.limits.checkView();\n\t\t\t// model controller is initialized after linking function\n\t\t\tthis.$timeout(() => {\n\t\t\t\tif ($attrs['ngModel']) {\n\t\t\t\t\tif (!$ctrl.$modelValue && $scope.value) $ctrl.$setViewValue($scope.value);\n\t\t\t\t\t$ctrl.$commitViewValue();\n\t\t\t\t\t$ctrl.$render();\n\t\t\t\t} else {\n\t\t\t\t\tif ($scope.value) $ctrl.$modelValue = valueToMoment($scope.value, $scope);\n\t\t\t\t}\n\t\t\t\t// view initialization\n\t\t\t\tif ($scope.startDate) $scope.view.moment = toMoment($scope.startDate, $scope.format, $scope.locale);\n\t\t\t\telse if (isValidMoment($ctrl.$modelValue)) $scope.view.moment = $ctrl.$modelValue.clone();\n\t\t\t\t$scope.view.update();\n\t\t\t\t$scope.view.render();\n\t\t\t});\n\n\t\t\t// model <-> view conversion\n\t\t\tif ($attrs['ngModel']) {\n\t\t\t\t$ctrl.$parsers.push((viewValue) => updateMoment($ctrl.$modelValue, valueToMoment(viewValue, $scope), $scope) || true);\n\t\t\t\t$ctrl.$formatters.push((modelValue) => momentToValue(modelValue, $scope.format) || '');\n\t\t\t\t$ctrl.$viewChangeListeners.push(() => { if ($attrs['ngModel'] != $attrs['momentPicker']) $scope.value = $ctrl.$viewValue; });\n\t\t\t\t$ctrl.$validators.minDate = (value) => $scope.validate || !isValidMoment(value) || $scope.limits.isAfterOrEqualMin(value);\n\t\t\t\t$ctrl.$validators.maxDate = (value) => $scope.validate || !isValidMoment(value) || $scope.limits.isBeforeOrEqualMax(value);\n\t\t\t}\n\n\t\t\t// properties listeners\n\t\t\tif ($attrs['ngModel'] != $attrs['momentPicker'])\n\t\t\t\t$scope.$watch('value', (newValue: string, oldValue: string) => {\n\t\t\t\t\tif (newValue !== oldValue) setValue(newValue, $scope, $ctrl, $attrs);\n\t\t\t\t});\n\t\t\t$scope.$watch(() => momentToValue($ctrl.$modelValue, $scope.format), (newViewValue, oldViewValue) => {\n\t\t\t\tif (newViewValue == oldViewValue) return;\n\n\t\t\t\tlet newModelValue = valueToMoment(newViewValue, $scope);\n\t\t\t\tsetValue(newModelValue, $scope, $ctrl, $attrs);\n\t\t\t\t$scope.limits.checkValue();\n\t\t\t\t$scope.view.moment = (newModelValue || moment().locale($scope.locale)).clone();\n\t\t\t\t$scope.view.update();\n\t\t\t\t$scope.view.render();\n\t\t\t\tif (angular.isFunction($scope.change) && $attrs['change']) {\n\t\t\t\t\tlet oldModelValue = valueToMoment(oldViewValue, $scope);\n\t\t\t\t\t$scope.$evalAsync(() => $scope.change({ newValue: newModelValue, oldValue: oldModelValue }));\n\t\t\t\t}\n\t\t\t});\n\t\t\t$scope.$watch(() => $ctrl.$modelValue && $ctrl.$modelValue.valueOf(), () => {\n\t\t\t\tlet viewMoment = (isValidMoment($ctrl.$modelValue) ? $ctrl.$modelValue : moment().locale($scope.locale)).clone();\n\t\t\t\tif (!viewMoment.isSame($scope.view.moment)) {\n\t\t\t\t\t$scope.view.moment = viewMoment;\n\t\t\t\t\t$scope.view.update();\n\t\t\t\t\t$scope.view.render();\n\t\t\t\t}\n\t\t\t});\n\t\t\t$scope.$watch('view.selected', () => $scope.view.render());\n\t\t\t$scope.$watchGroup(['minView', 'maxView'], () => {\n\t\t\t\t// auto-detect minView/maxView\n\t\t\t\t$scope.views.detectMinMax();\n\t\t\t\t// limit startView\n\t\t\t\t$scope.startView = $scope.views.all[\n\t\t\t\t\tMath.max(\n\t\t\t\t\t\tMath.min(\n\t\t\t\t\t\t\t$scope.views.all.indexOf($scope.startView),\n\t\t\t\t\t\t\t$scope.views.all.indexOf($scope.maxView)\n\t\t\t\t\t\t),\n\t\t\t\t\t\t$scope.views.all.indexOf($scope.minView)\n\t\t\t\t\t)\n\t\t\t\t];\n\t\t\t\t$scope.view.selected = $scope.startView;\n\t\t\t});\n\t\t\t$scope.$watchGroup([\n\t\t\t\t() => toValue($scope.minDate, $scope.format, $scope.locale),\n\t\t\t\t() => toValue($scope.maxDate, $scope.format, $scope.locale)\n\t\t\t], () => {\n\t\t\t\tangular.forEach(['minDate', 'maxDate'], (field: string) => {\n\t\t\t\t\t$scope.limits[field] = toMoment($scope[field], $scope.format, $scope.locale);\n\t\t\t\t});\n\t\t\t\t$scope.limits.checkValue();\n\t\t\t\t$scope.limits.checkView();\n\t\t\t\t$scope.view.render();\n\t\t\t});\n\t\t\t$scope.$watch(() => toValue($scope.startDate, $scope.format, $scope.locale), (newViewValue, oldViewValue) => {\n\t\t\t\tif (newViewValue == oldViewValue) return;\n\n\t\t\t\t$scope.view.moment = valueToMoment(newViewValue, $scope);\n\t\t\t\t$scope.view.update();\n\t\t\t\t$scope.view.render();\n\t\t\t});\n\t\t\t$attrs.$observe('locale', (locale: string) => $scope.locale = locale);\n\t\t\t$scope.$watch('locale', (locale: string, previous: string) => {\n\t\t\t\tif (!angular.isDefined(previous) || locale == previous) return;\n\t\t\t\tif (isValidMoment($ctrl.$modelValue)) setValue($ctrl.$modelValue.locale(locale), $scope, $ctrl, $attrs);\n\t\t\t\tif (isValidMoment($scope.view.moment)) $scope.view.moment = $scope.view.moment.locale(locale);\n\t\t\t\tif (isValidMoment($scope.limits.minDate)) $scope.limits.minDate = $scope.limits.minDate.locale(locale);\n\t\t\t\tif (isValidMoment($scope.limits.maxDate)) $scope.limits.maxDate = $scope.limits.maxDate.locale(locale);\n\t\t\t\t$scope.view.render();\n\t\t\t});\n\t\t\t$scope.$watch('validate', $scope.limits.checkValue);\n\t\t\t$scope.$watch('isOpen', (isOpen: boolean) => {\n\t\t\t\tif ($scope.inline) $scope.view.isOpen = true;\n\t\t\t\telse if (angular.isDefined(isOpen) && isOpen != $scope.view.isOpen) $scope.view.toggle();\n\t\t\t});\n\n\t\t\t// event listeners\n\t\t\tconst focusInput = (e?: JQueryEventObject) => {\n\t\t\t\tif (e) e.preventDefault();\n\t\t\t\t$scope.input[0].focus();\n\t\t\t};\n\t\t\t// use `touchstart` for iOS Safari, where click events aren't propogated under most circumstances.\n\t\t\t$scope.input\n\t\t\t\t.on('focus click touchstart', () => $scope.$evalAsync($scope.view.open))\n\t\t\t\t.on('blur',        \t\t\t  () => $scope.$evalAsync($scope.view.close))\n\t\t\t\t.on('keydown',     \t\t\t  (e) => { if ($scope.keyboard) $scope.view.keydown(e); });\n\t\t\t$element.on('click touchstart', () => focusInput());\n\t\t\t$scope.container.on('mousedown', (e: JQueryEventObject) => focusInput(e));\n\t\t\tangular.element(this.$window).on('resize scroll', $scope.view.position);\n\n\t\t\t// unbind events on destroy\n\t\t\t$scope.$on('$destroy', () => {\n\t\t\t\t$scope.input.off('focus click touchstart blur keydown');\n\t\t\t\t$element.off('click touchstart');\n\t\t\t\t$scope.container.off('mousedown');\n\t\t\t\t$scope.picker.remove();\n\t\t\t\tangular.element(this.$window).off('resize scroll', $scope.view.position);\n\t\t\t});\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "src/helpers.ts",
    "content": "/**\n * Offset getter method from jQuery: https://github.com/jquery/jquery/blob/3.1.1/src/offset.js#L78\n */\nexport const getOffset = (element: HTMLElement): { top: number, left: number } => {\n\tif (!element) return;\n\tif (!element.getClientRects().length) return { top: 0, left: 0 };\n\n\t// https://github.com/jquery/jquery/blob/3.1.1/src/core.js#L220\n\tconst isWindow = (obj: Window): boolean => obj != null && obj === obj.window;\n\tconst getWindow = (elem: any): Window => isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView; // tslint:disable-line:no-any\n\n\tlet rect: ClientRect = element.getBoundingClientRect();\n\tif (!rect.width && !rect.height) return rect;\n\t\n\tlet doc: Document        = element.ownerDocument;\n\tlet win: Window          = getWindow(doc);\n\tlet docElem: HTMLElement = doc.documentElement;\n\n\treturn {\n\t\ttop: rect.top + win.pageYOffset - docElem.clientTop,\n\t\tleft: rect.left + win.pageXOffset - docElem.clientLeft\n\t};\n};"
  },
  {
    "path": "src/index.less",
    "content": "@border-color:              #f0f3f4;\n@text-color:                #404040;\n@text-shadow:               fade(#fff, 90%);\n@background:                #fff;\n@box-shadow-color:          fade(#000, 7.5%);\n\n@today-fg:                  #404040;\n@today-fg-shadow:           fade(#fff, 90%);\n@today-bg:                  #e4eef5;\n\n@hover-bg-color:            #fafbfb;\n@hover-bg-image:            linear-gradient(#f0f3f4, @hover-bg-color);\n@disabled-fg:               #abbbc7;\n\n@highlighted-bg-image:      radial-gradient(transparent, fade(#000, 15%));\n\n@selected-fg:               #fff;\n@selected-fg-shadow:        0 -1px 0 fade(#000, 30%);\n@selected-bg-color:         #45b1e8;\n@selected-bg-image:         linear-gradient(#45b1e8, #3097de);\n@selected-border-color:     #3ca0dd;\n\n.moment-picker-input { cursor: pointer; }\n.moment-picker {\n    position: absolute;\n    z-index: 1060;\n\n    .moment-picker-container {\n        color: @text-color;\n        min-width: 15em;\n        background: @background;\n        padding: 4px;\n        border: 1px solid @border-color;\n        border-radius: 4px;\n        position: absolute;\n        margin-top: 4px;\n        margin-left: -.5em;\n        box-shadow: 0 2px 4px @box-shadow-color;\n        &:before, &:after { content: ''; display: block; width: 0; height: 0; border: 8px solid transparent; border-top: none; position: absolute; top: -9px; left: 15px; }\n        &:before { border-bottom-color: @border-color; border-width: 9px; }\n        &:after { border-bottom-color: @background; margin-top: 1px; margin-left: 1px; }\n    }\n\n    // inline picker\n    &.inline {\n        display: block;\n        position: relative;\n        .moment-picker-container {\n            position: relative;\n            margin: 0;\n            &:before, &:after { content: none; }\n        }\n    }\n\n    // picker on top\n    &.top .moment-picker-container {\n        bottom: 100%;\n        margin-top: auto;\n        margin-bottom: 4px;\n        &:before, &:after { border: 8px solid transparent; border-bottom: none; top: auto; bottom: -9px; }\n        &:before { border-top-color: @border-color; border-width: 9px; }\n        &:after { border-top-color: @background; margin-top: auto; margin-bottom: 1px; }\n    }\n\n    // picker on right\n    &.right .moment-picker-container {\n        right: 0;\n        margin-left: auto;\n        margin-right: -.5em;\n        &:before, &:after { left: auto; right: 15px; }\n        &:after { margin-left: auto; margin-right: 1px; }\n    }\n\n    // all views\n    table { border-collapse: collapse; border-spacing: 0; min-width: 100%; table-layout: fixed; }\n    th {\n        font-weight: bold;\n        &:first-child, &:last-child { width: 2em; }\n    }\n    th, td {\n        padding: 0;\n        text-align: center;\n        min-width: 2em;\n        height: 2em;\n        text-shadow: 0 1px 0 @text-shadow;\n        cursor: pointer;\n        border-radius: 4px;\n        &:hover { background-color: @hover-bg-color; background-image: @hover-bg-image; }\n        &.disabled, &.disabled:hover { color: @disabled-fg; background: none; cursor: default; }\n    }\n    td {\n        &.today { background: @today-bg; color: @today-fg; text-shadow: 0 1px 0 @today-fg-shadow; }\n        &.selected { color: @selected-fg; text-shadow: @selected-fg-shadow; border-color: @selected-border-color; background-color: @selected-bg-color; background-image: @selected-bg-image; }\n        &.highlighted { background-image: @highlighted-bg-image; }\n    }\n\n    // decade view, year view\n    .decade-view td,\n    .year-view td { height: 3.4em; }\n\n    // month view\n    .month-view {\n        .moment-picker-specific-views th { background: none; cursor: default; }\n        td { width: 1.4285714286em; }\n    }\n\n    // day view, hour view\n    .day-view td,\n    .hour-view td { height: 2.3333333333em; }\n\n    // minute view\n    .minute-view td { height: 1.8em; }\n}"
  },
  {
    "path": "src/index.ts",
    "content": "import * as angular from 'angular';\nimport Provider from './provider';\nimport Directive from './directive';\n\nangular\n\t.module('moment-picker', [])\n\t.provider('momentPicker', [() => new Provider()])\n\t.directive('momentPicker', [\n\t\t'$timeout', '$sce', '$log', '$window', 'momentPicker', '$compile', '$templateCache',\n\t\t($timeout: ng.ITimeoutService, $sce: ng.ISCEService, $log: ng.ILogService, $window: ng.IWindowService, momentPicker: Provider,\n\t\t$compile: ng.ICompileService, $templateCache: ng.ITemplateCacheService) => {\n\t\t\treturn new Directive($timeout, $sce, $log, $window, momentPicker, $compile, $templateCache);\n\t\t}\n\t]);\n\nexport { Provider, Directive };"
  },
  {
    "path": "src/provider.ts",
    "content": "import * as angular from 'angular';\nimport { ViewString, Position } from './definitions';\n\nexport interface IProviderOptions {\n\tlocale?: string;\n\tformat?: string;\n\tminView?: ViewString;\n\tmaxView?: ViewString;\n\tstartView?: ViewString;\n\tposition?: Position;\n\tinline?: boolean;\n\tvalidate?: boolean;\n\tautoclose?: boolean;\n\tsetOnSelect?: boolean;\n\ttoday?: boolean;\n\tkeyboard?: boolean;\n\tshowHeader?: boolean;\n\tleftArrow?: string;\n\trightArrow?: string;\n\t\n\t// Decade View\n\tyearsFormat?: string;\n\t\n\t// Year View\n\tmonthsFormat?: string;\n\t\n\t// Month View\n\tdaysFormat?: string;\n\t\n\t// Day View\n\thoursFormat?: string;\n\thoursStart?: number;\n\thoursEnd?: number;\n\t\n\t// Hour View\n\tminutesFormat?: string;\n\tminutesStep?: number;\n\tminutesStart?: number;\n\tminutesEnd?: number;\n\n\t// Minute View\n\tsecondsFormat?: string;\n\tsecondsStep?: number;\n\tsecondsStart?: number;\n\tsecondsEnd?: number;\n}\n\nexport default class Provider implements angular.IServiceProvider {\n\tprivate settings: IProviderOptions = <IProviderOptions>{\n\t\tlocale: 'en',\n\t\tformat: 'L LTS',\n\t\tminView: 'decade',\n\t\tmaxView: 'minute',\n\t\tstartView: 'year',\n\t\tinline: false,\n\t\tvalidate: true,\n\t\tautoclose: true,\n\t\tsetOnSelect: false,\n\t\ttoday: false,\n\t\tkeyboard: false,\n\t\tshowHeader: true,\n\t\tleftArrow: '&larr;',\n\t\trightArrow: '&rarr;',\n\t\t\n\t\t// Decade View\n\t\tyearsFormat: 'YYYY',\n\t\t\n\t\t// Year View\n\t\tmonthsFormat: 'MMM',\n\t\t\n\t\t// Month View\n\t\tdaysFormat: 'D',\n\t\t\n\t\t// Day View\n\t\thoursFormat: 'HH:[00]',\n\t\thoursStart: 0,\n\t\thoursEnd: 23,\n\t\t\n\t\t// Hour View\n\t\tminutesStep: 5,\n\t\tminutesStart: 0,\n\t\tminutesEnd: 59,\n\t\t\n\t\t// Minute View\n\t\tsecondsFormat: 'ss',\n\t\tsecondsStep: 1,\n\t\tsecondsStart: 0,\n\t\tsecondsEnd: 59\n\t};\n\t\n\tpublic options(options: IProviderOptions): IProviderOptions {\n\t\tangular.extend(this.settings, options);\n\t\treturn angular.copy(this.settings);\n\t}\n\t\n\tpublic $get(): IProviderOptions {\n\t\treturn this.settings;\n\t}\n}"
  },
  {
    "path": "src/template.tpl.html",
    "content": "<div class=\"moment-picker\">\n    <div class=\"moment-picker-container {{view.selected}}-view\"\n         ng-class=\"{'moment-picker-disabled': disabled, open: view.isOpen}\">\n        <div ng-if=\"additions.top\" class=\"moment-picker-addition top\"></div>\n        <table class=\"header-view\" ng-if=\"showHeader\">\n            <thead>\n                <tr>\n                    <th ng-class=\"{disabled: !view.previous.selectable}\" ng-bind-html=\"view.previous.label\" ng-click=\"view.previous.set()\"></th>\n                    <th ng-bind=\"view.title\" ng-click=\"view.setParentView()\"></th>\n                    <th ng-class=\"{disabled: !view.next.selectable}\" ng-bind-html=\"view.next.label\" ng-click=\"view.next.set()\"></th>\n                </tr>\n            </thead>\n        </table>\n        <div class=\"moment-picker-specific-views\">\n            <table>\n                <thead ng-if=\"views[view.selected].headers\">\n                    <tr>\n                        <th ng-repeat=\"header in views[view.selected].headers\" ng-bind=\"header\"></th>\n                    </tr>\n                </thead>\n                <tbody>\n                    <tr ng-repeat=\"row in views[view.selected].rows\">\n                        <td ng-repeat=\"item in row track by item.index\" ng-class=\"item.class\" ng-bind=\"item.label\"\n                            ng-click=\"!disabled && views[view.selected].set(item)\"></td>\n                    </tr>\n                </tbody>\n            </table>\n        </div>\n        <div ng-if=\"additions.bottom\" class=\"moment-picker-addition bottom\"></div>\n    </div>\n</div>"
  },
  {
    "path": "src/themes/material-ui.less",
    "content": "@cell-big-size:     60px;\n@cell-mid-size:     50px;\n@cell-def-size:     40px;\n@cell-min-size:     33px;\n@bg-gray:           #eee;\n@bg-dark-gray:      #e0e0e0;\n\n.moment-picker {\n    \n    .moment-picker-container {\n        text-shadow: none;\n        border-radius: 0;\n        padding: 0;\n    }\n    \n    .header-view {\n        border: 1px solid #fff;\n        th { background: @bg-gray; border-radius: 0; min-width: @cell-def-size; height: @cell-def-size; }\n    }\n    .header-view th, td {\n        &:hover { background-color: @bg-dark-gray; }\n    }\n    td { border-radius: @cell-big-size; }\n\n    .moment-picker-specific-views {\n        padding: 4px 8px;\n        table { border-collapse: separate; border-spacing: 3px; }\n        th { background: none; cursor: default; }\n    }\n\n    // specific view - custom sizes\n    .decade-view, .year-view {\n        td { min-width: @cell-big-size; height: @cell-big-size; }\n    }\n    .month-view {\n        td { min-width: @cell-min-size; height: @cell-min-size; }\n    }\n    .day-view, .hour-view {\n        td { min-width: @cell-big-size; height: @cell-def-size; }\n    }\n    .minute-view {\n        table { border-spacing: 2px; }\n        td { min-width: @cell-def-size; height: @cell-def-size; }\n    }\n}"
  },
  {
    "path": "src/utility.ts",
    "content": "import * as angular from 'angular';\nimport * as moment from 'moment';\nimport { Value, IDirectiveScopeInternal, IModelController, ViewString } from './definitions';\n\nexport const KEYS = { up: 38, down: 40, left: 37, right: 39, escape: 27, enter: 13 };\n\nexport const isValidMoment = (value: moment.Moment | Value): boolean => {\n\treturn moment.isMoment(value) && value.isValid();\n};\n\nexport const toValue = (date: moment.Moment | Value, format: string, locale: string): Value => {\n\tlet momentDate = <moment.Moment>date;\n\tif (!isValidMoment(date)) momentDate = toMoment(date, format, locale);\n\treturn momentToValue(momentDate, format);\n};\n\nexport const toMoment = (date: moment.Moment | Value, format: string, locale: string): moment.Moment => {\n\tlet momentDate = moment(date, format, locale);\n\tif (!isValidMoment(momentDate)) momentDate = undefined;\n\treturn momentDate;\n};\n\nexport const momentToValue = (momentObject: moment.Moment, format: string): Value => {\n\tif (!isValidMoment(momentObject)) return undefined;\n\treturn !format ? momentObject.valueOf() : momentObject.format(format);\n};\n\nexport const valueToMoment = (formattedValue: Value, $scope: IDirectiveScopeInternal): moment.Moment => {\n\tlet momentValue: moment.Moment;\n\tif (!formattedValue) return momentValue;\n\tif (!$scope.format) momentValue = moment(formattedValue);\n\telse momentValue = moment(formattedValue, $scope.format, $scope.locale);\n\tif ($scope.model) {\n\t\t// set value for each view precision (from Decade View to minView)\n\t\tconst views = $scope.views.all.slice(0, $scope.views.all.indexOf($scope.detectedMinView));\n\t\tangular.forEach(views, (view: ViewString) => {\n\t\t\tconst precision = $scope.views.precisions[view];\n\t\t\tmomentValue[precision]($scope.model[precision]());\n\t\t});\n\t}\n\treturn momentValue;\n};\n\nexport const setValue = (value: moment.Moment | Value, $scope: IDirectiveScopeInternal, $ctrl: IModelController, $attrs: ng.IAttributes): void => {\n\tlet modelValue = isValidMoment(value) ? (<moment.Moment>value).clone() : valueToMoment(<Value>value, $scope),\n\t\tviewValue = momentToValue(modelValue, $scope.format);\n\t$scope.model = updateMoment($scope.model, modelValue, $scope);\n\t$ctrl.$modelValue = updateMoment($ctrl.$modelValue, modelValue, $scope);\n\tif ($attrs['ngModel'] != $attrs['momentPicker']) $scope.value = viewValue;\n\tif ($attrs['ngModel']) {\n\t\t$ctrl.$setViewValue(viewValue);\n\t\t$ctrl.$render(); // render input value\n\t}\n};\n\nexport const updateMoment = (model: moment.Moment, value: moment.Moment, $scope: IDirectiveScopeInternal): moment.Moment => {\n\tif (!isValidMoment(model) || !value) model = value;\n\telse {\n\t\tif (!model.isSame(value)) {\n\t\t\t// set value for each view precision (from Decade View to maxView)\n\t\t\tconst views = $scope.views.all.slice(0, $scope.views.all.indexOf($scope.detectedMaxView) + 1);\n\t\t\tangular.forEach(views, (view: ViewString) => {\n\t\t\t\tconst precision = $scope.views.precisions[view];\n\t\t\t\tmodel[precision](value[precision]());\n\t\t\t});\n\t\t}\n\t}\n\treturn model;\n};"
  },
  {
    "path": "src/views/dayView.ts",
    "content": "import { IView, IViewItem, IDirectiveScopeInternal, IModelController } from '../definitions';\nimport { IProviderOptions } from '../provider';\nimport { isValidMoment } from '../utility';\n\nexport default class DayView implements IView {\n\tpublic perLine: number = 4;\n\tpublic rows: { [index: number]: IViewItem[] } = {};\n\n\tconstructor(\n\t\tprivate $scope: IDirectiveScopeInternal,\n\t\tprivate $ctrl: IModelController,\n\t\tprivate provider: IProviderOptions) { }\n\n\tpublic render(): string {\n\t\tlet hour = this.$scope.view.moment.clone().startOf('day').hour(this.provider.hoursStart);\n\n\t\tthis.rows = {};\n\t\tfor (let h = 0; h <= this.provider.hoursEnd - this.provider.hoursStart; h++) {\n\t\t\tlet index = Math.floor(h / this.perLine),\n\t\t\t\tselectable = this.$scope.limits.isSelectable(hour, 'hour');\n\n\t\t\tif (!this.rows[index]) this.rows[index] = [];\n\t\t\tthis.rows[index].push({\n\t\t\t\tindex: h, // this is to prevent DST conflicts\n\t\t\t\tlabel: hour.format(this.provider.hoursFormat),\n\t\t\t\tyear: hour.year(),\n\t\t\t\tmonth: hour.month(),\n\t\t\t\tdate: hour.date(),\n\t\t\t\thour: hour.hour(),\n\t\t\t\tclass: [\n\t\t\t\t\tthis.$scope.keyboard && hour.isSame(this.$scope.view.moment, 'hour') ? 'highlighted' : '',\n\t\t\t\t\t!selectable ? 'disabled' : isValidMoment(this.$ctrl.$modelValue) && hour.isSame(this.$ctrl.$modelValue, 'hour') ? 'selected' : ''\n\t\t\t\t].join(' ').trim(),\n\t\t\t\tselectable: selectable\n\t\t\t});\n\t\t\thour.add(1, 'hours');\n\t\t}\n\t\t// return title\n\t\treturn this.$scope.view.moment.format('LL');\n\t}\n\n\tpublic set(hour: IViewItem): void {\n\t\tif (!hour.selectable) return;\n\t\tthis.$scope.view.moment.year(hour.year).month(hour.month).date(hour.date).hour(hour.hour);\n\t\tthis.$scope.view.update();\n\t\tthis.$scope.view.change('hour');\n\t}\n}"
  },
  {
    "path": "src/views/decadeView.ts",
    "content": "import { IView, IViewItem, IDirectiveScopeInternal, IModelController } from '../definitions';\nimport { IProviderOptions } from '../provider';\nimport { isValidMoment } from '../utility';\n\nexport default class DecadeView implements IView {\n\tpublic perLine: number = 4;\n\tpublic rows: { [index: number]: IViewItem[] } = {};\n\n\tconstructor(\n\t\tprivate $scope: IDirectiveScopeInternal,\n\t\tprivate $ctrl: IModelController,\n\t\tprivate provider: IProviderOptions) { }\n\t\n\tpublic render(): string {\n\t\tlet year = this.$scope.view.moment.clone(),\n\t\t\tfirstYear = Math.floor(year.year() / 10) * 10 - 1;\n\n\t\tthis.rows = {};\n\t\tyear.year(firstYear);\n\t\tfor (let y = 0; y < 12; y++) {\n\t\t\tlet index = Math.floor(y / this.perLine),\n\t\t\t\tselectable = this.$scope.limits.isSelectable(year, 'year');\n\n\t\t\tif (!this.rows[index]) this.rows[index] = [];\n\t\t\tthis.rows[index].push(<IViewItem>{\n\t\t\t\tindex: year.year(),\n\t\t\t\tlabel: year.format(this.provider.yearsFormat),\n\t\t\t\tyear: year.year(),\n\t\t\t\tclass: [\n\t\t\t\t\tthis.$scope.keyboard && year.isSame(this.$scope.view.moment, 'year') ? 'highlighted' : '',\n\t\t\t\t\t!selectable || [0, 11].indexOf(y) >= 0 ? 'disabled' : isValidMoment(this.$ctrl.$modelValue) && year.isSame(this.$ctrl.$modelValue, 'year') ? 'selected' : ''\n\t\t\t\t].join(' ').trim(),\n\t\t\t\tselectable: selectable\n\t\t\t});\n\t\t\tyear.add(1, 'years');\n\t\t}\n\t\t// return title\n\t\treturn [year.subtract(2, 'years').format('YYYY'), year.subtract(9, 'years').format('YYYY')].reverse().join(' - ');\n\t}\n\n\tpublic set(year: IViewItem): void {\n\t\tif (!year.selectable) return;\n\t\tthis.$scope.view.moment.year(year.year);\n\t\tthis.$scope.view.update();\n\t\tthis.$scope.view.change('year');\n\t}\n}"
  },
  {
    "path": "src/views/hourView.ts",
    "content": "import * as angular from 'angular';\nimport * as moment from 'moment';\nimport { IView, IViewItem, IDirectiveScopeInternal, IModelController } from '../definitions';\nimport { IProviderOptions } from '../provider';\nimport { isValidMoment } from '../utility';\n\nexport default class HourView implements IView {\n\tpublic perLine: number = 4;\n\tpublic rows: { [index: number]: IViewItem[] } = {};\n\n\tconstructor(\n\t\tprivate $scope: IDirectiveScopeInternal,\n\t\tprivate $ctrl: IModelController,\n\t\tprivate provider: IProviderOptions) { }\n\n\tpublic render(): string {\n\t\tlet i = 0,\n\t\t\tminute = this.$scope.view.moment.clone().startOf('hour').minute(this.provider.minutesStart),\n\t\t\tminutesFormat = this.provider.minutesFormat || moment.localeData(this.$scope.locale).longDateFormat('LT').replace(/[aA]/, '').trim();\n\n\t\tthis.rows = {};\n\t\tfor (let m = 0; m <= this.provider.minutesEnd - this.provider.minutesStart; m += this.provider.minutesStep) {\n\t\t\tlet index = Math.floor(i / this.perLine),\n\t\t\t\tselectable = this.$scope.limits.isSelectable(minute, 'minute');\n\n\t\t\tif (!this.rows[index]) this.rows[index] = [];\n\t\t\tthis.rows[index].push(<IViewItem>{\n\t\t\t\tindex: minute.minute(),\n\t\t\t\tlabel: minute.format(minutesFormat),\n\t\t\t\tyear: minute.year(),\n\t\t\t\tmonth: minute.month(),\n\t\t\t\tdate: minute.date(),\n\t\t\t\thour: minute.hour(),\n\t\t\t\tminute: minute.minute(),\n\t\t\t\tclass: [\n\t\t\t\t\tthis.$scope.keyboard && minute.isSame(this.$scope.view.moment, 'minute') ? 'highlighted' : '',\n\t\t\t\t\t!selectable ? 'disabled' : isValidMoment(this.$ctrl.$modelValue) && minute.isSame(this.$ctrl.$modelValue, 'minute') ? 'selected' : ''\n\t\t\t\t].join(' ').trim(),\n\t\t\t\tselectable: selectable\n\t\t\t});\n\t\t\ti++;\n\t\t\tminute.add(this.provider.minutesStep, 'minutes');\n\t\t}\n\t\tif (this.$scope.keyboard) this.highlightClosest();\n\t\t// return title\n\t\treturn this.$scope.view.moment.clone().startOf('hour').format('lll');\n\t}\n\n\tpublic set(minute: IViewItem): void {\n\t\tif (!minute.selectable) return;\n\t\tthis.$scope.view.moment.year(minute.year).month(minute.month).date(minute.date).hour(minute.hour).minute(minute.minute);\n\t\tthis.$scope.view.update();\n\t\tthis.$scope.view.change('minute');\n\t}\n\n\tpublic highlightClosest(): void {\n\t\tlet minutes = <IViewItem[]>[], minute;\n\t\tangular.forEach(this.rows, (row) => {\n\t\t\tangular.forEach(row, (value) => {\n\t\t\t\tif (Math.abs(value.minute - this.$scope.view.moment.minute()) < this.provider.minutesStep) minutes.push(value);\n\t\t\t});\n\t\t});\n\t\tminute = minutes.sort((value1, value2) => {\n\t\t\treturn Math.abs(value1.minute - this.$scope.view.moment.minute()) > Math.abs(value2.minute - this.$scope.view.moment.minute()) ? 1 : 0;\n\t\t})[0];\n\t\tif (!minute || minute.minute - this.$scope.view.moment.minute() == 0) return;\n\t\tthis.$scope.view.moment.year(minute.year).month(minute.month).date(minute.date).hour(minute.hour).minute(minute.minute);\n\t\tthis.$scope.view.update();\n\t\tif (minute.selectable) minute.class = (minute.class + ' highlighted').trim();\n\t}\n}"
  },
  {
    "path": "src/views/index.ts",
    "content": "import DecadeView from './decadeView';\nimport YearView from './yearView';\nimport MonthView from './monthView';\nimport DayView from './dayView';\nimport HourView from './hourView';\nimport MinuteView from './minuteView';\n\nexport { DecadeView, YearView, MonthView, DayView, HourView, MinuteView };"
  },
  {
    "path": "src/views/minuteView.ts",
    "content": "import * as angular from 'angular';\nimport { IView, IViewItem, IDirectiveScopeInternal, IModelController } from '../definitions';\nimport { IProviderOptions } from '../provider';\nimport { isValidMoment } from '../utility';\n\nexport default class MinuteView implements IView {\n\tpublic perLine: number = 6;\n\tpublic rows: { [index: number]: IViewItem[] } = {};\n\n\tconstructor(\n\t\tprivate $scope: IDirectiveScopeInternal,\n\t\tprivate $ctrl: IModelController,\n\t\tprivate provider: IProviderOptions) { }\n\n\tpublic render(): string {\n\t\tlet i = 0,\n\t\t\tsecond = this.$scope.view.moment.clone().startOf('minute').second(this.provider.secondsStart);\n\n\t\tthis.rows = {};\n\t\tfor (let s = 0; s <= this.provider.secondsEnd - this.provider.secondsStart; s += this.provider.secondsStep) {\n\t\t\tlet index = Math.floor(i / this.perLine),\n\t\t\t\tselectable = this.$scope.limits.isSelectable(second, 'second');\n\n\t\t\tif (!this.rows[index]) this.rows[index] = [];\n\t\t\tthis.rows[index].push(<IViewItem>{\n\t\t\t\tindex: second.second(),\n\t\t\t\tlabel: second.format(this.provider.secondsFormat),\n\t\t\t\tyear: second.year(),\n\t\t\t\tmonth: second.month(),\n\t\t\t\tdate: second.date(),\n\t\t\t\thour: second.hour(),\n\t\t\t\tminute: second.minute(),\n\t\t\t\tsecond: second.second(),\n\t\t\t\tclass: [\n\t\t\t\t\tthis.$scope.keyboard && second.isSame(this.$scope.view.moment, 'second') ? 'highlighted' : '',\n\t\t\t\t\t!selectable ? 'disabled' : isValidMoment(this.$ctrl.$modelValue) && second.isSame(this.$ctrl.$modelValue, 'second') ? 'selected' : ''\n\t\t\t\t].join(' ').trim(),\n\t\t\t\tselectable: selectable\n\t\t\t});\n\t\t\ti++;\n\t\t\tsecond.add(this.provider.secondsStep, 'seconds');\n\t\t}\n\t\tif (this.$scope.keyboard) this.highlightClosest();\n\t\t// return title\n\t\treturn this.$scope.view.moment.clone().startOf('minute').format('lll');\n\t}\n\n\tpublic set(second: IViewItem): void {\n\t\tif (!second.selectable) return;\n\t\tthis.$scope.view.moment.year(second.year).month(second.month).date(second.date).hour(second.hour).minute(second.minute).second(second.second);\n\t\tthis.$scope.view.update();\n\t\tthis.$scope.view.change();\n\t}\n\n\tpublic highlightClosest(): void {\n\t\tlet seconds = <IViewItem[]>[], second;\n\t\tangular.forEach(this.rows, (row) => {\n\t\t\tangular.forEach(row, (value) => {\n\t\t\t\tif (Math.abs(value.second - this.$scope.view.moment.second()) < this.provider.secondsStep) seconds.push(value);\n\t\t\t});\n\t\t});\n\t\tsecond = seconds.sort((value1, value2) => {\n\t\t\treturn Math.abs(value1.second - this.$scope.view.moment.second()) > Math.abs(value2.second - this.$scope.view.moment.second()) ? 1 : 0;\n\t\t})[0];\n\t\tif (!second || second.second - this.$scope.view.moment.second() == 0) return;\n\t\tthis.$scope.view.moment.year(second.year).month(second.month).date(second.date).hour(second.hour).minute(second.minute).second(second.second);\n\t\tthis.$scope.view.update();\n\t\tif (second.selectable) second.class = (second.class + ' highlighted').trim();\n\t}\n}"
  },
  {
    "path": "src/views/monthView.ts",
    "content": "import * as angular from 'angular';\nimport * as moment from 'moment';\nimport { IView, IViewItem, IDirectiveScopeInternal, IModelController } from '../definitions';\nimport { IProviderOptions } from '../provider';\nimport { isValidMoment } from '../utility';\n\nexport default class MonthView implements IView {\n\tpublic perLine: number = moment.weekdays().length;\n\tpublic rows: { [index: number]: IViewItem[] } = [];\n\tpublic headers: string[];\n\n\tconstructor(\n\t\tprivate $scope: IDirectiveScopeInternal,\n\t\tprivate $ctrl: IModelController,\n\t\tprivate provider: IProviderOptions) { }\n\n\tpublic render(): string {\n\t\tlet month: number                         = this.$scope.view.moment.month(),\n\t\t\tday: moment.Moment                    = this.$scope.view.moment.clone().startOf('month').startOf('week').hour(12),\n\t\t\trows: { [week: number]: IViewItem[] } = {},\n\t\t\tfirstWeek: number                     = day.week(),\n\t\t\tlastWeek: number                      = firstWeek + 5;\n\n\t\tthis.rows = [];\n\t\tfor (let week = firstWeek; week <= lastWeek; week++)\n\t\t\trows[week] = Array.apply(null, Array(this.perLine)).map(() => {\n\t\t\t\tlet selectable = this.$scope.limits.isSelectable(day, 'day');\n\t\t\t\tlet date = <IViewItem>{\n\t\t\t\t\tindex: day.date(),\n\t\t\t\t\tlabel: day.format(this.provider.daysFormat),\n\t\t\t\t\tyear: day.year(),\n\t\t\t\t\tmonth: day.month(),\n\t\t\t\t\tdate: day.date(),\n\t\t\t\t\tclass: [\n\t\t\t\t\t\tthis.$scope.keyboard && day.isSame(this.$scope.view.moment, 'day') ? 'highlighted' : '',\n\t\t\t\t\t\t!!this.$scope.today && day.isSame(new Date(), 'day') ? 'today' : '',\n\t\t\t\t\t\t!selectable || day.month() != month ? 'disabled' : isValidMoment(this.$ctrl.$modelValue) && day.isSame(this.$ctrl.$modelValue, 'day') ? 'selected' : ''\n\t\t\t\t\t].join(' ').trim(),\n\t\t\t\t\tselectable: selectable\n\t\t\t\t};\n\t\t\t\tday.add(1, 'days');\n\t\t\t\treturn date;\n\t\t\t});\n\t\t// object to array - see https://github.com/indrimuska/angular-moment-picker/issues/9\n\t\tangular.forEach(rows, (row: IViewItem[]) => (<IViewItem[][]>this.rows).push(row));\n\t\t// render headers\n\t\tthis.headers = moment.weekdays().map((d: string, i: number) => moment().locale(this.$scope.locale).startOf('week').add(i, 'day').format('dd'));\n\t\t// return title\n\t\treturn this.$scope.view.moment.format('MMMM YYYY');\n\t}\n\t\n\tpublic set(day: IViewItem): void {\n\t\tif (!day.selectable) return;\n\t\tthis.$scope.view.moment.year(day.year).month(day.month).date(day.date);\n\t\tthis.$scope.view.update();\n\t\tthis.$scope.view.change('day');\n\t}\n}"
  },
  {
    "path": "src/views/yearView.ts",
    "content": "import * as moment from 'moment';\nimport { IView, IViewItem, IDirectiveScopeInternal, IModelController } from '../definitions';\nimport { IProviderOptions } from '../provider';\nimport { isValidMoment } from '../utility';\n\nclass YearView implements IView {\n\tpublic perLine: number = 4;\n\tpublic rows: { [index: number]: IViewItem[] } = {};\n\n\tconstructor(\n\t\tprivate $scope: IDirectiveScopeInternal,\n\t\tprivate $ctrl: IModelController,\n\t\tprivate provider: IProviderOptions) { }\n\n\tpublic render(): string {\n\t\tlet month = this.$scope.view.moment.clone().startOf('year'),\n\t\t\tmonths = moment.monthsShort();\n\n\t\tthis.rows = {};\n\t\tmonths.forEach((label, i) => {\n\t\t\tlet index = Math.floor(i / this.perLine),\n\t\t\t\tselectable = this.$scope.limits.isSelectable(month, 'month');\n\n\t\t\tif (!this.rows[index]) this.rows[index] = [];\n\t\t\tthis.rows[index].push(<IViewItem>{\n\t\t\t\tindex: month.month(),\n\t\t\t\tlabel: month.format(this.provider.monthsFormat),\n\t\t\t\tyear: month.year(),\n\t\t\t\tmonth: month.month(),\n\t\t\t\tclass: [\n\t\t\t\t\tthis.$scope.keyboard && month.isSame(this.$scope.view.moment, 'month') ? 'highlighted' : '',\n\t\t\t\t\t!selectable ? 'disabled' : isValidMoment(this.$ctrl.$modelValue) && month.isSame(this.$ctrl.$modelValue, 'month') ? 'selected' : ''\n\t\t\t\t].join(' ').trim(),\n\t\t\t\tselectable: selectable\n\t\t\t});\n\t\t\tmonth.add(1, 'months');\n\t\t});\n\t\t// return title\n\t\treturn this.$scope.view.moment.format('YYYY');\n\t}\n\n\tpublic set(month: IViewItem): void {\n\t\tif (!month.selectable) return;\n\t\tthis.$scope.view.moment.year(month.year).month(month.month);\n\t\tthis.$scope.view.update();\n\t\tthis.$scope.view.change('month');\n\t}\n}\n\nexport default YearView;"
  },
  {
    "path": "tests/elementCreation.ts",
    "content": "import * as angular from 'angular';\nimport * as test from './utility';\n\ndescribe('Element creation', () => {\n\t\n\t// init test\n\ttest.bootstrap();\n\t\n\t// check transcluded DIV content\n\tit('should transclude DIV content', () => {\n\t\tlet $element = test.buildTemplate('div', { class: 'my-content' }, 'My content');\n\t\t\n\t\texpect($element.length).toEqual(1);\n\t\texpect(angular.element($element[0]).hasClass('my-content')).toBe(true);\n\t\texpect(angular.element($element[0]).text()).toEqual('My content');\n\t});\n\t\n\t// check transcluded INPUT content\n\tit('should transclude INPUT content', () => {\n\t\tlet $element = test.buildTemplate('input', { class: 'my-content' });\n\t\t\n\t\texpect($element.length).toEqual(1);\n\t\texpect(angular.element($element[0]).hasClass('my-content')).toBe(true);\n\t});\n});\n"
  },
  {
    "path": "tests/hacks.ts",
    "content": "// extending jQLite\nangular.element.prototype.find = function (query: string) { // tslint:disable-line:only-arrow-functions\n\treturn angular.element(this[0].querySelectorAll(query));\n};\n\n// fix PhantomJS missing blur-on-clickout features\nlet lastFocused;\nangular.element(document.body).on('click', (event) => {\n\tif (lastFocused) lastFocused.trigger('blur');\n\tlastFocused = angular.element(event.target);\n});"
  },
  {
    "path": "tests/openClosePicker.ts",
    "content": "import * as angular from 'angular';\nimport * as test from './utility';\n\ndescribe('Open / close picker', () => {\n\t\n\tlet $inputContent: ng.IAugmentedJQuery;\n\tlet $divContent: ng.IAugmentedJQuery;\n\n\t// init test\n\ttest.bootstrap();\n\t\n\t// create two pickers for all tests\n\tbeforeEach(() => {\n\t\t// tslint:disable-next-line:no-unused-expression\n\t\t$inputContent = test.buildTemplate('input', { class: 'input-picker' });\n\t\t$divContent   = test.buildTemplate('div', { class: 'div-picker' });\n\t});\n\t\n\tconst isVisible = ($element: ng.IAugmentedJQuery) => test.getPicker($element).is(':visible');\n\t\n\t// open picker on click\n\tit('should open the picker on click', () => {\n\t\ttest.trigger($inputContent, 'click');\n\t\texpect(isVisible($inputContent)).toBe(true);\n\t\t\n\t\ttest.trigger($divContent, 'click');\n\t\texpect(isVisible($divContent)).toBe(true);\n\t});\n\t\n\t// open picker on focus\n\t// it('should open the picker on focus', () => {\n\t// \ttest.trigger($inputContent, 'focus');\n\t// \texpect(isVisible($inputContent)).toBe(true);\n\n\t// \ttest.trigger($divContent, 'focus');\n\t// \texpect(isVisible($divContent)).toBe(true);\n\t// });\n\t\n\t// close picker on blur\n\tit('should close the picker on blur', () => {\n\t\ttest.trigger($inputContent, 'click');\n\t\texpect(isVisible($inputContent)).toBe(true);\n\t\ttest.trigger($inputContent, 'blur');\n\t\texpect(isVisible($inputContent)).toBe(false);\n\t\t\n\t\ttest.trigger($divContent, 'click');\n\t\texpect(isVisible($divContent)).toBe(true);\n\t\ttest.trigger($divContent, 'blur');\n\t\texpect(isVisible($divContent)).toBe(false);\n\t});\n\t\n\t// close picker clicking on another one\n\tit('should close a picker when clicking to another picker', () => {\n\t\ttest.trigger($inputContent, 'click');\n\t\texpect(isVisible($inputContent)).toBe(true);\n\t\t\n\t\ttest.trigger($divContent, 'click');\n\t\texpect(isVisible($divContent)).toBe(true);\n\t\texpect(isVisible($inputContent)).toBe(false);\n\t});\n});\n"
  },
  {
    "path": "tests/properties/isOpen.ts",
    "content": "import * as angular from 'angular';\nimport * as test from '../utility';\n\ndescribe('Property `isOpen`', () => {\n\n\tlet $rootScope: ng.IRootScopeService;\n\n\t// init test\n\ttest.bootstrap();\n\n\t// get $rootScope service\n\tbeforeEach(inject((_$rootScope_: ng.IRootScopeService) => { // tslint:disable-line:variable-name\n\t\t// The injector unwraps the underscores (_) from around the parameter names when matching\n\t\t$rootScope = _$rootScope_;\n\t}));\n\t\n\tconst isVisible = ($element: ng.IAugmentedJQuery) => test.getPicker($element).is(':visible');\n\t\n\tit('should open the picker when set to `true`', () => {\n\t\tlet $picker = test.buildTemplate('input', { isOpen: true });\n\t\texpect(isVisible($picker)).toBe(true);\n\t});\n\n\tit('should close the picker when set to `false`', () => {\n\t\tlet $picker = test.buildTemplate('input', { isOpen: false });\n\t\texpect(isVisible($picker)).toBe(false);\n\t});\n\n\tit('should open and close the picker again when toggling value', () => {\n\t\tlet $scope  = $rootScope.$new(),\n\t\t\t$picker = test.buildTemplate('input', { isOpen: 'isOpen' }, undefined, $scope);\n\t\t\n\t\t// value to toggle\n\t\t[true, false, true].forEach((value: boolean) => {\n\t\t\t$scope['isOpen'] = value;\n\t\t\t$scope.$digest();\n\t\t\texpect(isVisible($picker)).toBe(value);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "tests/properties/keyboard.ts",
    "content": "import * as angular from 'angular';\nimport * as moment from 'moment';\nimport * as test from '../utility';\nimport { IProviderOptions } from '../../src/provider';\nimport { ViewString, IView } from '../../src/definitions';\nimport { KEYS } from '../../src/utility';\nimport * as views from '../../src/views';\n\ndescribe('Keyboard', () => {\n\n\t// init test\n\ttest.bootstrap();\n\n\t// available keyboard keys\n\ttype MockKeyboardKeys = 'up' | 'down' | 'left' | 'right' | 'enter' | 'escape' | 'a' | 'b' | 'c';\n\tKEYS['a'] = 65;\n\tKEYS['b'] = 66;\n\tKEYS['c'] = 67;\n\n\t// create an event object for each key to test\n\tconst EVENTS: { [name: string]: () => JQueryEventObject } = {};\n\tangular.forEach(KEYS, (code: number, key: MockKeyboardKeys) => {\n\t\tEVENTS[key] = () => $.Event('keydown', { keyCode: code });\n\t});\n\n\t/**\n\t * Utility function to trigger a custom event to a picker input field.\n\t * It first focus on the input to ensure the key is sent from the input field.\n\t */\n\tconst sendKey = ($input: ng.IAugmentedJQuery, key: MockKeyboardKeys): JQueryEventObject => {\n\t\t// get input focus first\n\t\ttest.trigger($input, 'focus');\n\t\t// get a fresh event\n\t\tlet event = EVENTS[key]();\n\t\t// and trigger it!\n\t\ttest.trigger($input, event);\n\t\treturn event;\n\t};\n\n\t// preventDefault()\n\tdescribe('default prevented event', () => {\n\t\tlet $input: ng.IAugmentedJQuery;\n\n\t\tbeforeEach(() => {\n\t\t\t$input = test.buildTemplate('input', { keyboard: 'true' });\n\t\t});\n\n\t\t// prevent default event\n\t\t['up', 'down', 'left', 'right', 'enter'].forEach((key: MockKeyboardKeys) => {\n\t\t\tit('should be set for ' + key.toUpperCase() + ' key', () => {\n\t\t\t\tlet event = sendKey($input, key);\n\t\t\t\texpect(event.isDefaultPrevented()).toBe(true);\n\t\t\t});\n\t\t});\n\n\t\t// do not prevent default event\n\t\tit('should be set for all the other keys', () => {\n\t\t\t['escape', 'a', 'b', 'c'].forEach((key: MockKeyboardKeys) => {\n\t\t\t\tlet event = sendKey($input, key);\n\t\t\t\texpect(event.isDefaultPrevented()).toBe(false);\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('picker open/close', () => {\n\t\tlet $input: ng.IAugmentedJQuery;\n\n\t\tconst isOpen = () => test.getPicker($input).is(':visible');\n\n\t\tbeforeEach(inject(($rootScope) => {\n\t\t\t$input = test.buildTemplate('input', { keyboard: 'true' });\n\t\t}));\n\n\t\t// close picker on pressing ESC\n\t\tit('should close the picker after pressing ESC key', () => {\n\t\t\t// focus on input\n\t\t\ttest.trigger($input, 'focus');\n\t\t\t// press ESC to close the picker (without clicking on the input first)\n\t\t\ttest.trigger($input, EVENTS['escape']());\n\t\t\t// check if the picker is closed\n\t\t\texpect(isOpen()).toBe(false);\n\t\t});\n\n\t\t// open picker after pressing UP or DOWN key\n\t\t['up', 'down'].forEach((key: MockKeyboardKeys) => {\n\t\t\tit('should open the picker after pressing ' + key.toUpperCase() + ' key', () => {\n\t\t\t\t// focus on input and close the picker\n\t\t\t\tsendKey($input, 'escape');\n\t\t\t\t// send key to be tested\n\t\t\t\ttest.trigger($input, EVENTS[key]());\n\t\t\t\t// check picker opening\n\t\t\t\texpect(isOpen()).toBe(true);\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('navigation', () => {\n\t\tlet locale = 'en';\n\t\tlet $scope: ng.IScope;\n\t\tlet formats: { [name: string]: string } = {};\n\t\tlet date = moment('2017-12-20 15:27:55', 'YYYY-MM-DD HH:mm:ss');\n\t\tlet previousSettings: IProviderOptions;\n\n\t\tconst pickerViews = ['decade', 'year', 'month', 'day', 'hour', 'minute'];\n\t\tconst commonOpts = { keyboard: 'true', ngModel: 'date', format: 'YYYY-MM-DD HH:mm:ss', class: 'input-picker', locale: locale };\n\t\tconst getHighlightedText = ($element: ng.IAugmentedJQuery) => test.getPicker($element).find('td.highlighted').text();\n\n\t\t// get formats from momentPickerProvider\n\t\tbeforeEach(inject(($rootScope: ng.IRootScopeService, momentPicker: IProviderOptions) => { // tslint:disable-line:variable-name\n\t\t\t$scope = $rootScope.$new();\n\t\t\t$scope['date'] = date;\n\t\t\t// get provider options\n\t\t\tpreviousSettings  = momentPicker;\n\t\t\tformats['decade'] = momentPicker.yearsFormat;\n\t\t\tformats['year']   = momentPicker.monthsFormat;\n\t\t\tformats['month']  = momentPicker.daysFormat;\n\t\t\tformats['day']    = momentPicker.hoursFormat;\n\t\t\tformats['hour']   = momentPicker.minutesFormat || moment.localeData(locale).longDateFormat('LT').replace(/[aA]/, '').trim();\n\t\t\tformats['minute'] = momentPicker.secondsFormat;\n\t\t\t// set steps on HourView\n\t\t\tmomentPicker.minutesStep = 1;\n\t\t\tmomentPicker.secondsStep = 1;\n\t\t}));\n\n\t\t// after each tests reset momentPickerProvider\n\t\tafterEach(inject((momentPicker: IProviderOptions) => {\n\t\t\tmomentPicker = previousSettings;\n\t\t}));\n\n\t\tpickerViews.forEach((view: ViewString, index: number) => {\n\t\t\tconst viewPrecision  = <moment.unitOfTime.DurationConstructor>(index === pickerViews.length - 1 ? 'seconds' : pickerViews[index + 1]);\n\t\t\tconst viewMultiplier = view == 'decade' ? 10 : 1;\n\t\t\tconst itemsPerLine   = { decade: 4, year: 4, month: 7, day: 4, hour: 4, minute: 6 }[view];\n\t\t\tconst keysOperations = { up: 'subtract', down: 'add', left: 'subtract', right: 'add' };\n\n\t\t\t// highlight on open\n\t\t\tit('should highlight the selected ' + view + ' on picker open', () => {\n\t\t\t\tlet options = angular.extend({ startView: view }, commonOpts),\n\t\t\t\t\t$input  = test.buildTemplate('input', options, undefined, $scope);\n\t\t\t\t\n\t\t\t\texpect(getHighlightedText($input)).toBe(date.format(formats[view]));\n\t\t\t});\n\n\t\t\t// highlight on key press\n\t\t\tangular.forEach(keysOperations, (operation: 'add' | 'subtract', key: MockKeyboardKeys) => {\n\t\t\t\tconst datesToShift = key == 'left' || key == 'right' ? 1 : itemsPerLine;\n\t\t\t\tconst title = 'should highlight ' + (keysOperations[key] == 'add' ? 'next' : 'previous') + ' ' +\n\t\t\t\t\tdatesToShift + ' ' + viewPrecision + (datesToShift != 1 ? 's' : '') + ' after pressing ' + key.toUpperCase() + ' key';\n\n\t\t\t\tit(title, () => {\n\t\t\t\t\tlet options   = angular.extend({ startView: view }, commonOpts),\n\t\t\t\t\t\t$input    = test.buildTemplate('input', options, undefined, $scope),\n\t\t\t\t\t\tfinalDate = date.clone()[operation](datesToShift, viewPrecision);\n\t\t\t\t\t\n\t\t\t\t\tsendKey($input, key);\n\t\t\t\t\texpect(getHighlightedText($input)).toBe(finalDate.format(formats[view]));\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t});\n});\n"
  },
  {
    "path": "tests/properties/locale.ts",
    "content": "import * as angular from 'angular';\nimport * as moment from 'moment';\nimport * as test from '../utility';\n\ndescribe('Property `locale`', () => {\n\n\tlet $rootScope: ng.IRootScopeService;\n\n\t// init test\n\ttest.bootstrap();\n\n\t// get $rootScope service\n\tbeforeEach(inject((_$rootScope_: ng.IRootScopeService) => { // tslint:disable-line:variable-name\n\t\t// The injector unwraps the underscores (_) from around the parameter names when matching\n\t\t$rootScope = _$rootScope_;\n\t}));\n\n\tdescribe('Picker labels', () => {\n\t\tlet format          = 'YYYY-MM-DD HH:mm:ss',\n\t\t\tstartDate       = moment(),\n\t\t\tstringDivider   = '|',\n\t\t\texpectedHeaders = {\n\t\t\t\tmonth:  {},\n\t\t\t\tday:    {},\n\t\t\t\thour:   {}\n\t\t\t};\n\t\t\n\t\t// build expected headers\n\t\t['en', 'it', 'fr', 'bn'].forEach((locale: string) => {\n\t\t\tlet localeDate    = startDate.clone().locale(locale);\n\t\t\tconst getWeekDays = () => moment.weekdays().map((day: string, i: number) => localeDate.clone().startOf('week').add(i, 'day').format('dd'));\n\t\t\t\n\t\t\texpectedHeaders.month[locale] = [localeDate.format('MMMM YYYY')].concat(getWeekDays()).join(stringDivider);\n\t\t\texpectedHeaders.day  [locale] = localeDate.format('LL');\n\t\t\texpectedHeaders.hour [locale] = localeDate.startOf('hour').format('lll');\n\t\t});\n\n\t\tconst getHeader = ($element: ng.IAugmentedJQuery) => Array.prototype.slice.call(test.getPicker($element).find('th'), 0)\n\t\t\t.map((e: Node) => e.textContent)\n\t\t\t.filter((s: string) => s != '←' && s != '→')\n\t\t\t.join(stringDivider);\n\t\t\n\t\tit('should change locale dinamically', () => {\n\t\t\tangular.forEach(expectedHeaders, (header, view: string) => {\n\t\t\t\tlet $scope = $rootScope.$new(),\n\t\t\t\t\t$input = test.buildTemplate('input', { locale: '\\{\\{locale\\}\\}', format: format, startView: view, startDate: startDate }, undefined, $scope);\n\t\t\t\t\n\t\t\t\tangular.forEach(header, (expectedHeader: string, locale: string) => {\n\t\t\t\t\t$scope['locale'] = locale;\n\t\t\t\t\t$scope.$apply();\n\t\t\t\t\texpect(getHeader($input)).toBe(expectedHeader);\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "tests/properties/startDate.ts",
    "content": "import * as angular from 'angular';\nimport * as moment from 'moment';\nimport * as test from '../utility';\n\ndescribe('Property `startDate`', () => {\n\t\n\tlet format          = 'YYYY-MM-DD HH:mm:ss',\n\t\tstartDate       = moment('2005-05-15 13:20:15', format),\n\t\tstartDateStr    = '\\'' + startDate.format(format) + '\\'',\n\t\texpectedHeaders = {\n\t\t\tdecade: '2000 - 2009',\n\t\t\tyear:   '2005',\n\t\t\tmonth:  'May 2005',\n\t\t\tday:    'May 15, 2005',\n\t\t\thour:   'May 15, 2005 1:00 PM',\n\t\t\tminute: 'May 15, 2005 1:20 PM'\n\t\t};\n\t\n\t// init test\n\ttest.bootstrap();\n\t\n\tconst getHeaderText = ($element: ng.IAugmentedJQuery) => angular.element(test.getPicker($element).find('.header-view th')[1]).text();\n\t\n\t// test all views\n\tangular.forEach(expectedHeaders, (expectedHeader, view) => {\n\t\tlet viewName = view[0].toUpperCase() + view.slice(1),\n\t\t\ttitle    = 'should open ' + viewName + ' View in ' + expectedHeader;\n\t\t\n\t\tit(title, () => {\n\t\t\tlet $propAsMoment = test.buildTemplate('div', { locale: 'en', format: format, startView: view, startDate: startDate }),\n\t\t\t\t$propAsString = test.buildTemplate('div', { locale: 'en', format: format, startView: view, startDate: startDateStr });\n\t\t\t\t\n\t\t\t// Moment object input\n\t\t\texpect(getHeaderText($propAsMoment)).toBe(expectedHeader);\n\t\t\t// string input\n\t\t\texpect(getHeaderText($propAsString)).toBe(expectedHeader);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "tests/properties/validate.ts",
    "content": "import * as angular from 'angular';\nimport * as moment from 'moment';\nimport * as test from '../utility';\n\ndescribe('Property `validate`', () => {\n\t\n\tlet $rootScope: ng.IRootScopeService;\n\n\t// init test\n\ttest.bootstrap();\n\n\t// get $rootScope service\n\tbeforeEach(inject((_$rootScope_: ng.IRootScopeService) => { // tslint:disable-line:variable-name\n\t\t// The injector unwraps the underscores (_) from around the parameter names when matching\n\t\t$rootScope = _$rootScope_;\n\t}));\n\t\n\tconst buildFormScope = (options) => {\n\t\tlet $scope = $rootScope.$new(),\n\t\t\t$form  = angular.element('<form name=\"form\">').appendTo(document.body),\n\t\t\t$input = test.buildTemplate('input', options, undefined, $scope, $form);\n\t\treturn $scope;\n\t};\n\t\n\tdescribe('set to false', () => {\n\t\t// required\n\t\tit('should raise `required` validation error', () => {\n\t\t\tlet $scope = buildFormScope({ name: 'date', validate: 'false', required: 'true' });\n\t\t\texpect($scope['form'].date.$error.required).toBe(true);\n\t\t});\n\t\t\n\t\t// minDate\n\t\tit('should raise `minDate` validation error', () => {\n\t\t\tlet format  = 'YYYY-MM-DD',\n\t\t\t\tngModel = moment('2016-12-15', format),\n\t\t\t\tminDate = ngModel.clone().add(1, 'month'),\n\t\t\t\t$scope  = buildFormScope({ name: 'date', validate: 'false', format: format, ngModel: ngModel, minDate: minDate });\n\t\t\t\n\t\t\texpect($scope['form'].date.$error.minDate).toBe(true);\n\t\t});\n\t\t\n\t\t// maxDate\n\t\tit('should raise `maxDate` validation error', () => {\n\t\t\tlet format  = 'YYYY-MM-DD',\n\t\t\t\tngModel = moment('2016-12-15', format),\n\t\t\t\tmaxDate = ngModel.clone().subtract(1, 'month'),\n\t\t\t\t$scope  = buildFormScope({ name: 'date', validate: 'false', format: format, ngModel: ngModel, maxDate: maxDate });\n\t\t\t\n\t\t\texpect($scope['form'].date.$error.maxDate).toBe(true);\n\t\t});\n\t});\n\t\n\tdescribe('set to true', () => {\n\t\t// required\n\t\tit('should raise `required` validation error', () => {\n\t\t\tlet $scope = buildFormScope({ name: 'date', validate: 'true', required: 'true' });\n\t\t\texpect($scope['form'].date.$error.required).toBe(true);\n\t\t});\n\t\t\n\t\t// minDate\n\t\tit('should set date to minimum allowable value', () => {\n\t\t\tlet format  = 'YYYY-MM-DD',\n\t\t\t\tngModel = moment('2016-12-15', format),\n\t\t\t\tminDate = ngModel.clone().add(1, 'month'),\n\t\t\t\t$scope  = buildFormScope({ validate: 'true', format: format, ngModel: ngModel, minDate: minDate });\n\t\t\t\n\t\t\texpect($scope['ngModel'].isSame(minDate)).toBe(true);\n\t\t});\n\t\t\n\t\t// maxDate\n\t\tit('should set date to maximum allowable value', () => {\n\t\t\tlet format  = 'YYYY-MM-DD',\n\t\t\t\tngModel = moment('2016-12-15', format),\n\t\t\t\tmaxDate = ngModel.clone().subtract(1, 'month'),\n\t\t\t\t$scope  = buildFormScope({ validate: 'true', format: format, ngModel: ngModel, maxDate: maxDate });\n\t\t\t\n\t\t\texpect($scope['ngModel'].isSame(maxDate)).toBe(true);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "tests/utility.ts",
    "content": "import * as angular from 'angular';\nimport { IDirectiveScopeInternal } from '../src/definitions';\n\nlet $compile, $timeout, $rootScope;\n\nexport const bootstrap = (): any => { // tslint:disable-line:no-any\n\t// load the moment-picker module, which contains the directive\n\tbeforeEach(angular.mock.module('moment-picker'));\n\t\n\t// store references to $rootScope and $compile\n\t// so they are available to all tests in this describe block\n\tbeforeEach(inject((\n\t\t_$compile_: ng.ICompileService, // tslint:disable-line:variable-name\n\t\t_$timeout_: ng.ITimeoutService, // tslint:disable-line:variable-name\n\t\t_$rootScope_: ng.IRootScopeService, // tslint:disable-line:variable-name\n\t) => {\n\t\t// The injector unwraps the underscores (_) from around the parameter names when matching\n\t\t$compile = _$compile_;\n\t\t$timeout = _$timeout_;\n\t\t$rootScope = _$rootScope_;\n\t}));\n};\n\nexport const $digest = () => $rootScope.$digest();\n\nexport const buildTemplate = (tag: string, options?: any, content?: any, $scope?: ng.IScope, $parent?: ng.IAugmentedJQuery) => { // tslint:disable-line:no-any\n\tlet $template, $container, $element;\n\tif (!$scope) $scope = $rootScope.$new();\n\ttag = tag.toLowerCase();\n\t// template string\n\tlet template = '<' + tag;\n\t// build attributes map\n\tif (!options) options = {};\n\tif (!options.momentPicker) options.momentPicker = 'mpTestFormattedString';\n\tif (tag === 'input' && !options.ngModel) options.ngModel = 'mpTestMomentObject';\n\tangular.forEach(options, (value, name) => {\n\t\tlet valueStr = name;\n\t\tif (typeof value === 'string') valueStr = value;\n\t\telse $scope[name] = value;\n\t\ttemplate += ' ' + name.replace(/([A-Z])/g, '-$1').toLowerCase() + '=\"' + valueStr + '\"';\n\t});\n\t// close template\n\ttemplate += tag === 'input' ? '>' : '></div>';\n\t$template = angular.element(template);\n\tif (tag !== 'input') {\n\t\tif (content) $template.append(content);\n\t\telse $template.append('{{' + options.momentPicker + '}}');\n\t}\n\t// append template to DOM\n\t$container = angular.element('<div></div>').append($template);\n\tangular.element($parent || document.body).append($container);\n\t// return compiled element\n\t$compile($parent || $container)($scope);\n\t$element = angular.element($container.children()[0]);\n\t$digest();\n\t$timeout.flush();\n\treturn $element;\n};\n\nexport const getPicker = (element: ng.IAugmentedJQuery) => (<IDirectiveScopeInternal>element.isolateScope()).picker;\n\n// wrap jquery trigger fn: event trigger + digest stimulation\nexport const trigger = (element: ng.IAugmentedJQuery, event: string | JQueryEventObject) => {\n\t// use jquey trigger method to propagate event to parent nodes\n\tangular.element(element).trigger(<string>event);\n\t$digest();\n};"
  },
  {
    "path": "tests/value.ts",
    "content": "import * as moment from 'moment';\nimport * as test from './utility';\n\ndescribe('Value', () => {\n\n\tlet $scope: ng.IScope;\n\tlet $input: ng.IAugmentedJQuery;\n\tlet format = 'YYYY-MM-DD';\n\n\t// init test\n\ttest.bootstrap();\n\n\t// same picker settings for all tests in this suite\n\tbeforeEach(inject(($rootScope: ng.IRootScopeService) => {\n\t\t$scope = $rootScope.$new();\n\t\t$input = test.buildTemplate('input', { momentPicker: 'dateStr', ngModel: 'dateObj', format: format }, undefined, $scope);\n\t}));\n\t\n\t// set Model Value from View Value\n\tit('should initialize Model Value from View Value', () => {\n\t\tlet dateObj = moment('2017-01-12', format),\n\t\t\tdateStr = dateObj.format(format);\n\t\t\n\t\t$scope['dateStr'] = dateStr;\n\t\t$scope.$digest();\n\t\texpect($scope['dateObj'].isSame(dateObj)).toBe(true);\n\t});\n\t\n\t// set View Value from Model Value\n\tit('should initialize View Value from Model Value', () => {\n\t\tlet dateObj = moment('2017-01-12', format),\n\t\t\tdateStr = dateObj.format(format);\n\t\t\n\t\t$scope['dateObj'] = dateObj;\n\t\t$scope.$digest();\n\t\texpect($scope['dateStr']).toBe(dateStr);\n\t\texpect($input.val()).toBe(dateStr);\n\t});\n\t\n\t// update Model Value\n\tit('should update Model Value after View Value update', () => {\n\t\tlet dateObj = moment('2017-01-12', format),\n\t\t\tdateStr = dateObj.format(format);\n\t\t\n\t\t// first set an initial date\n\t\t$scope['dateObj'] = dateObj;\n\t\t$scope['dateStr'] = dateStr;\n\t\t$scope.$digest();\n\t\t// then change it and listen for value update\n\t\tdateObj = moment('2016-11-23', format);\n\t\tdateStr = dateObj.format(format);\n\t\t$scope['dateStr'] = dateStr;\n\t\t$scope.$digest();\n\t\texpect($scope['dateObj'].isSame(dateObj)).toBe(true);\n\t});\n\t\n\t// update View Value\n\tit('should update View Value after Model Value update', () => {\n\t\tlet dateObj = moment('2017-01-12', format),\n\t\t\tdateStr = dateObj.format(format);\n\t\t\n\t\t// first set an initial date\n\t\t$scope['dateObj'] = dateObj;\n\t\t$scope['dateStr'] = dateStr;\n\t\t$scope.$digest();\n\t\t// then change it and listen for value update\n\t\tdateObj = moment('2016-11-23', format);\n\t\tdateStr = dateObj.format(format);\n\t\t$scope['dateObj'] = dateObj;\n\t\t$scope.$digest();\n\t\texpect($scope['dateStr']).toBe(dateStr);\n\t\texpect($input.val()).toBe(dateStr);\n\t});\n\t\n\t// same property for View Value and Model Value\n\tit('should update (View) Value when using the same property value', () => {\n\t\tlet date = moment('2017-01-12', format);\n\t\t\n\t\t$scope['date'] = date;\n\t\t$input = test.buildTemplate('input', { momentPicker: 'date', ngModel: 'date', format: format }, undefined, $scope);\n\t\texpect($scope['date'].isSame(date)).toBe(true);\n\t\texpect($input.val()).toBe(date.format(format));\n\t});\n\n\t// sync model across pickers\n\tit('should sync model updates across pickers', () => {\n\t\tlet dateFormat = 'YYYY-MM-DD',\n\t\t\ttimeFormat = 'HH:mm',\n\t\t\t$date = test.buildTemplate('input', { momentPicker: 'date', ngModel: 'datetime', format: dateFormat }, undefined, $scope),\n\t\t\t$time = test.buildTemplate('input', { momentPicker: 'time', ngModel: 'datetime', format: timeFormat }, undefined, $scope);\n\t\t\n\t\t$scope['datetime'] = moment('2017-01-12 20:32', dateFormat + ' ' + timeFormat);\n\t\t$scope.$digest();\n\t\texpect($date.val()).toBe($scope['datetime'].format(dateFormat));\n\t\texpect($time.val()).toBe($scope['datetime'].format(timeFormat));\n\t\texpect($scope['date']).toBe($scope['datetime'].format(dateFormat));\n\t\texpect($scope['time']).toBe($scope['datetime'].format(timeFormat));\n\n\t\t$scope['date'] = '2015-08-29';\n\t\t$scope.$digest();\n\t\texpect($date.val()).toBe($scope['date']);\n\t\texpect($scope['datetime'].format(dateFormat)).toBe($scope['date']);\n\n\t\t$scope['time'] = '23:11';\n\t\t$scope.$digest();\n\t\texpect($time.val()).toBe($scope['time']);\n\t\texpect($scope['datetime'].format(timeFormat)).toBe($scope['time']);\n\n\t\texpect($scope['datetime'].format(dateFormat + ' ' + timeFormat)).toBe('2015-08-29 23:11');\n\t});\n});\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n\t\"compilerOptions\": {\n\t\t\"target\": \"es3\",\n\t\t\"outDir\": \"./dist\",\n\t\t\"sourceMap\": true,\n\t\t\"alwaysStrict\": true\n\t},\n\t\"exclude\": [\n\t\t\"node_modules\"\n\t]\n}"
  },
  {
    "path": "tslint.json",
    "content": "{\n\t\"extends\": \"tslint:latest\",\n\t\"env\": {\n\t\t\"browser\": true\n\t},\n\t\"globals\": {\n\t\t\"angular\": 1,\n\t\t\"moment\": 1\n\t},\n\t\"rules\": {\n\t\t\"align\": [true, \"parameters\"],\n\t\t\"array-type\": [true, \"array\"],\n\t\t\"curly\": false,\n\t\t\"eofline\": false,\n\t\t\"indent\": [true, \"tabs\"],\n\t\t\"interface-name\": [true, \"always-prefix\"],\n\t\t\"linebreak-style\": [false],\n\t\t\"max-line-length\": [false],\n\t\t\"member-access\": [true, \"check-accessor\"],\n\t\t\"member-ordering\": [false],\n\t\t\"no-angle-bracket-type-assertion\": false,\n\t\t\"no-any\": true,\n\t\t\"no-arg\": true,\n\t\t\"no-consecutive-blank-lines\": [true],\n\t\t\"no-console\": [true],\n\t\t\"no-debugger\": true,\n\t\t\"no-duplicate-variable\": true,\n\t\t\"no-empty\": true,\n\t\t\"no-namespace\": true,\n\t\t\"no-reference\": true,\n\t\t\"no-string-literal\": false,\n\t\t\"no-trailing-whitespace\": false,\n\t\t\"no-unused-expression\": true,\n\t\t\"no-unused-new\": true,\n\t\t\"no-var-keyword\": true,\n\t\t\"no-var-requires\": false, // mandatory to allow webpack to grab HTML, CSS, LESS files\n\t\t\"object-literal-sort-keys\": false,\n\t\t\"object-literal-shorthand\": false,\n\t\t\"one-line\": [true, \"check-whitespace\"],\n\t\t\"one-variable-per-declaration\": [false],\n\t\t\"only-arrow-functions\": [true],\n\t\t\"ordered-imports\": [false],\n\t\t\"prefer-const\": false,\n\t\t\"quotemark\": [true, \"single\"],\n\t\t\"space-before-function-paren\": [\"error\", {\"anonymous\": \"always\" }],\n\t\t\"switch-default\": false,\n\t\t\"trailing-comma\": [false],\n\t\t\"triple-equals\": [false],\n\t\t\"whitespace\": [true, \"check-branch\", \"check-decl\", \"check-operator\", \"check-module\", \"check-separator\", \"check-type\"]\n\t},\n\t\"jsRules\": {\n\t\t\"align\": [true, \"parameters\"],\n\t\t\"array-type\": [true, \"array\"],\n\t\t\"curly\": false,\n\t\t\"eofline\": false,\n\t\t\"indent\": [true, \"tabs\"],\n\t\t\"interface-name\": [true, \"always-prefix\"],\n\t\t\"linebreak-style\": [false],\n\t\t\"max-line-length\": [false],\n\t\t\"member-access\": [true, \"check-accessor\"],\n\t\t\"member-ordering\": [false],\n\t\t\"no-any\": true,\n\t\t\"no-arg\": true,\n\t\t\"no-consecutive-blank-lines\": [true],\n\t\t\"no-console\": [true],\n\t\t\"no-debugger\": true,\n\t\t\"no-duplicate-variable\": true,\n\t\t\"no-empty\": true,\n\t\t\"no-namespace\": true,\n\t\t\"no-reference\": true,\n\t\t\"no-string-literal\": false,\n\t\t\"no-trailing-whitespace\": false,\n\t\t\"no-unused-expression\": true,\n\t\t\"no-unused-new\": true,\n\t\t\"no-var-keyword\": false,\n\t\t\"no-var-requires\": true,\n\t\t\"object-literal-sort-keys\": false,\n\t\t\"object-literal-shorthand\": false,\n\t\t\"one-line\": [true, \"check-whitespace\"],\n\t\t\"one-variable-per-declaration\": [false],\n\t\t\"only-arrow-functions\": [false],\n\t\t\"ordered-imports\": [false],\n\t\t\"quotemark\": [true, \"single\"],\n\t\t\"switch-default\": false,\n\t\t\"trailing-comma\": [false],\n\t\t\"triple-equals\": [false],\n\t\t\"whitespace\": [true, \"check-branch\", \"check-decl\", \"check-operator\", \"check-module\", \"check-separator\", \"check-type\"]\n\t}\n}"
  },
  {
    "path": "webpack.config.js",
    "content": "'use strict';\n\nlet fs = require('fs');\nlet path = require('path');\nlet pkg = require('./package');\nlet bower = require('./bower');\nlet semver = require('semver');\nlet webpack = require('webpack');\nlet autoprefixer = require('autoprefixer');\nlet extractTextPlugin = require('extract-text-webpack-plugin');\nlet generateJsonPlugin = require('generate-json-webpack-plugin');\n\nlet isProduction = process.argv.indexOf('-p') != -1;\nlet filesuffix = (isProduction ? '.min' : '');\nlet filename = 'angular-moment-picker' + filesuffix;\nlet increase = (process.argv.filter(argv => argv.match(/^increase=.+$/))[0] || '').replace('increase=', '');\n\n// sync bower.json with package.json\npkg.version = increase ? semver.inc(pkg.version, increase) : pkg.version;\n['name', 'version', 'description', 'homepage', 'license', 'keywords', 'dependencies'].forEach(field => bower[field] = pkg[field]);\n\n// themes - read file from `src/themes` folder\nlet themes = [];\nfs.readdirSync('src/themes').forEach(file => themes.push(file.replace('.less', '')));\n\n// extract plugin settings for css file generation\nlet extractBaseTheme = new extractTextPlugin(filename + '.css');\nlet extractOtherThemes = themes.map(theme => ({\n\tfile: path.resolve(__dirname, 'src/themes/' + theme + '.less'),\n\textract: new extractTextPlugin('themes/' + theme + filesuffix + '.css')\n}));\nlet extractPluginLoaders = [\n\t'css-loader',\n\t{ loader: 'postcss-loader', options: { plugins: [ autoprefixer({ browsers: ['> 0%'] }) ] } },\n\t'less-loader'\n];\n\nmodule.exports = {\n\tentry: [\n\t\t'./src/index.ts',\n\t\t'./src/index.less',\n\t\t...extractOtherThemes.map(theme => theme.file)\n\t],\n\toutput: {\n\t\tpath: path.join(__dirname, 'dist'),\n\t\tfilename: filename + '.js'\n\t},\n\tbail: true,\n\texternals: Object.keys(pkg.dependencies),\n\tresolve: {\n\t\textensions: ['.ts', '.html', '.less']\n\t},\n\tmodule: {\n\t\trules: [\n\t\t\t{ test: /\\.ts$/, use: ['ts-loader', 'tslint-loader'] },\n\t\t\t{ test: /\\.html$/, use: 'html-loader?minimize=true' },\n\t\t\t{ test: /\\.less$/, exclude: /themes/, use: extractBaseTheme.extract(extractPluginLoaders) },\n\t\t\t...extractOtherThemes.map(theme => {\n\t\t\t\treturn { include: theme.file, use: theme.extract.extract(extractPluginLoaders) };\n\t\t\t})\n\t\t]\n\t},\n\tplugins: [\n\t\textractBaseTheme,\n\t\t...extractOtherThemes.map(theme => theme.extract),\n\t\tnew webpack.BannerPlugin('Angular Moment Picker - v' + pkg.version + ' - ' + pkg.homepage + ' - (c) 2015 Indri Muska - ' + pkg.license),\n\t\tnew generateJsonPlugin('../bower.json', bower, undefined, 2),\n\t\tnew generateJsonPlugin('../package.json', pkg, undefined, 2)\n\t]\n};"
  }
]