From a317819d17a39c4de8ed470890f469934f63c3d2 Mon Sep 17 00:00:00 2001 From: Lasse Boisen Andersen Date: Wed, 2 Dec 2015 13:08:54 +0100 Subject: [PATCH] bumped to v1.5.0 --- README.md | 2 +- dist/booking.js | 68 ++++++++++++++++++++++++++++++++++++++++++--- dist/booking.js.map | 2 +- dist/booking.min.js | 20 ++++++------- package.json | 2 +- src/main.js | 2 +- 6 files changed, 78 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 819e0afc..e2f7ea89 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Circle CI](https://img.shields.io/circleci/project/timekit-io/booking-js.svg)](https://circleci.com/gh/timekit-io/booking-js) [![Codacy Badge](https://api.codacy.com/project/badge/grade/feb445801acf454a95b1690a75959893)](https://www.codacy.com/app/laander/booking-js) -**Latest release:** [v1.4.2](https://github.com/timekit-io/booking-js/releases) +**Latest release:** [v1.5.0](https://github.com/timekit-io/booking-js/releases) > Make a beautiful embeddable booking widget in minutes. diff --git a/dist/booking.js b/dist/booking.js index bd74d399..34fd4efa 100644 --- a/dist/booking.js +++ b/dist/booking.js @@ -58,7 +58,7 @@ return /******/ (function(modules) { // webpackBootstrap /*! * Booking.js - * Version: 1.4.2 + * Version: 1.5.0 * http://booking.timekit.io * * Copyright 2015 Timekit, Inc. @@ -131,6 +131,14 @@ return /******/ (function(modules) { // webpackBootstrap utils.doCallback('findTimeSuccessful', config, response); + // Go to first event if enabled + if(config.goToFirstEvent && response.data.length > 0) { + var firstEventStart = response.data[0].start; + var firstEventStartHour = moment(firstEventStart).format('H'); + goToDate(firstEventStart); + scrollToTime(firstEventStartHour); + } + // Render available timeslots in FullCalendar renderCalendarEvents(response.data); @@ -141,6 +149,54 @@ return /******/ (function(modules) { // webpackBootstrap }; + // Tells FullCalendar to go to a specifc date + var goToDate = function(date) { + + calendarTarget.fullCalendar('gotoDate', date); + + }; + + // Scrolls fullcalendar to the specified hour + var scrollToTime = function(time) { + + // Only proceed for agendaWeek view + if (calendarTarget.fullCalendar('getView').name !== 'agendaWeek'){ + return; + } + + // Get height of each hour row + var hours = calendarTarget.find('.fc-slats .fc-minor'); + var hourHeight = $(hours[0]).height() * 2; + + // If minTime is set in fullCalendar config, subtract that from the scollTo calculationn + var minTimeHeight = 0; + if (config.fullCalendar.minTime) { + var minTime = moment(config.fullCalendar.minTime, 'HH:mm:ss').format('H'); + minTimeHeight = hourHeight * minTime; + } + + // Calculate scrolling location and container sizes + var scrollTo = (hourHeight * time) - minTimeHeight; + var scrollable = calendarTarget.find('.fc-scroller'); + var scrollableHeight = scrollable.height(); + var scrollableScrollTop = scrollable.scrollTop(); + var maximumHeight = scrollable.find('.fc-time-grid').height(); + + // Only perform the scroll if the scrollTo is outside the current visible boundary + if (scrollTo > scrollableScrollTop && scrollTo < scrollableScrollTop + scrollableHeight) { + return; + } + + // If scrollTo point is past the maximum height, then scroll to maximum possible while still animating + if (scrollTo > maximumHeight - scrollableHeight) { + scrollTo = maximumHeight - scrollableHeight; + } + + // Perform the scrollTo animation + scrollable.animate({scrollTop: scrollTo}); + + }; + // Calculate and display timezone helper var renderTimezoneHelper = function() { @@ -154,6 +210,7 @@ return /******/ (function(modules) { // webpackBootstrap loading: true })); + rootTarget.addClass('has-timezonehelper'); rootTarget.append(timezoneHelperTarget); var args = { @@ -225,9 +282,9 @@ return /******/ (function(modules) { // webpackBootstrap if (rootWidth < 480) { view = 'basicDay'; height = 346; - rootTarget.addClass('bookingjs-small'); + rootTarget.addClass('is-small'); } else { - rootTarget.removeClass('bookingjs-small'); + rootTarget.removeClass('is-small'); } if (config.bookingFields.comment.enabled) { height += 84; } @@ -261,6 +318,7 @@ return /******/ (function(modules) { // webpackBootstrap image: config.avatar })); + rootTarget.addClass('has-avatar'); rootTarget.append(avatarTarget); }; @@ -273,6 +331,7 @@ return /******/ (function(modules) { // webpackBootstrap name: config.name })); + rootTarget.addClass('has-displayname'); rootTarget.append(displayNameTarget); }; @@ -18244,6 +18303,7 @@ return /******/ (function(modules) { // webpackBootstrap autoload: true, includeStyles: true, showCredits: true, + goToFirstEvent: true, bookingFields: { name: { placeholder: 'Your full name', @@ -18835,7 +18895,7 @@ return /******/ (function(modules) { // webpackBootstrap exports.push([module.id, "@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,600);", ""]); // module - exports.push([module.id, "/*!\n * Booking.js\n * http://booking.timekit.io\n * (c) 2015 Timekit Inc.\n */.bookingjs{position:relative;font-family:Open Sans,Helvetica,Tahoma,Arial,sans-serif;font-size:13px;border-radius:4px;background-color:#fff;box-shadow:rgba(0,0,0,.2) 0 2px 4px 0;margin:60px auto 20px;z-index:10;opacity:0;color:#333}.bookingjs.show{-webkit-transition:opacity .3s ease;transition:opacity .3s ease;opacity:1}.bookingjs-timezonehelper{color:#aeaeae;text-align:center;padding:7px 10px;background-color:#fbfbfb;border-top:1px solid #ececec;min-height:15px;z-index:20;border-radius:0 0 4px 4px}.bookingjs-timezoneicon{width:10px;margin-right:5px}.bookingjs-avatar{position:absolute;top:-50px;left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);border-radius:150px;border:3px solid #fff;box-shadow:0 1px 3px 0 rgba(0,0,0,.13);overflow:hidden;z-index:40;background-color:#fff}.bookingjs-avatar img{max-width:100%;vertical-align:middle;display:inline-block;width:80px;height:80px}.bookingjs-displayname{position:absolute;top:0;left:0;padding:15px 20px;color:#333;font-weight:600}.bookingjs-bookpage{position:absolute;height:100%;width:100%;top:0;left:0;background-color:#fbfbfb;z-index:30;opacity:0;-webkit-transition:opacity .2s ease;transition:opacity .2s ease;border-radius:4px}.bookingjs-bookpage.show{opacity:1}.bookingjs-bookpage-close{position:absolute;top:0;right:0;padding:18px;-webkit-transition:opacity .2s ease;transition:opacity .2s ease;opacity:.3}.bookingjs-bookpage-close:hover{opacity:1}.bookingjs-bookpage-date{text-align:center;font-size:34px;font-weight:400;margin-top:90px;margin-bottom:20px}.bookingjs-small .bookingjs-bookpage-date{font-size:24px;margin-top:60px;margin-bottom:15px}.bookingjs-bookpage-time{text-align:center;font-size:17px;font-weight:400;margin-bottom:70px}.bookingjs-small .bookingjs-bookpage-time{font-size:15px;margin-bottom:30px}.bookingjs-closeicon{width:15px}.bookingjs-form{width:350px;position:relative;margin:0 auto;text-align:center}.bookingjs-small .bookingjs-form{width:90%}.bookingjs-form-box{position:relative;box-shadow:0 1px 3px 0 rgba(0,0,0,.1);border-radius:4px;overflow:hidden;background-color:#fff;line-height:0}.bookingjs-form-success-message{position:absolute;top:-999px;left:0;right:0;padding:30px;background-color:#fff;opacity:0;-webkit-transition:opacity .3s ease;transition:opacity .3s ease;line-height:normal}.bookingjs-small .bookingjs-form-success-message{padding:22px 10px}.bookingjs-form-success-message .title{font-weight:600}.bookingjs-form-success-message .booked-email{color:#aeaeae}.bookingjs-form.success .bookingjs-form-success-message{opacity:1;top:0;bottom:0}.bookingjs-form-input{-webkit-transition:box-shadow .2s ease;transition:box-shadow .2s ease;width:100%;padding:15px 25px;border:0 solid #ececec;font-size:1em;box-shadow:inset 0 0 1px 1px hsla(0,0%,100%,0);text-align:left;box-sizing:border-box;line-height:normal;font-family:Open Sans,Helvetica,Tahoma,Arial,sans-serif}.bookingjs-form-input:focus{outline:0;box-shadow:inset 0 0 1px 1px #689ad8}.bookingjs-form-input.hidden{display:none}.bookingjs-form-button{position:relative;-webkit-transition:background-color .2s,max-width .3s;transition:background-color .2s,max-width .3s;display:inline-block;padding:13px 25px;background-color:#689ad8;text-transform:uppercase;box-shadow:0 1px 3px 0 rgba(0,0,0,.15);color:#fff;border:0;border-radius:3px;font-size:1.1em;font-weight:600;margin-top:30px;cursor:pointer;height:44px;outline:0;text-align:center;max-width:200px}.bookingjs-form-button .loading-text,.bookingjs-form-button .success-text{-webkit-transition:opacity .3s ease;transition:opacity .3s ease;position:absolute;top:13px;left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}.bookingjs-form-button .inactive-text{opacity:1}.bookingjs-form-button .loading-text,.bookingjs-form-button .success-text{opacity:0}.bookingjs-form-button .loading-text svg{height:19px;width:19px;-webkit-animation:spin .6s infinite linear;animation:spin .6s infinite linear}.bookingjs-form-button .success-text svg{height:15px;margin-top:2px;-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);-webkit-transition:-webkit-transform .6s ease;transition:-webkit-transform .6s ease;transition:transform .6s ease;transition:transform .6s ease,-webkit-transform .6s ease}.bookingjs-form-button:hover{background-color:#3f7fce}.bookingjs-form-button.button-shake{-webkit-animation:shake .5s 1 ease;animation:shake .5s 1 ease}.bookingjs-form.loading .bookingjs-form-button,.bookingjs-form.loading .bookingjs-form-button:hover{max-width:80px;background-color:#b1b1b1}.bookingjs-form.loading .bookingjs-form-button .inactive-text,.bookingjs-form.loading .bookingjs-form-button:hover .inactive-text{opacity:0}.bookingjs-form.loading .bookingjs-form-button .loading-text,.bookingjs-form.loading .bookingjs-form-button:hover .loading-text{opacity:1}.bookingjs-form.success .bookingjs-form-button,.bookingjs-form.success .bookingjs-form-button:hover{max-width:80px;background-color:#5baf56}.bookingjs-form.success .bookingjs-form-button .inactive-text,.bookingjs-form.success .bookingjs-form-button .loading-text,.bookingjs-form.success .bookingjs-form-button:hover .inactive-text,.bookingjs-form.success .bookingjs-form-button:hover .loading-text{opacity:0}.bookingjs-form.success .bookingjs-form-button .success-text,.bookingjs-form.success .bookingjs-form-button:hover .success-text{opacity:1}.bookingjs-form.success .bookingjs-form-button .success-text svg,.bookingjs-form.success .bookingjs-form-button:hover .success-text svg{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}.bookingjs-poweredby{position:absolute;bottom:0;left:0;right:0;text-align:center;padding:7px 10px}.bookingjs-poweredby a{-webkit-transition:color .2s ease;transition:color .2s ease;color:#aeaeae;text-decoration:none}.bookingjs-poweredby a svg path{-webkit-transition:fill .2s ease;transition:fill .2s ease;fill:#aeaeae}.bookingjs-poweredby a:hover{color:#333}.bookingjs-poweredby a:hover svg path{fill:#333}.bookingjs-timekiticon{width:13px;margin-right:5px;vertical-align:sub}", ""]); + exports.push([module.id, "/*!\n * Booking.js\n * http://booking.timekit.io\n * (c) 2015 Timekit Inc.\n */.bookingjs{position:relative;font-family:Open Sans,Helvetica,Tahoma,Arial,sans-serif;font-size:13px;border-radius:4px;background-color:#fff;box-shadow:rgba(0,0,0,.2) 0 2px 4px 0;margin:60px auto 20px;z-index:10;opacity:0;color:#333}.bookingjs.show{-webkit-transition:opacity .3s ease;transition:opacity .3s ease;opacity:1}.is-small.has-avatar.has-displayname .bookingjs-calendar .fc-toolbar{padding-bottom:24px}.is-small .bookingjs-calendar .fc-toolbar>.fc-right>button.fc-today-button{position:absolute;left:15px}.bookingjs-timezonehelper{color:#aeaeae;text-align:center;padding:7px 10px;background-color:#fbfbfb;border-top:1px solid #ececec;min-height:15px;z-index:20;border-radius:0 0 4px 4px}.bookingjs-timezoneicon{width:10px;margin-right:5px}.bookingjs-avatar{position:absolute;top:-50px;left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);border-radius:150px;border:3px solid #fff;box-shadow:0 1px 3px 0 rgba(0,0,0,.13);overflow:hidden;z-index:40;background-color:#fff}.is-small .bookingjs-avatar{top:-40px}.bookingjs-avatar img{max-width:100%;vertical-align:middle;display:inline-block;width:80px;height:80px}.is-small .bookingjs-avatar img{width:70px;height:70px}.bookingjs-displayname{position:absolute;top:0;left:0;padding:15px 20px;color:#333;font-weight:600}.is-small .bookingjs-displayname{text-align:center;width:100%;box-sizing:border-box}.is-small.has-avatar .bookingjs-displayname{top:28px}.bookingjs-bookpage{position:absolute;height:100%;width:100%;top:0;left:0;background-color:#fbfbfb;z-index:30;opacity:0;-webkit-transition:opacity .2s ease;transition:opacity .2s ease;border-radius:4px}.bookingjs-bookpage.show{opacity:1}.bookingjs-bookpage-close{position:absolute;top:0;right:0;padding:18px;-webkit-transition:opacity .2s ease;transition:opacity .2s ease;opacity:.3}.bookingjs-bookpage-close:hover{opacity:1}.bookingjs-bookpage-date{text-align:center;font-size:34px;font-weight:400;margin-top:90px;margin-bottom:20px}.is-small .bookingjs-bookpage-date{font-size:24px;margin-top:60px;margin-bottom:15px}.bookingjs-bookpage-time{text-align:center;font-size:17px;font-weight:400;margin-bottom:70px}.is-small .bookingjs-bookpage-time{font-size:15px;margin-bottom:30px}.bookingjs-closeicon{width:15px}.bookingjs-form{width:350px;position:relative;margin:0 auto;text-align:center}.is-small .bookingjs-form{width:90%}.bookingjs-form-box{position:relative;box-shadow:0 1px 3px 0 rgba(0,0,0,.1);border-radius:4px;overflow:hidden;background-color:#fff;line-height:0}.bookingjs-form-success-message{position:absolute;top:-999px;left:0;right:0;padding:30px;background-color:#fff;opacity:0;-webkit-transition:opacity .3s ease;transition:opacity .3s ease;line-height:normal}.is-small .bookingjs-form-success-message{padding:22px 10px}.bookingjs-form-success-message .title{font-weight:600}.bookingjs-form-success-message .booked-email{color:#aeaeae}.bookingjs-form.success .bookingjs-form-success-message{opacity:1;top:0;bottom:0}.bookingjs-form-input{-webkit-transition:box-shadow .2s ease;transition:box-shadow .2s ease;width:100%;padding:15px 25px;border:0 solid #ececec;font-size:1em;box-shadow:inset 0 0 1px 1px hsla(0,0%,100%,0);text-align:left;box-sizing:border-box;line-height:normal;font-family:Open Sans,Helvetica,Tahoma,Arial,sans-serif}.bookingjs-form-input:focus{outline:0;box-shadow:inset 0 0 1px 1px #689ad8}.bookingjs-form-input.hidden{display:none}.bookingjs-form-button{position:relative;-webkit-transition:background-color .2s,max-width .3s;transition:background-color .2s,max-width .3s;display:inline-block;padding:13px 25px;background-color:#689ad8;text-transform:uppercase;box-shadow:0 1px 3px 0 rgba(0,0,0,.15);color:#fff;border:0;border-radius:3px;font-size:1.1em;font-weight:600;margin-top:30px;cursor:pointer;height:44px;outline:0;text-align:center;max-width:200px}.bookingjs-form-button .loading-text,.bookingjs-form-button .success-text{-webkit-transition:opacity .3s ease;transition:opacity .3s ease;position:absolute;top:13px;left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}.bookingjs-form-button .inactive-text{opacity:1}.bookingjs-form-button .loading-text,.bookingjs-form-button .success-text{opacity:0}.bookingjs-form-button .loading-text svg{height:19px;width:19px;-webkit-animation:spin .6s infinite linear;animation:spin .6s infinite linear}.bookingjs-form-button .success-text svg{height:15px;margin-top:2px;-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);-webkit-transition:-webkit-transform .6s ease;transition:-webkit-transform .6s ease;transition:transform .6s ease;transition:transform .6s ease,-webkit-transform .6s ease}.bookingjs-form-button:hover{background-color:#3f7fce}.bookingjs-form-button.button-shake{-webkit-animation:shake .5s 1 ease;animation:shake .5s 1 ease}.bookingjs-form.loading .bookingjs-form-button,.bookingjs-form.loading .bookingjs-form-button:hover{max-width:80px;background-color:#b1b1b1}.bookingjs-form.loading .bookingjs-form-button .inactive-text,.bookingjs-form.loading .bookingjs-form-button:hover .inactive-text{opacity:0}.bookingjs-form.loading .bookingjs-form-button .loading-text,.bookingjs-form.loading .bookingjs-form-button:hover .loading-text{opacity:1}.bookingjs-form.success .bookingjs-form-button,.bookingjs-form.success .bookingjs-form-button:hover{max-width:80px;background-color:#5baf56}.bookingjs-form.success .bookingjs-form-button .inactive-text,.bookingjs-form.success .bookingjs-form-button .loading-text,.bookingjs-form.success .bookingjs-form-button:hover .inactive-text,.bookingjs-form.success .bookingjs-form-button:hover .loading-text{opacity:0}.bookingjs-form.success .bookingjs-form-button .success-text,.bookingjs-form.success .bookingjs-form-button:hover .success-text{opacity:1}.bookingjs-form.success .bookingjs-form-button .success-text svg,.bookingjs-form.success .bookingjs-form-button:hover .success-text svg{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}.bookingjs-poweredby{position:absolute;bottom:0;left:0;right:0;text-align:center;padding:7px 10px}.bookingjs-poweredby a{-webkit-transition:color .2s ease;transition:color .2s ease;color:#aeaeae;text-decoration:none}.bookingjs-poweredby a svg path{-webkit-transition:fill .2s ease;transition:fill .2s ease;fill:#aeaeae}.bookingjs-poweredby a:hover{color:#333}.bookingjs-poweredby a:hover svg path{fill:#333}.bookingjs-timekiticon{width:13px;margin-right:5px;vertical-align:sub}", ""]); // exports diff --git a/dist/booking.js.map b/dist/booking.js.map index aec48345..db2330b5 100644 --- a/dist/booking.js.map +++ b/dist/booking.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 72428110df9b2182a89e","webpack:///./src/main.js","webpack:///external \"jQuery\"","webpack:///./~/fullcalendar/dist/fullcalendar.js","webpack:///./~/moment/moment.js","webpack:///(webpack)/buildin/module.js","webpack:///./~/moment/locale en-gb","webpack:///./~/moment/locale/en-gb.js","webpack:///./~/timekit-sdk/src/timekit.js","webpack:///./~/axios/index.js","webpack:///./~/axios/lib/axios.js","webpack:///./~/axios/lib/defaults.js","webpack:///./~/axios/lib/utils.js","webpack:///./~/axios/lib/helpers/deprecatedMethod.js","webpack:///./~/axios/lib/core/dispatchRequest.js","webpack:///./~/process/browser.js","webpack:///./~/axios/lib/adapters/xhr.js","webpack:///./~/axios/lib/helpers/buildUrl.js","webpack:///./~/axios/lib/helpers/cookies.js","webpack:///./~/axios/lib/helpers/parseHeaders.js","webpack:///./~/axios/lib/helpers/transformData.js","webpack:///./~/axios/lib/helpers/urlIsSameOrigin.js","webpack:///./~/axios/lib/core/InterceptorManager.js","webpack:///./~/es6-promise/dist/es6-promise.js","webpack:///./~/timers-browserify/main.js","webpack:///vertx (ignored)","webpack:///(webpack)/buildin/amd-define.js","webpack:///./~/axios/lib/helpers/spread.js","webpack:///./~/base-64/base64.js","webpack:///./~/humps/humps.js","webpack:///./src/utils.js","webpack:///./src/defaults.js","webpack:///./~/fullcalendar/dist/fullcalendar.css?34a3","webpack:///./~/fullcalendar/dist/fullcalendar.css","webpack:///./~/css-loader/lib/css-base.js","webpack:///./~/style-loader/addStyles.js","webpack:///./src/styles/fullcalendar.scss?64b6","webpack:///./src/styles/fullcalendar.scss","webpack:///./src/styles/utils.scss?c3d7","webpack:///./src/styles/utils.scss","webpack:///./src/styles/main.scss?04c9","webpack:///./src/styles/main.scss","webpack:///./src/assets/timezone-icon.svg","webpack:///./src/templates/timezone-helper.html","webpack:///./~/hogan.js/lib/hogan.js","webpack:///./~/hogan.js/lib/compiler.js","webpack:///./~/hogan.js/lib/template.js","webpack:///./src/templates/user-avatar.html","webpack:///./src/templates/user-displayname.html","webpack:///./src/templates/booking-fields.html","webpack:///./src/templates/booking-page.html","webpack:///./src/assets/close-icon.svg","webpack:///./src/assets/checkmark-icon.svg","webpack:///./src/assets/loading-spinner.svg","webpack:///./src/templates/poweredby.html","webpack:///./src/assets/timekit-icon.svg"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,iBAAgB;AAChB;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;AACL;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA,MAAK;AACL;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA,gDAA+C,eAAe;AAC9D,8CAA6C,iBAAiB;AAC9D,6CAA4C,kBAAkB;AAC9D,iDAAgD,cAAc;;AAE9D;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA,8BAA6B,mBAAmB;AAChD,MAAK;;AAEL;;AAEA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;AACL;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iDAAgD,4BAA4B;AAC5E,8CAA6C,0FAA0F;AACvI,6CAA4C,yFAAyF;AACrI,gDAA+C,4FAA4F;;AAE3I;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA,sCAAqC;;AAErC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,wCAAuC;;AAEvC;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,qDAAoD,kBAAkB;AACtE;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,EAAC;AACD;AACA;;;;;;;AC7fA,gD;;;;;;ACAA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,yCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;;AAEA,4BAA2B;AAC3B;;;AAGA;AACA,sDAAqD;AACrD,iBAAgB;;AAEhB,mCAAkC;AAClC;AACA,+CAA8C;AAC9C,iBAAgB;;AAEhB;AACA;AACA;AACA;AACA;AACA,sBAAqB;AACrB;AACA,iCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA,wBAAuB;AACvB;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA,mBAAkB,yBAAyB,GAAG;AAC9C;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,uCAAsC;AACtC;AACA;AACA,+CAA8C;AAC9C;AACA,YAAW;AACX;AACA;AACA;AACA,gCAA+B;AAC/B;AACA,MAAK;;AAEL,kBAAiB;AACjB;AACA;AACA;AACA;AACA,2BAA0B;AAC1B;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,4DAA2D;AAC3D,+EAA8E;AAC9E,mBAAkB;AAClB,uBAAsB;AACtB,uBAAsB;AACtB;;AAEA,0BAAyB;;AAEzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,gFAA+E;AAC/E;;AAEA;AACA;AACA;AACA;AACA;AACA,+DAA8D;;AAE9D,mCAAkC;AAClC;AACA;AACA,GAAE;AACF;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF,kBAAiB;;AAEjB;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA,sEAAqE;AACrE;AACA;;AAEA,6BAA4B;AAC5B;AACA;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA,2BAA0B;AAC1B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA,2DAA0D;AAC1D;AACA;AACA;AACA;AACA;AACA;;AAEA,iEAAgE;AAChE;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA,oCAAmC;AACnC;AACA;AACA;AACA;AACA;;AAEA,wCAAuC;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,qDAAoD;AACpD;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,aAAY,mBAAmB;AAC/B;;AAEA;AACA;AACA;AACA,OAAM,uCAAuC;AAC7C,OAAM;AACN;AACA;AACA;AACA,gBAAe,cAAc;AAC7B;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;;AAEA,aAAY,uBAAuB;AACnC;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qEAAoE;;AAEpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;;;AAGA;AACA;AACA;AACA;AACA,GAAE;AACF;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA,aAAY,0BAA0B;AACtC;AACA;;AAEA;AACA;AACA;AACA;;AAEA,cAAa;AACb;;;AAGA;AACA,oBAAmB,UAAU;AAC7B;AACA;AACA;;AAEA,oBAAmB;AACnB;AACA;AACA,sCAAqC;AACrC;AACA;AACA,QAAO,WAAW,aAAa;AAC/B;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,2BAA0B,qBAAqB;AAC/C;AACA,0BAAyB,yBAAyB;AAClD;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA,oCAAmC,EAAE;AACrC;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;AAEA,0BAAyB;;;AAGzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAa,yBAAyB;AACtC;AACA;;AAEA;AACA,iCAAgC,QAAQ;AACxC;;AAEA;AACA;AACA;AACA;AACA,uBAAsB;AACtB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,+BAA8B,QAAQ;AACtC;;AAEA;AACA,0BAAyB;AACzB;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA,aAAY,kBAAkB;AAC9B;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,oBAAoB;AAC/B;AACA;AACA;AACA;AACA;;;AAGA;AACA,eAAc,oBAAoB;AAClC;AACA;AACA;AACA;AACA;;;AAGA;AACA,sCAAqC;AACrC,uBAAsB;AACtB,uBAAsB;AACtB,yBAAwB;AACxB,yBAAwB;AACxB;AACA;;;AAGA;AACA,4BAA2B;AAC3B;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;;AAEF,2BAA0B;AAC1B;;;AAGA;AACA;AACA;;;AAGA,gCAA+B;AAC/B;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,qCAAoC,EAAE;AACtC;AACA,UAAS,EAAE;AACX,gCAA+B;AAC/B,iCAAgC,kBAAkB;AAClD;AACA,kBAAiB;AACjB,oBAAmB;;;AAGnB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,sBAAqB;AACrB;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kCAAiC;AACjC,8BAA6B;AAC7B;AACA;AACA,kCAAiC;AACjC;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,sBAAqB;AACrB;AACA;AACA;AACA;AACA,kCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,0BAAyB;AACzB;AACA,wBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA,2BAA0B;AAC1B;AACA;AACA,sBAAqB;AACrB;AACA;AACA;AACA;;AAEA,2BAA0B;;AAE1B;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA,wDAAuD;AACvD;AACA;AACA;AACA,wDAAuD;AACvD;;AAEA,oDAAmD;AACnD;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,qBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,QAAO;;AAEP,2BAA0B;;AAE1B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,sBAAqB;;AAErB;AACA,cAAa;AACb,qCAAoC;;AAEpC;AACA;AACA;AACA,0BAAyB;AACzB;;AAEA,cAAa;AACb;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,sBAAqB;AACrB;;AAEA,cAAa;AACb,yBAAwB;;AAExB;AACA;;AAEA;AACA;AACA;AACA;;AAEA,cAAa;AACb;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;AACA,yBAAwB;AACxB;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAa;AACb;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA4B;;AAE5B;AACA;;AAEA,sBAAqB;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,EAAC;;;AAGD;AACA;;AAEA;AACA,2CAA0C;AAC1C,yCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,gDAA+C;AAC/C;AACA;AACA;AACA,sCAAqC;AACrC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,EAAC;;;AAGD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,aAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,kCAAiC;AACjC,EAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAiC;AACjC,EAAC;;AAED;;AAEA;AACA;;;AAGA;AACA;AACA,oDAAmD;AACnD;;;AAGA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA,WAAU,iBAAiB;AAC3B;AACA;;AAEA;AACA;;;AAGA;AACA;AACA,qBAAoB;AACpB;AACA,GAAE;AACF,qBAAoB;AACpB;AACA;AACA;;;AAGA;AACA;AACA;;AAEA,kCAAiC;AACjC;AACA;AACA,mCAAkC;AAClC;AACA,uCAAsC;AACtC;AACA;AACA;AACA,yBAAwB;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,4DAA2D;;AAE3D;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA6B;;;AAG7B;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAc,qBAAqB;AACnC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,8BAA6B,cAAc;AAC3C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,qBAAoB,iBAAiB;AACrC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA,kCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,yCAAwC;AACxC;AACA;AACA;;AAEA,eAAc;AACd;AACA;;;AAGA;AACA;;;AAGA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA,6EAA4E;AAC5E;;AAEA;AACA,kBAAiB;AACjB;AACA;AACA,uBAAsB;AACtB,iBAAgB,qCAAqC;AACrD;AACA,uBAAsB;AACtB,iBAAgB,kBAAkB;AAClC;AACA,uBAAsB;AACtB;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,kBAAiB;;AAEjB;AACA,mBAAkB;;AAElB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,iDAAgD;;AAEhD;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,6DAA4D;AAC5D;AACA;;AAEA;;AAEA;;;AAGA;AACA;AACA,eAAc;AACd,GAAE;;;AAGF;AACA;AACA,eAAc;AACd,GAAE;;;AAGF,2BAA0B;AAC1B;;AAEA;;AAEA,eAAc;AACd,GAAE;;;AAGF;AACA;;AAEA;;AAEA,eAAc;AACd,GAAE;;;AAGF;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,EAAC;AACD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA,iCAAgC;AAChC;AACA;AACA;AACA;;AAEA,0DAAyD;AACzD;AACA,oBAAmB;AACnB,qBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,EAAC;;AAED;;AAEA;AACA;AACA;;AAEA;AACA,uBAAsB;AACtB;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA,gCAA+B,WAAW;AAC1C,gCAA+B,WAAW;;AAE1C;AACA;;;AAGA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,eAAc,YAAY;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA,eAAc,YAAY;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,8CAA6C;AAC7C,2BAA0B;;AAE1B;AACA;;AAEA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,EAAC;;;AAGD;AACA;;AAEA;;AAEA;;;AAGA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA,cAAa,sBAAsB;AACnC;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA,cAAa,+BAA+B;AAC5C;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA,cAAa,sBAAsB;AACnC;AACA;AACA;;AAEA,EAAC;;AAED;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,0BAAyB;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA,wBAAuB;;AAEvB;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,6CAA4C;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,kBAAiB;;AAEjB,0BAAyB;AACzB;AACA;AACA;AACA,kDAAiD;AACjD;AACA;AACA;;AAEA;AACA,0BAAyB;AACzB;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA,2BAA0B;AAC1B;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,yBAAwB;AACxB,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA;;AAEA;AACA,0BAAyB;AACzB;AACA;AACA;AACA,IAAG;AACH,GAAE;;;AAGF;AACA;AACA,qBAAoB;;AAEpB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gBAAe;;AAEf;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,mDAAkD;AAClD;AACA;AACA;AACA;;AAEA;AACA;AACA,qDAAoD;AACpD;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;;AAEA;AACA;;AAEA,6BAA4B;;AAE5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA,+BAA8B;AAC9B,8BAA6B;AAC7B;AACA;AACA;AACA,oCAAmC;AACnC,oEAAmE;AACnE;AACA;AACA;;AAEA,gCAA+B;AAC/B,+BAA8B;AAC9B;AACA;AACA;AACA,qCAAoC;AACpC,mEAAkE;AAClE;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,2CAA0C;;AAE1C;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,6BAA4B;;AAE5B;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA,EAAC;;AAED;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA,0DAAyD;;AAEzD;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,6DAA4D;;AAE5D;;AAEA;AACA,iBAAgB;AAChB;;AAEA;AACA;AACA,2CAA0C;AAC1C;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,mBAAkB;AAClB;;AAEA;AACA;;AAEA,oDAAmD;AACnD;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA,2DAA0D;;AAE1D,2CAA0C;;AAE1C;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA,sDAAqD;;AAErD;;AAEA,wCAAuC;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,0DAAyD;AACzD,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA,4DAA2D;;AAE3D;AACA;AACA,GAAE;;;AAGF;AACA;AACA,4DAA2D;;AAE3D,wBAAuB;AACvB,GAAE;;;AAGF;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,EAAC;;;AAGD;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,8EAA6E;AAC7E,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,kCAAiC;;AAEjC;AACA;AACA;AACA;;AAEA,+CAA8C;AAC9C;;AAEA;;AAEA,2DAA0D;AAC1D;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA;AACA,0BAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA,gBAAe;;AAEf;AACA;AACA,0BAAyB;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,EAAC;;AAED;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,gBAAe,mBAAmB;AAClC;AACA;AACA;;AAEA,8DAA6D;;AAE7D;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,mBAAkB;AAClB,oBAAmB;AACnB,gBAAe;AACf;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,sDAAqD;AACrD;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,EAAC;;AAED;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA,sCAAqC;;AAErC;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAE;;;AAGF;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,sDAAqD;AACrD;;AAEA;AACA;AACA,oDAAmD;AACnD;;AAEA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA,kCAAiC;AACjC;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA,WAAU;;AAEV;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAa,iBAAiB;AAC9B;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAa,iBAAiB;AAC9B;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;;AAEA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA,sEAAqE;AACrE,GAAE;;;AAGF;AACA;AACA,uEAAsE;AACtE,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,oBAAmB;AACnB,sBAAqB;;AAErB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB,KAAI;AACJ;AACA,oBAAmB;AACnB,0CAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH,8BAA6B;AAC7B,GAAE;;;AAGF;AACA;AACA;;;AAGA;AACA;AACA;;AAEA,2CAA0C;AAC1C,GAAE;;;AAGF;AACA;AACA;AACA;AACA,kEAAiE;;AAEjE;AACA;AACA,2BAA0B;AAC1B;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,8BAA6B;;AAE7B;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,eAAc,iBAAiB;AAC/B;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,cAAa;AACb,iBAAgB;;AAEhB;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;;AAEA;AACA,GAAE;;;AAGF;;;AAGA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,gEAA+D;;AAE/D;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,EAAC;;AAED;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAa,iBAAiB;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA,6BAA4B;;AAE5B;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qBAAoB;;AAEpB;AACA,eAAc,iBAAiB;AAC/B;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,6BAA4B;AAC5B;AACA;AACA;AACA,KAAI;AACJ;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA,kDAAiD;AACjD,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA,6DAA4D;AAC5D,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,uCAAsC;;AAEtC;AACA;AACA,uCAAsC;AACtC;AACA,MAAK;AACL;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,iBAAgB;;AAEhB;AACA,oCAAmC;AACnC;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAAyB;AACzB;AACA,KAAI;AACJ;AACA,uCAAsC;AACtC;AACA,2BAA0B;AAC1B,KAAI;AACJ;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,2BAA0B;AAC1B;AACA;AACA,2BAA0B;AAC1B;;AAEA;AACA,0BAAyB;AACzB;AACA,KAAI;AACJ,yBAAwB;AACxB,yBAAwB;AACxB,0BAAyB;AACzB;AACA,KAAI;AACJ,0BAAyB;AACzB;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL,KAAI;AACJ;AACA,0BAAyB;AACzB;AACA,IAAG;;AAEH,8BAA6B;AAC7B,GAAE;;;AAGF;AACA;AACA;AACA,mEAAkE,EAAE;AACpE,GAAE;;;AAGF;AACA;AACA;AACA,kEAAiE,EAAE;AACnE,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA,+BAA8B;AAC9B;;AAEA;AACA;AACA;AACA;AACA,oCAAmC;AACnC;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,mCAAkC;AAClC;AACA,oBAAmB;;AAEnB;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,qCAAoC;AACpC;AACA,WAAU;AACV;AACA;AACA,KAAI;AACJ;AACA,yBAAwB;AACxB;AACA;AACA,KAAI;AACJ;AACA;AACA;;AAEA,wBAAuB;AACvB;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,IAAG;;AAEH,8BAA6B;AAC7B,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,GAAE;;;;AAIF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAqB;;AAErB;AACA;AACA;AACA;AACA;AACA;AACA,uCAAsC;AACtC;AACA,KAAI;AACJ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ,yBAAwB;AACxB;AACA,KAAI;AACJ,0BAAyB;AACzB;AACA;AACA;AACA,KAAI;AACJ;AACA;;AAEA,0BAAyB;AACzB;AACA;AACA;AACA,IAAG;;AAEH,8BAA6B;AAC7B,GAAE;;;AAGF;AACA;AACA;AACA,qEAAoE,EAAE;AACtE,GAAE;;;AAGF;AACA;AACA;AACA,oEAAmE,EAAE;AACrE,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,0BAAyB;;AAEzB;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,0BAAyB;AACzB;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAa,wBAAwB;AACrC;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAa,mBAAmB;AAChC;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,kDAAiD;AACjD,8CAA6C;AAC7C,wDAAuD;AACvD;AACA,0BAAyB;AACzB,yBAAwB;AACxB;;AAEA;AACA;;AAEA,cAAa,yBAAyB;AACtC;;AAEA;AACA,oCAAmC;AACnC;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;;AAEA;AACA,yBAAwB;AACxB;AACA;AACA;AACA;AACA,KAAI;AACJ;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,wCAAuC;AACvC;;AAEA,cAAa,iBAAiB;AAC9B;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,EAAC;;;AAGD;AACA;;;AAGA,4BAA2B;AAC3B;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA,yCAAwC;AACxC;;;AAGA;AACA;AACA;;AAEA,aAAY,mBAAmB;AAC/B;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA,mDAAkD;AAClD;;;AAGA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAgB;AAChB,gBAAe;AACf;AACA;;AAEA,eAAc,eAAe;AAC7B;;AAEA;AACA;AACA,4BAA2B,cAAc;AACzC;AACA,SAAQ;AACR;AACA;;AAEA;AACA;AACA,2BAA0B,6BAA6B,EAAE;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,0BAAyB,uCAAuC;AAChE,0BAAyB,sCAAsC,EAAE;AACjE,yBAAwB,yCAAyC;AACjE,sBAAqB,mCAAmC;;AAExD;AACA;AACA;AACA;;AAEA,UAAS;AACT;;;AAGA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA,iDAAgD;AAChD,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gBAAe,cAAc;AAC7B;AACA;AACA;;AAEA;AACA;;AAEA;AACA,cAAa,aAAa;AAC1B;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA,GAAE;;;AAGF;AACA,gEAA+D;AAC/D;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA,yBAAwB;AACxB,iBAAgB;AAChB;AACA,8BAA6B;AAC7B,6CAA4C;AAC5C;AACA,SAAQ;AACR,kBAAiB;AACjB;AACA,GAAE;;;AAGF;AACA;AACA,gDAA+C;AAC/C,GAAE;;;AAGF;AACA;AACA,2BAA0B;AAC1B,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA,0BAAyB;AACzB;;AAEA;AACA;AACA;AACA,oBAAmB,2BAA2B;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,oCAAmC;AACnC;AACA,gCAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA,8DAA6D;;AAE7D;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAkB;AAClB;AACA,yBAAwB;AACxB;AACA,yBAAwB;AACxB;;AAEA,4CAA2C;AAC3C;AACA,+DAA8D;;AAE9D,gBAAe,cAAc;AAC7B;AACA;;AAEA;AACA;AACA;;AAEA;AACA,mCAAkC;AAClC,kCAAiC;;AAEjC,8BAA6B;;AAE7B;AACA;AACA;;AAEA;AACA;AACA;;AAEA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,gBAAe;AACf;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA,oCAAmC;AACnC;;AAEA;AACA;AACA,2BAA0B;AAC1B,yEAAwE;AACxE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,IAAG;;AAEH,mCAAkC;AAClC,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA,4CAA2C;;AAE3C,cAAa,iBAAiB;AAC9B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,EAAC;;AAED;;AAEA;AACA;;AAEA;;AAEA;;;AAGA;AACA;AACA,2BAA0B;AAC1B,wDAAuD;AACvD,GAAE;;;AAGF;AACA;AACA;AACA,oCAAmC;AACnC,GAAE;;;AAGF;AACA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH,6DAA4D;AAC5D,GAAE;;;AAGF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH,eAAc;AACd,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qCAAoC;;AAEpC;AACA,gBAAe,sBAAsB;AACrC;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,8CAA6C;AAC7C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,gDAA+C;AAC/C,gDAA+C;AAC/C;AACA,sBAAqB;AACrB,uBAAsB;AACtB,2BAA0B;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAa,cAAc,OAAO;AAClC;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe,sBAAsB,OAAO;AAC5C;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,4BAA2B;AAC3B;AACA;AACA;;AAEA,WAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,cAAa,iBAAiB;AAC9B;;AAEA;AACA,eAAc,mBAAmB;AACjC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAa,mBAAmB;AAChC;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA,cAAa,iBAAiB;AAC9B;AACA;;AAEA,cAAa,iBAAiB;AAC9B;AACA;;AAEA;AACA;;AAEA,EAAC;;;AAGD;AACA;AACA;;AAEA,aAAY,sBAAsB;AAClC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;;AAGA;AACA;AACA,2BAA0B;AAC1B;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,WAAU;AACV;;AAEA,gBAAe,yBAAyB;AACxC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,mCAAkC;AAClC,kCAAiC;AACjC;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAa,kBAAkB;AAC/B,iDAAgD;;AAEhD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,gBAAe;AACf,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,sBAAqB;AACrB,eAAc;AACd;AACA,iBAAgB;AAChB,kBAAiB;AACjB,oBAAmB;AACnB;AACA,iBAAgB;AAChB,sBAAqB;AACrB,oBAAmB;AACnB;AACA,oBAAmB;AACnB;AACA;;AAEA;AACA,qCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,+DAA8D;AAC9D;AACA;;AAEA;AACA,mCAAkC;;AAElC;AACA,eAAc,sBAAsB;AACpC;AACA,kCAAiC;;AAEjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,0BAAyB;AACzB,mDAAkD;AAClD;AACA;;AAEA;AACA,iBAAgB,yBAAyB;AACzC;AACA;AACA;AACA,uEAAsE;AACtE;AACA;AACA;AACA;AACA;;AAEA,uDAAsD;AACtD;AACA;AACA;;AAEA,iCAAgC;AAChC,qCAAoC;AACpC,2CAA0C;AAC1C;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;;AAEA;AACA;AACA;AACA,gDAA+C;AAC/C;AACA;AACA,KAAI;AACJ,GAAE;;;AAGF;AACA;AACA;AACA;AACA,oCAAmC;AACnC,aAAY;AACZ;;AAEA;AACA,oBAAmB;AACnB;AACA;AACA,qCAAoC;AACpC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,uEAAsE;AACtE;AACA;AACA,8CAA6C;AAC7C;;AAEA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,0CAAyC;AACzC;;AAEA,cAAa,iBAAiB;;AAE9B;AACA;AACA;;AAEA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,mBAAkB;;AAElB;AACA;AACA;AACA;AACA,kDAAiD;AACjD,+BAA8B;AAC9B;AACA;;AAEA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,EAAC;;AAED;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;AACA,+BAA8B;AAC9B;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,iDAAgD;AAChD,gBAAe;AACf;AACA;;AAEA;AACA;AACA,iDAAgD;AAChD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,oCAAmC;;AAEnC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gCAA+B;;AAE/B;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA;AACA,kDAAiD,QAAQ;AACzD;AACA;AACA;AACA;AACA;AACA;;AAEA,wCAAuC;AACvC,GAAE;;;AAGF;AACA;AACA,yBAAwB;AACxB,6CAA4C;AAC5C;AACA,SAAQ;AACR,kBAAiB;AACjB;AACA,GAAE;;;AAGF;AACA;AACA,gDAA+C;AAC/C,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,8EAA6E;AAC7E,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA,8CAA6C;AAC7C;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,gBAAe,cAAc;AAC7B,iCAAgC;AAChC;AACA;AACA;AACA;AACA,6CAA4C;AAC5C;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;;;AAGA,kCAAiC;AACjC;;AAEA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAa,iBAAiB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,wCAAuC;AACvC;AACA,sCAAqC;;AAErC,uBAAsB;AACtB;AACA,4DAA2D;AAC3D;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH,sDAAqD;;AAErD;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;;AAEA,aAAY;AACZ;AACA;;AAEA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA,oCAAmC;AACnC;;AAEA;AACA,cAAa,iBAAiB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA,uCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,6CAA4C;AAC5C,sCAAqC;;AAErC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iBAAgB,sBAAsB;AACtC;AACA;;AAEA;AACA;AACA;;AAEA,iBAAgB,oBAAoB;AACpC;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,EAAC;;AAED;;AAEA;AACA;;AAEA;;AAEA;;;AAGA;AACA;AACA,oCAAmC;;AAEnC;AACA;AACA;AACA;;AAEA,eAAc;AACd,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qCAAoC;;AAEpC,kCAAiC;;AAEjC,gBAAe,sBAAsB,SAAS;AAC9C;AACA,gCAA+B;;AAE/B;;AAEA;AACA,eAAc,oBAAoB;AAClC;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;;AAEA,uBAAsB;AACtB;AACA;;AAEA;;AAEA,eAAc,mBAAmB;AACjC;AACA;;AAEA,eAAc,mBAAmB;AACjC;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,wCAAuC;;AAEvC;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,kCAAiC;;AAEjC;AACA;AACA,aAAY,sBAAsB;AAClC;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA;;AAEA,cAAa,oBAAoB;AACjC;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA,cAAa,iBAAiB;AAC9B;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB;AACnB,qBAAoB;;AAEpB;;AAEA,qCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,6DAA4D;AAC5D;AACA,IAAG;AACH;AACA;AACA;AACA,8DAA6D;AAC7D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,yCAAwC;AACxC,uCAAsC;AACtC,gDAA+C;AAC/C,YAAW;AACX,aAAY;;AAEZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gCAA+B;AAC/B;AACA;;AAEA;AACA;AACA,8DAA6D;AAC7D;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA,cAAa,iBAAiB;AAC9B;AACA;;AAEA,cAAa,iBAAiB;AAC9B;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,EAAC;;;AAGD;AACA;AACA;AACA;AACA;AACA;;AAEA,WAAU,eAAe;AACzB;;AAEA;AACA,YAAW,iBAAiB;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA,WAAU,iBAAiB;AAC3B;;AAEA,YAAW,gBAAgB;AAC3B;;AAEA;AACA,eAAc,iBAAiB;AAC/B;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA,0CAAyC;;AAEzC,YAAW,sBAAsB;AACjC;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA,eAAc,oBAAoB;AAClC;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;;AAEA;AACA,gCAA+B;AAC/B;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA,oCAAmC;AACnC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kDAAiD;AACjD;AACA;AACA;AACA,SAAQ;AACR;AACA,6DAA4D;AAC5D;AACA;AACA,yDAAwD;AACxD;AACA;;AAEA;AACA;AACA;AACA,4CAA2C;;AAE3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,+CAA8C;AAC9C;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,KAAI,mDAAmD;AACvD;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAsC;AACtC;AACA;AACA,gBAAe;AACf;AACA;AACA,gBAAe;AACf;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA,wBAAuB;AACvB,kCAAiC;AACjC;;AAEA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,gBAAe;;AAEf;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,wCAAuC;AACvC;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,IAAG;AACH,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;;AAEA,oBAAmB;AACnB,uCAAsC;AACtC;AACA;AACA,8BAA6B;AAC7B,KAAI;AACJ;AACA;AACA,oBAAmB;AACnB;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA,8BAA6B;AAC7B,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAkB;AAClB;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA,gCAA+B;;AAE/B;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,mBAAkB;;AAElB;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH,6DAA4D;AAC5D,aAAY,yBAAyB,EAAE;;AAEvC;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,uCAAsC;AACtC;AACA,GAAE;;;AAGF;AACA;AACA;AACA,kDAAiD;AACjD;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,0BAAyB;AACzB;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,IAAG;AACH,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA,0BAAyB;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,IAAG;AACH,GAAE;;;AAGF;AACA;AACA;AACA;AACA,IAAG;AACH,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAa,iBAAiB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,gCAA+B;AAC/B,GAAE;;;AAGF;AACA;AACA,sEAAqE,EAAE,MAAM;AAC7E,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,4BAA2B;AAC3B,iEAAgE;AAChE;;AAEA;AACA,GAAE;;;AAGF;AACA;;AAEA;AACA;;AAEA;AACA,8CAA6C;AAC7C;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,gCAA+B;AAC/B,GAAE;;;AAGF;AACA;AACA,4EAA2E,EAAE,MAAM;AACnF,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,6BAA4B;AAC5B;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA,iDAAgD;AAChD,4BAA2B;AAC3B;AACA;;AAEA;AACA,0BAAyB;AACzB;;AAEA,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,+BAA8B;AAC9B;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,kDAAiD;AACjD;AACA;AACA;;AAEA;AACA,qCAAoC;AACpC,4BAA2B;;AAE3B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,WAAU;AACV,GAAE;;;AAGF;AACA;AACA,2CAA0C;;AAE1C;AACA;;AAEA,EAAC;;AAED;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,2BAA0B;AAC1B,GAAE;;;AAGF;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;AACxC;AACA,KAAI;;AAEJ,eAAc,sBAAsB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,sBAAqB;AACrB,0BAAyB;AACzB,2BAA0B;AAC1B;AACA,YAAW;AACX,iBAAgB;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB;;AAEnB,qCAAoC;AACpC,aAAY;AACZ;;AAEA;AACA;AACA,8CAA6C;AAC7C;AACA;AACA;;AAEA;AACA,uCAAsC;AACtC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,6BAA4B;AAC5B;AACA;;AAEA;AACA;AACA;AACA;AACA,sDAAqD;AACrD;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,8BAA6B;;AAE7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAqB;AACrB,GAAE;;;AAGF;AACA;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,WAAU;AACV;;AAEA,EAAC;;;AAGD;;;AAGA;AACA;;;AAGA,+BAA8B;AAC9B;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,kCAAiC;AACjC,4BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA6C,YAAY;AACzD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;;AAIF;AACA;;;AAGA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,wBAAuB;AACvB;AACA;AACA;AACA;AACA,+CAA8C;AAC9C;AACA;AACA,qDAAoD;AACpD;;AAEA,0BAAyB;AACzB;AACA;AACA,SAAQ;AACR;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA,kDAAiD;AACjD;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oBAAmB;AACnB;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;;;AAGA;AACA;AACA;;;;AAIA;AACA;;;AAGA;AACA;AACA;AACA;AACA,SAAQ;AACR,kBAAiB;AACjB,uBAAsB;AACtB;AACA,wBAAuB;AACvB;AACA;AACA;;;;AAIA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,0EAAyE;AACzE;AACA;AACA;;;AAGA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;;;AAIA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,0BAAyB;AACzB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,8BAA6B;;AAE7B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,2BAA0B;AAC1B;AACA;;;;AAIA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,iCAAgC;AAChC;;AAEA,gBAAe;AACf;AACA;;;AAGA;AACA;AACA;AACA;AACA;;;AAGA,wBAAuB;AACvB,mDAAkD;AAClD;AACA;AACA,iDAAgD;AAChD;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;;;AAGA,4BAA2B;AAC3B,mBAAkB;AAClB;AACA;;;AAGA,2BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;;;AAIA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;;AAGA,uBAAsB;AACtB;AACA;AACA;AACA;;;;AAIA;AACA;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA,gCAA+B;AAC/B;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;;;;AAIA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;;AAGA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;;;AAIA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;;;AAGA,mCAAkC;AAClC;;AAEA;AACA,yCAAwC;;AAExC;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA,+BAA8B,UAAU;AACxC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;AAGA,6BAA4B;AAC5B;AACA;;;AAGA,yBAAwB;AACxB,WAAU;AACV;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,oCAAmC;;;AAGnC;AACA;;;AAGA;AACA;AACA;;AAEA;AACA,4EAA2E;;AAE3E;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA,wEAAuE;;AAEvE;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,6CAA4C;AAC5C;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,+CAA8C;;AAE9C;AACA;;AAEA;AACA,qBAAoB;AACpB;AACA;AACA,6BAA4B;AAC5B;AACA;AACA,GAAE;;AAEF;AACA,0CAAyC;AACzC;AACA,4BAA2B;AAC3B,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,4BAA2B;AAC3B,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,4BAA2B;AAC3B,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,4BAA2B;AAC3B,GAAE;;AAEF;AACA;AACA;AACA,2BAA0B;AAC1B;;AAEA;;;AAGA;AACA,kCAAiC;;AAEjC;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;;;AAGA;AACA;AACA;AACA;AACA;AACA,2BAA0B;AAC1B;;;AAGA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,iBAAgB;;AAEhB;AACA,sDAAqD,SAAS;AAC9D;AACA;AACA;AACA,qEAAoE;AACpE;AACA;AACA;AACA;AACA;AACA,0BAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAsC;AACtC;AACA;AACA;AACA,2DAA0D;AAC1D,qDAAoD;AACpD;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAU;AACV;AACA;AACA;AACA;AACA,6CAA4C;AAC5C;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC;AACrC;AACA,KAAI;AACJ;;AAEA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;;AAGA,iCAAgC;AAChC;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;;AAGA;AACA,sBAAqB;AACrB;AACA;AACA;AACA;AACA,iBAAgB;;;AAGhB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,iBAAgB,wBAAwB;AACxC;;AAEA,2BAA0B;AAC1B;AACA;AACA;AACA;AACA;;AAEA,2BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;;AAGA;AACA;AACA;AACA;;AAEA,YAAW,mBAAmB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,2BAA0B,kBAAkB;;AAE5C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,uBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA,MAAK;AACL,KAAI;AACJ;AACA;AACA;AACA;;;;AAIA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,6CAA4C;AAC5C;AACA;;;AAGA,0CAAyC;AACzC;AACA;AACA;;AAEA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA;AACA,wBAAuB,eAAe;AACtC;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,sCAAqC;AACrC;AACA;AACA,MAAK;AACL;;AAEA,aAAY,sBAAsB;AAClC;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;;;AAIA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gDAA+C;AAC/C,uBAAsB;AACtB;;;AAGA;AACA;AACA;;AAEA;AACA;AACA,8CAA6C;AAC7C;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA,uBAAsB;AACtB;;AAEA,eAAc,mBAAmB;AACjC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;;AAEA,wBAAuB;AACvB,yBAAwB,aAAa,GAAG;AACxC;AACA,oCAAmC;AACnC;AACA;AACA;AACA;AACA;;AAEA;AACA,uCAAsC;;AAEtC;AACA;AACA;AACA,YAAW,kBAAkB;AAC7B;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA,6BAA4B;AAC5B;AACA;AACA;AACA,KAAI;AACJ;AACA,gBAAe;AACf;;;;AAIA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA,qCAAoC;AACpC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,sDAAqD;AACrD,gDAA+C;AAC/C,0BAAyB;AACzB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,iBAAgB;AAChB;AACA;;AAEA;AACA,+BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA4C;AAC5C;AACA;AACA,yCAAwC;AACxC;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,0BAAyB;AACzB;AACA;AACA;;AAEA,uBAAsB,SAAS;AAC/B;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,iBAAgB,gBAAgB;AAChC;AACA;AACA;;AAEA;AACA,4CAA2C;AAC3C;;AAEA,4CAA2C;;AAE3C,uCAAsC;AACtC,mCAAkC;AAClC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,0BAAyB,iBAAiB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gCAA+B;AAC/B;AACA;;AAEA;AACA;;;;AAIA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,qCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAgC;AAChC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,2CAA0C,kBAAkB;AAC5D,mDAAkD,sBAAsB;;AAExE;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAiC;;AAEjC;AACA;AACA;AACA;AACA,8CAA6C;AAC7C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,qCAAoC;AACpC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,yCAAwC;AACxC,4BAA2B;;AAE3B;AACA;AACA,6BAA4B;AAC5B,KAAI;AACJ,IAAG;;AAEH;AACA,mBAAkB,0BAA0B;AAC5C;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,mBAAkB;AAClB;AACA,OAAM;AACN;AACA,mDAAkD;AAClD;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,0CAAyC;;AAEzC;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,4BAA2B;AAC3B;AACA;;AAEA;AACA;AACA;AACA,SAAQ;;AAER,2CAA0C;;AAE1C;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,sBAAqB,SAAS;AAC9B;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,eAAc,6BAA6B;AAC3C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,cAAa,uBAAuB;AACpC;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,8BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,wCAAuC;AACvC;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;;AAEA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA,aAAY,kBAAkB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;;AAGA;AACA;AACA,yCAAwC;AACxC,GAAE;;;AAGF;AACA;AACA,6CAA4C;;AAE5C,yEAAwE;AACxE;AACA,GAAE;;;AAGF;AACA;AACA,4DAA2D;;AAE3D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,0DAAyD;AACzD;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;;AAEA,oDAAmD;AACnD;AACA;;AAEA;;AAEA;;AAEA;AACA,uDAAsD;;AAEtD;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;AAChC,mBAAkB;AAClB;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,mCAAkC;;AAElC;AACA;AACA,uCAAsC;AACtC;;AAEA;AACA;;AAEA;AACA;AACA,uCAAsC;AACtC;;AAEA,0EAAyE;;AAEzE;;AAEA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,4CAA2C;AAC3C;AACA;AACA,wDAAuD;AACvD;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;;AAEA,uBAAsB;AACtB,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA,EAAC;;AAED;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,iEAAgE;AAChE;;AAEA;AACA;AACA,mEAAkE;AAClE;AACA;;AAEA;AACA,GAAE;;;AAGF;AACA;;AAEA,0DAAyD;;AAEzD;AACA;AACA;AACA;;AAEA,0DAAyD;AACzD,GAAE;;;AAGF;AACA,uCAAsC;AACtC;AACA,gCAA+B;AAC/B;;AAEA;AACA;;AAEA,EAAC;;AAED;;AAEA;AACA;AACA;;AAEA;AACA;AACA,aAAY;AACZ;;AAEA;AACA;AACA,aAAY;AACZ;;AAEA;AACA;AACA,aAAY,YAAY;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA,gCAA+B;AAC/B,qCAAoC;;AAEpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA,6CAA4C;;AAE5C;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;AAEA;;AAEA;AACA;AACA,wDAAuD;;AAEvD;AACA;;AAEA;AACA;AACA,gCAA+B;;AAE/B;AACA;AACA;;AAEA;AACA;AACA;;AAEA,qEAAoE;AACpE,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;AAEA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;;AAEA,kDAAiD;AACjD,GAAE;;;AAGF;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,4BAA2B;;AAE3B;AACA;AACA;AACA;;AAEA;AACA;AACA,oCAAmC;;AAEnC;AACA;AACA,6CAA4C;AAC5C;AACA;AACA;AACA;AACA;;AAEA,iBAAgB;;AAEhB;AACA,gEAA+D;;AAE/D;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,sEAAqE;AACrE;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,UAAS;AACT;;AAEA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAa,mBAAmB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,EAAC;;AAED;;AAEA;;AAEA;AACA;AACA;AACA,GAAE,WAAW;AACb,GAAE,cAAc;AAChB,GAAE,cAAc;AAChB,GAAE,cAAc;AAChB,GAAE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAY;AACZ;;AAEA;AACA;AACA,aAAY;AACZ;AACA;;AAEA,WAAU;AACV,EAAC,E;;;;;;ACj6VD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,oBAAoB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,oBAAmB,gBAAgB;AACnC;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,YAAY;AACzB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,iCAAgC;AAChC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,2KAA0K,IAAI;;AAE9K,sEAAqE,IAAI;;AAEzE;;AAEA;;AAEA;AACA;AACA;AACA,+BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,2CAA0C,YAAY;AACtD;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA;AACA,wBAAuB,YAAY;AACnC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,+BAA8B;AAC9B,iCAAgC;AAChC,8BAA6B,EAAE,EAAE;AACjC,8BAA6B,EAAE,EAAE;AACjC,mCAAkC,EAAE,EAAE;AACtC,kCAAiC;AACjC,8BAA6B,IAAI,EAAE;AACnC,8BAA6B,IAAI,EAAE;AACnC,mCAAkC,IAAI,EAAE;;AAExC,gCAA+B;AAC/B,qCAAoC;;AAEpC,+CAA8C;;AAE9C,yCAAwC,IAAI,IAAI;;AAEhD;AACA,iIAAgI,IAAI;;AAEpI;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS,+BAA+B;AACxC;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB,kBAAkB;AACrC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,oBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA,cAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,gDAA+C,EAAE,IAAI,EAAE;;AAEvD;AACA,kCAAiC,EAAE,IAAI,EAAE,IAAI,EAAE;AAC/C,4BAA2B,EAAE,IAAI,EAAE,IAAI,EAAE;AACzC,8BAA6B,EAAE,KAAK,EAAE;AACtC,4BAA2B,EAAE,KAAK,EAAE;AACpC,0BAAyB,EAAE,IAAI,EAAE;AACjC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,6CAA4C,OAAO;AACnD;AACA;AACA;AACA;AACA;AACA,6CAA4C,OAAO;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oBAAmB,+BAA+B;AAClD;AACA;;AAEA;AACA,eAAc,OAAO;AACrB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,oBAAmB,mBAAmB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,oBAAmB,sBAAsB;AACzC;AACA,uCAAsC;AACtC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,0CAAyC,gBAAgB;AACzD;;AAEA;AACA;AACA;;AAEA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA,cAAa;AACb;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,0BAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,sEAAqE,EAAE;;AAEvE;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS,6BAA6B;AACtC;AACA,UAAS;AACT;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oBAAmB;;AAEnB;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA0B,cAAc;AACxC;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,wCAAuC,qBAAqB;AAC5D;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,wCAAuC,qBAAqB;AAC5D;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,yBAAwB;AACxB;;AAEA;AACA;AACA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,yBAAwB,mBAAmB;AAC3C;AACA;;AAEA;AACA;AACA;;AAEA,sBAAqB,mBAAmB;AACxC;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,mCAAkC,IAAI;;AAEtC;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,uFAAsF,IAAI;AAC1F;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,oBAAmB,WAAW;AAC9B;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;;AAEL;;;AAGA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC,G;;;;;;;AC1nGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAiC,uDAAuD;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACfA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC,0BAA0B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT,2BAA0B,IAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA,EAAC,G;;;;;;ACjED;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;;AAEA;AACA;AACA;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAY;AACZ;AACA;;;AAGA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;;AAEA;AACA,qBAAoB;AACpB,qCAAoC,4DAA4D;AAChG,uCAAsC,4EAA4E;AAClH,wCAAuC,8EAA8E;AACrH,2BAA0B,oDAAoD;;AAE9E;AACA;AACA,uCAAsC,kBAAkB;AACxD;AACA;AACA;;AAEA;AACA,qBAAoB,6CAA6C;;AAEjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;AACA,+BAA8B,6BAA6B;AAC3D;AACA;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;AACL;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA,aAAY;AACZ,eAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;;;;;;AC5vBA,yC;;;;;;ACAA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,8CAA6C;AAC7C;AACA;AACA,UAAS;AACT;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA,8CAA6C;AAC7C;AACA;AACA;AACA,UAAS;AACT;AACA,MAAK;AACL;;AAEA;AACA;AACA,EAAC;;;;;;;AC9GD;;AAEA;;AAEA,iCAAgC;AAChC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAoD;AACpD;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;;;;;;;ACnDA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,aAAa;AACxB,YAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,oCAAmC,OAAO;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAuB,SAAS,GAAG,SAAS;AAC5C,4BAA2B;AAC3B;AACA;AACA,YAAW,OAAO;AAClB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACxNA;;AAEA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;;;;;;;ACrBA;;AAEA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;AACH;;;;;;;;;ACxBA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,wBAAuB,sBAAsB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAqB;AACrB;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,4BAA2B;AAC3B;AACA;AACA;AACA,6BAA4B,UAAU;;;;;;;AC1FtC;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,0CAAyC;AACzC;AACA;;AAEA;AACA,2CAA0C;AAC1C;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;ACzGA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;;;;;;;ACnDA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,qCAAoC;AACpC,IAAG;;AAEH;AACA,uDAAsD,wBAAwB;AAC9E;AACA,IAAG;;AAEH;AACA;AACA;AACA;;;;;;;ACpCA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,OAAO;AACpB;AACA;AACA,kBAAiB;;AAEjB,kBAAiB,eAAe;;AAEhC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;;;;;;ACjCA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW,cAAc;AACzB,YAAW,MAAM;AACjB,YAAW,eAAe;AAC1B,cAAa,EAAE;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;;;;;;AClBA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;;;;;;;ACnDA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,SAAS;AACpB,YAAW,SAAS;AACpB;AACA,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;;;;;;;+CCnDA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA,4CAA2C;AAC3C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,4EAA2E;;AAE3E;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,+BAA8B,sBAAsB;;AAEpD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,sBAAqB,+BAA+B;AACpD;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,wBAAuB,QAAQ;AAC/B;AACA;AACA;AACA,YAAW;AACX;AACA;AACA,UAAS;AACT,wBAAuB,QAAQ;AAC/B;;AAEA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,mEAAkE,QAAQ;;AAE1E;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,mEAAkE,QAAQ;AAC1E;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,sCAAqC,QAAQ;;AAE7C;;AAEA,sBAAqB,wBAAwB;AAC7C;AACA;;AAEA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;;AAEA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT,QAAO;AACP;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,sBAAqB,qEAAqE;AAC1F;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,sBAAqB,qEAAqE;AAC1F;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,QAAO;AACP;;AAEA;AACA,eAAc,SAAS;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA,QAAO;AACP;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;;AAEA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA,QAAO;AACP;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,QAAO;AACP;;AAEA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA,cAAa;AACb,YAAW;AACX;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;;AAEA;AACA,eAAc,SAAS;AACvB,eAAc,SAAS;AACvB;AACA,gBAAe;AACf;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;AACX,UAAS;AACT;AACA;;AAEA;AACA,QAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;;AAEA;AACA,eAAc,SAAS;AACvB;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA,YAAW;AACX;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,qDAAyB,wCAAwC,EAAE;AACnE,MAAK;AACL;AACA,MAAK;AACL;AACA;;AAEA;AACA,EAAC;;;;;;;;;AC18BD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA2C,iBAAiB;;AAE5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA,G;;;;;;;AC3EA,gB;;;;;;ACAA,8BAA6B,mDAAmD;;;;;;;ACAhF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAA+B;AAC/B;AACA;AACA,YAAW,SAAS;AACpB,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;;;;;;;mCC1BA;AACA,EAAC;;AAED;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAEA;AACA;AACA;AACA;AACA,IAAG;AACH,GAAE;AACF,oBAAmB;AACnB;AACA,IAAG,OAAO;AACV;AACA;AACA;AACA;AACA,GAAE,OAAO;AACT;AACA;;AAEA,EAAC;;;;;;;;ACpKD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA,EAAC;;AAED;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,wBAAuB,KAAK;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;;AAEA,EAAC;;;;;;;AClID;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AClBA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;AACH;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC5IA;;AAEA;AACA;AACA;AACA;AACA,gDAAqE,iBAAiB;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,iCAAgC,UAAU,EAAE;AAC5C,E;;;;;;ACpBA;AACA;;;AAGA;AACA,6IAA4I,cAAc,gBAAgB,QAAQ,iBAAiB,SAAS,cAAc,6IAA6I,kBAAkB,yBAAyB,sBAAsB,6DAA6D,gBAAgB,8CAA8C,WAAW,uBAAuB,mBAAmB,cAAc,mBAAmB,0BAA0B,WAAW,yBAAyB,YAAY,mBAAmB,gBAAgB,mBAAmB,SAAS,qBAAqB,UAAU,WAAW,gBAAgB,cAAc,kBAAkB,gBAAgB,0CAA0C,2BAA2B,yBAAyB,sBAAsB,qBAAqB,iBAAiB,eAAe,kBAAkB,cAAc,iCAAiC,mBAAmB,gBAAgB,eAAe,QAAQ,QAAQ,kCAAkC,mBAAmB,gBAAgB,eAAe,QAAQ,SAAS,iCAAiC,iBAAiB,eAAe,QAAQ,kCAAkC,iBAAiB,eAAe,QAAQ,6BAA6B,mBAAmB,eAAe,OAAO,SAAS,8BAA8B,mBAAmB,eAAe,OAAO,QAAQ,6BAA6B,mBAAmB,eAAe,OAAO,iBAAiB,iBAAiB,eAAe,OAAO,WAAW,sBAAsB,SAAS,aAAa,eAAe,cAAc,mBAAmB,eAAe,6BAA6B,SAAS,UAAU,kBAAkB,iBAAiB,iCAAiC,2BAA2B,8BAA8B,kCAAkC,4BAA4B,+BAA+B,oBAAoB,kBAAkB,WAAW,cAAc,sBAAsB,kBAAkB,yBAAyB,4EAA4E,2DAA2D,yDAAyD,2BAA2B,qCAAqC,2DAA2D,WAAW,0CAA0C,sEAAsE,mEAAmE,WAAW,yBAAyB,gBAAgB,WAAW,qBAAqB,4BAA4B,kDAAkD,0CAA0C,gCAAgC,sBAAsB,sBAAsB,qEAAqE,mBAAmB,eAAe,sBAAsB,YAAY,yBAAyB,gBAAgB,iBAAiB,qBAAqB,uBAAuB,WAAW,kBAAkB,kCAAkC,cAAc,YAAY,kBAAkB,qCAAqC,uBAAuB,gBAAgB,iCAAiC,aAAa,iCAAiC,eAAe,kFAAkF,WAAW,kFAAkF,YAAY,yBAAyB,iBAAiB,mBAAmB,8CAA8C,eAAe,eAAe,iDAAiD,aAAa,YAAY,mBAAmB,iBAAiB,cAAc,SAAS,SAAS,gBAAgB,mBAAmB,UAAU,WAAW,uEAAuE,kBAAkB,MAAM,OAAO,QAAQ,OAAO,SAAS,aAAa,YAAY,UAAU,WAAW,mBAAmB,yBAAyB,iBAAiB,cAAc,OAAO,kBAAkB,cAAc,mBAAmB,iBAAiB,UAAU,mBAAmB,gBAAgB,oBAAoB,YAAY,mBAAmB,eAAe,cAAc,iCAAiC,kCAAkC,mCAAmC,0BAA0B,gCAAgC,QAAQ,kBAAkB,eAAe,UAAU,4DAA4D,SAAS,wEAAwE,YAAY,kEAAkE,yBAAyB,6BAA6B,UAAU,+BAA+B,UAAU,6BAA6B,kBAAkB,UAAU,mBAAmB,4BAA4B,UAAU,+DAA+D,gBAAgB,yBAAyB,gBAAgB,2EAA2E,aAAa,aAAa,kBAAkB,kBAAkB,eAAe,kBAAkB,WAAW,gBAAgB,UAAU,kBAAkB,cAAc,gBAAgB,gBAAgB,kBAAkB,yBAAyB,yBAAyB,gBAAgB,+CAA+C,WAAW,qBAAqB,uCAAuC,eAAe,0CAA0C,mBAAmB,iBAAiB,UAAU,gBAAgB,YAAY,yBAAyB,sBAAsB,kBAAkB,UAAU,sBAAsB,kBAAkB,UAAU,gEAAgE,cAAc,oBAAoB,iBAAiB,yBAAyB,4BAA4B,gEAAgE,eAAe,qBAAqB,kBAAkB,0BAA0B,6BAA6B,wBAAwB,SAAS,YAAY,UAAU,WAAW,UAAU,wPAAwP,WAAW,gBAAgB,wPAAwP,UAAU,gBAAgB,mBAAmB,iBAAiB,cAAc,+BAA+B,mBAAmB,gBAAgB,4BAA4B,gBAAgB,+BAA+B,UAAU,WAAW,UAAU,UAAU,eAAe,gBAAgB,eAAe,qBAAqB,gBAAgB,0BAA0B,YAAY,aAAa,qBAAqB,UAAU,iBAAiB,UAAU,YAAY,qCAAqC,aAAa,YAAY,kBAAkB,kBAAkB,qBAAqB,WAAW,sBAAsB,YAAY,uBAAuB,qBAAqB,oBAAoB,WAAW,kBAAkB,+BAA+B,cAAc,eAAe,SAAS,mBAAmB,kBAAkB,wDAAwD,UAAU,2BAA2B,UAAU,0DAA0D,UAAU,yBAAyB,UAAU,0EAA0E,uBAAuB,wBAAwB,kBAAkB,UAAU,+EAA+E,gBAAgB,mBAAmB,gCAAgC,eAAe,iBAAiB,gBAAgB,sCAAsC,kBAAkB,MAAM,OAAO,QAAQ,6DAA6D,cAAc,sEAAsE,gBAAgB,mBAAmB,+BAA+B,kBAAkB,oCAAoC,qBAAqB,iBAAiB,sCAAsC,iBAAiB,sCAAsC,gBAAgB,8BAA8B,WAAW,yBAAyB,6BAA6B,kBAAkB,UAAU,qCAAqC,eAAe,0DAA0D,gBAAgB,mBAAmB,aAAa,sBAAsB,cAAc,mBAAmB,iBAAiB,iBAAiB,iBAAiB,gBAAgB,sBAAsB,gBAAgB,sCAAsC,kBAAkB,UAAU,cAAc,gBAAgB,oBAAoB,4BAA4B,qBAAqB,UAAU,yCAAyC,kBAAkB,UAAU,sEAAsE,kBAAkB,MAAM,OAAO,QAAQ,mCAAmC,UAAU,qCAAqC,UAAU,mCAAmC,UAAU,kCAAkC,UAAU,2BAA2B,aAAa,gBAAgB,qCAAqC,wBAAwB,2CAA2C,gBAAgB,sCAAsC,kBAAkB,4BAA4B,kBAAkB,OAAO,QAAQ,sEAAsE,kBAAkB,0CAA0C,oBAAoB,0CAA0C,oBAAoB,kDAAkD,kBAAkB,UAAU,0BAA0B,OAAO,QAAQ,yBAAyB,mBAAmB,gBAAgB,yBAAyB,0BAA0B,uBAAuB,sBAAsB,mBAAmB,4BAA4B,6BAA6B,oBAAoB,gBAAgB,2DAA2D,cAAc,6BAA6B,gBAAgB,mBAAmB,yCAAyC,mBAAmB,6EAA6E,qBAAqB,mBAAmB,2CAA2C,aAAa,6CAA6C,yBAAyB,4CAA4C,sBAAsB,uCAAuC,gBAAgB,UAAU,gCAAgC,OAAO,QAAQ,SAAS,WAAW,gBAAgB,gBAAgB,eAAe,sBAAsB,kBAAkB,gBAAgB,sCAAsC,cAAc;;AAE3rW;;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,iBAAgB,iBAAiB;AACjC;AACA;AACA,yCAAwC,gBAAgB;AACxD,KAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAgB,iBAAiB;AACjC;AACA;AACA;AACA;AACA,aAAY,oBAAoB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACjDA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,iBAAgB,mBAAmB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB,sBAAsB;AACtC;AACA;AACA,mBAAkB,2BAA2B;AAC7C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,gBAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA,kBAAiB,2BAA2B;AAC5C;AACA;AACA,SAAQ,uBAAuB;AAC/B;AACA;AACA,IAAG;AACH;AACA,kBAAiB,uBAAuB;AACxC;AACA;AACA,4BAA2B;AAC3B;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe,iBAAiB;AAChC;AACA;AACA;AACA;AACA;AACA,eAAc;AACd;AACA,iCAAgC,sBAAsB;AACtD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;;AAEA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,wDAAuD;AACvD;;AAEA,8BAA6B,mBAAmB;;AAEhD;;AAEA;;AAEA;AACA;AACA;;;;;;;ACvPA;;AAEA;AACA;AACA;AACA;AACA,gDAAkF,iBAAiB;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,iCAAgC,UAAU,EAAE;AAC5C,E;;;;;;ACpBA;AACA;;;AAGA;AACA,8CAA6C,yBAAyB,WAAW,yBAAyB,gCAAgC,wCAAwC,yBAAyB,eAAe,gBAAgB,4DAA4D,cAAc,SAAS,eAAe,kBAAkB,iBAAiB,gBAAgB,sBAAsB,sBAAsB,kBAAkB,WAAW,yBAAyB,gBAAgB,gBAAgB,qBAAqB,0BAA0B,gBAAgB,UAAU,gBAAgB,gCAAgC,yBAAyB,kBAAkB,YAAY,UAAU,cAAc,oCAAoC,4BAA4B,WAAW,+BAA+B,UAAU,2CAA2C,8BAA8B,sBAAsB,UAAU,wCAAwC,kBAAkB,wCAAwC,iBAAiB,kCAAkC,gBAAgB,iDAAiD,iBAAiB,uBAAuB,gBAAgB,6DAA6D,mBAAmB,OAAO,kBAAkB,YAAY,6DAA6D,6BAA6B,0BAA0B,UAAU,UAAU,uCAAuC,+BAA+B,YAAY,8BAA8B,YAAY,sBAAsB,kBAAkB,WAAW,aAAa,qCAAqC,eAAe,kBAAkB,UAAU,gBAAgB,WAAW,yBAAyB,8BAA8B,qCAAqC,iBAAiB,UAAU,mBAAmB,aAAa,WAAW,4BAA4B,gBAAgB,qCAAqC,sBAAsB,2BAA2B,yBAAyB,mCAAmC,yBAAyB,yCAAyC,eAAe,iBAAiB,4CAA4C,WAAW,6BAA6B,gBAAgB,YAAY,6IAA6I,qBAAqB,iCAAiC,WAAW;;AAEx9E;;;;;;;ACPA;;AAEA;AACA;AACA;AACA;AACA,gDAAkF,iBAAiB;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,iCAAgC,UAAU,EAAE;AAC5C,E;;;;;;ACpBA;AACA;;;AAGA;AACA,2CAA0C,GAAG,gCAAgC,yBAAyB,yBAAyB,GAAG,gCAAgC,wBAAwB,IAAI,kCAAkC,0BAA0B,IAAI,mCAAmC,2BAA2B,IAAI,kCAAkC,2BAA2B,iBAAiB,MAAM,gCAAgC,wBAAwB,IAAI,kCAAkC,0BAA0B,IAAI,mCAAmC,2BAA2B,IAAI,kCAAkC,0BAA0B,GAAG,gCAAgC,yBAAyB;;AAE1sB;;;;;;;ACPA;;AAEA;AACA;AACA;AACA;AACA,gDAAkF,iBAAiB;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,iCAAgC,UAAU,EAAE;AAC5C,E;;;;;;ACpBA;AACA;AACA,kGAAiG;;AAEjG;AACA,qHAAoH,kBAAkB,wDAAwD,eAAe,kBAAkB,sBAAsB,sCAAsC,sBAAsB,WAAW,UAAU,WAAW,gBAAgB,oCAAoC,4BAA4B,UAAU,0BAA0B,cAAc,kBAAkB,iBAAiB,yBAAyB,6BAA6B,gBAAgB,WAAW,0BAA0B,wBAAwB,WAAW,iBAAiB,kBAAkB,kBAAkB,UAAU,SAAS,mCAAmC,+BAA+B,2BAA2B,oBAAoB,sBAAsB,uCAAuC,gBAAgB,WAAW,sBAAsB,sBAAsB,eAAe,sBAAsB,qBAAqB,WAAW,YAAY,uBAAuB,kBAAkB,MAAM,OAAO,kBAAkB,WAAW,gBAAgB,oBAAoB,kBAAkB,YAAY,WAAW,MAAM,OAAO,yBAAyB,WAAW,UAAU,oCAAoC,4BAA4B,kBAAkB,yBAAyB,UAAU,0BAA0B,kBAAkB,MAAM,QAAQ,aAAa,oCAAoC,4BAA4B,WAAW,gCAAgC,UAAU,yBAAyB,kBAAkB,eAAe,gBAAgB,gBAAgB,mBAAmB,0CAA0C,eAAe,gBAAgB,mBAAmB,yBAAyB,kBAAkB,eAAe,gBAAgB,mBAAmB,0CAA0C,eAAe,mBAAmB,qBAAqB,WAAW,gBAAgB,YAAY,kBAAkB,cAAc,kBAAkB,iCAAiC,UAAU,oBAAoB,kBAAkB,sCAAsC,kBAAkB,gBAAgB,sBAAsB,cAAc,gCAAgC,kBAAkB,WAAW,OAAO,QAAQ,aAAa,sBAAsB,UAAU,oCAAoC,4BAA4B,mBAAmB,iDAAiD,kBAAkB,uCAAuC,gBAAgB,8CAA8C,cAAc,wDAAwD,UAAU,MAAM,SAAS,sBAAsB,uCAAuC,+BAA+B,WAAW,kBAAkB,uBAAuB,cAAc,+CAA+C,gBAAgB,sBAAsB,mBAAmB,wDAAwD,4BAA4B,UAAU,qCAAqC,6BAA6B,aAAa,uBAAuB,kBAAkB,sDAAsD,8CAA8C,qBAAqB,kBAAkB,yBAAyB,yBAAyB,uCAAuC,WAAW,SAAS,kBAAkB,gBAAgB,gBAAgB,gBAAgB,eAAe,YAAY,UAAU,kBAAkB,gBAAgB,0EAA0E,oCAAoC,4BAA4B,kBAAkB,SAAS,SAAS,mCAAmC,+BAA+B,2BAA2B,sCAAsC,UAAU,0EAA0E,UAAU,yCAAyC,YAAY,WAAW,2CAA2C,mCAAmC,yCAAyC,YAAY,eAAe,2BAA2B,uBAAuB,mBAAmB,8CAA8C,sCAAsC,8BAA8B,yDAAyD,6BAA6B,yBAAyB,oCAAoC,mCAAmC,2BAA2B,oGAAoG,eAAe,yBAAyB,kIAAkI,UAAU,gIAAgI,UAAU,oGAAoG,eAAe,yBAAyB,kQAAkQ,UAAU,gIAAgI,UAAU,wIAAwI,2BAA2B,uBAAuB,mBAAmB,qBAAqB,kBAAkB,SAAS,OAAO,QAAQ,kBAAkB,iBAAiB,uBAAuB,kCAAkC,0BAA0B,cAAc,qBAAqB,gCAAgC,iCAAiC,yBAAyB,aAAa,6BAA6B,WAAW,sCAAsC,UAAU,uBAAuB,WAAW,iBAAiB,mBAAmB;;AAElkM;;;;;;;ACPA,ooD;;;;;;ACAA;AACA,8BAA6B,yBAAyB,wBAAwB,YAAY,aAAa,gDAAgD,UAAU,cAAc,UAAU,oCAAoC,UAAU,cAAc,4CAA4C,GAAG,IAAI,yBAAyB,mCAAmC,eAAe,EAAE,SAAS,cAAc,4CAA4C,wDAAwD,GAAG,IAAI,yBAAyB,qCAAqC,sCAAsC,eAAe,yCAAyC,YAAY,gCAAgC,mDAAmD,eAAe,EAAE,SAAS,cAAc,uDAAuD,oDAAoD,gCAAgC,eAAe,kBAAkB,cAAc,cAAc,UAAU,cAAc,EAAE,aAAa,SAAS,IAAI,mDAAmD,iBAAiB,QAAQ,YAAY,mCAAmC,YAAY,QAAQ,YAAY,QAAQ,uBAAuB,iCAAiC,kBAAkB,SAAS,qBAAqB,MAAM,YAAY,mDAAmD,uBAAuB,UAAU,uBAAuB,gDAAgD,YAAY,eAAe,uBAAuB,MAAM,YAAY,kBAAkB,SAAS,EAAE,G;;;;;;ACD/iD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;;;;;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAM;AACN;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAkB;AAClB,mBAAkB;;AAElB;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;;AAEA;AACA;AACA,8BAA6B,mBAAmB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,sCAAqC,mBAAmB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,sBAAqB,SAAS;AAC9B;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,gBAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,YAAW;AACX;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA,wBAAuB;AACvB,sFAAqF;AACrF;AACA;AACA;AACA,4BAA2B;AAC3B,4BAA2B;AAC3B;AACA,cAAa;AACb;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,kDAAiD;AACjD;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,oCAAmC,OAAO;AAC1C;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,yBAAwB;;AAExB;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,qCAAoC,OAAO;AAC3C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,qCAAoC,OAAO;AAC3C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,0DAAyD,iBAAiB;AAC1E;AACA,cAAa,0BAA0B;AACvC;;AAEA;AACA;AACA;AACA,0CAAyC,iGAAiG;AAC1I;AACA,wBAAuB,2BAA2B;AAClD;;AAEA;AACA,cAAa,wBAAwB,uCAAuC,qCAAqC;AACjH;;AAEA;AACA;AACA;AACA,oBAAmB,mBAAmB,cAAc;AACpD;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,wBAAuB,aAAa,0BAA0B;AAC9D;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,0BAAyB,QAAQ;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,8BAA6B;AAC7B,uFAAsF;AACtF;AACA;;AAEA;AACA;AACA;AACA,sGAAqG;AACrG,sDAAqD;AACrD;AACA,yBAAwB,EAAE,SAAS;AACnC,MAAK;;AAEL;AACA,2GAA0G;AAC1G;AACA,0BAAyB;AACzB,MAAK;;AAEL;AACA;AACA,kBAAiB,YAAY,oBAAoB;AACjD;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA,kBAAiB,QAAQ;AACzB;AACA;AACA;AACA,6DAA4D;AAC5D;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA,8FAA6F;AAC7F,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL,OAAM;;AAEN;AACA;;AAEA;AACA,4FAA2F;AAC3F;;AAEA;AACA,4BAA2B;AAC3B;;AAEA;AACA;AACA,yCAAwC,OAAO;AAC/C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,EAAC;;;;;;;ACtaD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,8CAA6C,WAAW,EAAE;;AAE1D;AACA;;AAEA;AACA;;AAEA;AACA,+CAA8C;AAC9C,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,sBAAqB,iBAAiB;AACtC;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP,wBAAuB,kBAAkB;AACzC;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA,mCAAkC,QAAQ;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA,qBAAoB,eAAe,EAAE;;AAErC,qBAAoB,kBAAkB,eAAe,UAAU,EAAE;;AAEjE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA0B;AAC1B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,8BAA6B;AAC7B,4BAA2B;AAC3B,4BAA2B;AAC3B,+BAA8B;AAC9B,gCAA+B;AAC/B;AACA;;AAEA;AACA;AACA;;AAEA,EAAC;;;;;;;ACpVD;AACA,8BAA6B,yBAAyB,wBAAwB,YAAY,aAAa,wCAAwC,cAAc,qBAAqB,6BAA6B,aAAa,cAAc,cAAc,UAAU,cAAc,EAAE,aAAa,SAAS,IAAI,oDAAoD,UAAU,qBAAqB,SAAS,EAAE,G;;;;;;ACD1Y;AACA,8BAA6B,yBAAyB,wBAAwB,YAAY,aAAa,6CAA6C,cAAc,gBAAgB,4BAA4B,eAAe,cAAc,cAAc,UAAU,cAAc,EAAE,aAAa,SAAS,IAAI,oDAAoD,QAAQ,uBAAuB,SAAS,EAAE,G;;;;;;ACD3Y;AACA,8BAA6B,yBAAyB,wBAAwB,YAAY,aAAa,cAAc,cAAc,cAAc,mDAAmD,cAAc,uBAAuB,cAAc,uBAAuB,cAAc,wBAAwB,+CAA+C,UAAU,cAAc,UAAU,2DAA2D,GAAG,IAAI,yBAAyB,iBAAiB,6CAA6C,YAAY,EAAE,SAAS,cAAc,kBAAkB,cAAc,UAAU,UAAU,cAAc,cAAc,cAAc,oDAAoD,cAAc,wBAAwB,cAAc,wBAAwB,cAAc,wBAAwB,gDAAgD,UAAU,cAAc,UAAU,4DAA4D,GAAG,IAAI,yBAAyB,iBAAiB,8CAA8C,YAAY,EAAE,SAAS,cAAc,kBAAkB,cAAc,UAAU,UAAU,cAAc,0DAA0D,GAAG,IAAI,yBAAyB,gBAAgB,cAAc,sDAAsD,cAAc,wBAAwB,cAAc,0BAA0B,cAAc,0BAA0B,gDAAgD,UAAU,cAAc,YAAY,4DAA4D,GAAG,IAAI,yBAAyB,iBAAiB,8CAA8C,YAAY,EAAE,SAAS,cAAc,YAAY,2DAA2D,GAAG,IAAI,yBAAyB,mBAAmB,EAAE,SAAS,cAAc,YAAY,eAAe,EAAE,SAAS,cAAc,0DAA0D,GAAG,IAAI,yBAAyB,gBAAgB,cAAc,qDAAqD,cAAc,yBAAyB,cAAc,yBAAyB,cAAc,0BAA0B,+CAA+C,UAAU,cAAc,YAAY,6DAA6D,GAAG,IAAI,yBAAyB,iBAAiB,6CAA6C,YAAY,EAAE,SAAS,cAAc,YAAY,4DAA4D,GAAG,IAAI,yBAAyB,mBAAmB,EAAE,SAAS,cAAc,YAAY,eAAe,EAAE,SAAS,cAAc,+DAA+D,GAAG,IAAI,yBAAyB,gBAAgB,cAAc,yDAAyD,cAAc,yBAAyB,cAAc,6BAA6B,cAAc,0BAA0B,mDAAmD,UAAU,cAAc,YAAY,iEAAiE,GAAG,IAAI,yBAAyB,iBAAiB,iDAAiD,YAAY,EAAE,SAAS,cAAc,YAAY,gEAAgE,GAAG,IAAI,yBAAyB,mBAAmB,EAAE,SAAS,cAAc,YAAY,eAAe,EAAE,SAAS,cAAc,8DAA8D,GAAG,IAAI,yBAAyB,mBAAmB,cAAc,wDAAwD,cAAc,sBAAsB,cAAc,4BAA4B,cAAc,0BAA0B,kDAAkD,UAAU,cAAc,YAAY,gEAAgE,GAAG,IAAI,yBAAyB,iBAAiB,gDAAgD,YAAY,EAAE,SAAS,cAAc,YAAY,+DAA+D,GAAG,IAAI,yBAAyB,mBAAmB,EAAE,SAAS,cAAc,YAAY,eAAe,EAAE,SAAS,cAAc,EAAE,aAAa,SAAS,IAAI,8GAA8G,2BAA2B,QAAQ,0BAA0B,WAAW,yBAAyB,KAAK,0BAA0B,gIAAgI,4BAA4B,QAAQ,2BAA2B,WAAW,0BAA0B,KAAK,2BAA2B,sBAAsB,yBAAyB,sHAAsH,4BAA4B,UAAU,2BAA2B,WAAW,0BAA0B,KAAK,2BAA2B,QAAQ,0BAA0B,YAAY,0BAA0B,UAAU,yBAAyB,MAAM,wBAAwB,qHAAqH,2BAA2B,UAAU,0BAA0B,WAAW,yBAAyB,KAAK,0BAA0B,QAAQ,yBAAyB,YAAY,yBAAyB,UAAU,wBAAwB,MAAM,4BAA4B,6HAA6H,+BAA+B,UAAU,8BAA8B,WAAW,6BAA6B,KAAK,8BAA8B,QAAQ,6BAA6B,YAAY,6BAA6B,UAAU,4BAA4B,MAAM,2BAA2B,2HAA2H,8BAA8B,UAAU,6BAA6B,WAAW,4BAA4B,KAAK,6BAA6B,QAAQ,4BAA4B,YAAY,4BAA4B,UAAU,2BAA2B,MAAM,SAAS,EAAE,G;;;;;;ACDzzM;AACA,8BAA6B,yBAAyB,wBAAwB,YAAY,aAAa,0CAA0C,cAAc,2DAA2D,iCAAiC,YAAY,cAAc,gDAAgD,kCAAkC,aAAa,cAAc,gDAAgD,kCAAkC,aAAa,cAAc,sDAAsD,cAAc,8CAA8C,cAAc,4DAA4D,cAAc,sCAAsC,2CAA2C,2BAA2B,cAAc,sBAAsB,2CAA2C,qBAAqB,cAAc,gEAAgE,cAAc,sBAAsB,2CAA2C,eAAe,cAAc,oBAAoB,cAAc,mDAAmD,cAAc,kGAAkG,6BAA6B,aAAa,cAAc,gGAAgG,2BAA2B,aAAa,cAAc,yCAAyC,oBAAoB,cAAc,kBAAkB,cAAc,oEAAoE,cAAc,4CAA4C,kCAAkC,eAAe,cAAc,2CAA2C,mCAAmC,eAAe,cAAc,2CAA2C,qCAAqC,eAAe,cAAc,qBAAqB,cAAc,iBAAiB,cAAc,cAAc,UAAU,cAAc,EAAE,YAAY,gBAAgB,+BAA+B,SAAS,KAAK,SAAS,IAAI,4FAA4F,cAAc,gDAAgD,cAAc,iDAAiD,cAAc,qLAAqL,uBAAuB,qCAAqC,uBAAuB,yFAAyF,uBAAuB,gKAAgK,SAAS,iGAAiG,OAAO,iBAAiB,eAAe,gIAAgI,cAAc,8CAA8C,gBAAgB,8CAA8C,kBAAkB,iDAAiD,SAAS,EAAE,G;;;;;;ACD92G,g3B;;;;;;ACAA,67B;;;;;;ACAA,8b;;;;;;ACAA;AACA,8BAA6B,yBAAyB,wBAAwB,YAAY,aAAa,2CAA2C,cAAc,kEAAkE,cAAc,YAAY,mCAAmC,cAAc,2CAA2C,cAAc,cAAc,cAAc,cAAc,UAAU,cAAc,EAAE,aAAa,SAAS,IAAI,0GAA0G,gBAAgB,6DAA6D,SAAS,EAAE,G;;;;;;ACDtoB,02G","file":"booking.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"jQuery\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"jQuery\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"TimekitBooking\"] = factory(require(\"jQuery\"));\n\telse\n\t\troot[\"TimekitBooking\"] = factory(root[\"jQuery\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\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\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\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.loaded = 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// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 72428110df9b2182a89e\n **/","'use strict';\n\n/*!\n * Booking.js\n * Version: 1.4.2\n * http://booking.timekit.io\n *\n * Copyright 2015 Timekit, Inc.\n * Timekit Booking.js is freely distributable under the MIT license.\n *\n */\n\n// External depenencies\nvar $ = require('jquery');\nwindow.fullcalendar = require('fullcalendar');\nvar moment = window.moment = require('moment');\nvar timekit = require('timekit-sdk');\n\n// Internal dependencies\nvar utils = require('./utils');\nvar defaultConfig = require('./defaults');\n\n// Main library\nfunction TimekitBooking() {\n\n // Library config\n var config = {};\n\n // DOM nodes\n var rootTarget;\n var calendarTarget;\n var bookingPageTarget;\n\n // Inject style dependencies\n var includeStyles = function() {\n require('../node_modules/fullcalendar/dist/fullcalendar.css');\n require('./styles/fullcalendar.scss');\n require('./styles/utils.scss');\n require('./styles/main.scss');\n };\n\n // Make sure DOM element is ready and clean it\n var prepareDOM = function() {\n\n rootTarget = $(config.targetEl);\n if (rootTarget.length === 0) {\n throw new Error('TimekitBooking - No target DOM element was found (' + config.targetEl + ')');\n }\n rootTarget.addClass('bookingjs');\n rootTarget.children(':not(script)').remove();\n\n };\n\n // Setup the Timekit SDK with correct credentials\n var timekitSetup = function() {\n\n var args = {};\n $.extend(true, args, config.timekitConfig);\n\n timekit.configure(args);\n timekit.setUser(config.email, config.apiToken);\n\n };\n\n // Fetch availabile time through Timekit SDK\n var timekitFindTime = function() {\n\n var args = { emails: [config.email] };\n $.extend(args, config.timekitFindTime);\n\n utils.doCallback('findTimeStarted', config, args);\n\n timekit.findTime(args)\n .then(function(response){\n\n utils.doCallback('findTimeSuccessful', config, response);\n\n // Render available timeslots in FullCalendar\n renderCalendarEvents(response.data);\n\n }).catch(function(response){\n utils.doCallback('findTimeFailed', config, response);\n throw new Error('TimekitBooking - An error with Timekit FindTime occured, context: ' + response);\n });\n\n };\n\n // Calculate and display timezone helper\n var renderTimezoneHelper = function() {\n\n var localTzOffset = (new Date()).getTimezoneOffset()/60*-1;\n var timezoneIcon = require('!svg-inline!./assets/timezone-icon.svg');\n\n var template = require('./templates/timezone-helper.html');\n\n var timezoneHelperTarget = $(template.render({\n timezoneIcon: timezoneIcon,\n loading: true\n }));\n\n rootTarget.append(timezoneHelperTarget);\n\n var args = {\n email: config.email\n };\n\n utils.doCallback('getUserTimezoneStarted', config, args);\n\n timekit.getUserTimezone(args).then(function(response){\n\n utils.doCallback('getUserTimezoneSuccesful', config, response);\n\n var hostTzOffset = response.data.utc_offset;\n var tzOffsetDiff = Math.abs(localTzOffset - hostTzOffset);\n\n var template = require('./templates/timezone-helper.html');\n var newTimezoneHelperTarget = $(template.render({\n timezoneIcon: timezoneIcon,\n timezoneDifference: (tzOffsetDiff === 0 ? false : true),\n timezoneOffset: tzOffsetDiff,\n timezoneDirection: (tzOffsetDiff > 0 ? 'ahead' : 'behind'),\n hostName: config.name\n }));\n\n timezoneHelperTarget.replaceWith(newTimezoneHelperTarget);\n\n }).catch(function(response){\n utils.doCallback('getUserTimezoneFailed', config, response);\n throw new Error('TimekitBooking - An error with Timekit getUserTimezone occured, context: ' + response);\n });\n\n };\n\n // Setup and render FullCalendar\n var initializeCalendar = function() {\n\n var sizing = decideCalendarSize();\n\n var args = {\n defaultView: sizing.view,\n height: sizing.height,\n eventClick: showBookingPage,\n windowResize: function() {\n var sizing = decideCalendarSize();\n calendarTarget.fullCalendar('changeView', sizing.view);\n calendarTarget.fullCalendar('option', 'height', sizing.height);\n }\n };\n\n $.extend(true, args, config.fullCalendar);\n\n calendarTarget = $('
');\n rootTarget.append(calendarTarget);\n\n calendarTarget.fullCalendar(args);\n rootTarget.addClass('show');\n\n utils.doCallback('fullCalendarInitialized', config);\n\n };\n\n // Fires when window is resized and calendar must adhere\n var decideCalendarSize = function() {\n\n var view = 'agendaWeek';\n var height = 470;\n var rootWidth = rootTarget.width();\n\n if (rootWidth < 480) {\n view = 'basicDay';\n height = 346;\n rootTarget.addClass('bookingjs-small');\n } else {\n rootTarget.removeClass('bookingjs-small');\n }\n\n if (config.bookingFields.comment.enabled) { height += 84; }\n if (config.bookingFields.phone.enabled) { height += 48; }\n if (config.bookingFields.voip.enabled) { height += 48; }\n if (config.bookingFields.location.enabled) { height += 48; }\n\n return {\n height: height,\n view: view\n };\n\n };\n\n // Render the supplied calendar events in FullCalendar\n var renderCalendarEvents = function(eventData) {\n\n calendarTarget.fullCalendar('addEventSource', {\n events: eventData\n });\n\n calendarTarget.removeClass('empty-calendar');\n\n };\n\n // Render the avatar image\n var renderAvatarImage = function() {\n\n var template = require('./templates/user-avatar.html');\n var avatarTarget = $(template.render({\n image: config.avatar\n }));\n\n rootTarget.append(avatarTarget);\n\n };\n\n // Render the avatar image\n var renderDisplayName = function() {\n\n var template = require('./templates/user-displayname.html');\n var displayNameTarget = $(template.render({\n name: config.name\n }));\n\n rootTarget.append(displayNameTarget);\n\n };\n\n // Event handler when a timeslot is clicked in FullCalendar\n var showBookingPage = function(eventData) {\n\n utils.doCallback('showBookingPage', config, eventData);\n\n var fieldsTemplate = require('./templates/booking-fields.html');\n var template = require('./templates/booking-page.html');\n\n var dateFormat = config.localization.bookingDateFormat || moment.localeData().longDateFormat('LL');\n var timeFormat = config.localization.bookingTimeFormat || moment.localeData().longDateFormat('LT');\n\n bookingPageTarget = $(template.render({\n chosenDate: moment(eventData.start).format(dateFormat),\n chosenTime: moment(eventData.start).format(timeFormat) + ' - ' + moment(eventData.end).format(timeFormat),\n start: moment(eventData.start).format(),\n end: moment(eventData.end).format(),\n closeIcon: require('!svg-inline!./assets/close-icon.svg'),\n checkmarkIcon: require('!svg-inline!./assets/checkmark-icon.svg'),\n loadingIcon: require('!svg-inline!./assets/loading-spinner.svg'),\n submitText: 'Book it',\n successMessageTitle: 'Thanks!',\n successMessagePart1: 'An invitation has been sent to:',\n successMessagePart2: 'Accept the invitation to confirm the booking.',\n fields: config.bookingFields\n }, {\n formFields: fieldsTemplate\n }));\n\n bookingPageTarget.children('.bookingjs-bookpage-close').click(function(e) {\n e.preventDefault();\n hideBookingPage();\n });\n\n var form = bookingPageTarget.children('.bookingjs-form');\n\n form.submit(function(e) {\n submitBookingForm(this, e);\n });\n\n // Show powered by Timekit message\n if (config.showCredits) {\n renderPoweredByMessage(bookingPageTarget);\n }\n\n $(document).on('keyup', function(e) {\n // escape key maps to keycode `27`\n if (e.keyCode === 27) { hideBookingPage(); }\n });\n\n rootTarget.append(bookingPageTarget);\n\n setTimeout(function(){\n bookingPageTarget.addClass('show');\n }, 100);\n\n };\n\n // Remove the booking page DOM node\n var hideBookingPage = function() {\n\n utils.doCallback('closeBookingPage', config);\n\n bookingPageTarget.removeClass('show');\n\n setTimeout(function(){\n bookingPageTarget.remove();\n }, 200);\n\n $(document).off('keyup');\n\n };\n\n // Event handler on form submit\n var submitBookingForm = function(form, e) {\n\n e.preventDefault();\n\n var formElement = $(form);\n\n // Abort if form is submitting, have submitted or does not validate\n if(formElement.hasClass('loading') || formElement.hasClass('success') || !e.target.checkValidity()) {\n var submitButton = formElement.find('.bookingjs-form-button');\n submitButton.addClass('button-shake');\n setTimeout(function() {\n submitButton.removeClass('button-shake');\n }, 500);\n return;\n }\n\n var values = {};\n $.each(formElement.serializeArray(), function(i, field) {\n values[field.name] = field.value;\n });\n\n formElement.addClass('loading');\n\n utils.doCallback('submitBookingForm', config, values);\n\n // Call create event endpoint\n timekitCreateEvent(values).then(function(response){\n\n utils.doCallback('createEventSuccessful', config, response);\n\n formElement.find('.booked-email').html(values.email);\n formElement.removeClass('loading').addClass('success');\n\n }).catch(function(response){\n utils.doCallback('createEventFailed', config, response);\n throw new Error('TimekitBooking - An error with Timekit createEvent occured, context: ' + response);\n });\n\n };\n\n // Create new event through Timekit SDK\n var timekitCreateEvent = function(data) {\n\n var args = {\n start: data.start,\n end: data.end,\n what: config.name + ' x ' + data.name,\n where: 'TBD',\n description: '',\n calendar_id: config.calendar,\n participants: [config.email, data.email]\n };\n\n if (config.bookingFields.location.enabled) { args.where = data.location; }\n if (config.bookingFields.phone.enabled) { args.description += config.bookingFields.phone.placeholder + ': ' + data.phone + '\\n'; }\n if (config.bookingFields.voip.enabled) { args.description += config.bookingFields.voip.placeholder + ': ' + data.voip + '\\n'; }\n if (config.bookingFields.comment.enabled) { args.description += config.bookingFields.comment.placeholder + ': ' + data.comment + '\\n'; }\n\n $.extend(true, args, config.timekitCreateEvent);\n\n utils.doCallback('createEventStarted', config, args);\n\n return timekit.createEvent(args);\n\n };\n\n // Render the powered by Timekit message\n var renderPoweredByMessage = function(pageTarget) {\n\n var template = require('./templates/poweredby.html');\n var timekitIcon = require('!svg-inline!./assets/timekit-icon.svg');\n var poweredTarget = $(template.render({\n timekitIcon: timekitIcon\n }));\n\n pageTarget.append(poweredTarget);\n\n };\n\n // Set configs and defaults\n var setConfig = function(suppliedConfig) {\n\n // Check whether a config is supplied\n if(suppliedConfig === undefined || typeof suppliedConfig !== 'object' || $.isEmptyObject(suppliedConfig)) {\n if (window.timekitBookingConfig !== undefined) {\n suppliedConfig = window.timekitBookingConfig;\n } else {\n throw new Error('TimekitBooking - No configuration was supplied or found. Please supply a config object upon library initialization');\n }\n }\n\n // Extend the default config with supplied settings\n var newConfig = $.extend(true, {}, defaultConfig.primary, suppliedConfig);\n\n // Apply any presets if applicable (supplied config have presedence over preset)\n var presetsConfig = {};\n if(newConfig.localization.timeDateFormat === '24h-dmy-mon') {\n presetsConfig = defaultConfig.presets.timeDateFormat24hdmymon;\n }\n if(newConfig.localization.timeDateFormat === '12h-mdy-sun') {\n presetsConfig = defaultConfig.presets.timeDateFormat12hmdysun;\n }\n\n // Extend the config with the presets\n var finalConfig = $.extend(true, {}, presetsConfig, newConfig);\n\n // Check for required settings\n if(!finalConfig.email || !finalConfig.apiToken || !finalConfig.calendar) {\n throw new Error('TimekitBooking - A required config setting was missing (\"email\", \"apiToken\" or \"calendar\")');\n }\n\n // Set new config to instance config\n config = finalConfig;\n\n return config;\n\n };\n\n // Get library config\n var getConfig = function() {\n\n return config;\n\n };\n\n // Render method\n var render = function() {\n\n // Set rootTarget to the target element and clean before child nodes before continuing\n prepareDOM();\n\n // Setup Timekit SDK config\n timekitSetup();\n\n // Initialize FullCalendar\n initializeCalendar();\n\n // Get availability through Timekit SDK\n timekitFindTime();\n\n // Show timezone helper if enabled\n if (config.localization.showTimezoneHelper) {\n renderTimezoneHelper();\n }\n\n // Show image avatar if set\n if (config.avatar) {\n renderAvatarImage();\n }\n\n // Print out display name\n if (config.name) {\n renderDisplayName();\n }\n\n utils.doCallback('renderCompleted', config);\n\n return this;\n\n };\n\n // Initilization method\n var init = function(suppliedConfig) {\n\n // Handle config and defaults\n setConfig(suppliedConfig);\n\n // Include library styles if enabled\n if (config.includeStyles) {\n includeStyles();\n }\n\n return render();\n\n };\n\n var destroy = function() {\n\n prepareDOM();\n config = {};\n return this;\n\n };\n\n // The fullCalendar object for advanced puppeting\n var fullCalendar = function() {\n\n if (calendarTarget.fullCalendar === undefined) { return undefined; }\n return calendarTarget.fullCalendar.apply(calendarTarget, arguments);\n\n };\n\n // Expose methods\n return {\n setConfig: setConfig,\n getConfig: getConfig,\n render: render,\n init: init,\n destroy: destroy,\n fullCalendar: fullCalendar\n };\n\n}\n\n// Autoload if config is available on window, else export function\nif (window && window.timekitBookingConfig && window.timekitBookingConfig.autoload !== false) {\n $(window).load(function(){\n var instance = new TimekitBooking();\n instance.init(window.timekitBookingConfig);\n module.exports = instance;\n });\n} else {\n module.exports = TimekitBooking;\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/main.js\n ** module id = 0\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external \"jQuery\"\n ** module id = 1\n ** module chunks = 0\n **/","/*!\n * FullCalendar v2.4.0\n * Docs & License: http://fullcalendar.io/\n * (c) 2015 Adam Shaw\n */\n\n(function(factory) {\n\tif (typeof define === 'function' && define.amd) {\n\t\tdefine([ 'jquery', 'moment' ], factory);\n\t}\n\telse if (typeof exports === 'object') { // Node/CommonJS\n\t\tmodule.exports = factory(require('jquery'), require('moment'));\n\t}\n\telse {\n\t\tfactory(jQuery, moment);\n\t}\n})(function($, moment) {\n\n;;\n\nvar fc = $.fullCalendar = { version: \"2.4.0\" };\nvar fcViews = fc.views = {};\n\n\n$.fn.fullCalendar = function(options) {\n\tvar args = Array.prototype.slice.call(arguments, 1); // for a possible method call\n\tvar res = this; // what this function will return (this jQuery object by default)\n\n\tthis.each(function(i, _element) { // loop each DOM element involved\n\t\tvar element = $(_element);\n\t\tvar calendar = element.data('fullCalendar'); // get the existing calendar object (if any)\n\t\tvar singleRes; // the returned value of this single method call\n\n\t\t// a method call\n\t\tif (typeof options === 'string') {\n\t\t\tif (calendar && $.isFunction(calendar[options])) {\n\t\t\t\tsingleRes = calendar[options].apply(calendar, args);\n\t\t\t\tif (!i) {\n\t\t\t\t\tres = singleRes; // record the first method call result\n\t\t\t\t}\n\t\t\t\tif (options === 'destroy') { // for the destroy method, must remove Calendar object data\n\t\t\t\t\telement.removeData('fullCalendar');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// a new calendar initialization\n\t\telse if (!calendar) { // don't initialize twice\n\t\t\tcalendar = new Calendar(element, options);\n\t\t\telement.data('fullCalendar', calendar);\n\t\t\tcalendar.render();\n\t\t}\n\t});\n\t\n\treturn res;\n};\n\n\nvar complexOptions = [ // names of options that are objects whose properties should be combined\n\t'header',\n\t'buttonText',\n\t'buttonIcons',\n\t'themeButtonIcons'\n];\n\n\n// Merges an array of option objects into a single object\nfunction mergeOptions(optionObjs) {\n\treturn mergeProps(optionObjs, complexOptions);\n}\n\n\n// Given options specified for the calendar's constructor, massages any legacy options into a non-legacy form.\n// Converts View-Option-Hashes into the View-Specific-Options format.\nfunction massageOverrides(input) {\n\tvar overrides = { views: input.views || {} }; // the output. ensure a `views` hash\n\tvar subObj;\n\n\t// iterate through all option override properties (except `views`)\n\t$.each(input, function(name, val) {\n\t\tif (name != 'views') {\n\n\t\t\t// could the value be a legacy View-Option-Hash?\n\t\t\tif (\n\t\t\t\t$.isPlainObject(val) &&\n\t\t\t\t!/(time|duration|interval)$/i.test(name) && // exclude duration options. might be given as objects\n\t\t\t\t$.inArray(name, complexOptions) == -1 // complex options aren't allowed to be View-Option-Hashes\n\t\t\t) {\n\t\t\t\tsubObj = null;\n\n\t\t\t\t// iterate through the properties of this possible View-Option-Hash value\n\t\t\t\t$.each(val, function(subName, subVal) {\n\n\t\t\t\t\t// is the property targeting a view?\n\t\t\t\t\tif (/^(month|week|day|default|basic(Week|Day)?|agenda(Week|Day)?)$/.test(subName)) {\n\t\t\t\t\t\tif (!overrides.views[subName]) { // ensure the view-target entry exists\n\t\t\t\t\t\t\toverrides.views[subName] = {};\n\t\t\t\t\t\t}\n\t\t\t\t\t\toverrides.views[subName][name] = subVal; // record the value in the `views` object\n\t\t\t\t\t}\n\t\t\t\t\telse { // a non-View-Option-Hash property\n\t\t\t\t\t\tif (!subObj) {\n\t\t\t\t\t\t\tsubObj = {};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsubObj[subName] = subVal; // accumulate these unrelated values for later\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif (subObj) { // non-View-Option-Hash properties? transfer them as-is\n\t\t\t\t\toverrides[name] = subObj;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\toverrides[name] = val; // transfer normal options as-is\n\t\t\t}\n\t\t}\n\t});\n\n\treturn overrides;\n}\n\n;;\n\n// exports\nfc.intersectionToSeg = intersectionToSeg;\nfc.applyAll = applyAll;\nfc.debounce = debounce;\nfc.isInt = isInt;\nfc.htmlEscape = htmlEscape;\nfc.cssToStr = cssToStr;\nfc.proxy = proxy;\nfc.capitaliseFirstLetter = capitaliseFirstLetter;\n\n\n/* FullCalendar-specific DOM Utilities\n----------------------------------------------------------------------------------------------------------------------*/\n\n\n// Given the scrollbar widths of some other container, create borders/margins on rowEls in order to match the left\n// and right space that was offset by the scrollbars. A 1-pixel border first, then margin beyond that.\nfunction compensateScroll(rowEls, scrollbarWidths) {\n\tif (scrollbarWidths.left) {\n\t\trowEls.css({\n\t\t\t'border-left-width': 1,\n\t\t\t'margin-left': scrollbarWidths.left - 1\n\t\t});\n\t}\n\tif (scrollbarWidths.right) {\n\t\trowEls.css({\n\t\t\t'border-right-width': 1,\n\t\t\t'margin-right': scrollbarWidths.right - 1\n\t\t});\n\t}\n}\n\n\n// Undoes compensateScroll and restores all borders/margins\nfunction uncompensateScroll(rowEls) {\n\trowEls.css({\n\t\t'margin-left': '',\n\t\t'margin-right': '',\n\t\t'border-left-width': '',\n\t\t'border-right-width': ''\n\t});\n}\n\n\n// Make the mouse cursor express that an event is not allowed in the current area\nfunction disableCursor() {\n\t$('body').addClass('fc-not-allowed');\n}\n\n\n// Returns the mouse cursor to its original look\nfunction enableCursor() {\n\t$('body').removeClass('fc-not-allowed');\n}\n\n\n// Given a total available height to fill, have `els` (essentially child rows) expand to accomodate.\n// By default, all elements that are shorter than the recommended height are expanded uniformly, not considering\n// any other els that are already too tall. if `shouldRedistribute` is on, it considers these tall rows and \n// reduces the available height.\nfunction distributeHeight(els, availableHeight, shouldRedistribute) {\n\n\t// *FLOORING NOTE*: we floor in certain places because zoom can give inaccurate floating-point dimensions,\n\t// and it is better to be shorter than taller, to avoid creating unnecessary scrollbars.\n\n\tvar minOffset1 = Math.floor(availableHeight / els.length); // for non-last element\n\tvar minOffset2 = Math.floor(availableHeight - minOffset1 * (els.length - 1)); // for last element *FLOORING NOTE*\n\tvar flexEls = []; // elements that are allowed to expand. array of DOM nodes\n\tvar flexOffsets = []; // amount of vertical space it takes up\n\tvar flexHeights = []; // actual css height\n\tvar usedHeight = 0;\n\n\tundistributeHeight(els); // give all elements their natural height\n\n\t// find elements that are below the recommended height (expandable).\n\t// important to query for heights in a single first pass (to avoid reflow oscillation).\n\tels.each(function(i, el) {\n\t\tvar minOffset = i === els.length - 1 ? minOffset2 : minOffset1;\n\t\tvar naturalOffset = $(el).outerHeight(true);\n\n\t\tif (naturalOffset < minOffset) {\n\t\t\tflexEls.push(el);\n\t\t\tflexOffsets.push(naturalOffset);\n\t\t\tflexHeights.push($(el).height());\n\t\t}\n\t\telse {\n\t\t\t// this element stretches past recommended height (non-expandable). mark the space as occupied.\n\t\t\tusedHeight += naturalOffset;\n\t\t}\n\t});\n\n\t// readjust the recommended height to only consider the height available to non-maxed-out rows.\n\tif (shouldRedistribute) {\n\t\tavailableHeight -= usedHeight;\n\t\tminOffset1 = Math.floor(availableHeight / flexEls.length);\n\t\tminOffset2 = Math.floor(availableHeight - minOffset1 * (flexEls.length - 1)); // *FLOORING NOTE*\n\t}\n\n\t// assign heights to all expandable elements\n\t$(flexEls).each(function(i, el) {\n\t\tvar minOffset = i === flexEls.length - 1 ? minOffset2 : minOffset1;\n\t\tvar naturalOffset = flexOffsets[i];\n\t\tvar naturalHeight = flexHeights[i];\n\t\tvar newHeight = minOffset - (naturalOffset - naturalHeight); // subtract the margin/padding\n\n\t\tif (naturalOffset < minOffset) { // we check this again because redistribution might have changed things\n\t\t\t$(el).height(newHeight);\n\t\t}\n\t});\n}\n\n\n// Undoes distrubuteHeight, restoring all els to their natural height\nfunction undistributeHeight(els) {\n\tels.height('');\n}\n\n\n// Given `els`, a jQuery set of cells, find the cell with the largest natural width and set the widths of all the\n// cells to be that width.\n// PREREQUISITE: if you want a cell to take up width, it needs to have a single inner element w/ display:inline\nfunction matchCellWidths(els) {\n\tvar maxInnerWidth = 0;\n\n\tels.find('> *').each(function(i, innerEl) {\n\t\tvar innerWidth = $(innerEl).outerWidth();\n\t\tif (innerWidth > maxInnerWidth) {\n\t\t\tmaxInnerWidth = innerWidth;\n\t\t}\n\t});\n\n\tmaxInnerWidth++; // sometimes not accurate of width the text needs to stay on one line. insurance\n\n\tels.width(maxInnerWidth);\n\n\treturn maxInnerWidth;\n}\n\n\n// Turns a container element into a scroller if its contents is taller than the allotted height.\n// Returns true if the element is now a scroller, false otherwise.\n// NOTE: this method is best because it takes weird zooming dimensions into account\nfunction setPotentialScroller(containerEl, height) {\n\tcontainerEl.height(height).addClass('fc-scroller');\n\n\t// are scrollbars needed?\n\tif (containerEl[0].scrollHeight - 1 > containerEl[0].clientHeight) { // !!! -1 because IE is often off-by-one :(\n\t\treturn true;\n\t}\n\n\tunsetScroller(containerEl); // undo\n\treturn false;\n}\n\n\n// Takes an element that might have been a scroller, and turns it back into a normal element.\nfunction unsetScroller(containerEl) {\n\tcontainerEl.height('').removeClass('fc-scroller');\n}\n\n\n/* General DOM Utilities\n----------------------------------------------------------------------------------------------------------------------*/\n\nfc.getClientRect = getClientRect;\nfc.getContentRect = getContentRect;\nfc.getScrollbarWidths = getScrollbarWidths;\n\n\n// borrowed from https://github.com/jquery/jquery-ui/blob/1.11.0/ui/core.js#L51\nfunction getScrollParent(el) {\n\tvar position = el.css('position'),\n\t\tscrollParent = el.parents().filter(function() {\n\t\t\tvar parent = $(this);\n\t\t\treturn (/(auto|scroll)/).test(\n\t\t\t\tparent.css('overflow') + parent.css('overflow-y') + parent.css('overflow-x')\n\t\t\t);\n\t\t}).eq(0);\n\n\treturn position === 'fixed' || !scrollParent.length ? $(el[0].ownerDocument || document) : scrollParent;\n}\n\n\n// Queries the outer bounding area of a jQuery element.\n// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).\nfunction getOuterRect(el) {\n\tvar offset = el.offset();\n\n\treturn {\n\t\tleft: offset.left,\n\t\tright: offset.left + el.outerWidth(),\n\t\ttop: offset.top,\n\t\tbottom: offset.top + el.outerHeight()\n\t};\n}\n\n\n// Queries the area within the margin/border/scrollbars of a jQuery element. Does not go within the padding.\n// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).\n// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser.\nfunction getClientRect(el) {\n\tvar offset = el.offset();\n\tvar scrollbarWidths = getScrollbarWidths(el);\n\tvar left = offset.left + getCssFloat(el, 'border-left-width') + scrollbarWidths.left;\n\tvar top = offset.top + getCssFloat(el, 'border-top-width') + scrollbarWidths.top;\n\n\treturn {\n\t\tleft: left,\n\t\tright: left + el[0].clientWidth, // clientWidth includes padding but NOT scrollbars\n\t\ttop: top,\n\t\tbottom: top + el[0].clientHeight // clientHeight includes padding but NOT scrollbars\n\t};\n}\n\n\n// Queries the area within the margin/border/padding of a jQuery element. Assumed not to have scrollbars.\n// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).\nfunction getContentRect(el) {\n\tvar offset = el.offset(); // just outside of border, margin not included\n\tvar left = offset.left + getCssFloat(el, 'border-left-width') + getCssFloat(el, 'padding-left');\n\tvar top = offset.top + getCssFloat(el, 'border-top-width') + getCssFloat(el, 'padding-top');\n\n\treturn {\n\t\tleft: left,\n\t\tright: left + el.width(),\n\t\ttop: top,\n\t\tbottom: top + el.height()\n\t};\n}\n\n\n// Returns the computed left/right/top/bottom scrollbar widths for the given jQuery element.\n// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser.\nfunction getScrollbarWidths(el) {\n\tvar leftRightWidth = el.innerWidth() - el[0].clientWidth; // the paddings cancel out, leaving the scrollbars\n\tvar widths = {\n\t\tleft: 0,\n\t\tright: 0,\n\t\ttop: 0,\n\t\tbottom: el.innerHeight() - el[0].clientHeight // the paddings cancel out, leaving the bottom scrollbar\n\t};\n\n\tif (getIsLeftRtlScrollbars() && el.css('direction') == 'rtl') { // is the scrollbar on the left side?\n\t\twidths.left = leftRightWidth;\n\t}\n\telse {\n\t\twidths.right = leftRightWidth;\n\t}\n\n\treturn widths;\n}\n\n\n// Logic for determining if, when the element is right-to-left, the scrollbar appears on the left side\n\nvar _isLeftRtlScrollbars = null;\n\nfunction getIsLeftRtlScrollbars() { // responsible for caching the computation\n\tif (_isLeftRtlScrollbars === null) {\n\t\t_isLeftRtlScrollbars = computeIsLeftRtlScrollbars();\n\t}\n\treturn _isLeftRtlScrollbars;\n}\n\nfunction computeIsLeftRtlScrollbars() { // creates an offscreen test element, then removes it\n\tvar el = $('
')\n\t\t.css({\n\t\t\tposition: 'absolute',\n\t\t\ttop: -1000,\n\t\t\tleft: 0,\n\t\t\tborder: 0,\n\t\t\tpadding: 0,\n\t\t\toverflow: 'scroll',\n\t\t\tdirection: 'rtl'\n\t\t})\n\t\t.appendTo('body');\n\tvar innerEl = el.children();\n\tvar res = innerEl.offset().left > el.offset().left; // is the inner div shifted to accommodate a left scrollbar?\n\tel.remove();\n\treturn res;\n}\n\n\n// Retrieves a jQuery element's computed CSS value as a floating-point number.\n// If the queried value is non-numeric (ex: IE can return \"medium\" for border width), will just return zero.\nfunction getCssFloat(el, prop) {\n\treturn parseFloat(el.css(prop)) || 0;\n}\n\n\n// Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)\nfunction isPrimaryMouseButton(ev) {\n\treturn ev.which == 1 && !ev.ctrlKey;\n}\n\n\n/* Geometry\n----------------------------------------------------------------------------------------------------------------------*/\n\nfc.intersectRects = intersectRects;\n\n// Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false\nfunction intersectRects(rect1, rect2) {\n\tvar res = {\n\t\tleft: Math.max(rect1.left, rect2.left),\n\t\tright: Math.min(rect1.right, rect2.right),\n\t\ttop: Math.max(rect1.top, rect2.top),\n\t\tbottom: Math.min(rect1.bottom, rect2.bottom)\n\t};\n\n\tif (res.left < res.right && res.top < res.bottom) {\n\t\treturn res;\n\t}\n\treturn false;\n}\n\n\n// Returns a new point that will have been moved to reside within the given rectangle\nfunction constrainPoint(point, rect) {\n\treturn {\n\t\tleft: Math.min(Math.max(point.left, rect.left), rect.right),\n\t\ttop: Math.min(Math.max(point.top, rect.top), rect.bottom)\n\t};\n}\n\n\n// Returns a point that is the center of the given rectangle\nfunction getRectCenter(rect) {\n\treturn {\n\t\tleft: (rect.left + rect.right) / 2,\n\t\ttop: (rect.top + rect.bottom) / 2\n\t};\n}\n\n\n// Subtracts point2's coordinates from point1's coordinates, returning a delta\nfunction diffPoints(point1, point2) {\n\treturn {\n\t\tleft: point1.left - point2.left,\n\t\ttop: point1.top - point2.top\n\t};\n}\n\n\n/* Object Ordering by Field\n----------------------------------------------------------------------------------------------------------------------*/\n\nfc.parseFieldSpecs = parseFieldSpecs;\nfc.compareByFieldSpecs = compareByFieldSpecs;\nfc.compareByFieldSpec = compareByFieldSpec;\nfc.flexibleCompare = flexibleCompare;\n\n\nfunction parseFieldSpecs(input) {\n\tvar specs = [];\n\tvar tokens = [];\n\tvar i, token;\n\n\tif (typeof input === 'string') {\n\t\ttokens = input.split(/\\s*,\\s*/);\n\t}\n\telse if (typeof input === 'function') {\n\t\ttokens = [ input ];\n\t}\n\telse if ($.isArray(input)) {\n\t\ttokens = input;\n\t}\n\n\tfor (i = 0; i < tokens.length; i++) {\n\t\ttoken = tokens[i];\n\n\t\tif (typeof token === 'string') {\n\t\t\tspecs.push(\n\t\t\t\ttoken.charAt(0) == '-' ?\n\t\t\t\t\t{ field: token.substring(1), order: -1 } :\n\t\t\t\t\t{ field: token, order: 1 }\n\t\t\t);\n\t\t}\n\t\telse if (typeof token === 'function') {\n\t\t\tspecs.push({ func: token });\n\t\t}\n\t}\n\n\treturn specs;\n}\n\n\nfunction compareByFieldSpecs(obj1, obj2, fieldSpecs) {\n\tvar i;\n\tvar cmp;\n\n\tfor (i = 0; i < fieldSpecs.length; i++) {\n\t\tcmp = compareByFieldSpec(obj1, obj2, fieldSpecs[i]);\n\t\tif (cmp) {\n\t\t\treturn cmp;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n\nfunction compareByFieldSpec(obj1, obj2, fieldSpec) {\n\tif (fieldSpec.func) {\n\t\treturn fieldSpec.func(obj1, obj2);\n\t}\n\treturn flexibleCompare(obj1[fieldSpec.field], obj2[fieldSpec.field]) *\n\t\t(fieldSpec.order || 1);\n}\n\n\nfunction flexibleCompare(a, b) {\n\tif (!a && !b) {\n\t\treturn 0;\n\t}\n\tif (b == null) {\n\t\treturn -1;\n\t}\n\tif (a == null) {\n\t\treturn 1;\n\t}\n\tif ($.type(a) === 'string' || $.type(b) === 'string') {\n\t\treturn String(a).localeCompare(String(b));\n\t}\n\treturn a - b;\n}\n\n\n/* FullCalendar-specific Misc Utilities\n----------------------------------------------------------------------------------------------------------------------*/\n\n\n// Creates a basic segment with the intersection of the two ranges. Returns undefined if no intersection.\n// Expects all dates to be normalized to the same timezone beforehand.\n// TODO: move to date section?\nfunction intersectionToSeg(subjectRange, constraintRange) {\n\tvar subjectStart = subjectRange.start;\n\tvar subjectEnd = subjectRange.end;\n\tvar constraintStart = constraintRange.start;\n\tvar constraintEnd = constraintRange.end;\n\tvar segStart, segEnd;\n\tvar isStart, isEnd;\n\n\tif (subjectEnd > constraintStart && subjectStart < constraintEnd) { // in bounds at all?\n\n\t\tif (subjectStart >= constraintStart) {\n\t\t\tsegStart = subjectStart.clone();\n\t\t\tisStart = true;\n\t\t}\n\t\telse {\n\t\t\tsegStart = constraintStart.clone();\n\t\t\tisStart = false;\n\t\t}\n\n\t\tif (subjectEnd <= constraintEnd) {\n\t\t\tsegEnd = subjectEnd.clone();\n\t\t\tisEnd = true;\n\t\t}\n\t\telse {\n\t\t\tsegEnd = constraintEnd.clone();\n\t\t\tisEnd = false;\n\t\t}\n\n\t\treturn {\n\t\t\tstart: segStart,\n\t\t\tend: segEnd,\n\t\t\tisStart: isStart,\n\t\t\tisEnd: isEnd\n\t\t};\n\t}\n}\n\n\n/* Date Utilities\n----------------------------------------------------------------------------------------------------------------------*/\n\nfc.computeIntervalUnit = computeIntervalUnit;\nfc.divideRangeByDuration = divideRangeByDuration;\nfc.divideDurationByDuration = divideDurationByDuration;\nfc.multiplyDuration = multiplyDuration;\nfc.durationHasTime = durationHasTime;\n\nvar dayIDs = [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ];\nvar intervalUnits = [ 'year', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond' ];\n\n\n// Diffs the two moments into a Duration where full-days are recorded first, then the remaining time.\n// Moments will have their timezones normalized.\nfunction diffDayTime(a, b) {\n\treturn moment.duration({\n\t\tdays: a.clone().stripTime().diff(b.clone().stripTime(), 'days'),\n\t\tms: a.time() - b.time() // time-of-day from day start. disregards timezone\n\t});\n}\n\n\n// Diffs the two moments via their start-of-day (regardless of timezone). Produces whole-day durations.\nfunction diffDay(a, b) {\n\treturn moment.duration({\n\t\tdays: a.clone().stripTime().diff(b.clone().stripTime(), 'days')\n\t});\n}\n\n\n// Diffs two moments, producing a duration, made of a whole-unit-increment of the given unit. Uses rounding.\nfunction diffByUnit(a, b, unit) {\n\treturn moment.duration(\n\t\tMath.round(a.diff(b, unit, true)), // returnFloat=true\n\t\tunit\n\t);\n}\n\n\n// Computes the unit name of the largest whole-unit period of time.\n// For example, 48 hours will be \"days\" whereas 49 hours will be \"hours\".\n// Accepts start/end, a range object, or an original duration object.\nfunction computeIntervalUnit(start, end) {\n\tvar i, unit;\n\tvar val;\n\n\tfor (i = 0; i < intervalUnits.length; i++) {\n\t\tunit = intervalUnits[i];\n\t\tval = computeRangeAs(unit, start, end);\n\n\t\tif (val >= 1 && isInt(val)) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn unit; // will be \"milliseconds\" if nothing else matches\n}\n\n\n// Computes the number of units (like \"hours\") in the given range.\n// Range can be a {start,end} object, separate start/end args, or a Duration.\n// Results are based on Moment's .as() and .diff() methods, so results can depend on internal handling\n// of month-diffing logic (which tends to vary from version to version).\nfunction computeRangeAs(unit, start, end) {\n\n\tif (end != null) { // given start, end\n\t\treturn end.diff(start, unit, true);\n\t}\n\telse if (moment.isDuration(start)) { // given duration\n\t\treturn start.as(unit);\n\t}\n\telse { // given { start, end } range object\n\t\treturn start.end.diff(start.start, unit, true);\n\t}\n}\n\n\n// Intelligently divides a range (specified by a start/end params) by a duration\nfunction divideRangeByDuration(start, end, dur) {\n\tvar months;\n\n\tif (durationHasTime(dur)) {\n\t\treturn (end - start) / dur;\n\t}\n\tmonths = dur.asMonths();\n\tif (Math.abs(months) >= 1 && isInt(months)) {\n\t\treturn end.diff(start, 'months', true) / months;\n\t}\n\treturn end.diff(start, 'days', true) / dur.asDays();\n}\n\n\n// Intelligently divides one duration by another\nfunction divideDurationByDuration(dur1, dur2) {\n\tvar months1, months2;\n\n\tif (durationHasTime(dur1) || durationHasTime(dur2)) {\n\t\treturn dur1 / dur2;\n\t}\n\tmonths1 = dur1.asMonths();\n\tmonths2 = dur2.asMonths();\n\tif (\n\t\tMath.abs(months1) >= 1 && isInt(months1) &&\n\t\tMath.abs(months2) >= 1 && isInt(months2)\n\t) {\n\t\treturn months1 / months2;\n\t}\n\treturn dur1.asDays() / dur2.asDays();\n}\n\n\n// Intelligently multiplies a duration by a number\nfunction multiplyDuration(dur, n) {\n\tvar months;\n\n\tif (durationHasTime(dur)) {\n\t\treturn moment.duration(dur * n);\n\t}\n\tmonths = dur.asMonths();\n\tif (Math.abs(months) >= 1 && isInt(months)) {\n\t\treturn moment.duration({ months: months * n });\n\t}\n\treturn moment.duration({ days: dur.asDays() * n });\n}\n\n\n// Returns a boolean about whether the given duration has any time parts (hours/minutes/seconds/ms)\nfunction durationHasTime(dur) {\n\treturn Boolean(dur.hours() || dur.minutes() || dur.seconds() || dur.milliseconds());\n}\n\n\nfunction isNativeDate(input) {\n\treturn Object.prototype.toString.call(input) === '[object Date]' || input instanceof Date;\n}\n\n\n// Returns a boolean about whether the given input is a time string, like \"06:40:00\" or \"06:00\"\nfunction isTimeString(str) {\n\treturn /^\\d+\\:\\d+(?:\\:\\d+\\.?(?:\\d{3})?)?$/.test(str);\n}\n\n\n/* Logging and Debug\n----------------------------------------------------------------------------------------------------------------------*/\n\nfc.log = function() {\n\tvar console = window.console;\n\n\tif (console && console.log) {\n\t\treturn console.log.apply(console, arguments);\n\t}\n};\n\nfc.warn = function() {\n\tvar console = window.console;\n\n\tif (console && console.warn) {\n\t\treturn console.warn.apply(console, arguments);\n\t}\n\telse {\n\t\treturn fc.log.apply(fc, arguments);\n\t}\n};\n\n\n/* General Utilities\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar hasOwnPropMethod = {}.hasOwnProperty;\n\n\n// Merges an array of objects into a single object.\n// The second argument allows for an array of property names who's object values will be merged together.\nfunction mergeProps(propObjs, complexProps) {\n\tvar dest = {};\n\tvar i, name;\n\tvar complexObjs;\n\tvar j, val;\n\tvar props;\n\n\tif (complexProps) {\n\t\tfor (i = 0; i < complexProps.length; i++) {\n\t\t\tname = complexProps[i];\n\t\t\tcomplexObjs = [];\n\n\t\t\t// collect the trailing object values, stopping when a non-object is discovered\n\t\t\tfor (j = propObjs.length - 1; j >= 0; j--) {\n\t\t\t\tval = propObjs[j][name];\n\n\t\t\t\tif (typeof val === 'object') {\n\t\t\t\t\tcomplexObjs.unshift(val);\n\t\t\t\t}\n\t\t\t\telse if (val !== undefined) {\n\t\t\t\t\tdest[name] = val; // if there were no objects, this value will be used\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// if the trailing values were objects, use the merged value\n\t\t\tif (complexObjs.length) {\n\t\t\t\tdest[name] = mergeProps(complexObjs);\n\t\t\t}\n\t\t}\n\t}\n\n\t// copy values into the destination, going from last to first\n\tfor (i = propObjs.length - 1; i >= 0; i--) {\n\t\tprops = propObjs[i];\n\n\t\tfor (name in props) {\n\t\t\tif (!(name in dest)) { // if already assigned by previous props or complex props, don't reassign\n\t\t\t\tdest[name] = props[name];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn dest;\n}\n\n\n// Create an object that has the given prototype. Just like Object.create\nfunction createObject(proto) {\n\tvar f = function() {};\n\tf.prototype = proto;\n\treturn new f();\n}\n\n\nfunction copyOwnProps(src, dest) {\n\tfor (var name in src) {\n\t\tif (hasOwnProp(src, name)) {\n\t\t\tdest[name] = src[name];\n\t\t}\n\t}\n}\n\n\n// Copies over certain methods with the same names as Object.prototype methods. Overcomes an IE<=8 bug:\n// https://developer.mozilla.org/en-US/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug\nfunction copyNativeMethods(src, dest) {\n\tvar names = [ 'constructor', 'toString', 'valueOf' ];\n\tvar i, name;\n\n\tfor (i = 0; i < names.length; i++) {\n\t\tname = names[i];\n\n\t\tif (src[name] !== Object.prototype[name]) {\n\t\t\tdest[name] = src[name];\n\t\t}\n\t}\n}\n\n\nfunction hasOwnProp(obj, name) {\n\treturn hasOwnPropMethod.call(obj, name);\n}\n\n\n// Is the given value a non-object non-function value?\nfunction isAtomic(val) {\n\treturn /undefined|null|boolean|number|string/.test($.type(val));\n}\n\n\nfunction applyAll(functions, thisObj, args) {\n\tif ($.isFunction(functions)) {\n\t\tfunctions = [ functions ];\n\t}\n\tif (functions) {\n\t\tvar i;\n\t\tvar ret;\n\t\tfor (i=0; i/g, '>')\n\t\t.replace(/'/g, ''')\n\t\t.replace(/\"/g, '"')\n\t\t.replace(/\\n/g, '
');\n}\n\n\nfunction stripHtmlEntities(text) {\n\treturn text.replace(/&.*?;/g, '');\n}\n\n\n// Given a hash of CSS properties, returns a string of CSS.\n// Uses property names as-is (no camel-case conversion). Will not make statements for null/undefined values.\nfunction cssToStr(cssProps) {\n\tvar statements = [];\n\n\t$.each(cssProps, function(name, val) {\n\t\tif (val != null) {\n\t\t\tstatements.push(name + ':' + val);\n\t\t}\n\t});\n\n\treturn statements.join(';');\n}\n\n\nfunction capitaliseFirstLetter(str) {\n\treturn str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n\nfunction compareNumbers(a, b) { // for .sort()\n\treturn a - b;\n}\n\n\nfunction isInt(n) {\n\treturn n % 1 === 0;\n}\n\n\n// Returns a method bound to the given object context.\n// Just like one of the jQuery.proxy signatures, but without the undesired behavior of treating the same method with\n// different contexts as identical when binding/unbinding events.\nfunction proxy(obj, methodName) {\n\tvar method = obj[methodName];\n\n\treturn function() {\n\t\treturn method.apply(obj, arguments);\n\t};\n}\n\n\n// Returns a function, that, as long as it continues to be invoked, will not\n// be triggered. The function will be called after it stops being called for\n// N milliseconds.\n// https://github.com/jashkenas/underscore/blob/1.6.0/underscore.js#L714\nfunction debounce(func, wait) {\n\tvar timeoutId;\n\tvar args;\n\tvar context;\n\tvar timestamp; // of most recent call\n\tvar later = function() {\n\t\tvar last = +new Date() - timestamp;\n\t\tif (last < wait && last > 0) {\n\t\t\ttimeoutId = setTimeout(later, wait - last);\n\t\t}\n\t\telse {\n\t\t\ttimeoutId = null;\n\t\t\tfunc.apply(context, args);\n\t\t\tif (!timeoutId) {\n\t\t\t\tcontext = args = null;\n\t\t\t}\n\t\t}\n\t};\n\n\treturn function() {\n\t\tcontext = this;\n\t\targs = arguments;\n\t\ttimestamp = +new Date();\n\t\tif (!timeoutId) {\n\t\t\ttimeoutId = setTimeout(later, wait);\n\t\t}\n\t};\n}\n\n;;\n\nvar ambigDateOfMonthRegex = /^\\s*\\d{4}-\\d\\d$/;\nvar ambigTimeOrZoneRegex =\n\t/^\\s*\\d{4}-(?:(\\d\\d-\\d\\d)|(W\\d\\d$)|(W\\d\\d-\\d)|(\\d\\d\\d))((T| )(\\d\\d(:\\d\\d(:\\d\\d(\\.\\d+)?)?)?)?)?$/;\nvar newMomentProto = moment.fn; // where we will attach our new methods\nvar oldMomentProto = $.extend({}, newMomentProto); // copy of original moment methods\nvar allowValueOptimization;\nvar setUTCValues; // function defined below\nvar setLocalValues; // function defined below\n\n\n// Creating\n// -------------------------------------------------------------------------------------------------\n\n// Creates a new moment, similar to the vanilla moment(...) constructor, but with\n// extra features (ambiguous time, enhanced formatting). When given an existing moment,\n// it will function as a clone (and retain the zone of the moment). Anything else will\n// result in a moment in the local zone.\nfc.moment = function() {\n\treturn makeMoment(arguments);\n};\n\n// Sames as fc.moment, but forces the resulting moment to be in the UTC timezone.\nfc.moment.utc = function() {\n\tvar mom = makeMoment(arguments, true);\n\n\t// Force it into UTC because makeMoment doesn't guarantee it\n\t// (if given a pre-existing moment for example)\n\tif (mom.hasTime()) { // don't give ambiguously-timed moments a UTC zone\n\t\tmom.utc();\n\t}\n\n\treturn mom;\n};\n\n// Same as fc.moment, but when given an ISO8601 string, the timezone offset is preserved.\n// ISO8601 strings with no timezone offset will become ambiguously zoned.\nfc.moment.parseZone = function() {\n\treturn makeMoment(arguments, true, true);\n};\n\n// Builds an enhanced moment from args. When given an existing moment, it clones. When given a\n// native Date, or called with no arguments (the current time), the resulting moment will be local.\n// Anything else needs to be \"parsed\" (a string or an array), and will be affected by:\n// parseAsUTC - if there is no zone information, should we parse the input in UTC?\n// parseZone - if there is zone information, should we force the zone of the moment?\nfunction makeMoment(args, parseAsUTC, parseZone) {\n\tvar input = args[0];\n\tvar isSingleString = args.length == 1 && typeof input === 'string';\n\tvar isAmbigTime;\n\tvar isAmbigZone;\n\tvar ambigMatch;\n\tvar mom;\n\n\tif (moment.isMoment(input)) {\n\t\tmom = moment.apply(null, args); // clone it\n\t\ttransferAmbigs(input, mom); // the ambig flags weren't transfered with the clone\n\t}\n\telse if (isNativeDate(input) || input === undefined) {\n\t\tmom = moment.apply(null, args); // will be local\n\t}\n\telse { // \"parsing\" is required\n\t\tisAmbigTime = false;\n\t\tisAmbigZone = false;\n\n\t\tif (isSingleString) {\n\t\t\tif (ambigDateOfMonthRegex.test(input)) {\n\t\t\t\t// accept strings like '2014-05', but convert to the first of the month\n\t\t\t\tinput += '-01';\n\t\t\t\targs = [ input ]; // for when we pass it on to moment's constructor\n\t\t\t\tisAmbigTime = true;\n\t\t\t\tisAmbigZone = true;\n\t\t\t}\n\t\t\telse if ((ambigMatch = ambigTimeOrZoneRegex.exec(input))) {\n\t\t\t\tisAmbigTime = !ambigMatch[5]; // no time part?\n\t\t\t\tisAmbigZone = true;\n\t\t\t}\n\t\t}\n\t\telse if ($.isArray(input)) {\n\t\t\t// arrays have no timezone information, so assume ambiguous zone\n\t\t\tisAmbigZone = true;\n\t\t}\n\t\t// otherwise, probably a string with a format\n\n\t\tif (parseAsUTC || isAmbigTime) {\n\t\t\tmom = moment.utc.apply(moment, args);\n\t\t}\n\t\telse {\n\t\t\tmom = moment.apply(null, args);\n\t\t}\n\n\t\tif (isAmbigTime) {\n\t\t\tmom._ambigTime = true;\n\t\t\tmom._ambigZone = true; // ambiguous time always means ambiguous zone\n\t\t}\n\t\telse if (parseZone) { // let's record the inputted zone somehow\n\t\t\tif (isAmbigZone) {\n\t\t\t\tmom._ambigZone = true;\n\t\t\t}\n\t\t\telse if (isSingleString) {\n\t\t\t\tif (mom.utcOffset) {\n\t\t\t\t\tmom.utcOffset(input); // if not a valid zone, will assign UTC\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tmom.zone(input); // for moment-pre-2.9\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tmom._fullCalendar = true; // flag for extended functionality\n\n\treturn mom;\n}\n\n\n// A clone method that works with the flags related to our enhanced functionality.\n// In the future, use moment.momentProperties\nnewMomentProto.clone = function() {\n\tvar mom = oldMomentProto.clone.apply(this, arguments);\n\n\t// these flags weren't transfered with the clone\n\ttransferAmbigs(this, mom);\n\tif (this._fullCalendar) {\n\t\tmom._fullCalendar = true;\n\t}\n\n\treturn mom;\n};\n\n\n// Week Number\n// -------------------------------------------------------------------------------------------------\n\n\n// Returns the week number, considering the locale's custom week number calcuation\n// `weeks` is an alias for `week`\nnewMomentProto.week = newMomentProto.weeks = function(input) {\n\tvar weekCalc = (this._locale || this._lang) // works pre-moment-2.8\n\t\t._fullCalendar_weekCalc;\n\n\tif (input == null && typeof weekCalc === 'function') { // custom function only works for getter\n\t\treturn weekCalc(this);\n\t}\n\telse if (weekCalc === 'ISO') {\n\t\treturn oldMomentProto.isoWeek.apply(this, arguments); // ISO getter/setter\n\t}\n\n\treturn oldMomentProto.week.apply(this, arguments); // local getter/setter\n};\n\n\n// Time-of-day\n// -------------------------------------------------------------------------------------------------\n\n// GETTER\n// Returns a Duration with the hours/minutes/seconds/ms values of the moment.\n// If the moment has an ambiguous time, a duration of 00:00 will be returned.\n//\n// SETTER\n// You can supply a Duration, a Moment, or a Duration-like argument.\n// When setting the time, and the moment has an ambiguous time, it then becomes unambiguous.\nnewMomentProto.time = function(time) {\n\n\t// Fallback to the original method (if there is one) if this moment wasn't created via FullCalendar.\n\t// `time` is a generic enough method name where this precaution is necessary to avoid collisions w/ other plugins.\n\tif (!this._fullCalendar) {\n\t\treturn oldMomentProto.time.apply(this, arguments);\n\t}\n\n\tif (time == null) { // getter\n\t\treturn moment.duration({\n\t\t\thours: this.hours(),\n\t\t\tminutes: this.minutes(),\n\t\t\tseconds: this.seconds(),\n\t\t\tmilliseconds: this.milliseconds()\n\t\t});\n\t}\n\telse { // setter\n\n\t\tthis._ambigTime = false; // mark that the moment now has a time\n\n\t\tif (!moment.isDuration(time) && !moment.isMoment(time)) {\n\t\t\ttime = moment.duration(time);\n\t\t}\n\n\t\t// The day value should cause overflow (so 24 hours becomes 00:00:00 of next day).\n\t\t// Only for Duration times, not Moment times.\n\t\tvar dayHours = 0;\n\t\tif (moment.isDuration(time)) {\n\t\t\tdayHours = Math.floor(time.asDays()) * 24;\n\t\t}\n\n\t\t// We need to set the individual fields.\n\t\t// Can't use startOf('day') then add duration. In case of DST at start of day.\n\t\treturn this.hours(dayHours + time.hours())\n\t\t\t.minutes(time.minutes())\n\t\t\t.seconds(time.seconds())\n\t\t\t.milliseconds(time.milliseconds());\n\t}\n};\n\n// Converts the moment to UTC, stripping out its time-of-day and timezone offset,\n// but preserving its YMD. A moment with a stripped time will display no time\n// nor timezone offset when .format() is called.\nnewMomentProto.stripTime = function() {\n\tvar a;\n\n\tif (!this._ambigTime) {\n\n\t\t// get the values before any conversion happens\n\t\ta = this.toArray(); // array of y/m/d/h/m/s/ms\n\n\t\t// TODO: use keepLocalTime in the future\n\t\tthis.utc(); // set the internal UTC flag (will clear the ambig flags)\n\t\tsetUTCValues(this, a.slice(0, 3)); // set the year/month/date. time will be zero\n\n\t\t// Mark the time as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(),\n\t\t// which clears all ambig flags. Same with setUTCValues with moment-timezone.\n\t\tthis._ambigTime = true;\n\t\tthis._ambigZone = true; // if ambiguous time, also ambiguous timezone offset\n\t}\n\n\treturn this; // for chaining\n};\n\n// Returns if the moment has a non-ambiguous time (boolean)\nnewMomentProto.hasTime = function() {\n\treturn !this._ambigTime;\n};\n\n\n// Timezone\n// -------------------------------------------------------------------------------------------------\n\n// Converts the moment to UTC, stripping out its timezone offset, but preserving its\n// YMD and time-of-day. A moment with a stripped timezone offset will display no\n// timezone offset when .format() is called.\n// TODO: look into Moment's keepLocalTime functionality\nnewMomentProto.stripZone = function() {\n\tvar a, wasAmbigTime;\n\n\tif (!this._ambigZone) {\n\n\t\t// get the values before any conversion happens\n\t\ta = this.toArray(); // array of y/m/d/h/m/s/ms\n\t\twasAmbigTime = this._ambigTime;\n\n\t\tthis.utc(); // set the internal UTC flag (might clear the ambig flags, depending on Moment internals)\n\t\tsetUTCValues(this, a); // will set the year/month/date/hours/minutes/seconds/ms\n\n\t\t// the above call to .utc()/.utcOffset() unfortunately might clear the ambig flags, so restore\n\t\tthis._ambigTime = wasAmbigTime || false;\n\n\t\t// Mark the zone as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(),\n\t\t// which clears the ambig flags. Same with setUTCValues with moment-timezone.\n\t\tthis._ambigZone = true;\n\t}\n\n\treturn this; // for chaining\n};\n\n// Returns of the moment has a non-ambiguous timezone offset (boolean)\nnewMomentProto.hasZone = function() {\n\treturn !this._ambigZone;\n};\n\n\n// this method implicitly marks a zone\nnewMomentProto.local = function() {\n\tvar a = this.toArray(); // year,month,date,hours,minutes,seconds,ms as an array\n\tvar wasAmbigZone = this._ambigZone;\n\n\toldMomentProto.local.apply(this, arguments);\n\n\t// ensure non-ambiguous\n\t// this probably already happened via local() -> utcOffset(), but don't rely on Moment's internals\n\tthis._ambigTime = false;\n\tthis._ambigZone = false;\n\n\tif (wasAmbigZone) {\n\t\t// If the moment was ambiguously zoned, the date fields were stored as UTC.\n\t\t// We want to preserve these, but in local time.\n\t\t// TODO: look into Moment's keepLocalTime functionality\n\t\tsetLocalValues(this, a);\n\t}\n\n\treturn this; // for chaining\n};\n\n\n// implicitly marks a zone\nnewMomentProto.utc = function() {\n\toldMomentProto.utc.apply(this, arguments);\n\n\t// ensure non-ambiguous\n\t// this probably already happened via utc() -> utcOffset(), but don't rely on Moment's internals\n\tthis._ambigTime = false;\n\tthis._ambigZone = false;\n\n\treturn this;\n};\n\n\n// methods for arbitrarily manipulating timezone offset.\n// should clear time/zone ambiguity when called.\n$.each([\n\t'zone', // only in moment-pre-2.9. deprecated afterwards\n\t'utcOffset'\n], function(i, name) {\n\tif (oldMomentProto[name]) { // original method exists?\n\n\t\t// this method implicitly marks a zone (will probably get called upon .utc() and .local())\n\t\tnewMomentProto[name] = function(tzo) {\n\n\t\t\tif (tzo != null) { // setter\n\t\t\t\t// these assignments needs to happen before the original zone method is called.\n\t\t\t\t// I forget why, something to do with a browser crash.\n\t\t\t\tthis._ambigTime = false;\n\t\t\t\tthis._ambigZone = false;\n\t\t\t}\n\n\t\t\treturn oldMomentProto[name].apply(this, arguments);\n\t\t};\n\t}\n});\n\n\n// Formatting\n// -------------------------------------------------------------------------------------------------\n\nnewMomentProto.format = function() {\n\tif (this._fullCalendar && arguments[0]) { // an enhanced moment? and a format string provided?\n\t\treturn formatDate(this, arguments[0]); // our extended formatting\n\t}\n\tif (this._ambigTime) {\n\t\treturn oldMomentFormat(this, 'YYYY-MM-DD');\n\t}\n\tif (this._ambigZone) {\n\t\treturn oldMomentFormat(this, 'YYYY-MM-DD[T]HH:mm:ss');\n\t}\n\treturn oldMomentProto.format.apply(this, arguments);\n};\n\nnewMomentProto.toISOString = function() {\n\tif (this._ambigTime) {\n\t\treturn oldMomentFormat(this, 'YYYY-MM-DD');\n\t}\n\tif (this._ambigZone) {\n\t\treturn oldMomentFormat(this, 'YYYY-MM-DD[T]HH:mm:ss');\n\t}\n\treturn oldMomentProto.toISOString.apply(this, arguments);\n};\n\n\n// Querying\n// -------------------------------------------------------------------------------------------------\n\n// Is the moment within the specified range? `end` is exclusive.\n// FYI, this method is not a standard Moment method, so always do our enhanced logic.\nnewMomentProto.isWithin = function(start, end) {\n\tvar a = commonlyAmbiguate([ this, start, end ]);\n\treturn a[0] >= a[1] && a[0] < a[2];\n};\n\n// When isSame is called with units, timezone ambiguity is normalized before the comparison happens.\n// If no units specified, the two moments must be identically the same, with matching ambig flags.\nnewMomentProto.isSame = function(input, units) {\n\tvar a;\n\n\t// only do custom logic if this is an enhanced moment\n\tif (!this._fullCalendar) {\n\t\treturn oldMomentProto.isSame.apply(this, arguments);\n\t}\n\n\tif (units) {\n\t\ta = commonlyAmbiguate([ this, input ], true); // normalize timezones but don't erase times\n\t\treturn oldMomentProto.isSame.call(a[0], a[1], units);\n\t}\n\telse {\n\t\tinput = fc.moment.parseZone(input); // normalize input\n\t\treturn oldMomentProto.isSame.call(this, input) &&\n\t\t\tBoolean(this._ambigTime) === Boolean(input._ambigTime) &&\n\t\t\tBoolean(this._ambigZone) === Boolean(input._ambigZone);\n\t}\n};\n\n// Make these query methods work with ambiguous moments\n$.each([\n\t'isBefore',\n\t'isAfter'\n], function(i, methodName) {\n\tnewMomentProto[methodName] = function(input, units) {\n\t\tvar a;\n\n\t\t// only do custom logic if this is an enhanced moment\n\t\tif (!this._fullCalendar) {\n\t\t\treturn oldMomentProto[methodName].apply(this, arguments);\n\t\t}\n\n\t\ta = commonlyAmbiguate([ this, input ]);\n\t\treturn oldMomentProto[methodName].call(a[0], a[1], units);\n\t};\n});\n\n\n// Misc Internals\n// -------------------------------------------------------------------------------------------------\n\n// given an array of moment-like inputs, return a parallel array w/ moments similarly ambiguated.\n// for example, of one moment has ambig time, but not others, all moments will have their time stripped.\n// set `preserveTime` to `true` to keep times, but only normalize zone ambiguity.\n// returns the original moments if no modifications are necessary.\nfunction commonlyAmbiguate(inputs, preserveTime) {\n\tvar anyAmbigTime = false;\n\tvar anyAmbigZone = false;\n\tvar len = inputs.length;\n\tvar moms = [];\n\tvar i, mom;\n\n\t// parse inputs into real moments and query their ambig flags\n\tfor (i = 0; i < len; i++) {\n\t\tmom = inputs[i];\n\t\tif (!moment.isMoment(mom)) {\n\t\t\tmom = fc.moment.parseZone(mom);\n\t\t}\n\t\tanyAmbigTime = anyAmbigTime || mom._ambigTime;\n\t\tanyAmbigZone = anyAmbigZone || mom._ambigZone;\n\t\tmoms.push(mom);\n\t}\n\n\t// strip each moment down to lowest common ambiguity\n\t// use clones to avoid modifying the original moments\n\tfor (i = 0; i < len; i++) {\n\t\tmom = moms[i];\n\t\tif (!preserveTime && anyAmbigTime && !mom._ambigTime) {\n\t\t\tmoms[i] = mom.clone().stripTime();\n\t\t}\n\t\telse if (anyAmbigZone && !mom._ambigZone) {\n\t\t\tmoms[i] = mom.clone().stripZone();\n\t\t}\n\t}\n\n\treturn moms;\n}\n\n// Transfers all the flags related to ambiguous time/zone from the `src` moment to the `dest` moment\n// TODO: look into moment.momentProperties for this.\nfunction transferAmbigs(src, dest) {\n\tif (src._ambigTime) {\n\t\tdest._ambigTime = true;\n\t}\n\telse if (dest._ambigTime) {\n\t\tdest._ambigTime = false;\n\t}\n\n\tif (src._ambigZone) {\n\t\tdest._ambigZone = true;\n\t}\n\telse if (dest._ambigZone) {\n\t\tdest._ambigZone = false;\n\t}\n}\n\n\n// Sets the year/month/date/etc values of the moment from the given array.\n// Inefficient because it calls each individual setter.\nfunction setMomentValues(mom, a) {\n\tmom.year(a[0] || 0)\n\t\t.month(a[1] || 0)\n\t\t.date(a[2] || 0)\n\t\t.hours(a[3] || 0)\n\t\t.minutes(a[4] || 0)\n\t\t.seconds(a[5] || 0)\n\t\t.milliseconds(a[6] || 0);\n}\n\n// Can we set the moment's internal date directly?\nallowValueOptimization = '_d' in moment() && 'updateOffset' in moment;\n\n// Utility function. Accepts a moment and an array of the UTC year/month/date/etc values to set.\n// Assumes the given moment is already in UTC mode.\nsetUTCValues = allowValueOptimization ? function(mom, a) {\n\t// simlate what moment's accessors do\n\tmom._d.setTime(Date.UTC.apply(Date, a));\n\tmoment.updateOffset(mom, false); // keepTime=false\n} : setMomentValues;\n\n// Utility function. Accepts a moment and an array of the local year/month/date/etc values to set.\n// Assumes the given moment is already in local mode.\nsetLocalValues = allowValueOptimization ? function(mom, a) {\n\t// simlate what moment's accessors do\n\tmom._d.setTime(+new Date( // FYI, there is now way to apply an array of args to a constructor\n\t\ta[0] || 0,\n\t\ta[1] || 0,\n\t\ta[2] || 0,\n\t\ta[3] || 0,\n\t\ta[4] || 0,\n\t\ta[5] || 0,\n\t\ta[6] || 0\n\t));\n\tmoment.updateOffset(mom, false); // keepTime=false\n} : setMomentValues;\n\n;;\n\n// Single Date Formatting\n// -------------------------------------------------------------------------------------------------\n\n\n// call this if you want Moment's original format method to be used\nfunction oldMomentFormat(mom, formatStr) {\n\treturn oldMomentProto.format.call(mom, formatStr); // oldMomentProto defined in moment-ext.js\n}\n\n\n// Formats `date` with a Moment formatting string, but allow our non-zero areas and\n// additional token.\nfunction formatDate(date, formatStr) {\n\treturn formatDateWithChunks(date, getFormatStringChunks(formatStr));\n}\n\n\nfunction formatDateWithChunks(date, chunks) {\n\tvar s = '';\n\tvar i;\n\n\tfor (i=0; i \"MMMM D YYYY\"\n\tformatStr = localeData.longDateFormat(formatStr) || formatStr;\n\t// BTW, this is not important for `formatDate` because it is impossible to put custom tokens\n\t// or non-zero areas in Moment's localized format strings.\n\n\tseparator = separator || ' - ';\n\n\treturn formatRangeWithChunks(\n\t\tdate1,\n\t\tdate2,\n\t\tgetFormatStringChunks(formatStr),\n\t\tseparator,\n\t\tisRTL\n\t);\n}\nfc.formatRange = formatRange; // expose\n\n\nfunction formatRangeWithChunks(date1, date2, chunks, separator, isRTL) {\n\tvar chunkStr; // the rendering of the chunk\n\tvar leftI;\n\tvar leftStr = '';\n\tvar rightI;\n\tvar rightStr = '';\n\tvar middleI;\n\tvar middleStr1 = '';\n\tvar middleStr2 = '';\n\tvar middleStr = '';\n\n\t// Start at the leftmost side of the formatting string and continue until you hit a token\n\t// that is not the same between dates.\n\tfor (leftI=0; leftIleftI; rightI--) {\n\t\tchunkStr = formatSimilarChunk(date1, date2, chunks[rightI]);\n\t\tif (chunkStr === false) {\n\t\t\tbreak;\n\t\t}\n\t\trightStr = chunkStr + rightStr;\n\t}\n\n\t// The area in the middle is different for both of the dates.\n\t// Collect them distinctly so we can jam them together later.\n\tfor (middleI=leftI; middleI<=rightI; middleI++) {\n\t\tmiddleStr1 += formatDateWithChunk(date1, chunks[middleI]);\n\t\tmiddleStr2 += formatDateWithChunk(date2, chunks[middleI]);\n\t}\n\n\tif (middleStr1 || middleStr2) {\n\t\tif (isRTL) {\n\t\t\tmiddleStr = middleStr2 + separator + middleStr1;\n\t\t}\n\t\telse {\n\t\t\tmiddleStr = middleStr1 + separator + middleStr2;\n\t\t}\n\t}\n\n\treturn leftStr + middleStr + rightStr;\n}\n\n\nvar similarUnitMap = {\n\tY: 'year',\n\tM: 'month',\n\tD: 'day', // day of month\n\td: 'day', // day of week\n\t// prevents a separator between anything time-related...\n\tA: 'second', // AM/PM\n\ta: 'second', // am/pm\n\tT: 'second', // A/P\n\tt: 'second', // a/p\n\tH: 'second', // hour (24)\n\th: 'second', // hour (12)\n\tm: 'second', // minute\n\ts: 'second' // second\n};\n// TODO: week maybe?\n\n\n// Given a formatting chunk, and given that both dates are similar in the regard the\n// formatting chunk is concerned, format date1 against `chunk`. Otherwise, return `false`.\nfunction formatSimilarChunk(date1, date2, chunk) {\n\tvar token;\n\tvar unit;\n\n\tif (typeof chunk === 'string') { // a literal string\n\t\treturn chunk;\n\t}\n\telse if ((token = chunk.token)) {\n\t\tunit = similarUnitMap[token.charAt(0)];\n\t\t// are the dates the same for this unit of measurement?\n\t\tif (unit && date1.isSame(date2, unit)) {\n\t\t\treturn oldMomentFormat(date1, token); // would be the same if we used `date2`\n\t\t\t// BTW, don't support custom tokens\n\t\t}\n\t}\n\n\treturn false; // the chunk is NOT the same for the two dates\n\t// BTW, don't support splitting on non-zero areas\n}\n\n\n// Chunking Utils\n// -------------------------------------------------------------------------------------------------\n\n\nvar formatStringChunkCache = {};\n\n\nfunction getFormatStringChunks(formatStr) {\n\tif (formatStr in formatStringChunkCache) {\n\t\treturn formatStringChunkCache[formatStr];\n\t}\n\treturn (formatStringChunkCache[formatStr] = chunkFormatString(formatStr));\n}\n\n\n// Break the formatting string into an array of chunks\nfunction chunkFormatString(formatStr) {\n\tvar chunks = [];\n\tvar chunker = /\\[([^\\]]*)\\]|\\(([^\\)]*)\\)|(LTS|LT|(\\w)\\4*o?)|([^\\w\\[\\(]+)/g; // TODO: more descrimination\n\tvar match;\n\n\twhile ((match = chunker.exec(formatStr))) {\n\t\tif (match[1]) { // a literal string inside [ ... ]\n\t\t\tchunks.push(match[1]);\n\t\t}\n\t\telse if (match[2]) { // non-zero formatting inside ( ... )\n\t\t\tchunks.push({ maybe: chunkFormatString(match[2]) });\n\t\t}\n\t\telse if (match[3]) { // a formatting token\n\t\t\tchunks.push({ token: match[3] });\n\t\t}\n\t\telse if (match[5]) { // an unenclosed literal string\n\t\t\tchunks.push(match[5]);\n\t\t}\n\t}\n\n\treturn chunks;\n}\n\n;;\n\nfc.Class = Class; // export\n\n// class that all other classes will inherit from\nfunction Class() { }\n\n// called upon a class to create a subclass\nClass.extend = function(members) {\n\tvar superClass = this;\n\tvar subClass;\n\n\tmembers = members || {};\n\n\t// ensure a constructor for the subclass, forwarding all arguments to the super-constructor if it doesn't exist\n\tif (hasOwnProp(members, 'constructor')) {\n\t\tsubClass = members.constructor;\n\t}\n\tif (typeof subClass !== 'function') {\n\t\tsubClass = members.constructor = function() {\n\t\t\tsuperClass.apply(this, arguments);\n\t\t};\n\t}\n\n\t// build the base prototype for the subclass, which is an new object chained to the superclass's prototype\n\tsubClass.prototype = createObject(superClass.prototype);\n\n\t// copy each member variable/method onto the the subclass's prototype\n\tcopyOwnProps(members, subClass.prototype);\n\tcopyNativeMethods(members, subClass.prototype); // hack for IE8\n\n\t// copy over all class variables/methods to the subclass, such as `extend` and `mixin`\n\tcopyOwnProps(superClass, subClass);\n\n\treturn subClass;\n};\n\n// adds new member variables/methods to the class's prototype.\n// can be called with another class, or a plain object hash containing new members.\nClass.mixin = function(members) {\n\tcopyOwnProps(members.prototype || members, this.prototype); // TODO: copyNativeMethods?\n};\n;;\n\nvar Emitter = fc.Emitter = Class.extend({\n\n\tcallbackHash: null,\n\n\n\ton: function(name, callback) {\n\t\tthis.getCallbacks(name).add(callback);\n\t\treturn this; // for chaining\n\t},\n\n\n\toff: function(name, callback) {\n\t\tthis.getCallbacks(name).remove(callback);\n\t\treturn this; // for chaining\n\t},\n\n\n\ttrigger: function(name) { // args...\n\t\tvar args = Array.prototype.slice.call(arguments, 1);\n\n\t\tthis.triggerWith(name, this, args);\n\n\t\treturn this; // for chaining\n\t},\n\n\n\ttriggerWith: function(name, context, args) {\n\t\tvar callbacks = this.getCallbacks(name);\n\n\t\tcallbacks.fireWith(context, args);\n\n\t\treturn this; // for chaining\n\t},\n\n\n\tgetCallbacks: function(name) {\n\t\tvar callbacks;\n\n\t\tif (!this.callbackHash) {\n\t\t\tthis.callbackHash = {};\n\t\t}\n\n\t\tcallbacks = this.callbackHash[name];\n\t\tif (!callbacks) {\n\t\t\tcallbacks = this.callbackHash[name] = $.Callbacks();\n\t\t}\n\n\t\treturn callbacks;\n\t}\n\n});\n;;\n\n/* A rectangular panel that is absolutely positioned over other content\n------------------------------------------------------------------------------------------------------------------------\nOptions:\n\t- className (string)\n\t- content (HTML string or jQuery element set)\n\t- parentEl\n\t- top\n\t- left\n\t- right (the x coord of where the right edge should be. not a \"CSS\" right)\n\t- autoHide (boolean)\n\t- show (callback)\n\t- hide (callback)\n*/\n\nvar Popover = Class.extend({\n\n\tisHidden: true,\n\toptions: null,\n\tel: null, // the container element for the popover. generated by this object\n\tdocumentMousedownProxy: null, // document mousedown handler bound to `this`\n\tmargin: 10, // the space required between the popover and the edges of the scroll container\n\n\n\tconstructor: function(options) {\n\t\tthis.options = options || {};\n\t},\n\n\n\t// Shows the popover on the specified position. Renders it if not already\n\tshow: function() {\n\t\tif (this.isHidden) {\n\t\t\tif (!this.el) {\n\t\t\t\tthis.render();\n\t\t\t}\n\t\t\tthis.el.show();\n\t\t\tthis.position();\n\t\t\tthis.isHidden = false;\n\t\t\tthis.trigger('show');\n\t\t}\n\t},\n\n\n\t// Hides the popover, through CSS, but does not remove it from the DOM\n\thide: function() {\n\t\tif (!this.isHidden) {\n\t\t\tthis.el.hide();\n\t\t\tthis.isHidden = true;\n\t\t\tthis.trigger('hide');\n\t\t}\n\t},\n\n\n\t// Creates `this.el` and renders content inside of it\n\trender: function() {\n\t\tvar _this = this;\n\t\tvar options = this.options;\n\n\t\tthis.el = $('
')\n\t\t\t.addClass(options.className || '')\n\t\t\t.css({\n\t\t\t\t// position initially to the top left to avoid creating scrollbars\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0\n\t\t\t})\n\t\t\t.append(options.content)\n\t\t\t.appendTo(options.parentEl);\n\n\t\t// when a click happens on anything inside with a 'fc-close' className, hide the popover\n\t\tthis.el.on('click', '.fc-close', function() {\n\t\t\t_this.hide();\n\t\t});\n\n\t\tif (options.autoHide) {\n\t\t\t$(document).on('mousedown', this.documentMousedownProxy = proxy(this, 'documentMousedown'));\n\t\t}\n\t},\n\n\n\t// Triggered when the user clicks *anywhere* in the document, for the autoHide feature\n\tdocumentMousedown: function(ev) {\n\t\t// only hide the popover if the click happened outside the popover\n\t\tif (this.el && !$(ev.target).closest(this.el).length) {\n\t\t\tthis.hide();\n\t\t}\n\t},\n\n\n\t// Hides and unregisters any handlers\n\tremoveElement: function() {\n\t\tthis.hide();\n\n\t\tif (this.el) {\n\t\t\tthis.el.remove();\n\t\t\tthis.el = null;\n\t\t}\n\n\t\t$(document).off('mousedown', this.documentMousedownProxy);\n\t},\n\n\n\t// Positions the popover optimally, using the top/left/right options\n\tposition: function() {\n\t\tvar options = this.options;\n\t\tvar origin = this.el.offsetParent().offset();\n\t\tvar width = this.el.outerWidth();\n\t\tvar height = this.el.outerHeight();\n\t\tvar windowEl = $(window);\n\t\tvar viewportEl = getScrollParent(this.el);\n\t\tvar viewportTop;\n\t\tvar viewportLeft;\n\t\tvar viewportOffset;\n\t\tvar top; // the \"position\" (not \"offset\") values for the popover\n\t\tvar left; //\n\n\t\t// compute top and left\n\t\ttop = options.top || 0;\n\t\tif (options.left !== undefined) {\n\t\t\tleft = options.left;\n\t\t}\n\t\telse if (options.right !== undefined) {\n\t\t\tleft = options.right - width; // derive the left value from the right value\n\t\t}\n\t\telse {\n\t\t\tleft = 0;\n\t\t}\n\n\t\tif (viewportEl.is(window) || viewportEl.is(document)) { // normalize getScrollParent's result\n\t\t\tviewportEl = windowEl;\n\t\t\tviewportTop = 0; // the window is always at the top left\n\t\t\tviewportLeft = 0; // (and .offset() won't work if called here)\n\t\t}\n\t\telse {\n\t\t\tviewportOffset = viewportEl.offset();\n\t\t\tviewportTop = viewportOffset.top;\n\t\t\tviewportLeft = viewportOffset.left;\n\t\t}\n\n\t\t// if the window is scrolled, it causes the visible area to be further down\n\t\tviewportTop += windowEl.scrollTop();\n\t\tviewportLeft += windowEl.scrollLeft();\n\n\t\t// constrain to the view port. if constrained by two edges, give precedence to top/left\n\t\tif (options.viewportConstrain !== false) {\n\t\t\ttop = Math.min(top, viewportTop + viewportEl.outerHeight() - height - this.margin);\n\t\t\ttop = Math.max(top, viewportTop + this.margin);\n\t\t\tleft = Math.min(left, viewportLeft + viewportEl.outerWidth() - width - this.margin);\n\t\t\tleft = Math.max(left, viewportLeft + this.margin);\n\t\t}\n\n\t\tthis.el.css({\n\t\t\ttop: top - origin.top,\n\t\t\tleft: left - origin.left\n\t\t});\n\t},\n\n\n\t// Triggers a callback. Calls a function in the option hash of the same name.\n\t// Arguments beyond the first `name` are forwarded on.\n\t// TODO: better code reuse for this. Repeat code\n\ttrigger: function(name) {\n\t\tif (this.options[name]) {\n\t\t\tthis.options[name].apply(this, Array.prototype.slice.call(arguments, 1));\n\t\t}\n\t}\n\n});\n\n;;\n\n/* A \"coordinate map\" converts pixel coordinates into an associated cell, which has an associated date\n------------------------------------------------------------------------------------------------------------------------\nCommon interface:\n\n\tCoordMap.prototype = {\n\t\tbuild: function() {},\n\t\tgetCell: function(x, y) {}\n\t};\n\n*/\n\n/* Coordinate map for a grid component\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar GridCoordMap = Class.extend({\n\n\tgrid: null, // reference to the Grid\n\trowCoords: null, // array of {top,bottom} objects\n\tcolCoords: null, // array of {left,right} objects\n\n\tcontainerEl: null, // container element that all coordinates are constrained to. optionally assigned\n\tbounds: null,\n\n\n\tconstructor: function(grid) {\n\t\tthis.grid = grid;\n\t},\n\n\n\t// Queries the grid for the coordinates of all the cells\n\tbuild: function() {\n\t\tthis.grid.build();\n\t\tthis.rowCoords = this.grid.computeRowCoords();\n\t\tthis.colCoords = this.grid.computeColCoords();\n\t\tthis.computeBounds();\n\t},\n\n\n\t// Clears the coordinates data to free up memory\n\tclear: function() {\n\t\tthis.grid.clear();\n\t\tthis.rowCoords = null;\n\t\tthis.colCoords = null;\n\t},\n\n\n\t// Given a coordinate of the document, gets the associated cell. If no cell is underneath, returns null\n\tgetCell: function(x, y) {\n\t\tvar rowCoords = this.rowCoords;\n\t\tvar rowCnt = rowCoords.length;\n\t\tvar colCoords = this.colCoords;\n\t\tvar colCnt = colCoords.length;\n\t\tvar hitRow = null;\n\t\tvar hitCol = null;\n\t\tvar i, coords;\n\t\tvar cell;\n\n\t\tif (this.inBounds(x, y)) {\n\n\t\t\tfor (i = 0; i < rowCnt; i++) {\n\t\t\t\tcoords = rowCoords[i];\n\t\t\t\tif (y >= coords.top && y < coords.bottom) {\n\t\t\t\t\thitRow = i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (i = 0; i < colCnt; i++) {\n\t\t\t\tcoords = colCoords[i];\n\t\t\t\tif (x >= coords.left && x < coords.right) {\n\t\t\t\t\thitCol = i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (hitRow !== null && hitCol !== null) {\n\n\t\t\t\tcell = this.grid.getCell(hitRow, hitCol); // expected to return a fresh object we can modify\n\t\t\t\tcell.grid = this.grid; // for CellDragListener's isCellsEqual. dragging between grids\n\n\t\t\t\t// make the coordinates available on the cell object\n\t\t\t\t$.extend(cell, rowCoords[hitRow], colCoords[hitCol]);\n\n\t\t\t\treturn cell;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t},\n\n\n\t// If there is a containerEl, compute the bounds into min/max values\n\tcomputeBounds: function() {\n\t\tthis.bounds = this.containerEl ?\n\t\t\tgetClientRect(this.containerEl) : // area within scrollbars\n\t\t\tnull;\n\t},\n\n\n\t// Determines if the given coordinates are in bounds. If no `containerEl`, always true\n\tinBounds: function(x, y) {\n\t\tvar bounds = this.bounds;\n\n\t\tif (bounds) {\n\t\t\treturn x >= bounds.left && x < bounds.right && y >= bounds.top && y < bounds.bottom;\n\t\t}\n\n\t\treturn true;\n\t}\n\n});\n\n\n/* Coordinate map that is a combination of multiple other coordinate maps\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar ComboCoordMap = Class.extend({\n\n\tcoordMaps: null, // an array of CoordMaps\n\n\n\tconstructor: function(coordMaps) {\n\t\tthis.coordMaps = coordMaps;\n\t},\n\n\n\t// Builds all coordMaps\n\tbuild: function() {\n\t\tvar coordMaps = this.coordMaps;\n\t\tvar i;\n\n\t\tfor (i = 0; i < coordMaps.length; i++) {\n\t\t\tcoordMaps[i].build();\n\t\t}\n\t},\n\n\n\t// Queries all coordMaps for the cell underneath the given coordinates, returning the first result\n\tgetCell: function(x, y) {\n\t\tvar coordMaps = this.coordMaps;\n\t\tvar cell = null;\n\t\tvar i;\n\n\t\tfor (i = 0; i < coordMaps.length && !cell; i++) {\n\t\t\tcell = coordMaps[i].getCell(x, y);\n\t\t}\n\n\t\treturn cell;\n\t},\n\n\n\t// Clears all coordMaps\n\tclear: function() {\n\t\tvar coordMaps = this.coordMaps;\n\t\tvar i;\n\n\t\tfor (i = 0; i < coordMaps.length; i++) {\n\t\t\tcoordMaps[i].clear();\n\t\t}\n\t}\n\n});\n\n;;\n\n/* Tracks a drag's mouse movement, firing various handlers\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar DragListener = fc.DragListener = Class.extend({\n\n\toptions: null,\n\n\tisListening: false,\n\tisDragging: false,\n\n\t// coordinates of the initial mousedown\n\toriginX: null,\n\toriginY: null,\n\n\t// handler attached to the document, bound to the DragListener's `this`\n\tmousemoveProxy: null,\n\tmouseupProxy: null,\n\n\t// for IE8 bug-fighting behavior, for now\n\tsubjectEl: null, // the element being draged. optional\n\tsubjectHref: null,\n\n\tscrollEl: null,\n\tscrollBounds: null, // { top, bottom, left, right }\n\tscrollTopVel: null, // pixels per second\n\tscrollLeftVel: null, // pixels per second\n\tscrollIntervalId: null, // ID of setTimeout for scrolling animation loop\n\tscrollHandlerProxy: null, // this-scoped function for handling when scrollEl is scrolled\n\n\tscrollSensitivity: 30, // pixels from edge for scrolling to start\n\tscrollSpeed: 200, // pixels per second, at maximum speed\n\tscrollIntervalMs: 50, // millisecond wait between scroll increment\n\n\n\tconstructor: function(options) {\n\t\toptions = options || {};\n\t\tthis.options = options;\n\t\tthis.subjectEl = options.subjectEl;\n\t},\n\n\n\t// Call this when the user does a mousedown. Will probably lead to startListening\n\tmousedown: function(ev) {\n\t\tif (isPrimaryMouseButton(ev)) {\n\n\t\t\tev.preventDefault(); // prevents native selection in most browsers\n\n\t\t\tthis.startListening(ev);\n\n\t\t\t// start the drag immediately if there is no minimum distance for a drag start\n\t\t\tif (!this.options.distance) {\n\t\t\t\tthis.startDrag(ev);\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Call this to start tracking mouse movements\n\tstartListening: function(ev) {\n\t\tvar scrollParent;\n\n\t\tif (!this.isListening) {\n\n\t\t\t// grab scroll container and attach handler\n\t\t\tif (ev && this.options.scroll) {\n\t\t\t\tscrollParent = getScrollParent($(ev.target));\n\t\t\t\tif (!scrollParent.is(window) && !scrollParent.is(document)) {\n\t\t\t\t\tthis.scrollEl = scrollParent;\n\n\t\t\t\t\t// scope to `this`, and use `debounce` to make sure rapid calls don't happen\n\t\t\t\t\tthis.scrollHandlerProxy = debounce(proxy(this, 'scrollHandler'), 100);\n\t\t\t\t\tthis.scrollEl.on('scroll', this.scrollHandlerProxy);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$(document)\n\t\t\t\t.on('mousemove', this.mousemoveProxy = proxy(this, 'mousemove'))\n\t\t\t\t.on('mouseup', this.mouseupProxy = proxy(this, 'mouseup'))\n\t\t\t\t.on('selectstart', this.preventDefault); // prevents native selection in IE<=8\n\n\t\t\tif (ev) {\n\t\t\t\tthis.originX = ev.pageX;\n\t\t\t\tthis.originY = ev.pageY;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// if no starting information was given, origin will be the topleft corner of the screen.\n\t\t\t\t// if so, dx/dy in the future will be the absolute coordinates.\n\t\t\t\tthis.originX = 0;\n\t\t\t\tthis.originY = 0;\n\t\t\t}\n\n\t\t\tthis.isListening = true;\n\t\t\tthis.listenStart(ev);\n\t\t}\n\t},\n\n\n\t// Called when drag listening has started (but a real drag has not necessarily began)\n\tlistenStart: function(ev) {\n\t\tthis.trigger('listenStart', ev);\n\t},\n\n\n\t// Called when the user moves the mouse\n\tmousemove: function(ev) {\n\t\tvar dx = ev.pageX - this.originX;\n\t\tvar dy = ev.pageY - this.originY;\n\t\tvar minDistance;\n\t\tvar distanceSq; // current distance from the origin, squared\n\n\t\tif (!this.isDragging) { // if not already dragging...\n\t\t\t// then start the drag if the minimum distance criteria is met\n\t\t\tminDistance = this.options.distance || 1;\n\t\t\tdistanceSq = dx * dx + dy * dy;\n\t\t\tif (distanceSq >= minDistance * minDistance) { // use pythagorean theorem\n\t\t\t\tthis.startDrag(ev);\n\t\t\t}\n\t\t}\n\n\t\tif (this.isDragging) {\n\t\t\tthis.drag(dx, dy, ev); // report a drag, even if this mousemove initiated the drag\n\t\t}\n\t},\n\n\n\t// Call this to initiate a legitimate drag.\n\t// This function is called internally from this class, but can also be called explicitly from outside\n\tstartDrag: function(ev) {\n\n\t\tif (!this.isListening) { // startDrag must have manually initiated\n\t\t\tthis.startListening();\n\t\t}\n\n\t\tif (!this.isDragging) {\n\t\t\tthis.isDragging = true;\n\t\t\tthis.dragStart(ev);\n\t\t}\n\t},\n\n\n\t// Called when the actual drag has started (went beyond minDistance)\n\tdragStart: function(ev) {\n\t\tvar subjectEl = this.subjectEl;\n\n\t\tthis.trigger('dragStart', ev);\n\n\t\t// remove a mousedown'd 's href so it is not visited (IE8 bug)\n\t\tif ((this.subjectHref = subjectEl ? subjectEl.attr('href') : null)) {\n\t\t\tsubjectEl.removeAttr('href');\n\t\t}\n\t},\n\n\n\t// Called while the mouse is being moved and when we know a legitimate drag is taking place\n\tdrag: function(dx, dy, ev) {\n\t\tthis.trigger('drag', dx, dy, ev);\n\t\tthis.updateScroll(ev); // will possibly cause scrolling\n\t},\n\n\n\t// Called when the user does a mouseup\n\tmouseup: function(ev) {\n\t\tthis.stopListening(ev);\n\t},\n\n\n\t// Called when the drag is over. Will not cause listening to stop however.\n\t// A concluding 'cellOut' event will NOT be triggered.\n\tstopDrag: function(ev) {\n\t\tif (this.isDragging) {\n\t\t\tthis.stopScrolling();\n\t\t\tthis.dragStop(ev);\n\t\t\tthis.isDragging = false;\n\t\t}\n\t},\n\n\n\t// Called when dragging has been stopped\n\tdragStop: function(ev) {\n\t\tvar _this = this;\n\n\t\tthis.trigger('dragStop', ev);\n\n\t\t// restore a mousedown'd 's href (for IE8 bug)\n\t\tsetTimeout(function() { // must be outside of the click's execution\n\t\t\tif (_this.subjectHref) {\n\t\t\t\t_this.subjectEl.attr('href', _this.subjectHref);\n\t\t\t}\n\t\t}, 0);\n\t},\n\n\n\t// Call this to stop listening to the user's mouse events\n\tstopListening: function(ev) {\n\t\tthis.stopDrag(ev); // if there's a current drag, kill it\n\n\t\tif (this.isListening) {\n\n\t\t\t// remove the scroll handler if there is a scrollEl\n\t\t\tif (this.scrollEl) {\n\t\t\t\tthis.scrollEl.off('scroll', this.scrollHandlerProxy);\n\t\t\t\tthis.scrollHandlerProxy = null;\n\t\t\t}\n\n\t\t\t$(document)\n\t\t\t\t.off('mousemove', this.mousemoveProxy)\n\t\t\t\t.off('mouseup', this.mouseupProxy)\n\t\t\t\t.off('selectstart', this.preventDefault);\n\n\t\t\tthis.mousemoveProxy = null;\n\t\t\tthis.mouseupProxy = null;\n\n\t\t\tthis.isListening = false;\n\t\t\tthis.listenStop(ev);\n\t\t}\n\t},\n\n\n\t// Called when drag listening has stopped\n\tlistenStop: function(ev) {\n\t\tthis.trigger('listenStop', ev);\n\t},\n\n\n\t// Triggers a callback. Calls a function in the option hash of the same name.\n\t// Arguments beyond the first `name` are forwarded on.\n\ttrigger: function(name) {\n\t\tif (this.options[name]) {\n\t\t\tthis.options[name].apply(this, Array.prototype.slice.call(arguments, 1));\n\t\t}\n\t},\n\n\n\t// Stops a given mouse event from doing it's native browser action. In our case, text selection.\n\tpreventDefault: function(ev) {\n\t\tev.preventDefault();\n\t},\n\n\n\t/* Scrolling\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Computes and stores the bounding rectangle of scrollEl\n\tcomputeScrollBounds: function() {\n\t\tvar el = this.scrollEl;\n\n\t\tthis.scrollBounds = el ? getOuterRect(el) : null;\n\t\t\t// TODO: use getClientRect in future. but prevents auto scrolling when on top of scrollbars\n\t},\n\n\n\t// Called when the dragging is in progress and scrolling should be updated\n\tupdateScroll: function(ev) {\n\t\tvar sensitivity = this.scrollSensitivity;\n\t\tvar bounds = this.scrollBounds;\n\t\tvar topCloseness, bottomCloseness;\n\t\tvar leftCloseness, rightCloseness;\n\t\tvar topVel = 0;\n\t\tvar leftVel = 0;\n\n\t\tif (bounds) { // only scroll if scrollEl exists\n\n\t\t\t// compute closeness to edges. valid range is from 0.0 - 1.0\n\t\t\ttopCloseness = (sensitivity - (ev.pageY - bounds.top)) / sensitivity;\n\t\t\tbottomCloseness = (sensitivity - (bounds.bottom - ev.pageY)) / sensitivity;\n\t\t\tleftCloseness = (sensitivity - (ev.pageX - bounds.left)) / sensitivity;\n\t\t\trightCloseness = (sensitivity - (bounds.right - ev.pageX)) / sensitivity;\n\n\t\t\t// translate vertical closeness into velocity.\n\t\t\t// mouse must be completely in bounds for velocity to happen.\n\t\t\tif (topCloseness >= 0 && topCloseness <= 1) {\n\t\t\t\ttopVel = topCloseness * this.scrollSpeed * -1; // negative. for scrolling up\n\t\t\t}\n\t\t\telse if (bottomCloseness >= 0 && bottomCloseness <= 1) {\n\t\t\t\ttopVel = bottomCloseness * this.scrollSpeed;\n\t\t\t}\n\n\t\t\t// translate horizontal closeness into velocity\n\t\t\tif (leftCloseness >= 0 && leftCloseness <= 1) {\n\t\t\t\tleftVel = leftCloseness * this.scrollSpeed * -1; // negative. for scrolling left\n\t\t\t}\n\t\t\telse if (rightCloseness >= 0 && rightCloseness <= 1) {\n\t\t\t\tleftVel = rightCloseness * this.scrollSpeed;\n\t\t\t}\n\t\t}\n\n\t\tthis.setScrollVel(topVel, leftVel);\n\t},\n\n\n\t// Sets the speed-of-scrolling for the scrollEl\n\tsetScrollVel: function(topVel, leftVel) {\n\n\t\tthis.scrollTopVel = topVel;\n\t\tthis.scrollLeftVel = leftVel;\n\n\t\tthis.constrainScrollVel(); // massages into realistic values\n\n\t\t// if there is non-zero velocity, and an animation loop hasn't already started, then START\n\t\tif ((this.scrollTopVel || this.scrollLeftVel) && !this.scrollIntervalId) {\n\t\t\tthis.scrollIntervalId = setInterval(\n\t\t\t\tproxy(this, 'scrollIntervalFunc'), // scope to `this`\n\t\t\t\tthis.scrollIntervalMs\n\t\t\t);\n\t\t}\n\t},\n\n\n\t// Forces scrollTopVel and scrollLeftVel to be zero if scrolling has already gone all the way\n\tconstrainScrollVel: function() {\n\t\tvar el = this.scrollEl;\n\n\t\tif (this.scrollTopVel < 0) { // scrolling up?\n\t\t\tif (el.scrollTop() <= 0) { // already scrolled all the way up?\n\t\t\t\tthis.scrollTopVel = 0;\n\t\t\t}\n\t\t}\n\t\telse if (this.scrollTopVel > 0) { // scrolling down?\n\t\t\tif (el.scrollTop() + el[0].clientHeight >= el[0].scrollHeight) { // already scrolled all the way down?\n\t\t\t\tthis.scrollTopVel = 0;\n\t\t\t}\n\t\t}\n\n\t\tif (this.scrollLeftVel < 0) { // scrolling left?\n\t\t\tif (el.scrollLeft() <= 0) { // already scrolled all the left?\n\t\t\t\tthis.scrollLeftVel = 0;\n\t\t\t}\n\t\t}\n\t\telse if (this.scrollLeftVel > 0) { // scrolling right?\n\t\t\tif (el.scrollLeft() + el[0].clientWidth >= el[0].scrollWidth) { // already scrolled all the way right?\n\t\t\t\tthis.scrollLeftVel = 0;\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// This function gets called during every iteration of the scrolling animation loop\n\tscrollIntervalFunc: function() {\n\t\tvar el = this.scrollEl;\n\t\tvar frac = this.scrollIntervalMs / 1000; // considering animation frequency, what the vel should be mult'd by\n\n\t\t// change the value of scrollEl's scroll\n\t\tif (this.scrollTopVel) {\n\t\t\tel.scrollTop(el.scrollTop() + this.scrollTopVel * frac);\n\t\t}\n\t\tif (this.scrollLeftVel) {\n\t\t\tel.scrollLeft(el.scrollLeft() + this.scrollLeftVel * frac);\n\t\t}\n\n\t\tthis.constrainScrollVel(); // since the scroll values changed, recompute the velocities\n\n\t\t// if scrolled all the way, which causes the vels to be zero, stop the animation loop\n\t\tif (!this.scrollTopVel && !this.scrollLeftVel) {\n\t\t\tthis.stopScrolling();\n\t\t}\n\t},\n\n\n\t// Kills any existing scrolling animation loop\n\tstopScrolling: function() {\n\t\tif (this.scrollIntervalId) {\n\t\t\tclearInterval(this.scrollIntervalId);\n\t\t\tthis.scrollIntervalId = null;\n\n\t\t\t// when all done with scrolling, recompute positions since they probably changed\n\t\t\tthis.scrollStop();\n\t\t}\n\t},\n\n\n\t// Get called when the scrollEl is scrolled (NOTE: this is delayed via debounce)\n\tscrollHandler: function() {\n\t\t// recompute all coordinates, but *only* if this is *not* part of our scrolling animation\n\t\tif (!this.scrollIntervalId) {\n\t\t\tthis.scrollStop();\n\t\t}\n\t},\n\n\n\t// Called when scrolling has stopped, whether through auto scroll, or the user scrolling\n\tscrollStop: function() {\n\t}\n\n});\n\n;;\n\n/* Tracks mouse movements over a CoordMap and raises events about which cell the mouse is over.\n------------------------------------------------------------------------------------------------------------------------\noptions:\n- subjectEl\n- subjectCenter\n*/\n\nvar CellDragListener = DragListener.extend({\n\n\tcoordMap: null, // converts coordinates to date cells\n\torigCell: null, // the cell the mouse was over when listening started\n\tcell: null, // the cell the mouse is over\n\tcoordAdjust: null, // delta that will be added to the mouse coordinates when computing collisions\n\n\n\tconstructor: function(coordMap, options) {\n\t\tDragListener.prototype.constructor.call(this, options); // call the super-constructor\n\n\t\tthis.coordMap = coordMap;\n\t},\n\n\n\t// Called when drag listening starts (but a real drag has not necessarily began).\n\t// ev might be undefined if dragging was started manually.\n\tlistenStart: function(ev) {\n\t\tvar subjectEl = this.subjectEl;\n\t\tvar subjectRect;\n\t\tvar origPoint;\n\t\tvar point;\n\n\t\tDragListener.prototype.listenStart.apply(this, arguments); // call the super-method\n\n\t\tthis.computeCoords();\n\n\t\tif (ev) {\n\t\t\torigPoint = { left: ev.pageX, top: ev.pageY };\n\t\t\tpoint = origPoint;\n\n\t\t\t// constrain the point to bounds of the element being dragged\n\t\t\tif (subjectEl) {\n\t\t\t\tsubjectRect = getOuterRect(subjectEl); // used for centering as well\n\t\t\t\tpoint = constrainPoint(point, subjectRect);\n\t\t\t}\n\n\t\t\tthis.origCell = this.getCell(point.left, point.top);\n\n\t\t\t// treat the center of the subject as the collision point?\n\t\t\tif (subjectEl && this.options.subjectCenter) {\n\n\t\t\t\t// only consider the area the subject overlaps the cell. best for large subjects\n\t\t\t\tif (this.origCell) {\n\t\t\t\t\tsubjectRect = intersectRects(this.origCell, subjectRect) ||\n\t\t\t\t\t\tsubjectRect; // in case there is no intersection\n\t\t\t\t}\n\n\t\t\t\tpoint = getRectCenter(subjectRect);\n\t\t\t}\n\n\t\t\tthis.coordAdjust = diffPoints(point, origPoint); // point - origPoint\n\t\t}\n\t\telse {\n\t\t\tthis.origCell = null;\n\t\t\tthis.coordAdjust = null;\n\t\t}\n\t},\n\n\n\t// Recomputes the drag-critical positions of elements\n\tcomputeCoords: function() {\n\t\tthis.coordMap.build();\n\t\tthis.computeScrollBounds();\n\t},\n\n\n\t// Called when the actual drag has started\n\tdragStart: function(ev) {\n\t\tvar cell;\n\n\t\tDragListener.prototype.dragStart.apply(this, arguments); // call the super-method\n\n\t\tcell = this.getCell(ev.pageX, ev.pageY); // might be different from this.origCell if the min-distance is large\n\n\t\t// report the initial cell the mouse is over\n\t\t// especially important if no min-distance and drag starts immediately\n\t\tif (cell) {\n\t\t\tthis.cellOver(cell);\n\t\t}\n\t},\n\n\n\t// Called when the drag moves\n\tdrag: function(dx, dy, ev) {\n\t\tvar cell;\n\n\t\tDragListener.prototype.drag.apply(this, arguments); // call the super-method\n\n\t\tcell = this.getCell(ev.pageX, ev.pageY);\n\n\t\tif (!isCellsEqual(cell, this.cell)) { // a different cell than before?\n\t\t\tif (this.cell) {\n\t\t\t\tthis.cellOut();\n\t\t\t}\n\t\t\tif (cell) {\n\t\t\t\tthis.cellOver(cell);\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Called when dragging has been stopped\n\tdragStop: function() {\n\t\tthis.cellDone();\n\t\tDragListener.prototype.dragStop.apply(this, arguments); // call the super-method\n\t},\n\n\n\t// Called when a the mouse has just moved over a new cell\n\tcellOver: function(cell) {\n\t\tthis.cell = cell;\n\t\tthis.trigger('cellOver', cell, isCellsEqual(cell, this.origCell), this.origCell);\n\t},\n\n\n\t// Called when the mouse has just moved out of a cell\n\tcellOut: function() {\n\t\tif (this.cell) {\n\t\t\tthis.trigger('cellOut', this.cell);\n\t\t\tthis.cellDone();\n\t\t\tthis.cell = null;\n\t\t}\n\t},\n\n\n\t// Called after a cellOut. Also called before a dragStop\n\tcellDone: function() {\n\t\tif (this.cell) {\n\t\t\tthis.trigger('cellDone', this.cell);\n\t\t}\n\t},\n\n\n\t// Called when drag listening has stopped\n\tlistenStop: function() {\n\t\tDragListener.prototype.listenStop.apply(this, arguments); // call the super-method\n\n\t\tthis.origCell = this.cell = null;\n\t\tthis.coordMap.clear();\n\t},\n\n\n\t// Called when scrolling has stopped, whether through auto scroll, or the user scrolling\n\tscrollStop: function() {\n\t\tDragListener.prototype.scrollStop.apply(this, arguments); // call the super-method\n\n\t\tthis.computeCoords(); // cells' absolute positions will be in new places. recompute\n\t},\n\n\n\t// Gets the cell underneath the coordinates for the given mouse event\n\tgetCell: function(left, top) {\n\n\t\tif (this.coordAdjust) {\n\t\t\tleft += this.coordAdjust.left;\n\t\t\ttop += this.coordAdjust.top;\n\t\t}\n\n\t\treturn this.coordMap.getCell(left, top);\n\t}\n\n});\n\n\n// Returns `true` if the cells are identically equal. `false` otherwise.\n// They must have the same row, col, and be from the same grid.\n// Two null values will be considered equal, as two \"out of the grid\" states are the same.\nfunction isCellsEqual(cell1, cell2) {\n\n\tif (!cell1 && !cell2) {\n\t\treturn true;\n\t}\n\n\tif (cell1 && cell2) {\n\t\treturn cell1.grid === cell2.grid &&\n\t\t\tcell1.row === cell2.row &&\n\t\t\tcell1.col === cell2.col;\n\t}\n\n\treturn false;\n}\n\n;;\n\n/* Creates a clone of an element and lets it track the mouse as it moves\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar MouseFollower = Class.extend({\n\n\toptions: null,\n\n\tsourceEl: null, // the element that will be cloned and made to look like it is dragging\n\tel: null, // the clone of `sourceEl` that will track the mouse\n\tparentEl: null, // the element that `el` (the clone) will be attached to\n\n\t// the initial position of el, relative to the offset parent. made to match the initial offset of sourceEl\n\ttop0: null,\n\tleft0: null,\n\n\t// the initial position of the mouse\n\tmouseY0: null,\n\tmouseX0: null,\n\n\t// the number of pixels the mouse has moved from its initial position\n\ttopDelta: null,\n\tleftDelta: null,\n\n\tmousemoveProxy: null, // document mousemove handler, bound to the MouseFollower's `this`\n\n\tisFollowing: false,\n\tisHidden: false,\n\tisAnimating: false, // doing the revert animation?\n\n\tconstructor: function(sourceEl, options) {\n\t\tthis.options = options = options || {};\n\t\tthis.sourceEl = sourceEl;\n\t\tthis.parentEl = options.parentEl ? $(options.parentEl) : sourceEl.parent(); // default to sourceEl's parent\n\t},\n\n\n\t// Causes the element to start following the mouse\n\tstart: function(ev) {\n\t\tif (!this.isFollowing) {\n\t\t\tthis.isFollowing = true;\n\n\t\t\tthis.mouseY0 = ev.pageY;\n\t\t\tthis.mouseX0 = ev.pageX;\n\t\t\tthis.topDelta = 0;\n\t\t\tthis.leftDelta = 0;\n\n\t\t\tif (!this.isHidden) {\n\t\t\t\tthis.updatePosition();\n\t\t\t}\n\n\t\t\t$(document).on('mousemove', this.mousemoveProxy = proxy(this, 'mousemove'));\n\t\t}\n\t},\n\n\n\t// Causes the element to stop following the mouse. If shouldRevert is true, will animate back to original position.\n\t// `callback` gets invoked when the animation is complete. If no animation, it is invoked immediately.\n\tstop: function(shouldRevert, callback) {\n\t\tvar _this = this;\n\t\tvar revertDuration = this.options.revertDuration;\n\n\t\tfunction complete() {\n\t\t\tthis.isAnimating = false;\n\t\t\t_this.removeElement();\n\n\t\t\tthis.top0 = this.left0 = null; // reset state for future updatePosition calls\n\n\t\t\tif (callback) {\n\t\t\t\tcallback();\n\t\t\t}\n\t\t}\n\n\t\tif (this.isFollowing && !this.isAnimating) { // disallow more than one stop animation at a time\n\t\t\tthis.isFollowing = false;\n\n\t\t\t$(document).off('mousemove', this.mousemoveProxy);\n\n\t\t\tif (shouldRevert && revertDuration && !this.isHidden) { // do a revert animation?\n\t\t\t\tthis.isAnimating = true;\n\t\t\t\tthis.el.animate({\n\t\t\t\t\ttop: this.top0,\n\t\t\t\t\tleft: this.left0\n\t\t\t\t}, {\n\t\t\t\t\tduration: revertDuration,\n\t\t\t\t\tcomplete: complete\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\tcomplete();\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Gets the tracking element. Create it if necessary\n\tgetEl: function() {\n\t\tvar el = this.el;\n\n\t\tif (!el) {\n\t\t\tthis.sourceEl.width(); // hack to force IE8 to compute correct bounding box\n\t\t\tel = this.el = this.sourceEl.clone()\n\t\t\t\t.css({\n\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\tvisibility: '', // in case original element was hidden (commonly through hideEvents())\n\t\t\t\t\tdisplay: this.isHidden ? 'none' : '', // for when initially hidden\n\t\t\t\t\tmargin: 0,\n\t\t\t\t\tright: 'auto', // erase and set width instead\n\t\t\t\t\tbottom: 'auto', // erase and set height instead\n\t\t\t\t\twidth: this.sourceEl.width(), // explicit height in case there was a 'right' value\n\t\t\t\t\theight: this.sourceEl.height(), // explicit width in case there was a 'bottom' value\n\t\t\t\t\topacity: this.options.opacity || '',\n\t\t\t\t\tzIndex: this.options.zIndex\n\t\t\t\t})\n\t\t\t\t.appendTo(this.parentEl);\n\t\t}\n\n\t\treturn el;\n\t},\n\n\n\t// Removes the tracking element if it has already been created\n\tremoveElement: function() {\n\t\tif (this.el) {\n\t\t\tthis.el.remove();\n\t\t\tthis.el = null;\n\t\t}\n\t},\n\n\n\t// Update the CSS position of the tracking element\n\tupdatePosition: function() {\n\t\tvar sourceOffset;\n\t\tvar origin;\n\n\t\tthis.getEl(); // ensure this.el\n\n\t\t// make sure origin info was computed\n\t\tif (this.top0 === null) {\n\t\t\tthis.sourceEl.width(); // hack to force IE8 to compute correct bounding box\n\t\t\tsourceOffset = this.sourceEl.offset();\n\t\t\torigin = this.el.offsetParent().offset();\n\t\t\tthis.top0 = sourceOffset.top - origin.top;\n\t\t\tthis.left0 = sourceOffset.left - origin.left;\n\t\t}\n\n\t\tthis.el.css({\n\t\t\ttop: this.top0 + this.topDelta,\n\t\t\tleft: this.left0 + this.leftDelta\n\t\t});\n\t},\n\n\n\t// Gets called when the user moves the mouse\n\tmousemove: function(ev) {\n\t\tthis.topDelta = ev.pageY - this.mouseY0;\n\t\tthis.leftDelta = ev.pageX - this.mouseX0;\n\n\t\tif (!this.isHidden) {\n\t\t\tthis.updatePosition();\n\t\t}\n\t},\n\n\n\t// Temporarily makes the tracking element invisible. Can be called before following starts\n\thide: function() {\n\t\tif (!this.isHidden) {\n\t\t\tthis.isHidden = true;\n\t\t\tif (this.el) {\n\t\t\t\tthis.el.hide();\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Show the tracking element after it has been temporarily hidden\n\tshow: function() {\n\t\tif (this.isHidden) {\n\t\t\tthis.isHidden = false;\n\t\t\tthis.updatePosition();\n\t\t\tthis.getEl().show();\n\t\t}\n\t}\n\n});\n\n;;\n\n/* A utility class for rendering rows.\n----------------------------------------------------------------------------------------------------------------------*/\n// It leverages methods of the subclass and the View to determine custom rendering behavior for each row \"type\"\n// (such as highlight rows, day rows, helper rows, etc).\n\nvar RowRenderer = Class.extend({\n\n\tview: null, // a View object\n\tisRTL: null, // shortcut to the view's isRTL option\n\tcellHtml: '', // plain default HTML used for a cell when no other is available\n\n\n\tconstructor: function(view) {\n\t\tthis.view = view;\n\t\tthis.isRTL = view.opt('isRTL');\n\t},\n\n\n\t// Renders the HTML for a row, leveraging custom cell-HTML-renderers based on the `rowType`.\n\t// Also applies the \"intro\" and \"outro\" cells, which are specified by the subclass and views.\n\t// `row` is an optional row number.\n\trowHtml: function(rowType, row) {\n\t\tvar renderCell = this.getHtmlRenderer('cell', rowType);\n\t\tvar rowCellHtml = '';\n\t\tvar col;\n\t\tvar cell;\n\n\t\trow = row || 0;\n\n\t\tfor (col = 0; col < this.colCnt; col++) {\n\t\t\tcell = this.getCell(row, col);\n\t\t\trowCellHtml += renderCell(cell);\n\t\t}\n\n\t\trowCellHtml = this.bookendCells(rowCellHtml, rowType, row); // apply intro and outro\n\n\t\treturn '' + rowCellHtml + '';\n\t},\n\n\n\t// Applies the \"intro\" and \"outro\" HTML to the given cells.\n\t// Intro means the leftmost cell when the calendar is LTR and the rightmost cell when RTL. Vice-versa for outro.\n\t// `cells` can be an HTML string of 's or a jQuery element\n\t// `row` is an optional row number.\n\tbookendCells: function(cells, rowType, row) {\n\t\tvar intro = this.getHtmlRenderer('intro', rowType)(row || 0);\n\t\tvar outro = this.getHtmlRenderer('outro', rowType)(row || 0);\n\t\tvar prependHtml = this.isRTL ? outro : intro;\n\t\tvar appendHtml = this.isRTL ? intro : outro;\n\n\t\tif (typeof cells === 'string') {\n\t\t\treturn prependHtml + cells + appendHtml;\n\t\t}\n\t\telse { // a jQuery element\n\t\t\treturn cells.prepend(prependHtml).append(appendHtml);\n\t\t}\n\t},\n\n\n\t// Returns an HTML-rendering function given a specific `rendererName` (like cell, intro, or outro) and a specific\n\t// `rowType` (like day, eventSkeleton, helperSkeleton), which is optional.\n\t// If a renderer for the specific rowType doesn't exist, it will fall back to a generic renderer.\n\t// We will query the View object first for any custom rendering functions, then the methods of the subclass.\n\tgetHtmlRenderer: function(rendererName, rowType) {\n\t\tvar view = this.view;\n\t\tvar generalName; // like \"cellHtml\"\n\t\tvar specificName; // like \"dayCellHtml\". based on rowType\n\t\tvar provider; // either the View or the RowRenderer subclass, whichever provided the method\n\t\tvar renderer;\n\n\t\tgeneralName = rendererName + 'Html';\n\t\tif (rowType) {\n\t\t\tspecificName = rowType + capitaliseFirstLetter(rendererName) + 'Html';\n\t\t}\n\n\t\tif (specificName && (renderer = view[specificName])) {\n\t\t\tprovider = view;\n\t\t}\n\t\telse if (specificName && (renderer = this[specificName])) {\n\t\t\tprovider = this;\n\t\t}\n\t\telse if ((renderer = view[generalName])) {\n\t\t\tprovider = view;\n\t\t}\n\t\telse if ((renderer = this[generalName])) {\n\t\t\tprovider = this;\n\t\t}\n\n\t\tif (typeof renderer === 'function') {\n\t\t\treturn function() {\n\t\t\t\treturn renderer.apply(provider, arguments) || ''; // use correct `this` and always return a string\n\t\t\t};\n\t\t}\n\n\t\t// the rendered can be a plain string as well. if not specified, always an empty string.\n\t\treturn function() {\n\t\t\treturn renderer || '';\n\t\t};\n\t}\n\n});\n\n;;\n\n/* An abstract class comprised of a \"grid\" of cells that each represent a specific datetime\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar Grid = fc.Grid = RowRenderer.extend({\n\n\tstart: null, // the date of the first cell\n\tend: null, // the date after the last cell\n\n\trowCnt: 0, // number of rows\n\tcolCnt: 0, // number of cols\n\n\tel: null, // the containing element\n\tcoordMap: null, // a GridCoordMap that converts pixel values to datetimes\n\telsByFill: null, // a hash of jQuery element sets used for rendering each fill. Keyed by fill name.\n\n\texternalDragStartProxy: null, // binds the Grid's scope to externalDragStart (in DayGrid.events)\n\n\t// derived from options\n\tcolHeadFormat: null, // TODO: move to another class. not applicable to all Grids\n\teventTimeFormat: null,\n\tdisplayEventTime: null,\n\tdisplayEventEnd: null,\n\n\t// if all cells are the same length of time, the duration they all share. optional.\n\t// when defined, allows the computeCellRange shortcut, as well as improved resizing behavior.\n\tcellDuration: null,\n\n\t// if defined, holds the unit identified (ex: \"year\" or \"month\") that determines the level of granularity\n\t// of the date cells. if not defined, assumes to be day and time granularity.\n\tlargeUnit: null,\n\n\n\tconstructor: function() {\n\t\tRowRenderer.apply(this, arguments); // call the super-constructor\n\n\t\tthis.coordMap = new GridCoordMap(this);\n\t\tthis.elsByFill = {};\n\t\tthis.externalDragStartProxy = proxy(this, 'externalDragStart');\n\t},\n\n\n\t/* Options\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Generates the format string used for the text in column headers, if not explicitly defined by 'columnFormat'\n\t// TODO: move to another class. not applicable to all Grids\n\tcomputeColHeadFormat: function() {\n\t\t// subclasses must implement if they want to use headHtml()\n\t},\n\n\n\t// Generates the format string used for event time text, if not explicitly defined by 'timeFormat'\n\tcomputeEventTimeFormat: function() {\n\t\treturn this.view.opt('smallTimeFormat');\n\t},\n\n\n\t// Determines whether events should have their end times displayed, if not explicitly defined by 'displayEventTime'.\n\t// Only applies to non-all-day events.\n\tcomputeDisplayEventTime: function() {\n\t\treturn true;\n\t},\n\n\n\t// Determines whether events should have their end times displayed, if not explicitly defined by 'displayEventEnd'\n\tcomputeDisplayEventEnd: function() {\n\t\treturn true;\n\t},\n\n\n\t/* Dates\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Tells the grid about what period of time to display.\n\t// Any date-related cell system internal data should be generated.\n\tsetRange: function(range) {\n\t\tthis.start = range.start.clone();\n\t\tthis.end = range.end.clone();\n\n\t\tthis.rangeUpdated();\n\t\tthis.processRangeOptions();\n\t},\n\n\n\t// Called when internal variables that rely on the range should be updated\n\trangeUpdated: function() {\n\t},\n\n\n\t// Updates values that rely on options and also relate to range\n\tprocessRangeOptions: function() {\n\t\tvar view = this.view;\n\t\tvar displayEventTime;\n\t\tvar displayEventEnd;\n\n\t\t// Populate option-derived settings. Look for override first, then compute if necessary.\n\t\tthis.colHeadFormat = view.opt('columnFormat') || this.computeColHeadFormat();\n\n\t\tthis.eventTimeFormat =\n\t\t\tview.opt('eventTimeFormat') ||\n\t\t\tview.opt('timeFormat') || // deprecated\n\t\t\tthis.computeEventTimeFormat();\n\n\t\tdisplayEventTime = view.opt('displayEventTime');\n\t\tif (displayEventTime == null) {\n\t\t\tdisplayEventTime = this.computeDisplayEventTime(); // might be based off of range\n\t\t}\n\n\t\tdisplayEventEnd = view.opt('displayEventEnd');\n\t\tif (displayEventEnd == null) {\n\t\t\tdisplayEventEnd = this.computeDisplayEventEnd(); // might be based off of range\n\t\t}\n\n\t\tthis.displayEventTime = displayEventTime;\n\t\tthis.displayEventEnd = displayEventEnd;\n\t},\n\n\n\t// Called before the grid's coordinates will need to be queried for cells.\n\t// Any non-date-related cell system internal data should be built.\n\tbuild: function() {\n\t},\n\n\n\t// Called after the grid's coordinates are done being relied upon.\n\t// Any non-date-related cell system internal data should be cleared.\n\tclear: function() {\n\t},\n\n\n\t// Converts a range with an inclusive `start` and an exclusive `end` into an array of segment objects\n\trangeToSegs: function(range) {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Diffs the two dates, returning a duration, based on granularity of the grid\n\tdiffDates: function(a, b) {\n\t\tif (this.largeUnit) {\n\t\t\treturn diffByUnit(a, b, this.largeUnit);\n\t\t}\n\t\telse {\n\t\t\treturn diffDayTime(a, b);\n\t\t}\n\t},\n\n\n\t/* Cells\n\t------------------------------------------------------------------------------------------------------------------*/\n\t// NOTE: columns are ordered left-to-right\n\n\n\t// Gets an object containing row/col number, misc data, and range information about the cell.\n\t// Accepts row/col values, an object with row/col properties, or a single-number offset from the first cell.\n\tgetCell: function(row, col) {\n\t\tvar cell;\n\n\t\tif (col == null) {\n\t\t\tif (typeof row === 'number') { // a single-number offset\n\t\t\t\tcol = row % this.colCnt;\n\t\t\t\trow = Math.floor(row / this.colCnt);\n\t\t\t}\n\t\t\telse { // an object with row/col properties\n\t\t\t\tcol = row.col;\n\t\t\t\trow = row.row;\n\t\t\t}\n\t\t}\n\n\t\tcell = { row: row, col: col };\n\n\t\t$.extend(cell, this.getRowData(row), this.getColData(col));\n\t\t$.extend(cell, this.computeCellRange(cell));\n\n\t\treturn cell;\n\t},\n\n\n\t// Given a cell object with index and misc data, generates a range object\n\t// If the grid is leveraging cellDuration, this doesn't need to be defined. Only computeCellDate does.\n\t// If being overridden, should return a range with reference-free date copies.\n\tcomputeCellRange: function(cell) {\n\t\tvar date = this.computeCellDate(cell);\n\n\t\treturn {\n\t\t\tstart: date,\n\t\t\tend: date.clone().add(this.cellDuration)\n\t\t};\n\t},\n\n\n\t// Given a cell, returns its start date. Should return a reference-free date copy.\n\tcomputeCellDate: function(cell) {\n\t\t// subclasses can implement\n\t},\n\n\n\t// Retrieves misc data about the given row\n\tgetRowData: function(row) {\n\t\treturn {};\n\t},\n\n\n\t// Retrieves misc data baout the given column\n\tgetColData: function(col) {\n\t\treturn {};\n\t},\n\n\n\t// Retrieves the element representing the given row\n\tgetRowEl: function(row) {\n\t\t// subclasses should implement if leveraging the default getCellDayEl() or computeRowCoords()\n\t},\n\n\n\t// Retrieves the element representing the given column\n\tgetColEl: function(col) {\n\t\t// subclasses should implement if leveraging the default getCellDayEl() or computeColCoords()\n\t},\n\n\n\t// Given a cell object, returns the element that represents the cell's whole-day\n\tgetCellDayEl: function(cell) {\n\t\treturn this.getColEl(cell.col) || this.getRowEl(cell.row);\n\t},\n\n\n\t/* Cell Coordinates\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Computes the top/bottom coordinates of all rows.\n\t// By default, queries the dimensions of the element provided by getRowEl().\n\tcomputeRowCoords: function() {\n\t\tvar items = [];\n\t\tvar i, el;\n\t\tvar top;\n\n\t\tfor (i = 0; i < this.rowCnt; i++) {\n\t\t\tel = this.getRowEl(i);\n\t\t\ttop = el.offset().top;\n\t\t\titems.push({\n\t\t\t\ttop: top,\n\t\t\t\tbottom: top + el.outerHeight()\n\t\t\t});\n\t\t}\n\n\t\treturn items;\n\t},\n\n\n\t// Computes the left/right coordinates of all rows.\n\t// By default, queries the dimensions of the element provided by getColEl(). Columns can be LTR or RTL.\n\tcomputeColCoords: function() {\n\t\tvar items = [];\n\t\tvar i, el;\n\t\tvar left;\n\n\t\tfor (i = 0; i < this.colCnt; i++) {\n\t\t\tel = this.getColEl(i);\n\t\t\tleft = el.offset().left;\n\t\t\titems.push({\n\t\t\t\tleft: left,\n\t\t\t\tright: left + el.outerWidth()\n\t\t\t});\n\t\t}\n\n\t\treturn items;\n\t},\n\n\n\t/* Rendering\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Sets the container element that the grid should render inside of.\n\t// Does other DOM-related initializations.\n\tsetElement: function(el) {\n\t\tvar _this = this;\n\n\t\tthis.el = el;\n\n\t\t// attach a handler to the grid's root element.\n\t\t// jQuery will take care of unregistering them when removeElement gets called.\n\t\tel.on('mousedown', function(ev) {\n\t\t\tif (\n\t\t\t\t!$(ev.target).is('.fc-event-container *, .fc-more') && // not an an event element, or \"more..\" link\n\t\t\t\t!$(ev.target).closest('.fc-popover').length // not on a popover (like the \"more..\" events one)\n\t\t\t) {\n\t\t\t\t_this.dayMousedown(ev);\n\t\t\t}\n\t\t});\n\n\t\t// attach event-element-related handlers. in Grid.events\n\t\t// same garbage collection note as above.\n\t\tthis.bindSegHandlers();\n\n\t\tthis.bindGlobalHandlers();\n\t},\n\n\n\t// Removes the grid's container element from the DOM. Undoes any other DOM-related attachments.\n\t// DOES NOT remove any content beforehand (doesn't clear events or call unrenderDates), unlike View\n\tremoveElement: function() {\n\t\tthis.unbindGlobalHandlers();\n\n\t\tthis.el.remove();\n\n\t\t// NOTE: we don't null-out this.el for the same reasons we don't do it within View::removeElement\n\t},\n\n\n\t// Renders the basic structure of grid view before any content is rendered\n\trenderSkeleton: function() {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Renders the grid's date-related content (like cells that represent days/times).\n\t// Assumes setRange has already been called and the skeleton has already been rendered.\n\trenderDates: function() {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Unrenders the grid's date-related content\n\tunrenderDates: function() {\n\t\t// subclasses should implement\n\t},\n\n\n\t/* Handlers\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Binds DOM handlers to elements that reside outside the grid, such as the document\n\tbindGlobalHandlers: function() {\n\t\t$(document).on('dragstart sortstart', this.externalDragStartProxy); // jqui\n\t},\n\n\n\t// Unbinds DOM handlers from elements that reside outside the grid\n\tunbindGlobalHandlers: function() {\n\t\t$(document).off('dragstart sortstart', this.externalDragStartProxy); // jqui\n\t},\n\n\n\t// Process a mousedown on an element that represents a day. For day clicking and selecting.\n\tdayMousedown: function(ev) {\n\t\tvar _this = this;\n\t\tvar view = this.view;\n\t\tvar isSelectable = view.opt('selectable');\n\t\tvar dayClickCell; // null if invalid dayClick\n\t\tvar selectionRange; // null if invalid selection\n\n\t\t// this listener tracks a mousedown on a day element, and a subsequent drag.\n\t\t// if the drag ends on the same day, it is a 'dayClick'.\n\t\t// if 'selectable' is enabled, this listener also detects selections.\n\t\tvar dragListener = new CellDragListener(this.coordMap, {\n\t\t\t//distance: 5, // needs more work if we want dayClick to fire correctly\n\t\t\tscroll: view.opt('dragScroll'),\n\t\t\tdragStart: function() {\n\t\t\t\tview.unselect(); // since we could be rendering a new selection, we want to clear any old one\n\t\t\t},\n\t\t\tcellOver: function(cell, isOrig, origCell) {\n\t\t\t\tif (origCell) { // click needs to have started on a cell\n\t\t\t\t\tdayClickCell = isOrig ? cell : null; // single-cell selection is a day click\n\t\t\t\t\tif (isSelectable) {\n\t\t\t\t\t\tselectionRange = _this.computeSelection(origCell, cell);\n\t\t\t\t\t\tif (selectionRange) {\n\t\t\t\t\t\t\t_this.renderSelection(selectionRange);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tdisableCursor();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tcellOut: function(cell) {\n\t\t\t\tdayClickCell = null;\n\t\t\t\tselectionRange = null;\n\t\t\t\t_this.unrenderSelection();\n\t\t\t\tenableCursor();\n\t\t\t},\n\t\t\tlistenStop: function(ev) {\n\t\t\t\tif (dayClickCell) {\n\t\t\t\t\tview.triggerDayClick(dayClickCell, _this.getCellDayEl(dayClickCell), ev);\n\t\t\t\t}\n\t\t\t\tif (selectionRange) {\n\t\t\t\t\t// the selection will already have been rendered. just report it\n\t\t\t\t\tview.reportSelection(selectionRange, ev);\n\t\t\t\t}\n\t\t\t\tenableCursor();\n\t\t\t}\n\t\t});\n\n\t\tdragListener.mousedown(ev); // start listening, which will eventually initiate a dragStart\n\t},\n\n\n\t/* Event Helper\n\t------------------------------------------------------------------------------------------------------------------*/\n\t// TODO: should probably move this to Grid.events, like we did event dragging / resizing\n\n\n\t// Renders a mock event over the given range\n\trenderRangeHelper: function(range, sourceSeg) {\n\t\tvar fakeEvent = this.fabricateHelperEvent(range, sourceSeg);\n\n\t\tthis.renderHelper(fakeEvent, sourceSeg); // do the actual rendering\n\t},\n\n\n\t// Builds a fake event given a date range it should cover, and a segment is should be inspired from.\n\t// The range's end can be null, in which case the mock event that is rendered will have a null end time.\n\t// `sourceSeg` is the internal segment object involved in the drag. If null, something external is dragging.\n\tfabricateHelperEvent: function(range, sourceSeg) {\n\t\tvar fakeEvent = sourceSeg ? createObject(sourceSeg.event) : {}; // mask the original event object if possible\n\n\t\tfakeEvent.start = range.start.clone();\n\t\tfakeEvent.end = range.end ? range.end.clone() : null;\n\t\tfakeEvent.allDay = null; // force it to be freshly computed by normalizeEventRange\n\t\tthis.view.calendar.normalizeEventRange(fakeEvent);\n\n\t\t// this extra className will be useful for differentiating real events from mock events in CSS\n\t\tfakeEvent.className = (fakeEvent.className || []).concat('fc-helper');\n\n\t\t// if something external is being dragged in, don't render a resizer\n\t\tif (!sourceSeg) {\n\t\t\tfakeEvent.editable = false;\n\t\t}\n\n\t\treturn fakeEvent;\n\t},\n\n\n\t// Renders a mock event\n\trenderHelper: function(event, sourceSeg) {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Unrenders a mock event\n\tunrenderHelper: function() {\n\t\t// subclasses must implement\n\t},\n\n\n\t/* Selection\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of a selection. Will highlight by default but can be overridden by subclasses.\n\trenderSelection: function(range) {\n\t\tthis.renderHighlight(this.selectionRangeToSegs(range));\n\t},\n\n\n\t// Unrenders any visual indications of a selection. Will unrender a highlight by default.\n\tunrenderSelection: function() {\n\t\tthis.unrenderHighlight();\n\t},\n\n\n\t// Given the first and last cells of a selection, returns a range object.\n\t// Will return something falsy if the selection is invalid (when outside of selectionConstraint for example).\n\t// Subclasses can override and provide additional data in the range object. Will be passed to renderSelection().\n\tcomputeSelection: function(firstCell, lastCell) {\n\t\tvar dates = [\n\t\t\tfirstCell.start,\n\t\t\tfirstCell.end,\n\t\t\tlastCell.start,\n\t\t\tlastCell.end\n\t\t];\n\t\tvar range;\n\n\t\tdates.sort(compareNumbers); // sorts chronologically. works with Moments\n\n\t\trange = {\n\t\t\tstart: dates[0].clone(),\n\t\t\tend: dates[3].clone()\n\t\t};\n\n\t\tif (!this.view.calendar.isSelectionRangeAllowed(range)) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn range;\n\t},\n\n\n\tselectionRangeToSegs: function(range) {\n\t\treturn this.rangeToSegs(range);\n\t},\n\n\n\t/* Highlight\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders an emphasis on the given date range. Given an array of segments.\n\trenderHighlight: function(segs) {\n\t\tthis.renderFill('highlight', segs);\n\t},\n\n\n\t// Unrenders the emphasis on a date range\n\tunrenderHighlight: function() {\n\t\tthis.unrenderFill('highlight');\n\t},\n\n\n\t// Generates an array of classNames for rendering the highlight. Used by the fill system.\n\thighlightSegClasses: function() {\n\t\treturn [ 'fc-highlight' ];\n\t},\n\n\n\t/* Fill System (highlight, background events, business hours)\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a set of rectangles over the given segments of time.\n\t// MUST RETURN a subset of segs, the segs that were actually rendered.\n\t// Responsible for populating this.elsByFill. TODO: better API for expressing this requirement\n\trenderFill: function(type, segs) {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Unrenders a specific type of fill that is currently rendered on the grid\n\tunrenderFill: function(type) {\n\t\tvar el = this.elsByFill[type];\n\n\t\tif (el) {\n\t\t\tel.remove();\n\t\t\tdelete this.elsByFill[type];\n\t\t}\n\t},\n\n\n\t// Renders and assigns an `el` property for each fill segment. Generic enough to work with different types.\n\t// Only returns segments that successfully rendered.\n\t// To be harnessed by renderFill (implemented by subclasses).\n\t// Analagous to renderFgSegEls.\n\trenderFillSegEls: function(type, segs) {\n\t\tvar _this = this;\n\t\tvar segElMethod = this[type + 'SegEl'];\n\t\tvar html = '';\n\t\tvar renderedSegs = [];\n\t\tvar i;\n\n\t\tif (segs.length) {\n\n\t\t\t// build a large concatenation of segment HTML\n\t\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\t\thtml += this.fillSegHtml(type, segs[i]);\n\t\t\t}\n\n\t\t\t// Grab individual elements from the combined HTML string. Use each as the default rendering.\n\t\t\t// Then, compute the 'el' for each segment.\n\t\t\t$(html).each(function(i, node) {\n\t\t\t\tvar seg = segs[i];\n\t\t\t\tvar el = $(node);\n\n\t\t\t\t// allow custom filter methods per-type\n\t\t\t\tif (segElMethod) {\n\t\t\t\t\tel = segElMethod.call(_this, seg, el);\n\t\t\t\t}\n\n\t\t\t\tif (el) { // custom filters did not cancel the render\n\t\t\t\t\tel = $(el); // allow custom filter to return raw DOM node\n\n\t\t\t\t\t// correct element type? (would be bad if a non-TD were inserted into a table for example)\n\t\t\t\t\tif (el.is(_this.fillSegTag)) {\n\t\t\t\t\t\tseg.el = el;\n\t\t\t\t\t\trenderedSegs.push(seg);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn renderedSegs;\n\t},\n\n\n\tfillSegTag: 'div', // subclasses can override\n\n\n\t// Builds the HTML needed for one fill segment. Generic enought o work with different types.\n\tfillSegHtml: function(type, seg) {\n\n\t\t// custom hooks per-type\n\t\tvar classesMethod = this[type + 'SegClasses'];\n\t\tvar cssMethod = this[type + 'SegCss'];\n\n\t\tvar classes = classesMethod ? classesMethod.call(this, seg) : [];\n\t\tvar css = cssToStr(cssMethod ? cssMethod.call(this, seg) : {});\n\n\t\treturn '<' + this.fillSegTag +\n\t\t\t(classes.length ? ' class=\"' + classes.join(' ') + '\"' : '') +\n\t\t\t(css ? ' style=\"' + css + '\"' : '') +\n\t\t\t' />';\n\t},\n\n\n\t/* Generic rendering utilities for subclasses\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a day-of-week header row.\n\t// TODO: move to another class. not applicable to all Grids\n\theadHtml: function() {\n\t\treturn '' +\n\t\t\t'
' +\n\t\t\t\t'' +\n\t\t\t\t\t'' +\n\t\t\t\t\t\tthis.rowHtml('head') + // leverages RowRenderer\n\t\t\t\t\t'' +\n\t\t\t\t'
' +\n\t\t\t'
';\n\t},\n\n\n\t// Used by the `headHtml` method, via RowRenderer, for rendering the HTML of a day-of-week header cell\n\t// TODO: move to another class. not applicable to all Grids\n\theadCellHtml: function(cell) {\n\t\tvar view = this.view;\n\t\tvar date = cell.start;\n\n\t\treturn '' +\n\t\t\t'' +\n\t\t\t\thtmlEscape(date.format(this.colHeadFormat)) +\n\t\t\t'';\n\t},\n\n\n\t// Renders the HTML for a single-day background cell\n\tbgCellHtml: function(cell) {\n\t\tvar view = this.view;\n\t\tvar date = cell.start;\n\t\tvar classes = this.getDayClasses(date);\n\n\t\tclasses.unshift('fc-day', view.widgetContentClass);\n\n\t\treturn '';\n\t},\n\n\n\t// Computes HTML classNames for a single-day cell\n\tgetDayClasses: function(date) {\n\t\tvar view = this.view;\n\t\tvar today = view.calendar.getNow().stripTime();\n\t\tvar classes = [ 'fc-' + dayIDs[date.day()] ];\n\n\t\tif (\n\t\t\tview.intervalDuration.as('months') == 1 &&\n\t\t\tdate.month() != view.intervalStart.month()\n\t\t) {\n\t\t\tclasses.push('fc-other-month');\n\t\t}\n\n\t\tif (date.isSame(today, 'day')) {\n\t\t\tclasses.push(\n\t\t\t\t'fc-today',\n\t\t\t\tview.highlightStateClass\n\t\t\t);\n\t\t}\n\t\telse if (date < today) {\n\t\t\tclasses.push('fc-past');\n\t\t}\n\t\telse {\n\t\t\tclasses.push('fc-future');\n\t\t}\n\n\t\treturn classes;\n\t}\n\n});\n\n;;\n\n/* Event-rendering and event-interaction methods for the abstract Grid class\n----------------------------------------------------------------------------------------------------------------------*/\n\nGrid.mixin({\n\n\tmousedOverSeg: null, // the segment object the user's mouse is over. null if over nothing\n\tisDraggingSeg: false, // is a segment being dragged? boolean\n\tisResizingSeg: false, // is a segment being resized? boolean\n\tisDraggingExternal: false, // jqui-dragging an external element? boolean\n\tsegs: null, // the event segments currently rendered in the grid\n\n\n\t// Renders the given events onto the grid\n\trenderEvents: function(events) {\n\t\tvar segs = this.eventsToSegs(events);\n\t\tvar bgSegs = [];\n\t\tvar fgSegs = [];\n\t\tvar i, seg;\n\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tseg = segs[i];\n\n\t\t\tif (isBgEvent(seg.event)) {\n\t\t\t\tbgSegs.push(seg);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tfgSegs.push(seg);\n\t\t\t}\n\t\t}\n\n\t\t// Render each different type of segment.\n\t\t// Each function may return a subset of the segs, segs that were actually rendered.\n\t\tbgSegs = this.renderBgSegs(bgSegs) || bgSegs;\n\t\tfgSegs = this.renderFgSegs(fgSegs) || fgSegs;\n\n\t\tthis.segs = bgSegs.concat(fgSegs);\n\t},\n\n\n\t// Unrenders all events currently rendered on the grid\n\tunrenderEvents: function() {\n\t\tthis.triggerSegMouseout(); // trigger an eventMouseout if user's mouse is over an event\n\n\t\tthis.unrenderFgSegs();\n\t\tthis.unrenderBgSegs();\n\n\t\tthis.segs = null;\n\t},\n\n\n\t// Retrieves all rendered segment objects currently rendered on the grid\n\tgetEventSegs: function() {\n\t\treturn this.segs || [];\n\t},\n\n\n\t/* Foreground Segment Rendering\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders foreground event segments onto the grid. May return a subset of segs that were rendered.\n\trenderFgSegs: function(segs) {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Unrenders all currently rendered foreground segments\n\tunrenderFgSegs: function() {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Renders and assigns an `el` property for each foreground event segment.\n\t// Only returns segments that successfully rendered.\n\t// A utility that subclasses may use.\n\trenderFgSegEls: function(segs, disableResizing) {\n\t\tvar view = this.view;\n\t\tvar html = '';\n\t\tvar renderedSegs = [];\n\t\tvar i;\n\n\t\tif (segs.length) { // don't build an empty html string\n\n\t\t\t// build a large concatenation of event segment HTML\n\t\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\t\thtml += this.fgSegHtml(segs[i], disableResizing);\n\t\t\t}\n\n\t\t\t// Grab individual elements from the combined HTML string. Use each as the default rendering.\n\t\t\t// Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false.\n\t\t\t$(html).each(function(i, node) {\n\t\t\t\tvar seg = segs[i];\n\t\t\t\tvar el = view.resolveEventEl(seg.event, $(node));\n\n\t\t\t\tif (el) {\n\t\t\t\t\tel.data('fc-seg', seg); // used by handlers\n\t\t\t\t\tseg.el = el;\n\t\t\t\t\trenderedSegs.push(seg);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn renderedSegs;\n\t},\n\n\n\t// Generates the HTML for the default rendering of a foreground event segment. Used by renderFgSegEls()\n\tfgSegHtml: function(seg, disableResizing) {\n\t\t// subclasses should implement\n\t},\n\n\n\t/* Background Segment Rendering\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders the given background event segments onto the grid.\n\t// Returns a subset of the segs that were actually rendered.\n\trenderBgSegs: function(segs) {\n\t\treturn this.renderFill('bgEvent', segs);\n\t},\n\n\n\t// Unrenders all the currently rendered background event segments\n\tunrenderBgSegs: function() {\n\t\tthis.unrenderFill('bgEvent');\n\t},\n\n\n\t// Renders a background event element, given the default rendering. Called by the fill system.\n\tbgEventSegEl: function(seg, el) {\n\t\treturn this.view.resolveEventEl(seg.event, el); // will filter through eventRender\n\t},\n\n\n\t// Generates an array of classNames to be used for the default rendering of a background event.\n\t// Called by the fill system.\n\tbgEventSegClasses: function(seg) {\n\t\tvar event = seg.event;\n\t\tvar source = event.source || {};\n\n\t\treturn [ 'fc-bgevent' ].concat(\n\t\t\tevent.className,\n\t\t\tsource.className || []\n\t\t);\n\t},\n\n\n\t// Generates a semicolon-separated CSS string to be used for the default rendering of a background event.\n\t// Called by the fill system.\n\t// TODO: consolidate with getEventSkinCss?\n\tbgEventSegCss: function(seg) {\n\t\tvar view = this.view;\n\t\tvar event = seg.event;\n\t\tvar source = event.source || {};\n\n\t\treturn {\n\t\t\t'background-color':\n\t\t\t\tevent.backgroundColor ||\n\t\t\t\tevent.color ||\n\t\t\t\tsource.backgroundColor ||\n\t\t\t\tsource.color ||\n\t\t\t\tview.opt('eventBackgroundColor') ||\n\t\t\t\tview.opt('eventColor')\n\t\t};\n\t},\n\n\n\t// Generates an array of classNames to be used for the rendering business hours overlay. Called by the fill system.\n\tbusinessHoursSegClasses: function(seg) {\n\t\treturn [ 'fc-nonbusiness', 'fc-bgevent' ];\n\t},\n\n\n\t/* Handlers\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Attaches event-element-related handlers to the container element and leverage bubbling\n\tbindSegHandlers: function() {\n\t\tvar _this = this;\n\t\tvar view = this.view;\n\n\t\t$.each(\n\t\t\t{\n\t\t\t\tmouseenter: function(seg, ev) {\n\t\t\t\t\t_this.triggerSegMouseover(seg, ev);\n\t\t\t\t},\n\t\t\t\tmouseleave: function(seg, ev) {\n\t\t\t\t\t_this.triggerSegMouseout(seg, ev);\n\t\t\t\t},\n\t\t\t\tclick: function(seg, ev) {\n\t\t\t\t\treturn view.trigger('eventClick', this, seg.event, ev); // can return `false` to cancel\n\t\t\t\t},\n\t\t\t\tmousedown: function(seg, ev) {\n\t\t\t\t\tif ($(ev.target).is('.fc-resizer') && view.isEventResizable(seg.event)) {\n\t\t\t\t\t\t_this.segResizeMousedown(seg, ev, $(ev.target).is('.fc-start-resizer'));\n\t\t\t\t\t}\n\t\t\t\t\telse if (view.isEventDraggable(seg.event)) {\n\t\t\t\t\t\t_this.segDragMousedown(seg, ev);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tfunction(name, func) {\n\t\t\t\t// attach the handler to the container element and only listen for real event elements via bubbling\n\t\t\t\t_this.el.on(name, '.fc-event-container > *', function(ev) {\n\t\t\t\t\tvar seg = $(this).data('fc-seg'); // grab segment data. put there by View::renderEvents\n\n\t\t\t\t\t// only call the handlers if there is not a drag/resize in progress\n\t\t\t\t\tif (seg && !_this.isDraggingSeg && !_this.isResizingSeg) {\n\t\t\t\t\t\treturn func.call(this, seg, ev); // `this` will be the event element\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t);\n\t},\n\n\n\t// Updates internal state and triggers handlers for when an event element is moused over\n\ttriggerSegMouseover: function(seg, ev) {\n\t\tif (!this.mousedOverSeg) {\n\t\t\tthis.mousedOverSeg = seg;\n\t\t\tthis.view.trigger('eventMouseover', seg.el[0], seg.event, ev);\n\t\t}\n\t},\n\n\n\t// Updates internal state and triggers handlers for when an event element is moused out.\n\t// Can be given no arguments, in which case it will mouseout the segment that was previously moused over.\n\ttriggerSegMouseout: function(seg, ev) {\n\t\tev = ev || {}; // if given no args, make a mock mouse event\n\n\t\tif (this.mousedOverSeg) {\n\t\t\tseg = seg || this.mousedOverSeg; // if given no args, use the currently moused-over segment\n\t\t\tthis.mousedOverSeg = null;\n\t\t\tthis.view.trigger('eventMouseout', seg.el[0], seg.event, ev);\n\t\t}\n\t},\n\n\n\t/* Event Dragging\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Called when the user does a mousedown on an event, which might lead to dragging.\n\t// Generic enough to work with any type of Grid.\n\tsegDragMousedown: function(seg, ev) {\n\t\tvar _this = this;\n\t\tvar view = this.view;\n\t\tvar calendar = view.calendar;\n\t\tvar el = seg.el;\n\t\tvar event = seg.event;\n\t\tvar dropLocation;\n\n\t\t// A clone of the original element that will move with the mouse\n\t\tvar mouseFollower = new MouseFollower(seg.el, {\n\t\t\tparentEl: view.el,\n\t\t\topacity: view.opt('dragOpacity'),\n\t\t\trevertDuration: view.opt('dragRevertDuration'),\n\t\t\tzIndex: 2 // one above the .fc-view\n\t\t});\n\n\t\t// Tracks mouse movement over the *view's* coordinate map. Allows dragging and dropping between subcomponents\n\t\t// of the view.\n\t\tvar dragListener = new CellDragListener(view.coordMap, {\n\t\t\tdistance: 5,\n\t\t\tscroll: view.opt('dragScroll'),\n\t\t\tsubjectEl: el,\n\t\t\tsubjectCenter: true,\n\t\t\tlistenStart: function(ev) {\n\t\t\t\tmouseFollower.hide(); // don't show until we know this is a real drag\n\t\t\t\tmouseFollower.start(ev);\n\t\t\t},\n\t\t\tdragStart: function(ev) {\n\t\t\t\t_this.triggerSegMouseout(seg, ev); // ensure a mouseout on the manipulated event has been reported\n\t\t\t\t_this.segDragStart(seg, ev);\n\t\t\t\tview.hideEvent(event); // hide all event segments. our mouseFollower will take over\n\t\t\t},\n\t\t\tcellOver: function(cell, isOrig, origCell) {\n\n\t\t\t\t// starting cell could be forced (DayGrid.limit)\n\t\t\t\tif (seg.cell) {\n\t\t\t\t\torigCell = seg.cell;\n\t\t\t\t}\n\n\t\t\t\tdropLocation = _this.computeEventDrop(origCell, cell, event);\n\n\t\t\t\tif (dropLocation && !calendar.isEventRangeAllowed(dropLocation, event)) {\n\t\t\t\t\tdisableCursor();\n\t\t\t\t\tdropLocation = null;\n\t\t\t\t}\n\n\t\t\t\t// if a valid drop location, have the subclass render a visual indication\n\t\t\t\tif (dropLocation && view.renderDrag(dropLocation, seg)) {\n\t\t\t\t\tmouseFollower.hide(); // if the subclass is already using a mock event \"helper\", hide our own\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tmouseFollower.show(); // otherwise, have the helper follow the mouse (no snapping)\n\t\t\t\t}\n\n\t\t\t\tif (isOrig) {\n\t\t\t\t\tdropLocation = null; // needs to have moved cells to be a valid drop\n\t\t\t\t}\n\t\t\t},\n\t\t\tcellOut: function() { // called before mouse moves to a different cell OR moved out of all cells\n\t\t\t\tview.unrenderDrag(); // unrender whatever was done in renderDrag\n\t\t\t\tmouseFollower.show(); // show in case we are moving out of all cells\n\t\t\t\tdropLocation = null;\n\t\t\t},\n\t\t\tcellDone: function() { // Called after a cellOut OR before a dragStop\n\t\t\t\tenableCursor();\n\t\t\t},\n\t\t\tdragStop: function(ev) {\n\t\t\t\t// do revert animation if hasn't changed. calls a callback when finished (whether animation or not)\n\t\t\t\tmouseFollower.stop(!dropLocation, function() {\n\t\t\t\t\tview.unrenderDrag();\n\t\t\t\t\tview.showEvent(event);\n\t\t\t\t\t_this.segDragStop(seg, ev);\n\n\t\t\t\t\tif (dropLocation) {\n\t\t\t\t\t\tview.reportEventDrop(event, dropLocation, this.largeUnit, el, ev);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t\tlistenStop: function() {\n\t\t\t\tmouseFollower.stop(); // put in listenStop in case there was a mousedown but the drag never started\n\t\t\t}\n\t\t});\n\n\t\tdragListener.mousedown(ev); // start listening, which will eventually lead to a dragStart\n\t},\n\n\n\t// Called before event segment dragging starts\n\tsegDragStart: function(seg, ev) {\n\t\tthis.isDraggingSeg = true;\n\t\tthis.view.trigger('eventDragStart', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy\n\t},\n\n\n\t// Called after event segment dragging stops\n\tsegDragStop: function(seg, ev) {\n\t\tthis.isDraggingSeg = false;\n\t\tthis.view.trigger('eventDragStop', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy\n\t},\n\n\n\t// Given the cell an event drag began, and the cell event was dropped, calculates the new start/end/allDay\n\t// values for the event. Subclasses may override and set additional properties to be used by renderDrag.\n\t// A falsy returned value indicates an invalid drop.\n\tcomputeEventDrop: function(startCell, endCell, event) {\n\t\tvar calendar = this.view.calendar;\n\t\tvar dragStart = startCell.start;\n\t\tvar dragEnd = endCell.start;\n\t\tvar delta;\n\t\tvar dropLocation;\n\n\t\tif (dragStart.hasTime() === dragEnd.hasTime()) {\n\t\t\tdelta = this.diffDates(dragEnd, dragStart);\n\n\t\t\t// if an all-day event was in a timed area and it was dragged to a different time,\n\t\t\t// guarantee an end and adjust start/end to have times\n\t\t\tif (event.allDay && durationHasTime(delta)) {\n\t\t\t\tdropLocation = {\n\t\t\t\t\tstart: event.start.clone(),\n\t\t\t\t\tend: calendar.getEventEnd(event), // will be an ambig day\n\t\t\t\t\tallDay: false // for normalizeEventRangeTimes\n\t\t\t\t};\n\t\t\t\tcalendar.normalizeEventRangeTimes(dropLocation);\n\t\t\t}\n\t\t\t// othewise, work off existing values\n\t\t\telse {\n\t\t\t\tdropLocation = {\n\t\t\t\t\tstart: event.start.clone(),\n\t\t\t\t\tend: event.end ? event.end.clone() : null,\n\t\t\t\t\tallDay: event.allDay // keep it the same\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tdropLocation.start.add(delta);\n\t\t\tif (dropLocation.end) {\n\t\t\t\tdropLocation.end.add(delta);\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// if switching from day <-> timed, start should be reset to the dropped date, and the end cleared\n\t\t\tdropLocation = {\n\t\t\t\tstart: dragEnd.clone(),\n\t\t\t\tend: null, // end should be cleared\n\t\t\t\tallDay: !dragEnd.hasTime()\n\t\t\t};\n\t\t}\n\n\t\treturn dropLocation;\n\t},\n\n\n\t// Utility for apply dragOpacity to a jQuery set\n\tapplyDragOpacity: function(els) {\n\t\tvar opacity = this.view.opt('dragOpacity');\n\n\t\tif (opacity != null) {\n\t\t\tels.each(function(i, node) {\n\t\t\t\t// Don't use jQuery (will set an IE filter), do it the old fashioned way.\n\t\t\t\t// In IE8, a helper element will disappears if there's a filter.\n\t\t\t\tnode.style.opacity = opacity;\n\t\t\t});\n\t\t}\n\t},\n\n\n\t/* External Element Dragging\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Called when a jQuery UI drag is initiated anywhere in the DOM\n\texternalDragStart: function(ev, ui) {\n\t\tvar view = this.view;\n\t\tvar el;\n\t\tvar accept;\n\n\t\tif (view.opt('droppable')) { // only listen if this setting is on\n\t\t\tel = $((ui ? ui.item : null) || ev.target);\n\n\t\t\t// Test that the dragged element passes the dropAccept selector or filter function.\n\t\t\t// FYI, the default is \"*\" (matches all)\n\t\t\taccept = view.opt('dropAccept');\n\t\t\tif ($.isFunction(accept) ? accept.call(el[0], el) : el.is(accept)) {\n\t\t\t\tif (!this.isDraggingExternal) { // prevent double-listening if fired twice\n\t\t\t\t\tthis.listenToExternalDrag(el, ev, ui);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Called when a jQuery UI drag starts and it needs to be monitored for cell dropping\n\tlistenToExternalDrag: function(el, ev, ui) {\n\t\tvar _this = this;\n\t\tvar meta = getDraggedElMeta(el); // extra data about event drop, including possible event to create\n\t\tvar dragListener;\n\t\tvar dropLocation; // a null value signals an unsuccessful drag\n\n\t\t// listener that tracks mouse movement over date-associated pixel regions\n\t\tdragListener = new CellDragListener(this.coordMap, {\n\t\t\tlistenStart: function() {\n\t\t\t\t_this.isDraggingExternal = true;\n\t\t\t},\n\t\t\tcellOver: function(cell) {\n\t\t\t\tdropLocation = _this.computeExternalDrop(cell, meta);\n\t\t\t\tif (dropLocation) {\n\t\t\t\t\t_this.renderDrag(dropLocation); // called without a seg parameter\n\t\t\t\t}\n\t\t\t\telse { // invalid drop cell\n\t\t\t\t\tdisableCursor();\n\t\t\t\t}\n\t\t\t},\n\t\t\tcellOut: function() {\n\t\t\t\tdropLocation = null; // signal unsuccessful\n\t\t\t\t_this.unrenderDrag();\n\t\t\t\tenableCursor();\n\t\t\t},\n\t\t\tdragStop: function() {\n\t\t\t\t_this.unrenderDrag();\n\t\t\t\tenableCursor();\n\n\t\t\t\tif (dropLocation) { // element was dropped on a valid date/time cell\n\t\t\t\t\t_this.view.reportExternalDrop(meta, dropLocation, el, ev, ui);\n\t\t\t\t}\n\t\t\t},\n\t\t\tlistenStop: function() {\n\t\t\t\t_this.isDraggingExternal = false;\n\t\t\t}\n\t\t});\n\n\t\tdragListener.startDrag(ev); // start listening immediately\n\t},\n\n\n\t// Given a cell to be dropped upon, and misc data associated with the jqui drag (guaranteed to be a plain object),\n\t// returns start/end dates for the event that would result from the hypothetical drop. end might be null.\n\t// Returning a null value signals an invalid drop cell.\n\tcomputeExternalDrop: function(cell, meta) {\n\t\tvar dropLocation = {\n\t\t\tstart: cell.start.clone(),\n\t\t\tend: null\n\t\t};\n\n\t\t// if dropped on an all-day cell, and element's metadata specified a time, set it\n\t\tif (meta.startTime && !dropLocation.start.hasTime()) {\n\t\t\tdropLocation.start.time(meta.startTime);\n\t\t}\n\n\t\tif (meta.duration) {\n\t\t\tdropLocation.end = dropLocation.start.clone().add(meta.duration);\n\t\t}\n\n\t\tif (!this.view.calendar.isExternalDropRangeAllowed(dropLocation, meta.eventProps)) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn dropLocation;\n\t},\n\n\n\n\t/* Drag Rendering (for both events and an external elements)\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of an event or external element being dragged.\n\t// `dropLocation` contains hypothetical start/end/allDay values the event would have if dropped. end can be null.\n\t// `seg` is the internal segment object that is being dragged. If dragging an external element, `seg` is null.\n\t// A truthy returned value indicates this method has rendered a helper element.\n\trenderDrag: function(dropLocation, seg) {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Unrenders a visual indication of an event or external element being dragged\n\tunrenderDrag: function() {\n\t\t// subclasses must implement\n\t},\n\n\n\t/* Resizing\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Called when the user does a mousedown on an event's resizer, which might lead to resizing.\n\t// Generic enough to work with any type of Grid.\n\tsegResizeMousedown: function(seg, ev, isStart) {\n\t\tvar _this = this;\n\t\tvar view = this.view;\n\t\tvar calendar = view.calendar;\n\t\tvar el = seg.el;\n\t\tvar event = seg.event;\n\t\tvar eventEnd = calendar.getEventEnd(event);\n\t\tvar dragListener;\n\t\tvar resizeLocation; // falsy if invalid resize\n\n\t\t// Tracks mouse movement over the *grid's* coordinate map\n\t\tdragListener = new CellDragListener(this.coordMap, {\n\t\t\tdistance: 5,\n\t\t\tscroll: view.opt('dragScroll'),\n\t\t\tsubjectEl: el,\n\t\t\tdragStart: function(ev) {\n\t\t\t\t_this.triggerSegMouseout(seg, ev); // ensure a mouseout on the manipulated event has been reported\n\t\t\t\t_this.segResizeStart(seg, ev);\n\t\t\t},\n\t\t\tcellOver: function(cell, isOrig, origCell) {\n\t\t\t\tresizeLocation = isStart ?\n\t\t\t\t\t_this.computeEventStartResize(origCell, cell, event) :\n\t\t\t\t\t_this.computeEventEndResize(origCell, cell, event);\n\n\t\t\t\tif (resizeLocation) {\n\t\t\t\t\tif (!calendar.isEventRangeAllowed(resizeLocation, event)) {\n\t\t\t\t\t\tdisableCursor();\n\t\t\t\t\t\tresizeLocation = null;\n\t\t\t\t\t}\n\t\t\t\t\t// no change? (TODO: how does this work with timezones?)\n\t\t\t\t\telse if (resizeLocation.start.isSame(event.start) && resizeLocation.end.isSame(eventEnd)) {\n\t\t\t\t\t\tresizeLocation = null;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (resizeLocation) {\n\t\t\t\t\tview.hideEvent(event);\n\t\t\t\t\t_this.renderEventResize(resizeLocation, seg);\n\t\t\t\t}\n\t\t\t},\n\t\t\tcellOut: function() { // called before mouse moves to a different cell OR moved out of all cells\n\t\t\t\tresizeLocation = null;\n\t\t\t},\n\t\t\tcellDone: function() { // resets the rendering to show the original event\n\t\t\t\t_this.unrenderEventResize();\n\t\t\t\tview.showEvent(event);\n\t\t\t\tenableCursor();\n\t\t\t},\n\t\t\tdragStop: function(ev) {\n\t\t\t\t_this.segResizeStop(seg, ev);\n\n\t\t\t\tif (resizeLocation) { // valid date to resize to?\n\t\t\t\t\tview.reportEventResize(event, resizeLocation, this.largeUnit, el, ev);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tdragListener.mousedown(ev); // start listening, which will eventually lead to a dragStart\n\t},\n\n\n\t// Called before event segment resizing starts\n\tsegResizeStart: function(seg, ev) {\n\t\tthis.isResizingSeg = true;\n\t\tthis.view.trigger('eventResizeStart', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy\n\t},\n\n\n\t// Called after event segment resizing stops\n\tsegResizeStop: function(seg, ev) {\n\t\tthis.isResizingSeg = false;\n\t\tthis.view.trigger('eventResizeStop', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy\n\t},\n\n\n\t// Returns new date-information for an event segment being resized from its start\n\tcomputeEventStartResize: function(startCell, endCell, event) {\n\t\treturn this.computeEventResize('start', startCell, endCell, event);\n\t},\n\n\n\t// Returns new date-information for an event segment being resized from its end\n\tcomputeEventEndResize: function(startCell, endCell, event) {\n\t\treturn this.computeEventResize('end', startCell, endCell, event);\n\t},\n\n\n\t// Returns new date-information for an event segment being resized from its start OR end\n\t// `type` is either 'start' or 'end'\n\tcomputeEventResize: function(type, startCell, endCell, event) {\n\t\tvar calendar = this.view.calendar;\n\t\tvar delta = this.diffDates(endCell[type], startCell[type]);\n\t\tvar range;\n\t\tvar defaultDuration;\n\n\t\t// build original values to work from, guaranteeing a start and end\n\t\trange = {\n\t\t\tstart: event.start.clone(),\n\t\t\tend: calendar.getEventEnd(event),\n\t\t\tallDay: event.allDay\n\t\t};\n\n\t\t// if an all-day event was in a timed area and was resized to a time, adjust start/end to have times\n\t\tif (range.allDay && durationHasTime(delta)) {\n\t\t\trange.allDay = false;\n\t\t\tcalendar.normalizeEventRangeTimes(range);\n\t\t}\n\n\t\trange[type].add(delta); // apply delta to start or end\n\n\t\t// if the event was compressed too small, find a new reasonable duration for it\n\t\tif (!range.start.isBefore(range.end)) {\n\n\t\t\tdefaultDuration = event.allDay ?\n\t\t\t\tcalendar.defaultAllDayEventDuration :\n\t\t\t\tcalendar.defaultTimedEventDuration;\n\n\t\t\t// between the cell's duration and the event's default duration, use the smaller of the two.\n\t\t\t// example: if year-length slots, and compressed to one slot, we don't want the event to be a year long\n\t\t\tif (this.cellDuration && this.cellDuration < defaultDuration) {\n\t\t\t\tdefaultDuration = this.cellDuration;\n\t\t\t}\n\n\t\t\tif (type == 'start') { // resizing the start?\n\t\t\t\trange.start = range.end.clone().subtract(defaultDuration);\n\t\t\t}\n\t\t\telse { // resizing the end?\n\t\t\t\trange.end = range.start.clone().add(defaultDuration);\n\t\t\t}\n\t\t}\n\n\t\treturn range;\n\t},\n\n\n\t// Renders a visual indication of an event being resized.\n\t// `range` has the updated dates of the event. `seg` is the original segment object involved in the drag.\n\trenderEventResize: function(range, seg) {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Unrenders a visual indication of an event being resized.\n\tunrenderEventResize: function() {\n\t\t// subclasses must implement\n\t},\n\n\n\t/* Rendering Utils\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Compute the text that should be displayed on an event's element.\n\t// `range` can be the Event object itself, or something range-like, with at least a `start`.\n\t// If event times are disabled, or the event has no time, will return a blank string.\n\t// If not specified, formatStr will default to the eventTimeFormat setting,\n\t// and displayEnd will default to the displayEventEnd setting.\n\tgetEventTimeText: function(range, formatStr, displayEnd) {\n\n\t\tif (formatStr == null) {\n\t\t\tformatStr = this.eventTimeFormat;\n\t\t}\n\n\t\tif (displayEnd == null) {\n\t\t\tdisplayEnd = this.displayEventEnd;\n\t\t}\n\n\t\tif (this.displayEventTime && range.start.hasTime()) {\n\t\t\tif (displayEnd && range.end) {\n\t\t\t\treturn this.view.formatRange(range, formatStr);\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn range.start.format(formatStr);\n\t\t\t}\n\t\t}\n\n\t\treturn '';\n\t},\n\n\n\t// Generic utility for generating the HTML classNames for an event segment's element\n\tgetSegClasses: function(seg, isDraggable, isResizable) {\n\t\tvar event = seg.event;\n\t\tvar classes = [\n\t\t\t'fc-event',\n\t\t\tseg.isStart ? 'fc-start' : 'fc-not-start',\n\t\t\tseg.isEnd ? 'fc-end' : 'fc-not-end'\n\t\t].concat(\n\t\t\tevent.className,\n\t\t\tevent.source ? event.source.className : []\n\t\t);\n\n\t\tif (isDraggable) {\n\t\t\tclasses.push('fc-draggable');\n\t\t}\n\t\tif (isResizable) {\n\t\t\tclasses.push('fc-resizable');\n\t\t}\n\n\t\treturn classes;\n\t},\n\n\n\t// Utility for generating event skin-related CSS properties\n\tgetEventSkinCss: function(event) {\n\t\tvar view = this.view;\n\t\tvar source = event.source || {};\n\t\tvar eventColor = event.color;\n\t\tvar sourceColor = source.color;\n\t\tvar optionColor = view.opt('eventColor');\n\n\t\treturn {\n\t\t\t'background-color':\n\t\t\t\tevent.backgroundColor ||\n\t\t\t\teventColor ||\n\t\t\t\tsource.backgroundColor ||\n\t\t\t\tsourceColor ||\n\t\t\t\tview.opt('eventBackgroundColor') ||\n\t\t\t\toptionColor,\n\t\t\t'border-color':\n\t\t\t\tevent.borderColor ||\n\t\t\t\teventColor ||\n\t\t\t\tsource.borderColor ||\n\t\t\t\tsourceColor ||\n\t\t\t\tview.opt('eventBorderColor') ||\n\t\t\t\toptionColor,\n\t\t\tcolor:\n\t\t\t\tevent.textColor ||\n\t\t\t\tsource.textColor ||\n\t\t\t\tview.opt('eventTextColor')\n\t\t};\n\t},\n\n\n\t/* Converting events -> ranges -> segs\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Converts an array of event objects into an array of event segment objects.\n\t// A custom `rangeToSegsFunc` may be given for arbitrarily slicing up events.\n\t// Doesn't guarantee an order for the resulting array.\n\teventsToSegs: function(events, rangeToSegsFunc) {\n\t\tvar eventRanges = this.eventsToRanges(events);\n\t\tvar segs = [];\n\t\tvar i;\n\n\t\tfor (i = 0; i < eventRanges.length; i++) {\n\t\t\tsegs.push.apply(\n\t\t\t\tsegs,\n\t\t\t\tthis.eventRangeToSegs(eventRanges[i], rangeToSegsFunc)\n\t\t\t);\n\t\t}\n\n\t\treturn segs;\n\t},\n\n\n\t// Converts an array of events into an array of \"range\" objects.\n\t// A \"range\" object is a plain object with start/end properties denoting the time it covers. Also an event property.\n\t// For \"normal\" events, this will be identical to the event's start/end, but for \"inverse-background\" events,\n\t// will create an array of ranges that span the time *not* covered by the given event.\n\t// Doesn't guarantee an order for the resulting array.\n\teventsToRanges: function(events) {\n\t\tvar _this = this;\n\t\tvar eventsById = groupEventsById(events);\n\t\tvar ranges = [];\n\n\t\t// group by ID so that related inverse-background events can be rendered together\n\t\t$.each(eventsById, function(id, eventGroup) {\n\t\t\tif (eventGroup.length) {\n\t\t\t\tranges.push.apply(\n\t\t\t\t\tranges,\n\t\t\t\t\tisInverseBgEvent(eventGroup[0]) ?\n\t\t\t\t\t\t_this.eventsToInverseRanges(eventGroup) :\n\t\t\t\t\t\t_this.eventsToNormalRanges(eventGroup)\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\treturn ranges;\n\t},\n\n\n\t// Converts an array of \"normal\" events (not inverted rendering) into a parallel array of ranges\n\teventsToNormalRanges: function(events) {\n\t\tvar calendar = this.view.calendar;\n\t\tvar ranges = [];\n\t\tvar i, event;\n\t\tvar eventStart, eventEnd;\n\n\t\tfor (i = 0; i < events.length; i++) {\n\t\t\tevent = events[i];\n\n\t\t\t// make copies and normalize by stripping timezone\n\t\t\teventStart = event.start.clone().stripZone();\n\t\t\teventEnd = calendar.getEventEnd(event).stripZone();\n\n\t\t\tranges.push({\n\t\t\t\tevent: event,\n\t\t\t\tstart: eventStart,\n\t\t\t\tend: eventEnd,\n\t\t\t\teventStartMS: +eventStart,\n\t\t\t\teventDurationMS: eventEnd - eventStart\n\t\t\t});\n\t\t}\n\n\t\treturn ranges;\n\t},\n\n\n\t// Converts an array of events, with inverse-background rendering, into an array of range objects.\n\t// The range objects will cover all the time NOT covered by the events.\n\teventsToInverseRanges: function(events) {\n\t\tvar view = this.view;\n\t\tvar viewStart = view.start.clone().stripZone(); // normalize timezone\n\t\tvar viewEnd = view.end.clone().stripZone(); // normalize timezone\n\t\tvar normalRanges = this.eventsToNormalRanges(events); // will give us normalized dates we can use w/o copies\n\t\tvar inverseRanges = [];\n\t\tvar event0 = events[0]; // assign this to each range's `.event`\n\t\tvar start = viewStart; // the end of the previous range. the start of the new range\n\t\tvar i, normalRange;\n\n\t\t// ranges need to be in order. required for our date-walking algorithm\n\t\tnormalRanges.sort(compareNormalRanges);\n\n\t\tfor (i = 0; i < normalRanges.length; i++) {\n\t\t\tnormalRange = normalRanges[i];\n\n\t\t\t// add the span of time before the event (if there is any)\n\t\t\tif (normalRange.start > start) { // compare millisecond time (skip any ambig logic)\n\t\t\t\tinverseRanges.push({\n\t\t\t\t\tevent: event0,\n\t\t\t\t\tstart: start,\n\t\t\t\t\tend: normalRange.start\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tstart = normalRange.end;\n\t\t}\n\n\t\t// add the span of time after the last event (if there is any)\n\t\tif (start < viewEnd) { // compare millisecond time (skip any ambig logic)\n\t\t\tinverseRanges.push({\n\t\t\t\tevent: event0,\n\t\t\t\tstart: start,\n\t\t\t\tend: viewEnd\n\t\t\t});\n\t\t}\n\n\t\treturn inverseRanges;\n\t},\n\n\n\t// Slices the given event range into one or more segment objects.\n\t// A `rangeToSegsFunc` custom slicing function can be given.\n\teventRangeToSegs: function(eventRange, rangeToSegsFunc) {\n\t\tvar segs;\n\t\tvar i, seg;\n\n\t\teventRange = this.view.calendar.ensureVisibleEventRange(eventRange);\n\n\t\tif (rangeToSegsFunc) {\n\t\t\tsegs = rangeToSegsFunc(eventRange);\n\t\t}\n\t\telse {\n\t\t\tsegs = this.rangeToSegs(eventRange); // defined by the subclass\n\t\t}\n\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tseg = segs[i];\n\t\t\tseg.event = eventRange.event;\n\t\t\tseg.eventStartMS = eventRange.eventStartMS;\n\t\t\tseg.eventDurationMS = eventRange.eventDurationMS;\n\t\t}\n\n\t\treturn segs;\n\t},\n\n\n\tsortSegs: function(segs) {\n\t\tsegs.sort(proxy(this, 'compareSegs'));\n\t},\n\n\n\t// A cmp function for determining which segments should take visual priority\n\t// DOES NOT WORK ON INVERTED BACKGROUND EVENTS because they have no eventStartMS/eventDurationMS\n\tcompareSegs: function(seg1, seg2) {\n\t\treturn seg1.eventStartMS - seg2.eventStartMS || // earlier events go first\n\t\t\tseg2.eventDurationMS - seg1.eventDurationMS || // tie? longer events go first\n\t\t\tseg2.event.allDay - seg1.event.allDay || // tie? put all-day events first (booleans cast to 0/1)\n\t\t\tcompareByFieldSpecs(seg1.event, seg2.event, this.view.eventOrderSpecs);\n\t}\n\n});\n\n\n/* Utilities\n----------------------------------------------------------------------------------------------------------------------*/\n\n\nfunction isBgEvent(event) { // returns true if background OR inverse-background\n\tvar rendering = getEventRendering(event);\n\treturn rendering === 'background' || rendering === 'inverse-background';\n}\n\n\nfunction isInverseBgEvent(event) {\n\treturn getEventRendering(event) === 'inverse-background';\n}\n\n\nfunction getEventRendering(event) {\n\treturn firstDefined((event.source || {}).rendering, event.rendering);\n}\n\n\nfunction groupEventsById(events) {\n\tvar eventsById = {};\n\tvar i, event;\n\n\tfor (i = 0; i < events.length; i++) {\n\t\tevent = events[i];\n\t\t(eventsById[event._id] || (eventsById[event._id] = [])).push(event);\n\t}\n\n\treturn eventsById;\n}\n\n\n// A cmp function for determining which non-inverted \"ranges\" (see above) happen earlier\nfunction compareNormalRanges(range1, range2) {\n\treturn range1.eventStartMS - range2.eventStartMS; // earlier ranges go first\n}\n\n\n/* External-Dragging-Element Data\n----------------------------------------------------------------------------------------------------------------------*/\n\n// Require all HTML5 data-* attributes used by FullCalendar to have this prefix.\n// A value of '' will query attributes like data-event. A value of 'fc' will query attributes like data-fc-event.\nfc.dataAttrPrefix = '';\n\n// Given a jQuery element that might represent a dragged FullCalendar event, returns an intermediate data structure\n// to be used for Event Object creation.\n// A defined `.eventProps`, even when empty, indicates that an event should be created.\nfunction getDraggedElMeta(el) {\n\tvar prefix = fc.dataAttrPrefix;\n\tvar eventProps; // properties for creating the event, not related to date/time\n\tvar startTime; // a Duration\n\tvar duration;\n\tvar stick;\n\n\tif (prefix) { prefix += '-'; }\n\teventProps = el.data(prefix + 'event') || null;\n\n\tif (eventProps) {\n\t\tif (typeof eventProps === 'object') {\n\t\t\teventProps = $.extend({}, eventProps); // make a copy\n\t\t}\n\t\telse { // something like 1 or true. still signal event creation\n\t\t\teventProps = {};\n\t\t}\n\n\t\t// pluck special-cased date/time properties\n\t\tstartTime = eventProps.start;\n\t\tif (startTime == null) { startTime = eventProps.time; } // accept 'time' as well\n\t\tduration = eventProps.duration;\n\t\tstick = eventProps.stick;\n\t\tdelete eventProps.start;\n\t\tdelete eventProps.time;\n\t\tdelete eventProps.duration;\n\t\tdelete eventProps.stick;\n\t}\n\n\t// fallback to standalone attribute values for each of the date/time properties\n\tif (startTime == null) { startTime = el.data(prefix + 'start'); }\n\tif (startTime == null) { startTime = el.data(prefix + 'time'); } // accept 'time' as well\n\tif (duration == null) { duration = el.data(prefix + 'duration'); }\n\tif (stick == null) { stick = el.data(prefix + 'stick'); }\n\n\t// massage into correct data types\n\tstartTime = startTime != null ? moment.duration(startTime) : null;\n\tduration = duration != null ? moment.duration(duration) : null;\n\tstick = Boolean(stick);\n\n\treturn { eventProps: eventProps, startTime: startTime, duration: duration, stick: stick };\n}\n\n\n;;\n\n/* A component that renders a grid of whole-days that runs horizontally. There can be multiple rows, one per week.\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar DayGrid = Grid.extend({\n\n\tnumbersVisible: false, // should render a row for day/week numbers? set by outside view. TODO: make internal\n\tbottomCoordPadding: 0, // hack for extending the hit area for the last row of the coordinate grid\n\tbreakOnWeeks: null, // should create a new row for each week? set by outside view\n\n\tcellDates: null, // flat chronological array of each cell's dates\n\tdayToCellOffsets: null, // maps days offsets from grid's start date, to cell offsets\n\n\trowEls: null, // set of fake row elements\n\tdayEls: null, // set of whole-day elements comprising the row's background\n\thelperEls: null, // set of cell skeleton elements for rendering the mock event \"helper\"\n\n\n\tconstructor: function() {\n\t\tGrid.apply(this, arguments);\n\n\t\tthis.cellDuration = moment.duration(1, 'day'); // for Grid system\n\t},\n\n\n\t// Renders the rows and columns into the component's `this.el`, which should already be assigned.\n\t// isRigid determins whether the individual rows should ignore the contents and be a constant height.\n\t// Relies on the view's colCnt and rowCnt. In the future, this component should probably be self-sufficient.\n\trenderDates: function(isRigid) {\n\t\tvar view = this.view;\n\t\tvar rowCnt = this.rowCnt;\n\t\tvar colCnt = this.colCnt;\n\t\tvar cellCnt = rowCnt * colCnt;\n\t\tvar html = '';\n\t\tvar row;\n\t\tvar i, cell;\n\n\t\tfor (row = 0; row < rowCnt; row++) {\n\t\t\thtml += this.dayRowHtml(row, isRigid);\n\t\t}\n\t\tthis.el.html(html);\n\n\t\tthis.rowEls = this.el.find('.fc-row');\n\t\tthis.dayEls = this.el.find('.fc-day');\n\n\t\t// trigger dayRender with each cell's element\n\t\tfor (i = 0; i < cellCnt; i++) {\n\t\t\tcell = this.getCell(i);\n\t\t\tview.trigger('dayRender', null, cell.start, this.dayEls.eq(i));\n\t\t}\n\t},\n\n\n\tunrenderDates: function() {\n\t\tthis.removeSegPopover();\n\t},\n\n\n\trenderBusinessHours: function() {\n\t\tvar events = this.view.calendar.getBusinessHoursEvents(true); // wholeDay=true\n\t\tvar segs = this.eventsToSegs(events);\n\n\t\tthis.renderFill('businessHours', segs, 'bgevent');\n\t},\n\n\n\t// Generates the HTML for a single row. `row` is the row number.\n\tdayRowHtml: function(row, isRigid) {\n\t\tvar view = this.view;\n\t\tvar classes = [ 'fc-row', 'fc-week', view.widgetContentClass ];\n\n\t\tif (isRigid) {\n\t\t\tclasses.push('fc-rigid');\n\t\t}\n\n\t\treturn '' +\n\t\t\t'
' +\n\t\t\t\t'
' +\n\t\t\t\t\t'' +\n\t\t\t\t\t\tthis.rowHtml('day', row) + // leverages RowRenderer. calls dayCellHtml()\n\t\t\t\t\t'
' +\n\t\t\t\t'
' +\n\t\t\t\t'
' +\n\t\t\t\t\t'' +\n\t\t\t\t\t\t(this.numbersVisible ?\n\t\t\t\t\t\t\t'' +\n\t\t\t\t\t\t\t\tthis.rowHtml('number', row) + // leverages RowRenderer. View will define render method\n\t\t\t\t\t\t\t'' :\n\t\t\t\t\t\t\t''\n\t\t\t\t\t\t\t) +\n\t\t\t\t\t'
' +\n\t\t\t\t'
' +\n\t\t\t'
';\n\t},\n\n\n\t// Renders the HTML for a whole-day cell. Will eventually end up in the day-row's background.\n\t// We go through a 'day' row type instead of just doing a 'bg' row type so that the View can do custom rendering\n\t// specifically for whole-day rows, whereas a 'bg' might also be used for other purposes (TimeGrid bg for example).\n\tdayCellHtml: function(cell) {\n\t\treturn this.bgCellHtml(cell);\n\t},\n\n\n\t/* Options\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Computes a default column header formatting string if `colFormat` is not explicitly defined\n\tcomputeColHeadFormat: function() {\n\t\tif (this.rowCnt > 1) { // more than one week row. day numbers will be in each cell\n\t\t\treturn 'ddd'; // \"Sat\"\n\t\t}\n\t\telse if (this.colCnt > 1) { // multiple days, so full single date string WON'T be in title text\n\t\t\treturn this.view.opt('dayOfMonthFormat'); // \"Sat 12/10\"\n\t\t}\n\t\telse { // single day, so full single date string will probably be in title text\n\t\t\treturn 'dddd'; // \"Saturday\"\n\t\t}\n\t},\n\n\n\t// Computes a default event time formatting string if `timeFormat` is not explicitly defined\n\tcomputeEventTimeFormat: function() {\n\t\treturn this.view.opt('extraSmallTimeFormat'); // like \"6p\" or \"6:30p\"\n\t},\n\n\n\t// Computes a default `displayEventEnd` value if one is not expliclty defined\n\tcomputeDisplayEventEnd: function() {\n\t\treturn this.colCnt == 1; // we'll likely have space if there's only one day\n\t},\n\n\n\t/* Cell System\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\trangeUpdated: function() {\n\t\tvar cellDates;\n\t\tvar firstDay;\n\t\tvar rowCnt;\n\t\tvar colCnt;\n\n\t\tthis.updateCellDates(); // populates cellDates and dayToCellOffsets\n\t\tcellDates = this.cellDates;\n\n\t\tif (this.breakOnWeeks) {\n\t\t\t// count columns until the day-of-week repeats\n\t\t\tfirstDay = cellDates[0].day();\n\t\t\tfor (colCnt = 1; colCnt < cellDates.length; colCnt++) {\n\t\t\t\tif (cellDates[colCnt].day() == firstDay) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\trowCnt = Math.ceil(cellDates.length / colCnt);\n\t\t}\n\t\telse {\n\t\t\trowCnt = 1;\n\t\t\tcolCnt = cellDates.length;\n\t\t}\n\n\t\tthis.rowCnt = rowCnt;\n\t\tthis.colCnt = colCnt;\n\t},\n\n\n\t// Populates cellDates and dayToCellOffsets\n\tupdateCellDates: function() {\n\t\tvar view = this.view;\n\t\tvar date = this.start.clone();\n\t\tvar dates = [];\n\t\tvar offset = -1;\n\t\tvar offsets = [];\n\n\t\twhile (date.isBefore(this.end)) { // loop each day from start to end\n\t\t\tif (view.isHiddenDay(date)) {\n\t\t\t\toffsets.push(offset + 0.5); // mark that it's between offsets\n\t\t\t}\n\t\t\telse {\n\t\t\t\toffset++;\n\t\t\t\toffsets.push(offset);\n\t\t\t\tdates.push(date.clone());\n\t\t\t}\n\t\t\tdate.add(1, 'days');\n\t\t}\n\n\t\tthis.cellDates = dates;\n\t\tthis.dayToCellOffsets = offsets;\n\t},\n\n\n\t// Given a cell object, generates its start date. Returns a reference-free copy.\n\tcomputeCellDate: function(cell) {\n\t\tvar colCnt = this.colCnt;\n\t\tvar index = cell.row * colCnt + (this.isRTL ? colCnt - cell.col - 1 : cell.col);\n\n\t\treturn this.cellDates[index].clone();\n\t},\n\n\n\t// Retrieves the element representing the given row\n\tgetRowEl: function(row) {\n\t\treturn this.rowEls.eq(row);\n\t},\n\n\n\t// Retrieves the element representing the given column\n\tgetColEl: function(col) {\n\t\treturn this.dayEls.eq(col);\n\t},\n\n\n\t// Gets the whole-day element associated with the cell\n\tgetCellDayEl: function(cell) {\n\t\treturn this.dayEls.eq(cell.row * this.colCnt + cell.col);\n\t},\n\n\n\t// Overrides Grid's method for when row coordinates are computed\n\tcomputeRowCoords: function() {\n\t\tvar rowCoords = Grid.prototype.computeRowCoords.call(this); // call the super-method\n\n\t\t// hack for extending last row (used by AgendaView)\n\t\trowCoords[rowCoords.length - 1].bottom += this.bottomCoordPadding;\n\n\t\treturn rowCoords;\n\t},\n\n\n\t/* Dates\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Slices up a date range by row into an array of segments\n\trangeToSegs: function(range) {\n\t\tvar isRTL = this.isRTL;\n\t\tvar rowCnt = this.rowCnt;\n\t\tvar colCnt = this.colCnt;\n\t\tvar segs = [];\n\t\tvar first, last; // inclusive cell-offset range for given range\n\t\tvar row;\n\t\tvar rowFirst, rowLast; // inclusive cell-offset range for current row\n\t\tvar isStart, isEnd;\n\t\tvar segFirst, segLast; // inclusive cell-offset range for segment\n\t\tvar seg;\n\n\t\trange = this.view.computeDayRange(range); // make whole-day range, considering nextDayThreshold\n\t\tfirst = this.dateToCellOffset(range.start);\n\t\tlast = this.dateToCellOffset(range.end.subtract(1, 'days')); // offset of inclusive end date\n\n\t\tfor (row = 0; row < rowCnt; row++) {\n\t\t\trowFirst = row * colCnt;\n\t\t\trowLast = rowFirst + colCnt - 1;\n\n\t\t\t// intersect segment's offset range with the row's\n\t\t\tsegFirst = Math.max(rowFirst, first);\n\t\t\tsegLast = Math.min(rowLast, last);\n\n\t\t\t// deal with in-between indices\n\t\t\tsegFirst = Math.ceil(segFirst); // in-between starts round to next cell\n\t\t\tsegLast = Math.floor(segLast); // in-between ends round to prev cell\n\n\t\t\tif (segFirst <= segLast) { // was there any intersection with the current row?\n\n\t\t\t\t// must be matching integers to be the segment's start/end\n\t\t\t\tisStart = segFirst === first;\n\t\t\t\tisEnd = segLast === last;\n\n\t\t\t\t// translate offsets to be relative to start-of-row\n\t\t\t\tsegFirst -= rowFirst;\n\t\t\t\tsegLast -= rowFirst;\n\n\t\t\t\tseg = { row: row, isStart: isStart, isEnd: isEnd };\n\t\t\t\tif (isRTL) {\n\t\t\t\t\tseg.leftCol = colCnt - segLast - 1;\n\t\t\t\t\tseg.rightCol = colCnt - segFirst - 1;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tseg.leftCol = segFirst;\n\t\t\t\t\tseg.rightCol = segLast;\n\t\t\t\t}\n\t\t\t\tsegs.push(seg);\n\t\t\t}\n\t\t}\n\n\t\treturn segs;\n\t},\n\n\n\t// Given a date, returns its chronolocial cell-offset from the first cell of the grid.\n\t// If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.\n\t// If before the first offset, returns a negative number.\n\t// If after the last offset, returns an offset past the last cell offset.\n\t// Only works for *start* dates of cells. Will not work for exclusive end dates for cells.\n\tdateToCellOffset: function(date) {\n\t\tvar offsets = this.dayToCellOffsets;\n\t\tvar day = date.diff(this.start, 'days');\n\n\t\tif (day < 0) {\n\t\t\treturn offsets[0] - 1;\n\t\t}\n\t\telse if (day >= offsets.length) {\n\t\t\treturn offsets[offsets.length - 1] + 1;\n\t\t}\n\t\telse {\n\t\t\treturn offsets[day];\n\t\t}\n\t},\n\n\n\t/* Event Drag Visualization\n\t------------------------------------------------------------------------------------------------------------------*/\n\t// TODO: move to DayGrid.event, similar to what we did with Grid's drag methods\n\n\n\t// Renders a visual indication of an event or external element being dragged.\n\t// The dropLocation's end can be null. seg can be null. See Grid::renderDrag for more info.\n\trenderDrag: function(dropLocation, seg) {\n\n\t\t// always render a highlight underneath\n\t\tthis.renderHighlight(this.eventRangeToSegs(dropLocation));\n\n\t\t// if a segment from the same calendar but another component is being dragged, render a helper event\n\t\tif (seg && !seg.el.closest(this.el).length) {\n\n\t\t\tthis.renderRangeHelper(dropLocation, seg);\n\t\t\tthis.applyDragOpacity(this.helperEls);\n\n\t\t\treturn true; // a helper has been rendered\n\t\t}\n\t},\n\n\n\t// Unrenders any visual indication of a hovering event\n\tunrenderDrag: function() {\n\t\tthis.unrenderHighlight();\n\t\tthis.unrenderHelper();\n\t},\n\n\n\t/* Event Resize Visualization\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of an event being resized\n\trenderEventResize: function(range, seg) {\n\t\tthis.renderHighlight(this.eventRangeToSegs(range));\n\t\tthis.renderRangeHelper(range, seg);\n\t},\n\n\n\t// Unrenders a visual indication of an event being resized\n\tunrenderEventResize: function() {\n\t\tthis.unrenderHighlight();\n\t\tthis.unrenderHelper();\n\t},\n\n\n\t/* Event Helper\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a mock \"helper\" event. `sourceSeg` is the associated internal segment object. It can be null.\n\trenderHelper: function(event, sourceSeg) {\n\t\tvar helperNodes = [];\n\t\tvar segs = this.eventsToSegs([ event ]);\n\t\tvar rowStructs;\n\n\t\tsegs = this.renderFgSegEls(segs); // assigns each seg's el and returns a subset of segs that were rendered\n\t\trowStructs = this.renderSegRows(segs);\n\n\t\t// inject each new event skeleton into each associated row\n\t\tthis.rowEls.each(function(row, rowNode) {\n\t\t\tvar rowEl = $(rowNode); // the .fc-row\n\t\t\tvar skeletonEl = $('
'); // will be absolutely positioned\n\t\t\tvar skeletonTop;\n\n\t\t\t// If there is an original segment, match the top position. Otherwise, put it at the row's top level\n\t\t\tif (sourceSeg && sourceSeg.row === row) {\n\t\t\t\tskeletonTop = sourceSeg.el.position().top;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tskeletonTop = rowEl.find('.fc-content-skeleton tbody').position().top;\n\t\t\t}\n\n\t\t\tskeletonEl.css('top', skeletonTop)\n\t\t\t\t.find('table')\n\t\t\t\t\t.append(rowStructs[row].tbodyEl);\n\n\t\t\trowEl.append(skeletonEl);\n\t\t\thelperNodes.push(skeletonEl[0]);\n\t\t});\n\n\t\tthis.helperEls = $(helperNodes); // array -> jQuery set\n\t},\n\n\n\t// Unrenders any visual indication of a mock helper event\n\tunrenderHelper: function() {\n\t\tif (this.helperEls) {\n\t\t\tthis.helperEls.remove();\n\t\t\tthis.helperEls = null;\n\t\t}\n\t},\n\n\n\t/* Fill System (highlight, background events, business hours)\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\tfillSegTag: 'td', // override the default tag name\n\n\n\t// Renders a set of rectangles over the given segments of days.\n\t// Only returns segments that successfully rendered.\n\trenderFill: function(type, segs, className) {\n\t\tvar nodes = [];\n\t\tvar i, seg;\n\t\tvar skeletonEl;\n\n\t\tsegs = this.renderFillSegEls(type, segs); // assignes `.el` to each seg. returns successfully rendered segs\n\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tseg = segs[i];\n\t\t\tskeletonEl = this.renderFillRow(type, seg, className);\n\t\t\tthis.rowEls.eq(seg.row).append(skeletonEl);\n\t\t\tnodes.push(skeletonEl[0]);\n\t\t}\n\n\t\tthis.elsByFill[type] = $(nodes);\n\n\t\treturn segs;\n\t},\n\n\n\t// Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered.\n\trenderFillRow: function(type, seg, className) {\n\t\tvar colCnt = this.colCnt;\n\t\tvar startCol = seg.leftCol;\n\t\tvar endCol = seg.rightCol + 1;\n\t\tvar skeletonEl;\n\t\tvar trEl;\n\n\t\tclassName = className || type.toLowerCase();\n\n\t\tskeletonEl = $(\n\t\t\t'
' +\n\t\t\t\t'
' +\n\t\t\t'
'\n\t\t);\n\t\ttrEl = skeletonEl.find('tr');\n\n\t\tif (startCol > 0) {\n\t\t\ttrEl.append('');\n\t\t}\n\n\t\ttrEl.append(\n\t\t\tseg.el.attr('colspan', endCol - startCol)\n\t\t);\n\n\t\tif (endCol < colCnt) {\n\t\t\ttrEl.append('');\n\t\t}\n\n\t\tthis.bookendCells(trEl, type);\n\n\t\treturn skeletonEl;\n\t}\n\n});\n\n;;\n\n/* Event-rendering methods for the DayGrid class\n----------------------------------------------------------------------------------------------------------------------*/\n\nDayGrid.mixin({\n\n\trowStructs: null, // an array of objects, each holding information about a row's foreground event-rendering\n\n\n\t// Unrenders all events currently rendered on the grid\n\tunrenderEvents: function() {\n\t\tthis.removeSegPopover(); // removes the \"more..\" events popover\n\t\tGrid.prototype.unrenderEvents.apply(this, arguments); // calls the super-method\n\t},\n\n\n\t// Retrieves all rendered segment objects currently rendered on the grid\n\tgetEventSegs: function() {\n\t\treturn Grid.prototype.getEventSegs.call(this) // get the segments from the super-method\n\t\t\t.concat(this.popoverSegs || []); // append the segments from the \"more...\" popover\n\t},\n\n\n\t// Renders the given background event segments onto the grid\n\trenderBgSegs: function(segs) {\n\n\t\t// don't render timed background events\n\t\tvar allDaySegs = $.grep(segs, function(seg) {\n\t\t\treturn seg.event.allDay;\n\t\t});\n\n\t\treturn Grid.prototype.renderBgSegs.call(this, allDaySegs); // call the super-method\n\t},\n\n\n\t// Renders the given foreground event segments onto the grid\n\trenderFgSegs: function(segs) {\n\t\tvar rowStructs;\n\n\t\t// render an `.el` on each seg\n\t\t// returns a subset of the segs. segs that were actually rendered\n\t\tsegs = this.renderFgSegEls(segs);\n\n\t\trowStructs = this.rowStructs = this.renderSegRows(segs);\n\n\t\t// append to each row's content skeleton\n\t\tthis.rowEls.each(function(i, rowNode) {\n\t\t\t$(rowNode).find('.fc-content-skeleton > table').append(\n\t\t\t\trowStructs[i].tbodyEl\n\t\t\t);\n\t\t});\n\n\t\treturn segs; // return only the segs that were actually rendered\n\t},\n\n\n\t// Unrenders all currently rendered foreground event segments\n\tunrenderFgSegs: function() {\n\t\tvar rowStructs = this.rowStructs || [];\n\t\tvar rowStruct;\n\n\t\twhile ((rowStruct = rowStructs.pop())) {\n\t\t\trowStruct.tbodyEl.remove();\n\t\t}\n\n\t\tthis.rowStructs = null;\n\t},\n\n\n\t// Uses the given events array to generate elements that should be appended to each row's content skeleton.\n\t// Returns an array of rowStruct objects (see the bottom of `renderSegRow`).\n\t// PRECONDITION: each segment shoud already have a rendered and assigned `.el`\n\trenderSegRows: function(segs) {\n\t\tvar rowStructs = [];\n\t\tvar segRows;\n\t\tvar row;\n\n\t\tsegRows = this.groupSegRows(segs); // group into nested arrays\n\n\t\t// iterate each row of segment groupings\n\t\tfor (row = 0; row < segRows.length; row++) {\n\t\t\trowStructs.push(\n\t\t\t\tthis.renderSegRow(row, segRows[row])\n\t\t\t);\n\t\t}\n\n\t\treturn rowStructs;\n\t},\n\n\n\t// Builds the HTML to be used for the default element for an individual segment\n\tfgSegHtml: function(seg, disableResizing) {\n\t\tvar view = this.view;\n\t\tvar event = seg.event;\n\t\tvar isDraggable = view.isEventDraggable(event);\n\t\tvar isResizableFromStart = !disableResizing && event.allDay &&\n\t\t\tseg.isStart && view.isEventResizableFromStart(event);\n\t\tvar isResizableFromEnd = !disableResizing && event.allDay &&\n\t\t\tseg.isEnd && view.isEventResizableFromEnd(event);\n\t\tvar classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd);\n\t\tvar skinCss = cssToStr(this.getEventSkinCss(event));\n\t\tvar timeHtml = '';\n\t\tvar timeText;\n\t\tvar titleHtml;\n\n\t\tclasses.unshift('fc-day-grid-event', 'fc-h-event');\n\n\t\t// Only display a timed events time if it is the starting segment\n\t\tif (seg.isStart) {\n\t\t\ttimeText = this.getEventTimeText(event);\n\t\t\tif (timeText) {\n\t\t\t\ttimeHtml = '' + htmlEscape(timeText) + '';\n\t\t\t}\n\t\t}\n\n\t\ttitleHtml =\n\t\t\t'' +\n\t\t\t\t(htmlEscape(event.title || '') || ' ') + // we always want one line of height\n\t\t\t'';\n\t\t\n\t\treturn '
' +\n\t\t\t\t'
' +\n\t\t\t\t\t(this.isRTL ?\n\t\t\t\t\t\ttitleHtml + ' ' + timeHtml : // put a natural space in between\n\t\t\t\t\t\ttimeHtml + ' ' + titleHtml //\n\t\t\t\t\t\t) +\n\t\t\t\t'
' +\n\t\t\t\t(isResizableFromStart ?\n\t\t\t\t\t'
' :\n\t\t\t\t\t''\n\t\t\t\t\t) +\n\t\t\t\t(isResizableFromEnd ?\n\t\t\t\t\t'
' :\n\t\t\t\t\t''\n\t\t\t\t\t) +\n\t\t\t'';\n\t},\n\n\n\t// Given a row # and an array of segments all in the same row, render a element, a skeleton that contains\n\t// the segments. Returns object with a bunch of internal data about how the render was calculated.\n\t// NOTE: modifies rowSegs\n\trenderSegRow: function(row, rowSegs) {\n\t\tvar colCnt = this.colCnt;\n\t\tvar segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels\n\t\tvar levelCnt = Math.max(1, segLevels.length); // ensure at least one level\n\t\tvar tbody = $('');\n\t\tvar segMatrix = []; // lookup for which segments are rendered into which level+col cells\n\t\tvar cellMatrix = []; // lookup for all elements of the level+col matrix\n\t\tvar loneCellMatrix = []; // lookup for elements that only take up a single column\n\t\tvar i, levelSegs;\n\t\tvar col;\n\t\tvar tr;\n\t\tvar j, seg;\n\t\tvar td;\n\n\t\t// populates empty cells from the current column (`col`) to `endCol`\n\t\tfunction emptyCellsUntil(endCol) {\n\t\t\twhile (col < endCol) {\n\t\t\t\t// try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell\n\t\t\t\ttd = (loneCellMatrix[i - 1] || [])[col];\n\t\t\t\tif (td) {\n\t\t\t\t\ttd.attr(\n\t\t\t\t\t\t'rowspan',\n\t\t\t\t\t\tparseInt(td.attr('rowspan') || 1, 10) + 1\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ttd = $('');\n\t\t\t\t\ttr.append(td);\n\t\t\t\t}\n\t\t\t\tcellMatrix[i][col] = td;\n\t\t\t\tloneCellMatrix[i][col] = td;\n\t\t\t\tcol++;\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < levelCnt; i++) { // iterate through all levels\n\t\t\tlevelSegs = segLevels[i];\n\t\t\tcol = 0;\n\t\t\ttr = $('');\n\n\t\t\tsegMatrix.push([]);\n\t\t\tcellMatrix.push([]);\n\t\t\tloneCellMatrix.push([]);\n\n\t\t\t// levelCnt might be 1 even though there are no actual levels. protect against this.\n\t\t\t// this single empty row is useful for styling.\n\t\t\tif (levelSegs) {\n\t\t\t\tfor (j = 0; j < levelSegs.length; j++) { // iterate through segments in level\n\t\t\t\t\tseg = levelSegs[j];\n\n\t\t\t\t\temptyCellsUntil(seg.leftCol);\n\n\t\t\t\t\t// create a container that occupies or more columns. append the event element.\n\t\t\t\t\ttd = $('').append(seg.el);\n\t\t\t\t\tif (seg.leftCol != seg.rightCol) {\n\t\t\t\t\t\ttd.attr('colspan', seg.rightCol - seg.leftCol + 1);\n\t\t\t\t\t}\n\t\t\t\t\telse { // a single-column segment\n\t\t\t\t\t\tloneCellMatrix[i][col] = td;\n\t\t\t\t\t}\n\n\t\t\t\t\twhile (col <= seg.rightCol) {\n\t\t\t\t\t\tcellMatrix[i][col] = td;\n\t\t\t\t\t\tsegMatrix[i][col] = seg;\n\t\t\t\t\t\tcol++;\n\t\t\t\t\t}\n\n\t\t\t\t\ttr.append(td);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\temptyCellsUntil(colCnt); // finish off the row\n\t\t\tthis.bookendCells(tr, 'eventSkeleton');\n\t\t\ttbody.append(tr);\n\t\t}\n\n\t\treturn { // a \"rowStruct\"\n\t\t\trow: row, // the row number\n\t\t\ttbodyEl: tbody,\n\t\t\tcellMatrix: cellMatrix,\n\t\t\tsegMatrix: segMatrix,\n\t\t\tsegLevels: segLevels,\n\t\t\tsegs: rowSegs\n\t\t};\n\t},\n\n\n\t// Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels.\n\t// NOTE: modifies segs\n\tbuildSegLevels: function(segs) {\n\t\tvar levels = [];\n\t\tvar i, seg;\n\t\tvar j;\n\n\t\t// Give preference to elements with certain criteria, so they have\n\t\t// a chance to be closer to the top.\n\t\tthis.sortSegs(segs);\n\t\t\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tseg = segs[i];\n\n\t\t\t// loop through levels, starting with the topmost, until the segment doesn't collide with other segments\n\t\t\tfor (j = 0; j < levels.length; j++) {\n\t\t\t\tif (!isDaySegCollision(seg, levels[j])) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// `j` now holds the desired subrow index\n\t\t\tseg.level = j;\n\n\t\t\t// create new level array if needed and append segment\n\t\t\t(levels[j] || (levels[j] = [])).push(seg);\n\t\t}\n\n\t\t// order segments left-to-right. very important if calendar is RTL\n\t\tfor (j = 0; j < levels.length; j++) {\n\t\t\tlevels[j].sort(compareDaySegCols);\n\t\t}\n\n\t\treturn levels;\n\t},\n\n\n\t// Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row\n\tgroupSegRows: function(segs) {\n\t\tvar segRows = [];\n\t\tvar i;\n\n\t\tfor (i = 0; i < this.rowCnt; i++) {\n\t\t\tsegRows.push([]);\n\t\t}\n\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tsegRows[segs[i].row].push(segs[i]);\n\t\t}\n\n\t\treturn segRows;\n\t}\n\n});\n\n\n// Computes whether two segments' columns collide. They are assumed to be in the same row.\nfunction isDaySegCollision(seg, otherSegs) {\n\tvar i, otherSeg;\n\n\tfor (i = 0; i < otherSegs.length; i++) {\n\t\totherSeg = otherSegs[i];\n\n\t\tif (\n\t\t\totherSeg.leftCol <= seg.rightCol &&\n\t\t\totherSeg.rightCol >= seg.leftCol\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n\n// A cmp function for determining the leftmost event\nfunction compareDaySegCols(a, b) {\n\treturn a.leftCol - b.leftCol;\n}\n\n;;\n\n/* Methods relate to limiting the number events for a given day on a DayGrid\n----------------------------------------------------------------------------------------------------------------------*/\n// NOTE: all the segs being passed around in here are foreground segs\n\nDayGrid.mixin({\n\n\tsegPopover: null, // the Popover that holds events that can't fit in a cell. null when not visible\n\tpopoverSegs: null, // an array of segment objects that the segPopover holds. null when not visible\n\n\n\tremoveSegPopover: function() {\n\t\tif (this.segPopover) {\n\t\t\tthis.segPopover.hide(); // in handler, will call segPopover's removeElement\n\t\t}\n\t},\n\n\n\t// Limits the number of \"levels\" (vertically stacking layers of events) for each row of the grid.\n\t// `levelLimit` can be false (don't limit), a number, or true (should be computed).\n\tlimitRows: function(levelLimit) {\n\t\tvar rowStructs = this.rowStructs || [];\n\t\tvar row; // row #\n\t\tvar rowLevelLimit;\n\n\t\tfor (row = 0; row < rowStructs.length; row++) {\n\t\t\tthis.unlimitRow(row);\n\n\t\t\tif (!levelLimit) {\n\t\t\t\trowLevelLimit = false;\n\t\t\t}\n\t\t\telse if (typeof levelLimit === 'number') {\n\t\t\t\trowLevelLimit = levelLimit;\n\t\t\t}\n\t\t\telse {\n\t\t\t\trowLevelLimit = this.computeRowLevelLimit(row);\n\t\t\t}\n\n\t\t\tif (rowLevelLimit !== false) {\n\t\t\t\tthis.limitRow(row, rowLevelLimit);\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Computes the number of levels a row will accomodate without going outside its bounds.\n\t// Assumes the row is \"rigid\" (maintains a constant height regardless of what is inside).\n\t// `row` is the row number.\n\tcomputeRowLevelLimit: function(row) {\n\t\tvar rowEl = this.rowEls.eq(row); // the containing \"fake\" row div\n\t\tvar rowHeight = rowEl.height(); // TODO: cache somehow?\n\t\tvar trEls = this.rowStructs[row].tbodyEl.children();\n\t\tvar i, trEl;\n\t\tvar trHeight;\n\n\t\tfunction iterInnerHeights(i, childNode) {\n\t\t\ttrHeight = Math.max(trHeight, $(childNode).outerHeight());\n\t\t}\n\n\t\t// Reveal one level at a time and stop when we find one out of bounds\n\t\tfor (i = 0; i < trEls.length; i++) {\n\t\t\ttrEl = trEls.eq(i).removeClass('fc-limited'); // reset to original state (reveal)\n\n\t\t\t// with rowspans>1 and IE8, trEl.outerHeight() would return the height of the largest cell,\n\t\t\t// so instead, find the tallest inner content element.\n\t\t\ttrHeight = 0;\n\t\t\ttrEl.find('> td > :first-child').each(iterInnerHeights);\n\n\t\t\tif (trEl.position().top + trHeight > rowHeight) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\n\t\treturn false; // should not limit at all\n\t},\n\n\n\t// Limits the given grid row to the maximum number of levels and injects \"more\" links if necessary.\n\t// `row` is the row number.\n\t// `levelLimit` is a number for the maximum (inclusive) number of levels allowed.\n\tlimitRow: function(row, levelLimit) {\n\t\tvar _this = this;\n\t\tvar rowStruct = this.rowStructs[row];\n\t\tvar moreNodes = []; // array of \"more\" links and DOM nodes\n\t\tvar col = 0; // col #, left-to-right (not chronologically)\n\t\tvar cell;\n\t\tvar levelSegs; // array of segment objects in the last allowable level, ordered left-to-right\n\t\tvar cellMatrix; // a matrix (by level, then column) of all jQuery elements in the row\n\t\tvar limitedNodes; // array of temporarily hidden level and segment DOM nodes\n\t\tvar i, seg;\n\t\tvar segsBelow; // array of segment objects below `seg` in the current `col`\n\t\tvar totalSegsBelow; // total number of segments below `seg` in any of the columns `seg` occupies\n\t\tvar colSegsBelow; // array of segment arrays, below seg, one for each column (offset from segs's first column)\n\t\tvar td, rowspan;\n\t\tvar segMoreNodes; // array of \"more\" cells that will stand-in for the current seg's cell\n\t\tvar j;\n\t\tvar moreTd, moreWrap, moreLink;\n\n\t\t// Iterates through empty level cells and places \"more\" links inside if need be\n\t\tfunction emptyCellsUntil(endCol) { // goes from current `col` to `endCol`\n\t\t\twhile (col < endCol) {\n\t\t\t\tcell = _this.getCell(row, col);\n\t\t\t\tsegsBelow = _this.getCellSegs(cell, levelLimit);\n\t\t\t\tif (segsBelow.length) {\n\t\t\t\t\ttd = cellMatrix[levelLimit - 1][col];\n\t\t\t\t\tmoreLink = _this.renderMoreLink(cell, segsBelow);\n\t\t\t\t\tmoreWrap = $('
').append(moreLink);\n\t\t\t\t\ttd.append(moreWrap);\n\t\t\t\t\tmoreNodes.push(moreWrap[0]);\n\t\t\t\t}\n\t\t\t\tcol++;\n\t\t\t}\n\t\t}\n\n\t\tif (levelLimit && levelLimit < rowStruct.segLevels.length) { // is it actually over the limit?\n\t\t\tlevelSegs = rowStruct.segLevels[levelLimit - 1];\n\t\t\tcellMatrix = rowStruct.cellMatrix;\n\n\t\t\tlimitedNodes = rowStruct.tbodyEl.children().slice(levelLimit) // get level elements past the limit\n\t\t\t\t.addClass('fc-limited').get(); // hide elements and get a simple DOM-nodes array\n\n\t\t\t// iterate though segments in the last allowable level\n\t\t\tfor (i = 0; i < levelSegs.length; i++) {\n\t\t\t\tseg = levelSegs[i];\n\t\t\t\temptyCellsUntil(seg.leftCol); // process empty cells before the segment\n\n\t\t\t\t// determine *all* segments below `seg` that occupy the same columns\n\t\t\t\tcolSegsBelow = [];\n\t\t\t\ttotalSegsBelow = 0;\n\t\t\t\twhile (col <= seg.rightCol) {\n\t\t\t\t\tcell = this.getCell(row, col);\n\t\t\t\t\tsegsBelow = this.getCellSegs(cell, levelLimit);\n\t\t\t\t\tcolSegsBelow.push(segsBelow);\n\t\t\t\t\ttotalSegsBelow += segsBelow.length;\n\t\t\t\t\tcol++;\n\t\t\t\t}\n\n\t\t\t\tif (totalSegsBelow) { // do we need to replace this segment with one or many \"more\" links?\n\t\t\t\t\ttd = cellMatrix[levelLimit - 1][seg.leftCol]; // the segment's parent cell\n\t\t\t\t\trowspan = td.attr('rowspan') || 1;\n\t\t\t\t\tsegMoreNodes = [];\n\n\t\t\t\t\t// make a replacement for each column the segment occupies. will be one for each colspan\n\t\t\t\t\tfor (j = 0; j < colSegsBelow.length; j++) {\n\t\t\t\t\t\tmoreTd = $('').attr('rowspan', rowspan);\n\t\t\t\t\t\tsegsBelow = colSegsBelow[j];\n\t\t\t\t\t\tcell = this.getCell(row, seg.leftCol + j);\n\t\t\t\t\t\tmoreLink = this.renderMoreLink(cell, [ seg ].concat(segsBelow)); // count seg as hidden too\n\t\t\t\t\t\tmoreWrap = $('
').append(moreLink);\n\t\t\t\t\t\tmoreTd.append(moreWrap);\n\t\t\t\t\t\tsegMoreNodes.push(moreTd[0]);\n\t\t\t\t\t\tmoreNodes.push(moreTd[0]);\n\t\t\t\t\t}\n\n\t\t\t\t\ttd.addClass('fc-limited').after($(segMoreNodes)); // hide original and inject replacements\n\t\t\t\t\tlimitedNodes.push(td[0]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\temptyCellsUntil(this.colCnt); // finish off the level\n\t\t\trowStruct.moreEls = $(moreNodes); // for easy undoing later\n\t\t\trowStruct.limitedEls = $(limitedNodes); // for easy undoing later\n\t\t}\n\t},\n\n\n\t// Reveals all levels and removes all \"more\"-related elements for a grid's row.\n\t// `row` is a row number.\n\tunlimitRow: function(row) {\n\t\tvar rowStruct = this.rowStructs[row];\n\n\t\tif (rowStruct.moreEls) {\n\t\t\trowStruct.moreEls.remove();\n\t\t\trowStruct.moreEls = null;\n\t\t}\n\n\t\tif (rowStruct.limitedEls) {\n\t\t\trowStruct.limitedEls.removeClass('fc-limited');\n\t\t\trowStruct.limitedEls = null;\n\t\t}\n\t},\n\n\n\t// Renders an element that represents hidden event element for a cell.\n\t// Responsible for attaching click handler as well.\n\trenderMoreLink: function(cell, hiddenSegs) {\n\t\tvar _this = this;\n\t\tvar view = this.view;\n\n\t\treturn $('')\n\t\t\t.text(\n\t\t\t\tthis.getMoreLinkText(hiddenSegs.length)\n\t\t\t)\n\t\t\t.on('click', function(ev) {\n\t\t\t\tvar clickOption = view.opt('eventLimitClick');\n\t\t\t\tvar date = cell.start;\n\t\t\t\tvar moreEl = $(this);\n\t\t\t\tvar dayEl = _this.getCellDayEl(cell);\n\t\t\t\tvar allSegs = _this.getCellSegs(cell);\n\n\t\t\t\t// rescope the segments to be within the cell's date\n\t\t\t\tvar reslicedAllSegs = _this.resliceDaySegs(allSegs, date);\n\t\t\t\tvar reslicedHiddenSegs = _this.resliceDaySegs(hiddenSegs, date);\n\n\t\t\t\tif (typeof clickOption === 'function') {\n\t\t\t\t\t// the returned value can be an atomic option\n\t\t\t\t\tclickOption = view.trigger('eventLimitClick', null, {\n\t\t\t\t\t\tdate: date,\n\t\t\t\t\t\tdayEl: dayEl,\n\t\t\t\t\t\tmoreEl: moreEl,\n\t\t\t\t\t\tsegs: reslicedAllSegs,\n\t\t\t\t\t\thiddenSegs: reslicedHiddenSegs\n\t\t\t\t\t}, ev);\n\t\t\t\t}\n\n\t\t\t\tif (clickOption === 'popover') {\n\t\t\t\t\t_this.showSegPopover(cell, moreEl, reslicedAllSegs);\n\t\t\t\t}\n\t\t\t\telse if (typeof clickOption === 'string') { // a view name\n\t\t\t\t\tview.calendar.zoomTo(date, clickOption);\n\t\t\t\t}\n\t\t\t});\n\t},\n\n\n\t// Reveals the popover that displays all events within a cell\n\tshowSegPopover: function(cell, moreLink, segs) {\n\t\tvar _this = this;\n\t\tvar view = this.view;\n\t\tvar moreWrap = moreLink.parent(); // the
wrapper around the \n\t\tvar topEl; // the element we want to match the top coordinate of\n\t\tvar options;\n\n\t\tif (this.rowCnt == 1) {\n\t\t\ttopEl = view.el; // will cause the popover to cover any sort of header\n\t\t}\n\t\telse {\n\t\t\ttopEl = this.rowEls.eq(cell.row); // will align with top of row\n\t\t}\n\n\t\toptions = {\n\t\t\tclassName: 'fc-more-popover',\n\t\t\tcontent: this.renderSegPopoverContent(cell, segs),\n\t\t\tparentEl: this.el,\n\t\t\ttop: topEl.offset().top,\n\t\t\tautoHide: true, // when the user clicks elsewhere, hide the popover\n\t\t\tviewportConstrain: view.opt('popoverViewportConstrain'),\n\t\t\thide: function() {\n\t\t\t\t// kill everything when the popover is hidden\n\t\t\t\t_this.segPopover.removeElement();\n\t\t\t\t_this.segPopover = null;\n\t\t\t\t_this.popoverSegs = null;\n\t\t\t}\n\t\t};\n\n\t\t// Determine horizontal coordinate.\n\t\t// We use the moreWrap instead of the to avoid border confusion.\n\t\tif (this.isRTL) {\n\t\t\toptions.right = moreWrap.offset().left + moreWrap.outerWidth() + 1; // +1 to be over cell border\n\t\t}\n\t\telse {\n\t\t\toptions.left = moreWrap.offset().left - 1; // -1 to be over cell border\n\t\t}\n\n\t\tthis.segPopover = new Popover(options);\n\t\tthis.segPopover.show();\n\t},\n\n\n\t// Builds the inner DOM contents of the segment popover\n\trenderSegPopoverContent: function(cell, segs) {\n\t\tvar view = this.view;\n\t\tvar isTheme = view.opt('theme');\n\t\tvar title = cell.start.format(view.opt('dayPopoverFormat'));\n\t\tvar content = $(\n\t\t\t'
' +\n\t\t\t\t'' +\n\t\t\t\t'' +\n\t\t\t\t\thtmlEscape(title) +\n\t\t\t\t'' +\n\t\t\t\t'
' +\n\t\t\t'
' +\n\t\t\t'
' +\n\t\t\t\t'
' +\n\t\t\t'
'\n\t\t);\n\t\tvar segContainer = content.find('.fc-event-container');\n\t\tvar i;\n\n\t\t// render each seg's `el` and only return the visible segs\n\t\tsegs = this.renderFgSegEls(segs, true); // disableResizing=true\n\t\tthis.popoverSegs = segs;\n\n\t\tfor (i = 0; i < segs.length; i++) {\n\n\t\t\t// because segments in the popover are not part of a grid coordinate system, provide a hint to any\n\t\t\t// grids that want to do drag-n-drop about which cell it came from\n\t\t\tsegs[i].cell = cell;\n\n\t\t\tsegContainer.append(segs[i].el);\n\t\t}\n\n\t\treturn content;\n\t},\n\n\n\t// Given the events within an array of segment objects, reslice them to be in a single day\n\tresliceDaySegs: function(segs, dayDate) {\n\n\t\t// build an array of the original events\n\t\tvar events = $.map(segs, function(seg) {\n\t\t\treturn seg.event;\n\t\t});\n\n\t\tvar dayStart = dayDate.clone().stripTime();\n\t\tvar dayEnd = dayStart.clone().add(1, 'days');\n\t\tvar dayRange = { start: dayStart, end: dayEnd };\n\n\t\t// slice the events with a custom slicing function\n\t\tsegs = this.eventsToSegs(\n\t\t\tevents,\n\t\t\tfunction(range) {\n\t\t\t\tvar seg = intersectionToSeg(range, dayRange); // undefind if no intersection\n\t\t\t\treturn seg ? [ seg ] : []; // must return an array of segments\n\t\t\t}\n\t\t);\n\n\t\t// force an order because eventsToSegs doesn't guarantee one\n\t\tthis.sortSegs(segs);\n\n\t\treturn segs;\n\t},\n\n\n\t// Generates the text that should be inside a \"more\" link, given the number of events it represents\n\tgetMoreLinkText: function(num) {\n\t\tvar opt = this.view.opt('eventLimitText');\n\n\t\tif (typeof opt === 'function') {\n\t\t\treturn opt(num);\n\t\t}\n\t\telse {\n\t\t\treturn '+' + num + ' ' + opt;\n\t\t}\n\t},\n\n\n\t// Returns segments within a given cell.\n\t// If `startLevel` is specified, returns only events including and below that level. Otherwise returns all segs.\n\tgetCellSegs: function(cell, startLevel) {\n\t\tvar segMatrix = this.rowStructs[cell.row].segMatrix;\n\t\tvar level = startLevel || 0;\n\t\tvar segs = [];\n\t\tvar seg;\n\n\t\twhile (level < segMatrix.length) {\n\t\t\tseg = segMatrix[level][cell.col];\n\t\t\tif (seg) {\n\t\t\t\tsegs.push(seg);\n\t\t\t}\n\t\t\tlevel++;\n\t\t}\n\n\t\treturn segs;\n\t}\n\n});\n\n;;\n\n/* A component that renders one or more columns of vertical time slots\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar TimeGrid = Grid.extend({\n\n\tslotDuration: null, // duration of a \"slot\", a distinct time segment on given day, visualized by lines\n\tsnapDuration: null, // granularity of time for dragging and selecting\n\tminTime: null, // Duration object that denotes the first visible time of any given day\n\tmaxTime: null, // Duration object that denotes the exclusive visible end time of any given day\n\tcolDates: null, // whole-day dates for each column. left to right\n\tlabelFormat: null, // formatting string for times running along vertical axis\n\tlabelInterval: null, // duration of how often a label should be displayed for a slot\n\n\tdayEls: null, // cells elements in the day-row background\n\tslatEls: null, // elements running horizontally across all columns\n\n\tslatTops: null, // an array of top positions, relative to the container. last item holds bottom of last slot\n\n\thelperEl: null, // cell skeleton element for rendering the mock event \"helper\"\n\n\tbusinessHourSegs: null,\n\n\n\tconstructor: function() {\n\t\tGrid.apply(this, arguments); // call the super-constructor\n\t\tthis.processOptions();\n\t},\n\n\n\t// Renders the time grid into `this.el`, which should already be assigned.\n\t// Relies on the view's colCnt. In the future, this component should probably be self-sufficient.\n\trenderDates: function() {\n\t\tthis.el.html(this.renderHtml());\n\t\tthis.dayEls = this.el.find('.fc-day');\n\t\tthis.slatEls = this.el.find('.fc-slats tr');\n\t},\n\n\n\trenderBusinessHours: function() {\n\t\tvar events = this.view.calendar.getBusinessHoursEvents();\n\t\tthis.businessHourSegs = this.renderFill('businessHours', this.eventsToSegs(events), 'bgevent');\n\t},\n\n\n\t// Renders the basic HTML skeleton for the grid\n\trenderHtml: function() {\n\t\treturn '' +\n\t\t\t'
' +\n\t\t\t\t'' +\n\t\t\t\t\tthis.rowHtml('slotBg') + // leverages RowRenderer, which will call slotBgCellHtml\n\t\t\t\t'
' +\n\t\t\t'
' +\n\t\t\t'
' +\n\t\t\t\t'' +\n\t\t\t\t\tthis.slatRowHtml() +\n\t\t\t\t'
' +\n\t\t\t'
';\n\t},\n\n\n\t// Renders the HTML for a vertical background cell behind the slots.\n\t// This method is distinct from 'bg' because we wanted a new `rowType` so the View could customize the rendering.\n\tslotBgCellHtml: function(cell) {\n\t\treturn this.bgCellHtml(cell);\n\t},\n\n\n\t// Generates the HTML for the horizontal \"slats\" that run width-wise. Has a time axis on a side. Depends on RTL.\n\tslatRowHtml: function() {\n\t\tvar view = this.view;\n\t\tvar isRTL = this.isRTL;\n\t\tvar html = '';\n\t\tvar slotTime = moment.duration(+this.minTime); // wish there was .clone() for durations\n\t\tvar slotDate; // will be on the view's first day, but we only care about its time\n\t\tvar isLabeled;\n\t\tvar axisHtml;\n\n\t\t// Calculate the time for each slot\n\t\twhile (slotTime < this.maxTime) {\n\t\t\tslotDate = this.start.clone().time(slotTime); // after .time() will be in UTC. but that's good, avoids DST issues\n\t\t\tisLabeled = isInt(divideDurationByDuration(slotTime, this.labelInterval));\n\n\t\t\taxisHtml =\n\t\t\t\t'' +\n\t\t\t\t\t(isLabeled ?\n\t\t\t\t\t\t'' + // for matchCellWidths\n\t\t\t\t\t\t\thtmlEscape(slotDate.format(this.labelFormat)) +\n\t\t\t\t\t\t'' :\n\t\t\t\t\t\t''\n\t\t\t\t\t\t) +\n\t\t\t\t'';\n\n\t\t\thtml +=\n\t\t\t\t'' +\n\t\t\t\t\t(!isRTL ? axisHtml : '') +\n\t\t\t\t\t'' +\n\t\t\t\t\t(isRTL ? axisHtml : '') +\n\t\t\t\t\"\";\n\n\t\t\tslotTime.add(this.slotDuration);\n\t\t}\n\n\t\treturn html;\n\t},\n\n\n\t/* Options\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Parses various options into properties of this object\n\tprocessOptions: function() {\n\t\tvar view = this.view;\n\t\tvar slotDuration = view.opt('slotDuration');\n\t\tvar snapDuration = view.opt('snapDuration');\n\t\tvar input;\n\n\t\tslotDuration = moment.duration(slotDuration);\n\t\tsnapDuration = snapDuration ? moment.duration(snapDuration) : slotDuration;\n\n\t\tthis.slotDuration = slotDuration;\n\t\tthis.snapDuration = snapDuration;\n\t\tthis.cellDuration = snapDuration; // for Grid system\n\n\t\tthis.minTime = moment.duration(view.opt('minTime'));\n\t\tthis.maxTime = moment.duration(view.opt('maxTime'));\n\n\t\t// might be an array value (for TimelineView).\n\t\t// if so, getting the most granular entry (the last one probably).\n\t\tinput = view.opt('slotLabelFormat');\n\t\tif ($.isArray(input)) {\n\t\t\tinput = input[input.length - 1];\n\t\t}\n\n\t\tthis.labelFormat =\n\t\t\tinput ||\n\t\t\tview.opt('axisFormat') || // deprecated\n\t\t\tview.opt('smallTimeFormat'); // the computed default\n\n\t\tinput = view.opt('slotLabelInterval');\n\t\tthis.labelInterval = input ?\n\t\t\tmoment.duration(input) :\n\t\t\tthis.computeLabelInterval(slotDuration);\n\t},\n\n\n\t// Computes an automatic value for slotLabelInterval\n\tcomputeLabelInterval: function(slotDuration) {\n\t\tvar i;\n\t\tvar labelInterval;\n\t\tvar slotsPerLabel;\n\n\t\t// find the smallest stock label interval that results in more than one slots-per-label\n\t\tfor (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) {\n\t\t\tlabelInterval = moment.duration(AGENDA_STOCK_SUB_DURATIONS[i]);\n\t\t\tslotsPerLabel = divideDurationByDuration(labelInterval, slotDuration);\n\t\t\tif (isInt(slotsPerLabel) && slotsPerLabel > 1) {\n\t\t\t\treturn labelInterval;\n\t\t\t}\n\t\t}\n\n\t\treturn moment.duration(slotDuration); // fall back. clone\n\t},\n\n\n\t// Computes a default column header formatting string if `colFormat` is not explicitly defined\n\tcomputeColHeadFormat: function() {\n\t\tif (this.colCnt > 1) { // multiple days, so full single date string WON'T be in title text\n\t\t\treturn this.view.opt('dayOfMonthFormat'); // \"Sat 12/10\"\n\t\t}\n\t\telse { // single day, so full single date string will probably be in title text\n\t\t\treturn 'dddd'; // \"Saturday\"\n\t\t}\n\t},\n\n\n\t// Computes a default event time formatting string if `timeFormat` is not explicitly defined\n\tcomputeEventTimeFormat: function() {\n\t\treturn this.view.opt('noMeridiemTimeFormat'); // like \"6:30\" (no AM/PM)\n\t},\n\n\n\t// Computes a default `displayEventEnd` value if one is not expliclty defined\n\tcomputeDisplayEventEnd: function() {\n\t\treturn true;\n\t},\n\n\n\t/* Cell System\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\trangeUpdated: function() {\n\t\tvar view = this.view;\n\t\tvar colDates = [];\n\t\tvar date;\n\n\t\tdate = this.start.clone();\n\t\twhile (date.isBefore(this.end)) {\n\t\t\tcolDates.push(date.clone());\n\t\t\tdate.add(1, 'day');\n\t\t\tdate = view.skipHiddenDays(date);\n\t\t}\n\n\t\tif (this.isRTL) {\n\t\t\tcolDates.reverse();\n\t\t}\n\n\t\tthis.colDates = colDates;\n\t\tthis.colCnt = colDates.length;\n\t\tthis.rowCnt = Math.ceil((this.maxTime - this.minTime) / this.snapDuration); // # of vertical snaps\n\t},\n\n\n\t// Given a cell object, generates its start date. Returns a reference-free copy.\n\tcomputeCellDate: function(cell) {\n\t\tvar date = this.colDates[cell.col];\n\t\tvar time = this.computeSnapTime(cell.row);\n\n\t\tdate = this.view.calendar.rezoneDate(date); // give it a 00:00 time\n\t\tdate.time(time);\n\n\t\treturn date;\n\t},\n\n\n\t// Retrieves the element representing the given column\n\tgetColEl: function(col) {\n\t\treturn this.dayEls.eq(col);\n\t},\n\n\n\t/* Dates\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Given a row number of the grid, representing a \"snap\", returns a time (Duration) from its start-of-day\n\tcomputeSnapTime: function(row) {\n\t\treturn moment.duration(this.minTime + this.snapDuration * row);\n\t},\n\n\n\t// Slices up a date range by column into an array of segments\n\trangeToSegs: function(range) {\n\t\tvar colCnt = this.colCnt;\n\t\tvar segs = [];\n\t\tvar seg;\n\t\tvar col;\n\t\tvar colDate;\n\t\tvar colRange;\n\n\t\t// normalize :(\n\t\trange = {\n\t\t\tstart: range.start.clone().stripZone(),\n\t\t\tend: range.end.clone().stripZone()\n\t\t};\n\n\t\tfor (col = 0; col < colCnt; col++) {\n\t\t\tcolDate = this.colDates[col]; // will be ambig time/timezone\n\t\t\tcolRange = {\n\t\t\t\tstart: colDate.clone().time(this.minTime),\n\t\t\t\tend: colDate.clone().time(this.maxTime)\n\t\t\t};\n\t\t\tseg = intersectionToSeg(range, colRange); // both will be ambig timezone\n\t\t\tif (seg) {\n\t\t\t\tseg.col = col;\n\t\t\t\tsegs.push(seg);\n\t\t\t}\n\t\t}\n\n\t\treturn segs;\n\t},\n\n\n\t/* Coordinates\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\tupdateSize: function(isResize) { // NOT a standard Grid method\n\t\tthis.computeSlatTops();\n\n\t\tif (isResize) {\n\t\t\tthis.updateSegVerticals();\n\t\t}\n\t},\n\n\n\t// Computes the top/bottom coordinates of each \"snap\" rows\n\tcomputeRowCoords: function() {\n\t\tvar originTop = this.el.offset().top;\n\t\tvar items = [];\n\t\tvar i;\n\t\tvar item;\n\n\t\tfor (i = 0; i < this.rowCnt; i++) {\n\t\t\titem = {\n\t\t\t\ttop: originTop + this.computeTimeTop(this.computeSnapTime(i))\n\t\t\t};\n\t\t\tif (i > 0) {\n\t\t\t\titems[i - 1].bottom = item.top;\n\t\t\t}\n\t\t\titems.push(item);\n\t\t}\n\t\titem.bottom = item.top + this.computeTimeTop(this.computeSnapTime(i));\n\n\t\treturn items;\n\t},\n\n\n\t// Computes the top coordinate, relative to the bounds of the grid, of the given date.\n\t// A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.\n\tcomputeDateTop: function(date, startOfDayDate) {\n\t\treturn this.computeTimeTop(\n\t\t\tmoment.duration(\n\t\t\t\tdate.clone().stripZone() - startOfDayDate.clone().stripTime()\n\t\t\t)\n\t\t);\n\t},\n\n\n\t// Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).\n\tcomputeTimeTop: function(time) {\n\t\tvar slatCoverage = (time - this.minTime) / this.slotDuration; // floating-point value of # of slots covered\n\t\tvar slatIndex;\n\t\tvar slatRemainder;\n\t\tvar slatTop;\n\t\tvar slatBottom;\n\n\t\t// constrain. because minTime/maxTime might be customized\n\t\tslatCoverage = Math.max(0, slatCoverage);\n\t\tslatCoverage = Math.min(this.slatEls.length, slatCoverage);\n\n\t\tslatIndex = Math.floor(slatCoverage); // an integer index of the furthest whole slot\n\t\tslatRemainder = slatCoverage - slatIndex;\n\t\tslatTop = this.slatTops[slatIndex]; // the top position of the furthest whole slot\n\n\t\tif (slatRemainder) { // time spans part-way into the slot\n\t\t\tslatBottom = this.slatTops[slatIndex + 1];\n\t\t\treturn slatTop + (slatBottom - slatTop) * slatRemainder; // part-way between slots\n\t\t}\n\t\telse {\n\t\t\treturn slatTop;\n\t\t}\n\t},\n\n\n\t// Queries each `slatEl` for its position relative to the grid's container and stores it in `slatTops`.\n\t// Includes the the bottom of the last slat as the last item in the array.\n\tcomputeSlatTops: function() {\n\t\tvar tops = [];\n\t\tvar top;\n\n\t\tthis.slatEls.each(function(i, node) {\n\t\t\ttop = $(node).position().top;\n\t\t\ttops.push(top);\n\t\t});\n\n\t\ttops.push(top + this.slatEls.last().outerHeight()); // bottom of the last slat\n\n\t\tthis.slatTops = tops;\n\t},\n\n\n\t/* Event Drag Visualization\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of an event being dragged over the specified date(s).\n\t// dropLocation's end might be null, as well as `seg`. See Grid::renderDrag for more info.\n\t// A returned value of `true` signals that a mock \"helper\" event has been rendered.\n\trenderDrag: function(dropLocation, seg) {\n\n\t\tif (seg) { // if there is event information for this drag, render a helper event\n\t\t\tthis.renderRangeHelper(dropLocation, seg);\n\t\t\tthis.applyDragOpacity(this.helperEl);\n\n\t\t\treturn true; // signal that a helper has been rendered\n\t\t}\n\t\telse {\n\t\t\t// otherwise, just render a highlight\n\t\t\tthis.renderHighlight(this.eventRangeToSegs(dropLocation));\n\t\t}\n\t},\n\n\n\t// Unrenders any visual indication of an event being dragged\n\tunrenderDrag: function() {\n\t\tthis.unrenderHelper();\n\t\tthis.unrenderHighlight();\n\t},\n\n\n\t/* Event Resize Visualization\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of an event being resized\n\trenderEventResize: function(range, seg) {\n\t\tthis.renderRangeHelper(range, seg);\n\t},\n\n\n\t// Unrenders any visual indication of an event being resized\n\tunrenderEventResize: function() {\n\t\tthis.unrenderHelper();\n\t},\n\n\n\t/* Event Helper\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a mock \"helper\" event. `sourceSeg` is the original segment object and might be null (an external drag)\n\trenderHelper: function(event, sourceSeg) {\n\t\tvar segs = this.eventsToSegs([ event ]);\n\t\tvar tableEl;\n\t\tvar i, seg;\n\t\tvar sourceEl;\n\n\t\tsegs = this.renderFgSegEls(segs); // assigns each seg's el and returns a subset of segs that were rendered\n\t\ttableEl = this.renderSegTable(segs);\n\n\t\t// Try to make the segment that is in the same row as sourceSeg look the same\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tseg = segs[i];\n\t\t\tif (sourceSeg && sourceSeg.col === seg.col) {\n\t\t\t\tsourceEl = sourceSeg.el;\n\t\t\t\tseg.el.css({\n\t\t\t\t\tleft: sourceEl.css('left'),\n\t\t\t\t\tright: sourceEl.css('right'),\n\t\t\t\t\t'margin-left': sourceEl.css('margin-left'),\n\t\t\t\t\t'margin-right': sourceEl.css('margin-right')\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis.helperEl = $('
')\n\t\t\t.append(tableEl)\n\t\t\t\t.appendTo(this.el);\n\t},\n\n\n\t// Unrenders any mock helper event\n\tunrenderHelper: function() {\n\t\tif (this.helperEl) {\n\t\t\tthis.helperEl.remove();\n\t\t\tthis.helperEl = null;\n\t\t}\n\t},\n\n\n\t/* Selection\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight.\n\trenderSelection: function(range) {\n\t\tif (this.view.opt('selectHelper')) { // this setting signals that a mock helper event should be rendered\n\t\t\tthis.renderRangeHelper(range);\n\t\t}\n\t\telse {\n\t\t\tthis.renderHighlight(this.selectionRangeToSegs(range));\n\t\t}\n\t},\n\n\n\t// Unrenders any visual indication of a selection\n\tunrenderSelection: function() {\n\t\tthis.unrenderHelper();\n\t\tthis.unrenderHighlight();\n\t},\n\n\n\t/* Fill System (highlight, background events, business hours)\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a set of rectangles over the given time segments.\n\t// Only returns segments that successfully rendered.\n\trenderFill: function(type, segs, className) {\n\t\tvar segCols;\n\t\tvar skeletonEl;\n\t\tvar trEl;\n\t\tvar col, colSegs;\n\t\tvar tdEl;\n\t\tvar containerEl;\n\t\tvar dayDate;\n\t\tvar i, seg;\n\n\t\tif (segs.length) {\n\n\t\t\tsegs = this.renderFillSegEls(type, segs); // assignes `.el` to each seg. returns successfully rendered segs\n\t\t\tsegCols = this.groupSegCols(segs); // group into sub-arrays, and assigns 'col' to each seg\n\n\t\t\tclassName = className || type.toLowerCase();\n\t\t\tskeletonEl = $(\n\t\t\t\t'
' +\n\t\t\t\t\t'
' +\n\t\t\t\t'
'\n\t\t\t);\n\t\t\ttrEl = skeletonEl.find('tr');\n\n\t\t\tfor (col = 0; col < segCols.length; col++) {\n\t\t\t\tcolSegs = segCols[col];\n\t\t\t\ttdEl = $('').appendTo(trEl);\n\n\t\t\t\tif (colSegs.length) {\n\t\t\t\t\tcontainerEl = $('
').appendTo(tdEl);\n\t\t\t\t\tdayDate = this.colDates[col];\n\n\t\t\t\t\tfor (i = 0; i < colSegs.length; i++) {\n\t\t\t\t\t\tseg = colSegs[i];\n\t\t\t\t\t\tcontainerEl.append(\n\t\t\t\t\t\t\tseg.el.css({\n\t\t\t\t\t\t\t\ttop: this.computeDateTop(seg.start, dayDate),\n\t\t\t\t\t\t\t\tbottom: -this.computeDateTop(seg.end, dayDate) // the y position of the bottom edge\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.bookendCells(trEl, type);\n\n\t\t\tthis.el.append(skeletonEl);\n\t\t\tthis.elsByFill[type] = skeletonEl;\n\t\t}\n\n\t\treturn segs;\n\t}\n\n});\n\n;;\n\n/* Event-rendering methods for the TimeGrid class\n----------------------------------------------------------------------------------------------------------------------*/\n\nTimeGrid.mixin({\n\n\teventSkeletonEl: null, // has cells with event-containers, which contain absolutely positioned event elements\n\n\n\t// Renders the given foreground event segments onto the grid\n\trenderFgSegs: function(segs) {\n\t\tsegs = this.renderFgSegEls(segs); // returns a subset of the segs. segs that were actually rendered\n\n\t\tthis.el.append(\n\t\t\tthis.eventSkeletonEl = $('
')\n\t\t\t\t.append(this.renderSegTable(segs))\n\t\t);\n\n\t\treturn segs; // return only the segs that were actually rendered\n\t},\n\n\n\t// Unrenders all currently rendered foreground event segments\n\tunrenderFgSegs: function(segs) {\n\t\tif (this.eventSkeletonEl) {\n\t\t\tthis.eventSkeletonEl.remove();\n\t\t\tthis.eventSkeletonEl = null;\n\t\t}\n\t},\n\n\n\t// Renders and returns the portion of the event-skeleton.\n\t// Returns an object with properties 'tbodyEl' and 'segs'.\n\trenderSegTable: function(segs) {\n\t\tvar tableEl = $('
');\n\t\tvar trEl = tableEl.find('tr');\n\t\tvar segCols;\n\t\tvar i, seg;\n\t\tvar col, colSegs;\n\t\tvar containerEl;\n\n\t\tsegCols = this.groupSegCols(segs); // group into sub-arrays, and assigns 'col' to each seg\n\n\t\tthis.computeSegVerticals(segs); // compute and assign top/bottom\n\n\t\tfor (col = 0; col < segCols.length; col++) { // iterate each column grouping\n\t\t\tcolSegs = segCols[col];\n\t\t\tthis.placeSlotSegs(colSegs); // compute horizontal coordinates, z-index's, and reorder the array\n\n\t\t\tcontainerEl = $('
');\n\n\t\t\t// assign positioning CSS and insert into container\n\t\t\tfor (i = 0; i < colSegs.length; i++) {\n\t\t\t\tseg = colSegs[i];\n\t\t\t\tseg.el.css(this.generateSegPositionCss(seg));\n\n\t\t\t\t// if the height is short, add a className for alternate styling\n\t\t\t\tif (seg.bottom - seg.top < 30) {\n\t\t\t\t\tseg.el.addClass('fc-short');\n\t\t\t\t}\n\n\t\t\t\tcontainerEl.append(seg.el);\n\t\t\t}\n\n\t\t\ttrEl.append($('').append(containerEl));\n\t\t}\n\n\t\tthis.bookendCells(trEl, 'eventSkeleton');\n\n\t\treturn tableEl;\n\t},\n\n\n\t// Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.\n\t// NOTE: Also reorders the given array by date!\n\tplaceSlotSegs: function(segs) {\n\t\tvar levels;\n\t\tvar level0;\n\t\tvar i;\n\n\t\tthis.sortSegs(segs); // order by date\n\t\tlevels = buildSlotSegLevels(segs);\n\t\tcomputeForwardSlotSegs(levels);\n\n\t\tif ((level0 = levels[0])) {\n\n\t\t\tfor (i = 0; i < level0.length; i++) {\n\t\t\t\tcomputeSlotSegPressures(level0[i]);\n\t\t\t}\n\n\t\t\tfor (i = 0; i < level0.length; i++) {\n\t\t\t\tthis.computeSlotSegCoords(level0[i], 0, 0);\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range\n\t// from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to \"left\" and\n\t// seg.forwardCoord maps to \"right\" (via percentage). Vice-versa if the calendar is right-to-left.\n\t//\n\t// The segment might be part of a \"series\", which means consecutive segments with the same pressure\n\t// who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of\n\t// segments behind this one in the current series, and `seriesBackwardCoord` is the starting\n\t// coordinate of the first segment in the series.\n\tcomputeSlotSegCoords: function(seg, seriesBackwardPressure, seriesBackwardCoord) {\n\t\tvar forwardSegs = seg.forwardSegs;\n\t\tvar i;\n\n\t\tif (seg.forwardCoord === undefined) { // not already computed\n\n\t\t\tif (!forwardSegs.length) {\n\n\t\t\t\t// if there are no forward segments, this segment should butt up against the edge\n\t\t\t\tseg.forwardCoord = 1;\n\t\t\t}\n\t\t\telse {\n\n\t\t\t\t// sort highest pressure first\n\t\t\t\tthis.sortForwardSlotSegs(forwardSegs);\n\n\t\t\t\t// this segment's forwardCoord will be calculated from the backwardCoord of the\n\t\t\t\t// highest-pressure forward segment.\n\t\t\t\tthis.computeSlotSegCoords(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);\n\t\t\t\tseg.forwardCoord = forwardSegs[0].backwardCoord;\n\t\t\t}\n\n\t\t\t// calculate the backwardCoord from the forwardCoord. consider the series\n\t\t\tseg.backwardCoord = seg.forwardCoord -\n\t\t\t\t(seg.forwardCoord - seriesBackwardCoord) / // available width for series\n\t\t\t\t(seriesBackwardPressure + 1); // # of segments in the series\n\n\t\t\t// use this segment's coordinates to computed the coordinates of the less-pressurized\n\t\t\t// forward segments\n\t\t\tfor (i=0; i' +\n\t\t\t\t'
' +\n\t\t\t\t\t(timeText ?\n\t\t\t\t\t\t'
' +\n\t\t\t\t\t\t\t'' + htmlEscape(timeText) + '' +\n\t\t\t\t\t\t'
' :\n\t\t\t\t\t\t''\n\t\t\t\t\t\t) +\n\t\t\t\t\t(event.title ?\n\t\t\t\t\t\t'
' +\n\t\t\t\t\t\t\thtmlEscape(event.title) +\n\t\t\t\t\t\t'
' :\n\t\t\t\t\t\t''\n\t\t\t\t\t\t) +\n\t\t\t\t'
' +\n\t\t\t\t'
' +\n\t\t\t\t/* TODO: write CSS for this\n\t\t\t\t(isResizableFromStart ?\n\t\t\t\t\t'
' :\n\t\t\t\t\t''\n\t\t\t\t\t) +\n\t\t\t\t*/\n\t\t\t\t(isResizableFromEnd ?\n\t\t\t\t\t'
' :\n\t\t\t\t\t''\n\t\t\t\t\t) +\n\t\t\t'';\n\t},\n\n\n\t// Generates an object with CSS properties/values that should be applied to an event segment element.\n\t// Contains important positioning-related properties that should be applied to any event element, customized or not.\n\tgenerateSegPositionCss: function(seg) {\n\t\tvar shouldOverlap = this.view.opt('slotEventOverlap');\n\t\tvar backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point\n\t\tvar forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point\n\t\tvar props = this.generateSegVerticalCss(seg); // get top/bottom first\n\t\tvar left; // amount of space from left edge, a fraction of the total width\n\t\tvar right; // amount of space from right edge, a fraction of the total width\n\n\t\tif (shouldOverlap) {\n\t\t\t// double the width, but don't go beyond the maximum forward coordinate (1.0)\n\t\t\tforwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);\n\t\t}\n\n\t\tif (this.isRTL) {\n\t\t\tleft = 1 - forwardCoord;\n\t\t\tright = backwardCoord;\n\t\t}\n\t\telse {\n\t\t\tleft = backwardCoord;\n\t\t\tright = 1 - forwardCoord;\n\t\t}\n\n\t\tprops.zIndex = seg.level + 1; // convert from 0-base to 1-based\n\t\tprops.left = left * 100 + '%';\n\t\tprops.right = right * 100 + '%';\n\n\t\tif (shouldOverlap && seg.forwardPressure) {\n\t\t\t// add padding to the edge so that forward stacked events don't cover the resizer's icon\n\t\t\tprops[this.isRTL ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width\n\t\t}\n\n\t\treturn props;\n\t},\n\n\n\t// Generates an object with CSS properties for the top/bottom coordinates of a segment element\n\tgenerateSegVerticalCss: function(seg) {\n\t\treturn {\n\t\t\ttop: seg.top,\n\t\t\tbottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container\n\t\t};\n\t},\n\n\n\t// Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col\n\tgroupSegCols: function(segs) {\n\t\tvar segCols = [];\n\t\tvar i;\n\n\t\tfor (i = 0; i < this.colCnt; i++) {\n\t\t\tsegCols.push([]);\n\t\t}\n\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tsegCols[segs[i].col].push(segs[i]);\n\t\t}\n\n\t\treturn segCols;\n\t},\n\n\n\tsortForwardSlotSegs: function(forwardSegs) {\n\t\tforwardSegs.sort(proxy(this, 'compareForwardSlotSegs'));\n\t},\n\n\n\t// A cmp function for determining which forward segment to rely on more when computing coordinates.\n\tcompareForwardSlotSegs: function(seg1, seg2) {\n\t\t// put higher-pressure first\n\t\treturn seg2.forwardPressure - seg1.forwardPressure ||\n\t\t\t// put segments that are closer to initial edge first (and favor ones with no coords yet)\n\t\t\t(seg1.backwardCoord || 0) - (seg2.backwardCoord || 0) ||\n\t\t\t// do normal sorting...\n\t\t\tthis.compareSegs(seg1, seg2);\n\t}\n\n});\n\n\n// Builds an array of segments \"levels\". The first level will be the leftmost tier of segments if the calendar is\n// left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.\nfunction buildSlotSegLevels(segs) {\n\tvar levels = [];\n\tvar i, seg;\n\tvar j;\n\n\tfor (i=0; i seg2.top && seg1.top < seg2.bottom;\n}\n\n;;\n\n/* An abstract class from which other views inherit from\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar View = fc.View = Class.extend({\n\n\ttype: null, // subclass' view name (string)\n\tname: null, // deprecated. use `type` instead\n\ttitle: null, // the text that will be displayed in the header's title\n\n\tcalendar: null, // owner Calendar object\n\toptions: null, // hash containing all options. already merged with view-specific-options\n\tcoordMap: null, // a CoordMap object for converting pixel regions to dates\n\tel: null, // the view's containing element. set by Calendar\n\n\tdisplaying: null, // a promise representing the state of rendering. null if no render requested\n\tisSkeletonRendered: false,\n\tisEventsRendered: false,\n\n\t// range the view is actually displaying (moments)\n\tstart: null,\n\tend: null, // exclusive\n\n\t// range the view is formally responsible for (moments)\n\t// may be different from start/end. for example, a month view might have 1st-31st, excluding padded dates\n\tintervalStart: null,\n\tintervalEnd: null, // exclusive\n\tintervalDuration: null,\n\tintervalUnit: null, // name of largest unit being displayed, like \"month\" or \"week\"\n\n\tisRTL: false,\n\tisSelected: false, // boolean whether a range of time is user-selected or not\n\n\teventOrderSpecs: null, // criteria for ordering events when they have same date/time\n\n\t// subclasses can optionally use a scroll container\n\tscrollerEl: null, // the element that will most likely scroll when content is too tall\n\tscrollTop: null, // cached vertical scroll value\n\n\t// classNames styled by jqui themes\n\twidgetHeaderClass: null,\n\twidgetContentClass: null,\n\thighlightStateClass: null,\n\n\t// for date utils, computed from options\n\tnextDayThreshold: null,\n\tisHiddenDayHash: null,\n\n\t// document handlers, bound to `this` object\n\tdocumentMousedownProxy: null, // TODO: doesn't work with touch\n\n\n\tconstructor: function(calendar, type, options, intervalDuration) {\n\n\t\tthis.calendar = calendar;\n\t\tthis.type = this.name = type; // .name is deprecated\n\t\tthis.options = options;\n\t\tthis.intervalDuration = intervalDuration || moment.duration(1, 'day');\n\n\t\tthis.nextDayThreshold = moment.duration(this.opt('nextDayThreshold'));\n\t\tthis.initThemingProps();\n\t\tthis.initHiddenDays();\n\t\tthis.isRTL = this.opt('isRTL');\n\n\t\tthis.eventOrderSpecs = parseFieldSpecs(this.opt('eventOrder'));\n\n\t\tthis.documentMousedownProxy = proxy(this, 'documentMousedown');\n\n\t\tthis.initialize();\n\t},\n\n\n\t// A good place for subclasses to initialize member variables\n\tinitialize: function() {\n\t\t// subclasses can implement\n\t},\n\n\n\t// Retrieves an option with the given name\n\topt: function(name) {\n\t\treturn this.options[name];\n\t},\n\n\n\t// Triggers handlers that are view-related. Modifies args before passing to calendar.\n\ttrigger: function(name, thisObj) { // arguments beyond thisObj are passed along\n\t\tvar calendar = this.calendar;\n\n\t\treturn calendar.trigger.apply(\n\t\t\tcalendar,\n\t\t\t[name, thisObj || this].concat(\n\t\t\t\tArray.prototype.slice.call(arguments, 2), // arguments beyond thisObj\n\t\t\t\t[ this ] // always make the last argument a reference to the view. TODO: deprecate\n\t\t\t)\n\t\t);\n\t},\n\n\n\t/* Dates\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Updates all internal dates to center around the given current date\n\tsetDate: function(date) {\n\t\tthis.setRange(this.computeRange(date));\n\t},\n\n\n\t// Updates all internal dates for displaying the given range.\n\t// Expects all values to be normalized (like what computeRange does).\n\tsetRange: function(range) {\n\t\t$.extend(this, range);\n\t\tthis.updateTitle();\n\t},\n\n\n\t// Given a single current date, produce information about what range to display.\n\t// Subclasses can override. Must return all properties.\n\tcomputeRange: function(date) {\n\t\tvar intervalUnit = computeIntervalUnit(this.intervalDuration);\n\t\tvar intervalStart = date.clone().startOf(intervalUnit);\n\t\tvar intervalEnd = intervalStart.clone().add(this.intervalDuration);\n\t\tvar start, end;\n\n\t\t// normalize the range's time-ambiguity\n\t\tif (/year|month|week|day/.test(intervalUnit)) { // whole-days?\n\t\t\tintervalStart.stripTime();\n\t\t\tintervalEnd.stripTime();\n\t\t}\n\t\telse { // needs to have a time?\n\t\t\tif (!intervalStart.hasTime()) {\n\t\t\t\tintervalStart = this.calendar.rezoneDate(intervalStart); // convert to current timezone, with 00:00\n\t\t\t}\n\t\t\tif (!intervalEnd.hasTime()) {\n\t\t\t\tintervalEnd = this.calendar.rezoneDate(intervalEnd); // convert to current timezone, with 00:00\n\t\t\t}\n\t\t}\n\n\t\tstart = intervalStart.clone();\n\t\tstart = this.skipHiddenDays(start);\n\t\tend = intervalEnd.clone();\n\t\tend = this.skipHiddenDays(end, -1, true); // exclusively move backwards\n\n\t\treturn {\n\t\t\tintervalUnit: intervalUnit,\n\t\t\tintervalStart: intervalStart,\n\t\t\tintervalEnd: intervalEnd,\n\t\t\tstart: start,\n\t\t\tend: end\n\t\t};\n\t},\n\n\n\t// Computes the new date when the user hits the prev button, given the current date\n\tcomputePrevDate: function(date) {\n\t\treturn this.massageCurrentDate(\n\t\t\tdate.clone().startOf(this.intervalUnit).subtract(this.intervalDuration), -1\n\t\t);\n\t},\n\n\n\t// Computes the new date when the user hits the next button, given the current date\n\tcomputeNextDate: function(date) {\n\t\treturn this.massageCurrentDate(\n\t\t\tdate.clone().startOf(this.intervalUnit).add(this.intervalDuration)\n\t\t);\n\t},\n\n\n\t// Given an arbitrarily calculated current date of the calendar, returns a date that is ensured to be completely\n\t// visible. `direction` is optional and indicates which direction the current date was being\n\t// incremented or decremented (1 or -1).\n\tmassageCurrentDate: function(date, direction) {\n\t\tif (this.intervalDuration.as('days') <= 1) { // if the view displays a single day or smaller\n\t\t\tif (this.isHiddenDay(date)) {\n\t\t\t\tdate = this.skipHiddenDays(date, direction);\n\t\t\t\tdate.startOf('day');\n\t\t\t}\n\t\t}\n\n\t\treturn date;\n\t},\n\n\n\t/* Title and Date Formatting\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Sets the view's title property to the most updated computed value\n\tupdateTitle: function() {\n\t\tthis.title = this.computeTitle();\n\t},\n\n\n\t// Computes what the title at the top of the calendar should be for this view\n\tcomputeTitle: function() {\n\t\treturn this.formatRange(\n\t\t\t{ start: this.intervalStart, end: this.intervalEnd },\n\t\t\tthis.opt('titleFormat') || this.computeTitleFormat(),\n\t\t\tthis.opt('titleRangeSeparator')\n\t\t);\n\t},\n\n\n\t// Generates the format string that should be used to generate the title for the current date range.\n\t// Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.\n\tcomputeTitleFormat: function() {\n\t\tif (this.intervalUnit == 'year') {\n\t\t\treturn 'YYYY';\n\t\t}\n\t\telse if (this.intervalUnit == 'month') {\n\t\t\treturn this.opt('monthYearFormat'); // like \"September 2014\"\n\t\t}\n\t\telse if (this.intervalDuration.as('days') > 1) {\n\t\t\treturn 'll'; // multi-day range. shorter, like \"Sep 9 - 10 2014\"\n\t\t}\n\t\telse {\n\t\t\treturn 'LL'; // one day. longer, like \"September 9 2014\"\n\t\t}\n\t},\n\n\n\t// Utility for formatting a range. Accepts a range object, formatting string, and optional separator.\n\t// Displays all-day ranges naturally, with an inclusive end. Takes the current isRTL into account.\n\tformatRange: function(range, formatStr, separator) {\n\t\tvar end = range.end;\n\n\t\tif (!end.hasTime()) { // all-day?\n\t\t\tend = end.clone().subtract(1); // convert to inclusive. last ms of previous day\n\t\t}\n\n\t\treturn formatRange(range.start, end, formatStr, separator, this.opt('isRTL'));\n\t},\n\n\n\t/* Rendering\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Sets the container element that the view should render inside of.\n\t// Does other DOM-related initializations.\n\tsetElement: function(el) {\n\t\tthis.el = el;\n\t\tthis.bindGlobalHandlers();\n\t},\n\n\n\t// Removes the view's container element from the DOM, clearing any content beforehand.\n\t// Undoes any other DOM-related attachments.\n\tremoveElement: function() {\n\t\tthis.clear(); // clears all content\n\n\t\t// clean up the skeleton\n\t\tif (this.isSkeletonRendered) {\n\t\t\tthis.unrenderSkeleton();\n\t\t\tthis.isSkeletonRendered = false;\n\t\t}\n\n\t\tthis.unbindGlobalHandlers();\n\n\t\tthis.el.remove();\n\n\t\t// NOTE: don't null-out this.el in case the View was destroyed within an API callback.\n\t\t// We don't null-out the View's other jQuery element references upon destroy,\n\t\t// so we shouldn't kill this.el either.\n\t},\n\n\n\t// Does everything necessary to display the view centered around the given date.\n\t// Does every type of rendering EXCEPT rendering events.\n\t// Is asychronous and returns a promise.\n\tdisplay: function(date) {\n\t\tvar _this = this;\n\t\tvar scrollState = null;\n\n\t\tif (this.displaying) {\n\t\t\tscrollState = this.queryScroll();\n\t\t}\n\n\t\treturn this.clear().then(function() { // clear the content first (async)\n\t\t\treturn (\n\t\t\t\t_this.displaying =\n\t\t\t\t\t$.when(_this.displayView(date)) // displayView might return a promise\n\t\t\t\t\t\t.then(function() {\n\t\t\t\t\t\t\t_this.forceScroll(_this.computeInitialScroll(scrollState));\n\t\t\t\t\t\t\t_this.triggerRender();\n\t\t\t\t\t\t})\n\t\t\t);\n\t\t});\n\t},\n\n\n\t// Does everything necessary to clear the content of the view.\n\t// Clears dates and events. Does not clear the skeleton.\n\t// Is asychronous and returns a promise.\n\tclear: function() {\n\t\tvar _this = this;\n\t\tvar displaying = this.displaying;\n\n\t\tif (displaying) { // previously displayed, or in the process of being displayed?\n\t\t\treturn displaying.then(function() { // wait for the display to finish\n\t\t\t\t_this.displaying = null;\n\t\t\t\t_this.clearEvents();\n\t\t\t\treturn _this.clearView(); // might return a promise. chain it\n\t\t\t});\n\t\t}\n\t\telse {\n\t\t\treturn $.when(); // an immediately-resolved promise\n\t\t}\n\t},\n\n\n\t// Displays the view's non-event content, such as date-related content or anything required by events.\n\t// Renders the view's non-content skeleton if necessary.\n\t// Can be asynchronous and return a promise.\n\tdisplayView: function(date) {\n\t\tif (!this.isSkeletonRendered) {\n\t\t\tthis.renderSkeleton();\n\t\t\tthis.isSkeletonRendered = true;\n\t\t}\n\t\tthis.setDate(date);\n\t\tif (this.render) {\n\t\t\tthis.render(); // TODO: deprecate\n\t\t}\n\t\tthis.renderDates();\n\t\tthis.updateSize();\n\t\tthis.renderBusinessHours(); // might need coordinates, so should go after updateSize()\n\t},\n\n\n\t// Unrenders the view content that was rendered in displayView.\n\t// Can be asynchronous and return a promise.\n\tclearView: function() {\n\t\tthis.unselect();\n\t\tthis.triggerUnrender();\n\t\tthis.unrenderBusinessHours();\n\t\tthis.unrenderDates();\n\t\tif (this.destroy) {\n\t\t\tthis.destroy(); // TODO: deprecate\n\t\t}\n\t},\n\n\n\t// Renders the basic structure of the view before any content is rendered\n\trenderSkeleton: function() {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Unrenders the basic structure of the view\n\tunrenderSkeleton: function() {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Renders the view's date-related content (like cells that represent days/times).\n\t// Assumes setRange has already been called and the skeleton has already been rendered.\n\trenderDates: function() {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Unrenders the view's date-related content\n\tunrenderDates: function() {\n\t\t// subclasses should override\n\t},\n\n\n\t// Renders business-hours onto the view. Assumes updateSize has already been called.\n\trenderBusinessHours: function() {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Unrenders previously-rendered business-hours\n\tunrenderBusinessHours: function() {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Signals that the view's content has been rendered\n\ttriggerRender: function() {\n\t\tthis.trigger('viewRender', this, this, this.el);\n\t},\n\n\n\t// Signals that the view's content is about to be unrendered\n\ttriggerUnrender: function() {\n\t\tthis.trigger('viewDestroy', this, this, this.el);\n\t},\n\n\n\t// Binds DOM handlers to elements that reside outside the view container, such as the document\n\tbindGlobalHandlers: function() {\n\t\t$(document).on('mousedown', this.documentMousedownProxy);\n\t},\n\n\n\t// Unbinds DOM handlers from elements that reside outside the view container\n\tunbindGlobalHandlers: function() {\n\t\t$(document).off('mousedown', this.documentMousedownProxy);\n\t},\n\n\n\t// Initializes internal variables related to theming\n\tinitThemingProps: function() {\n\t\tvar tm = this.opt('theme') ? 'ui' : 'fc';\n\n\t\tthis.widgetHeaderClass = tm + '-widget-header';\n\t\tthis.widgetContentClass = tm + '-widget-content';\n\t\tthis.highlightStateClass = tm + '-state-highlight';\n\t},\n\n\n\t/* Dimensions\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Refreshes anything dependant upon sizing of the container element of the grid\n\tupdateSize: function(isResize) {\n\t\tvar scrollState;\n\n\t\tif (isResize) {\n\t\t\tscrollState = this.queryScroll();\n\t\t}\n\n\t\tthis.updateHeight(isResize);\n\t\tthis.updateWidth(isResize);\n\n\t\tif (isResize) {\n\t\t\tthis.setScroll(scrollState);\n\t\t}\n\t},\n\n\n\t// Refreshes the horizontal dimensions of the calendar\n\tupdateWidth: function(isResize) {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Refreshes the vertical dimensions of the calendar\n\tupdateHeight: function(isResize) {\n\t\tvar calendar = this.calendar; // we poll the calendar for height information\n\n\t\tthis.setHeight(\n\t\t\tcalendar.getSuggestedViewHeight(),\n\t\t\tcalendar.isHeightAuto()\n\t\t);\n\t},\n\n\n\t// Updates the vertical dimensions of the calendar to the specified height.\n\t// if `isAuto` is set to true, height becomes merely a suggestion and the view should use its \"natural\" height.\n\tsetHeight: function(height, isAuto) {\n\t\t// subclasses should implement\n\t},\n\n\n\t/* Scroller\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Given the total height of the view, return the number of pixels that should be used for the scroller.\n\t// Utility for subclasses.\n\tcomputeScrollerHeight: function(totalHeight) {\n\t\tvar scrollerEl = this.scrollerEl;\n\t\tvar both;\n\t\tvar otherHeight; // cumulative height of everything that is not the scrollerEl in the view (header+borders)\n\n\t\tboth = this.el.add(scrollerEl);\n\n\t\t// fuckin IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked\n\t\tboth.css({\n\t\t\tposition: 'relative', // cause a reflow, which will force fresh dimension recalculation\n\t\t\tleft: -1 // ensure reflow in case the el was already relative. negative is less likely to cause new scroll\n\t\t});\n\t\totherHeight = this.el.outerHeight() - scrollerEl.height(); // grab the dimensions\n\t\tboth.css({ position: '', left: '' }); // undo hack\n\n\t\treturn totalHeight - otherHeight;\n\t},\n\n\n\t// Computes the initial pre-configured scroll state prior to allowing the user to change it.\n\t// Given the scroll state from the previous rendering. If first time rendering, given null.\n\tcomputeInitialScroll: function(previousScrollState) {\n\t\treturn 0;\n\t},\n\n\n\t// Retrieves the view's current natural scroll state. Can return an arbitrary format.\n\tqueryScroll: function() {\n\t\tif (this.scrollerEl) {\n\t\t\treturn this.scrollerEl.scrollTop(); // operates on scrollerEl by default\n\t\t}\n\t},\n\n\n\t// Sets the view's scroll state. Will accept the same format computeInitialScroll and queryScroll produce.\n\tsetScroll: function(scrollState) {\n\t\tif (this.scrollerEl) {\n\t\t\treturn this.scrollerEl.scrollTop(scrollState); // operates on scrollerEl by default\n\t\t}\n\t},\n\n\n\t// Sets the scroll state, making sure to overcome any predefined scroll value the browser has in mind\n\tforceScroll: function(scrollState) {\n\t\tvar _this = this;\n\n\t\tthis.setScroll(scrollState);\n\t\tsetTimeout(function() {\n\t\t\t_this.setScroll(scrollState);\n\t\t}, 0);\n\t},\n\n\n\t/* Event Elements / Segments\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Does everything necessary to display the given events onto the current view\n\tdisplayEvents: function(events) {\n\t\tvar scrollState = this.queryScroll();\n\n\t\tthis.clearEvents();\n\t\tthis.renderEvents(events);\n\t\tthis.isEventsRendered = true;\n\t\tthis.setScroll(scrollState);\n\t\tthis.triggerEventRender();\n\t},\n\n\n\t// Does everything necessary to clear the view's currently-rendered events\n\tclearEvents: function() {\n\t\tif (this.isEventsRendered) {\n\t\t\tthis.triggerEventUnrender();\n\t\t\tif (this.destroyEvents) {\n\t\t\t\tthis.destroyEvents(); // TODO: deprecate\n\t\t\t}\n\t\t\tthis.unrenderEvents();\n\t\t\tthis.isEventsRendered = false;\n\t\t}\n\t},\n\n\n\t// Renders the events onto the view.\n\trenderEvents: function(events) {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Removes event elements from the view.\n\tunrenderEvents: function() {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Signals that all events have been rendered\n\ttriggerEventRender: function() {\n\t\tthis.renderedEventSegEach(function(seg) {\n\t\t\tthis.trigger('eventAfterRender', seg.event, seg.event, seg.el);\n\t\t});\n\t\tthis.trigger('eventAfterAllRender');\n\t},\n\n\n\t// Signals that all event elements are about to be removed\n\ttriggerEventUnrender: function() {\n\t\tthis.renderedEventSegEach(function(seg) {\n\t\t\tthis.trigger('eventDestroy', seg.event, seg.event, seg.el);\n\t\t});\n\t},\n\n\n\t// Given an event and the default element used for rendering, returns the element that should actually be used.\n\t// Basically runs events and elements through the eventRender hook.\n\tresolveEventEl: function(event, el) {\n\t\tvar custom = this.trigger('eventRender', event, event, el);\n\n\t\tif (custom === false) { // means don't render at all\n\t\t\tel = null;\n\t\t}\n\t\telse if (custom && custom !== true) {\n\t\t\tel = $(custom);\n\t\t}\n\n\t\treturn el;\n\t},\n\n\n\t// Hides all rendered event segments linked to the given event\n\tshowEvent: function(event) {\n\t\tthis.renderedEventSegEach(function(seg) {\n\t\t\tseg.el.css('visibility', '');\n\t\t}, event);\n\t},\n\n\n\t// Shows all rendered event segments linked to the given event\n\thideEvent: function(event) {\n\t\tthis.renderedEventSegEach(function(seg) {\n\t\t\tseg.el.css('visibility', 'hidden');\n\t\t}, event);\n\t},\n\n\n\t// Iterates through event segments that have been rendered (have an el). Goes through all by default.\n\t// If the optional `event` argument is specified, only iterates through segments linked to that event.\n\t// The `this` value of the callback function will be the view.\n\trenderedEventSegEach: function(func, event) {\n\t\tvar segs = this.getEventSegs();\n\t\tvar i;\n\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tif (!event || segs[i].event._id === event._id) {\n\t\t\t\tif (segs[i].el) {\n\t\t\t\t\tfunc.call(this, segs[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Retrieves all the rendered segment objects for the view\n\tgetEventSegs: function() {\n\t\t// subclasses must implement\n\t\treturn [];\n\t},\n\n\n\t/* Event Drag-n-Drop\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Computes if the given event is allowed to be dragged by the user\n\tisEventDraggable: function(event) {\n\t\tvar source = event.source || {};\n\n\t\treturn firstDefined(\n\t\t\tevent.startEditable,\n\t\t\tsource.startEditable,\n\t\t\tthis.opt('eventStartEditable'),\n\t\t\tevent.editable,\n\t\t\tsource.editable,\n\t\t\tthis.opt('editable')\n\t\t);\n\t},\n\n\n\t// Must be called when an event in the view is dropped onto new location.\n\t// `dropLocation` is an object that contains the new start/end/allDay values for the event.\n\treportEventDrop: function(event, dropLocation, largeUnit, el, ev) {\n\t\tvar calendar = this.calendar;\n\t\tvar mutateResult = calendar.mutateEvent(event, dropLocation, largeUnit);\n\t\tvar undoFunc = function() {\n\t\t\tmutateResult.undo();\n\t\t\tcalendar.reportEventChange();\n\t\t};\n\n\t\tthis.triggerEventDrop(event, mutateResult.dateDelta, undoFunc, el, ev);\n\t\tcalendar.reportEventChange(); // will rerender events\n\t},\n\n\n\t// Triggers event-drop handlers that have subscribed via the API\n\ttriggerEventDrop: function(event, dateDelta, undoFunc, el, ev) {\n\t\tthis.trigger('eventDrop', el[0], event, dateDelta, undoFunc, ev, {}); // {} = jqui dummy\n\t},\n\n\n\t/* External Element Drag-n-Drop\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Must be called when an external element, via jQuery UI, has been dropped onto the calendar.\n\t// `meta` is the parsed data that has been embedded into the dragging event.\n\t// `dropLocation` is an object that contains the new start/end/allDay values for the event.\n\treportExternalDrop: function(meta, dropLocation, el, ev, ui) {\n\t\tvar eventProps = meta.eventProps;\n\t\tvar eventInput;\n\t\tvar event;\n\n\t\t// Try to build an event object and render it. TODO: decouple the two\n\t\tif (eventProps) {\n\t\t\teventInput = $.extend({}, eventProps, dropLocation);\n\t\t\tevent = this.calendar.renderEvent(eventInput, meta.stick)[0]; // renderEvent returns an array\n\t\t}\n\n\t\tthis.triggerExternalDrop(event, dropLocation, el, ev, ui);\n\t},\n\n\n\t// Triggers external-drop handlers that have subscribed via the API\n\ttriggerExternalDrop: function(event, dropLocation, el, ev, ui) {\n\n\t\t// trigger 'drop' regardless of whether element represents an event\n\t\tthis.trigger('drop', el[0], dropLocation.start, ev, ui);\n\n\t\tif (event) {\n\t\t\tthis.trigger('eventReceive', null, event); // signal an external event landed\n\t\t}\n\t},\n\n\n\t/* Drag-n-Drop Rendering (for both events and external elements)\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of a event or external-element drag over the given drop zone.\n\t// If an external-element, seg will be `null`\n\trenderDrag: function(dropLocation, seg) {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Unrenders a visual indication of an event or external-element being dragged.\n\tunrenderDrag: function() {\n\t\t// subclasses must implement\n\t},\n\n\n\t/* Event Resizing\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Computes if the given event is allowed to be resized from its starting edge\n\tisEventResizableFromStart: function(event) {\n\t\treturn this.opt('eventResizableFromStart') && this.isEventResizable(event);\n\t},\n\n\n\t// Computes if the given event is allowed to be resized from its ending edge\n\tisEventResizableFromEnd: function(event) {\n\t\treturn this.isEventResizable(event);\n\t},\n\n\n\t// Computes if the given event is allowed to be resized by the user at all\n\tisEventResizable: function(event) {\n\t\tvar source = event.source || {};\n\n\t\treturn firstDefined(\n\t\t\tevent.durationEditable,\n\t\t\tsource.durationEditable,\n\t\t\tthis.opt('eventDurationEditable'),\n\t\t\tevent.editable,\n\t\t\tsource.editable,\n\t\t\tthis.opt('editable')\n\t\t);\n\t},\n\n\n\t// Must be called when an event in the view has been resized to a new length\n\treportEventResize: function(event, resizeLocation, largeUnit, el, ev) {\n\t\tvar calendar = this.calendar;\n\t\tvar mutateResult = calendar.mutateEvent(event, resizeLocation, largeUnit);\n\t\tvar undoFunc = function() {\n\t\t\tmutateResult.undo();\n\t\t\tcalendar.reportEventChange();\n\t\t};\n\n\t\tthis.triggerEventResize(event, mutateResult.durationDelta, undoFunc, el, ev);\n\t\tcalendar.reportEventChange(); // will rerender events\n\t},\n\n\n\t// Triggers event-resize handlers that have subscribed via the API\n\ttriggerEventResize: function(event, durationDelta, undoFunc, el, ev) {\n\t\tthis.trigger('eventResize', el[0], event, durationDelta, undoFunc, ev, {}); // {} = jqui dummy\n\t},\n\n\n\t/* Selection\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Selects a date range on the view. `start` and `end` are both Moments.\n\t// `ev` is the native mouse event that begin the interaction.\n\tselect: function(range, ev) {\n\t\tthis.unselect(ev);\n\t\tthis.renderSelection(range);\n\t\tthis.reportSelection(range, ev);\n\t},\n\n\n\t// Renders a visual indication of the selection\n\trenderSelection: function(range) {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Called when a new selection is made. Updates internal state and triggers handlers.\n\treportSelection: function(range, ev) {\n\t\tthis.isSelected = true;\n\t\tthis.triggerSelect(range, ev);\n\t},\n\n\n\t// Triggers handlers to 'select'\n\ttriggerSelect: function(range, ev) {\n\t\tthis.trigger('select', null, range.start, range.end, ev);\n\t},\n\n\n\t// Undoes a selection. updates in the internal state and triggers handlers.\n\t// `ev` is the native mouse event that began the interaction.\n\tunselect: function(ev) {\n\t\tif (this.isSelected) {\n\t\t\tthis.isSelected = false;\n\t\t\tif (this.destroySelection) {\n\t\t\t\tthis.destroySelection(); // TODO: deprecate\n\t\t\t}\n\t\t\tthis.unrenderSelection();\n\t\t\tthis.trigger('unselect', null, ev);\n\t\t}\n\t},\n\n\n\t// Unrenders a visual indication of selection\n\tunrenderSelection: function() {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Handler for unselecting when the user clicks something and the 'unselectAuto' setting is on\n\tdocumentMousedown: function(ev) {\n\t\tvar ignore;\n\n\t\t// is there a selection, and has the user made a proper left click?\n\t\tif (this.isSelected && this.opt('unselectAuto') && isPrimaryMouseButton(ev)) {\n\n\t\t\t// only unselect if the clicked element is not identical to or inside of an 'unselectCancel' element\n\t\t\tignore = this.opt('unselectCancel');\n\t\t\tif (!ignore || !$(ev.target).closest(ignore).length) {\n\t\t\t\tthis.unselect(ev);\n\t\t\t}\n\t\t}\n\t},\n\n\n\t/* Day Click\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Triggers handlers to 'dayClick'\n\ttriggerDayClick: function(cell, dayEl, ev) {\n\t\tthis.trigger('dayClick', dayEl, cell.start, ev);\n\t},\n\n\n\t/* Date Utils\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Initializes internal variables related to calculating hidden days-of-week\n\tinitHiddenDays: function() {\n\t\tvar hiddenDays = this.opt('hiddenDays') || []; // array of day-of-week indices that are hidden\n\t\tvar isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)\n\t\tvar dayCnt = 0;\n\t\tvar i;\n\n\t\tif (this.opt('weekends') === false) {\n\t\t\thiddenDays.push(0, 6); // 0=sunday, 6=saturday\n\t\t}\n\n\t\tfor (i = 0; i < 7; i++) {\n\t\t\tif (\n\t\t\t\t!(isHiddenDayHash[i] = $.inArray(i, hiddenDays) !== -1)\n\t\t\t) {\n\t\t\t\tdayCnt++;\n\t\t\t}\n\t\t}\n\n\t\tif (!dayCnt) {\n\t\t\tthrow 'invalid hiddenDays'; // all days were hidden? bad.\n\t\t}\n\n\t\tthis.isHiddenDayHash = isHiddenDayHash;\n\t},\n\n\n\t// Is the current day hidden?\n\t// `day` is a day-of-week index (0-6), or a Moment\n\tisHiddenDay: function(day) {\n\t\tif (moment.isMoment(day)) {\n\t\t\tday = day.day();\n\t\t}\n\t\treturn this.isHiddenDayHash[day];\n\t},\n\n\n\t// Incrementing the current day until it is no longer a hidden day, returning a copy.\n\t// If the initial value of `date` is not a hidden day, don't do anything.\n\t// Pass `isExclusive` as `true` if you are dealing with an end date.\n\t// `inc` defaults to `1` (increment one day forward each time)\n\tskipHiddenDays: function(date, inc, isExclusive) {\n\t\tvar out = date.clone();\n\t\tinc = inc || 1;\n\t\twhile (\n\t\t\tthis.isHiddenDayHash[(out.day() + (isExclusive ? inc : 0) + 7) % 7]\n\t\t) {\n\t\t\tout.add(inc, 'days');\n\t\t}\n\t\treturn out;\n\t},\n\n\n\t// Returns the date range of the full days the given range visually appears to occupy.\n\t// Returns a new range object.\n\tcomputeDayRange: function(range) {\n\t\tvar startDay = range.start.clone().stripTime(); // the beginning of the day the range starts\n\t\tvar end = range.end;\n\t\tvar endDay = null;\n\t\tvar endTimeMS;\n\n\t\tif (end) {\n\t\t\tendDay = end.clone().stripTime(); // the beginning of the day the range exclusively ends\n\t\t\tendTimeMS = +end.time(); // # of milliseconds into `endDay`\n\n\t\t\t// If the end time is actually inclusively part of the next day and is equal to or\n\t\t\t// beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.\n\t\t\t// Otherwise, leaving it as inclusive will cause it to exclude `endDay`.\n\t\t\tif (endTimeMS && endTimeMS >= this.nextDayThreshold) {\n\t\t\t\tendDay.add(1, 'days');\n\t\t\t}\n\t\t}\n\n\t\t// If no end was specified, or if it is within `startDay` but not past nextDayThreshold,\n\t\t// assign the default duration of one day.\n\t\tif (!end || endDay <= startDay) {\n\t\t\tendDay = startDay.clone().add(1, 'days');\n\t\t}\n\n\t\treturn { start: startDay, end: endDay };\n\t},\n\n\n\t// Does the given event visually appear to occupy more than one day?\n\tisMultiDayEvent: function(event) {\n\t\tvar range = this.computeDayRange(event); // event is range-ish\n\n\t\treturn range.end.diff(range.start, 'days') > 1;\n\t}\n\n});\n\n;;\n\nvar Calendar = fc.Calendar = Class.extend({\n\n\tdirDefaults: null, // option defaults related to LTR or RTL\n\tlangDefaults: null, // option defaults related to current locale\n\toverrides: null, // option overrides given to the fullCalendar constructor\n\toptions: null, // all defaults combined with overrides\n\tviewSpecCache: null, // cache of view definitions\n\tview: null, // current View object\n\theader: null,\n\tloadingLevel: 0, // number of simultaneous loading tasks\n\n\n\t// a lot of this class' OOP logic is scoped within this constructor function,\n\t// but in the future, write individual methods on the prototype.\n\tconstructor: Calendar_constructor,\n\n\n\t// Subclasses can override this for initialization logic after the constructor has been called\n\tinitialize: function() {\n\t},\n\n\n\t// Initializes `this.options` and other important options-related objects\n\tinitOptions: function(overrides) {\n\t\tvar lang, langDefaults;\n\t\tvar isRTL, dirDefaults;\n\n\t\t// converts legacy options into non-legacy ones.\n\t\t// in the future, when this is removed, don't use `overrides` reference. make a copy.\n\t\toverrides = massageOverrides(overrides);\n\n\t\tlang = overrides.lang;\n\t\tlangDefaults = langOptionHash[lang];\n\t\tif (!langDefaults) {\n\t\t\tlang = Calendar.defaults.lang;\n\t\t\tlangDefaults = langOptionHash[lang] || {};\n\t\t}\n\n\t\tisRTL = firstDefined(\n\t\t\toverrides.isRTL,\n\t\t\tlangDefaults.isRTL,\n\t\t\tCalendar.defaults.isRTL\n\t\t);\n\t\tdirDefaults = isRTL ? Calendar.rtlDefaults : {};\n\n\t\tthis.dirDefaults = dirDefaults;\n\t\tthis.langDefaults = langDefaults;\n\t\tthis.overrides = overrides;\n\t\tthis.options = mergeOptions([ // merge defaults and overrides. lowest to highest precedence\n\t\t\tCalendar.defaults, // global defaults\n\t\t\tdirDefaults,\n\t\t\tlangDefaults,\n\t\t\toverrides\n\t\t]);\n\t\tpopulateInstanceComputableOptions(this.options);\n\n\t\tthis.viewSpecCache = {}; // somewhat unrelated\n\t},\n\n\n\t// Gets information about how to create a view. Will use a cache.\n\tgetViewSpec: function(viewType) {\n\t\tvar cache = this.viewSpecCache;\n\n\t\treturn cache[viewType] || (cache[viewType] = this.buildViewSpec(viewType));\n\t},\n\n\n\t// Given a duration singular unit, like \"week\" or \"day\", finds a matching view spec.\n\t// Preference is given to views that have corresponding buttons.\n\tgetUnitViewSpec: function(unit) {\n\t\tvar viewTypes;\n\t\tvar i;\n\t\tvar spec;\n\n\t\tif ($.inArray(unit, intervalUnits) != -1) {\n\n\t\t\t// put views that have buttons first. there will be duplicates, but oh well\n\t\t\tviewTypes = this.header.getViewsWithButtons();\n\t\t\t$.each(fc.views, function(viewType) { // all views\n\t\t\t\tviewTypes.push(viewType);\n\t\t\t});\n\n\t\t\tfor (i = 0; i < viewTypes.length; i++) {\n\t\t\t\tspec = this.getViewSpec(viewTypes[i]);\n\t\t\t\tif (spec) {\n\t\t\t\t\tif (spec.singleUnit == unit) {\n\t\t\t\t\t\treturn spec;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Builds an object with information on how to create a given view\n\tbuildViewSpec: function(requestedViewType) {\n\t\tvar viewOverrides = this.overrides.views || {};\n\t\tvar specChain = []; // for the view. lowest to highest priority\n\t\tvar defaultsChain = []; // for the view. lowest to highest priority\n\t\tvar overridesChain = []; // for the view. lowest to highest priority\n\t\tvar viewType = requestedViewType;\n\t\tvar spec; // for the view\n\t\tvar overrides; // for the view\n\t\tvar duration;\n\t\tvar unit;\n\n\t\t// iterate from the specific view definition to a more general one until we hit an actual View class\n\t\twhile (viewType) {\n\t\t\tspec = fcViews[viewType];\n\t\t\toverrides = viewOverrides[viewType];\n\t\t\tviewType = null; // clear. might repopulate for another iteration\n\n\t\t\tif (typeof spec === 'function') { // TODO: deprecate\n\t\t\t\tspec = { 'class': spec };\n\t\t\t}\n\n\t\t\tif (spec) {\n\t\t\t\tspecChain.unshift(spec);\n\t\t\t\tdefaultsChain.unshift(spec.defaults || {});\n\t\t\t\tduration = duration || spec.duration;\n\t\t\t\tviewType = viewType || spec.type;\n\t\t\t}\n\n\t\t\tif (overrides) {\n\t\t\t\toverridesChain.unshift(overrides); // view-specific option hashes have options at zero-level\n\t\t\t\tduration = duration || overrides.duration;\n\t\t\t\tviewType = viewType || overrides.type;\n\t\t\t}\n\t\t}\n\n\t\tspec = mergeProps(specChain);\n\t\tspec.type = requestedViewType;\n\t\tif (!spec['class']) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (duration) {\n\t\t\tduration = moment.duration(duration);\n\t\t\tif (duration.valueOf()) { // valid?\n\t\t\t\tspec.duration = duration;\n\t\t\t\tunit = computeIntervalUnit(duration);\n\n\t\t\t\t// view is a single-unit duration, like \"week\" or \"day\"\n\t\t\t\t// incorporate options for this. lowest priority\n\t\t\t\tif (duration.as(unit) === 1) {\n\t\t\t\t\tspec.singleUnit = unit;\n\t\t\t\t\toverridesChain.unshift(viewOverrides[unit] || {});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tspec.defaults = mergeOptions(defaultsChain);\n\t\tspec.overrides = mergeOptions(overridesChain);\n\n\t\tthis.buildViewSpecOptions(spec);\n\t\tthis.buildViewSpecButtonText(spec, requestedViewType);\n\n\t\treturn spec;\n\t},\n\n\n\t// Builds and assigns a view spec's options object from its already-assigned defaults and overrides\n\tbuildViewSpecOptions: function(spec) {\n\t\tspec.options = mergeOptions([ // lowest to highest priority\n\t\t\tCalendar.defaults, // global defaults\n\t\t\tspec.defaults, // view's defaults (from ViewSubclass.defaults)\n\t\t\tthis.dirDefaults,\n\t\t\tthis.langDefaults, // locale and dir take precedence over view's defaults!\n\t\t\tthis.overrides, // calendar's overrides (options given to constructor)\n\t\t\tspec.overrides // view's overrides (view-specific options)\n\t\t]);\n\t\tpopulateInstanceComputableOptions(spec.options);\n\t},\n\n\n\t// Computes and assigns a view spec's buttonText-related options\n\tbuildViewSpecButtonText: function(spec, requestedViewType) {\n\n\t\t// given an options object with a possible `buttonText` hash, lookup the buttonText for the\n\t\t// requested view, falling back to a generic unit entry like \"week\" or \"day\"\n\t\tfunction queryButtonText(options) {\n\t\t\tvar buttonText = options.buttonText || {};\n\t\t\treturn buttonText[requestedViewType] ||\n\t\t\t\t(spec.singleUnit ? buttonText[spec.singleUnit] : null);\n\t\t}\n\n\t\t// highest to lowest priority\n\t\tspec.buttonTextOverride =\n\t\t\tqueryButtonText(this.overrides) || // constructor-specified buttonText lookup hash takes precedence\n\t\t\tspec.overrides.buttonText; // `buttonText` for view-specific options is a string\n\n\t\t// highest to lowest priority. mirrors buildViewSpecOptions\n\t\tspec.buttonTextDefault =\n\t\t\tqueryButtonText(this.langDefaults) ||\n\t\t\tqueryButtonText(this.dirDefaults) ||\n\t\t\tspec.defaults.buttonText || // a single string. from ViewSubclass.defaults\n\t\t\tqueryButtonText(Calendar.defaults) ||\n\t\t\t(spec.duration ? this.humanizeDuration(spec.duration) : null) || // like \"3 days\"\n\t\t\trequestedViewType; // fall back to given view name\n\t},\n\n\n\t// Given a view name for a custom view or a standard view, creates a ready-to-go View object\n\tinstantiateView: function(viewType) {\n\t\tvar spec = this.getViewSpec(viewType);\n\n\t\treturn new spec['class'](this, viewType, spec.options, spec.duration);\n\t},\n\n\n\t// Returns a boolean about whether the view is okay to instantiate at some point\n\tisValidViewType: function(viewType) {\n\t\treturn Boolean(this.getViewSpec(viewType));\n\t},\n\n\n\t// Should be called when any type of async data fetching begins\n\tpushLoading: function() {\n\t\tif (!(this.loadingLevel++)) {\n\t\t\tthis.trigger('loading', null, true, this.view);\n\t\t}\n\t},\n\n\n\t// Should be called when any type of async data fetching completes\n\tpopLoading: function() {\n\t\tif (!(--this.loadingLevel)) {\n\t\t\tthis.trigger('loading', null, false, this.view);\n\t\t}\n\t},\n\n\n\t// Given arguments to the select method in the API, returns a range\n\tbuildSelectRange: function(start, end) {\n\n\t\tstart = this.moment(start);\n\t\tif (end) {\n\t\t\tend = this.moment(end);\n\t\t}\n\t\telse if (start.hasTime()) {\n\t\t\tend = start.clone().add(this.defaultTimedEventDuration);\n\t\t}\n\t\telse {\n\t\t\tend = start.clone().add(this.defaultAllDayEventDuration);\n\t\t}\n\n\t\treturn { start: start, end: end };\n\t}\n\n});\n\n\nCalendar.mixin(Emitter);\n\n\nfunction Calendar_constructor(element, overrides) {\n\tvar t = this;\n\n\n\tt.initOptions(overrides || {});\n\tvar options = this.options;\n\n\t\n\t// Exports\n\t// -----------------------------------------------------------------------------------\n\n\tt.render = render;\n\tt.destroy = destroy;\n\tt.refetchEvents = refetchEvents;\n\tt.reportEvents = reportEvents;\n\tt.reportEventChange = reportEventChange;\n\tt.rerenderEvents = renderEvents; // `renderEvents` serves as a rerender. an API method\n\tt.changeView = renderView; // `renderView` will switch to another view\n\tt.select = select;\n\tt.unselect = unselect;\n\tt.prev = prev;\n\tt.next = next;\n\tt.prevYear = prevYear;\n\tt.nextYear = nextYear;\n\tt.today = today;\n\tt.gotoDate = gotoDate;\n\tt.incrementDate = incrementDate;\n\tt.zoomTo = zoomTo;\n\tt.getDate = getDate;\n\tt.getCalendar = getCalendar;\n\tt.getView = getView;\n\tt.option = option;\n\tt.trigger = trigger;\n\n\n\n\t// Language-data Internals\n\t// -----------------------------------------------------------------------------------\n\t// Apply overrides to the current language's data\n\n\n\tvar localeData = createObject( // make a cheap copy\n\t\tgetMomentLocaleData(options.lang) // will fall back to en\n\t);\n\n\tif (options.monthNames) {\n\t\tlocaleData._months = options.monthNames;\n\t}\n\tif (options.monthNamesShort) {\n\t\tlocaleData._monthsShort = options.monthNamesShort;\n\t}\n\tif (options.dayNames) {\n\t\tlocaleData._weekdays = options.dayNames;\n\t}\n\tif (options.dayNamesShort) {\n\t\tlocaleData._weekdaysShort = options.dayNamesShort;\n\t}\n\tif (options.firstDay != null) {\n\t\tvar _week = createObject(localeData._week); // _week: { dow: # }\n\t\t_week.dow = options.firstDay;\n\t\tlocaleData._week = _week;\n\t}\n\n\t// assign a normalized value, to be used by our .week() moment extension\n\tlocaleData._fullCalendar_weekCalc = (function(weekCalc) {\n\t\tif (typeof weekCalc === 'function') {\n\t\t\treturn weekCalc;\n\t\t}\n\t\telse if (weekCalc === 'local') {\n\t\t\treturn weekCalc;\n\t\t}\n\t\telse if (weekCalc === 'iso' || weekCalc === 'ISO') {\n\t\t\treturn 'ISO';\n\t\t}\n\t})(options.weekNumberCalculation);\n\n\n\n\t// Calendar-specific Date Utilities\n\t// -----------------------------------------------------------------------------------\n\n\n\tt.defaultAllDayEventDuration = moment.duration(options.defaultAllDayEventDuration);\n\tt.defaultTimedEventDuration = moment.duration(options.defaultTimedEventDuration);\n\n\n\t// Builds a moment using the settings of the current calendar: timezone and language.\n\t// Accepts anything the vanilla moment() constructor accepts.\n\tt.moment = function() {\n\t\tvar mom;\n\n\t\tif (options.timezone === 'local') {\n\t\t\tmom = fc.moment.apply(null, arguments);\n\n\t\t\t// Force the moment to be local, because fc.moment doesn't guarantee it.\n\t\t\tif (mom.hasTime()) { // don't give ambiguously-timed moments a local zone\n\t\t\t\tmom.local();\n\t\t\t}\n\t\t}\n\t\telse if (options.timezone === 'UTC') {\n\t\t\tmom = fc.moment.utc.apply(null, arguments); // process as UTC\n\t\t}\n\t\telse {\n\t\t\tmom = fc.moment.parseZone.apply(null, arguments); // let the input decide the zone\n\t\t}\n\n\t\tif ('_locale' in mom) { // moment 2.8 and above\n\t\t\tmom._locale = localeData;\n\t\t}\n\t\telse { // pre-moment-2.8\n\t\t\tmom._lang = localeData;\n\t\t}\n\n\t\treturn mom;\n\t};\n\n\n\t// Returns a boolean about whether or not the calendar knows how to calculate\n\t// the timezone offset of arbitrary dates in the current timezone.\n\tt.getIsAmbigTimezone = function() {\n\t\treturn options.timezone !== 'local' && options.timezone !== 'UTC';\n\t};\n\n\n\t// Returns a copy of the given date in the current timezone of it is ambiguously zoned.\n\t// This will also give the date an unambiguous time.\n\tt.rezoneDate = function(date) {\n\t\treturn t.moment(date.toArray());\n\t};\n\n\n\t// Returns a moment for the current date, as defined by the client's computer,\n\t// or overridden by the `now` option.\n\tt.getNow = function() {\n\t\tvar now = options.now;\n\t\tif (typeof now === 'function') {\n\t\t\tnow = now();\n\t\t}\n\t\treturn t.moment(now);\n\t};\n\n\n\t// Get an event's normalized end date. If not present, calculate it from the defaults.\n\tt.getEventEnd = function(event) {\n\t\tif (event.end) {\n\t\t\treturn event.end.clone();\n\t\t}\n\t\telse {\n\t\t\treturn t.getDefaultEventEnd(event.allDay, event.start);\n\t\t}\n\t};\n\n\n\t// Given an event's allDay status and start date, return swhat its fallback end date should be.\n\tt.getDefaultEventEnd = function(allDay, start) { // TODO: rename to computeDefaultEventEnd\n\t\tvar end = start.clone();\n\n\t\tif (allDay) {\n\t\t\tend.stripTime().add(t.defaultAllDayEventDuration);\n\t\t}\n\t\telse {\n\t\t\tend.add(t.defaultTimedEventDuration);\n\t\t}\n\n\t\tif (t.getIsAmbigTimezone()) {\n\t\t\tend.stripZone(); // we don't know what the tzo should be\n\t\t}\n\n\t\treturn end;\n\t};\n\n\n\t// Produces a human-readable string for the given duration.\n\t// Side-effect: changes the locale of the given duration.\n\tt.humanizeDuration = function(duration) {\n\t\treturn (duration.locale || duration.lang).call(duration, options.lang) // works moment-pre-2.8\n\t\t\t.humanize();\n\t};\n\n\n\t\n\t// Imports\n\t// -----------------------------------------------------------------------------------\n\n\n\tEventManager.call(t, options);\n\tvar isFetchNeeded = t.isFetchNeeded;\n\tvar fetchEvents = t.fetchEvents;\n\n\n\n\t// Locals\n\t// -----------------------------------------------------------------------------------\n\n\n\tvar _element = element[0];\n\tvar header;\n\tvar headerElement;\n\tvar content;\n\tvar tm; // for making theme classes\n\tvar currentView; // NOTE: keep this in sync with this.view\n\tvar viewsByType = {}; // holds all instantiated view instances, current or not\n\tvar suggestedViewHeight;\n\tvar windowResizeProxy; // wraps the windowResize function\n\tvar ignoreWindowResize = 0;\n\tvar date;\n\tvar events = [];\n\t\n\t\n\t\n\t// Main Rendering\n\t// -----------------------------------------------------------------------------------\n\n\n\tif (options.defaultDate != null) {\n\t\tdate = t.moment(options.defaultDate);\n\t}\n\telse {\n\t\tdate = t.getNow();\n\t}\n\t\n\t\n\tfunction render() {\n\t\tif (!content) {\n\t\t\tinitialRender();\n\t\t}\n\t\telse if (elementVisible()) {\n\t\t\t// mainly for the public API\n\t\t\tcalcSize();\n\t\t\trenderView();\n\t\t}\n\t}\n\t\n\t\n\tfunction initialRender() {\n\t\ttm = options.theme ? 'ui' : 'fc';\n\t\telement.addClass('fc');\n\n\t\tif (options.isRTL) {\n\t\t\telement.addClass('fc-rtl');\n\t\t}\n\t\telse {\n\t\t\telement.addClass('fc-ltr');\n\t\t}\n\n\t\tif (options.theme) {\n\t\t\telement.addClass('ui-widget');\n\t\t}\n\t\telse {\n\t\t\telement.addClass('fc-unthemed');\n\t\t}\n\n\t\tcontent = $(\"
\").prependTo(element);\n\n\t\theader = t.header = new Header(t, options);\n\t\theaderElement = header.render();\n\t\tif (headerElement) {\n\t\t\telement.prepend(headerElement);\n\t\t}\n\n\t\trenderView(options.defaultView);\n\n\t\tif (options.handleWindowResize) {\n\t\t\twindowResizeProxy = debounce(windowResize, options.windowResizeDelay); // prevents rapid calls\n\t\t\t$(window).resize(windowResizeProxy);\n\t\t}\n\t}\n\t\n\t\n\tfunction destroy() {\n\n\t\tif (currentView) {\n\t\t\tcurrentView.removeElement();\n\n\t\t\t// NOTE: don't null-out currentView/t.view in case API methods are called after destroy.\n\t\t\t// It is still the \"current\" view, just not rendered.\n\t\t}\n\n\t\theader.removeElement();\n\t\tcontent.remove();\n\t\telement.removeClass('fc fc-ltr fc-rtl fc-unthemed ui-widget');\n\n\t\tif (windowResizeProxy) {\n\t\t\t$(window).unbind('resize', windowResizeProxy);\n\t\t}\n\t}\n\t\n\t\n\tfunction elementVisible() {\n\t\treturn element.is(':visible');\n\t}\n\t\n\t\n\n\t// View Rendering\n\t// -----------------------------------------------------------------------------------\n\n\n\t// Renders a view because of a date change, view-type change, or for the first time.\n\t// If not given a viewType, keep the current view but render different dates.\n\tfunction renderView(viewType) {\n\t\tignoreWindowResize++;\n\n\t\t// if viewType is changing, remove the old view's rendering\n\t\tif (currentView && viewType && currentView.type !== viewType) {\n\t\t\theader.deactivateButton(currentView.type);\n\t\t\tfreezeContentHeight(); // prevent a scroll jump when view element is removed\n\t\t\tcurrentView.removeElement();\n\t\t\tcurrentView = t.view = null;\n\t\t}\n\n\t\t// if viewType changed, or the view was never created, create a fresh view\n\t\tif (!currentView && viewType) {\n\t\t\tcurrentView = t.view =\n\t\t\t\tviewsByType[viewType] ||\n\t\t\t\t(viewsByType[viewType] = t.instantiateView(viewType));\n\n\t\t\tcurrentView.setElement(\n\t\t\t\t$(\"
\").appendTo(content)\n\t\t\t);\n\t\t\theader.activateButton(viewType);\n\t\t}\n\n\t\tif (currentView) {\n\n\t\t\t// in case the view should render a period of time that is completely hidden\n\t\t\tdate = currentView.massageCurrentDate(date);\n\n\t\t\t// render or rerender the view\n\t\t\tif (\n\t\t\t\t!currentView.displaying ||\n\t\t\t\t!date.isWithin(currentView.intervalStart, currentView.intervalEnd) // implicit date window change\n\t\t\t) {\n\t\t\t\tif (elementVisible()) {\n\n\t\t\t\t\tfreezeContentHeight();\n\t\t\t\t\tcurrentView.display(date);\n\t\t\t\t\tunfreezeContentHeight(); // immediately unfreeze regardless of whether display is async\n\n\t\t\t\t\t// need to do this after View::render, so dates are calculated\n\t\t\t\t\tupdateHeaderTitle();\n\t\t\t\t\tupdateTodayButton();\n\n\t\t\t\t\tgetAndRenderEvents();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tunfreezeContentHeight(); // undo any lone freezeContentHeight calls\n\t\tignoreWindowResize--;\n\t}\n\n\t\n\n\t// Resizing\n\t// -----------------------------------------------------------------------------------\n\n\n\tt.getSuggestedViewHeight = function() {\n\t\tif (suggestedViewHeight === undefined) {\n\t\t\tcalcSize();\n\t\t}\n\t\treturn suggestedViewHeight;\n\t};\n\n\n\tt.isHeightAuto = function() {\n\t\treturn options.contentHeight === 'auto' || options.height === 'auto';\n\t};\n\t\n\t\n\tfunction updateSize(shouldRecalc) {\n\t\tif (elementVisible()) {\n\n\t\t\tif (shouldRecalc) {\n\t\t\t\t_calcSize();\n\t\t\t}\n\n\t\t\tignoreWindowResize++;\n\t\t\tcurrentView.updateSize(true); // isResize=true. will poll getSuggestedViewHeight() and isHeightAuto()\n\t\t\tignoreWindowResize--;\n\n\t\t\treturn true; // signal success\n\t\t}\n\t}\n\n\n\tfunction calcSize() {\n\t\tif (elementVisible()) {\n\t\t\t_calcSize();\n\t\t}\n\t}\n\t\n\t\n\tfunction _calcSize() { // assumes elementVisible\n\t\tif (typeof options.contentHeight === 'number') { // exists and not 'auto'\n\t\t\tsuggestedViewHeight = options.contentHeight;\n\t\t}\n\t\telse if (typeof options.height === 'number') { // exists and not 'auto'\n\t\t\tsuggestedViewHeight = options.height - (headerElement ? headerElement.outerHeight(true) : 0);\n\t\t}\n\t\telse {\n\t\t\tsuggestedViewHeight = Math.round(content.width() / Math.max(options.aspectRatio, .5));\n\t\t}\n\t}\n\t\n\t\n\tfunction windowResize(ev) {\n\t\tif (\n\t\t\t!ignoreWindowResize &&\n\t\t\tev.target === window && // so we don't process jqui \"resize\" events that have bubbled up\n\t\t\tcurrentView.start // view has already been rendered\n\t\t) {\n\t\t\tif (updateSize(true)) {\n\t\t\t\tcurrentView.trigger('windowResize', _element);\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t\n\t/* Event Fetching/Rendering\n\t-----------------------------------------------------------------------------*/\n\t// TODO: going forward, most of this stuff should be directly handled by the view\n\n\n\tfunction refetchEvents() { // can be called as an API method\n\t\tdestroyEvents(); // so that events are cleared before user starts waiting for AJAX\n\t\tfetchAndRenderEvents();\n\t}\n\n\n\tfunction renderEvents() { // destroys old events if previously rendered\n\t\tif (elementVisible()) {\n\t\t\tfreezeContentHeight();\n\t\t\tcurrentView.displayEvents(events);\n\t\t\tunfreezeContentHeight();\n\t\t}\n\t}\n\n\n\tfunction destroyEvents() {\n\t\tfreezeContentHeight();\n\t\tcurrentView.clearEvents();\n\t\tunfreezeContentHeight();\n\t}\n\t\n\n\tfunction getAndRenderEvents() {\n\t\tif (!options.lazyFetching || isFetchNeeded(currentView.start, currentView.end)) {\n\t\t\tfetchAndRenderEvents();\n\t\t}\n\t\telse {\n\t\t\trenderEvents();\n\t\t}\n\t}\n\n\n\tfunction fetchAndRenderEvents() {\n\t\tfetchEvents(currentView.start, currentView.end);\n\t\t\t// ... will call reportEvents\n\t\t\t// ... which will call renderEvents\n\t}\n\n\t\n\t// called when event data arrives\n\tfunction reportEvents(_events) {\n\t\tevents = _events;\n\t\trenderEvents();\n\t}\n\n\n\t// called when a single event's data has been changed\n\tfunction reportEventChange() {\n\t\trenderEvents();\n\t}\n\n\n\n\t/* Header Updating\n\t-----------------------------------------------------------------------------*/\n\n\n\tfunction updateHeaderTitle() {\n\t\theader.updateTitle(currentView.title);\n\t}\n\n\n\tfunction updateTodayButton() {\n\t\tvar now = t.getNow();\n\t\tif (now.isWithin(currentView.intervalStart, currentView.intervalEnd)) {\n\t\t\theader.disableButton('today');\n\t\t}\n\t\telse {\n\t\t\theader.enableButton('today');\n\t\t}\n\t}\n\t\n\n\n\t/* Selection\n\t-----------------------------------------------------------------------------*/\n\t\n\n\tfunction select(start, end) {\n\t\tcurrentView.select(\n\t\t\tt.buildSelectRange.apply(t, arguments)\n\t\t);\n\t}\n\t\n\n\tfunction unselect() { // safe to be called before renderView\n\t\tif (currentView) {\n\t\t\tcurrentView.unselect();\n\t\t}\n\t}\n\t\n\t\n\t\n\t/* Date\n\t-----------------------------------------------------------------------------*/\n\t\n\t\n\tfunction prev() {\n\t\tdate = currentView.computePrevDate(date);\n\t\trenderView();\n\t}\n\t\n\t\n\tfunction next() {\n\t\tdate = currentView.computeNextDate(date);\n\t\trenderView();\n\t}\n\t\n\t\n\tfunction prevYear() {\n\t\tdate.add(-1, 'years');\n\t\trenderView();\n\t}\n\t\n\t\n\tfunction nextYear() {\n\t\tdate.add(1, 'years');\n\t\trenderView();\n\t}\n\t\n\t\n\tfunction today() {\n\t\tdate = t.getNow();\n\t\trenderView();\n\t}\n\t\n\t\n\tfunction gotoDate(dateInput) {\n\t\tdate = t.moment(dateInput);\n\t\trenderView();\n\t}\n\t\n\t\n\tfunction incrementDate(delta) {\n\t\tdate.add(moment.duration(delta));\n\t\trenderView();\n\t}\n\n\n\t// Forces navigation to a view for the given date.\n\t// `viewType` can be a specific view name or a generic one like \"week\" or \"day\".\n\tfunction zoomTo(newDate, viewType) {\n\t\tvar spec;\n\n\t\tviewType = viewType || 'day'; // day is default zoom\n\t\tspec = t.getViewSpec(viewType) || t.getUnitViewSpec(viewType);\n\n\t\tdate = newDate;\n\t\trenderView(spec ? spec.type : null);\n\t}\n\t\n\t\n\tfunction getDate() {\n\t\treturn date.clone();\n\t}\n\n\n\n\t/* Height \"Freezing\"\n\t-----------------------------------------------------------------------------*/\n\t// TODO: move this into the view\n\n\n\tfunction freezeContentHeight() {\n\t\tcontent.css({\n\t\t\twidth: '100%',\n\t\t\theight: content.height(),\n\t\t\toverflow: 'hidden'\n\t\t});\n\t}\n\n\n\tfunction unfreezeContentHeight() {\n\t\tcontent.css({\n\t\t\twidth: '',\n\t\t\theight: '',\n\t\t\toverflow: ''\n\t\t});\n\t}\n\t\n\t\n\t\n\t/* Misc\n\t-----------------------------------------------------------------------------*/\n\t\n\n\tfunction getCalendar() {\n\t\treturn t;\n\t}\n\n\t\n\tfunction getView() {\n\t\treturn currentView;\n\t}\n\t\n\t\n\tfunction option(name, value) {\n\t\tif (value === undefined) {\n\t\t\treturn options[name];\n\t\t}\n\t\tif (name == 'height' || name == 'contentHeight' || name == 'aspectRatio') {\n\t\t\toptions[name] = value;\n\t\t\tupdateSize(true); // true = allow recalculation of height\n\t\t}\n\t}\n\t\n\t\n\tfunction trigger(name, thisObj) { // overrides the Emitter's trigger method :(\n\t\tvar args = Array.prototype.slice.call(arguments, 2);\n\n\t\tthisObj = thisObj || _element;\n\t\tthis.triggerWith(name, thisObj, args); // Emitter's method\n\n\t\tif (options[name]) {\n\t\t\treturn options[name].apply(thisObj, args);\n\t\t}\n\t}\n\n\tt.initialize();\n}\n\n;;\n\nCalendar.defaults = {\n\n\ttitleRangeSeparator: ' \\u2014 ', // emphasized dash\n\tmonthYearFormat: 'MMMM YYYY', // required for en. other languages rely on datepicker computable option\n\n\tdefaultTimedEventDuration: '02:00:00',\n\tdefaultAllDayEventDuration: { days: 1 },\n\tforceEventDuration: false,\n\tnextDayThreshold: '09:00:00', // 9am\n\n\t// display\n\tdefaultView: 'month',\n\taspectRatio: 1.35,\n\theader: {\n\t\tleft: 'title',\n\t\tcenter: '',\n\t\tright: 'today prev,next'\n\t},\n\tweekends: true,\n\tweekNumbers: false,\n\n\tweekNumberTitle: 'W',\n\tweekNumberCalculation: 'local',\n\t\n\t//editable: false,\n\n\tscrollTime: '06:00:00',\n\t\n\t// event ajax\n\tlazyFetching: true,\n\tstartParam: 'start',\n\tendParam: 'end',\n\ttimezoneParam: 'timezone',\n\n\ttimezone: false,\n\n\t//allDayDefault: undefined,\n\n\t// locale\n\tisRTL: false,\n\tbuttonText: {\n\t\tprev: \"prev\",\n\t\tnext: \"next\",\n\t\tprevYear: \"prev year\",\n\t\tnextYear: \"next year\",\n\t\tyear: 'year', // TODO: locale files need to specify this\n\t\ttoday: 'today',\n\t\tmonth: 'month',\n\t\tweek: 'week',\n\t\tday: 'day'\n\t},\n\n\tbuttonIcons: {\n\t\tprev: 'left-single-arrow',\n\t\tnext: 'right-single-arrow',\n\t\tprevYear: 'left-double-arrow',\n\t\tnextYear: 'right-double-arrow'\n\t},\n\t\n\t// jquery-ui theming\n\ttheme: false,\n\tthemeButtonIcons: {\n\t\tprev: 'circle-triangle-w',\n\t\tnext: 'circle-triangle-e',\n\t\tprevYear: 'seek-prev',\n\t\tnextYear: 'seek-next'\n\t},\n\n\t//eventResizableFromStart: false,\n\tdragOpacity: .75,\n\tdragRevertDuration: 500,\n\tdragScroll: true,\n\t\n\t//selectable: false,\n\tunselectAuto: true,\n\t\n\tdropAccept: '*',\n\n\teventOrder: 'title',\n\n\teventLimit: false,\n\teventLimitText: 'more',\n\teventLimitClick: 'popover',\n\tdayPopoverFormat: 'LL',\n\t\n\thandleWindowResize: true,\n\twindowResizeDelay: 200 // milliseconds before an updateSize happens\n\t\n};\n\n\nCalendar.englishDefaults = { // used by lang.js\n\tdayPopoverFormat: 'dddd, MMMM D'\n};\n\n\nCalendar.rtlDefaults = { // right-to-left defaults\n\theader: { // TODO: smarter solution (first/center/last ?)\n\t\tleft: 'next,prev today',\n\t\tcenter: '',\n\t\tright: 'title'\n\t},\n\tbuttonIcons: {\n\t\tprev: 'right-single-arrow',\n\t\tnext: 'left-single-arrow',\n\t\tprevYear: 'right-double-arrow',\n\t\tnextYear: 'left-double-arrow'\n\t},\n\tthemeButtonIcons: {\n\t\tprev: 'circle-triangle-e',\n\t\tnext: 'circle-triangle-w',\n\t\tnextYear: 'seek-prev',\n\t\tprevYear: 'seek-next'\n\t}\n};\n\n;;\n\nvar langOptionHash = fc.langs = {}; // initialize and expose\n\n\n// TODO: document the structure and ordering of a FullCalendar lang file\n// TODO: rename everything \"lang\" to \"locale\", like what the moment project did\n\n\n// Initialize jQuery UI datepicker translations while using some of the translations\n// Will set this as the default language for datepicker.\nfc.datepickerLang = function(langCode, dpLangCode, dpOptions) {\n\n\t// get the FullCalendar internal option hash for this language. create if necessary\n\tvar fcOptions = langOptionHash[langCode] || (langOptionHash[langCode] = {});\n\n\t// transfer some simple options from datepicker to fc\n\tfcOptions.isRTL = dpOptions.isRTL;\n\tfcOptions.weekNumberTitle = dpOptions.weekHeader;\n\n\t// compute some more complex options from datepicker\n\t$.each(dpComputableOptions, function(name, func) {\n\t\tfcOptions[name] = func(dpOptions);\n\t});\n\n\t// is jQuery UI Datepicker is on the page?\n\tif ($.datepicker) {\n\n\t\t// Register the language data.\n\t\t// FullCalendar and MomentJS use language codes like \"pt-br\" but Datepicker\n\t\t// does it like \"pt-BR\" or if it doesn't have the language, maybe just \"pt\".\n\t\t// Make an alias so the language can be referenced either way.\n\t\t$.datepicker.regional[dpLangCode] =\n\t\t\t$.datepicker.regional[langCode] = // alias\n\t\t\t\tdpOptions;\n\n\t\t// Alias 'en' to the default language data. Do this every time.\n\t\t$.datepicker.regional.en = $.datepicker.regional[''];\n\n\t\t// Set as Datepicker's global defaults.\n\t\t$.datepicker.setDefaults(dpOptions);\n\t}\n};\n\n\n// Sets FullCalendar-specific translations. Will set the language as the global default.\nfc.lang = function(langCode, newFcOptions) {\n\tvar fcOptions;\n\tvar momOptions;\n\n\t// get the FullCalendar internal option hash for this language. create if necessary\n\tfcOptions = langOptionHash[langCode] || (langOptionHash[langCode] = {});\n\n\t// provided new options for this language? merge them in\n\tif (newFcOptions) {\n\t\tfcOptions = langOptionHash[langCode] = mergeOptions([ fcOptions, newFcOptions ]);\n\t}\n\n\t// compute language options that weren't defined.\n\t// always do this. newFcOptions can be undefined when initializing from i18n file,\n\t// so no way to tell if this is an initialization or a default-setting.\n\tmomOptions = getMomentLocaleData(langCode); // will fall back to en\n\t$.each(momComputableOptions, function(name, func) {\n\t\tif (fcOptions[name] == null) {\n\t\t\tfcOptions[name] = func(momOptions, fcOptions);\n\t\t}\n\t});\n\n\t// set it as the default language for FullCalendar\n\tCalendar.defaults.lang = langCode;\n};\n\n\n// NOTE: can't guarantee any of these computations will run because not every language has datepicker\n// configs, so make sure there are English fallbacks for these in the defaults file.\nvar dpComputableOptions = {\n\n\tbuttonText: function(dpOptions) {\n\t\treturn {\n\t\t\t// the translations sometimes wrongly contain HTML entities\n\t\t\tprev: stripHtmlEntities(dpOptions.prevText),\n\t\t\tnext: stripHtmlEntities(dpOptions.nextText),\n\t\t\ttoday: stripHtmlEntities(dpOptions.currentText)\n\t\t};\n\t},\n\n\t// Produces format strings like \"MMMM YYYY\" -> \"September 2014\"\n\tmonthYearFormat: function(dpOptions) {\n\t\treturn dpOptions.showMonthAfterYear ?\n\t\t\t'YYYY[' + dpOptions.yearSuffix + '] MMMM' :\n\t\t\t'MMMM YYYY[' + dpOptions.yearSuffix + ']';\n\t}\n\n};\n\nvar momComputableOptions = {\n\n\t// Produces format strings like \"ddd M/D\" -> \"Fri 9/15\"\n\tdayOfMonthFormat: function(momOptions, fcOptions) {\n\t\tvar format = momOptions.longDateFormat('l'); // for the format like \"M/D/YYYY\"\n\n\t\t// strip the year off the edge, as well as other misc non-whitespace chars\n\t\tformat = format.replace(/^Y+[^\\w\\s]*|[^\\w\\s]*Y+$/g, '');\n\n\t\tif (fcOptions.isRTL) {\n\t\t\tformat += ' ddd'; // for RTL, add day-of-week to end\n\t\t}\n\t\telse {\n\t\t\tformat = 'ddd ' + format; // for LTR, add day-of-week to beginning\n\t\t}\n\t\treturn format;\n\t},\n\n\t// Produces format strings like \"h:mma\" -> \"6:00pm\"\n\tmediumTimeFormat: function(momOptions) { // can't be called `timeFormat` because collides with option\n\t\treturn momOptions.longDateFormat('LT')\n\t\t\t.replace(/\\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand\n\t},\n\n\t// Produces format strings like \"h(:mm)a\" -> \"6pm\" / \"6:30pm\"\n\tsmallTimeFormat: function(momOptions) {\n\t\treturn momOptions.longDateFormat('LT')\n\t\t\t.replace(':mm', '(:mm)')\n\t\t\t.replace(/(\\Wmm)$/, '($1)') // like above, but for foreign langs\n\t\t\t.replace(/\\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand\n\t},\n\n\t// Produces format strings like \"h(:mm)t\" -> \"6p\" / \"6:30p\"\n\textraSmallTimeFormat: function(momOptions) {\n\t\treturn momOptions.longDateFormat('LT')\n\t\t\t.replace(':mm', '(:mm)')\n\t\t\t.replace(/(\\Wmm)$/, '($1)') // like above, but for foreign langs\n\t\t\t.replace(/\\s*a$/i, 't'); // convert to AM/PM/am/pm to lowercase one-letter. remove any spaces beforehand\n\t},\n\n\t// Produces format strings like \"ha\" / \"H\" -> \"6pm\" / \"18\"\n\thourFormat: function(momOptions) {\n\t\treturn momOptions.longDateFormat('LT')\n\t\t\t.replace(':mm', '')\n\t\t\t.replace(/(\\Wmm)$/, '') // like above, but for foreign langs\n\t\t\t.replace(/\\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand\n\t},\n\n\t// Produces format strings like \"h:mm\" -> \"6:30\" (with no AM/PM)\n\tnoMeridiemTimeFormat: function(momOptions) {\n\t\treturn momOptions.longDateFormat('LT')\n\t\t\t.replace(/\\s*a$/i, ''); // remove trailing AM/PM\n\t}\n\n};\n\n\n// options that should be computed off live calendar options (considers override options)\nvar instanceComputableOptions = { // TODO: best place for this? related to lang?\n\n\t// Produces format strings for results like \"Mo 16\"\n\tsmallDayDateFormat: function(options) {\n\t\treturn options.isRTL ?\n\t\t\t'D dd' :\n\t\t\t'dd D';\n\t},\n\n\t// Produces format strings for results like \"Wk 5\"\n\tweekFormat: function(options) {\n\t\treturn options.isRTL ?\n\t\t\t'w[ ' + options.weekNumberTitle + ']' :\n\t\t\t'[' + options.weekNumberTitle + ' ]w';\n\t},\n\n\t// Produces format strings for results like \"Wk5\"\n\tsmallWeekFormat: function(options) {\n\t\treturn options.isRTL ?\n\t\t\t'w[' + options.weekNumberTitle + ']' :\n\t\t\t'[' + options.weekNumberTitle + ']w';\n\t}\n\n};\n\nfunction populateInstanceComputableOptions(options) {\n\t$.each(instanceComputableOptions, function(name, func) {\n\t\tif (options[name] == null) {\n\t\t\toptions[name] = func(options);\n\t\t}\n\t});\n}\n\n\n// Returns moment's internal locale data. If doesn't exist, returns English.\n// Works with moment-pre-2.8\nfunction getMomentLocaleData(langCode) {\n\tvar func = moment.localeData || moment.langData;\n\treturn func.call(moment, langCode) ||\n\t\tfunc.call(moment, 'en'); // the newer localData could return null, so fall back to en\n}\n\n\n// Initialize English by forcing computation of moment-derived options.\n// Also, sets it as the default.\nfc.lang('en', Calendar.englishDefaults);\n\n;;\n\n/* Top toolbar area with buttons and title\n----------------------------------------------------------------------------------------------------------------------*/\n// TODO: rename all header-related things to \"toolbar\"\n\nfunction Header(calendar, options) {\n\tvar t = this;\n\t\n\t// exports\n\tt.render = render;\n\tt.removeElement = removeElement;\n\tt.updateTitle = updateTitle;\n\tt.activateButton = activateButton;\n\tt.deactivateButton = deactivateButton;\n\tt.disableButton = disableButton;\n\tt.enableButton = enableButton;\n\tt.getViewsWithButtons = getViewsWithButtons;\n\t\n\t// locals\n\tvar el = $();\n\tvar viewsWithButtons = [];\n\tvar tm;\n\n\n\tfunction render() {\n\t\tvar sections = options.header;\n\n\t\ttm = options.theme ? 'ui' : 'fc';\n\n\t\tif (sections) {\n\t\t\tel = $(\"
\")\n\t\t\t\t.append(renderSection('left'))\n\t\t\t\t.append(renderSection('right'))\n\t\t\t\t.append(renderSection('center'))\n\t\t\t\t.append('
');\n\n\t\t\treturn el;\n\t\t}\n\t}\n\t\n\t\n\tfunction removeElement() {\n\t\tel.remove();\n\t\tel = $();\n\t}\n\t\n\t\n\tfunction renderSection(position) {\n\t\tvar sectionEl = $('
');\n\t\tvar buttonStr = options.header[position];\n\n\t\tif (buttonStr) {\n\t\t\t$.each(buttonStr.split(' '), function(i) {\n\t\t\t\tvar groupChildren = $();\n\t\t\t\tvar isOnlyButtons = true;\n\t\t\t\tvar groupEl;\n\n\t\t\t\t$.each(this.split(','), function(j, buttonName) {\n\t\t\t\t\tvar customButtonProps;\n\t\t\t\t\tvar viewSpec;\n\t\t\t\t\tvar buttonClick;\n\t\t\t\t\tvar overrideText; // text explicitly set by calendar's constructor options. overcomes icons\n\t\t\t\t\tvar defaultText;\n\t\t\t\t\tvar themeIcon;\n\t\t\t\t\tvar normalIcon;\n\t\t\t\t\tvar innerHtml;\n\t\t\t\t\tvar classes;\n\t\t\t\t\tvar button; // the element\n\n\t\t\t\t\tif (buttonName == 'title') {\n\t\t\t\t\t\tgroupChildren = groupChildren.add($('

 

')); // we always want it to take up height\n\t\t\t\t\t\tisOnlyButtons = false;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tif ((customButtonProps = (calendar.options.customButtons || {})[buttonName])) {\n\t\t\t\t\t\t\tbuttonClick = function(ev) {\n\t\t\t\t\t\t\t\tif (customButtonProps.click) {\n\t\t\t\t\t\t\t\t\tcustomButtonProps.click.call(button[0], ev);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\toverrideText = ''; // icons will override text\n\t\t\t\t\t\t\tdefaultText = customButtonProps.text;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if ((viewSpec = calendar.getViewSpec(buttonName))) {\n\t\t\t\t\t\t\tbuttonClick = function() {\n\t\t\t\t\t\t\t\tcalendar.changeView(buttonName);\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tviewsWithButtons.push(buttonName);\n\t\t\t\t\t\t\toverrideText = viewSpec.buttonTextOverride;\n\t\t\t\t\t\t\tdefaultText = viewSpec.buttonTextDefault;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (calendar[buttonName]) { // a calendar method\n\t\t\t\t\t\t\tbuttonClick = function() {\n\t\t\t\t\t\t\t\tcalendar[buttonName]();\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\toverrideText = (calendar.overrides.buttonText || {})[buttonName];\n\t\t\t\t\t\t\tdefaultText = options.buttonText[buttonName]; // everything else is considered default\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (buttonClick) {\n\n\t\t\t\t\t\t\tthemeIcon =\n\t\t\t\t\t\t\t\tcustomButtonProps ?\n\t\t\t\t\t\t\t\t\tcustomButtonProps.themeIcon :\n\t\t\t\t\t\t\t\t\toptions.themeButtonIcons[buttonName];\n\n\t\t\t\t\t\t\tnormalIcon =\n\t\t\t\t\t\t\t\tcustomButtonProps ?\n\t\t\t\t\t\t\t\t\tcustomButtonProps.icon :\n\t\t\t\t\t\t\t\t\toptions.buttonIcons[buttonName];\n\n\t\t\t\t\t\t\tif (overrideText) {\n\t\t\t\t\t\t\t\tinnerHtml = htmlEscape(overrideText);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (themeIcon && options.theme) {\n\t\t\t\t\t\t\t\tinnerHtml = \"\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (normalIcon && !options.theme) {\n\t\t\t\t\t\t\t\tinnerHtml = \"\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tinnerHtml = htmlEscape(defaultText);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tclasses = [\n\t\t\t\t\t\t\t\t'fc-' + buttonName + '-button',\n\t\t\t\t\t\t\t\ttm + '-button',\n\t\t\t\t\t\t\t\ttm + '-state-default'\n\t\t\t\t\t\t\t];\n\n\t\t\t\t\t\t\tbutton = $( // type=\"button\" so that it doesn't submit a form\n\t\t\t\t\t\t\t\t''\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.click(function(ev) {\n\t\t\t\t\t\t\t\t\t// don't process clicks for disabled buttons\n\t\t\t\t\t\t\t\t\tif (!button.hasClass(tm + '-state-disabled')) {\n\n\t\t\t\t\t\t\t\t\t\tbuttonClick(ev);\n\n\t\t\t\t\t\t\t\t\t\t// after the click action, if the button becomes the \"active\" tab, or disabled,\n\t\t\t\t\t\t\t\t\t\t// it should never have a hover class, so remove it now.\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\tbutton.hasClass(tm + '-state-active') ||\n\t\t\t\t\t\t\t\t\t\t\tbutton.hasClass(tm + '-state-disabled')\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\tbutton.removeClass(tm + '-state-hover');\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.mousedown(function() {\n\t\t\t\t\t\t\t\t\t// the *down* effect (mouse pressed in).\n\t\t\t\t\t\t\t\t\t// only on buttons that are not the \"active\" tab, or disabled\n\t\t\t\t\t\t\t\t\tbutton\n\t\t\t\t\t\t\t\t\t\t.not('.' + tm + '-state-active')\n\t\t\t\t\t\t\t\t\t\t.not('.' + tm + '-state-disabled')\n\t\t\t\t\t\t\t\t\t\t.addClass(tm + '-state-down');\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.mouseup(function() {\n\t\t\t\t\t\t\t\t\t// undo the *down* effect\n\t\t\t\t\t\t\t\t\tbutton.removeClass(tm + '-state-down');\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.hover(\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\t// the *hover* effect.\n\t\t\t\t\t\t\t\t\t\t// only on buttons that are not the \"active\" tab, or disabled\n\t\t\t\t\t\t\t\t\t\tbutton\n\t\t\t\t\t\t\t\t\t\t\t.not('.' + tm + '-state-active')\n\t\t\t\t\t\t\t\t\t\t\t.not('.' + tm + '-state-disabled')\n\t\t\t\t\t\t\t\t\t\t\t.addClass(tm + '-state-hover');\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\t// undo the *hover* effect\n\t\t\t\t\t\t\t\t\t\tbutton\n\t\t\t\t\t\t\t\t\t\t\t.removeClass(tm + '-state-hover')\n\t\t\t\t\t\t\t\t\t\t\t.removeClass(tm + '-state-down'); // if mouseleave happens before mouseup\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tgroupChildren = groupChildren.add(button);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif (isOnlyButtons) {\n\t\t\t\t\tgroupChildren\n\t\t\t\t\t\t.first().addClass(tm + '-corner-left').end()\n\t\t\t\t\t\t.last().addClass(tm + '-corner-right').end();\n\t\t\t\t}\n\n\t\t\t\tif (groupChildren.length > 1) {\n\t\t\t\t\tgroupEl = $('
');\n\t\t\t\t\tif (isOnlyButtons) {\n\t\t\t\t\t\tgroupEl.addClass('fc-button-group');\n\t\t\t\t\t}\n\t\t\t\t\tgroupEl.append(groupChildren);\n\t\t\t\t\tsectionEl.append(groupEl);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tsectionEl.append(groupChildren); // 1 or 0 children\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn sectionEl;\n\t}\n\t\n\t\n\tfunction updateTitle(text) {\n\t\tel.find('h2').text(text);\n\t}\n\t\n\t\n\tfunction activateButton(buttonName) {\n\t\tel.find('.fc-' + buttonName + '-button')\n\t\t\t.addClass(tm + '-state-active');\n\t}\n\t\n\t\n\tfunction deactivateButton(buttonName) {\n\t\tel.find('.fc-' + buttonName + '-button')\n\t\t\t.removeClass(tm + '-state-active');\n\t}\n\t\n\t\n\tfunction disableButton(buttonName) {\n\t\tel.find('.fc-' + buttonName + '-button')\n\t\t\t.attr('disabled', 'disabled')\n\t\t\t.addClass(tm + '-state-disabled');\n\t}\n\t\n\t\n\tfunction enableButton(buttonName) {\n\t\tel.find('.fc-' + buttonName + '-button')\n\t\t\t.removeAttr('disabled')\n\t\t\t.removeClass(tm + '-state-disabled');\n\t}\n\n\n\tfunction getViewsWithButtons() {\n\t\treturn viewsWithButtons;\n\t}\n\n}\n\n;;\n\nfc.sourceNormalizers = [];\nfc.sourceFetchers = [];\n\nvar ajaxDefaults = {\n\tdataType: 'json',\n\tcache: false\n};\n\nvar eventGUID = 1;\n\n\nfunction EventManager(options) { // assumed to be a calendar\n\tvar t = this;\n\t\n\t\n\t// exports\n\tt.isFetchNeeded = isFetchNeeded;\n\tt.fetchEvents = fetchEvents;\n\tt.addEventSource = addEventSource;\n\tt.removeEventSource = removeEventSource;\n\tt.updateEvent = updateEvent;\n\tt.renderEvent = renderEvent;\n\tt.removeEvents = removeEvents;\n\tt.clientEvents = clientEvents;\n\tt.mutateEvent = mutateEvent;\n\tt.normalizeEventRange = normalizeEventRange;\n\tt.normalizeEventRangeTimes = normalizeEventRangeTimes;\n\tt.ensureVisibleEventRange = ensureVisibleEventRange;\n\t\n\t\n\t// imports\n\tvar reportEvents = t.reportEvents;\n\t\n\t\n\t// locals\n\tvar stickySource = { events: [] };\n\tvar sources = [ stickySource ];\n\tvar rangeStart, rangeEnd;\n\tvar currentFetchID = 0;\n\tvar pendingSourceCnt = 0;\n\tvar cache = []; // holds events that have already been expanded\n\n\n\t$.each(\n\t\t(options.events ? [ options.events ] : []).concat(options.eventSources || []),\n\t\tfunction(i, sourceInput) {\n\t\t\tvar source = buildEventSource(sourceInput);\n\t\t\tif (source) {\n\t\t\t\tsources.push(source);\n\t\t\t}\n\t\t}\n\t);\n\t\n\t\n\t\n\t/* Fetching\n\t-----------------------------------------------------------------------------*/\n\t\n\t\n\tfunction isFetchNeeded(start, end) {\n\t\treturn !rangeStart || // nothing has been fetched yet?\n\t\t\t// or, a part of the new range is outside of the old range? (after normalizing)\n\t\t\tstart.clone().stripZone() < rangeStart.clone().stripZone() ||\n\t\t\tend.clone().stripZone() > rangeEnd.clone().stripZone();\n\t}\n\t\n\t\n\tfunction fetchEvents(start, end) {\n\t\trangeStart = start;\n\t\trangeEnd = end;\n\t\tcache = [];\n\t\tvar fetchID = ++currentFetchID;\n\t\tvar len = sources.length;\n\t\tpendingSourceCnt = len;\n\t\tfor (var i=0; i eventRange system\n\tfunction ensureVisibleEventRange(range) {\n\t\tvar allDay;\n\n\t\tif (!range.end) {\n\n\t\t\tallDay = range.allDay; // range might be more event-ish than we think\n\t\t\tif (allDay == null) {\n\t\t\t\tallDay = !range.start.hasTime();\n\t\t\t}\n\n\t\t\trange = $.extend({}, range); // make a copy, copying over other misc properties\n\t\t\trange.end = t.getDefaultEventEnd(allDay, range.start);\n\t\t}\n\t\treturn range;\n\t}\n\n\n\t// If the given event is a recurring event, break it down into an array of individual instances.\n\t// If not a recurring event, return an array with the single original event.\n\t// If given a falsy input (probably because of a failed buildEventFromInput call), returns an empty array.\n\t// HACK: can override the recurring window by providing custom rangeStart/rangeEnd (for businessHours).\n\tfunction expandEvent(abstractEvent, _rangeStart, _rangeEnd) {\n\t\tvar events = [];\n\t\tvar dowHash;\n\t\tvar dow;\n\t\tvar i;\n\t\tvar date;\n\t\tvar startTime, endTime;\n\t\tvar start, end;\n\t\tvar event;\n\n\t\t_rangeStart = _rangeStart || rangeStart;\n\t\t_rangeEnd = _rangeEnd || rangeEnd;\n\n\t\tif (abstractEvent) {\n\t\t\tif (abstractEvent._recurring) {\n\n\t\t\t\t// make a boolean hash as to whether the event occurs on each day-of-week\n\t\t\t\tif ((dow = abstractEvent.dow)) {\n\t\t\t\t\tdowHash = {};\n\t\t\t\t\tfor (i = 0; i < dow.length; i++) {\n\t\t\t\t\t\tdowHash[dow[i]] = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// iterate through every day in the current range\n\t\t\t\tdate = _rangeStart.clone().stripTime(); // holds the date of the current day\n\t\t\t\twhile (date.isBefore(_rangeEnd)) {\n\n\t\t\t\t\tif (!dowHash || dowHash[date.day()]) { // if everyday, or this particular day-of-week\n\n\t\t\t\t\t\tstartTime = abstractEvent.start; // the stored start and end properties are times (Durations)\n\t\t\t\t\t\tendTime = abstractEvent.end; // \"\n\t\t\t\t\t\tstart = date.clone();\n\t\t\t\t\t\tend = null;\n\n\t\t\t\t\t\tif (startTime) {\n\t\t\t\t\t\t\tstart = start.time(startTime);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (endTime) {\n\t\t\t\t\t\t\tend = date.clone().time(endTime);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tevent = $.extend({}, abstractEvent); // make a copy of the original\n\t\t\t\t\t\tassignDatesToEvent(\n\t\t\t\t\t\t\tstart, end,\n\t\t\t\t\t\t\t!startTime && !endTime, // allDay?\n\t\t\t\t\t\t\tevent\n\t\t\t\t\t\t);\n\t\t\t\t\t\tevents.push(event);\n\t\t\t\t\t}\n\n\t\t\t\t\tdate.add(1, 'days');\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tevents.push(abstractEvent); // return the original event. will be a one-item array\n\t\t\t}\n\t\t}\n\n\t\treturn events;\n\t}\n\n\n\n\t/* Event Modification Math\n\t-----------------------------------------------------------------------------------------*/\n\n\n\t// Modifies an event and all related events by applying the given properties.\n\t// Special date-diffing logic is used for manipulation of dates.\n\t// If `props` does not contain start/end dates, the updated values are assumed to be the event's current start/end.\n\t// All date comparisons are done against the event's pristine _start and _end dates.\n\t// Returns an object with delta information and a function to undo all operations.\n\t// For making computations in a granularity greater than day/time, specify largeUnit.\n\t// NOTE: The given `newProps` might be mutated for normalization purposes.\n\tfunction mutateEvent(event, newProps, largeUnit) {\n\t\tvar miscProps = {};\n\t\tvar oldProps;\n\t\tvar clearEnd;\n\t\tvar startDelta;\n\t\tvar endDelta;\n\t\tvar durationDelta;\n\t\tvar undoFunc;\n\n\t\t// diffs the dates in the appropriate way, returning a duration\n\t\tfunction diffDates(date1, date0) { // date1 - date0\n\t\t\tif (largeUnit) {\n\t\t\t\treturn diffByUnit(date1, date0, largeUnit);\n\t\t\t}\n\t\t\telse if (newProps.allDay) {\n\t\t\t\treturn diffDay(date1, date0);\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn diffDayTime(date1, date0);\n\t\t\t}\n\t\t}\n\n\t\tnewProps = newProps || {};\n\n\t\t// normalize new date-related properties\n\t\tif (!newProps.start) {\n\t\t\tnewProps.start = event.start.clone();\n\t\t}\n\t\tif (newProps.end === undefined) {\n\t\t\tnewProps.end = event.end ? event.end.clone() : null;\n\t\t}\n\t\tif (newProps.allDay == null) { // is null or undefined?\n\t\t\tnewProps.allDay = event.allDay;\n\t\t}\n\t\tnormalizeEventRange(newProps);\n\n\t\t// create normalized versions of the original props to compare against\n\t\t// need a real end value, for diffing\n\t\toldProps = {\n\t\t\tstart: event._start.clone(),\n\t\t\tend: event._end ? event._end.clone() : t.getDefaultEventEnd(event._allDay, event._start),\n\t\t\tallDay: newProps.allDay // normalize the dates in the same regard as the new properties\n\t\t};\n\t\tnormalizeEventRange(oldProps);\n\n\t\t// need to clear the end date if explicitly changed to null\n\t\tclearEnd = event._end !== null && newProps.end === null;\n\n\t\t// compute the delta for moving the start date\n\t\tstartDelta = diffDates(newProps.start, oldProps.start);\n\n\t\t// compute the delta for moving the end date\n\t\tif (newProps.end) {\n\t\t\tendDelta = diffDates(newProps.end, oldProps.end);\n\t\t\tdurationDelta = endDelta.subtract(startDelta);\n\t\t}\n\t\telse {\n\t\t\tdurationDelta = null;\n\t\t}\n\n\t\t// gather all non-date-related properties\n\t\t$.each(newProps, function(name, val) {\n\t\t\tif (isMiscEventPropName(name)) {\n\t\t\t\tif (val !== undefined) {\n\t\t\t\t\tmiscProps[name] = val;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// apply the operations to the event and all related events\n\t\tundoFunc = mutateEvents(\n\t\t\tclientEvents(event._id), // get events with this ID\n\t\t\tclearEnd,\n\t\t\tnewProps.allDay,\n\t\t\tstartDelta,\n\t\t\tdurationDelta,\n\t\t\tmiscProps\n\t\t);\n\n\t\treturn {\n\t\t\tdateDelta: startDelta,\n\t\t\tdurationDelta: durationDelta,\n\t\t\tundo: undoFunc\n\t\t};\n\t}\n\n\n\t// Modifies an array of events in the following ways (operations are in order):\n\t// - clear the event's `end`\n\t// - convert the event to allDay\n\t// - add `dateDelta` to the start and end\n\t// - add `durationDelta` to the event's duration\n\t// - assign `miscProps` to the event\n\t//\n\t// Returns a function that can be called to undo all the operations.\n\t//\n\t// TODO: don't use so many closures. possible memory issues when lots of events with same ID.\n\t//\n\tfunction mutateEvents(events, clearEnd, allDay, dateDelta, durationDelta, miscProps) {\n\t\tvar isAmbigTimezone = t.getIsAmbigTimezone();\n\t\tvar undoFunctions = [];\n\n\t\t// normalize zero-length deltas to be null\n\t\tif (dateDelta && !dateDelta.valueOf()) { dateDelta = null; }\n\t\tif (durationDelta && !durationDelta.valueOf()) { durationDelta = null; }\n\n\t\t$.each(events, function(i, event) {\n\t\t\tvar oldProps;\n\t\t\tvar newProps;\n\n\t\t\t// build an object holding all the old values, both date-related and misc.\n\t\t\t// for the undo function.\n\t\t\toldProps = {\n\t\t\t\tstart: event.start.clone(),\n\t\t\t\tend: event.end ? event.end.clone() : null,\n\t\t\t\tallDay: event.allDay\n\t\t\t};\n\t\t\t$.each(miscProps, function(name) {\n\t\t\t\toldProps[name] = event[name];\n\t\t\t});\n\n\t\t\t// new date-related properties. work off the original date snapshot.\n\t\t\t// ok to use references because they will be thrown away when backupEventDates is called.\n\t\t\tnewProps = {\n\t\t\t\tstart: event._start,\n\t\t\t\tend: event._end,\n\t\t\t\tallDay: allDay // normalize the dates in the same regard as the new properties\n\t\t\t};\n\t\t\tnormalizeEventRange(newProps); // massages start/end/allDay\n\n\t\t\t// strip or ensure the end date\n\t\t\tif (clearEnd) {\n\t\t\t\tnewProps.end = null;\n\t\t\t}\n\t\t\telse if (durationDelta && !newProps.end) { // the duration translation requires an end date\n\t\t\t\tnewProps.end = t.getDefaultEventEnd(newProps.allDay, newProps.start);\n\t\t\t}\n\n\t\t\tif (dateDelta) {\n\t\t\t\tnewProps.start.add(dateDelta);\n\t\t\t\tif (newProps.end) {\n\t\t\t\t\tnewProps.end.add(dateDelta);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (durationDelta) {\n\t\t\t\tnewProps.end.add(durationDelta); // end already ensured above\n\t\t\t}\n\n\t\t\t// if the dates have changed, and we know it is impossible to recompute the\n\t\t\t// timezone offsets, strip the zone.\n\t\t\tif (\n\t\t\t\tisAmbigTimezone &&\n\t\t\t\t!newProps.allDay &&\n\t\t\t\t(dateDelta || durationDelta)\n\t\t\t) {\n\t\t\t\tnewProps.start.stripZone();\n\t\t\t\tif (newProps.end) {\n\t\t\t\t\tnewProps.end.stripZone();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$.extend(event, miscProps, newProps); // copy over misc props, then date-related props\n\t\t\tbackupEventDates(event); // regenerate internal _start/_end/_allDay\n\n\t\t\tundoFunctions.push(function() {\n\t\t\t\t$.extend(event, oldProps);\n\t\t\t\tbackupEventDates(event); // regenerate internal _start/_end/_allDay\n\t\t\t});\n\t\t});\n\n\t\treturn function() {\n\t\t\tfor (var i = 0; i < undoFunctions.length; i++) {\n\t\t\t\tundoFunctions[i]();\n\t\t\t}\n\t\t};\n\t}\n\n\n\t/* Business Hours\n\t-----------------------------------------------------------------------------------------*/\n\n\tt.getBusinessHoursEvents = getBusinessHoursEvents;\n\n\n\t// Returns an array of events as to when the business hours occur in the given view.\n\t// Abuse of our event system :(\n\tfunction getBusinessHoursEvents(wholeDay) {\n\t\tvar optionVal = options.businessHours;\n\t\tvar defaultVal = {\n\t\t\tclassName: 'fc-nonbusiness',\n\t\t\tstart: '09:00',\n\t\t\tend: '17:00',\n\t\t\tdow: [ 1, 2, 3, 4, 5 ], // monday - friday\n\t\t\trendering: 'inverse-background'\n\t\t};\n\t\tvar view = t.getView();\n\t\tvar eventInput;\n\n\t\tif (optionVal) { // `true` (which means \"use the defaults\") or an override object\n\t\t\teventInput = $.extend(\n\t\t\t\t{}, // copy to a new object in either case\n\t\t\t\tdefaultVal,\n\t\t\t\ttypeof optionVal === 'object' ? optionVal : {} // override the defaults\n\t\t\t);\n\t\t}\n\n\t\tif (eventInput) {\n\n\t\t\t// if a whole-day series is requested, clear the start/end times\n\t\t\tif (wholeDay) {\n\t\t\t\teventInput.start = null;\n\t\t\t\teventInput.end = null;\n\t\t\t}\n\n\t\t\treturn expandEvent(\n\t\t\t\tbuildEventFromInput(eventInput),\n\t\t\t\tview.start,\n\t\t\t\tview.end\n\t\t\t);\n\t\t}\n\n\t\treturn [];\n\t}\n\n\n\t/* Overlapping / Constraining\n\t-----------------------------------------------------------------------------------------*/\n\n\tt.isEventRangeAllowed = isEventRangeAllowed;\n\tt.isSelectionRangeAllowed = isSelectionRangeAllowed;\n\tt.isExternalDropRangeAllowed = isExternalDropRangeAllowed;\n\n\n\tfunction isEventRangeAllowed(range, event) {\n\t\tvar source = event.source || {};\n\t\tvar constraint = firstDefined(\n\t\t\tevent.constraint,\n\t\t\tsource.constraint,\n\t\t\toptions.eventConstraint\n\t\t);\n\t\tvar overlap = firstDefined(\n\t\t\tevent.overlap,\n\t\t\tsource.overlap,\n\t\t\toptions.eventOverlap\n\t\t);\n\n\t\trange = ensureVisibleEventRange(range); // ensure a proper range with an end for isRangeAllowed\n\n\t\treturn isRangeAllowed(range, constraint, overlap, event);\n\t}\n\n\n\tfunction isSelectionRangeAllowed(range) {\n\t\treturn isRangeAllowed(range, options.selectConstraint, options.selectOverlap);\n\t}\n\n\n\t// when `eventProps` is defined, consider this an event.\n\t// `eventProps` can contain misc non-date-related info about the event.\n\tfunction isExternalDropRangeAllowed(range, eventProps) {\n\t\tvar eventInput;\n\t\tvar event;\n\n\t\t// note: very similar logic is in View's reportExternalDrop\n\t\tif (eventProps) {\n\t\t\teventInput = $.extend({}, eventProps, range);\n\t\t\tevent = expandEvent(buildEventFromInput(eventInput))[0];\n\t\t}\n\n\t\tif (event) {\n\t\t\treturn isEventRangeAllowed(range, event);\n\t\t}\n\t\telse { // treat it as a selection\n\n\t\t\trange = ensureVisibleEventRange(range); // ensure a proper range with an end for isSelectionRangeAllowed\n\n\t\t\treturn isSelectionRangeAllowed(range);\n\t\t}\n\t}\n\n\n\t// Returns true if the given range (caused by an event drop/resize or a selection) is allowed to exist\n\t// according to the constraint/overlap settings.\n\t// `event` is not required if checking a selection.\n\tfunction isRangeAllowed(range, constraint, overlap, event) {\n\t\tvar constraintEvents;\n\t\tvar anyContainment;\n\t\tvar peerEvents;\n\t\tvar i, peerEvent;\n\t\tvar peerOverlap;\n\n\t\t// normalize. fyi, we're normalizing in too many places :(\n\t\trange = $.extend({}, range); // copy all properties in case there are misc non-date properties\n\t\trange.start = range.start.clone().stripZone();\n\t\trange.end = range.end.clone().stripZone();\n\n\t\t// the range must be fully contained by at least one of produced constraint events\n\t\tif (constraint != null) {\n\n\t\t\t// not treated as an event! intermediate data structure\n\t\t\t// TODO: use ranges in the future\n\t\t\tconstraintEvents = constraintToEvents(constraint);\n\n\t\t\tanyContainment = false;\n\t\t\tfor (i = 0; i < constraintEvents.length; i++) {\n\t\t\t\tif (eventContainsRange(constraintEvents[i], range)) {\n\t\t\t\t\tanyContainment = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!anyContainment) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpeerEvents = t.getPeerEvents(event, range);\n\n\t\tfor (i = 0; i < peerEvents.length; i++) {\n\t\t\tpeerEvent = peerEvents[i];\n\n\t\t\t// there needs to be an actual intersection before disallowing anything\n\t\t\tif (eventIntersectsRange(peerEvent, range)) {\n\n\t\t\t\t// evaluate overlap for the given range and short-circuit if necessary\n\t\t\t\tif (overlap === false) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// if the event's overlap is a test function, pass the peer event in question as the first param\n\t\t\t\telse if (typeof overlap === 'function' && !overlap(peerEvent, event)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// if we are computing if the given range is allowable for an event, consider the other event's\n\t\t\t\t// EventObject-specific or Source-specific `overlap` property\n\t\t\t\tif (event) {\n\t\t\t\t\tpeerOverlap = firstDefined(\n\t\t\t\t\t\tpeerEvent.overlap,\n\t\t\t\t\t\t(peerEvent.source || {}).overlap\n\t\t\t\t\t\t// we already considered the global `eventOverlap`\n\t\t\t\t\t);\n\t\t\t\t\tif (peerOverlap === false) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\t// if the peer event's overlap is a test function, pass the subject event as the first param\n\t\t\t\t\tif (typeof peerOverlap === 'function' && !peerOverlap(event, peerEvent)) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\n\t// Given an event input from the API, produces an array of event objects. Possible event inputs:\n\t// 'businessHours'\n\t// An event ID (number or string)\n\t// An object with specific start/end dates or a recurring event (like what businessHours accepts)\n\tfunction constraintToEvents(constraintInput) {\n\n\t\tif (constraintInput === 'businessHours') {\n\t\t\treturn getBusinessHoursEvents();\n\t\t}\n\n\t\tif (typeof constraintInput === 'object') {\n\t\t\treturn expandEvent(buildEventFromInput(constraintInput));\n\t\t}\n\n\t\treturn clientEvents(constraintInput); // probably an ID\n\t}\n\n\n\t// Does the event's date range fully contain the given range?\n\t// start/end already assumed to have stripped zones :(\n\tfunction eventContainsRange(event, range) {\n\t\tvar eventStart = event.start.clone().stripZone();\n\t\tvar eventEnd = t.getEventEnd(event).stripZone();\n\n\t\treturn range.start >= eventStart && range.end <= eventEnd;\n\t}\n\n\n\t// Does the event's date range intersect with the given range?\n\t// start/end already assumed to have stripped zones :(\n\tfunction eventIntersectsRange(event, range) {\n\t\tvar eventStart = event.start.clone().stripZone();\n\t\tvar eventEnd = t.getEventEnd(event).stripZone();\n\n\t\treturn range.start < eventEnd && range.end > eventStart;\n\t}\n\n\n\tt.getEventCache = function() {\n\t\treturn cache;\n\t};\n\n}\n\n\n// Returns a list of events that the given event should be compared against when being considered for a move to\n// the specified range. Attached to the Calendar's prototype because EventManager is a mixin for a Calendar.\nCalendar.prototype.getPeerEvents = function(event, range) {\n\tvar cache = this.getEventCache();\n\tvar peerEvents = [];\n\tvar i, otherEvent;\n\n\tfor (i = 0; i < cache.length; i++) {\n\t\totherEvent = cache[i];\n\t\tif (\n\t\t\t!event ||\n\t\t\tevent._id !== otherEvent._id // don't compare the event to itself or other related [repeating] events\n\t\t) {\n\t\t\tpeerEvents.push(otherEvent);\n\t\t}\n\t}\n\n\treturn peerEvents;\n};\n\n\n// updates the \"backup\" properties, which are preserved in order to compute diffs later on.\nfunction backupEventDates(event) {\n\tevent._allDay = event.allDay;\n\tevent._start = event.start.clone();\n\tevent._end = event.end ? event.end.clone() : null;\n}\n\n;;\n\n/* An abstract class for the \"basic\" views, as well as month view. Renders one or more rows of day cells.\n----------------------------------------------------------------------------------------------------------------------*/\n// It is a manager for a DayGrid subcomponent, which does most of the heavy lifting.\n// It is responsible for managing width/height.\n\nvar BasicView = View.extend({\n\n\tdayGrid: null, // the main subcomponent that does most of the heavy lifting\n\n\tdayNumbersVisible: false, // display day numbers on each day cell?\n\tweekNumbersVisible: false, // display week numbers along the side?\n\n\tweekNumberWidth: null, // width of all the week-number cells running down the side\n\n\theadRowEl: null, // the fake row element of the day-of-week header\n\n\n\tinitialize: function() {\n\t\tthis.dayGrid = new DayGrid(this);\n\t\tthis.coordMap = this.dayGrid.coordMap; // the view's date-to-cell mapping is identical to the subcomponent's\n\t},\n\n\n\t// Sets the display range and computes all necessary dates\n\tsetRange: function(range) {\n\t\tView.prototype.setRange.call(this, range); // call the super-method\n\n\t\tthis.dayGrid.breakOnWeeks = /year|month|week/.test(this.intervalUnit); // do before setRange\n\t\tthis.dayGrid.setRange(range);\n\t},\n\n\n\t// Compute the value to feed into setRange. Overrides superclass.\n\tcomputeRange: function(date) {\n\t\tvar range = View.prototype.computeRange.call(this, date); // get value from the super-method\n\n\t\t// year and month views should be aligned with weeks. this is already done for week\n\t\tif (/year|month/.test(range.intervalUnit)) {\n\t\t\trange.start.startOf('week');\n\t\t\trange.start = this.skipHiddenDays(range.start);\n\n\t\t\t// make end-of-week if not already\n\t\t\tif (range.end.weekday()) {\n\t\t\t\trange.end.add(1, 'week').startOf('week');\n\t\t\t\trange.end = this.skipHiddenDays(range.end, -1, true); // exclusively move backwards\n\t\t\t}\n\t\t}\n\n\t\treturn range;\n\t},\n\n\n\t// Renders the view into `this.el`, which should already be assigned\n\trenderDates: function() {\n\n\t\tthis.dayNumbersVisible = this.dayGrid.rowCnt > 1; // TODO: make grid responsible\n\t\tthis.weekNumbersVisible = this.opt('weekNumbers');\n\t\tthis.dayGrid.numbersVisible = this.dayNumbersVisible || this.weekNumbersVisible;\n\n\t\tthis.el.addClass('fc-basic-view').html(this.renderHtml());\n\n\t\tthis.headRowEl = this.el.find('thead .fc-row');\n\n\t\tthis.scrollerEl = this.el.find('.fc-day-grid-container');\n\t\tthis.dayGrid.coordMap.containerEl = this.scrollerEl; // constrain clicks/etc to the dimensions of the scroller\n\n\t\tthis.dayGrid.setElement(this.el.find('.fc-day-grid'));\n\t\tthis.dayGrid.renderDates(this.hasRigidRows());\n\t},\n\n\n\t// Unrenders the content of the view. Since we haven't separated skeleton rendering from date rendering,\n\t// always completely kill the dayGrid's rendering.\n\tunrenderDates: function() {\n\t\tthis.dayGrid.unrenderDates();\n\t\tthis.dayGrid.removeElement();\n\t},\n\n\n\trenderBusinessHours: function() {\n\t\tthis.dayGrid.renderBusinessHours();\n\t},\n\n\n\t// Builds the HTML skeleton for the view.\n\t// The day-grid component will render inside of a container defined by this HTML.\n\trenderHtml: function() {\n\t\treturn '' +\n\t\t\t'' +\n\t\t\t\t'' +\n\t\t\t\t\t'' +\n\t\t\t\t\t\t'' +\n\t\t\t\t\t'' +\n\t\t\t\t'' +\n\t\t\t\t'' +\n\t\t\t\t\t'' +\n\t\t\t\t\t\t'' +\n\t\t\t\t\t'' +\n\t\t\t\t'' +\n\t\t\t'
' +\n\t\t\t\t\t\t\tthis.dayGrid.headHtml() + // render the day-of-week headers\n\t\t\t\t\t\t'
' +\n\t\t\t\t\t\t\t'
' +\n\t\t\t\t\t\t\t\t'
' +\n\t\t\t\t\t\t\t'
' +\n\t\t\t\t\t\t'
';\n\t},\n\n\n\t// Generates the HTML that will go before the day-of week header cells.\n\t// Queried by the DayGrid subcomponent when generating rows. Ordering depends on isRTL.\n\theadIntroHtml: function() {\n\t\tif (this.weekNumbersVisible) {\n\t\t\treturn '' +\n\t\t\t\t'' +\n\t\t\t\t\t'' + // needed for matchCellWidths\n\t\t\t\t\t\thtmlEscape(this.opt('weekNumberTitle')) +\n\t\t\t\t\t'' +\n\t\t\t\t'';\n\t\t}\n\t},\n\n\n\t// Generates the HTML that will go before content-skeleton cells that display the day/week numbers.\n\t// Queried by the DayGrid subcomponent. Ordering depends on isRTL.\n\tnumberIntroHtml: function(row) {\n\t\tif (this.weekNumbersVisible) {\n\t\t\treturn '' +\n\t\t\t\t'' +\n\t\t\t\t\t'' + // needed for matchCellWidths\n\t\t\t\t\t\tthis.dayGrid.getCell(row, 0).start.format('w') +\n\t\t\t\t\t'' +\n\t\t\t\t'';\n\t\t}\n\t},\n\n\n\t// Generates the HTML that goes before the day bg cells for each day-row.\n\t// Queried by the DayGrid subcomponent. Ordering depends on isRTL.\n\tdayIntroHtml: function() {\n\t\tif (this.weekNumbersVisible) {\n\t\t\treturn '';\n\t\t}\n\t},\n\n\n\t// Generates the HTML that goes before every other type of row generated by DayGrid. Ordering depends on isRTL.\n\t// Affects helper-skeleton and highlight-skeleton rows.\n\tintroHtml: function() {\n\t\tif (this.weekNumbersVisible) {\n\t\t\treturn '';\n\t\t}\n\t},\n\n\n\t// Generates the HTML for the s of the \"number\" row in the DayGrid's content skeleton.\n\t// The number row will only exist if either day numbers or week numbers are turned on.\n\tnumberCellHtml: function(cell) {\n\t\tvar date = cell.start;\n\t\tvar classes;\n\n\t\tif (!this.dayNumbersVisible) { // if there are week numbers but not day numbers\n\t\t\treturn ''; // will create an empty space above events :(\n\t\t}\n\n\t\tclasses = this.dayGrid.getDayClasses(date);\n\t\tclasses.unshift('fc-day-number');\n\n\t\treturn '' +\n\t\t\t'' +\n\t\t\t\tdate.date() +\n\t\t\t'';\n\t},\n\n\n\t// Generates an HTML attribute string for setting the width of the week number column, if it is known\n\tweekNumberStyleAttr: function() {\n\t\tif (this.weekNumberWidth !== null) {\n\t\t\treturn 'style=\"width:' + this.weekNumberWidth + 'px\"';\n\t\t}\n\t\treturn '';\n\t},\n\n\n\t// Determines whether each row should have a constant height\n\thasRigidRows: function() {\n\t\tvar eventLimit = this.opt('eventLimit');\n\t\treturn eventLimit && typeof eventLimit !== 'number';\n\t},\n\n\n\t/* Dimensions\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Refreshes the horizontal dimensions of the view\n\tupdateWidth: function() {\n\t\tif (this.weekNumbersVisible) {\n\t\t\t// Make sure all week number cells running down the side have the same width.\n\t\t\t// Record the width for cells created later.\n\t\t\tthis.weekNumberWidth = matchCellWidths(\n\t\t\t\tthis.el.find('.fc-week-number')\n\t\t\t);\n\t\t}\n\t},\n\n\n\t// Adjusts the vertical dimensions of the view to the specified values\n\tsetHeight: function(totalHeight, isAuto) {\n\t\tvar eventLimit = this.opt('eventLimit');\n\t\tvar scrollerHeight;\n\n\t\t// reset all heights to be natural\n\t\tunsetScroller(this.scrollerEl);\n\t\tuncompensateScroll(this.headRowEl);\n\n\t\tthis.dayGrid.removeSegPopover(); // kill the \"more\" popover if displayed\n\n\t\t// is the event limit a constant level number?\n\t\tif (eventLimit && typeof eventLimit === 'number') {\n\t\t\tthis.dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after\n\t\t}\n\n\t\tscrollerHeight = this.computeScrollerHeight(totalHeight);\n\t\tthis.setGridHeight(scrollerHeight, isAuto);\n\n\t\t// is the event limit dynamically calculated?\n\t\tif (eventLimit && typeof eventLimit !== 'number') {\n\t\t\tthis.dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set\n\t\t}\n\n\t\tif (!isAuto && setPotentialScroller(this.scrollerEl, scrollerHeight)) { // using scrollbars?\n\n\t\t\tcompensateScroll(this.headRowEl, getScrollbarWidths(this.scrollerEl));\n\n\t\t\t// doing the scrollbar compensation might have created text overflow which created more height. redo\n\t\t\tscrollerHeight = this.computeScrollerHeight(totalHeight);\n\t\t\tthis.scrollerEl.height(scrollerHeight);\n\t\t}\n\t},\n\n\n\t// Sets the height of just the DayGrid component in this view\n\tsetGridHeight: function(height, isAuto) {\n\t\tif (isAuto) {\n\t\t\tundistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding\n\t\t}\n\t\telse {\n\t\t\tdistributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows\n\t\t}\n\t},\n\n\n\t/* Events\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders the given events onto the view and populates the segments array\n\trenderEvents: function(events) {\n\t\tthis.dayGrid.renderEvents(events);\n\n\t\tthis.updateHeight(); // must compensate for events that overflow the row\n\t},\n\n\n\t// Retrieves all segment objects that are rendered in the view\n\tgetEventSegs: function() {\n\t\treturn this.dayGrid.getEventSegs();\n\t},\n\n\n\t// Unrenders all event elements and clears internal segment data\n\tunrenderEvents: function() {\n\t\tthis.dayGrid.unrenderEvents();\n\n\t\t// we DON'T need to call updateHeight() because:\n\t\t// A) a renderEvents() call always happens after this, which will eventually call updateHeight()\n\t\t// B) in IE8, this causes a flash whenever events are rerendered\n\t},\n\n\n\t/* Dragging (for both events and external elements)\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// A returned value of `true` signals that a mock \"helper\" event has been rendered.\n\trenderDrag: function(dropLocation, seg) {\n\t\treturn this.dayGrid.renderDrag(dropLocation, seg);\n\t},\n\n\n\tunrenderDrag: function() {\n\t\tthis.dayGrid.unrenderDrag();\n\t},\n\n\n\t/* Selection\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of a selection\n\trenderSelection: function(range) {\n\t\tthis.dayGrid.renderSelection(range);\n\t},\n\n\n\t// Unrenders a visual indications of a selection\n\tunrenderSelection: function() {\n\t\tthis.dayGrid.unrenderSelection();\n\t}\n\n});\n\n;;\n\n/* A month view with day cells running in rows (one-per-week) and columns\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar MonthView = BasicView.extend({\n\n\t// Produces information about what range to display\n\tcomputeRange: function(date) {\n\t\tvar range = BasicView.prototype.computeRange.call(this, date); // get value from super-method\n\t\tvar rowCnt;\n\n\t\t// ensure 6 weeks\n\t\tif (this.isFixedWeeks()) {\n\t\t\trowCnt = Math.ceil(range.end.diff(range.start, 'weeks', true)); // could be partial weeks due to hiddenDays\n\t\t\trange.end.add(6 - rowCnt, 'weeks');\n\t\t}\n\n\t\treturn range;\n\t},\n\n\n\t// Overrides the default BasicView behavior to have special multi-week auto-height logic\n\tsetGridHeight: function(height, isAuto) {\n\n\t\tisAuto = isAuto || this.opt('weekMode') === 'variable'; // LEGACY: weekMode is deprecated\n\n\t\t// if auto, make the height of each row the height that it would be if there were 6 weeks\n\t\tif (isAuto) {\n\t\t\theight *= this.rowCnt / 6;\n\t\t}\n\n\t\tdistributeHeight(this.dayGrid.rowEls, height, !isAuto); // if auto, don't compensate for height-hogging rows\n\t},\n\n\n\tisFixedWeeks: function() {\n\t\tvar weekMode = this.opt('weekMode'); // LEGACY: weekMode is deprecated\n\t\tif (weekMode) {\n\t\t\treturn weekMode === 'fixed'; // if any other type of weekMode, assume NOT fixed\n\t\t}\n\n\t\treturn this.opt('fixedWeekCount');\n\t}\n\n});\n\n;;\n\nfcViews.basic = {\n\t'class': BasicView\n};\n\nfcViews.basicDay = {\n\ttype: 'basic',\n\tduration: { days: 1 }\n};\n\nfcViews.basicWeek = {\n\ttype: 'basic',\n\tduration: { weeks: 1 }\n};\n\nfcViews.month = {\n\t'class': MonthView,\n\tduration: { months: 1 }, // important for prev/next\n\tdefaults: {\n\t\tfixedWeekCount: true\n\t}\n};\n;;\n\n/* An abstract class for all agenda-related views. Displays one more columns with time slots running vertically.\n----------------------------------------------------------------------------------------------------------------------*/\n// Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on).\n// Responsible for managing width/height.\n\nvar AgendaView = View.extend({\n\n\ttimeGrid: null, // the main time-grid subcomponent of this view\n\tdayGrid: null, // the \"all-day\" subcomponent. if all-day is turned off, this will be null\n\n\taxisWidth: null, // the width of the time axis running down the side\n\n\tnoScrollRowEls: null, // set of fake row elements that must compensate when scrollerEl has scrollbars\n\n\t// when the time-grid isn't tall enough to occupy the given height, we render an
underneath\n\tbottomRuleEl: null,\n\tbottomRuleHeight: null,\n\n\n\tinitialize: function() {\n\t\tthis.timeGrid = new TimeGrid(this);\n\n\t\tif (this.opt('allDaySlot')) { // should we display the \"all-day\" area?\n\t\t\tthis.dayGrid = new DayGrid(this); // the all-day subcomponent of this view\n\n\t\t\t// the coordinate grid will be a combination of both subcomponents' grids\n\t\t\tthis.coordMap = new ComboCoordMap([\n\t\t\t\tthis.dayGrid.coordMap,\n\t\t\t\tthis.timeGrid.coordMap\n\t\t\t]);\n\t\t}\n\t\telse {\n\t\t\tthis.coordMap = this.timeGrid.coordMap;\n\t\t}\n\t},\n\n\n\t/* Rendering\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Sets the display range and computes all necessary dates\n\tsetRange: function(range) {\n\t\tView.prototype.setRange.call(this, range); // call the super-method\n\n\t\tthis.timeGrid.setRange(range);\n\t\tif (this.dayGrid) {\n\t\t\tthis.dayGrid.setRange(range);\n\t\t}\n\t},\n\n\n\t// Renders the view into `this.el`, which has already been assigned\n\trenderDates: function() {\n\n\t\tthis.el.addClass('fc-agenda-view').html(this.renderHtml());\n\n\t\t// the element that wraps the time-grid that will probably scroll\n\t\tthis.scrollerEl = this.el.find('.fc-time-grid-container');\n\t\tthis.timeGrid.coordMap.containerEl = this.scrollerEl; // don't accept clicks/etc outside of this\n\n\t\tthis.timeGrid.setElement(this.el.find('.fc-time-grid'));\n\t\tthis.timeGrid.renderDates();\n\n\t\t// the
that sometimes displays under the time-grid\n\t\tthis.bottomRuleEl = $('
')\n\t\t\t.appendTo(this.timeGrid.el); // inject it into the time-grid\n\n\t\tif (this.dayGrid) {\n\t\t\tthis.dayGrid.setElement(this.el.find('.fc-day-grid'));\n\t\t\tthis.dayGrid.renderDates();\n\n\t\t\t// have the day-grid extend it's coordinate area over the
dividing the two grids\n\t\t\tthis.dayGrid.bottomCoordPadding = this.dayGrid.el.next('hr').outerHeight();\n\t\t}\n\n\t\tthis.noScrollRowEls = this.el.find('.fc-row:not(.fc-scroller *)'); // fake rows not within the scroller\n\t},\n\n\n\t// Unrenders the content of the view. Since we haven't separated skeleton rendering from date rendering,\n\t// always completely kill each grid's rendering.\n\tunrenderDates: function() {\n\t\tthis.timeGrid.unrenderDates();\n\t\tthis.timeGrid.removeElement();\n\n\t\tif (this.dayGrid) {\n\t\t\tthis.dayGrid.unrenderDates();\n\t\t\tthis.dayGrid.removeElement();\n\t\t}\n\t},\n\n\n\trenderBusinessHours: function() {\n\t\tthis.timeGrid.renderBusinessHours();\n\n\t\tif (this.dayGrid) {\n\t\t\tthis.dayGrid.renderBusinessHours();\n\t\t}\n\t},\n\n\n\t// Builds the HTML skeleton for the view.\n\t// The day-grid and time-grid components will render inside containers defined by this HTML.\n\trenderHtml: function() {\n\t\treturn '' +\n\t\t\t'' +\n\t\t\t\t'' +\n\t\t\t\t\t'' +\n\t\t\t\t\t\t'' +\n\t\t\t\t\t'' +\n\t\t\t\t'' +\n\t\t\t\t'' +\n\t\t\t\t\t'' +\n\t\t\t\t\t\t'' +\n\t\t\t\t\t'' +\n\t\t\t\t'' +\n\t\t\t'
' +\n\t\t\t\t\t\t\tthis.timeGrid.headHtml() + // render the day-of-week headers\n\t\t\t\t\t\t'
' +\n\t\t\t\t\t\t\t(this.dayGrid ?\n\t\t\t\t\t\t\t\t'
' +\n\t\t\t\t\t\t\t\t'
' :\n\t\t\t\t\t\t\t\t''\n\t\t\t\t\t\t\t\t) +\n\t\t\t\t\t\t\t'
' +\n\t\t\t\t\t\t\t\t'
' +\n\t\t\t\t\t\t\t'
' +\n\t\t\t\t\t\t'
';\n\t},\n\n\n\t// Generates the HTML that will go before the day-of week header cells.\n\t// Queried by the TimeGrid subcomponent when generating rows. Ordering depends on isRTL.\n\theadIntroHtml: function() {\n\t\tvar date;\n\t\tvar weekText;\n\n\t\tif (this.opt('weekNumbers')) {\n\t\t\tdate = this.timeGrid.getCell(0).start;\n\t\t\tweekText = date.format(this.opt('smallWeekFormat'));\n\n\t\t\treturn '' +\n\t\t\t\t'' +\n\t\t\t\t\t'' + // needed for matchCellWidths\n\t\t\t\t\t\thtmlEscape(weekText) +\n\t\t\t\t\t'' +\n\t\t\t\t'';\n\t\t}\n\t\telse {\n\t\t\treturn '';\n\t\t}\n\t},\n\n\n\t// Generates the HTML that goes before the all-day cells.\n\t// Queried by the DayGrid subcomponent when generating rows. Ordering depends on isRTL.\n\tdayIntroHtml: function() {\n\t\treturn '' +\n\t\t\t'' +\n\t\t\t\t'' + // needed for matchCellWidths\n\t\t\t\t\t(this.opt('allDayHtml') || htmlEscape(this.opt('allDayText'))) +\n\t\t\t\t'' +\n\t\t\t'';\n\t},\n\n\n\t// Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column.\n\tslotBgIntroHtml: function() {\n\t\treturn '';\n\t},\n\n\n\t// Generates the HTML that goes before all other types of cells.\n\t// Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid.\n\t// Queried by the TimeGrid and DayGrid subcomponents when generating rows. Ordering depends on isRTL.\n\tintroHtml: function() {\n\t\treturn '';\n\t},\n\n\n\t// Generates an HTML attribute string for setting the width of the axis, if it is known\n\taxisStyleAttr: function() {\n\t\tif (this.axisWidth !== null) {\n\t\t\t return 'style=\"width:' + this.axisWidth + 'px\"';\n\t\t}\n\t\treturn '';\n\t},\n\n\n\t/* Dimensions\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\tupdateSize: function(isResize) {\n\t\tthis.timeGrid.updateSize(isResize);\n\n\t\tView.prototype.updateSize.call(this, isResize); // call the super-method\n\t},\n\n\n\t// Refreshes the horizontal dimensions of the view\n\tupdateWidth: function() {\n\t\t// make all axis cells line up, and record the width so newly created axis cells will have it\n\t\tthis.axisWidth = matchCellWidths(this.el.find('.fc-axis'));\n\t},\n\n\n\t// Adjusts the vertical dimensions of the view to the specified values\n\tsetHeight: function(totalHeight, isAuto) {\n\t\tvar eventLimit;\n\t\tvar scrollerHeight;\n\n\t\tif (this.bottomRuleHeight === null) {\n\t\t\t// calculate the height of the rule the very first time\n\t\t\tthis.bottomRuleHeight = this.bottomRuleEl.outerHeight();\n\t\t}\n\t\tthis.bottomRuleEl.hide(); // .show() will be called later if this
is necessary\n\n\t\t// reset all dimensions back to the original state\n\t\tthis.scrollerEl.css('overflow', '');\n\t\tunsetScroller(this.scrollerEl);\n\t\tuncompensateScroll(this.noScrollRowEls);\n\n\t\t// limit number of events in the all-day area\n\t\tif (this.dayGrid) {\n\t\t\tthis.dayGrid.removeSegPopover(); // kill the \"more\" popover if displayed\n\n\t\t\teventLimit = this.opt('eventLimit');\n\t\t\tif (eventLimit && typeof eventLimit !== 'number') {\n\t\t\t\teventLimit = AGENDA_ALL_DAY_EVENT_LIMIT; // make sure \"auto\" goes to a real number\n\t\t\t}\n\t\t\tif (eventLimit) {\n\t\t\t\tthis.dayGrid.limitRows(eventLimit);\n\t\t\t}\n\t\t}\n\n\t\tif (!isAuto) { // should we force dimensions of the scroll container, or let the contents be natural height?\n\n\t\t\tscrollerHeight = this.computeScrollerHeight(totalHeight);\n\t\t\tif (setPotentialScroller(this.scrollerEl, scrollerHeight)) { // using scrollbars?\n\n\t\t\t\t// make the all-day and header rows lines up\n\t\t\t\tcompensateScroll(this.noScrollRowEls, getScrollbarWidths(this.scrollerEl));\n\n\t\t\t\t// the scrollbar compensation might have changed text flow, which might affect height, so recalculate\n\t\t\t\t// and reapply the desired height to the scroller.\n\t\t\t\tscrollerHeight = this.computeScrollerHeight(totalHeight);\n\t\t\t\tthis.scrollerEl.height(scrollerHeight);\n\t\t\t}\n\t\t\telse { // no scrollbars\n\t\t\t\t// still, force a height and display the bottom rule (marks the end of day)\n\t\t\t\tthis.scrollerEl.height(scrollerHeight).css('overflow', 'hidden'); // in case
goes outside\n\t\t\t\tthis.bottomRuleEl.show();\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Computes the initial pre-configured scroll state prior to allowing the user to change it\n\tcomputeInitialScroll: function() {\n\t\tvar scrollTime = moment.duration(this.opt('scrollTime'));\n\t\tvar top = this.timeGrid.computeTimeTop(scrollTime);\n\n\t\t// zoom can give weird floating-point values. rather scroll a little bit further\n\t\ttop = Math.ceil(top);\n\n\t\tif (top) {\n\t\t\ttop++; // to overcome top border that slots beyond the first have. looks better\n\t\t}\n\n\t\treturn top;\n\t},\n\n\n\t/* Events\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders events onto the view and populates the View's segment array\n\trenderEvents: function(events) {\n\t\tvar dayEvents = [];\n\t\tvar timedEvents = [];\n\t\tvar daySegs = [];\n\t\tvar timedSegs;\n\t\tvar i;\n\n\t\t// separate the events into all-day and timed\n\t\tfor (i = 0; i < events.length; i++) {\n\t\t\tif (events[i].allDay) {\n\t\t\t\tdayEvents.push(events[i]);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttimedEvents.push(events[i]);\n\t\t\t}\n\t\t}\n\n\t\t// render the events in the subcomponents\n\t\ttimedSegs = this.timeGrid.renderEvents(timedEvents);\n\t\tif (this.dayGrid) {\n\t\t\tdaySegs = this.dayGrid.renderEvents(dayEvents);\n\t\t}\n\n\t\t// the all-day area is flexible and might have a lot of events, so shift the height\n\t\tthis.updateHeight();\n\t},\n\n\n\t// Retrieves all segment objects that are rendered in the view\n\tgetEventSegs: function() {\n\t\treturn this.timeGrid.getEventSegs().concat(\n\t\t\tthis.dayGrid ? this.dayGrid.getEventSegs() : []\n\t\t);\n\t},\n\n\n\t// Unrenders all event elements and clears internal segment data\n\tunrenderEvents: function() {\n\n\t\t// unrender the events in the subcomponents\n\t\tthis.timeGrid.unrenderEvents();\n\t\tif (this.dayGrid) {\n\t\t\tthis.dayGrid.unrenderEvents();\n\t\t}\n\n\t\t// we DON'T need to call updateHeight() because:\n\t\t// A) a renderEvents() call always happens after this, which will eventually call updateHeight()\n\t\t// B) in IE8, this causes a flash whenever events are rerendered\n\t},\n\n\n\t/* Dragging (for events and external elements)\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// A returned value of `true` signals that a mock \"helper\" event has been rendered.\n\trenderDrag: function(dropLocation, seg) {\n\t\tif (dropLocation.start.hasTime()) {\n\t\t\treturn this.timeGrid.renderDrag(dropLocation, seg);\n\t\t}\n\t\telse if (this.dayGrid) {\n\t\t\treturn this.dayGrid.renderDrag(dropLocation, seg);\n\t\t}\n\t},\n\n\n\tunrenderDrag: function() {\n\t\tthis.timeGrid.unrenderDrag();\n\t\tif (this.dayGrid) {\n\t\t\tthis.dayGrid.unrenderDrag();\n\t\t}\n\t},\n\n\n\t/* Selection\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of a selection\n\trenderSelection: function(range) {\n\t\tif (range.start.hasTime() || range.end.hasTime()) {\n\t\t\tthis.timeGrid.renderSelection(range);\n\t\t}\n\t\telse if (this.dayGrid) {\n\t\t\tthis.dayGrid.renderSelection(range);\n\t\t}\n\t},\n\n\n\t// Unrenders a visual indications of a selection\n\tunrenderSelection: function() {\n\t\tthis.timeGrid.unrenderSelection();\n\t\tif (this.dayGrid) {\n\t\t\tthis.dayGrid.unrenderSelection();\n\t\t}\n\t}\n\n});\n\n;;\n\nvar AGENDA_ALL_DAY_EVENT_LIMIT = 5;\n\n// potential nice values for the slot-duration and interval-duration\n// from largest to smallest\nvar AGENDA_STOCK_SUB_DURATIONS = [\n\t{ hours: 1 },\n\t{ minutes: 30 },\n\t{ minutes: 15 },\n\t{ seconds: 30 },\n\t{ seconds: 15 }\n];\n\nfcViews.agenda = {\n\t'class': AgendaView,\n\tdefaults: {\n\t\tallDaySlot: true,\n\t\tallDayText: 'all-day',\n\t\tslotDuration: '00:30:00',\n\t\tminTime: '00:00:00',\n\t\tmaxTime: '24:00:00',\n\t\tslotEventOverlap: true // a bad name. confused with overlap/constraint system\n\t}\n};\n\nfcViews.agendaDay = {\n\ttype: 'agenda',\n\tduration: { days: 1 }\n};\n\nfcViews.agendaWeek = {\n\ttype: 'agenda',\n\tduration: { weeks: 1 }\n};\n;;\n\nreturn fc; // export for Node/CommonJS\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/fullcalendar/dist/fullcalendar.js\n ** module id = 2\n ** module chunks = 0\n **/","//! moment.js\n//! version : 2.10.6\n//! authors : Tim Wood, Iskren Chernev, Moment.js contributors\n//! license : MIT\n//! momentjs.com\n\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n global.moment = factory()\n}(this, function () { 'use strict';\n\n var hookCallback;\n\n function utils_hooks__hooks () {\n return hookCallback.apply(null, arguments);\n }\n\n // This is done to register the method called with moment()\n // without creating circular dependencies.\n function setHookCallback (callback) {\n hookCallback = callback;\n }\n\n function isArray(input) {\n return Object.prototype.toString.call(input) === '[object Array]';\n }\n\n function isDate(input) {\n return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n }\n\n function map(arr, fn) {\n var res = [], i;\n for (i = 0; i < arr.length; ++i) {\n res.push(fn(arr[i], i));\n }\n return res;\n }\n\n function hasOwnProp(a, b) {\n return Object.prototype.hasOwnProperty.call(a, b);\n }\n\n function extend(a, b) {\n for (var i in b) {\n if (hasOwnProp(b, i)) {\n a[i] = b[i];\n }\n }\n\n if (hasOwnProp(b, 'toString')) {\n a.toString = b.toString;\n }\n\n if (hasOwnProp(b, 'valueOf')) {\n a.valueOf = b.valueOf;\n }\n\n return a;\n }\n\n function create_utc__createUTC (input, format, locale, strict) {\n return createLocalOrUTC(input, format, locale, strict, true).utc();\n }\n\n function defaultParsingFlags() {\n // We need to deep clone this object.\n return {\n empty : false,\n unusedTokens : [],\n unusedInput : [],\n overflow : -2,\n charsLeftOver : 0,\n nullInput : false,\n invalidMonth : null,\n invalidFormat : false,\n userInvalidated : false,\n iso : false\n };\n }\n\n function getParsingFlags(m) {\n if (m._pf == null) {\n m._pf = defaultParsingFlags();\n }\n return m._pf;\n }\n\n function valid__isValid(m) {\n if (m._isValid == null) {\n var flags = getParsingFlags(m);\n m._isValid = !isNaN(m._d.getTime()) &&\n flags.overflow < 0 &&\n !flags.empty &&\n !flags.invalidMonth &&\n !flags.invalidWeekday &&\n !flags.nullInput &&\n !flags.invalidFormat &&\n !flags.userInvalidated;\n\n if (m._strict) {\n m._isValid = m._isValid &&\n flags.charsLeftOver === 0 &&\n flags.unusedTokens.length === 0 &&\n flags.bigHour === undefined;\n }\n }\n return m._isValid;\n }\n\n function valid__createInvalid (flags) {\n var m = create_utc__createUTC(NaN);\n if (flags != null) {\n extend(getParsingFlags(m), flags);\n }\n else {\n getParsingFlags(m).userInvalidated = true;\n }\n\n return m;\n }\n\n var momentProperties = utils_hooks__hooks.momentProperties = [];\n\n function copyConfig(to, from) {\n var i, prop, val;\n\n if (typeof from._isAMomentObject !== 'undefined') {\n to._isAMomentObject = from._isAMomentObject;\n }\n if (typeof from._i !== 'undefined') {\n to._i = from._i;\n }\n if (typeof from._f !== 'undefined') {\n to._f = from._f;\n }\n if (typeof from._l !== 'undefined') {\n to._l = from._l;\n }\n if (typeof from._strict !== 'undefined') {\n to._strict = from._strict;\n }\n if (typeof from._tzm !== 'undefined') {\n to._tzm = from._tzm;\n }\n if (typeof from._isUTC !== 'undefined') {\n to._isUTC = from._isUTC;\n }\n if (typeof from._offset !== 'undefined') {\n to._offset = from._offset;\n }\n if (typeof from._pf !== 'undefined') {\n to._pf = getParsingFlags(from);\n }\n if (typeof from._locale !== 'undefined') {\n to._locale = from._locale;\n }\n\n if (momentProperties.length > 0) {\n for (i in momentProperties) {\n prop = momentProperties[i];\n val = from[prop];\n if (typeof val !== 'undefined') {\n to[prop] = val;\n }\n }\n }\n\n return to;\n }\n\n var updateInProgress = false;\n\n // Moment prototype object\n function Moment(config) {\n copyConfig(this, config);\n this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n // Prevent infinite loop in case updateOffset creates new moment\n // objects.\n if (updateInProgress === false) {\n updateInProgress = true;\n utils_hooks__hooks.updateOffset(this);\n updateInProgress = false;\n }\n }\n\n function isMoment (obj) {\n return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n }\n\n function absFloor (number) {\n if (number < 0) {\n return Math.ceil(number);\n } else {\n return Math.floor(number);\n }\n }\n\n function toInt(argumentForCoercion) {\n var coercedNumber = +argumentForCoercion,\n value = 0;\n\n if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n value = absFloor(coercedNumber);\n }\n\n return value;\n }\n\n function compareArrays(array1, array2, dontConvert) {\n var len = Math.min(array1.length, array2.length),\n lengthDiff = Math.abs(array1.length - array2.length),\n diffs = 0,\n i;\n for (i = 0; i < len; i++) {\n if ((dontConvert && array1[i] !== array2[i]) ||\n (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n diffs++;\n }\n }\n return diffs + lengthDiff;\n }\n\n function Locale() {\n }\n\n var locales = {};\n var globalLocale;\n\n function normalizeLocale(key) {\n return key ? key.toLowerCase().replace('_', '-') : key;\n }\n\n // pick the locale from the array\n // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\n function chooseLocale(names) {\n var i = 0, j, next, locale, split;\n\n while (i < names.length) {\n split = normalizeLocale(names[i]).split('-');\n j = split.length;\n next = normalizeLocale(names[i + 1]);\n next = next ? next.split('-') : null;\n while (j > 0) {\n locale = loadLocale(split.slice(0, j).join('-'));\n if (locale) {\n return locale;\n }\n if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n //the next array item is better than a shallower substring of this one\n break;\n }\n j--;\n }\n i++;\n }\n return null;\n }\n\n function loadLocale(name) {\n var oldLocale = null;\n // TODO: Find a better way to register and load all the locales in Node\n if (!locales[name] && typeof module !== 'undefined' &&\n module && module.exports) {\n try {\n oldLocale = globalLocale._abbr;\n require('./locale/' + name);\n // because defineLocale currently also sets the global locale, we\n // want to undo that for lazy loaded locales\n locale_locales__getSetGlobalLocale(oldLocale);\n } catch (e) { }\n }\n return locales[name];\n }\n\n // This function will load locale and then set the global locale. If\n // no arguments are passed in, it will simply return the current global\n // locale key.\n function locale_locales__getSetGlobalLocale (key, values) {\n var data;\n if (key) {\n if (typeof values === 'undefined') {\n data = locale_locales__getLocale(key);\n }\n else {\n data = defineLocale(key, values);\n }\n\n if (data) {\n // moment.duration._locale = moment._locale = data;\n globalLocale = data;\n }\n }\n\n return globalLocale._abbr;\n }\n\n function defineLocale (name, values) {\n if (values !== null) {\n values.abbr = name;\n locales[name] = locales[name] || new Locale();\n locales[name].set(values);\n\n // backwards compat for now: also set the locale\n locale_locales__getSetGlobalLocale(name);\n\n return locales[name];\n } else {\n // useful for testing\n delete locales[name];\n return null;\n }\n }\n\n // returns locale data\n function locale_locales__getLocale (key) {\n var locale;\n\n if (key && key._locale && key._locale._abbr) {\n key = key._locale._abbr;\n }\n\n if (!key) {\n return globalLocale;\n }\n\n if (!isArray(key)) {\n //short-circuit everything else\n locale = loadLocale(key);\n if (locale) {\n return locale;\n }\n key = [key];\n }\n\n return chooseLocale(key);\n }\n\n var aliases = {};\n\n function addUnitAlias (unit, shorthand) {\n var lowerCase = unit.toLowerCase();\n aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n }\n\n function normalizeUnits(units) {\n return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n }\n\n function normalizeObjectUnits(inputObject) {\n var normalizedInput = {},\n normalizedProp,\n prop;\n\n for (prop in inputObject) {\n if (hasOwnProp(inputObject, prop)) {\n normalizedProp = normalizeUnits(prop);\n if (normalizedProp) {\n normalizedInput[normalizedProp] = inputObject[prop];\n }\n }\n }\n\n return normalizedInput;\n }\n\n function makeGetSet (unit, keepTime) {\n return function (value) {\n if (value != null) {\n get_set__set(this, unit, value);\n utils_hooks__hooks.updateOffset(this, keepTime);\n return this;\n } else {\n return get_set__get(this, unit);\n }\n };\n }\n\n function get_set__get (mom, unit) {\n return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();\n }\n\n function get_set__set (mom, unit, value) {\n return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n }\n\n // MOMENTS\n\n function getSet (units, value) {\n var unit;\n if (typeof units === 'object') {\n for (unit in units) {\n this.set(unit, units[unit]);\n }\n } else {\n units = normalizeUnits(units);\n if (typeof this[units] === 'function') {\n return this[units](value);\n }\n }\n return this;\n }\n\n function zeroFill(number, targetLength, forceSign) {\n var absNumber = '' + Math.abs(number),\n zerosToFill = targetLength - absNumber.length,\n sign = number >= 0;\n return (sign ? (forceSign ? '+' : '') : '-') +\n Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n }\n\n var formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\n var localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\n var formatFunctions = {};\n\n var formatTokenFunctions = {};\n\n // token: 'M'\n // padded: ['MM', 2]\n // ordinal: 'Mo'\n // callback: function () { this.month() + 1 }\n function addFormatToken (token, padded, ordinal, callback) {\n var func = callback;\n if (typeof callback === 'string') {\n func = function () {\n return this[callback]();\n };\n }\n if (token) {\n formatTokenFunctions[token] = func;\n }\n if (padded) {\n formatTokenFunctions[padded[0]] = function () {\n return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n };\n }\n if (ordinal) {\n formatTokenFunctions[ordinal] = function () {\n return this.localeData().ordinal(func.apply(this, arguments), token);\n };\n }\n }\n\n function removeFormattingTokens(input) {\n if (input.match(/\\[[\\s\\S]/)) {\n return input.replace(/^\\[|\\]$/g, '');\n }\n return input.replace(/\\\\/g, '');\n }\n\n function makeFormatFunction(format) {\n var array = format.match(formattingTokens), i, length;\n\n for (i = 0, length = array.length; i < length; i++) {\n if (formatTokenFunctions[array[i]]) {\n array[i] = formatTokenFunctions[array[i]];\n } else {\n array[i] = removeFormattingTokens(array[i]);\n }\n }\n\n return function (mom) {\n var output = '';\n for (i = 0; i < length; i++) {\n output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];\n }\n return output;\n };\n }\n\n // format date using native date object\n function formatMoment(m, format) {\n if (!m.isValid()) {\n return m.localeData().invalidDate();\n }\n\n format = expandFormat(format, m.localeData());\n formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n return formatFunctions[format](m);\n }\n\n function expandFormat(format, locale) {\n var i = 5;\n\n function replaceLongDateFormatTokens(input) {\n return locale.longDateFormat(input) || input;\n }\n\n localFormattingTokens.lastIndex = 0;\n while (i >= 0 && localFormattingTokens.test(format)) {\n format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n localFormattingTokens.lastIndex = 0;\n i -= 1;\n }\n\n return format;\n }\n\n var match1 = /\\d/; // 0 - 9\n var match2 = /\\d\\d/; // 00 - 99\n var match3 = /\\d{3}/; // 000 - 999\n var match4 = /\\d{4}/; // 0000 - 9999\n var match6 = /[+-]?\\d{6}/; // -999999 - 999999\n var match1to2 = /\\d\\d?/; // 0 - 99\n var match1to3 = /\\d{1,3}/; // 0 - 999\n var match1to4 = /\\d{1,4}/; // 0 - 9999\n var match1to6 = /[+-]?\\d{1,6}/; // -999999 - 999999\n\n var matchUnsigned = /\\d+/; // 0 - inf\n var matchSigned = /[+-]?\\d+/; // -inf - inf\n\n var matchOffset = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\n\n var matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n // any word (or two) characters or numbers including two/three word month in arabic.\n var matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\n var regexes = {};\n\n function isFunction (sth) {\n // https://github.com/moment/moment/issues/2325\n return typeof sth === 'function' &&\n Object.prototype.toString.call(sth) === '[object Function]';\n }\n\n\n function addRegexToken (token, regex, strictRegex) {\n regexes[token] = isFunction(regex) ? regex : function (isStrict) {\n return (isStrict && strictRegex) ? strictRegex : regex;\n };\n }\n\n function getParseRegexForToken (token, config) {\n if (!hasOwnProp(regexes, token)) {\n return new RegExp(unescapeFormat(token));\n }\n\n return regexes[token](config._strict, config._locale);\n }\n\n // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\n function unescapeFormat(s) {\n return s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n return p1 || p2 || p3 || p4;\n }).replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n }\n\n var tokens = {};\n\n function addParseToken (token, callback) {\n var i, func = callback;\n if (typeof token === 'string') {\n token = [token];\n }\n if (typeof callback === 'number') {\n func = function (input, array) {\n array[callback] = toInt(input);\n };\n }\n for (i = 0; i < token.length; i++) {\n tokens[token[i]] = func;\n }\n }\n\n function addWeekParseToken (token, callback) {\n addParseToken(token, function (input, array, config, token) {\n config._w = config._w || {};\n callback(input, config._w, config, token);\n });\n }\n\n function addTimeToArrayFromToken(token, input, config) {\n if (input != null && hasOwnProp(tokens, token)) {\n tokens[token](input, config._a, config, token);\n }\n }\n\n var YEAR = 0;\n var MONTH = 1;\n var DATE = 2;\n var HOUR = 3;\n var MINUTE = 4;\n var SECOND = 5;\n var MILLISECOND = 6;\n\n function daysInMonth(year, month) {\n return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n }\n\n // FORMATTING\n\n addFormatToken('M', ['MM', 2], 'Mo', function () {\n return this.month() + 1;\n });\n\n addFormatToken('MMM', 0, 0, function (format) {\n return this.localeData().monthsShort(this, format);\n });\n\n addFormatToken('MMMM', 0, 0, function (format) {\n return this.localeData().months(this, format);\n });\n\n // ALIASES\n\n addUnitAlias('month', 'M');\n\n // PARSING\n\n addRegexToken('M', match1to2);\n addRegexToken('MM', match1to2, match2);\n addRegexToken('MMM', matchWord);\n addRegexToken('MMMM', matchWord);\n\n addParseToken(['M', 'MM'], function (input, array) {\n array[MONTH] = toInt(input) - 1;\n });\n\n addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n var month = config._locale.monthsParse(input, token, config._strict);\n // if we didn't find a month name, mark the date as invalid.\n if (month != null) {\n array[MONTH] = month;\n } else {\n getParsingFlags(config).invalidMonth = input;\n }\n });\n\n // LOCALES\n\n var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\n function localeMonths (m) {\n return this._months[m.month()];\n }\n\n var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\n function localeMonthsShort (m) {\n return this._monthsShort[m.month()];\n }\n\n function localeMonthsParse (monthName, format, strict) {\n var i, mom, regex;\n\n if (!this._monthsParse) {\n this._monthsParse = [];\n this._longMonthsParse = [];\n this._shortMonthsParse = [];\n }\n\n for (i = 0; i < 12; i++) {\n // make the regex if we don't have it already\n mom = create_utc__createUTC([2000, i]);\n if (strict && !this._longMonthsParse[i]) {\n this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n }\n if (!strict && !this._monthsParse[i]) {\n regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n }\n // test the regex\n if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n return i;\n } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n return i;\n } else if (!strict && this._monthsParse[i].test(monthName)) {\n return i;\n }\n }\n }\n\n // MOMENTS\n\n function setMonth (mom, value) {\n var dayOfMonth;\n\n // TODO: Move this out of here!\n if (typeof value === 'string') {\n value = mom.localeData().monthsParse(value);\n // TODO: Another silent failure?\n if (typeof value !== 'number') {\n return mom;\n }\n }\n\n dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n return mom;\n }\n\n function getSetMonth (value) {\n if (value != null) {\n setMonth(this, value);\n utils_hooks__hooks.updateOffset(this, true);\n return this;\n } else {\n return get_set__get(this, 'Month');\n }\n }\n\n function getDaysInMonth () {\n return daysInMonth(this.year(), this.month());\n }\n\n function checkOverflow (m) {\n var overflow;\n var a = m._a;\n\n if (a && getParsingFlags(m).overflow === -2) {\n overflow =\n a[MONTH] < 0 || a[MONTH] > 11 ? MONTH :\n a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE :\n a[SECOND] < 0 || a[SECOND] > 59 ? SECOND :\n a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n -1;\n\n if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n overflow = DATE;\n }\n\n getParsingFlags(m).overflow = overflow;\n }\n\n return m;\n }\n\n function warn(msg) {\n if (utils_hooks__hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {\n console.warn('Deprecation warning: ' + msg);\n }\n }\n\n function deprecate(msg, fn) {\n var firstTime = true;\n\n return extend(function () {\n if (firstTime) {\n warn(msg + '\\n' + (new Error()).stack);\n firstTime = false;\n }\n return fn.apply(this, arguments);\n }, fn);\n }\n\n var deprecations = {};\n\n function deprecateSimple(name, msg) {\n if (!deprecations[name]) {\n warn(msg);\n deprecations[name] = true;\n }\n }\n\n utils_hooks__hooks.suppressDeprecationWarnings = false;\n\n var from_string__isoRegex = /^\\s*(?:[+-]\\d{6}|\\d{4})-(?:(\\d\\d-\\d\\d)|(W\\d\\d$)|(W\\d\\d-\\d)|(\\d\\d\\d))((T| )(\\d\\d(:\\d\\d(:\\d\\d(\\.\\d+)?)?)?)?([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\n var isoDates = [\n ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d{2}-\\d{2}/],\n ['YYYY-MM-DD', /\\d{4}-\\d{2}-\\d{2}/],\n ['GGGG-[W]WW-E', /\\d{4}-W\\d{2}-\\d/],\n ['GGGG-[W]WW', /\\d{4}-W\\d{2}/],\n ['YYYY-DDD', /\\d{4}-\\d{3}/]\n ];\n\n // iso time formats and regexes\n var isoTimes = [\n ['HH:mm:ss.SSSS', /(T| )\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n ['HH:mm:ss', /(T| )\\d\\d:\\d\\d:\\d\\d/],\n ['HH:mm', /(T| )\\d\\d:\\d\\d/],\n ['HH', /(T| )\\d\\d/]\n ];\n\n var aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n // date from iso format\n function configFromISO(config) {\n var i, l,\n string = config._i,\n match = from_string__isoRegex.exec(string);\n\n if (match) {\n getParsingFlags(config).iso = true;\n for (i = 0, l = isoDates.length; i < l; i++) {\n if (isoDates[i][1].exec(string)) {\n config._f = isoDates[i][0];\n break;\n }\n }\n for (i = 0, l = isoTimes.length; i < l; i++) {\n if (isoTimes[i][1].exec(string)) {\n // match[6] should be 'T' or space\n config._f += (match[6] || ' ') + isoTimes[i][0];\n break;\n }\n }\n if (string.match(matchOffset)) {\n config._f += 'Z';\n }\n configFromStringAndFormat(config);\n } else {\n config._isValid = false;\n }\n }\n\n // date from iso format or fallback\n function configFromString(config) {\n var matched = aspNetJsonRegex.exec(config._i);\n\n if (matched !== null) {\n config._d = new Date(+matched[1]);\n return;\n }\n\n configFromISO(config);\n if (config._isValid === false) {\n delete config._isValid;\n utils_hooks__hooks.createFromInputFallback(config);\n }\n }\n\n utils_hooks__hooks.createFromInputFallback = deprecate(\n 'moment construction falls back to js Date. This is ' +\n 'discouraged and will be removed in upcoming major ' +\n 'release. Please refer to ' +\n 'https://github.com/moment/moment/issues/1407 for more info.',\n function (config) {\n config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n }\n );\n\n function createDate (y, m, d, h, M, s, ms) {\n //can't just apply() to create a date:\n //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply\n var date = new Date(y, m, d, h, M, s, ms);\n\n //the date constructor doesn't accept years < 1970\n if (y < 1970) {\n date.setFullYear(y);\n }\n return date;\n }\n\n function createUTCDate (y) {\n var date = new Date(Date.UTC.apply(null, arguments));\n if (y < 1970) {\n date.setUTCFullYear(y);\n }\n return date;\n }\n\n addFormatToken(0, ['YY', 2], 0, function () {\n return this.year() % 100;\n });\n\n addFormatToken(0, ['YYYY', 4], 0, 'year');\n addFormatToken(0, ['YYYYY', 5], 0, 'year');\n addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n // ALIASES\n\n addUnitAlias('year', 'y');\n\n // PARSING\n\n addRegexToken('Y', matchSigned);\n addRegexToken('YY', match1to2, match2);\n addRegexToken('YYYY', match1to4, match4);\n addRegexToken('YYYYY', match1to6, match6);\n addRegexToken('YYYYYY', match1to6, match6);\n\n addParseToken(['YYYYY', 'YYYYYY'], YEAR);\n addParseToken('YYYY', function (input, array) {\n array[YEAR] = input.length === 2 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input);\n });\n addParseToken('YY', function (input, array) {\n array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);\n });\n\n // HELPERS\n\n function daysInYear(year) {\n return isLeapYear(year) ? 366 : 365;\n }\n\n function isLeapYear(year) {\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n }\n\n // HOOKS\n\n utils_hooks__hooks.parseTwoDigitYear = function (input) {\n return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n };\n\n // MOMENTS\n\n var getSetYear = makeGetSet('FullYear', false);\n\n function getIsLeapYear () {\n return isLeapYear(this.year());\n }\n\n addFormatToken('w', ['ww', 2], 'wo', 'week');\n addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n // ALIASES\n\n addUnitAlias('week', 'w');\n addUnitAlias('isoWeek', 'W');\n\n // PARSING\n\n addRegexToken('w', match1to2);\n addRegexToken('ww', match1to2, match2);\n addRegexToken('W', match1to2);\n addRegexToken('WW', match1to2, match2);\n\n addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n week[token.substr(0, 1)] = toInt(input);\n });\n\n // HELPERS\n\n // firstDayOfWeek 0 = sun, 6 = sat\n // the day of the week that starts the week\n // (usually sunday or monday)\n // firstDayOfWeekOfYear 0 = sun, 6 = sat\n // the first week is the week that contains the first\n // of this day of the week\n // (eg. ISO weeks use thursday (4))\n function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {\n var end = firstDayOfWeekOfYear - firstDayOfWeek,\n daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),\n adjustedMoment;\n\n\n if (daysToDayOfWeek > end) {\n daysToDayOfWeek -= 7;\n }\n\n if (daysToDayOfWeek < end - 7) {\n daysToDayOfWeek += 7;\n }\n\n adjustedMoment = local__createLocal(mom).add(daysToDayOfWeek, 'd');\n return {\n week: Math.ceil(adjustedMoment.dayOfYear() / 7),\n year: adjustedMoment.year()\n };\n }\n\n // LOCALES\n\n function localeWeek (mom) {\n return weekOfYear(mom, this._week.dow, this._week.doy).week;\n }\n\n var defaultLocaleWeek = {\n dow : 0, // Sunday is the first day of the week.\n doy : 6 // The week that contains Jan 1st is the first week of the year.\n };\n\n function localeFirstDayOfWeek () {\n return this._week.dow;\n }\n\n function localeFirstDayOfYear () {\n return this._week.doy;\n }\n\n // MOMENTS\n\n function getSetWeek (input) {\n var week = this.localeData().week(this);\n return input == null ? week : this.add((input - week) * 7, 'd');\n }\n\n function getSetISOWeek (input) {\n var week = weekOfYear(this, 1, 4).week;\n return input == null ? week : this.add((input - week) * 7, 'd');\n }\n\n addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n // ALIASES\n\n addUnitAlias('dayOfYear', 'DDD');\n\n // PARSING\n\n addRegexToken('DDD', match1to3);\n addRegexToken('DDDD', match3);\n addParseToken(['DDD', 'DDDD'], function (input, array, config) {\n config._dayOfYear = toInt(input);\n });\n\n // HELPERS\n\n //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\n function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {\n var week1Jan = 6 + firstDayOfWeek - firstDayOfWeekOfYear, janX = createUTCDate(year, 0, 1 + week1Jan), d = janX.getUTCDay(), dayOfYear;\n if (d < firstDayOfWeek) {\n d += 7;\n }\n\n weekday = weekday != null ? 1 * weekday : firstDayOfWeek;\n\n dayOfYear = 1 + week1Jan + 7 * (week - 1) - d + weekday;\n\n return {\n year: dayOfYear > 0 ? year : year - 1,\n dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear\n };\n }\n\n // MOMENTS\n\n function getSetDayOfYear (input) {\n var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n }\n\n // Pick the first defined of two or three arguments.\n function defaults(a, b, c) {\n if (a != null) {\n return a;\n }\n if (b != null) {\n return b;\n }\n return c;\n }\n\n function currentDateArray(config) {\n var now = new Date();\n if (config._useUTC) {\n return [now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()];\n }\n return [now.getFullYear(), now.getMonth(), now.getDate()];\n }\n\n // convert an array to a date.\n // the array should mirror the parameters below\n // note: all values past the year are optional and will default to the lowest possible value.\n // [year, month, day , hour, minute, second, millisecond]\n function configFromArray (config) {\n var i, date, input = [], currentDate, yearToUse;\n\n if (config._d) {\n return;\n }\n\n currentDate = currentDateArray(config);\n\n //compute day of the year from weeks and weekdays\n if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n dayOfYearFromWeekInfo(config);\n }\n\n //if the day of the year is set, figure out what it is\n if (config._dayOfYear) {\n yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n if (config._dayOfYear > daysInYear(yearToUse)) {\n getParsingFlags(config)._overflowDayOfYear = true;\n }\n\n date = createUTCDate(yearToUse, 0, config._dayOfYear);\n config._a[MONTH] = date.getUTCMonth();\n config._a[DATE] = date.getUTCDate();\n }\n\n // Default to current date.\n // * if no year, month, day of month are given, default to today\n // * if day of month is given, default month and year\n // * if month is given, default only year\n // * if year is given, don't default anything\n for (i = 0; i < 3 && config._a[i] == null; ++i) {\n config._a[i] = input[i] = currentDate[i];\n }\n\n // Zero out whatever was not defaulted, including time\n for (; i < 7; i++) {\n config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n }\n\n // Check for 24:00:00.000\n if (config._a[HOUR] === 24 &&\n config._a[MINUTE] === 0 &&\n config._a[SECOND] === 0 &&\n config._a[MILLISECOND] === 0) {\n config._nextDay = true;\n config._a[HOUR] = 0;\n }\n\n config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n // Apply timezone offset from input. The actual utcOffset can be changed\n // with parseZone.\n if (config._tzm != null) {\n config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n }\n\n if (config._nextDay) {\n config._a[HOUR] = 24;\n }\n }\n\n function dayOfYearFromWeekInfo(config) {\n var w, weekYear, week, weekday, dow, doy, temp;\n\n w = config._w;\n if (w.GG != null || w.W != null || w.E != null) {\n dow = 1;\n doy = 4;\n\n // TODO: We need to take the current isoWeekYear, but that depends on\n // how we interpret now (local, utc, fixed offset). So create\n // a now version of current config (take local/utc/offset flags, and\n // create now).\n weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year);\n week = defaults(w.W, 1);\n weekday = defaults(w.E, 1);\n } else {\n dow = config._locale._week.dow;\n doy = config._locale._week.doy;\n\n weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year);\n week = defaults(w.w, 1);\n\n if (w.d != null) {\n // weekday -- low day numbers are considered next week\n weekday = w.d;\n if (weekday < dow) {\n ++week;\n }\n } else if (w.e != null) {\n // local weekday -- counting starts from begining of week\n weekday = w.e + dow;\n } else {\n // default to begining of week\n weekday = dow;\n }\n }\n temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);\n\n config._a[YEAR] = temp.year;\n config._dayOfYear = temp.dayOfYear;\n }\n\n utils_hooks__hooks.ISO_8601 = function () {};\n\n // date from string and format string\n function configFromStringAndFormat(config) {\n // TODO: Move this to another part of the creation flow to prevent circular deps\n if (config._f === utils_hooks__hooks.ISO_8601) {\n configFromISO(config);\n return;\n }\n\n config._a = [];\n getParsingFlags(config).empty = true;\n\n // This array is used to make a Date, either with `new Date` or `Date.UTC`\n var string = '' + config._i,\n i, parsedInput, tokens, token, skipped,\n stringLength = string.length,\n totalParsedInputLength = 0;\n\n tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n for (i = 0; i < tokens.length; i++) {\n token = tokens[i];\n parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n if (parsedInput) {\n skipped = string.substr(0, string.indexOf(parsedInput));\n if (skipped.length > 0) {\n getParsingFlags(config).unusedInput.push(skipped);\n }\n string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n totalParsedInputLength += parsedInput.length;\n }\n // don't parse if it's not a known token\n if (formatTokenFunctions[token]) {\n if (parsedInput) {\n getParsingFlags(config).empty = false;\n }\n else {\n getParsingFlags(config).unusedTokens.push(token);\n }\n addTimeToArrayFromToken(token, parsedInput, config);\n }\n else if (config._strict && !parsedInput) {\n getParsingFlags(config).unusedTokens.push(token);\n }\n }\n\n // add remaining unparsed input length to the string\n getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n if (string.length > 0) {\n getParsingFlags(config).unusedInput.push(string);\n }\n\n // clear _12h flag if hour is <= 12\n if (getParsingFlags(config).bigHour === true &&\n config._a[HOUR] <= 12 &&\n config._a[HOUR] > 0) {\n getParsingFlags(config).bigHour = undefined;\n }\n // handle meridiem\n config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n configFromArray(config);\n checkOverflow(config);\n }\n\n\n function meridiemFixWrap (locale, hour, meridiem) {\n var isPm;\n\n if (meridiem == null) {\n // nothing to do\n return hour;\n }\n if (locale.meridiemHour != null) {\n return locale.meridiemHour(hour, meridiem);\n } else if (locale.isPM != null) {\n // Fallback\n isPm = locale.isPM(meridiem);\n if (isPm && hour < 12) {\n hour += 12;\n }\n if (!isPm && hour === 12) {\n hour = 0;\n }\n return hour;\n } else {\n // this is not supposed to happen\n return hour;\n }\n }\n\n function configFromStringAndArray(config) {\n var tempConfig,\n bestMoment,\n\n scoreToBeat,\n i,\n currentScore;\n\n if (config._f.length === 0) {\n getParsingFlags(config).invalidFormat = true;\n config._d = new Date(NaN);\n return;\n }\n\n for (i = 0; i < config._f.length; i++) {\n currentScore = 0;\n tempConfig = copyConfig({}, config);\n if (config._useUTC != null) {\n tempConfig._useUTC = config._useUTC;\n }\n tempConfig._f = config._f[i];\n configFromStringAndFormat(tempConfig);\n\n if (!valid__isValid(tempConfig)) {\n continue;\n }\n\n // if there is any input that was not parsed add a penalty for that format\n currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n //or tokens\n currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n getParsingFlags(tempConfig).score = currentScore;\n\n if (scoreToBeat == null || currentScore < scoreToBeat) {\n scoreToBeat = currentScore;\n bestMoment = tempConfig;\n }\n }\n\n extend(config, bestMoment || tempConfig);\n }\n\n function configFromObject(config) {\n if (config._d) {\n return;\n }\n\n var i = normalizeObjectUnits(config._i);\n config._a = [i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond];\n\n configFromArray(config);\n }\n\n function createFromConfig (config) {\n var res = new Moment(checkOverflow(prepareConfig(config)));\n if (res._nextDay) {\n // Adding is smart enough around DST\n res.add(1, 'd');\n res._nextDay = undefined;\n }\n\n return res;\n }\n\n function prepareConfig (config) {\n var input = config._i,\n format = config._f;\n\n config._locale = config._locale || locale_locales__getLocale(config._l);\n\n if (input === null || (format === undefined && input === '')) {\n return valid__createInvalid({nullInput: true});\n }\n\n if (typeof input === 'string') {\n config._i = input = config._locale.preparse(input);\n }\n\n if (isMoment(input)) {\n return new Moment(checkOverflow(input));\n } else if (isArray(format)) {\n configFromStringAndArray(config);\n } else if (format) {\n configFromStringAndFormat(config);\n } else if (isDate(input)) {\n config._d = input;\n } else {\n configFromInput(config);\n }\n\n return config;\n }\n\n function configFromInput(config) {\n var input = config._i;\n if (input === undefined) {\n config._d = new Date();\n } else if (isDate(input)) {\n config._d = new Date(+input);\n } else if (typeof input === 'string') {\n configFromString(config);\n } else if (isArray(input)) {\n config._a = map(input.slice(0), function (obj) {\n return parseInt(obj, 10);\n });\n configFromArray(config);\n } else if (typeof(input) === 'object') {\n configFromObject(config);\n } else if (typeof(input) === 'number') {\n // from milliseconds\n config._d = new Date(input);\n } else {\n utils_hooks__hooks.createFromInputFallback(config);\n }\n }\n\n function createLocalOrUTC (input, format, locale, strict, isUTC) {\n var c = {};\n\n if (typeof(locale) === 'boolean') {\n strict = locale;\n locale = undefined;\n }\n // object construction must be done this way.\n // https://github.com/moment/moment/issues/1423\n c._isAMomentObject = true;\n c._useUTC = c._isUTC = isUTC;\n c._l = locale;\n c._i = input;\n c._f = format;\n c._strict = strict;\n\n return createFromConfig(c);\n }\n\n function local__createLocal (input, format, locale, strict) {\n return createLocalOrUTC(input, format, locale, strict, false);\n }\n\n var prototypeMin = deprecate(\n 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',\n function () {\n var other = local__createLocal.apply(null, arguments);\n return other < this ? this : other;\n }\n );\n\n var prototypeMax = deprecate(\n 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',\n function () {\n var other = local__createLocal.apply(null, arguments);\n return other > this ? this : other;\n }\n );\n\n // Pick a moment m from moments so that m[fn](other) is true for all\n // other. This relies on the function fn to be transitive.\n //\n // moments should either be an array of moment objects or an array, whose\n // first element is an array of moment objects.\n function pickBy(fn, moments) {\n var res, i;\n if (moments.length === 1 && isArray(moments[0])) {\n moments = moments[0];\n }\n if (!moments.length) {\n return local__createLocal();\n }\n res = moments[0];\n for (i = 1; i < moments.length; ++i) {\n if (!moments[i].isValid() || moments[i][fn](res)) {\n res = moments[i];\n }\n }\n return res;\n }\n\n // TODO: Use [].sort instead?\n function min () {\n var args = [].slice.call(arguments, 0);\n\n return pickBy('isBefore', args);\n }\n\n function max () {\n var args = [].slice.call(arguments, 0);\n\n return pickBy('isAfter', args);\n }\n\n function Duration (duration) {\n var normalizedInput = normalizeObjectUnits(duration),\n years = normalizedInput.year || 0,\n quarters = normalizedInput.quarter || 0,\n months = normalizedInput.month || 0,\n weeks = normalizedInput.week || 0,\n days = normalizedInput.day || 0,\n hours = normalizedInput.hour || 0,\n minutes = normalizedInput.minute || 0,\n seconds = normalizedInput.second || 0,\n milliseconds = normalizedInput.millisecond || 0;\n\n // representation for dateAddRemove\n this._milliseconds = +milliseconds +\n seconds * 1e3 + // 1000\n minutes * 6e4 + // 1000 * 60\n hours * 36e5; // 1000 * 60 * 60\n // Because of dateAddRemove treats 24 hours as different from a\n // day when working around DST, we need to store them separately\n this._days = +days +\n weeks * 7;\n // It is impossible translate months into days without knowing\n // which months you are are talking about, so we have to store\n // it separately.\n this._months = +months +\n quarters * 3 +\n years * 12;\n\n this._data = {};\n\n this._locale = locale_locales__getLocale();\n\n this._bubble();\n }\n\n function isDuration (obj) {\n return obj instanceof Duration;\n }\n\n function offset (token, separator) {\n addFormatToken(token, 0, 0, function () {\n var offset = this.utcOffset();\n var sign = '+';\n if (offset < 0) {\n offset = -offset;\n sign = '-';\n }\n return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n });\n }\n\n offset('Z', ':');\n offset('ZZ', '');\n\n // PARSING\n\n addRegexToken('Z', matchOffset);\n addRegexToken('ZZ', matchOffset);\n addParseToken(['Z', 'ZZ'], function (input, array, config) {\n config._useUTC = true;\n config._tzm = offsetFromString(input);\n });\n\n // HELPERS\n\n // timezone chunker\n // '+10:00' > ['10', '00']\n // '-1530' > ['-15', '30']\n var chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\n function offsetFromString(string) {\n var matches = ((string || '').match(matchOffset) || []);\n var chunk = matches[matches.length - 1] || [];\n var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n return parts[0] === '+' ? minutes : -minutes;\n }\n\n // Return a moment from input, that is local/utc/zone equivalent to model.\n function cloneWithOffset(input, model) {\n var res, diff;\n if (model._isUTC) {\n res = model.clone();\n diff = (isMoment(input) || isDate(input) ? +input : +local__createLocal(input)) - (+res);\n // Use low-level api, because this fn is low-level api.\n res._d.setTime(+res._d + diff);\n utils_hooks__hooks.updateOffset(res, false);\n return res;\n } else {\n return local__createLocal(input).local();\n }\n }\n\n function getDateOffset (m) {\n // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n // https://github.com/moment/moment/pull/1871\n return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n }\n\n // HOOKS\n\n // This function will be called whenever a moment is mutated.\n // It is intended to keep the offset in sync with the timezone.\n utils_hooks__hooks.updateOffset = function () {};\n\n // MOMENTS\n\n // keepLocalTime = true means only change the timezone, without\n // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->\n // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n // +0200, so we adjust the time as needed, to be valid.\n //\n // Keeping the time actually adds/subtracts (one hour)\n // from the actual represented time. That is why we call updateOffset\n // a second time. In case it wants us to change the offset again\n // _changeInProgress == true case, then we have to adjust, because\n // there is no such time in the given timezone.\n function getSetOffset (input, keepLocalTime) {\n var offset = this._offset || 0,\n localAdjust;\n if (input != null) {\n if (typeof input === 'string') {\n input = offsetFromString(input);\n }\n if (Math.abs(input) < 16) {\n input = input * 60;\n }\n if (!this._isUTC && keepLocalTime) {\n localAdjust = getDateOffset(this);\n }\n this._offset = input;\n this._isUTC = true;\n if (localAdjust != null) {\n this.add(localAdjust, 'm');\n }\n if (offset !== input) {\n if (!keepLocalTime || this._changeInProgress) {\n add_subtract__addSubtract(this, create__createDuration(input - offset, 'm'), 1, false);\n } else if (!this._changeInProgress) {\n this._changeInProgress = true;\n utils_hooks__hooks.updateOffset(this, true);\n this._changeInProgress = null;\n }\n }\n return this;\n } else {\n return this._isUTC ? offset : getDateOffset(this);\n }\n }\n\n function getSetZone (input, keepLocalTime) {\n if (input != null) {\n if (typeof input !== 'string') {\n input = -input;\n }\n\n this.utcOffset(input, keepLocalTime);\n\n return this;\n } else {\n return -this.utcOffset();\n }\n }\n\n function setOffsetToUTC (keepLocalTime) {\n return this.utcOffset(0, keepLocalTime);\n }\n\n function setOffsetToLocal (keepLocalTime) {\n if (this._isUTC) {\n this.utcOffset(0, keepLocalTime);\n this._isUTC = false;\n\n if (keepLocalTime) {\n this.subtract(getDateOffset(this), 'm');\n }\n }\n return this;\n }\n\n function setOffsetToParsedOffset () {\n if (this._tzm) {\n this.utcOffset(this._tzm);\n } else if (typeof this._i === 'string') {\n this.utcOffset(offsetFromString(this._i));\n }\n return this;\n }\n\n function hasAlignedHourOffset (input) {\n input = input ? local__createLocal(input).utcOffset() : 0;\n\n return (this.utcOffset() - input) % 60 === 0;\n }\n\n function isDaylightSavingTime () {\n return (\n this.utcOffset() > this.clone().month(0).utcOffset() ||\n this.utcOffset() > this.clone().month(5).utcOffset()\n );\n }\n\n function isDaylightSavingTimeShifted () {\n if (typeof this._isDSTShifted !== 'undefined') {\n return this._isDSTShifted;\n }\n\n var c = {};\n\n copyConfig(c, this);\n c = prepareConfig(c);\n\n if (c._a) {\n var other = c._isUTC ? create_utc__createUTC(c._a) : local__createLocal(c._a);\n this._isDSTShifted = this.isValid() &&\n compareArrays(c._a, other.toArray()) > 0;\n } else {\n this._isDSTShifted = false;\n }\n\n return this._isDSTShifted;\n }\n\n function isLocal () {\n return !this._isUTC;\n }\n\n function isUtcOffset () {\n return this._isUTC;\n }\n\n function isUtc () {\n return this._isUTC && this._offset === 0;\n }\n\n var aspNetRegex = /(\\-)?(?:(\\d*)\\.)?(\\d+)\\:(\\d+)(?:\\:(\\d+)\\.?(\\d{3})?)?/;\n\n // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n var create__isoRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;\n\n function create__createDuration (input, key) {\n var duration = input,\n // matching against regexp is expensive, do it on demand\n match = null,\n sign,\n ret,\n diffRes;\n\n if (isDuration(input)) {\n duration = {\n ms : input._milliseconds,\n d : input._days,\n M : input._months\n };\n } else if (typeof input === 'number') {\n duration = {};\n if (key) {\n duration[key] = input;\n } else {\n duration.milliseconds = input;\n }\n } else if (!!(match = aspNetRegex.exec(input))) {\n sign = (match[1] === '-') ? -1 : 1;\n duration = {\n y : 0,\n d : toInt(match[DATE]) * sign,\n h : toInt(match[HOUR]) * sign,\n m : toInt(match[MINUTE]) * sign,\n s : toInt(match[SECOND]) * sign,\n ms : toInt(match[MILLISECOND]) * sign\n };\n } else if (!!(match = create__isoRegex.exec(input))) {\n sign = (match[1] === '-') ? -1 : 1;\n duration = {\n y : parseIso(match[2], sign),\n M : parseIso(match[3], sign),\n d : parseIso(match[4], sign),\n h : parseIso(match[5], sign),\n m : parseIso(match[6], sign),\n s : parseIso(match[7], sign),\n w : parseIso(match[8], sign)\n };\n } else if (duration == null) {// checks for null or undefined\n duration = {};\n } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to));\n\n duration = {};\n duration.ms = diffRes.milliseconds;\n duration.M = diffRes.months;\n }\n\n ret = new Duration(duration);\n\n if (isDuration(input) && hasOwnProp(input, '_locale')) {\n ret._locale = input._locale;\n }\n\n return ret;\n }\n\n create__createDuration.fn = Duration.prototype;\n\n function parseIso (inp, sign) {\n // We'd normally use ~~inp for this, but unfortunately it also\n // converts floats to ints.\n // inp may be undefined, so careful calling replace on it.\n var res = inp && parseFloat(inp.replace(',', '.'));\n // apply sign while we're at it\n return (isNaN(res) ? 0 : res) * sign;\n }\n\n function positiveMomentsDifference(base, other) {\n var res = {milliseconds: 0, months: 0};\n\n res.months = other.month() - base.month() +\n (other.year() - base.year()) * 12;\n if (base.clone().add(res.months, 'M').isAfter(other)) {\n --res.months;\n }\n\n res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n return res;\n }\n\n function momentsDifference(base, other) {\n var res;\n other = cloneWithOffset(other, base);\n if (base.isBefore(other)) {\n res = positiveMomentsDifference(base, other);\n } else {\n res = positiveMomentsDifference(other, base);\n res.milliseconds = -res.milliseconds;\n res.months = -res.months;\n }\n\n return res;\n }\n\n function createAdder(direction, name) {\n return function (val, period) {\n var dur, tmp;\n //invert the arguments, but complain about it\n if (period !== null && !isNaN(+period)) {\n deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');\n tmp = val; val = period; period = tmp;\n }\n\n val = typeof val === 'string' ? +val : val;\n dur = create__createDuration(val, period);\n add_subtract__addSubtract(this, dur, direction);\n return this;\n };\n }\n\n function add_subtract__addSubtract (mom, duration, isAdding, updateOffset) {\n var milliseconds = duration._milliseconds,\n days = duration._days,\n months = duration._months;\n updateOffset = updateOffset == null ? true : updateOffset;\n\n if (milliseconds) {\n mom._d.setTime(+mom._d + milliseconds * isAdding);\n }\n if (days) {\n get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding);\n }\n if (months) {\n setMonth(mom, get_set__get(mom, 'Month') + months * isAdding);\n }\n if (updateOffset) {\n utils_hooks__hooks.updateOffset(mom, days || months);\n }\n }\n\n var add_subtract__add = createAdder(1, 'add');\n var add_subtract__subtract = createAdder(-1, 'subtract');\n\n function moment_calendar__calendar (time, formats) {\n // We want to compare the start of today, vs this.\n // Getting start-of-today depends on whether we're local/utc/offset or not.\n var now = time || local__createLocal(),\n sod = cloneWithOffset(now, this).startOf('day'),\n diff = this.diff(sod, 'days', true),\n format = diff < -6 ? 'sameElse' :\n diff < -1 ? 'lastWeek' :\n diff < 0 ? 'lastDay' :\n diff < 1 ? 'sameDay' :\n diff < 2 ? 'nextDay' :\n diff < 7 ? 'nextWeek' : 'sameElse';\n return this.format(formats && formats[format] || this.localeData().calendar(format, this, local__createLocal(now)));\n }\n\n function clone () {\n return new Moment(this);\n }\n\n function isAfter (input, units) {\n var inputMs;\n units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n if (units === 'millisecond') {\n input = isMoment(input) ? input : local__createLocal(input);\n return +this > +input;\n } else {\n inputMs = isMoment(input) ? +input : +local__createLocal(input);\n return inputMs < +this.clone().startOf(units);\n }\n }\n\n function isBefore (input, units) {\n var inputMs;\n units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n if (units === 'millisecond') {\n input = isMoment(input) ? input : local__createLocal(input);\n return +this < +input;\n } else {\n inputMs = isMoment(input) ? +input : +local__createLocal(input);\n return +this.clone().endOf(units) < inputMs;\n }\n }\n\n function isBetween (from, to, units) {\n return this.isAfter(from, units) && this.isBefore(to, units);\n }\n\n function isSame (input, units) {\n var inputMs;\n units = normalizeUnits(units || 'millisecond');\n if (units === 'millisecond') {\n input = isMoment(input) ? input : local__createLocal(input);\n return +this === +input;\n } else {\n inputMs = +local__createLocal(input);\n return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));\n }\n }\n\n function diff (input, units, asFloat) {\n var that = cloneWithOffset(input, this),\n zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4,\n delta, output;\n\n units = normalizeUnits(units);\n\n if (units === 'year' || units === 'month' || units === 'quarter') {\n output = monthDiff(this, that);\n if (units === 'quarter') {\n output = output / 3;\n } else if (units === 'year') {\n output = output / 12;\n }\n } else {\n delta = this - that;\n output = units === 'second' ? delta / 1e3 : // 1000\n units === 'minute' ? delta / 6e4 : // 1000 * 60\n units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n delta;\n }\n return asFloat ? output : absFloor(output);\n }\n\n function monthDiff (a, b) {\n // difference in months\n var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n // b is in (anchor - 1 month, anchor + 1 month)\n anchor = a.clone().add(wholeMonthDiff, 'months'),\n anchor2, adjust;\n\n if (b - anchor < 0) {\n anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n // linear across the month\n adjust = (b - anchor) / (anchor - anchor2);\n } else {\n anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n // linear across the month\n adjust = (b - anchor) / (anchor2 - anchor);\n }\n\n return -(wholeMonthDiff + adjust);\n }\n\n utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\n\n function toString () {\n return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n }\n\n function moment_format__toISOString () {\n var m = this.clone().utc();\n if (0 < m.year() && m.year() <= 9999) {\n if ('function' === typeof Date.prototype.toISOString) {\n // native implementation is ~50x faster, use it when we can\n return this.toDate().toISOString();\n } else {\n return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n }\n } else {\n return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n }\n }\n\n function format (inputString) {\n var output = formatMoment(this, inputString || utils_hooks__hooks.defaultFormat);\n return this.localeData().postformat(output);\n }\n\n function from (time, withoutSuffix) {\n if (!this.isValid()) {\n return this.localeData().invalidDate();\n }\n return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n }\n\n function fromNow (withoutSuffix) {\n return this.from(local__createLocal(), withoutSuffix);\n }\n\n function to (time, withoutSuffix) {\n if (!this.isValid()) {\n return this.localeData().invalidDate();\n }\n return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n }\n\n function toNow (withoutSuffix) {\n return this.to(local__createLocal(), withoutSuffix);\n }\n\n function locale (key) {\n var newLocaleData;\n\n if (key === undefined) {\n return this._locale._abbr;\n } else {\n newLocaleData = locale_locales__getLocale(key);\n if (newLocaleData != null) {\n this._locale = newLocaleData;\n }\n return this;\n }\n }\n\n var lang = deprecate(\n 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n function (key) {\n if (key === undefined) {\n return this.localeData();\n } else {\n return this.locale(key);\n }\n }\n );\n\n function localeData () {\n return this._locale;\n }\n\n function startOf (units) {\n units = normalizeUnits(units);\n // the following switch intentionally omits break keywords\n // to utilize falling through the cases.\n switch (units) {\n case 'year':\n this.month(0);\n /* falls through */\n case 'quarter':\n case 'month':\n this.date(1);\n /* falls through */\n case 'week':\n case 'isoWeek':\n case 'day':\n this.hours(0);\n /* falls through */\n case 'hour':\n this.minutes(0);\n /* falls through */\n case 'minute':\n this.seconds(0);\n /* falls through */\n case 'second':\n this.milliseconds(0);\n }\n\n // weeks are a special case\n if (units === 'week') {\n this.weekday(0);\n }\n if (units === 'isoWeek') {\n this.isoWeekday(1);\n }\n\n // quarters are also special\n if (units === 'quarter') {\n this.month(Math.floor(this.month() / 3) * 3);\n }\n\n return this;\n }\n\n function endOf (units) {\n units = normalizeUnits(units);\n if (units === undefined || units === 'millisecond') {\n return this;\n }\n return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n }\n\n function to_type__valueOf () {\n return +this._d - ((this._offset || 0) * 60000);\n }\n\n function unix () {\n return Math.floor(+this / 1000);\n }\n\n function toDate () {\n return this._offset ? new Date(+this) : this._d;\n }\n\n function toArray () {\n var m = this;\n return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n }\n\n function toObject () {\n var m = this;\n return {\n years: m.year(),\n months: m.month(),\n date: m.date(),\n hours: m.hours(),\n minutes: m.minutes(),\n seconds: m.seconds(),\n milliseconds: m.milliseconds()\n };\n }\n\n function moment_valid__isValid () {\n return valid__isValid(this);\n }\n\n function parsingFlags () {\n return extend({}, getParsingFlags(this));\n }\n\n function invalidAt () {\n return getParsingFlags(this).overflow;\n }\n\n addFormatToken(0, ['gg', 2], 0, function () {\n return this.weekYear() % 100;\n });\n\n addFormatToken(0, ['GG', 2], 0, function () {\n return this.isoWeekYear() % 100;\n });\n\n function addWeekYearFormatToken (token, getter) {\n addFormatToken(0, [token, token.length], 0, getter);\n }\n\n addWeekYearFormatToken('gggg', 'weekYear');\n addWeekYearFormatToken('ggggg', 'weekYear');\n addWeekYearFormatToken('GGGG', 'isoWeekYear');\n addWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n // ALIASES\n\n addUnitAlias('weekYear', 'gg');\n addUnitAlias('isoWeekYear', 'GG');\n\n // PARSING\n\n addRegexToken('G', matchSigned);\n addRegexToken('g', matchSigned);\n addRegexToken('GG', match1to2, match2);\n addRegexToken('gg', match1to2, match2);\n addRegexToken('GGGG', match1to4, match4);\n addRegexToken('gggg', match1to4, match4);\n addRegexToken('GGGGG', match1to6, match6);\n addRegexToken('ggggg', match1to6, match6);\n\n addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n week[token.substr(0, 2)] = toInt(input);\n });\n\n addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n week[token] = utils_hooks__hooks.parseTwoDigitYear(input);\n });\n\n // HELPERS\n\n function weeksInYear(year, dow, doy) {\n return weekOfYear(local__createLocal([year, 11, 31 + dow - doy]), dow, doy).week;\n }\n\n // MOMENTS\n\n function getSetWeekYear (input) {\n var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;\n return input == null ? year : this.add((input - year), 'y');\n }\n\n function getSetISOWeekYear (input) {\n var year = weekOfYear(this, 1, 4).year;\n return input == null ? year : this.add((input - year), 'y');\n }\n\n function getISOWeeksInYear () {\n return weeksInYear(this.year(), 1, 4);\n }\n\n function getWeeksInYear () {\n var weekInfo = this.localeData()._week;\n return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n }\n\n addFormatToken('Q', 0, 0, 'quarter');\n\n // ALIASES\n\n addUnitAlias('quarter', 'Q');\n\n // PARSING\n\n addRegexToken('Q', match1);\n addParseToken('Q', function (input, array) {\n array[MONTH] = (toInt(input) - 1) * 3;\n });\n\n // MOMENTS\n\n function getSetQuarter (input) {\n return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n }\n\n addFormatToken('D', ['DD', 2], 'Do', 'date');\n\n // ALIASES\n\n addUnitAlias('date', 'D');\n\n // PARSING\n\n addRegexToken('D', match1to2);\n addRegexToken('DD', match1to2, match2);\n addRegexToken('Do', function (isStrict, locale) {\n return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;\n });\n\n addParseToken(['D', 'DD'], DATE);\n addParseToken('Do', function (input, array) {\n array[DATE] = toInt(input.match(match1to2)[0], 10);\n });\n\n // MOMENTS\n\n var getSetDayOfMonth = makeGetSet('Date', true);\n\n addFormatToken('d', 0, 'do', 'day');\n\n addFormatToken('dd', 0, 0, function (format) {\n return this.localeData().weekdaysMin(this, format);\n });\n\n addFormatToken('ddd', 0, 0, function (format) {\n return this.localeData().weekdaysShort(this, format);\n });\n\n addFormatToken('dddd', 0, 0, function (format) {\n return this.localeData().weekdays(this, format);\n });\n\n addFormatToken('e', 0, 0, 'weekday');\n addFormatToken('E', 0, 0, 'isoWeekday');\n\n // ALIASES\n\n addUnitAlias('day', 'd');\n addUnitAlias('weekday', 'e');\n addUnitAlias('isoWeekday', 'E');\n\n // PARSING\n\n addRegexToken('d', match1to2);\n addRegexToken('e', match1to2);\n addRegexToken('E', match1to2);\n addRegexToken('dd', matchWord);\n addRegexToken('ddd', matchWord);\n addRegexToken('dddd', matchWord);\n\n addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config) {\n var weekday = config._locale.weekdaysParse(input);\n // if we didn't get a weekday name, mark the date as invalid\n if (weekday != null) {\n week.d = weekday;\n } else {\n getParsingFlags(config).invalidWeekday = input;\n }\n });\n\n addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n week[token] = toInt(input);\n });\n\n // HELPERS\n\n function parseWeekday(input, locale) {\n if (typeof input !== 'string') {\n return input;\n }\n\n if (!isNaN(input)) {\n return parseInt(input, 10);\n }\n\n input = locale.weekdaysParse(input);\n if (typeof input === 'number') {\n return input;\n }\n\n return null;\n }\n\n // LOCALES\n\n var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\n function localeWeekdays (m) {\n return this._weekdays[m.day()];\n }\n\n var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\n function localeWeekdaysShort (m) {\n return this._weekdaysShort[m.day()];\n }\n\n var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\n function localeWeekdaysMin (m) {\n return this._weekdaysMin[m.day()];\n }\n\n function localeWeekdaysParse (weekdayName) {\n var i, mom, regex;\n\n this._weekdaysParse = this._weekdaysParse || [];\n\n for (i = 0; i < 7; i++) {\n // make the regex if we don't have it already\n if (!this._weekdaysParse[i]) {\n mom = local__createLocal([2000, 1]).day(i);\n regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n }\n // test the regex\n if (this._weekdaysParse[i].test(weekdayName)) {\n return i;\n }\n }\n }\n\n // MOMENTS\n\n function getSetDayOfWeek (input) {\n var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n if (input != null) {\n input = parseWeekday(input, this.localeData());\n return this.add(input - day, 'd');\n } else {\n return day;\n }\n }\n\n function getSetLocaleDayOfWeek (input) {\n var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n return input == null ? weekday : this.add(input - weekday, 'd');\n }\n\n function getSetISODayOfWeek (input) {\n // behaves the same as moment#day except\n // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n // as a setter, sunday should belong to the previous week.\n return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);\n }\n\n addFormatToken('H', ['HH', 2], 0, 'hour');\n addFormatToken('h', ['hh', 2], 0, function () {\n return this.hours() % 12 || 12;\n });\n\n function meridiem (token, lowercase) {\n addFormatToken(token, 0, 0, function () {\n return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n });\n }\n\n meridiem('a', true);\n meridiem('A', false);\n\n // ALIASES\n\n addUnitAlias('hour', 'h');\n\n // PARSING\n\n function matchMeridiem (isStrict, locale) {\n return locale._meridiemParse;\n }\n\n addRegexToken('a', matchMeridiem);\n addRegexToken('A', matchMeridiem);\n addRegexToken('H', match1to2);\n addRegexToken('h', match1to2);\n addRegexToken('HH', match1to2, match2);\n addRegexToken('hh', match1to2, match2);\n\n addParseToken(['H', 'HH'], HOUR);\n addParseToken(['a', 'A'], function (input, array, config) {\n config._isPm = config._locale.isPM(input);\n config._meridiem = input;\n });\n addParseToken(['h', 'hh'], function (input, array, config) {\n array[HOUR] = toInt(input);\n getParsingFlags(config).bigHour = true;\n });\n\n // LOCALES\n\n function localeIsPM (input) {\n // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n // Using charAt should be more compatible.\n return ((input + '').toLowerCase().charAt(0) === 'p');\n }\n\n var defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\n function localeMeridiem (hours, minutes, isLower) {\n if (hours > 11) {\n return isLower ? 'pm' : 'PM';\n } else {\n return isLower ? 'am' : 'AM';\n }\n }\n\n\n // MOMENTS\n\n // Setting the hour should keep the time, because the user explicitly\n // specified which hour he wants. So trying to maintain the same hour (in\n // a new timezone) makes sense. Adding/subtracting hours does not follow\n // this rule.\n var getSetHour = makeGetSet('Hours', true);\n\n addFormatToken('m', ['mm', 2], 0, 'minute');\n\n // ALIASES\n\n addUnitAlias('minute', 'm');\n\n // PARSING\n\n addRegexToken('m', match1to2);\n addRegexToken('mm', match1to2, match2);\n addParseToken(['m', 'mm'], MINUTE);\n\n // MOMENTS\n\n var getSetMinute = makeGetSet('Minutes', false);\n\n addFormatToken('s', ['ss', 2], 0, 'second');\n\n // ALIASES\n\n addUnitAlias('second', 's');\n\n // PARSING\n\n addRegexToken('s', match1to2);\n addRegexToken('ss', match1to2, match2);\n addParseToken(['s', 'ss'], SECOND);\n\n // MOMENTS\n\n var getSetSecond = makeGetSet('Seconds', false);\n\n addFormatToken('S', 0, 0, function () {\n return ~~(this.millisecond() / 100);\n });\n\n addFormatToken(0, ['SS', 2], 0, function () {\n return ~~(this.millisecond() / 10);\n });\n\n addFormatToken(0, ['SSS', 3], 0, 'millisecond');\n addFormatToken(0, ['SSSS', 4], 0, function () {\n return this.millisecond() * 10;\n });\n addFormatToken(0, ['SSSSS', 5], 0, function () {\n return this.millisecond() * 100;\n });\n addFormatToken(0, ['SSSSSS', 6], 0, function () {\n return this.millisecond() * 1000;\n });\n addFormatToken(0, ['SSSSSSS', 7], 0, function () {\n return this.millisecond() * 10000;\n });\n addFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n return this.millisecond() * 100000;\n });\n addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n return this.millisecond() * 1000000;\n });\n\n\n // ALIASES\n\n addUnitAlias('millisecond', 'ms');\n\n // PARSING\n\n addRegexToken('S', match1to3, match1);\n addRegexToken('SS', match1to3, match2);\n addRegexToken('SSS', match1to3, match3);\n\n var token;\n for (token = 'SSSS'; token.length <= 9; token += 'S') {\n addRegexToken(token, matchUnsigned);\n }\n\n function parseMs(input, array) {\n array[MILLISECOND] = toInt(('0.' + input) * 1000);\n }\n\n for (token = 'S'; token.length <= 9; token += 'S') {\n addParseToken(token, parseMs);\n }\n // MOMENTS\n\n var getSetMillisecond = makeGetSet('Milliseconds', false);\n\n addFormatToken('z', 0, 0, 'zoneAbbr');\n addFormatToken('zz', 0, 0, 'zoneName');\n\n // MOMENTS\n\n function getZoneAbbr () {\n return this._isUTC ? 'UTC' : '';\n }\n\n function getZoneName () {\n return this._isUTC ? 'Coordinated Universal Time' : '';\n }\n\n var momentPrototype__proto = Moment.prototype;\n\n momentPrototype__proto.add = add_subtract__add;\n momentPrototype__proto.calendar = moment_calendar__calendar;\n momentPrototype__proto.clone = clone;\n momentPrototype__proto.diff = diff;\n momentPrototype__proto.endOf = endOf;\n momentPrototype__proto.format = format;\n momentPrototype__proto.from = from;\n momentPrototype__proto.fromNow = fromNow;\n momentPrototype__proto.to = to;\n momentPrototype__proto.toNow = toNow;\n momentPrototype__proto.get = getSet;\n momentPrototype__proto.invalidAt = invalidAt;\n momentPrototype__proto.isAfter = isAfter;\n momentPrototype__proto.isBefore = isBefore;\n momentPrototype__proto.isBetween = isBetween;\n momentPrototype__proto.isSame = isSame;\n momentPrototype__proto.isValid = moment_valid__isValid;\n momentPrototype__proto.lang = lang;\n momentPrototype__proto.locale = locale;\n momentPrototype__proto.localeData = localeData;\n momentPrototype__proto.max = prototypeMax;\n momentPrototype__proto.min = prototypeMin;\n momentPrototype__proto.parsingFlags = parsingFlags;\n momentPrototype__proto.set = getSet;\n momentPrototype__proto.startOf = startOf;\n momentPrototype__proto.subtract = add_subtract__subtract;\n momentPrototype__proto.toArray = toArray;\n momentPrototype__proto.toObject = toObject;\n momentPrototype__proto.toDate = toDate;\n momentPrototype__proto.toISOString = moment_format__toISOString;\n momentPrototype__proto.toJSON = moment_format__toISOString;\n momentPrototype__proto.toString = toString;\n momentPrototype__proto.unix = unix;\n momentPrototype__proto.valueOf = to_type__valueOf;\n\n // Year\n momentPrototype__proto.year = getSetYear;\n momentPrototype__proto.isLeapYear = getIsLeapYear;\n\n // Week Year\n momentPrototype__proto.weekYear = getSetWeekYear;\n momentPrototype__proto.isoWeekYear = getSetISOWeekYear;\n\n // Quarter\n momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter;\n\n // Month\n momentPrototype__proto.month = getSetMonth;\n momentPrototype__proto.daysInMonth = getDaysInMonth;\n\n // Week\n momentPrototype__proto.week = momentPrototype__proto.weeks = getSetWeek;\n momentPrototype__proto.isoWeek = momentPrototype__proto.isoWeeks = getSetISOWeek;\n momentPrototype__proto.weeksInYear = getWeeksInYear;\n momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear;\n\n // Day\n momentPrototype__proto.date = getSetDayOfMonth;\n momentPrototype__proto.day = momentPrototype__proto.days = getSetDayOfWeek;\n momentPrototype__proto.weekday = getSetLocaleDayOfWeek;\n momentPrototype__proto.isoWeekday = getSetISODayOfWeek;\n momentPrototype__proto.dayOfYear = getSetDayOfYear;\n\n // Hour\n momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour;\n\n // Minute\n momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute;\n\n // Second\n momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond;\n\n // Millisecond\n momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond;\n\n // Offset\n momentPrototype__proto.utcOffset = getSetOffset;\n momentPrototype__proto.utc = setOffsetToUTC;\n momentPrototype__proto.local = setOffsetToLocal;\n momentPrototype__proto.parseZone = setOffsetToParsedOffset;\n momentPrototype__proto.hasAlignedHourOffset = hasAlignedHourOffset;\n momentPrototype__proto.isDST = isDaylightSavingTime;\n momentPrototype__proto.isDSTShifted = isDaylightSavingTimeShifted;\n momentPrototype__proto.isLocal = isLocal;\n momentPrototype__proto.isUtcOffset = isUtcOffset;\n momentPrototype__proto.isUtc = isUtc;\n momentPrototype__proto.isUTC = isUtc;\n\n // Timezone\n momentPrototype__proto.zoneAbbr = getZoneAbbr;\n momentPrototype__proto.zoneName = getZoneName;\n\n // Deprecations\n momentPrototype__proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\n momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\n momentPrototype__proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);\n momentPrototype__proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779', getSetZone);\n\n var momentPrototype = momentPrototype__proto;\n\n function moment__createUnix (input) {\n return local__createLocal(input * 1000);\n }\n\n function moment__createInZone () {\n return local__createLocal.apply(null, arguments).parseZone();\n }\n\n var defaultCalendar = {\n sameDay : '[Today at] LT',\n nextDay : '[Tomorrow at] LT',\n nextWeek : 'dddd [at] LT',\n lastDay : '[Yesterday at] LT',\n lastWeek : '[Last] dddd [at] LT',\n sameElse : 'L'\n };\n\n function locale_calendar__calendar (key, mom, now) {\n var output = this._calendar[key];\n return typeof output === 'function' ? output.call(mom, now) : output;\n }\n\n var defaultLongDateFormat = {\n LTS : 'h:mm:ss A',\n LT : 'h:mm A',\n L : 'MM/DD/YYYY',\n LL : 'MMMM D, YYYY',\n LLL : 'MMMM D, YYYY h:mm A',\n LLLL : 'dddd, MMMM D, YYYY h:mm A'\n };\n\n function longDateFormat (key) {\n var format = this._longDateFormat[key],\n formatUpper = this._longDateFormat[key.toUpperCase()];\n\n if (format || !formatUpper) {\n return format;\n }\n\n this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n return val.slice(1);\n });\n\n return this._longDateFormat[key];\n }\n\n var defaultInvalidDate = 'Invalid date';\n\n function invalidDate () {\n return this._invalidDate;\n }\n\n var defaultOrdinal = '%d';\n var defaultOrdinalParse = /\\d{1,2}/;\n\n function ordinal (number) {\n return this._ordinal.replace('%d', number);\n }\n\n function preParsePostFormat (string) {\n return string;\n }\n\n var defaultRelativeTime = {\n future : 'in %s',\n past : '%s ago',\n s : 'a few seconds',\n m : 'a minute',\n mm : '%d minutes',\n h : 'an hour',\n hh : '%d hours',\n d : 'a day',\n dd : '%d days',\n M : 'a month',\n MM : '%d months',\n y : 'a year',\n yy : '%d years'\n };\n\n function relative__relativeTime (number, withoutSuffix, string, isFuture) {\n var output = this._relativeTime[string];\n return (typeof output === 'function') ?\n output(number, withoutSuffix, string, isFuture) :\n output.replace(/%d/i, number);\n }\n\n function pastFuture (diff, output) {\n var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);\n }\n\n function locale_set__set (config) {\n var prop, i;\n for (i in config) {\n prop = config[i];\n if (typeof prop === 'function') {\n this[i] = prop;\n } else {\n this['_' + i] = prop;\n }\n }\n // Lenient ordinal parsing accepts just a number in addition to\n // number + (possibly) stuff coming from _ordinalParseLenient.\n this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\\d{1,2}/).source);\n }\n\n var prototype__proto = Locale.prototype;\n\n prototype__proto._calendar = defaultCalendar;\n prototype__proto.calendar = locale_calendar__calendar;\n prototype__proto._longDateFormat = defaultLongDateFormat;\n prototype__proto.longDateFormat = longDateFormat;\n prototype__proto._invalidDate = defaultInvalidDate;\n prototype__proto.invalidDate = invalidDate;\n prototype__proto._ordinal = defaultOrdinal;\n prototype__proto.ordinal = ordinal;\n prototype__proto._ordinalParse = defaultOrdinalParse;\n prototype__proto.preparse = preParsePostFormat;\n prototype__proto.postformat = preParsePostFormat;\n prototype__proto._relativeTime = defaultRelativeTime;\n prototype__proto.relativeTime = relative__relativeTime;\n prototype__proto.pastFuture = pastFuture;\n prototype__proto.set = locale_set__set;\n\n // Month\n prototype__proto.months = localeMonths;\n prototype__proto._months = defaultLocaleMonths;\n prototype__proto.monthsShort = localeMonthsShort;\n prototype__proto._monthsShort = defaultLocaleMonthsShort;\n prototype__proto.monthsParse = localeMonthsParse;\n\n // Week\n prototype__proto.week = localeWeek;\n prototype__proto._week = defaultLocaleWeek;\n prototype__proto.firstDayOfYear = localeFirstDayOfYear;\n prototype__proto.firstDayOfWeek = localeFirstDayOfWeek;\n\n // Day of Week\n prototype__proto.weekdays = localeWeekdays;\n prototype__proto._weekdays = defaultLocaleWeekdays;\n prototype__proto.weekdaysMin = localeWeekdaysMin;\n prototype__proto._weekdaysMin = defaultLocaleWeekdaysMin;\n prototype__proto.weekdaysShort = localeWeekdaysShort;\n prototype__proto._weekdaysShort = defaultLocaleWeekdaysShort;\n prototype__proto.weekdaysParse = localeWeekdaysParse;\n\n // Hours\n prototype__proto.isPM = localeIsPM;\n prototype__proto._meridiemParse = defaultLocaleMeridiemParse;\n prototype__proto.meridiem = localeMeridiem;\n\n function lists__get (format, index, field, setter) {\n var locale = locale_locales__getLocale();\n var utc = create_utc__createUTC().set(setter, index);\n return locale[field](utc, format);\n }\n\n function list (format, index, field, count, setter) {\n if (typeof format === 'number') {\n index = format;\n format = undefined;\n }\n\n format = format || '';\n\n if (index != null) {\n return lists__get(format, index, field, setter);\n }\n\n var i;\n var out = [];\n for (i = 0; i < count; i++) {\n out[i] = lists__get(format, i, field, setter);\n }\n return out;\n }\n\n function lists__listMonths (format, index) {\n return list(format, index, 'months', 12, 'month');\n }\n\n function lists__listMonthsShort (format, index) {\n return list(format, index, 'monthsShort', 12, 'month');\n }\n\n function lists__listWeekdays (format, index) {\n return list(format, index, 'weekdays', 7, 'day');\n }\n\n function lists__listWeekdaysShort (format, index) {\n return list(format, index, 'weekdaysShort', 7, 'day');\n }\n\n function lists__listWeekdaysMin (format, index) {\n return list(format, index, 'weekdaysMin', 7, 'day');\n }\n\n locale_locales__getSetGlobalLocale('en', {\n ordinalParse: /\\d{1,2}(th|st|nd|rd)/,\n ordinal : function (number) {\n var b = number % 10,\n output = (toInt(number % 100 / 10) === 1) ? 'th' :\n (b === 1) ? 'st' :\n (b === 2) ? 'nd' :\n (b === 3) ? 'rd' : 'th';\n return number + output;\n }\n });\n\n // Side effect imports\n utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale);\n utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale);\n\n var mathAbs = Math.abs;\n\n function duration_abs__abs () {\n var data = this._data;\n\n this._milliseconds = mathAbs(this._milliseconds);\n this._days = mathAbs(this._days);\n this._months = mathAbs(this._months);\n\n data.milliseconds = mathAbs(data.milliseconds);\n data.seconds = mathAbs(data.seconds);\n data.minutes = mathAbs(data.minutes);\n data.hours = mathAbs(data.hours);\n data.months = mathAbs(data.months);\n data.years = mathAbs(data.years);\n\n return this;\n }\n\n function duration_add_subtract__addSubtract (duration, input, value, direction) {\n var other = create__createDuration(input, value);\n\n duration._milliseconds += direction * other._milliseconds;\n duration._days += direction * other._days;\n duration._months += direction * other._months;\n\n return duration._bubble();\n }\n\n // supports only 2.0-style add(1, 's') or add(duration)\n function duration_add_subtract__add (input, value) {\n return duration_add_subtract__addSubtract(this, input, value, 1);\n }\n\n // supports only 2.0-style subtract(1, 's') or subtract(duration)\n function duration_add_subtract__subtract (input, value) {\n return duration_add_subtract__addSubtract(this, input, value, -1);\n }\n\n function absCeil (number) {\n if (number < 0) {\n return Math.floor(number);\n } else {\n return Math.ceil(number);\n }\n }\n\n function bubble () {\n var milliseconds = this._milliseconds;\n var days = this._days;\n var months = this._months;\n var data = this._data;\n var seconds, minutes, hours, years, monthsFromDays;\n\n // if we have a mix of positive and negative values, bubble down first\n // check: https://github.com/moment/moment/issues/2166\n if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n (milliseconds <= 0 && days <= 0 && months <= 0))) {\n milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n days = 0;\n months = 0;\n }\n\n // The following code bubbles up values, see the tests for\n // examples of what that means.\n data.milliseconds = milliseconds % 1000;\n\n seconds = absFloor(milliseconds / 1000);\n data.seconds = seconds % 60;\n\n minutes = absFloor(seconds / 60);\n data.minutes = minutes % 60;\n\n hours = absFloor(minutes / 60);\n data.hours = hours % 24;\n\n days += absFloor(hours / 24);\n\n // convert days to months\n monthsFromDays = absFloor(daysToMonths(days));\n months += monthsFromDays;\n days -= absCeil(monthsToDays(monthsFromDays));\n\n // 12 months -> 1 year\n years = absFloor(months / 12);\n months %= 12;\n\n data.days = days;\n data.months = months;\n data.years = years;\n\n return this;\n }\n\n function daysToMonths (days) {\n // 400 years have 146097 days (taking into account leap year rules)\n // 400 years have 12 months === 4800\n return days * 4800 / 146097;\n }\n\n function monthsToDays (months) {\n // the reverse of daysToMonths\n return months * 146097 / 4800;\n }\n\n function as (units) {\n var days;\n var months;\n var milliseconds = this._milliseconds;\n\n units = normalizeUnits(units);\n\n if (units === 'month' || units === 'year') {\n days = this._days + milliseconds / 864e5;\n months = this._months + daysToMonths(days);\n return units === 'month' ? months : months / 12;\n } else {\n // handle milliseconds separately because of floating point math errors (issue #1867)\n days = this._days + Math.round(monthsToDays(this._months));\n switch (units) {\n case 'week' : return days / 7 + milliseconds / 6048e5;\n case 'day' : return days + milliseconds / 864e5;\n case 'hour' : return days * 24 + milliseconds / 36e5;\n case 'minute' : return days * 1440 + milliseconds / 6e4;\n case 'second' : return days * 86400 + milliseconds / 1000;\n // Math.floor prevents floating point math errors here\n case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n default: throw new Error('Unknown unit ' + units);\n }\n }\n }\n\n // TODO: Use this.as('ms')?\n function duration_as__valueOf () {\n return (\n this._milliseconds +\n this._days * 864e5 +\n (this._months % 12) * 2592e6 +\n toInt(this._months / 12) * 31536e6\n );\n }\n\n function makeAs (alias) {\n return function () {\n return this.as(alias);\n };\n }\n\n var asMilliseconds = makeAs('ms');\n var asSeconds = makeAs('s');\n var asMinutes = makeAs('m');\n var asHours = makeAs('h');\n var asDays = makeAs('d');\n var asWeeks = makeAs('w');\n var asMonths = makeAs('M');\n var asYears = makeAs('y');\n\n function duration_get__get (units) {\n units = normalizeUnits(units);\n return this[units + 's']();\n }\n\n function makeGetter(name) {\n return function () {\n return this._data[name];\n };\n }\n\n var milliseconds = makeGetter('milliseconds');\n var seconds = makeGetter('seconds');\n var minutes = makeGetter('minutes');\n var hours = makeGetter('hours');\n var days = makeGetter('days');\n var months = makeGetter('months');\n var years = makeGetter('years');\n\n function weeks () {\n return absFloor(this.days() / 7);\n }\n\n var round = Math.round;\n var thresholds = {\n s: 45, // seconds to minute\n m: 45, // minutes to hour\n h: 22, // hours to day\n d: 26, // days to month\n M: 11 // months to year\n };\n\n // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\n function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n }\n\n function duration_humanize__relativeTime (posNegDuration, withoutSuffix, locale) {\n var duration = create__createDuration(posNegDuration).abs();\n var seconds = round(duration.as('s'));\n var minutes = round(duration.as('m'));\n var hours = round(duration.as('h'));\n var days = round(duration.as('d'));\n var months = round(duration.as('M'));\n var years = round(duration.as('y'));\n\n var a = seconds < thresholds.s && ['s', seconds] ||\n minutes === 1 && ['m'] ||\n minutes < thresholds.m && ['mm', minutes] ||\n hours === 1 && ['h'] ||\n hours < thresholds.h && ['hh', hours] ||\n days === 1 && ['d'] ||\n days < thresholds.d && ['dd', days] ||\n months === 1 && ['M'] ||\n months < thresholds.M && ['MM', months] ||\n years === 1 && ['y'] || ['yy', years];\n\n a[2] = withoutSuffix;\n a[3] = +posNegDuration > 0;\n a[4] = locale;\n return substituteTimeAgo.apply(null, a);\n }\n\n // This function allows you to set a threshold for relative time strings\n function duration_humanize__getSetRelativeTimeThreshold (threshold, limit) {\n if (thresholds[threshold] === undefined) {\n return false;\n }\n if (limit === undefined) {\n return thresholds[threshold];\n }\n thresholds[threshold] = limit;\n return true;\n }\n\n function humanize (withSuffix) {\n var locale = this.localeData();\n var output = duration_humanize__relativeTime(this, !withSuffix, locale);\n\n if (withSuffix) {\n output = locale.pastFuture(+this, output);\n }\n\n return locale.postformat(output);\n }\n\n var iso_string__abs = Math.abs;\n\n function iso_string__toISOString() {\n // for ISO strings we do not use the normal bubbling rules:\n // * milliseconds bubble up until they become hours\n // * days do not bubble at all\n // * months bubble up until they become years\n // This is because there is no context-free conversion between hours and days\n // (think of clock changes)\n // and also not between days and months (28-31 days per month)\n var seconds = iso_string__abs(this._milliseconds) / 1000;\n var days = iso_string__abs(this._days);\n var months = iso_string__abs(this._months);\n var minutes, hours, years;\n\n // 3600 seconds -> 60 minutes -> 1 hour\n minutes = absFloor(seconds / 60);\n hours = absFloor(minutes / 60);\n seconds %= 60;\n minutes %= 60;\n\n // 12 months -> 1 year\n years = absFloor(months / 12);\n months %= 12;\n\n\n // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n var Y = years;\n var M = months;\n var D = days;\n var h = hours;\n var m = minutes;\n var s = seconds;\n var total = this.asSeconds();\n\n if (!total) {\n // this is the same as C#'s (Noda) and python (isodate)...\n // but not other JS (goog.date)\n return 'P0D';\n }\n\n return (total < 0 ? '-' : '') +\n 'P' +\n (Y ? Y + 'Y' : '') +\n (M ? M + 'M' : '') +\n (D ? D + 'D' : '') +\n ((h || m || s) ? 'T' : '') +\n (h ? h + 'H' : '') +\n (m ? m + 'M' : '') +\n (s ? s + 'S' : '');\n }\n\n var duration_prototype__proto = Duration.prototype;\n\n duration_prototype__proto.abs = duration_abs__abs;\n duration_prototype__proto.add = duration_add_subtract__add;\n duration_prototype__proto.subtract = duration_add_subtract__subtract;\n duration_prototype__proto.as = as;\n duration_prototype__proto.asMilliseconds = asMilliseconds;\n duration_prototype__proto.asSeconds = asSeconds;\n duration_prototype__proto.asMinutes = asMinutes;\n duration_prototype__proto.asHours = asHours;\n duration_prototype__proto.asDays = asDays;\n duration_prototype__proto.asWeeks = asWeeks;\n duration_prototype__proto.asMonths = asMonths;\n duration_prototype__proto.asYears = asYears;\n duration_prototype__proto.valueOf = duration_as__valueOf;\n duration_prototype__proto._bubble = bubble;\n duration_prototype__proto.get = duration_get__get;\n duration_prototype__proto.milliseconds = milliseconds;\n duration_prototype__proto.seconds = seconds;\n duration_prototype__proto.minutes = minutes;\n duration_prototype__proto.hours = hours;\n duration_prototype__proto.days = days;\n duration_prototype__proto.weeks = weeks;\n duration_prototype__proto.months = months;\n duration_prototype__proto.years = years;\n duration_prototype__proto.humanize = humanize;\n duration_prototype__proto.toISOString = iso_string__toISOString;\n duration_prototype__proto.toString = iso_string__toISOString;\n duration_prototype__proto.toJSON = iso_string__toISOString;\n duration_prototype__proto.locale = locale;\n duration_prototype__proto.localeData = localeData;\n\n // Deprecations\n duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString);\n duration_prototype__proto.lang = lang;\n\n // Side effect imports\n\n addFormatToken('X', 0, 0, 'unix');\n addFormatToken('x', 0, 0, 'valueOf');\n\n // PARSING\n\n addRegexToken('x', matchSigned);\n addRegexToken('X', matchTimestamp);\n addParseToken('X', function (input, array, config) {\n config._d = new Date(parseFloat(input, 10) * 1000);\n });\n addParseToken('x', function (input, array, config) {\n config._d = new Date(toInt(input));\n });\n\n // Side effect imports\n\n\n utils_hooks__hooks.version = '2.10.6';\n\n setHookCallback(local__createLocal);\n\n utils_hooks__hooks.fn = momentPrototype;\n utils_hooks__hooks.min = min;\n utils_hooks__hooks.max = max;\n utils_hooks__hooks.utc = create_utc__createUTC;\n utils_hooks__hooks.unix = moment__createUnix;\n utils_hooks__hooks.months = lists__listMonths;\n utils_hooks__hooks.isDate = isDate;\n utils_hooks__hooks.locale = locale_locales__getSetGlobalLocale;\n utils_hooks__hooks.invalid = valid__createInvalid;\n utils_hooks__hooks.duration = create__createDuration;\n utils_hooks__hooks.isMoment = isMoment;\n utils_hooks__hooks.weekdays = lists__listWeekdays;\n utils_hooks__hooks.parseZone = moment__createInZone;\n utils_hooks__hooks.localeData = locale_locales__getLocale;\n utils_hooks__hooks.isDuration = isDuration;\n utils_hooks__hooks.monthsShort = lists__listMonthsShort;\n utils_hooks__hooks.weekdaysMin = lists__listWeekdaysMin;\n utils_hooks__hooks.defineLocale = defineLocale;\n utils_hooks__hooks.weekdaysShort = lists__listWeekdaysShort;\n utils_hooks__hooks.normalizeUnits = normalizeUnits;\n utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold;\n\n var _moment = utils_hooks__hooks;\n\n return _moment;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/moment.js\n ** module id = 3\n ** module chunks = 0\n **/","module.exports = function(module) {\r\n\tif(!module.webpackPolyfill) {\r\n\t\tmodule.deprecate = function() {};\r\n\t\tmodule.paths = [];\r\n\t\t// module.parent = undefined by default\r\n\t\tmodule.children = [];\r\n\t\tmodule.webpackPolyfill = 1;\r\n\t}\r\n\treturn module;\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** (webpack)/buildin/module.js\n ** module id = 4\n ** module chunks = 0\n **/","var map = {\n\t\"./en-gb\": 6,\n\t\"./en-gb.js\": 6\n};\nfunction webpackContext(req) {\n\treturn __webpack_require__(webpackContextResolve(req));\n};\nfunction webpackContextResolve(req) {\n\treturn map[req] || (function() { throw new Error(\"Cannot find module '\" + req + \"'.\") }());\n};\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = 5;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale en-gb\n ** module id = 5\n ** module chunks = 0\n **/","//! moment.js locale configuration\n//! locale : great britain english (en-gb)\n//! author : Chris Gedrim : https://github.com/chrisgedrim\n\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n typeof define === 'function' && define.amd ? define(['moment'], factory) :\n factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n var en_gb = moment.defineLocale('en-gb', {\n months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n longDateFormat : {\n LT : 'HH:mm',\n LTS : 'HH:mm:ss',\n L : 'DD/MM/YYYY',\n LL : 'D MMMM YYYY',\n LLL : 'D MMMM YYYY HH:mm',\n LLLL : 'dddd, D MMMM YYYY HH:mm'\n },\n calendar : {\n sameDay : '[Today at] LT',\n nextDay : '[Tomorrow at] LT',\n nextWeek : 'dddd [at] LT',\n lastDay : '[Yesterday at] LT',\n lastWeek : '[Last] dddd [at] LT',\n sameElse : 'L'\n },\n relativeTime : {\n future : 'in %s',\n past : '%s ago',\n s : 'a few seconds',\n m : 'a minute',\n mm : '%d minutes',\n h : 'an hour',\n hh : '%d hours',\n d : 'a day',\n dd : '%d days',\n M : 'a month',\n MM : '%d months',\n y : 'a year',\n yy : '%d years'\n },\n ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n ordinal : function (number) {\n var b = number % 10,\n output = (~~(number % 100 / 10) === 1) ? 'th' :\n (b === 1) ? 'st' :\n (b === 2) ? 'nd' :\n (b === 3) ? 'rd' : 'th';\n return number + output;\n },\n week : {\n dow : 1, // Monday is the first day of the week.\n doy : 4 // The week that contains Jan 4th is the first week of the year.\n }\n });\n\n return en_gb;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/moment/locale/en-gb.js\n ** module id = 6\n ** module chunks = 0\n **/","'use strict';\n\n/*!\n * Timekit JavaScript SDK\n * Version: 1.1.0\n * http://timekit.io\n *\n * Copyright 2015 Timekit, Inc.\n * The Timekit JavaScript SDK is freely distributable under the MIT license.\n *\n */\nvar axios = require('axios');\nvar base64 = require('base-64');\nvar humps = require('humps');\n\nfunction Timekit() {\n\n /**\n * Auth variables for login gated API methods\n * @type {String}\n */\n var userEmail;\n var userApiToken;\n var includes;\n\n /**\n * Default config\n * @type {Object}\n */\n var config = {\n app: 'demo',\n apiBaseUrl: 'https://api.timekit.io/',\n apiVersion: 'v2',\n convertResponseToCamelcase: false\n };\n\n /**\n * Generate base64 string for basic auth purposes\n * @type {Function}\n * @return {String}\n */\n\n var encodeAuthHeader = function() {\n return base64.encode(userEmail + ':' + userApiToken);\n };\n\n /**\n * Build absolute URL for API call\n * @type {Function}\n * @return {String}\n */\n var buildUrl = function(endpoint) {\n return config.apiBaseUrl + config.apiVersion + endpoint;\n };\n\n /**\n * Root Object that holds methods to expose for API consumption\n * @type {Object}\n */\n var TK = {};\n\n\n /**\n * Prepare and make HTTP request to API\n * @type {Object}\n * @return {Promise}\n */\n TK.makeRequest = function(args) {\n\n // construct URL with base, version and endpoint\n args.url = buildUrl(args.url);\n\n // add http headers if applicable\n args.headers = { 'Timekit-App': config.app };\n if (userEmail && userApiToken) { args.headers.Authorization = 'Basic ' + encodeAuthHeader(); }\n if (config.inputTimestampFormat) { args.headers['Timekit-InputTimestampFormat'] = config.inputTimestampFormat; }\n if (config.outputTimestampFormat) { args.headers['Timekit-OutputTimestampFormat'] = config.outputTimestampFormat; }\n if (config.timezone) { args.headers['Timekit-Timezone'] = config.timezone; }\n\n // add dynamic includes if applicable\n if (includes && includes.length > 0) {\n if (args.params === undefined) { args.params = {}; }\n args.params.include = includes.join();\n includes = [];\n }\n\n // decamelize keys in data objects\n if (args.data) { args.data = humps.decamelizeKeys(args.data); }\n\n // register response interceptor for data manipulation\n var interceptor = axios.interceptors.response.use(function (response) {\n if(response.data && response.data.data) {\n response.data = response.data.data;\n if (config.convertResponseToCamelcase) {\n response.data = humps.camelizeKeys(response.data);\n }\n }\n return response;\n }, function (error) {\n return Promise.reject(error);\n });\n\n // execute request!\n var request = axios(args);\n\n // deregister response interceptor\n axios.interceptors.response.eject(interceptor);\n\n return request;\n };\n\n /**\n * Overwrite default config with supplied settings\n * @type {Function}\n * @return {Object}\n */\n TK.configure = function(custom) {\n for (var attr in custom) { config[attr] = custom[attr]; }\n return config;\n };\n\n /**\n * Returns the current config\n * @type {Function}\n * @return {Object}\n */\n TK.getConfig = function() {\n return config;\n };\n\n /**\n * Set the active user manuallt (happens automatically on timekit.auth())\n * @type {Function}\n */\n TK.setUser = function(email, apiToken) {\n userEmail = email;\n userApiToken = apiToken;\n };\n\n /**\n * Returns the current active user\n * @type {Function}\n * @return {Object}\n */\n TK.getUser = function() {\n return {\n email: userEmail,\n apiToken: userApiToken\n };\n };\n\n /**\n * Add supplied dynamic includes to the next request (fluent/chainable return)\n * @type {Function}\n * @return {Object}\n */\n TK.include = function() {\n includes = Array.prototype.slice.call(arguments);\n return this;\n };\n\n /**\n * Get user's connected accounts\n * @type {Function}\n * @return {Promise}\n */\n TK.getAccounts = function() {\n\n return TK.makeRequest({\n url: '/accounts',\n method: 'get'\n });\n\n };\n\n /**\n * Redirect to the Google signup/login page\n * @type {Function}\n * @return {String}\n */\n TK.accountGoogleSignup = function(data, shouldAutoRedirect) {\n\n var url = buildUrl('/accounts/google/signup') + '?Timekit-App=' + config.app + (data && data.callback ? '&callback=' + data.callback : '');\n\n if(shouldAutoRedirect && window) {\n window.location.href = url;\n } else {\n return url;\n }\n\n };\n\n /**\n * Get user's Google calendars\n * @type {Function\n * @return {Promise}\n */\n TK.getAccountGoogleCalendars = function() {\n\n return TK.makeRequest({\n url: '/accounts/google/calendars',\n method: 'get'\n });\n\n };\n\n /**\n * Initiate a server sync on all the users accounts\n * @type {Function}\n * @return {Promise}\n */\n TK.accountSync = function() {\n\n return TK.makeRequest({\n url: '/accounts/sync',\n method: 'get'\n });\n\n };\n\n /**\n * Authenticate a user to retrive API token for future calls\n * @type {Function}\n * @return {Promise}\n */\n TK.auth = function(data) {\n\n var r = TK.makeRequest({\n url: '/auth',\n method: 'post',\n data: data\n });\n\n r.then(function(response) {\n TK.setUser(response.data.email, response.data.api_token);\n }).catch(function(){\n TK.setUser('','');\n });\n\n return r;\n\n };\n\n /**\n * Get list of apps\n * @type {Function}\n * @return {Promise}\n */\n TK.getApps = function() {\n\n return TK.makeRequest({\n url: '/apps',\n method: 'get'\n });\n\n };\n\n /**\n * Get settings for a specific app\n * @type {Function}\n * @return {Promise}\n */\n TK.getApp = function(data) {\n\n return TK.makeRequest({\n url: '/apps/' + data.slug,\n method: 'get'\n });\n\n };\n\n /**\n * Create a new Timekit app\n * @type {Function}\n * @return {Promise}\n */\n TK.createApp = function(data) {\n\n return TK.makeRequest({\n url: '/apps',\n method: 'post',\n data: data\n });\n\n };\n\n /**\n * Update settings for a specific app\n * @type {Function}\n * @return {Promise}\n */\n TK.updateApp = function(data) {\n\n var slug = data.slug;\n delete data.slug;\n\n return TK.makeRequest({\n url: '/apps/' + slug,\n method: 'put',\n data: data\n });\n\n };\n\n /**\n * Delete an app\n * @type {Function}\n * @return {Promise}\n */\n TK.deleteApp = function(data) {\n\n return TK.makeRequest({\n url: '/apps/' + data.slug,\n method: 'delete'\n });\n\n };\n\n /**\n * Get users calendars that are present on Timekit (synced from providers)\n * @type {Function}\n * @return {Promise}\n */\n TK.getCalendars = function() {\n\n return TK.makeRequest({\n url: '/calendars',\n method: 'get'\n });\n\n };\n\n /**\n * Get users calendars that are present on Timekit (synced from providers)\n * @type {Function}\n * @return {Promise}\n */\n TK.getCalendar = function(data) {\n\n return TK.makeRequest({\n url: '/calendars/' + data.id,\n method: 'get'\n });\n\n };\n\n /**\n * Create a new calendar for current user\n * @type {Function}\n * @return {Promise}\n */\n TK.createCalendar = function(data) {\n\n return TK.makeRequest({\n url: '/calendars/',\n method: 'post',\n data: data\n });\n\n };\n\n /**\n * Delete a calendar\n * @type {Function}\n * @return {Promise}\n */\n TK.deleteCalendar = function(data) {\n\n return TK.makeRequest({\n url: '/calendars/' + data.id,\n method: 'delete'\n });\n\n };\n\n /**\n * Get users contacts that are present on Timekit (synced from providers)\n * @type {Function}\n * @return {Promise}\n */\n TK.getContacts = function() {\n\n return TK.makeRequest({\n url: '/contacts/',\n method: 'get'\n });\n\n };\n\n /**\n * Get all user's events\n * @type {Function}\n * @return {Promise}\n */\n TK.getEvents = function(data) {\n\n return TK.makeRequest({\n url: '/events',\n method: 'get',\n params: data\n });\n\n };\n\n /**\n * Get a user's event by ID\n * @type {Function}\n * @return {Promise}\n */\n TK.getEvent = function(data) {\n\n return TK.makeRequest({\n url: '/events/' + data.id,\n method: 'get'\n });\n\n };\n\n /**\n * Create a new event\n * @type {Function}\n * @return {Promise}\n */\n TK.createEvent = function(data) {\n\n return TK.makeRequest({\n url: '/events',\n method: 'post',\n data: data\n });\n\n };\n\n /**\n * Delete a user's event by ID\n * @type {Function}\n * @return {Promise}\n */\n TK.deleteEvent = function(data) {\n\n return TK.makeRequest({\n url: '/events/' + data.id,\n method: 'delete'\n });\n\n };\n\n /**\n * Get a user's anonymized availability (other user's on Timekit can be queryied by supplying their email)\n * @type {Function}\n * @return {Promise}\n */\n TK.getAvailability = function(data) {\n\n return TK.makeRequest({\n url: '/events/availability',\n method: 'get',\n params: data\n });\n\n };\n\n /**\n * Find mutual availability across multiple users/calendars\n * @type {Function}\n * @return {Promise}\n */\n TK.findTime = function(data) {\n\n return TK.makeRequest({\n url: '/findtime',\n method: 'post',\n data: data\n });\n\n };\n\n /**\n * Find mutual availability across multiple users/calendars\n * @type {Function}\n * @return {Promise}\n */\n TK.findTimeBulk = function(data) {\n\n return TK.makeRequest({\n url: '/findtime/bulk',\n method: 'post',\n data: data\n });\n\n };\n\n /**\n * Get a user's meetings\n * @type {Function}\n * @return {Promise}\n */\n TK.getMeetings = function() {\n\n return TK.makeRequest({\n url: '/meetings',\n method: 'get'\n });\n\n };\n\n /**\n * Get a user's specific meeting\n * @type {Function}\n * @return {Promise}\n */\n TK.getMeeting = function(data) {\n\n return TK.makeRequest({\n url: '/meetings/' + data.id,\n method: 'get'\n });\n\n };\n\n /**\n * Get a user's specific meeting\n * @type {Function}\n * @return {Promise}\n */\n TK.createMeeting = function(data) {\n\n return TK.makeRequest({\n url: '/meetings',\n method: 'post',\n data: data\n });\n\n };\n\n /**\n * Get a user's specific meeting\n * @type {Function}\n * @return {Promise}\n */\n TK.updateMeeting = function(data) {\n\n var id = data.id;\n delete data.id;\n\n return TK.makeRequest({\n url: '/meetings/' + id,\n method: 'put',\n data: data\n });\n\n };\n\n /**\n * Set availability (true/faalse) on a meeting's suggestion\n * @type {Function}\n * @return {Promise}\n */\n TK.setMeetingAvailability = function(data) {\n\n return TK.makeRequest({\n url: '/meetings/availability',\n method: 'post',\n data: data\n });\n\n };\n\n /**\n * Book/finalize the meeting, sending out meeting invites to all participants\n * @type {Function}\n * @return {Promise}\n */\n TK.bookMeeting = function(data) {\n\n return TK.makeRequest({\n url: '/meetings/book',\n method: 'post',\n data: data\n });\n\n };\n\n /**\n * Invite users/emails to a meeting, sending out invite emails to the supplied addresses\n * @type {Function}\n * @return {Promise}\n */\n TK.inviteToMeeting = function(data) {\n\n var id = data.id;\n delete data.id;\n\n return TK.makeRequest({\n url: '/meetings/' + id + '/invite',\n method: 'post',\n data: data\n });\n\n };\n\n /**\n * Create a new user with the given properties\n * @type {Function}\n * @return {Promise}\n */\n TK.createUser = function(data) {\n\n return TK.makeRequest({\n url: '/users',\n method: 'post',\n data: data\n });\n\n };\n\n /**\n * Fetch current user data from server\n * @type {Function}\n * @return {Promise}\n */\n TK.getUserInfo = function() {\n\n return TK.makeRequest({\n url: '/users/me',\n method: 'get'\n });\n\n };\n\n /**\n * Fetch current user data from server\n * @type {Function}\n * @return {Promise}\n */\n TK.updateUser = function(data) {\n\n return TK.makeRequest({\n url: '/users/me',\n method: 'put',\n data: data\n });\n\n };\n\n /**\n * Reset password for a user\n * @type {Function}\n * @return {Promise}\n */\n TK.resetUserPassword = function(data) {\n\n return TK.makeRequest({\n url: '/users/resetpassword',\n method: 'post',\n data: data\n });\n\n };\n\n /**\n * Get a specific users' timezone\n * @type {Function}\n * @return {Promise}\n */\n TK.getUserTimezone = function(data) {\n\n return TK.makeRequest({\n url: '/users/timezone/' + data.email,\n method: 'get'\n });\n\n };\n\n /**\n * Get a user property by key\n * @type {Function}\n * @return {Promise}\n */\n TK.getUserProperties = function() {\n\n return TK.makeRequest({\n url: '/properties',\n method: 'get'\n });\n\n };\n\n /**\n * Get a user property by key\n * @type {Function}\n * @return {Promise}\n */\n TK.getUserProperty = function(data) {\n\n return TK.makeRequest({\n url: '/properties/' + data.key,\n method: 'get'\n });\n\n };\n\n /**\n * Set or update user properties\n * @type {Function}\n * @return {Promise}\n */\n TK.setUserProperties = function(data) {\n\n return TK.makeRequest({\n url: '/properties',\n method: 'put',\n data: data\n });\n\n };\n\n /**\n * Get all user auth credentials\n * @type {Function}\n * @return {Promise}\n */\n TK.getCredentials = function() {\n\n return TK.makeRequest({\n url: '/credentials',\n method: 'get'\n });\n\n };\n\n /**\n * Create a new pair of auth credentials\n * @type {Function}\n * @return {Promise}\n */\n TK.createCredential = function(data) {\n\n return TK.makeRequest({\n url: '/credentials',\n method: 'post',\n data: data\n });\n\n };\n\n /**\n * Delete a pair of auth credentials\n * @type {Function}\n * @return {Promise}\n */\n TK.deleteCredential = function(data) {\n\n return TK.makeRequest({\n url: '/credentials/' + data.id,\n method: 'delete'\n });\n\n };\n\n return TK;\n\n}\n\nmodule.exports = new Timekit();\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/timekit-sdk/src/timekit.js\n ** module id = 7\n ** module chunks = 0\n **/","module.exports = require('./lib/axios');\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/axios/index.js\n ** module id = 8\n ** module chunks = 0\n **/","'use strict';\n\nvar defaults = require('./defaults');\nvar utils = require('./utils');\nvar deprecatedMethod = require('./helpers/deprecatedMethod');\nvar dispatchRequest = require('./core/dispatchRequest');\nvar InterceptorManager = require('./core/InterceptorManager');\n\n// Polyfill ES6 Promise if needed\n(function () {\n // webpack is being used to set es6-promise to the native Promise\n // for the standalone build. It's necessary to make sure polyfill exists.\n var P = require('es6-promise');\n if (P && typeof P.polyfill === 'function') {\n P.polyfill();\n }\n})();\n\nvar axios = module.exports = function axios(config) {\n config = utils.merge({\n method: 'get',\n headers: {},\n transformRequest: defaults.transformRequest,\n transformResponse: defaults.transformResponse\n }, config);\n\n // Don't allow overriding defaults.withCredentials\n config.withCredentials = config.withCredentials || defaults.withCredentials;\n\n // Hook up interceptors middleware\n var chain = [dispatchRequest, undefined];\n var promise = Promise.resolve(config);\n\n axios.interceptors.request.forEach(function (interceptor) {\n chain.unshift(interceptor.fulfilled, interceptor.rejected);\n });\n\n axios.interceptors.response.forEach(function (interceptor) {\n chain.push(interceptor.fulfilled, interceptor.rejected);\n });\n\n while (chain.length) {\n promise = promise.then(chain.shift(), chain.shift());\n }\n\n // Provide alias for success\n promise.success = function success(fn) {\n deprecatedMethod('success', 'then', 'https://github.com/mzabriskie/axios/blob/master/README.md#response-api');\n\n promise.then(function(response) {\n fn(response.data, response.status, response.headers, response.config);\n });\n return promise;\n };\n\n // Provide alias for error\n promise.error = function error(fn) {\n deprecatedMethod('error', 'catch', 'https://github.com/mzabriskie/axios/blob/master/README.md#response-api');\n\n promise.then(null, function(response) {\n fn(response.data, response.status, response.headers, response.config);\n });\n return promise;\n };\n\n return promise;\n};\n\n// Expose defaults\naxios.defaults = defaults;\n\n// Expose all/spread\naxios.all = function (promises) {\n return Promise.all(promises);\n};\naxios.spread = require('./helpers/spread');\n\n// Expose interceptors\naxios.interceptors = {\n request: new InterceptorManager(),\n response: new InterceptorManager()\n};\n\n// Provide aliases for supported request methods\n(function () {\n function createShortMethods() {\n utils.forEach(arguments, function (method) {\n axios[method] = function (url, config) {\n return axios(utils.merge(config || {}, {\n method: method,\n url: url\n }));\n };\n });\n }\n\n function createShortMethodsWithData() {\n utils.forEach(arguments, function (method) {\n axios[method] = function (url, data, config) {\n return axios(utils.merge(config || {}, {\n method: method,\n url: url,\n data: data\n }));\n };\n });\n }\n\n createShortMethods('delete', 'get', 'head');\n createShortMethodsWithData('post', 'put', 'patch');\n})();\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/axios/lib/axios.js\n ** module id = 9\n ** module chunks = 0\n **/","'use strict';\n\nvar utils = require('./utils');\n\nvar PROTECTION_PREFIX = /^\\)\\]\\}',?\\n/;\nvar DEFAULT_CONTENT_TYPE = {\n 'Content-Type': 'application/x-www-form-urlencoded'\n};\n\nmodule.exports = {\n transformRequest: [function (data, headers) {\n if(utils.isFormData(data)) {\n return data;\n }\n if (utils.isArrayBuffer(data)) {\n return data;\n }\n if (utils.isArrayBufferView(data)) {\n return data.buffer;\n }\n if (utils.isObject(data) && !utils.isFile(data) && !utils.isBlob(data)) {\n // Set application/json if no Content-Type has been specified\n if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {\n headers['Content-Type'] = 'application/json;charset=utf-8';\n }\n return JSON.stringify(data);\n }\n return data;\n }],\n\n transformResponse: [function (data) {\n if (typeof data === 'string') {\n data = data.replace(PROTECTION_PREFIX, '');\n try {\n data = JSON.parse(data);\n } catch (e) {}\n }\n return data;\n }],\n\n headers: {\n common: {\n 'Accept': 'application/json, text/plain, */*'\n },\n patch: utils.merge(DEFAULT_CONTENT_TYPE),\n post: utils.merge(DEFAULT_CONTENT_TYPE),\n put: utils.merge(DEFAULT_CONTENT_TYPE)\n },\n\n xsrfCookieName: 'XSRF-TOKEN',\n xsrfHeaderName: 'X-XSRF-TOKEN'\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/axios/lib/defaults.js\n ** module id = 10\n ** module chunks = 0\n **/","'use strict';\n\n/*global toString:true*/\n\n// utils is a library of generic helper functions non-specific to axios\n\nvar toString = Object.prototype.toString;\n\n/**\n * Determine if a value is an Array\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is an Array, otherwise false\n */\nfunction isArray(val) {\n return toString.call(val) === '[object Array]';\n}\n\n/**\n * Determine if a value is an ArrayBuffer\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n */\nfunction isArrayBuffer(val) {\n return toString.call(val) === '[object ArrayBuffer]';\n}\n\n/**\n * Determine if a value is a FormData\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is an FormData, otherwise false\n */\nfunction isFormData(val) {\n return toString.call(val) === '[object FormData]';\n}\n\n/**\n * Determine if a value is a view on an ArrayBuffer\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n */\nfunction isArrayBufferView(val) {\n if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n return ArrayBuffer.isView(val);\n } else {\n return (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);\n }\n}\n\n/**\n * Determine if a value is a String\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a String, otherwise false\n */\nfunction isString(val) {\n return typeof val === 'string';\n}\n\n/**\n * Determine if a value is a Number\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Number, otherwise false\n */\nfunction isNumber(val) {\n return typeof val === 'number';\n}\n\n/**\n * Determine if a value is undefined\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if the value is undefined, otherwise false\n */\nfunction isUndefined(val) {\n return typeof val === 'undefined';\n}\n\n/**\n * Determine if a value is an Object\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is an Object, otherwise false\n */\nfunction isObject(val) {\n return val !== null && typeof val === 'object';\n}\n\n/**\n * Determine if a value is a Date\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Date, otherwise false\n */\nfunction isDate(val) {\n return toString.call(val) === '[object Date]';\n}\n\n/**\n * Determine if a value is a File\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a File, otherwise false\n */\nfunction isFile(val) {\n return toString.call(val) === '[object File]';\n}\n\n/**\n * Determine if a value is a Blob\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Blob, otherwise false\n */\nfunction isBlob(val) {\n return toString.call(val) === '[object Blob]';\n}\n\n/**\n * Trim excess whitespace off the beginning and end of a string\n *\n * @param {String} str The String to trim\n * @returns {String} The String freed of excess whitespace\n */\nfunction trim(str) {\n return str.replace(/^\\s*/, '').replace(/\\s*$/, '');\n}\n\n/**\n * Iterate over an Array or an Object invoking a function for each item.\n *\n * If `obj` is an Array or arguments callback will be called passing\n * the value, index, and complete array for each item.\n *\n * If 'obj' is an Object callback will be called passing\n * the value, key, and complete object for each property.\n *\n * @param {Object|Array} obj The object to iterate\n * @param {Function} fn The callback to invoke for each item\n */\nfunction forEach(obj, fn) {\n // Don't bother if no value provided\n if (obj === null || typeof obj === 'undefined') {\n return;\n }\n\n // Check if obj is array-like\n var isArrayLike = isArray(obj) || (typeof obj === 'object' && !isNaN(obj.length));\n\n // Force an array if not already something iterable\n if (typeof obj !== 'object' && !isArrayLike) {\n obj = [obj];\n }\n\n // Iterate over array values\n if (isArrayLike) {\n for (var i = 0, l = obj.length; i < l; i++) {\n fn.call(null, obj[i], i, obj);\n }\n }\n // Iterate over object keys\n else {\n for (var key in obj) {\n if (obj.hasOwnProperty(key)) {\n fn.call(null, obj[key], key, obj);\n }\n }\n }\n}\n\n/**\n * Accepts varargs expecting each argument to be an object, then\n * immutably merges the properties of each object and returns result.\n *\n * When multiple objects contain the same key the later object in\n * the arguments list will take precedence.\n *\n * Example:\n *\n * ```js\n * var result = merge({foo: 123}, {foo: 456});\n * console.log(result.foo); // outputs 456\n * ```\n *\n * @param {Object} obj1 Object to merge\n * @returns {Object} Result of all merge properties\n */\nfunction merge(/*obj1, obj2, obj3, ...*/) {\n var result = {};\n forEach(arguments, function (obj) {\n forEach(obj, function (val, key) {\n result[key] = val;\n });\n });\n return result;\n}\n\nmodule.exports = {\n isArray: isArray,\n isArrayBuffer: isArrayBuffer,\n isFormData: isFormData,\n isArrayBufferView: isArrayBufferView,\n isString: isString,\n isNumber: isNumber,\n isObject: isObject,\n isUndefined: isUndefined,\n isDate: isDate,\n isFile: isFile,\n isBlob: isBlob,\n forEach: forEach,\n merge: merge,\n trim: trim\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/axios/lib/utils.js\n ** module id = 11\n ** module chunks = 0\n **/","'use strict';\n\n/**\n * Supply a warning to the developer that a method they are using\n * has been deprecated.\n *\n * @param {string} method The name of the deprecated method\n * @param {string} [instead] The alternate method to use if applicable\n * @param {string} [docs] The documentation URL to get further details\n */\nmodule.exports = function deprecatedMethod(method, instead, docs) {\n try {\n console.warn(\n 'DEPRECATED method `' + method + '`.' +\n (instead ? ' Use `' + instead + '` instead.' : '') +\n ' This method will be removed in a future release.');\n\n if (docs) {\n console.warn('For more information about usage see ' + docs);\n }\n } catch (e) {}\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/axios/lib/helpers/deprecatedMethod.js\n ** module id = 12\n ** module chunks = 0\n **/","'use strict';\n\n/**\n * Dispatch a request to the server using whichever adapter\n * is supported by the current environment.\n *\n * @param {object} config The config that is to be used for the request\n * @returns {Promise} The Promise to be fulfilled\n */\nmodule.exports = function dispatchRequest(config) {\n return new Promise(function (resolve, reject) {\n try {\n // For browsers use XHR adapter\n if (typeof window !== 'undefined') {\n require('../adapters/xhr')(resolve, reject, config);\n }\n // For node use HTTP adapter\n else if (typeof process !== 'undefined') {\n require('../adapters/http')(resolve, reject, config);\n }\n } catch (e) {\n reject(e);\n }\n });\n};\n\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/axios/lib/core/dispatchRequest.js\n ** module id = 13\n ** module chunks = 0\n **/","// shim for using process in browser\n\nvar process = module.exports = {};\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = setTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n clearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n setTimeout(drainQueue, 0);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/process/browser.js\n ** module id = 14\n ** module chunks = 0\n **/","'use strict';\n\n/*global ActiveXObject:true*/\n\nvar defaults = require('./../defaults');\nvar utils = require('./../utils');\nvar buildUrl = require('./../helpers/buildUrl');\nvar cookies = require('./../helpers/cookies');\nvar parseHeaders = require('./../helpers/parseHeaders');\nvar transformData = require('./../helpers/transformData');\nvar urlIsSameOrigin = require('./../helpers/urlIsSameOrigin');\n\nmodule.exports = function xhrAdapter(resolve, reject, config) {\n // Transform request data\n var data = transformData(\n config.data,\n config.headers,\n config.transformRequest\n );\n\n // Merge headers\n var requestHeaders = utils.merge(\n defaults.headers.common,\n defaults.headers[config.method] || {},\n config.headers || {}\n );\n\n if (utils.isFormData(data)) {\n delete requestHeaders['Content-Type']; // Let the browser set it\n }\n\n // Create the request\n var request = new (XMLHttpRequest || ActiveXObject)('Microsoft.XMLHTTP');\n request.open(config.method.toUpperCase(), buildUrl(config.url, config.params), true);\n\n // Listen for ready state\n request.onreadystatechange = function () {\n if (request && request.readyState === 4) {\n // Prepare the response\n var responseHeaders = parseHeaders(request.getAllResponseHeaders());\n var responseData = ['text', ''].indexOf(config.responseType || '') !== -1 ? request.responseText : request.response;\n var response = {\n data: transformData(\n responseData,\n responseHeaders,\n config.transformResponse\n ),\n status: request.status,\n statusText: request.statusText,\n headers: responseHeaders,\n config: config\n };\n\n // Resolve or reject the Promise based on the status\n (request.status >= 200 && request.status < 300 ?\n resolve :\n reject)(response);\n\n // Clean up request\n request = null;\n }\n };\n\n // Add xsrf header\n var xsrfValue = urlIsSameOrigin(config.url) ?\n cookies.read(config.xsrfCookieName || defaults.xsrfCookieName) :\n undefined;\n if (xsrfValue) {\n requestHeaders[config.xsrfHeaderName || defaults.xsrfHeaderName] = xsrfValue;\n }\n\n // Add headers to the request\n utils.forEach(requestHeaders, function (val, key) {\n // Remove Content-Type if data is undefined\n if (!data && key.toLowerCase() === 'content-type') {\n delete requestHeaders[key];\n }\n // Otherwise add header to the request\n else {\n request.setRequestHeader(key, val);\n }\n });\n\n // Add withCredentials to request if needed\n if (config.withCredentials) {\n request.withCredentials = true;\n }\n\n // Add responseType to request if needed\n if (config.responseType) {\n try {\n request.responseType = config.responseType;\n } catch (e) {\n if (request.responseType !== 'json') {\n throw e;\n }\n }\n }\n\n if (utils.isArrayBuffer(data)) {\n data = new DataView(data);\n }\n\n // Send the request\n request.send(data);\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/axios/lib/adapters/xhr.js\n ** module id = 15\n ** module chunks = 0\n **/","'use strict';\n\nvar utils = require('./../utils');\n\nfunction encode(val) {\n return encodeURIComponent(val).\n replace(/%40/gi, '@').\n replace(/%3A/gi, ':').\n replace(/%24/g, '$').\n replace(/%2C/gi, ',').\n replace(/%20/g, '+');\n}\n\n/**\n * Build a URL by appending params to the end\n *\n * @param {string} url The base of the url (e.g., http://www.google.com)\n * @param {object} [params] The params to be appended\n * @returns {string} The formatted url\n */\nmodule.exports = function buildUrl(url, params) {\n if (!params) {\n return url;\n }\n\n var parts = [];\n\n utils.forEach(params, function (val, key) {\n if (val === null || typeof val === 'undefined') {\n return;\n }\n if (!utils.isArray(val)) {\n val = [val];\n }\n\n utils.forEach(val, function (v) {\n if (utils.isDate(v)) {\n v = v.toISOString();\n }\n else if (utils.isObject(v)) {\n v = JSON.stringify(v);\n }\n parts.push(encode(key) + '=' + encode(v));\n });\n });\n\n if (parts.length > 0) {\n url += (url.indexOf('?') === -1 ? '?' : '&') + parts.join('&');\n }\n\n return url;\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/axios/lib/helpers/buildUrl.js\n ** module id = 16\n ** module chunks = 0\n **/","'use strict';\n\nvar utils = require('./../utils');\n\nmodule.exports = {\n write: function write(name, value, expires, path, domain, secure) {\n var cookie = [];\n cookie.push(name + '=' + encodeURIComponent(value));\n\n if (utils.isNumber(expires)) {\n cookie.push('expires=' + new Date(expires).toGMTString());\n }\n\n if (utils.isString(path)) {\n cookie.push('path=' + path);\n }\n\n if (utils.isString(domain)) {\n cookie.push('domain=' + domain);\n }\n\n if (secure === true) {\n cookie.push('secure');\n }\n\n document.cookie = cookie.join('; ');\n },\n\n read: function read(name) {\n var match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n return (match ? decodeURIComponent(match[3]) : null);\n },\n\n remove: function remove(name) {\n this.write(name, '', Date.now() - 86400000);\n }\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/axios/lib/helpers/cookies.js\n ** module id = 17\n ** module chunks = 0\n **/","'use strict';\n\nvar utils = require('./../utils');\n\n/**\n * Parse headers into an object\n *\n * ```\n * Date: Wed, 27 Aug 2014 08:58:49 GMT\n * Content-Type: application/json\n * Connection: keep-alive\n * Transfer-Encoding: chunked\n * ```\n *\n * @param {String} headers Headers needing to be parsed\n * @returns {Object} Headers parsed into an object\n */\nmodule.exports = function parseHeaders(headers) {\n var parsed = {}, key, val, i;\n\n if (!headers) { return parsed; }\n\n utils.forEach(headers.split('\\n'), function(line) {\n i = line.indexOf(':');\n key = utils.trim(line.substr(0, i)).toLowerCase();\n val = utils.trim(line.substr(i + 1));\n\n if (key) {\n parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n }\n });\n\n return parsed;\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/axios/lib/helpers/parseHeaders.js\n ** module id = 18\n ** module chunks = 0\n **/","'use strict';\n\nvar utils = require('./../utils');\n\n/**\n * Transform the data for a request or a response\n *\n * @param {Object|String} data The data to be transformed\n * @param {Array} headers The headers for the request or response\n * @param {Array|Function} fns A single function or Array of functions\n * @returns {*} The resulting transformed data\n */\nmodule.exports = function transformData(data, headers, fns) {\n utils.forEach(fns, function (fn) {\n data = fn(data, headers);\n });\n\n return data;\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/axios/lib/helpers/transformData.js\n ** module id = 19\n ** module chunks = 0\n **/","'use strict';\n\nvar utils = require('./../utils');\nvar msie = /(msie|trident)/i.test(navigator.userAgent);\nvar urlParsingNode = document.createElement('a');\nvar originUrl;\n\n/**\n * Parse a URL to discover it's components\n *\n * @param {String} url The URL to be parsed\n * @returns {Object}\n */\nfunction urlResolve(url) {\n var href = url;\n\n if (msie) {\n // IE needs attribute set twice to normalize properties\n urlParsingNode.setAttribute('href', href);\n href = urlParsingNode.href;\n }\n\n urlParsingNode.setAttribute('href', href);\n\n // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n return {\n href: urlParsingNode.href,\n protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n host: urlParsingNode.host,\n search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n hostname: urlParsingNode.hostname,\n port: urlParsingNode.port,\n pathname: (urlParsingNode.pathname.charAt(0) === '/') ?\n urlParsingNode.pathname :\n '/' + urlParsingNode.pathname\n };\n}\n\noriginUrl = urlResolve(window.location.href);\n\n/**\n * Determine if a URL shares the same origin as the current location\n *\n * @param {String} requestUrl The URL to test\n * @returns {boolean} True if URL shares the same origin, otherwise false\n */\nmodule.exports = function urlIsSameOrigin(requestUrl) {\n var parsed = (utils.isString(requestUrl)) ? urlResolve(requestUrl) : requestUrl;\n return (parsed.protocol === originUrl.protocol &&\n parsed.host === originUrl.host);\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/axios/lib/helpers/urlIsSameOrigin.js\n ** module id = 20\n ** module chunks = 0\n **/","'use strict';\n\nvar utils = require('./../utils');\n\nfunction InterceptorManager() {\n this.handlers = [];\n}\n\n/**\n * Add a new interceptor to the stack\n *\n * @param {Function} fulfilled The function to handle `then` for a `Promise`\n * @param {Function} rejected The function to handle `reject` for a `Promise`\n *\n * @return {Number} An ID used to remove interceptor later\n */\nInterceptorManager.prototype.use = function (fulfilled, rejected) {\n this.handlers.push({\n fulfilled: fulfilled,\n rejected: rejected\n });\n return this.handlers.length - 1;\n};\n\n/**\n * Remove an interceptor from the stack\n *\n * @param {Number} id The ID that was returned by `use`\n */\nInterceptorManager.prototype.eject = function (id) {\n if (this.handlers[id]) {\n this.handlers[id] = null;\n }\n};\n\n/**\n * Iterate over all the registered interceptors\n *\n * This method is particularly useful for skipping over any\n * interceptors that may have become `null` calling `remove`.\n *\n * @param {Function} fn The function to call for each interceptor\n */\nInterceptorManager.prototype.forEach = function (fn) {\n utils.forEach(this.handlers, function (h) {\n if (h !== null) {\n fn(h);\n }\n });\n};\n\nmodule.exports = InterceptorManager;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/axios/lib/core/InterceptorManager.js\n ** module id = 21\n ** module chunks = 0\n **/","/*!\n * @overview es6-promise - a tiny implementation of Promises/A+.\n * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)\n * @license Licensed under MIT license\n * See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE\n * @version 2.3.0\n */\n\n(function() {\n \"use strict\";\n function lib$es6$promise$utils$$objectOrFunction(x) {\n return typeof x === 'function' || (typeof x === 'object' && x !== null);\n }\n\n function lib$es6$promise$utils$$isFunction(x) {\n return typeof x === 'function';\n }\n\n function lib$es6$promise$utils$$isMaybeThenable(x) {\n return typeof x === 'object' && x !== null;\n }\n\n var lib$es6$promise$utils$$_isArray;\n if (!Array.isArray) {\n lib$es6$promise$utils$$_isArray = function (x) {\n return Object.prototype.toString.call(x) === '[object Array]';\n };\n } else {\n lib$es6$promise$utils$$_isArray = Array.isArray;\n }\n\n var lib$es6$promise$utils$$isArray = lib$es6$promise$utils$$_isArray;\n var lib$es6$promise$asap$$len = 0;\n var lib$es6$promise$asap$$toString = {}.toString;\n var lib$es6$promise$asap$$vertxNext;\n var lib$es6$promise$asap$$customSchedulerFn;\n\n var lib$es6$promise$asap$$asap = function asap(callback, arg) {\n lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len] = callback;\n lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len + 1] = arg;\n lib$es6$promise$asap$$len += 2;\n if (lib$es6$promise$asap$$len === 2) {\n // If len is 2, that means that we need to schedule an async flush.\n // If additional callbacks are queued before the queue is flushed, they\n // will be processed by this flush that we are scheduling.\n if (lib$es6$promise$asap$$customSchedulerFn) {\n lib$es6$promise$asap$$customSchedulerFn(lib$es6$promise$asap$$flush);\n } else {\n lib$es6$promise$asap$$scheduleFlush();\n }\n }\n }\n\n function lib$es6$promise$asap$$setScheduler(scheduleFn) {\n lib$es6$promise$asap$$customSchedulerFn = scheduleFn;\n }\n\n function lib$es6$promise$asap$$setAsap(asapFn) {\n lib$es6$promise$asap$$asap = asapFn;\n }\n\n var lib$es6$promise$asap$$browserWindow = (typeof window !== 'undefined') ? window : undefined;\n var lib$es6$promise$asap$$browserGlobal = lib$es6$promise$asap$$browserWindow || {};\n var lib$es6$promise$asap$$BrowserMutationObserver = lib$es6$promise$asap$$browserGlobal.MutationObserver || lib$es6$promise$asap$$browserGlobal.WebKitMutationObserver;\n var lib$es6$promise$asap$$isNode = typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';\n\n // test for web worker but not in IE10\n var lib$es6$promise$asap$$isWorker = typeof Uint8ClampedArray !== 'undefined' &&\n typeof importScripts !== 'undefined' &&\n typeof MessageChannel !== 'undefined';\n\n // node\n function lib$es6$promise$asap$$useNextTick() {\n var nextTick = process.nextTick;\n // node version 0.10.x displays a deprecation warning when nextTick is used recursively\n // setImmediate should be used instead instead\n var version = process.versions.node.match(/^(?:(\\d+)\\.)?(?:(\\d+)\\.)?(\\*|\\d+)$/);\n if (Array.isArray(version) && version[1] === '0' && version[2] === '10') {\n nextTick = setImmediate;\n }\n return function() {\n nextTick(lib$es6$promise$asap$$flush);\n };\n }\n\n // vertx\n function lib$es6$promise$asap$$useVertxTimer() {\n return function() {\n lib$es6$promise$asap$$vertxNext(lib$es6$promise$asap$$flush);\n };\n }\n\n function lib$es6$promise$asap$$useMutationObserver() {\n var iterations = 0;\n var observer = new lib$es6$promise$asap$$BrowserMutationObserver(lib$es6$promise$asap$$flush);\n var node = document.createTextNode('');\n observer.observe(node, { characterData: true });\n\n return function() {\n node.data = (iterations = ++iterations % 2);\n };\n }\n\n // web worker\n function lib$es6$promise$asap$$useMessageChannel() {\n var channel = new MessageChannel();\n channel.port1.onmessage = lib$es6$promise$asap$$flush;\n return function () {\n channel.port2.postMessage(0);\n };\n }\n\n function lib$es6$promise$asap$$useSetTimeout() {\n return function() {\n setTimeout(lib$es6$promise$asap$$flush, 1);\n };\n }\n\n var lib$es6$promise$asap$$queue = new Array(1000);\n function lib$es6$promise$asap$$flush() {\n for (var i = 0; i < lib$es6$promise$asap$$len; i+=2) {\n var callback = lib$es6$promise$asap$$queue[i];\n var arg = lib$es6$promise$asap$$queue[i+1];\n\n callback(arg);\n\n lib$es6$promise$asap$$queue[i] = undefined;\n lib$es6$promise$asap$$queue[i+1] = undefined;\n }\n\n lib$es6$promise$asap$$len = 0;\n }\n\n function lib$es6$promise$asap$$attemptVertex() {\n try {\n var r = require;\n var vertx = r('vertx');\n lib$es6$promise$asap$$vertxNext = vertx.runOnLoop || vertx.runOnContext;\n return lib$es6$promise$asap$$useVertxTimer();\n } catch(e) {\n return lib$es6$promise$asap$$useSetTimeout();\n }\n }\n\n var lib$es6$promise$asap$$scheduleFlush;\n // Decide what async method to use to triggering processing of queued callbacks:\n if (lib$es6$promise$asap$$isNode) {\n lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useNextTick();\n } else if (lib$es6$promise$asap$$BrowserMutationObserver) {\n lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMutationObserver();\n } else if (lib$es6$promise$asap$$isWorker) {\n lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMessageChannel();\n } else if (lib$es6$promise$asap$$browserWindow === undefined && typeof require === 'function') {\n lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$attemptVertex();\n } else {\n lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useSetTimeout();\n }\n\n function lib$es6$promise$$internal$$noop() {}\n\n var lib$es6$promise$$internal$$PENDING = void 0;\n var lib$es6$promise$$internal$$FULFILLED = 1;\n var lib$es6$promise$$internal$$REJECTED = 2;\n\n var lib$es6$promise$$internal$$GET_THEN_ERROR = new lib$es6$promise$$internal$$ErrorObject();\n\n function lib$es6$promise$$internal$$selfFullfillment() {\n return new TypeError(\"You cannot resolve a promise with itself\");\n }\n\n function lib$es6$promise$$internal$$cannotReturnOwn() {\n return new TypeError('A promises callback cannot return that same promise.');\n }\n\n function lib$es6$promise$$internal$$getThen(promise) {\n try {\n return promise.then;\n } catch(error) {\n lib$es6$promise$$internal$$GET_THEN_ERROR.error = error;\n return lib$es6$promise$$internal$$GET_THEN_ERROR;\n }\n }\n\n function lib$es6$promise$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) {\n try {\n then.call(value, fulfillmentHandler, rejectionHandler);\n } catch(e) {\n return e;\n }\n }\n\n function lib$es6$promise$$internal$$handleForeignThenable(promise, thenable, then) {\n lib$es6$promise$asap$$asap(function(promise) {\n var sealed = false;\n var error = lib$es6$promise$$internal$$tryThen(then, thenable, function(value) {\n if (sealed) { return; }\n sealed = true;\n if (thenable !== value) {\n lib$es6$promise$$internal$$resolve(promise, value);\n } else {\n lib$es6$promise$$internal$$fulfill(promise, value);\n }\n }, function(reason) {\n if (sealed) { return; }\n sealed = true;\n\n lib$es6$promise$$internal$$reject(promise, reason);\n }, 'Settle: ' + (promise._label || ' unknown promise'));\n\n if (!sealed && error) {\n sealed = true;\n lib$es6$promise$$internal$$reject(promise, error);\n }\n }, promise);\n }\n\n function lib$es6$promise$$internal$$handleOwnThenable(promise, thenable) {\n if (thenable._state === lib$es6$promise$$internal$$FULFILLED) {\n lib$es6$promise$$internal$$fulfill(promise, thenable._result);\n } else if (thenable._state === lib$es6$promise$$internal$$REJECTED) {\n lib$es6$promise$$internal$$reject(promise, thenable._result);\n } else {\n lib$es6$promise$$internal$$subscribe(thenable, undefined, function(value) {\n lib$es6$promise$$internal$$resolve(promise, value);\n }, function(reason) {\n lib$es6$promise$$internal$$reject(promise, reason);\n });\n }\n }\n\n function lib$es6$promise$$internal$$handleMaybeThenable(promise, maybeThenable) {\n if (maybeThenable.constructor === promise.constructor) {\n lib$es6$promise$$internal$$handleOwnThenable(promise, maybeThenable);\n } else {\n var then = lib$es6$promise$$internal$$getThen(maybeThenable);\n\n if (then === lib$es6$promise$$internal$$GET_THEN_ERROR) {\n lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$GET_THEN_ERROR.error);\n } else if (then === undefined) {\n lib$es6$promise$$internal$$fulfill(promise, maybeThenable);\n } else if (lib$es6$promise$utils$$isFunction(then)) {\n lib$es6$promise$$internal$$handleForeignThenable(promise, maybeThenable, then);\n } else {\n lib$es6$promise$$internal$$fulfill(promise, maybeThenable);\n }\n }\n }\n\n function lib$es6$promise$$internal$$resolve(promise, value) {\n if (promise === value) {\n lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$selfFullfillment());\n } else if (lib$es6$promise$utils$$objectOrFunction(value)) {\n lib$es6$promise$$internal$$handleMaybeThenable(promise, value);\n } else {\n lib$es6$promise$$internal$$fulfill(promise, value);\n }\n }\n\n function lib$es6$promise$$internal$$publishRejection(promise) {\n if (promise._onerror) {\n promise._onerror(promise._result);\n }\n\n lib$es6$promise$$internal$$publish(promise);\n }\n\n function lib$es6$promise$$internal$$fulfill(promise, value) {\n if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }\n\n promise._result = value;\n promise._state = lib$es6$promise$$internal$$FULFILLED;\n\n if (promise._subscribers.length !== 0) {\n lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, promise);\n }\n }\n\n function lib$es6$promise$$internal$$reject(promise, reason) {\n if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }\n promise._state = lib$es6$promise$$internal$$REJECTED;\n promise._result = reason;\n\n lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publishRejection, promise);\n }\n\n function lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection) {\n var subscribers = parent._subscribers;\n var length = subscribers.length;\n\n parent._onerror = null;\n\n subscribers[length] = child;\n subscribers[length + lib$es6$promise$$internal$$FULFILLED] = onFulfillment;\n subscribers[length + lib$es6$promise$$internal$$REJECTED] = onRejection;\n\n if (length === 0 && parent._state) {\n lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, parent);\n }\n }\n\n function lib$es6$promise$$internal$$publish(promise) {\n var subscribers = promise._subscribers;\n var settled = promise._state;\n\n if (subscribers.length === 0) { return; }\n\n var child, callback, detail = promise._result;\n\n for (var i = 0; i < subscribers.length; i += 3) {\n child = subscribers[i];\n callback = subscribers[i + settled];\n\n if (child) {\n lib$es6$promise$$internal$$invokeCallback(settled, child, callback, detail);\n } else {\n callback(detail);\n }\n }\n\n promise._subscribers.length = 0;\n }\n\n function lib$es6$promise$$internal$$ErrorObject() {\n this.error = null;\n }\n\n var lib$es6$promise$$internal$$TRY_CATCH_ERROR = new lib$es6$promise$$internal$$ErrorObject();\n\n function lib$es6$promise$$internal$$tryCatch(callback, detail) {\n try {\n return callback(detail);\n } catch(e) {\n lib$es6$promise$$internal$$TRY_CATCH_ERROR.error = e;\n return lib$es6$promise$$internal$$TRY_CATCH_ERROR;\n }\n }\n\n function lib$es6$promise$$internal$$invokeCallback(settled, promise, callback, detail) {\n var hasCallback = lib$es6$promise$utils$$isFunction(callback),\n value, error, succeeded, failed;\n\n if (hasCallback) {\n value = lib$es6$promise$$internal$$tryCatch(callback, detail);\n\n if (value === lib$es6$promise$$internal$$TRY_CATCH_ERROR) {\n failed = true;\n error = value.error;\n value = null;\n } else {\n succeeded = true;\n }\n\n if (promise === value) {\n lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$cannotReturnOwn());\n return;\n }\n\n } else {\n value = detail;\n succeeded = true;\n }\n\n if (promise._state !== lib$es6$promise$$internal$$PENDING) {\n // noop\n } else if (hasCallback && succeeded) {\n lib$es6$promise$$internal$$resolve(promise, value);\n } else if (failed) {\n lib$es6$promise$$internal$$reject(promise, error);\n } else if (settled === lib$es6$promise$$internal$$FULFILLED) {\n lib$es6$promise$$internal$$fulfill(promise, value);\n } else if (settled === lib$es6$promise$$internal$$REJECTED) {\n lib$es6$promise$$internal$$reject(promise, value);\n }\n }\n\n function lib$es6$promise$$internal$$initializePromise(promise, resolver) {\n try {\n resolver(function resolvePromise(value){\n lib$es6$promise$$internal$$resolve(promise, value);\n }, function rejectPromise(reason) {\n lib$es6$promise$$internal$$reject(promise, reason);\n });\n } catch(e) {\n lib$es6$promise$$internal$$reject(promise, e);\n }\n }\n\n function lib$es6$promise$enumerator$$Enumerator(Constructor, input) {\n var enumerator = this;\n\n enumerator._instanceConstructor = Constructor;\n enumerator.promise = new Constructor(lib$es6$promise$$internal$$noop);\n\n if (enumerator._validateInput(input)) {\n enumerator._input = input;\n enumerator.length = input.length;\n enumerator._remaining = input.length;\n\n enumerator._init();\n\n if (enumerator.length === 0) {\n lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);\n } else {\n enumerator.length = enumerator.length || 0;\n enumerator._enumerate();\n if (enumerator._remaining === 0) {\n lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);\n }\n }\n } else {\n lib$es6$promise$$internal$$reject(enumerator.promise, enumerator._validationError());\n }\n }\n\n lib$es6$promise$enumerator$$Enumerator.prototype._validateInput = function(input) {\n return lib$es6$promise$utils$$isArray(input);\n };\n\n lib$es6$promise$enumerator$$Enumerator.prototype._validationError = function() {\n return new Error('Array Methods must be provided an Array');\n };\n\n lib$es6$promise$enumerator$$Enumerator.prototype._init = function() {\n this._result = new Array(this.length);\n };\n\n var lib$es6$promise$enumerator$$default = lib$es6$promise$enumerator$$Enumerator;\n\n lib$es6$promise$enumerator$$Enumerator.prototype._enumerate = function() {\n var enumerator = this;\n\n var length = enumerator.length;\n var promise = enumerator.promise;\n var input = enumerator._input;\n\n for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {\n enumerator._eachEntry(input[i], i);\n }\n };\n\n lib$es6$promise$enumerator$$Enumerator.prototype._eachEntry = function(entry, i) {\n var enumerator = this;\n var c = enumerator._instanceConstructor;\n\n if (lib$es6$promise$utils$$isMaybeThenable(entry)) {\n if (entry.constructor === c && entry._state !== lib$es6$promise$$internal$$PENDING) {\n entry._onerror = null;\n enumerator._settledAt(entry._state, i, entry._result);\n } else {\n enumerator._willSettleAt(c.resolve(entry), i);\n }\n } else {\n enumerator._remaining--;\n enumerator._result[i] = entry;\n }\n };\n\n lib$es6$promise$enumerator$$Enumerator.prototype._settledAt = function(state, i, value) {\n var enumerator = this;\n var promise = enumerator.promise;\n\n if (promise._state === lib$es6$promise$$internal$$PENDING) {\n enumerator._remaining--;\n\n if (state === lib$es6$promise$$internal$$REJECTED) {\n lib$es6$promise$$internal$$reject(promise, value);\n } else {\n enumerator._result[i] = value;\n }\n }\n\n if (enumerator._remaining === 0) {\n lib$es6$promise$$internal$$fulfill(promise, enumerator._result);\n }\n };\n\n lib$es6$promise$enumerator$$Enumerator.prototype._willSettleAt = function(promise, i) {\n var enumerator = this;\n\n lib$es6$promise$$internal$$subscribe(promise, undefined, function(value) {\n enumerator._settledAt(lib$es6$promise$$internal$$FULFILLED, i, value);\n }, function(reason) {\n enumerator._settledAt(lib$es6$promise$$internal$$REJECTED, i, reason);\n });\n };\n function lib$es6$promise$promise$all$$all(entries) {\n return new lib$es6$promise$enumerator$$default(this, entries).promise;\n }\n var lib$es6$promise$promise$all$$default = lib$es6$promise$promise$all$$all;\n function lib$es6$promise$promise$race$$race(entries) {\n /*jshint validthis:true */\n var Constructor = this;\n\n var promise = new Constructor(lib$es6$promise$$internal$$noop);\n\n if (!lib$es6$promise$utils$$isArray(entries)) {\n lib$es6$promise$$internal$$reject(promise, new TypeError('You must pass an array to race.'));\n return promise;\n }\n\n var length = entries.length;\n\n function onFulfillment(value) {\n lib$es6$promise$$internal$$resolve(promise, value);\n }\n\n function onRejection(reason) {\n lib$es6$promise$$internal$$reject(promise, reason);\n }\n\n for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {\n lib$es6$promise$$internal$$subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);\n }\n\n return promise;\n }\n var lib$es6$promise$promise$race$$default = lib$es6$promise$promise$race$$race;\n function lib$es6$promise$promise$resolve$$resolve(object) {\n /*jshint validthis:true */\n var Constructor = this;\n\n if (object && typeof object === 'object' && object.constructor === Constructor) {\n return object;\n }\n\n var promise = new Constructor(lib$es6$promise$$internal$$noop);\n lib$es6$promise$$internal$$resolve(promise, object);\n return promise;\n }\n var lib$es6$promise$promise$resolve$$default = lib$es6$promise$promise$resolve$$resolve;\n function lib$es6$promise$promise$reject$$reject(reason) {\n /*jshint validthis:true */\n var Constructor = this;\n var promise = new Constructor(lib$es6$promise$$internal$$noop);\n lib$es6$promise$$internal$$reject(promise, reason);\n return promise;\n }\n var lib$es6$promise$promise$reject$$default = lib$es6$promise$promise$reject$$reject;\n\n var lib$es6$promise$promise$$counter = 0;\n\n function lib$es6$promise$promise$$needsResolver() {\n throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');\n }\n\n function lib$es6$promise$promise$$needsNew() {\n throw new TypeError(\"Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.\");\n }\n\n var lib$es6$promise$promise$$default = lib$es6$promise$promise$$Promise;\n /**\n Promise objects represent the eventual result of an asynchronous operation. The\n primary way of interacting with a promise is through its `then` method, which\n registers callbacks to receive either a promise's eventual value or the reason\n why the promise cannot be fulfilled.\n\n Terminology\n -----------\n\n - `promise` is an object or function with a `then` method whose behavior conforms to this specification.\n - `thenable` is an object or function that defines a `then` method.\n - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).\n - `exception` is a value that is thrown using the throw statement.\n - `reason` is a value that indicates why a promise was rejected.\n - `settled` the final resting state of a promise, fulfilled or rejected.\n\n A promise can be in one of three states: pending, fulfilled, or rejected.\n\n Promises that are fulfilled have a fulfillment value and are in the fulfilled\n state. Promises that are rejected have a rejection reason and are in the\n rejected state. A fulfillment value is never a thenable.\n\n Promises can also be said to *resolve* a value. If this value is also a\n promise, then the original promise's settled state will match the value's\n settled state. So a promise that *resolves* a promise that rejects will\n itself reject, and a promise that *resolves* a promise that fulfills will\n itself fulfill.\n\n\n Basic Usage:\n ------------\n\n ```js\n var promise = new Promise(function(resolve, reject) {\n // on success\n resolve(value);\n\n // on failure\n reject(reason);\n });\n\n promise.then(function(value) {\n // on fulfillment\n }, function(reason) {\n // on rejection\n });\n ```\n\n Advanced Usage:\n ---------------\n\n Promises shine when abstracting away asynchronous interactions such as\n `XMLHttpRequest`s.\n\n ```js\n function getJSON(url) {\n return new Promise(function(resolve, reject){\n var xhr = new XMLHttpRequest();\n\n xhr.open('GET', url);\n xhr.onreadystatechange = handler;\n xhr.responseType = 'json';\n xhr.setRequestHeader('Accept', 'application/json');\n xhr.send();\n\n function handler() {\n if (this.readyState === this.DONE) {\n if (this.status === 200) {\n resolve(this.response);\n } else {\n reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));\n }\n }\n };\n });\n }\n\n getJSON('/posts.json').then(function(json) {\n // on fulfillment\n }, function(reason) {\n // on rejection\n });\n ```\n\n Unlike callbacks, promises are great composable primitives.\n\n ```js\n Promise.all([\n getJSON('/posts'),\n getJSON('/comments')\n ]).then(function(values){\n values[0] // => postsJSON\n values[1] // => commentsJSON\n\n return values;\n });\n ```\n\n @class Promise\n @param {function} resolver\n Useful for tooling.\n @constructor\n */\n function lib$es6$promise$promise$$Promise(resolver) {\n this._id = lib$es6$promise$promise$$counter++;\n this._state = undefined;\n this._result = undefined;\n this._subscribers = [];\n\n if (lib$es6$promise$$internal$$noop !== resolver) {\n if (!lib$es6$promise$utils$$isFunction(resolver)) {\n lib$es6$promise$promise$$needsResolver();\n }\n\n if (!(this instanceof lib$es6$promise$promise$$Promise)) {\n lib$es6$promise$promise$$needsNew();\n }\n\n lib$es6$promise$$internal$$initializePromise(this, resolver);\n }\n }\n\n lib$es6$promise$promise$$Promise.all = lib$es6$promise$promise$all$$default;\n lib$es6$promise$promise$$Promise.race = lib$es6$promise$promise$race$$default;\n lib$es6$promise$promise$$Promise.resolve = lib$es6$promise$promise$resolve$$default;\n lib$es6$promise$promise$$Promise.reject = lib$es6$promise$promise$reject$$default;\n lib$es6$promise$promise$$Promise._setScheduler = lib$es6$promise$asap$$setScheduler;\n lib$es6$promise$promise$$Promise._setAsap = lib$es6$promise$asap$$setAsap;\n lib$es6$promise$promise$$Promise._asap = lib$es6$promise$asap$$asap;\n\n lib$es6$promise$promise$$Promise.prototype = {\n constructor: lib$es6$promise$promise$$Promise,\n\n /**\n The primary way of interacting with a promise is through its `then` method,\n which registers callbacks to receive either a promise's eventual value or the\n reason why the promise cannot be fulfilled.\n\n ```js\n findUser().then(function(user){\n // user is available\n }, function(reason){\n // user is unavailable, and you are given the reason why\n });\n ```\n\n Chaining\n --------\n\n The return value of `then` is itself a promise. This second, 'downstream'\n promise is resolved with the return value of the first promise's fulfillment\n or rejection handler, or rejected if the handler throws an exception.\n\n ```js\n findUser().then(function (user) {\n return user.name;\n }, function (reason) {\n return 'default name';\n }).then(function (userName) {\n // If `findUser` fulfilled, `userName` will be the user's name, otherwise it\n // will be `'default name'`\n });\n\n findUser().then(function (user) {\n throw new Error('Found user, but still unhappy');\n }, function (reason) {\n throw new Error('`findUser` rejected and we're unhappy');\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.\n // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.\n });\n ```\n If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.\n\n ```js\n findUser().then(function (user) {\n throw new PedagogicalException('Upstream error');\n }).then(function (value) {\n // never reached\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // The `PedgagocialException` is propagated all the way down to here\n });\n ```\n\n Assimilation\n ------------\n\n Sometimes the value you want to propagate to a downstream promise can only be\n retrieved asynchronously. This can be achieved by returning a promise in the\n fulfillment or rejection handler. The downstream promise will then be pending\n until the returned promise is settled. This is called *assimilation*.\n\n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // The user's comments are now available\n });\n ```\n\n If the assimliated promise rejects, then the downstream promise will also reject.\n\n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // If `findCommentsByAuthor` fulfills, we'll have the value here\n }, function (reason) {\n // If `findCommentsByAuthor` rejects, we'll have the reason here\n });\n ```\n\n Simple Example\n --------------\n\n Synchronous Example\n\n ```javascript\n var result;\n\n try {\n result = findResult();\n // success\n } catch(reason) {\n // failure\n }\n ```\n\n Errback Example\n\n ```js\n findResult(function(result, err){\n if (err) {\n // failure\n } else {\n // success\n }\n });\n ```\n\n Promise Example;\n\n ```javascript\n findResult().then(function(result){\n // success\n }, function(reason){\n // failure\n });\n ```\n\n Advanced Example\n --------------\n\n Synchronous Example\n\n ```javascript\n var author, books;\n\n try {\n author = findAuthor();\n books = findBooksByAuthor(author);\n // success\n } catch(reason) {\n // failure\n }\n ```\n\n Errback Example\n\n ```js\n\n function foundBooks(books) {\n\n }\n\n function failure(reason) {\n\n }\n\n findAuthor(function(author, err){\n if (err) {\n failure(err);\n // failure\n } else {\n try {\n findBoooksByAuthor(author, function(books, err) {\n if (err) {\n failure(err);\n } else {\n try {\n foundBooks(books);\n } catch(reason) {\n failure(reason);\n }\n }\n });\n } catch(error) {\n failure(err);\n }\n // success\n }\n });\n ```\n\n Promise Example;\n\n ```javascript\n findAuthor().\n then(findBooksByAuthor).\n then(function(books){\n // found books\n }).catch(function(reason){\n // something went wrong\n });\n ```\n\n @method then\n @param {Function} onFulfilled\n @param {Function} onRejected\n Useful for tooling.\n @return {Promise}\n */\n then: function(onFulfillment, onRejection) {\n var parent = this;\n var state = parent._state;\n\n if (state === lib$es6$promise$$internal$$FULFILLED && !onFulfillment || state === lib$es6$promise$$internal$$REJECTED && !onRejection) {\n return this;\n }\n\n var child = new this.constructor(lib$es6$promise$$internal$$noop);\n var result = parent._result;\n\n if (state) {\n var callback = arguments[state - 1];\n lib$es6$promise$asap$$asap(function(){\n lib$es6$promise$$internal$$invokeCallback(state, child, callback, result);\n });\n } else {\n lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection);\n }\n\n return child;\n },\n\n /**\n `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same\n as the catch block of a try/catch statement.\n\n ```js\n function findAuthor(){\n throw new Error('couldn't find that author');\n }\n\n // synchronous\n try {\n findAuthor();\n } catch(reason) {\n // something went wrong\n }\n\n // async with promises\n findAuthor().catch(function(reason){\n // something went wrong\n });\n ```\n\n @method catch\n @param {Function} onRejection\n Useful for tooling.\n @return {Promise}\n */\n 'catch': function(onRejection) {\n return this.then(null, onRejection);\n }\n };\n function lib$es6$promise$polyfill$$polyfill() {\n var local;\n\n if (typeof global !== 'undefined') {\n local = global;\n } else if (typeof self !== 'undefined') {\n local = self;\n } else {\n try {\n local = Function('return this')();\n } catch (e) {\n throw new Error('polyfill failed because global object is unavailable in this environment');\n }\n }\n\n var P = local.Promise;\n\n if (P && Object.prototype.toString.call(P.resolve()) === '[object Promise]' && !P.cast) {\n return;\n }\n\n local.Promise = lib$es6$promise$promise$$default;\n }\n var lib$es6$promise$polyfill$$default = lib$es6$promise$polyfill$$polyfill;\n\n var lib$es6$promise$umd$$ES6Promise = {\n 'Promise': lib$es6$promise$promise$$default,\n 'polyfill': lib$es6$promise$polyfill$$default\n };\n\n /* global define:true module:true window: true */\n if (typeof define === 'function' && define['amd']) {\n define(function() { return lib$es6$promise$umd$$ES6Promise; });\n } else if (typeof module !== 'undefined' && module['exports']) {\n module['exports'] = lib$es6$promise$umd$$ES6Promise;\n } else if (typeof this !== 'undefined') {\n this['ES6Promise'] = lib$es6$promise$umd$$ES6Promise;\n }\n\n lib$es6$promise$polyfill$$default();\n}).call(this);\n\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/es6-promise/dist/es6-promise.js\n ** module id = 22\n ** module chunks = 0\n **/","var nextTick = require('process/browser.js').nextTick;\nvar apply = Function.prototype.apply;\nvar slice = Array.prototype.slice;\nvar immediateIds = {};\nvar nextImmediateId = 0;\n\n// DOM APIs, for completeness\n\nexports.setTimeout = function() {\n return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);\n};\nexports.setInterval = function() {\n return new Timeout(apply.call(setInterval, window, arguments), clearInterval);\n};\nexports.clearTimeout =\nexports.clearInterval = function(timeout) { timeout.close(); };\n\nfunction Timeout(id, clearFn) {\n this._id = id;\n this._clearFn = clearFn;\n}\nTimeout.prototype.unref = Timeout.prototype.ref = function() {};\nTimeout.prototype.close = function() {\n this._clearFn.call(window, this._id);\n};\n\n// Does not start the time, just sets up the members needed.\nexports.enroll = function(item, msecs) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = msecs;\n};\n\nexports.unenroll = function(item) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = -1;\n};\n\nexports._unrefActive = exports.active = function(item) {\n clearTimeout(item._idleTimeoutId);\n\n var msecs = item._idleTimeout;\n if (msecs >= 0) {\n item._idleTimeoutId = setTimeout(function onTimeout() {\n if (item._onTimeout)\n item._onTimeout();\n }, msecs);\n }\n};\n\n// That's not how node.js implements it but the exposed api is the same.\nexports.setImmediate = typeof setImmediate === \"function\" ? setImmediate : function(fn) {\n var id = nextImmediateId++;\n var args = arguments.length < 2 ? false : slice.call(arguments, 1);\n\n immediateIds[id] = true;\n\n nextTick(function onNextTick() {\n if (immediateIds[id]) {\n // fn.call() is faster so we optimize for the common use-case\n // @see http://jsperf.com/call-apply-segu\n if (args) {\n fn.apply(null, args);\n } else {\n fn.call(null);\n }\n // Prevent ids from leaking\n exports.clearImmediate(id);\n }\n });\n\n return id;\n};\n\nexports.clearImmediate = typeof clearImmediate === \"function\" ? clearImmediate : function(id) {\n delete immediateIds[id];\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/timers-browserify/main.js\n ** module id = 23\n ** module chunks = 0\n **/","/* (ignored) */\n\n\n/*****************\n ** WEBPACK FOOTER\n ** vertx (ignored)\n ** module id = 24\n ** module chunks = 0\n **/","module.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** (webpack)/buildin/amd-define.js\n ** module id = 25\n ** module chunks = 0\n **/","'use strict';\n\n/**\n * Syntactic sugar for invoking a function and expanding an array for arguments.\n *\n * Common use case would be to use `Function.prototype.apply`.\n *\n * ```js\n * function f(x, y, z) {}\n * var args = [1, 2, 3];\n * f.apply(null, args);\n * ```\n *\n * With `spread` this example can be re-written.\n *\n * ```js\n * spread(function(x, y, z) {})([1, 2, 3]);\n * ```\n *\n * @param {Function} callback\n * @returns {Function}\n */\nmodule.exports = function spread(callback) {\n return function (arr) {\n callback.apply(null, arr);\n };\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/axios/lib/helpers/spread.js\n ** module id = 26\n ** module chunks = 0\n **/","/*! http://mths.be/base64 v0.1.0 by @mathias | MIT license */\n;(function(root) {\n\n\t// Detect free variables `exports`.\n\tvar freeExports = typeof exports == 'object' && exports;\n\n\t// Detect free variable `module`.\n\tvar freeModule = typeof module == 'object' && module &&\n\t\tmodule.exports == freeExports && module;\n\n\t// Detect free variable `global`, from Node.js or Browserified code, and use\n\t// it as `root`.\n\tvar freeGlobal = typeof global == 'object' && global;\n\tif (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {\n\t\troot = freeGlobal;\n\t}\n\n\t/*--------------------------------------------------------------------------*/\n\n\tvar InvalidCharacterError = function(message) {\n\t\tthis.message = message;\n\t};\n\tInvalidCharacterError.prototype = new Error;\n\tInvalidCharacterError.prototype.name = 'InvalidCharacterError';\n\n\tvar error = function(message) {\n\t\t// Note: the error messages used throughout this file match those used by\n\t\t// the native `atob`/`btoa` implementation in Chromium.\n\t\tthrow new InvalidCharacterError(message);\n\t};\n\n\tvar TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\t// http://whatwg.org/html/common-microsyntaxes.html#space-character\n\tvar REGEX_SPACE_CHARACTERS = /[\\t\\n\\f\\r ]/g;\n\n\t// `decode` is designed to be fully compatible with `atob` as described in the\n\t// HTML Standard. http://whatwg.org/html/webappapis.html#dom-windowbase64-atob\n\t// The optimized base64-decoding algorithm used is based on @atk’s excellent\n\t// implementation. https://gist.github.com/atk/1020396\n\tvar decode = function(input) {\n\t\tinput = String(input)\n\t\t\t.replace(REGEX_SPACE_CHARACTERS, '');\n\t\tvar length = input.length;\n\t\tif (length % 4 == 0) {\n\t\t\tinput = input.replace(/==?$/, '');\n\t\t\tlength = input.length;\n\t\t}\n\t\tif (\n\t\t\tlength % 4 == 1 ||\n\t\t\t// http://whatwg.org/C#alphanumeric-ascii-characters\n\t\t\t/[^+a-zA-Z0-9/]/.test(input)\n\t\t) {\n\t\t\terror(\n\t\t\t\t'Invalid character: the string to be decoded is not correctly encoded.'\n\t\t\t);\n\t\t}\n\t\tvar bitCounter = 0;\n\t\tvar bitStorage;\n\t\tvar buffer;\n\t\tvar output = '';\n\t\tvar position = -1;\n\t\twhile (++position < length) {\n\t\t\tbuffer = TABLE.indexOf(input.charAt(position));\n\t\t\tbitStorage = bitCounter % 4 ? bitStorage * 64 + buffer : buffer;\n\t\t\t// Unless this is the first of a group of 4 characters…\n\t\t\tif (bitCounter++ % 4) {\n\t\t\t\t// …convert the first 8 bits to a single ASCII character.\n\t\t\t\toutput += String.fromCharCode(\n\t\t\t\t\t0xFF & bitStorage >> (-2 * bitCounter & 6)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t};\n\n\t// `encode` is designed to be fully compatible with `btoa` as described in the\n\t// HTML Standard: http://whatwg.org/html/webappapis.html#dom-windowbase64-btoa\n\tvar encode = function(input) {\n\t\tinput = String(input);\n\t\tif (/[^\\0-\\xFF]/.test(input)) {\n\t\t\t// Note: no need to special-case astral symbols here, as surrogates are\n\t\t\t// matched, and the input is supposed to only contain ASCII anyway.\n\t\t\terror(\n\t\t\t\t'The string to be encoded contains characters outside of the ' +\n\t\t\t\t'Latin1 range.'\n\t\t\t);\n\t\t}\n\t\tvar padding = input.length % 3;\n\t\tvar output = '';\n\t\tvar position = -1;\n\t\tvar a;\n\t\tvar b;\n\t\tvar c;\n\t\tvar d;\n\t\tvar buffer;\n\t\t// Make sure any padding is handled outside of the loop.\n\t\tvar length = input.length - padding;\n\n\t\twhile (++position < length) {\n\t\t\t// Read three bytes, i.e. 24 bits.\n\t\t\ta = input.charCodeAt(position) << 16;\n\t\t\tb = input.charCodeAt(++position) << 8;\n\t\t\tc = input.charCodeAt(++position);\n\t\t\tbuffer = a + b + c;\n\t\t\t// Turn the 24 bits into four chunks of 6 bits each, and append the\n\t\t\t// matching character for each of them to the output.\n\t\t\toutput += (\n\t\t\t\tTABLE.charAt(buffer >> 18 & 0x3F) +\n\t\t\t\tTABLE.charAt(buffer >> 12 & 0x3F) +\n\t\t\t\tTABLE.charAt(buffer >> 6 & 0x3F) +\n\t\t\t\tTABLE.charAt(buffer & 0x3F)\n\t\t\t);\n\t\t}\n\n\t\tif (padding == 2) {\n\t\t\ta = input.charCodeAt(position) << 8;\n\t\t\tb = input.charCodeAt(++position);\n\t\t\tbuffer = a + b;\n\t\t\toutput += (\n\t\t\t\tTABLE.charAt(buffer >> 10) +\n\t\t\t\tTABLE.charAt((buffer >> 4) & 0x3F) +\n\t\t\t\tTABLE.charAt((buffer << 2) & 0x3F) +\n\t\t\t\t'='\n\t\t\t);\n\t\t} else if (padding == 1) {\n\t\t\tbuffer = input.charCodeAt(position);\n\t\t\toutput += (\n\t\t\t\tTABLE.charAt(buffer >> 2) +\n\t\t\t\tTABLE.charAt((buffer << 4) & 0x3F) +\n\t\t\t\t'=='\n\t\t\t);\n\t\t}\n\n\t\treturn output;\n\t};\n\n\tvar base64 = {\n\t\t'encode': encode,\n\t\t'decode': decode,\n\t\t'version': '0.1.0'\n\t};\n\n\t// Some AMD build optimizers, like r.js, check for specific condition patterns\n\t// like the following:\n\tif (\n\t\ttypeof define == 'function' &&\n\t\ttypeof define.amd == 'object' &&\n\t\tdefine.amd\n\t) {\n\t\tdefine(function() {\n\t\t\treturn base64;\n\t\t});\n\t}\telse if (freeExports && !freeExports.nodeType) {\n\t\tif (freeModule) { // in Node.js or RingoJS v0.8.0+\n\t\t\tfreeModule.exports = base64;\n\t\t} else { // in Narwhal or RingoJS v0.7.0-\n\t\t\tfor (var key in base64) {\n\t\t\t\tbase64.hasOwnProperty(key) && (freeExports[key] = base64[key]);\n\t\t\t}\n\t\t}\n\t} else { // in Rhino or a web browser\n\t\troot.base64 = base64;\n\t}\n\n}(this));\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/base-64/base64.js\n ** module id = 27\n ** module chunks = 0\n **/","// =========\n// = humps =\n// =========\n// version 0.7.0\n// Underscore-to-camelCase converter (and vice versa)\n// for strings and object keys\n\n// humps is copyright © 2012+ Dom Christie\n// Released under the MIT license.\n\n\n;(function(global) {\n\n var _processKeys = function(convert, obj, separator, ignoreNumbers) {\n if(!_isObject(obj) || _isDate(obj) || _isRegExp(obj) || _isBoolean(obj)) {\n return obj;\n }\n\n var output,\n i = 0,\n l = 0;\n\n if(_isArray(obj)) {\n output = [];\n for(l=obj.length; i tag\n\n// load the styles\nvar content = require(\"!!./../../css-loader/index.js?minimize!./../../autoprefixer-loader/index.js!./fullcalendar.css\");\nif(typeof content === 'string') content = [[module.id, content, '']];\n// add the styles to the DOM\nvar update = require(\"!./../../style-loader/addStyles.js\")(content, {\"singleton\":true});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(module.hot) {\n\t// When the styles change, update the