: https://github.com/nicolaidavies\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var ss = moment.defineLocale('ss', {\n\t months: \"Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni\".split(\n\t '_'\n\t ),\n\t monthsShort: 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'),\n\t weekdays: 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split(\n\t '_'\n\t ),\n\t weekdaysShort: 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'),\n\t weekdaysMin: 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'),\n\t weekdaysParseExact: true,\n\t longDateFormat: {\n\t LT: 'h:mm A',\n\t LTS: 'h:mm:ss A',\n\t L: 'DD/MM/YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY h:mm A',\n\t LLLL: 'dddd, D MMMM YYYY h:mm A',\n\t },\n\t calendar: {\n\t sameDay: '[Namuhla nga] LT',\n\t nextDay: '[Kusasa nga] LT',\n\t nextWeek: 'dddd [nga] LT',\n\t lastDay: '[Itolo nga] LT',\n\t lastWeek: 'dddd [leliphelile] [nga] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: 'nga %s',\n\t past: 'wenteka nga %s',\n\t s: 'emizuzwana lomcane',\n\t ss: '%d mzuzwana',\n\t m: 'umzuzu',\n\t mm: '%d emizuzu',\n\t h: 'lihora',\n\t hh: '%d emahora',\n\t d: 'lilanga',\n\t dd: '%d emalanga',\n\t M: 'inyanga',\n\t MM: '%d tinyanga',\n\t y: 'umnyaka',\n\t yy: '%d iminyaka',\n\t },\n\t meridiemParse: /ekuseni|emini|entsambama|ebusuku/,\n\t meridiem: function (hours, minutes, isLower) {\n\t if (hours < 11) {\n\t return 'ekuseni';\n\t } else if (hours < 15) {\n\t return 'emini';\n\t } else if (hours < 19) {\n\t return 'entsambama';\n\t } else {\n\t return 'ebusuku';\n\t }\n\t },\n\t meridiemHour: function (hour, meridiem) {\n\t if (hour === 12) {\n\t hour = 0;\n\t }\n\t if (meridiem === 'ekuseni') {\n\t return hour;\n\t } else if (meridiem === 'emini') {\n\t return hour >= 11 ? hour : hour + 12;\n\t } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') {\n\t if (hour === 0) {\n\t return 0;\n\t }\n\t return hour + 12;\n\t }\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}/,\n\t ordinal: '%d',\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 4, // The week that contains Jan 4th is the first week of the year.\n\t },\n\t });\n\t\n\t return ss;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 414:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Swedish [sv]\n\t//! author : Jens Alm : https://github.com/ulmus\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var sv = moment.defineLocale('sv', {\n\t months: 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split(\n\t '_'\n\t ),\n\t monthsShort: 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n\t weekdays: 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),\n\t weekdaysShort: 'sön_mån_tis_ons_tor_fre_lör'.split('_'),\n\t weekdaysMin: 'sö_må_ti_on_to_fr_lö'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'YYYY-MM-DD',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY [kl.] HH:mm',\n\t LLLL: 'dddd D MMMM YYYY [kl.] HH:mm',\n\t lll: 'D MMM YYYY HH:mm',\n\t llll: 'ddd D MMM YYYY HH:mm',\n\t },\n\t calendar: {\n\t sameDay: '[Idag] LT',\n\t nextDay: '[Imorgon] LT',\n\t lastDay: '[Igår] LT',\n\t nextWeek: '[På] dddd LT',\n\t lastWeek: '[I] dddd[s] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: 'om %s',\n\t past: 'för %s sedan',\n\t s: 'några sekunder',\n\t ss: '%d sekunder',\n\t m: 'en minut',\n\t mm: '%d minuter',\n\t h: 'en timme',\n\t hh: '%d timmar',\n\t d: 'en dag',\n\t dd: '%d dagar',\n\t M: 'en månad',\n\t MM: '%d månader',\n\t y: 'ett år',\n\t yy: '%d år',\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}(\\:e|\\:a)/,\n\t ordinal: function (number) {\n\t var b = number % 10,\n\t output =\n\t ~~((number % 100) / 10) === 1\n\t ? ':e'\n\t : b === 1\n\t ? ':a'\n\t : b === 2\n\t ? ':a'\n\t : b === 3\n\t ? ':e'\n\t : ':e';\n\t return number + output;\n\t },\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 4, // The week that contains Jan 4th is the first week of the year.\n\t },\n\t });\n\t\n\t return sv;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 415:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Swahili [sw]\n\t//! author : Fahad Kassim : https://github.com/fadsel\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var sw = moment.defineLocale('sw', {\n\t months: 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split(\n\t '_'\n\t ),\n\t monthsShort: 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'),\n\t weekdays: 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split(\n\t '_'\n\t ),\n\t weekdaysShort: 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'),\n\t weekdaysMin: 'J2_J3_J4_J5_Al_Ij_J1'.split('_'),\n\t weekdaysParseExact: true,\n\t longDateFormat: {\n\t LT: 'hh:mm A',\n\t LTS: 'HH:mm:ss',\n\t L: 'DD.MM.YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY HH:mm',\n\t LLLL: 'dddd, D MMMM YYYY HH:mm',\n\t },\n\t calendar: {\n\t sameDay: '[leo saa] LT',\n\t nextDay: '[kesho saa] LT',\n\t nextWeek: '[wiki ijayo] dddd [saat] LT',\n\t lastDay: '[jana] LT',\n\t lastWeek: '[wiki iliyopita] dddd [saat] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: '%s baadaye',\n\t past: 'tokea %s',\n\t s: 'hivi punde',\n\t ss: 'sekunde %d',\n\t m: 'dakika moja',\n\t mm: 'dakika %d',\n\t h: 'saa limoja',\n\t hh: 'masaa %d',\n\t d: 'siku moja',\n\t dd: 'siku %d',\n\t M: 'mwezi mmoja',\n\t MM: 'miezi %d',\n\t y: 'mwaka mmoja',\n\t yy: 'miaka %d',\n\t },\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 7, // The week that contains Jan 7th is the first week of the year.\n\t },\n\t });\n\t\n\t return sw;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 416:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Tamil [ta]\n\t//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var symbolMap = {\n\t 1: '௧',\n\t 2: '௨',\n\t 3: '௩',\n\t 4: '௪',\n\t 5: '௫',\n\t 6: '௬',\n\t 7: '௭',\n\t 8: '௮',\n\t 9: '௯',\n\t 0: '௦',\n\t },\n\t numberMap = {\n\t '௧': '1',\n\t '௨': '2',\n\t '௩': '3',\n\t '௪': '4',\n\t '௫': '5',\n\t '௬': '6',\n\t '௭': '7',\n\t '௮': '8',\n\t '௯': '9',\n\t '௦': '0',\n\t };\n\t\n\t var ta = moment.defineLocale('ta', {\n\t months: 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split(\n\t '_'\n\t ),\n\t monthsShort: 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split(\n\t '_'\n\t ),\n\t weekdays: 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split(\n\t '_'\n\t ),\n\t weekdaysShort: 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split(\n\t '_'\n\t ),\n\t weekdaysMin: 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'DD/MM/YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY, HH:mm',\n\t LLLL: 'dddd, D MMMM YYYY, HH:mm',\n\t },\n\t calendar: {\n\t sameDay: '[இன்று] LT',\n\t nextDay: '[நாளை] LT',\n\t nextWeek: 'dddd, LT',\n\t lastDay: '[நேற்று] LT',\n\t lastWeek: '[கடந்த வாரம்] dddd, LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: '%s இல்',\n\t past: '%s முன்',\n\t s: 'ஒரு சில விநாடிகள்',\n\t ss: '%d விநாடிகள்',\n\t m: 'ஒரு நிமிடம்',\n\t mm: '%d நிமிடங்கள்',\n\t h: 'ஒரு மணி நேரம்',\n\t hh: '%d மணி நேரம்',\n\t d: 'ஒரு நாள்',\n\t dd: '%d நாட்கள்',\n\t M: 'ஒரு மாதம்',\n\t MM: '%d மாதங்கள்',\n\t y: 'ஒரு வருடம்',\n\t yy: '%d ஆண்டுகள்',\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}வது/,\n\t ordinal: function (number) {\n\t return number + 'வது';\n\t },\n\t preparse: function (string) {\n\t return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) {\n\t return numberMap[match];\n\t });\n\t },\n\t postformat: function (string) {\n\t return string.replace(/\\d/g, function (match) {\n\t return symbolMap[match];\n\t });\n\t },\n\t // refer http://ta.wikipedia.org/s/1er1\n\t meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,\n\t meridiem: function (hour, minute, isLower) {\n\t if (hour < 2) {\n\t return ' யாமம்';\n\t } else if (hour < 6) {\n\t return ' வைகறை'; // வைகறை\n\t } else if (hour < 10) {\n\t return ' காலை'; // காலை\n\t } else if (hour < 14) {\n\t return ' நண்பகல்'; // நண்பகல்\n\t } else if (hour < 18) {\n\t return ' எற்பாடு'; // எற்பாடு\n\t } else if (hour < 22) {\n\t return ' மாலை'; // மாலை\n\t } else {\n\t return ' யாமம்';\n\t }\n\t },\n\t meridiemHour: function (hour, meridiem) {\n\t if (hour === 12) {\n\t hour = 0;\n\t }\n\t if (meridiem === 'யாமம்') {\n\t return hour < 2 ? hour : hour + 12;\n\t } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {\n\t return hour;\n\t } else if (meridiem === 'நண்பகல்') {\n\t return hour >= 10 ? hour : hour + 12;\n\t } else {\n\t return hour + 12;\n\t }\n\t },\n\t week: {\n\t dow: 0, // Sunday is the first day of the week.\n\t doy: 6, // The week that contains Jan 6th is the first week of the year.\n\t },\n\t });\n\t\n\t return ta;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 417:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Telugu [te]\n\t//! author : Krishna Chaitanya Thota : https://github.com/kcthota\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var te = moment.defineLocale('te', {\n\t months: 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జులై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split(\n\t '_'\n\t ),\n\t monthsShort: 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జులై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split(\n\t '_'\n\t ),\n\t monthsParseExact: true,\n\t weekdays: 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split(\n\t '_'\n\t ),\n\t weekdaysShort: 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'),\n\t weekdaysMin: 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'),\n\t longDateFormat: {\n\t LT: 'A h:mm',\n\t LTS: 'A h:mm:ss',\n\t L: 'DD/MM/YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY, A h:mm',\n\t LLLL: 'dddd, D MMMM YYYY, A h:mm',\n\t },\n\t calendar: {\n\t sameDay: '[నేడు] LT',\n\t nextDay: '[రేపు] LT',\n\t nextWeek: 'dddd, LT',\n\t lastDay: '[నిన్న] LT',\n\t lastWeek: '[గత] dddd, LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: '%s లో',\n\t past: '%s క్రితం',\n\t s: 'కొన్ని క్షణాలు',\n\t ss: '%d సెకన్లు',\n\t m: 'ఒక నిమిషం',\n\t mm: '%d నిమిషాలు',\n\t h: 'ఒక గంట',\n\t hh: '%d గంటలు',\n\t d: 'ఒక రోజు',\n\t dd: '%d రోజులు',\n\t M: 'ఒక నెల',\n\t MM: '%d నెలలు',\n\t y: 'ఒక సంవత్సరం',\n\t yy: '%d సంవత్సరాలు',\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}వ/,\n\t ordinal: '%dవ',\n\t meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,\n\t meridiemHour: function (hour, meridiem) {\n\t if (hour === 12) {\n\t hour = 0;\n\t }\n\t if (meridiem === 'రాత్రి') {\n\t return hour < 4 ? hour : hour + 12;\n\t } else if (meridiem === 'ఉదయం') {\n\t return hour;\n\t } else if (meridiem === 'మధ్యాహ్నం') {\n\t return hour >= 10 ? hour : hour + 12;\n\t } else if (meridiem === 'సాయంత్రం') {\n\t return hour + 12;\n\t }\n\t },\n\t meridiem: function (hour, minute, isLower) {\n\t if (hour < 4) {\n\t return 'రాత్రి';\n\t } else if (hour < 10) {\n\t return 'ఉదయం';\n\t } else if (hour < 17) {\n\t return 'మధ్యాహ్నం';\n\t } else if (hour < 20) {\n\t return 'సాయంత్రం';\n\t } else {\n\t return 'రాత్రి';\n\t }\n\t },\n\t week: {\n\t dow: 0, // Sunday is the first day of the week.\n\t doy: 6, // The week that contains Jan 6th is the first week of the year.\n\t },\n\t });\n\t\n\t return te;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 418:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Tetun Dili (East Timor) [tet]\n\t//! author : Joshua Brooks : https://github.com/joshbrooks\n\t//! author : Onorio De J. Afonso : https://github.com/marobo\n\t//! author : Sonia Simoes : https://github.com/soniasimoes\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var tet = moment.defineLocale('tet', {\n\t months: 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juñu_Jullu_Agustu_Setembru_Outubru_Novembru_Dezembru'.split(\n\t '_'\n\t ),\n\t monthsShort: 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n\t weekdays: 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sesta_Sabadu'.split('_'),\n\t weekdaysShort: 'Dom_Seg_Ters_Kua_Kint_Sest_Sab'.split('_'),\n\t weekdaysMin: 'Do_Seg_Te_Ku_Ki_Ses_Sa'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'DD/MM/YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY HH:mm',\n\t LLLL: 'dddd, D MMMM YYYY HH:mm',\n\t },\n\t calendar: {\n\t sameDay: '[Ohin iha] LT',\n\t nextDay: '[Aban iha] LT',\n\t nextWeek: 'dddd [iha] LT',\n\t lastDay: '[Horiseik iha] LT',\n\t lastWeek: 'dddd [semana kotuk] [iha] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: 'iha %s',\n\t past: '%s liuba',\n\t s: 'segundu balun',\n\t ss: 'segundu %d',\n\t m: 'minutu ida',\n\t mm: 'minutu %d',\n\t h: 'oras ida',\n\t hh: 'oras %d',\n\t d: 'loron ida',\n\t dd: 'loron %d',\n\t M: 'fulan ida',\n\t MM: 'fulan %d',\n\t y: 'tinan ida',\n\t yy: 'tinan %d',\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n\t ordinal: function (number) {\n\t var b = number % 10,\n\t output =\n\t ~~((number % 100) / 10) === 1\n\t ? 'th'\n\t : b === 1\n\t ? 'st'\n\t : b === 2\n\t ? 'nd'\n\t : b === 3\n\t ? 'rd'\n\t : 'th';\n\t return number + output;\n\t },\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 4, // The week that contains Jan 4th is the first week of the year.\n\t },\n\t });\n\t\n\t return tet;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 419:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Tajik [tg]\n\t//! author : Orif N. Jr. : https://github.com/orif-jr\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var suffixes = {\n\t 0: '-ум',\n\t 1: '-ум',\n\t 2: '-юм',\n\t 3: '-юм',\n\t 4: '-ум',\n\t 5: '-ум',\n\t 6: '-ум',\n\t 7: '-ум',\n\t 8: '-ум',\n\t 9: '-ум',\n\t 10: '-ум',\n\t 12: '-ум',\n\t 13: '-ум',\n\t 20: '-ум',\n\t 30: '-юм',\n\t 40: '-ум',\n\t 50: '-ум',\n\t 60: '-ум',\n\t 70: '-ум',\n\t 80: '-ум',\n\t 90: '-ум',\n\t 100: '-ум',\n\t };\n\t\n\t var tg = moment.defineLocale('tg', {\n\t months: {\n\t format: 'январи_феврали_марти_апрели_майи_июни_июли_августи_сентябри_октябри_ноябри_декабри'.split(\n\t '_'\n\t ),\n\t standalone: 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split(\n\t '_'\n\t ),\n\t },\n\t monthsShort: 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),\n\t weekdays: 'якшанбе_душанбе_сешанбе_чоршанбе_панҷшанбе_ҷумъа_шанбе'.split(\n\t '_'\n\t ),\n\t weekdaysShort: 'яшб_дшб_сшб_чшб_пшб_ҷум_шнб'.split('_'),\n\t weekdaysMin: 'яш_дш_сш_чш_пш_ҷм_шб'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'DD.MM.YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY HH:mm',\n\t LLLL: 'dddd, D MMMM YYYY HH:mm',\n\t },\n\t calendar: {\n\t sameDay: '[Имрӯз соати] LT',\n\t nextDay: '[Фардо соати] LT',\n\t lastDay: '[Дирӯз соати] LT',\n\t nextWeek: 'dddd[и] [ҳафтаи оянда соати] LT',\n\t lastWeek: 'dddd[и] [ҳафтаи гузашта соати] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: 'баъди %s',\n\t past: '%s пеш',\n\t s: 'якчанд сония',\n\t m: 'як дақиқа',\n\t mm: '%d дақиқа',\n\t h: 'як соат',\n\t hh: '%d соат',\n\t d: 'як рӯз',\n\t dd: '%d рӯз',\n\t M: 'як моҳ',\n\t MM: '%d моҳ',\n\t y: 'як сол',\n\t yy: '%d сол',\n\t },\n\t meridiemParse: /шаб|субҳ|рӯз|бегоҳ/,\n\t meridiemHour: function (hour, meridiem) {\n\t if (hour === 12) {\n\t hour = 0;\n\t }\n\t if (meridiem === 'шаб') {\n\t return hour < 4 ? hour : hour + 12;\n\t } else if (meridiem === 'субҳ') {\n\t return hour;\n\t } else if (meridiem === 'рӯз') {\n\t return hour >= 11 ? hour : hour + 12;\n\t } else if (meridiem === 'бегоҳ') {\n\t return hour + 12;\n\t }\n\t },\n\t meridiem: function (hour, minute, isLower) {\n\t if (hour < 4) {\n\t return 'шаб';\n\t } else if (hour < 11) {\n\t return 'субҳ';\n\t } else if (hour < 16) {\n\t return 'рӯз';\n\t } else if (hour < 19) {\n\t return 'бегоҳ';\n\t } else {\n\t return 'шаб';\n\t }\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}-(ум|юм)/,\n\t ordinal: function (number) {\n\t var a = number % 10,\n\t b = number >= 100 ? 100 : null;\n\t return number + (suffixes[number] || suffixes[a] || suffixes[b]);\n\t },\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 7, // The week that contains Jan 1th is the first week of the year.\n\t },\n\t });\n\t\n\t return tg;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 420:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Thai [th]\n\t//! author : Kridsada Thanabulpong : https://github.com/sirn\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var th = moment.defineLocale('th', {\n\t months: 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split(\n\t '_'\n\t ),\n\t monthsShort: 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split(\n\t '_'\n\t ),\n\t monthsParseExact: true,\n\t weekdays: 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),\n\t weekdaysShort: 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference\n\t weekdaysMin: 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),\n\t weekdaysParseExact: true,\n\t longDateFormat: {\n\t LT: 'H:mm',\n\t LTS: 'H:mm:ss',\n\t L: 'DD/MM/YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY เวลา H:mm',\n\t LLLL: 'วันddddที่ D MMMM YYYY เวลา H:mm',\n\t },\n\t meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,\n\t isPM: function (input) {\n\t return input === 'หลังเที่ยง';\n\t },\n\t meridiem: function (hour, minute, isLower) {\n\t if (hour < 12) {\n\t return 'ก่อนเที่ยง';\n\t } else {\n\t return 'หลังเที่ยง';\n\t }\n\t },\n\t calendar: {\n\t sameDay: '[วันนี้ เวลา] LT',\n\t nextDay: '[พรุ่งนี้ เวลา] LT',\n\t nextWeek: 'dddd[หน้า เวลา] LT',\n\t lastDay: '[เมื่อวานนี้ เวลา] LT',\n\t lastWeek: '[วัน]dddd[ที่แล้ว เวลา] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: 'อีก %s',\n\t past: '%sที่แล้ว',\n\t s: 'ไม่กี่วินาที',\n\t ss: '%d วินาที',\n\t m: '1 นาที',\n\t mm: '%d นาที',\n\t h: '1 ชั่วโมง',\n\t hh: '%d ชั่วโมง',\n\t d: '1 วัน',\n\t dd: '%d วัน',\n\t w: '1 สัปดาห์',\n\t ww: '%d สัปดาห์',\n\t M: '1 เดือน',\n\t MM: '%d เดือน',\n\t y: '1 ปี',\n\t yy: '%d ปี',\n\t },\n\t });\n\t\n\t return th;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 421:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Turkmen [tk]\n\t//! author : Atamyrat Abdyrahmanov : https://github.com/atamyratabdy\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var suffixes = {\n\t 1: \"'inji\",\n\t 5: \"'inji\",\n\t 8: \"'inji\",\n\t 70: \"'inji\",\n\t 80: \"'inji\",\n\t 2: \"'nji\",\n\t 7: \"'nji\",\n\t 20: \"'nji\",\n\t 50: \"'nji\",\n\t 3: \"'ünji\",\n\t 4: \"'ünji\",\n\t 100: \"'ünji\",\n\t 6: \"'njy\",\n\t 9: \"'unjy\",\n\t 10: \"'unjy\",\n\t 30: \"'unjy\",\n\t 60: \"'ynjy\",\n\t 90: \"'ynjy\",\n\t };\n\t\n\t var tk = moment.defineLocale('tk', {\n\t months: 'Ýanwar_Fewral_Mart_Aprel_Maý_Iýun_Iýul_Awgust_Sentýabr_Oktýabr_Noýabr_Dekabr'.split(\n\t '_'\n\t ),\n\t monthsShort: 'Ýan_Few_Mar_Apr_Maý_Iýn_Iýl_Awg_Sen_Okt_Noý_Dek'.split('_'),\n\t weekdays: 'Ýekşenbe_Duşenbe_Sişenbe_Çarşenbe_Penşenbe_Anna_Şenbe'.split(\n\t '_'\n\t ),\n\t weekdaysShort: 'Ýek_Duş_Siş_Çar_Pen_Ann_Şen'.split('_'),\n\t weekdaysMin: 'Ýk_Dş_Sş_Çr_Pn_An_Şn'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'DD.MM.YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY HH:mm',\n\t LLLL: 'dddd, D MMMM YYYY HH:mm',\n\t },\n\t calendar: {\n\t sameDay: '[bugün sagat] LT',\n\t nextDay: '[ertir sagat] LT',\n\t nextWeek: '[indiki] dddd [sagat] LT',\n\t lastDay: '[düýn] LT',\n\t lastWeek: '[geçen] dddd [sagat] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: '%s soň',\n\t past: '%s öň',\n\t s: 'birnäçe sekunt',\n\t m: 'bir minut',\n\t mm: '%d minut',\n\t h: 'bir sagat',\n\t hh: '%d sagat',\n\t d: 'bir gün',\n\t dd: '%d gün',\n\t M: 'bir aý',\n\t MM: '%d aý',\n\t y: 'bir ýyl',\n\t yy: '%d ýyl',\n\t },\n\t ordinal: function (number, period) {\n\t switch (period) {\n\t case 'd':\n\t case 'D':\n\t case 'Do':\n\t case 'DD':\n\t return number;\n\t default:\n\t if (number === 0) {\n\t // special case for zero\n\t return number + \"'unjy\";\n\t }\n\t var a = number % 10,\n\t b = (number % 100) - a,\n\t c = number >= 100 ? 100 : null;\n\t return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n\t }\n\t },\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 7, // The week that contains Jan 7th is the first week of the year.\n\t },\n\t });\n\t\n\t return tk;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 422:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Tagalog (Philippines) [tl-ph]\n\t//! author : Dan Hagman : https://github.com/hagmandan\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var tlPh = moment.defineLocale('tl-ph', {\n\t months: 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split(\n\t '_'\n\t ),\n\t monthsShort: 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),\n\t weekdays: 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split(\n\t '_'\n\t ),\n\t weekdaysShort: 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),\n\t weekdaysMin: 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'MM/D/YYYY',\n\t LL: 'MMMM D, YYYY',\n\t LLL: 'MMMM D, YYYY HH:mm',\n\t LLLL: 'dddd, MMMM DD, YYYY HH:mm',\n\t },\n\t calendar: {\n\t sameDay: 'LT [ngayong araw]',\n\t nextDay: '[Bukas ng] LT',\n\t nextWeek: 'LT [sa susunod na] dddd',\n\t lastDay: 'LT [kahapon]',\n\t lastWeek: 'LT [noong nakaraang] dddd',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: 'sa loob ng %s',\n\t past: '%s ang nakalipas',\n\t s: 'ilang segundo',\n\t ss: '%d segundo',\n\t m: 'isang minuto',\n\t mm: '%d minuto',\n\t h: 'isang oras',\n\t hh: '%d oras',\n\t d: 'isang araw',\n\t dd: '%d araw',\n\t M: 'isang buwan',\n\t MM: '%d buwan',\n\t y: 'isang taon',\n\t yy: '%d taon',\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}/,\n\t ordinal: function (number) {\n\t return number;\n\t },\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 4, // The week that contains Jan 4th is the first week of the year.\n\t },\n\t });\n\t\n\t return tlPh;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 423:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Klingon [tlh]\n\t//! author : Dominika Kruk : https://github.com/amaranthrose\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_');\n\t\n\t function translateFuture(output) {\n\t var time = output;\n\t time =\n\t output.indexOf('jaj') !== -1\n\t ? time.slice(0, -3) + 'leS'\n\t : output.indexOf('jar') !== -1\n\t ? time.slice(0, -3) + 'waQ'\n\t : output.indexOf('DIS') !== -1\n\t ? time.slice(0, -3) + 'nem'\n\t : time + ' pIq';\n\t return time;\n\t }\n\t\n\t function translatePast(output) {\n\t var time = output;\n\t time =\n\t output.indexOf('jaj') !== -1\n\t ? time.slice(0, -3) + 'Hu’'\n\t : output.indexOf('jar') !== -1\n\t ? time.slice(0, -3) + 'wen'\n\t : output.indexOf('DIS') !== -1\n\t ? time.slice(0, -3) + 'ben'\n\t : time + ' ret';\n\t return time;\n\t }\n\t\n\t function translate(number, withoutSuffix, string, isFuture) {\n\t var numberNoun = numberAsNoun(number);\n\t switch (string) {\n\t case 'ss':\n\t return numberNoun + ' lup';\n\t case 'mm':\n\t return numberNoun + ' tup';\n\t case 'hh':\n\t return numberNoun + ' rep';\n\t case 'dd':\n\t return numberNoun + ' jaj';\n\t case 'MM':\n\t return numberNoun + ' jar';\n\t case 'yy':\n\t return numberNoun + ' DIS';\n\t }\n\t }\n\t\n\t function numberAsNoun(number) {\n\t var hundred = Math.floor((number % 1000) / 100),\n\t ten = Math.floor((number % 100) / 10),\n\t one = number % 10,\n\t word = '';\n\t if (hundred > 0) {\n\t word += numbersNouns[hundred] + 'vatlh';\n\t }\n\t if (ten > 0) {\n\t word += (word !== '' ? ' ' : '') + numbersNouns[ten] + 'maH';\n\t }\n\t if (one > 0) {\n\t word += (word !== '' ? ' ' : '') + numbersNouns[one];\n\t }\n\t return word === '' ? 'pagh' : word;\n\t }\n\t\n\t var tlh = moment.defineLocale('tlh', {\n\t months: 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split(\n\t '_'\n\t ),\n\t monthsShort: 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split(\n\t '_'\n\t ),\n\t monthsParseExact: true,\n\t weekdays: 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split(\n\t '_'\n\t ),\n\t weekdaysShort: 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split(\n\t '_'\n\t ),\n\t weekdaysMin: 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split(\n\t '_'\n\t ),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'DD.MM.YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY HH:mm',\n\t LLLL: 'dddd, D MMMM YYYY HH:mm',\n\t },\n\t calendar: {\n\t sameDay: '[DaHjaj] LT',\n\t nextDay: '[wa’leS] LT',\n\t nextWeek: 'LLL',\n\t lastDay: '[wa’Hu’] LT',\n\t lastWeek: 'LLL',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: translateFuture,\n\t past: translatePast,\n\t s: 'puS lup',\n\t ss: translate,\n\t m: 'wa’ tup',\n\t mm: translate,\n\t h: 'wa’ rep',\n\t hh: translate,\n\t d: 'wa’ jaj',\n\t dd: translate,\n\t M: 'wa’ jar',\n\t MM: translate,\n\t y: 'wa’ DIS',\n\t yy: translate,\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n\t ordinal: '%d.',\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 4, // The week that contains Jan 4th is the first week of the year.\n\t },\n\t });\n\t\n\t return tlh;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 424:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Turkish [tr]\n\t//! authors : Erhan Gundogan : https://github.com/erhangundogan,\n\t//! Burak Yiğit Kaya: https://github.com/BYK\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var suffixes = {\n\t 1: \"'inci\",\n\t 5: \"'inci\",\n\t 8: \"'inci\",\n\t 70: \"'inci\",\n\t 80: \"'inci\",\n\t 2: \"'nci\",\n\t 7: \"'nci\",\n\t 20: \"'nci\",\n\t 50: \"'nci\",\n\t 3: \"'üncü\",\n\t 4: \"'üncü\",\n\t 100: \"'üncü\",\n\t 6: \"'ncı\",\n\t 9: \"'uncu\",\n\t 10: \"'uncu\",\n\t 30: \"'uncu\",\n\t 60: \"'ıncı\",\n\t 90: \"'ıncı\",\n\t };\n\t\n\t var tr = moment.defineLocale('tr', {\n\t months: 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split(\n\t '_'\n\t ),\n\t monthsShort: 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),\n\t weekdays: 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split(\n\t '_'\n\t ),\n\t weekdaysShort: 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),\n\t weekdaysMin: 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),\n\t meridiem: function (hours, minutes, isLower) {\n\t if (hours < 12) {\n\t return isLower ? 'öö' : 'ÖÖ';\n\t } else {\n\t return isLower ? 'ös' : 'ÖS';\n\t }\n\t },\n\t meridiemParse: /öö|ÖÖ|ös|ÖS/,\n\t isPM: function (input) {\n\t return input === 'ös' || input === 'ÖS';\n\t },\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'DD.MM.YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY HH:mm',\n\t LLLL: 'dddd, D MMMM YYYY HH:mm',\n\t },\n\t calendar: {\n\t sameDay: '[bugün saat] LT',\n\t nextDay: '[yarın saat] LT',\n\t nextWeek: '[gelecek] dddd [saat] LT',\n\t lastDay: '[dün] LT',\n\t lastWeek: '[geçen] dddd [saat] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: '%s sonra',\n\t past: '%s önce',\n\t s: 'birkaç saniye',\n\t ss: '%d saniye',\n\t m: 'bir dakika',\n\t mm: '%d dakika',\n\t h: 'bir saat',\n\t hh: '%d saat',\n\t d: 'bir gün',\n\t dd: '%d gün',\n\t w: 'bir hafta',\n\t ww: '%d hafta',\n\t M: 'bir ay',\n\t MM: '%d ay',\n\t y: 'bir yıl',\n\t yy: '%d yıl',\n\t },\n\t ordinal: function (number, period) {\n\t switch (period) {\n\t case 'd':\n\t case 'D':\n\t case 'Do':\n\t case 'DD':\n\t return number;\n\t default:\n\t if (number === 0) {\n\t // special case for zero\n\t return number + \"'ıncı\";\n\t }\n\t var a = number % 10,\n\t b = (number % 100) - a,\n\t c = number >= 100 ? 100 : null;\n\t return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n\t }\n\t },\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 7, // The week that contains Jan 7th is the first week of the year.\n\t },\n\t });\n\t\n\t return tr;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 425:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Talossan [tzl]\n\t//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n\t//! author : Iustì Canun\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t // After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals.\n\t // This is currently too difficult (maybe even impossible) to add.\n\t var tzl = moment.defineLocale('tzl', {\n\t months: 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split(\n\t '_'\n\t ),\n\t monthsShort: 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),\n\t weekdays: 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),\n\t weekdaysShort: 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),\n\t weekdaysMin: 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH.mm',\n\t LTS: 'HH.mm.ss',\n\t L: 'DD.MM.YYYY',\n\t LL: 'D. MMMM [dallas] YYYY',\n\t LLL: 'D. MMMM [dallas] YYYY HH.mm',\n\t LLLL: 'dddd, [li] D. MMMM [dallas] YYYY HH.mm',\n\t },\n\t meridiemParse: /d\\'o|d\\'a/i,\n\t isPM: function (input) {\n\t return \"d'o\" === input.toLowerCase();\n\t },\n\t meridiem: function (hours, minutes, isLower) {\n\t if (hours > 11) {\n\t return isLower ? \"d'o\" : \"D'O\";\n\t } else {\n\t return isLower ? \"d'a\" : \"D'A\";\n\t }\n\t },\n\t calendar: {\n\t sameDay: '[oxhi à] LT',\n\t nextDay: '[demà à] LT',\n\t nextWeek: 'dddd [à] LT',\n\t lastDay: '[ieiri à] LT',\n\t lastWeek: '[sür el] dddd [lasteu à] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: 'osprei %s',\n\t past: 'ja%s',\n\t s: processRelativeTime,\n\t ss: processRelativeTime,\n\t m: processRelativeTime,\n\t mm: processRelativeTime,\n\t h: processRelativeTime,\n\t hh: processRelativeTime,\n\t d: processRelativeTime,\n\t dd: processRelativeTime,\n\t M: processRelativeTime,\n\t MM: processRelativeTime,\n\t y: processRelativeTime,\n\t yy: processRelativeTime,\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n\t ordinal: '%d.',\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 4, // The week that contains Jan 4th is the first week of the year.\n\t },\n\t });\n\t\n\t function processRelativeTime(number, withoutSuffix, key, isFuture) {\n\t var format = {\n\t s: ['viensas secunds', \"'iensas secunds\"],\n\t ss: [number + ' secunds', '' + number + ' secunds'],\n\t m: [\"'n míut\", \"'iens míut\"],\n\t mm: [number + ' míuts', '' + number + ' míuts'],\n\t h: [\"'n þora\", \"'iensa þora\"],\n\t hh: [number + ' þoras', '' + number + ' þoras'],\n\t d: [\"'n ziua\", \"'iensa ziua\"],\n\t dd: [number + ' ziuas', '' + number + ' ziuas'],\n\t M: [\"'n mes\", \"'iens mes\"],\n\t MM: [number + ' mesen', '' + number + ' mesen'],\n\t y: [\"'n ar\", \"'iens ar\"],\n\t yy: [number + ' ars', '' + number + ' ars'],\n\t };\n\t return isFuture\n\t ? format[key][0]\n\t : withoutSuffix\n\t ? format[key][0]\n\t : format[key][1];\n\t }\n\t\n\t return tzl;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 426:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Central Atlas Tamazight Latin [tzm-latn]\n\t//! author : Abdel Said : https://github.com/abdelsaid\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var tzmLatn = moment.defineLocale('tzm-latn', {\n\t months: 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split(\n\t '_'\n\t ),\n\t monthsShort: 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split(\n\t '_'\n\t ),\n\t weekdays: 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n\t weekdaysShort: 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n\t weekdaysMin: 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'DD/MM/YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY HH:mm',\n\t LLLL: 'dddd D MMMM YYYY HH:mm',\n\t },\n\t calendar: {\n\t sameDay: '[asdkh g] LT',\n\t nextDay: '[aska g] LT',\n\t nextWeek: 'dddd [g] LT',\n\t lastDay: '[assant g] LT',\n\t lastWeek: 'dddd [g] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: 'dadkh s yan %s',\n\t past: 'yan %s',\n\t s: 'imik',\n\t ss: '%d imik',\n\t m: 'minuḍ',\n\t mm: '%d minuḍ',\n\t h: 'saɛa',\n\t hh: '%d tassaɛin',\n\t d: 'ass',\n\t dd: '%d ossan',\n\t M: 'ayowr',\n\t MM: '%d iyyirn',\n\t y: 'asgas',\n\t yy: '%d isgasn',\n\t },\n\t week: {\n\t dow: 6, // Saturday is the first day of the week.\n\t doy: 12, // The week that contains Jan 12th is the first week of the year.\n\t },\n\t });\n\t\n\t return tzmLatn;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 427:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Central Atlas Tamazight [tzm]\n\t//! author : Abdel Said : https://github.com/abdelsaid\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var tzm = moment.defineLocale('tzm', {\n\t months: 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split(\n\t '_'\n\t ),\n\t monthsShort: 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split(\n\t '_'\n\t ),\n\t weekdays: 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n\t weekdaysShort: 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n\t weekdaysMin: 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'DD/MM/YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY HH:mm',\n\t LLLL: 'dddd D MMMM YYYY HH:mm',\n\t },\n\t calendar: {\n\t sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',\n\t nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',\n\t nextWeek: 'dddd [ⴴ] LT',\n\t lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',\n\t lastWeek: 'dddd [ⴴ] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',\n\t past: 'ⵢⴰⵏ %s',\n\t s: 'ⵉⵎⵉⴽ',\n\t ss: '%d ⵉⵎⵉⴽ',\n\t m: 'ⵎⵉⵏⵓⴺ',\n\t mm: '%d ⵎⵉⵏⵓⴺ',\n\t h: 'ⵙⴰⵄⴰ',\n\t hh: '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',\n\t d: 'ⴰⵙⵙ',\n\t dd: '%d oⵙⵙⴰⵏ',\n\t M: 'ⴰⵢoⵓⵔ',\n\t MM: '%d ⵉⵢⵢⵉⵔⵏ',\n\t y: 'ⴰⵙⴳⴰⵙ',\n\t yy: '%d ⵉⵙⴳⴰⵙⵏ',\n\t },\n\t week: {\n\t dow: 6, // Saturday is the first day of the week.\n\t doy: 12, // The week that contains Jan 12th is the first week of the year.\n\t },\n\t });\n\t\n\t return tzm;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 428:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Uyghur (China) [ug-cn]\n\t//! author: boyaq : https://github.com/boyaq\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var ugCn = moment.defineLocale('ug-cn', {\n\t months: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split(\n\t '_'\n\t ),\n\t monthsShort: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split(\n\t '_'\n\t ),\n\t weekdays: 'يەكشەنبە_دۈشەنبە_سەيشەنبە_چارشەنبە_پەيشەنبە_جۈمە_شەنبە'.split(\n\t '_'\n\t ),\n\t weekdaysShort: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'),\n\t weekdaysMin: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'YYYY-MM-DD',\n\t LL: 'YYYY-يىلىM-ئاينىڭD-كۈنى',\n\t LLL: 'YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm',\n\t LLLL: 'dddd، YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm',\n\t },\n\t meridiemParse: /يېرىم كېچە|سەھەر|چۈشتىن بۇرۇن|چۈش|چۈشتىن كېيىن|كەچ/,\n\t meridiemHour: function (hour, meridiem) {\n\t if (hour === 12) {\n\t hour = 0;\n\t }\n\t if (\n\t meridiem === 'يېرىم كېچە' ||\n\t meridiem === 'سەھەر' ||\n\t meridiem === 'چۈشتىن بۇرۇن'\n\t ) {\n\t return hour;\n\t } else if (meridiem === 'چۈشتىن كېيىن' || meridiem === 'كەچ') {\n\t return hour + 12;\n\t } else {\n\t return hour >= 11 ? hour : hour + 12;\n\t }\n\t },\n\t meridiem: function (hour, minute, isLower) {\n\t var hm = hour * 100 + minute;\n\t if (hm < 600) {\n\t return 'يېرىم كېچە';\n\t } else if (hm < 900) {\n\t return 'سەھەر';\n\t } else if (hm < 1130) {\n\t return 'چۈشتىن بۇرۇن';\n\t } else if (hm < 1230) {\n\t return 'چۈش';\n\t } else if (hm < 1800) {\n\t return 'چۈشتىن كېيىن';\n\t } else {\n\t return 'كەچ';\n\t }\n\t },\n\t calendar: {\n\t sameDay: '[بۈگۈن سائەت] LT',\n\t nextDay: '[ئەتە سائەت] LT',\n\t nextWeek: '[كېلەركى] dddd [سائەت] LT',\n\t lastDay: '[تۆنۈگۈن] LT',\n\t lastWeek: '[ئالدىنقى] dddd [سائەت] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: '%s كېيىن',\n\t past: '%s بۇرۇن',\n\t s: 'نەچچە سېكونت',\n\t ss: '%d سېكونت',\n\t m: 'بىر مىنۇت',\n\t mm: '%d مىنۇت',\n\t h: 'بىر سائەت',\n\t hh: '%d سائەت',\n\t d: 'بىر كۈن',\n\t dd: '%d كۈن',\n\t M: 'بىر ئاي',\n\t MM: '%d ئاي',\n\t y: 'بىر يىل',\n\t yy: '%d يىل',\n\t },\n\t\n\t dayOfMonthOrdinalParse: /\\d{1,2}(-كۈنى|-ئاي|-ھەپتە)/,\n\t ordinal: function (number, period) {\n\t switch (period) {\n\t case 'd':\n\t case 'D':\n\t case 'DDD':\n\t return number + '-كۈنى';\n\t case 'w':\n\t case 'W':\n\t return number + '-ھەپتە';\n\t default:\n\t return number;\n\t }\n\t },\n\t preparse: function (string) {\n\t return string.replace(/،/g, ',');\n\t },\n\t postformat: function (string) {\n\t return string.replace(/,/g, '،');\n\t },\n\t week: {\n\t // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 7, // The week that contains Jan 1st is the first week of the year.\n\t },\n\t });\n\t\n\t return ugCn;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 429:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Ukrainian [uk]\n\t//! author : zemlanin : https://github.com/zemlanin\n\t//! Author : Menelion Elensúle : https://github.com/Oire\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t function plural(word, num) {\n\t var forms = word.split('_');\n\t return num % 10 === 1 && num % 100 !== 11\n\t ? forms[0]\n\t : num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20)\n\t ? forms[1]\n\t : forms[2];\n\t }\n\t function relativeTimeWithPlural(number, withoutSuffix, key) {\n\t var format = {\n\t ss: withoutSuffix ? 'секунда_секунди_секунд' : 'секунду_секунди_секунд',\n\t mm: withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',\n\t hh: withoutSuffix ? 'година_години_годин' : 'годину_години_годин',\n\t dd: 'день_дні_днів',\n\t MM: 'місяць_місяці_місяців',\n\t yy: 'рік_роки_років',\n\t };\n\t if (key === 'm') {\n\t return withoutSuffix ? 'хвилина' : 'хвилину';\n\t } else if (key === 'h') {\n\t return withoutSuffix ? 'година' : 'годину';\n\t } else {\n\t return number + ' ' + plural(format[key], +number);\n\t }\n\t }\n\t function weekdaysCaseReplace(m, format) {\n\t var weekdays = {\n\t nominative: 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split(\n\t '_'\n\t ),\n\t accusative: 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split(\n\t '_'\n\t ),\n\t genitive: 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split(\n\t '_'\n\t ),\n\t },\n\t nounCase;\n\t\n\t if (m === true) {\n\t return weekdays['nominative']\n\t .slice(1, 7)\n\t .concat(weekdays['nominative'].slice(0, 1));\n\t }\n\t if (!m) {\n\t return weekdays['nominative'];\n\t }\n\t\n\t nounCase = /(\\[[ВвУу]\\]) ?dddd/.test(format)\n\t ? 'accusative'\n\t : /\\[?(?:минулої|наступної)? ?\\] ?dddd/.test(format)\n\t ? 'genitive'\n\t : 'nominative';\n\t return weekdays[nounCase][m.day()];\n\t }\n\t function processHoursFunction(str) {\n\t return function () {\n\t return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';\n\t };\n\t }\n\t\n\t var uk = moment.defineLocale('uk', {\n\t months: {\n\t format: 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split(\n\t '_'\n\t ),\n\t standalone: 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split(\n\t '_'\n\t ),\n\t },\n\t monthsShort: 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split(\n\t '_'\n\t ),\n\t weekdays: weekdaysCaseReplace,\n\t weekdaysShort: 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n\t weekdaysMin: 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'DD.MM.YYYY',\n\t LL: 'D MMMM YYYY р.',\n\t LLL: 'D MMMM YYYY р., HH:mm',\n\t LLLL: 'dddd, D MMMM YYYY р., HH:mm',\n\t },\n\t calendar: {\n\t sameDay: processHoursFunction('[Сьогодні '),\n\t nextDay: processHoursFunction('[Завтра '),\n\t lastDay: processHoursFunction('[Вчора '),\n\t nextWeek: processHoursFunction('[У] dddd ['),\n\t lastWeek: function () {\n\t switch (this.day()) {\n\t case 0:\n\t case 3:\n\t case 5:\n\t case 6:\n\t return processHoursFunction('[Минулої] dddd [').call(this);\n\t case 1:\n\t case 2:\n\t case 4:\n\t return processHoursFunction('[Минулого] dddd [').call(this);\n\t }\n\t },\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: 'за %s',\n\t past: '%s тому',\n\t s: 'декілька секунд',\n\t ss: relativeTimeWithPlural,\n\t m: relativeTimeWithPlural,\n\t mm: relativeTimeWithPlural,\n\t h: 'годину',\n\t hh: relativeTimeWithPlural,\n\t d: 'день',\n\t dd: relativeTimeWithPlural,\n\t M: 'місяць',\n\t MM: relativeTimeWithPlural,\n\t y: 'рік',\n\t yy: relativeTimeWithPlural,\n\t },\n\t // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason\n\t meridiemParse: /ночі|ранку|дня|вечора/,\n\t isPM: function (input) {\n\t return /^(дня|вечора)$/.test(input);\n\t },\n\t meridiem: function (hour, minute, isLower) {\n\t if (hour < 4) {\n\t return 'ночі';\n\t } else if (hour < 12) {\n\t return 'ранку';\n\t } else if (hour < 17) {\n\t return 'дня';\n\t } else {\n\t return 'вечора';\n\t }\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}-(й|го)/,\n\t ordinal: function (number, period) {\n\t switch (period) {\n\t case 'M':\n\t case 'd':\n\t case 'DDD':\n\t case 'w':\n\t case 'W':\n\t return number + '-й';\n\t case 'D':\n\t return number + '-го';\n\t default:\n\t return number;\n\t }\n\t },\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 7, // The week that contains Jan 7th is the first week of the year.\n\t },\n\t });\n\t\n\t return uk;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 430:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Urdu [ur]\n\t//! author : Sawood Alam : https://github.com/ibnesayeed\n\t//! author : Zack : https://github.com/ZackVision\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var months = [\n\t 'جنوری',\n\t 'فروری',\n\t 'مارچ',\n\t 'اپریل',\n\t 'مئی',\n\t 'جون',\n\t 'جولائی',\n\t 'اگست',\n\t 'ستمبر',\n\t 'اکتوبر',\n\t 'نومبر',\n\t 'دسمبر',\n\t ],\n\t days = ['اتوار', 'پیر', 'منگل', 'بدھ', 'جمعرات', 'جمعہ', 'ہفتہ'];\n\t\n\t var ur = moment.defineLocale('ur', {\n\t months: months,\n\t monthsShort: months,\n\t weekdays: days,\n\t weekdaysShort: days,\n\t weekdaysMin: days,\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'DD/MM/YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY HH:mm',\n\t LLLL: 'dddd، D MMMM YYYY HH:mm',\n\t },\n\t meridiemParse: /صبح|شام/,\n\t isPM: function (input) {\n\t return 'شام' === input;\n\t },\n\t meridiem: function (hour, minute, isLower) {\n\t if (hour < 12) {\n\t return 'صبح';\n\t }\n\t return 'شام';\n\t },\n\t calendar: {\n\t sameDay: '[آج بوقت] LT',\n\t nextDay: '[کل بوقت] LT',\n\t nextWeek: 'dddd [بوقت] LT',\n\t lastDay: '[گذشتہ روز بوقت] LT',\n\t lastWeek: '[گذشتہ] dddd [بوقت] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: '%s بعد',\n\t past: '%s قبل',\n\t s: 'چند سیکنڈ',\n\t ss: '%d سیکنڈ',\n\t m: 'ایک منٹ',\n\t mm: '%d منٹ',\n\t h: 'ایک گھنٹہ',\n\t hh: '%d گھنٹے',\n\t d: 'ایک دن',\n\t dd: '%d دن',\n\t M: 'ایک ماہ',\n\t MM: '%d ماہ',\n\t y: 'ایک سال',\n\t yy: '%d سال',\n\t },\n\t preparse: function (string) {\n\t return string.replace(/،/g, ',');\n\t },\n\t postformat: function (string) {\n\t return string.replace(/,/g, '،');\n\t },\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 4, // The week that contains Jan 4th is the first week of the year.\n\t },\n\t });\n\t\n\t return ur;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 431:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Uzbek Latin [uz-latn]\n\t//! author : Rasulbek Mirzayev : github.com/Rasulbeeek\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var uzLatn = moment.defineLocale('uz-latn', {\n\t months: 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split(\n\t '_'\n\t ),\n\t monthsShort: 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'),\n\t weekdays: 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split(\n\t '_'\n\t ),\n\t weekdaysShort: 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'),\n\t weekdaysMin: 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'DD/MM/YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY HH:mm',\n\t LLLL: 'D MMMM YYYY, dddd HH:mm',\n\t },\n\t calendar: {\n\t sameDay: '[Bugun soat] LT [da]',\n\t nextDay: '[Ertaga] LT [da]',\n\t nextWeek: 'dddd [kuni soat] LT [da]',\n\t lastDay: '[Kecha soat] LT [da]',\n\t lastWeek: \"[O'tgan] dddd [kuni soat] LT [da]\",\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: 'Yaqin %s ichida',\n\t past: 'Bir necha %s oldin',\n\t s: 'soniya',\n\t ss: '%d soniya',\n\t m: 'bir daqiqa',\n\t mm: '%d daqiqa',\n\t h: 'bir soat',\n\t hh: '%d soat',\n\t d: 'bir kun',\n\t dd: '%d kun',\n\t M: 'bir oy',\n\t MM: '%d oy',\n\t y: 'bir yil',\n\t yy: '%d yil',\n\t },\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 7, // The week that contains Jan 7th is the first week of the year.\n\t },\n\t });\n\t\n\t return uzLatn;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 432:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Uzbek [uz]\n\t//! author : Sardor Muminov : https://github.com/muminoff\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var uz = moment.defineLocale('uz', {\n\t months: 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split(\n\t '_'\n\t ),\n\t monthsShort: 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),\n\t weekdays: 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),\n\t weekdaysShort: 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),\n\t weekdaysMin: 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'DD/MM/YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY HH:mm',\n\t LLLL: 'D MMMM YYYY, dddd HH:mm',\n\t },\n\t calendar: {\n\t sameDay: '[Бугун соат] LT [да]',\n\t nextDay: '[Эртага] LT [да]',\n\t nextWeek: 'dddd [куни соат] LT [да]',\n\t lastDay: '[Кеча соат] LT [да]',\n\t lastWeek: '[Утган] dddd [куни соат] LT [да]',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: 'Якин %s ичида',\n\t past: 'Бир неча %s олдин',\n\t s: 'фурсат',\n\t ss: '%d фурсат',\n\t m: 'бир дакика',\n\t mm: '%d дакика',\n\t h: 'бир соат',\n\t hh: '%d соат',\n\t d: 'бир кун',\n\t dd: '%d кун',\n\t M: 'бир ой',\n\t MM: '%d ой',\n\t y: 'бир йил',\n\t yy: '%d йил',\n\t },\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 7, // The week that contains Jan 4th is the first week of the year.\n\t },\n\t });\n\t\n\t return uz;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 433:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Vietnamese [vi]\n\t//! author : Bang Nguyen : https://github.com/bangnk\n\t//! author : Chien Kira : https://github.com/chienkira\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var vi = moment.defineLocale('vi', {\n\t months: 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split(\n\t '_'\n\t ),\n\t monthsShort: 'Thg 01_Thg 02_Thg 03_Thg 04_Thg 05_Thg 06_Thg 07_Thg 08_Thg 09_Thg 10_Thg 11_Thg 12'.split(\n\t '_'\n\t ),\n\t monthsParseExact: true,\n\t weekdays: 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split(\n\t '_'\n\t ),\n\t weekdaysShort: 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n\t weekdaysMin: 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n\t weekdaysParseExact: true,\n\t meridiemParse: /sa|ch/i,\n\t isPM: function (input) {\n\t return /^ch$/i.test(input);\n\t },\n\t meridiem: function (hours, minutes, isLower) {\n\t if (hours < 12) {\n\t return isLower ? 'sa' : 'SA';\n\t } else {\n\t return isLower ? 'ch' : 'CH';\n\t }\n\t },\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'DD/MM/YYYY',\n\t LL: 'D MMMM [năm] YYYY',\n\t LLL: 'D MMMM [năm] YYYY HH:mm',\n\t LLLL: 'dddd, D MMMM [năm] YYYY HH:mm',\n\t l: 'DD/M/YYYY',\n\t ll: 'D MMM YYYY',\n\t lll: 'D MMM YYYY HH:mm',\n\t llll: 'ddd, D MMM YYYY HH:mm',\n\t },\n\t calendar: {\n\t sameDay: '[Hôm nay lúc] LT',\n\t nextDay: '[Ngày mai lúc] LT',\n\t nextWeek: 'dddd [tuần tới lúc] LT',\n\t lastDay: '[Hôm qua lúc] LT',\n\t lastWeek: 'dddd [tuần trước lúc] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: '%s tới',\n\t past: '%s trước',\n\t s: 'vài giây',\n\t ss: '%d giây',\n\t m: 'một phút',\n\t mm: '%d phút',\n\t h: 'một giờ',\n\t hh: '%d giờ',\n\t d: 'một ngày',\n\t dd: '%d ngày',\n\t w: 'một tuần',\n\t ww: '%d tuần',\n\t M: 'một tháng',\n\t MM: '%d tháng',\n\t y: 'một năm',\n\t yy: '%d năm',\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}/,\n\t ordinal: function (number) {\n\t return number;\n\t },\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 4, // The week that contains Jan 4th is the first week of the year.\n\t },\n\t });\n\t\n\t return vi;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 434:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Pseudo [x-pseudo]\n\t//! author : Andrew Hood : https://github.com/andrewhood125\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var xPseudo = moment.defineLocale('x-pseudo', {\n\t months: 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split(\n\t '_'\n\t ),\n\t monthsShort: 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split(\n\t '_'\n\t ),\n\t monthsParseExact: true,\n\t weekdays: 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split(\n\t '_'\n\t ),\n\t weekdaysShort: 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'),\n\t weekdaysMin: 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'),\n\t weekdaysParseExact: true,\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t L: 'DD/MM/YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY HH:mm',\n\t LLLL: 'dddd, D MMMM YYYY HH:mm',\n\t },\n\t calendar: {\n\t sameDay: '[T~ódá~ý át] LT',\n\t nextDay: '[T~ómó~rró~w át] LT',\n\t nextWeek: 'dddd [át] LT',\n\t lastDay: '[Ý~ést~érdá~ý át] LT',\n\t lastWeek: '[L~ást] dddd [át] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: 'í~ñ %s',\n\t past: '%s á~gó',\n\t s: 'á ~féw ~sécó~ñds',\n\t ss: '%d s~écóñ~ds',\n\t m: 'á ~míñ~úté',\n\t mm: '%d m~íñú~tés',\n\t h: 'á~ñ hó~úr',\n\t hh: '%d h~óúrs',\n\t d: 'á ~dáý',\n\t dd: '%d d~áýs',\n\t M: 'á ~móñ~th',\n\t MM: '%d m~óñt~hs',\n\t y: 'á ~ýéár',\n\t yy: '%d ý~éárs',\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n\t ordinal: function (number) {\n\t var b = number % 10,\n\t output =\n\t ~~((number % 100) / 10) === 1\n\t ? 'th'\n\t : b === 1\n\t ? 'st'\n\t : b === 2\n\t ? 'nd'\n\t : b === 3\n\t ? 'rd'\n\t : 'th';\n\t return number + output;\n\t },\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 4, // The week that contains Jan 4th is the first week of the year.\n\t },\n\t });\n\t\n\t return xPseudo;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 435:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Yoruba Nigeria [yo]\n\t//! author : Atolagbe Abisoye : https://github.com/andela-batolagbe\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var yo = moment.defineLocale('yo', {\n\t months: 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split(\n\t '_'\n\t ),\n\t monthsShort: 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'),\n\t weekdays: 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'),\n\t weekdaysShort: 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'),\n\t weekdaysMin: 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'),\n\t longDateFormat: {\n\t LT: 'h:mm A',\n\t LTS: 'h:mm:ss A',\n\t L: 'DD/MM/YYYY',\n\t LL: 'D MMMM YYYY',\n\t LLL: 'D MMMM YYYY h:mm A',\n\t LLLL: 'dddd, D MMMM YYYY h:mm A',\n\t },\n\t calendar: {\n\t sameDay: '[Ònì ni] LT',\n\t nextDay: '[Ọ̀la ni] LT',\n\t nextWeek: \"dddd [Ọsẹ̀ tón'bọ] [ni] LT\",\n\t lastDay: '[Àna ni] LT',\n\t lastWeek: 'dddd [Ọsẹ̀ tólọ́] [ni] LT',\n\t sameElse: 'L',\n\t },\n\t relativeTime: {\n\t future: 'ní %s',\n\t past: '%s kọjá',\n\t s: 'ìsẹjú aayá die',\n\t ss: 'aayá %d',\n\t m: 'ìsẹjú kan',\n\t mm: 'ìsẹjú %d',\n\t h: 'wákati kan',\n\t hh: 'wákati %d',\n\t d: 'ọjọ́ kan',\n\t dd: 'ọjọ́ %d',\n\t M: 'osù kan',\n\t MM: 'osù %d',\n\t y: 'ọdún kan',\n\t yy: 'ọdún %d',\n\t },\n\t dayOfMonthOrdinalParse: /ọjọ́\\s\\d{1,2}/,\n\t ordinal: 'ọjọ́ %d',\n\t week: {\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 4, // The week that contains Jan 4th is the first week of the year.\n\t },\n\t });\n\t\n\t return yo;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 436:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Chinese (China) [zh-cn]\n\t//! author : suupic : https://github.com/suupic\n\t//! author : Zeno Zeng : https://github.com/zenozeng\n\t//! author : uu109 : https://github.com/uu109\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var zhCn = moment.defineLocale('zh-cn', {\n\t months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split(\n\t '_'\n\t ),\n\t monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split(\n\t '_'\n\t ),\n\t weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n\t weekdaysShort: '周日_周一_周二_周三_周四_周五_周六'.split('_'),\n\t weekdaysMin: '日_一_二_三_四_五_六'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'YYYY/MM/DD',\n\t LL: 'YYYY年M月D日',\n\t LLL: 'YYYY年M月D日Ah点mm分',\n\t LLLL: 'YYYY年M月D日ddddAh点mm分',\n\t l: 'YYYY/M/D',\n\t ll: 'YYYY年M月D日',\n\t lll: 'YYYY年M月D日 HH:mm',\n\t llll: 'YYYY年M月D日dddd HH:mm',\n\t },\n\t meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n\t meridiemHour: function (hour, meridiem) {\n\t if (hour === 12) {\n\t hour = 0;\n\t }\n\t if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n\t return hour;\n\t } else if (meridiem === '下午' || meridiem === '晚上') {\n\t return hour + 12;\n\t } else {\n\t // '中午'\n\t return hour >= 11 ? hour : hour + 12;\n\t }\n\t },\n\t meridiem: function (hour, minute, isLower) {\n\t var hm = hour * 100 + minute;\n\t if (hm < 600) {\n\t return '凌晨';\n\t } else if (hm < 900) {\n\t return '早上';\n\t } else if (hm < 1130) {\n\t return '上午';\n\t } else if (hm < 1230) {\n\t return '中午';\n\t } else if (hm < 1800) {\n\t return '下午';\n\t } else {\n\t return '晚上';\n\t }\n\t },\n\t calendar: {\n\t sameDay: '[今天]LT',\n\t nextDay: '[明天]LT',\n\t nextWeek: function (now) {\n\t if (now.week() !== this.week()) {\n\t return '[下]dddLT';\n\t } else {\n\t return '[本]dddLT';\n\t }\n\t },\n\t lastDay: '[昨天]LT',\n\t lastWeek: function (now) {\n\t if (this.week() !== now.week()) {\n\t return '[上]dddLT';\n\t } else {\n\t return '[本]dddLT';\n\t }\n\t },\n\t sameElse: 'L',\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}(日|月|周)/,\n\t ordinal: function (number, period) {\n\t switch (period) {\n\t case 'd':\n\t case 'D':\n\t case 'DDD':\n\t return number + '日';\n\t case 'M':\n\t return number + '月';\n\t case 'w':\n\t case 'W':\n\t return number + '周';\n\t default:\n\t return number;\n\t }\n\t },\n\t relativeTime: {\n\t future: '%s后',\n\t past: '%s前',\n\t s: '几秒',\n\t ss: '%d 秒',\n\t m: '1 分钟',\n\t mm: '%d 分钟',\n\t h: '1 小时',\n\t hh: '%d 小时',\n\t d: '1 天',\n\t dd: '%d 天',\n\t w: '1 周',\n\t ww: '%d 周',\n\t M: '1 个月',\n\t MM: '%d 个月',\n\t y: '1 年',\n\t yy: '%d 年',\n\t },\n\t week: {\n\t // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效\n\t dow: 1, // Monday is the first day of the week.\n\t doy: 4, // The week that contains Jan 4th is the first week of the year.\n\t },\n\t });\n\t\n\t return zhCn;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 437:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Chinese (Hong Kong) [zh-hk]\n\t//! author : Ben : https://github.com/ben-lin\n\t//! author : Chris Lam : https://github.com/hehachris\n\t//! author : Konstantin : https://github.com/skfd\n\t//! author : Anthony : https://github.com/anthonylau\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var zhHk = moment.defineLocale('zh-hk', {\n\t months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split(\n\t '_'\n\t ),\n\t monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split(\n\t '_'\n\t ),\n\t weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n\t weekdaysShort: '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n\t weekdaysMin: '日_一_二_三_四_五_六'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'YYYY/MM/DD',\n\t LL: 'YYYY年M月D日',\n\t LLL: 'YYYY年M月D日 HH:mm',\n\t LLLL: 'YYYY年M月D日dddd HH:mm',\n\t l: 'YYYY/M/D',\n\t ll: 'YYYY年M月D日',\n\t lll: 'YYYY年M月D日 HH:mm',\n\t llll: 'YYYY年M月D日dddd HH:mm',\n\t },\n\t meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n\t meridiemHour: function (hour, meridiem) {\n\t if (hour === 12) {\n\t hour = 0;\n\t }\n\t if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n\t return hour;\n\t } else if (meridiem === '中午') {\n\t return hour >= 11 ? hour : hour + 12;\n\t } else if (meridiem === '下午' || meridiem === '晚上') {\n\t return hour + 12;\n\t }\n\t },\n\t meridiem: function (hour, minute, isLower) {\n\t var hm = hour * 100 + minute;\n\t if (hm < 600) {\n\t return '凌晨';\n\t } else if (hm < 900) {\n\t return '早上';\n\t } else if (hm < 1200) {\n\t return '上午';\n\t } else if (hm === 1200) {\n\t return '中午';\n\t } else if (hm < 1800) {\n\t return '下午';\n\t } else {\n\t return '晚上';\n\t }\n\t },\n\t calendar: {\n\t sameDay: '[今天]LT',\n\t nextDay: '[明天]LT',\n\t nextWeek: '[下]ddddLT',\n\t lastDay: '[昨天]LT',\n\t lastWeek: '[上]ddddLT',\n\t sameElse: 'L',\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n\t ordinal: function (number, period) {\n\t switch (period) {\n\t case 'd':\n\t case 'D':\n\t case 'DDD':\n\t return number + '日';\n\t case 'M':\n\t return number + '月';\n\t case 'w':\n\t case 'W':\n\t return number + '週';\n\t default:\n\t return number;\n\t }\n\t },\n\t relativeTime: {\n\t future: '%s後',\n\t past: '%s前',\n\t s: '幾秒',\n\t ss: '%d 秒',\n\t m: '1 分鐘',\n\t mm: '%d 分鐘',\n\t h: '1 小時',\n\t hh: '%d 小時',\n\t d: '1 天',\n\t dd: '%d 天',\n\t M: '1 個月',\n\t MM: '%d 個月',\n\t y: '1 年',\n\t yy: '%d 年',\n\t },\n\t });\n\t\n\t return zhHk;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Chinese (Macau) [zh-mo]\n\t//! author : Ben : https://github.com/ben-lin\n\t//! author : Chris Lam : https://github.com/hehachris\n\t//! author : Tan Yuanhong : https://github.com/le0tan\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var zhMo = moment.defineLocale('zh-mo', {\n\t months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split(\n\t '_'\n\t ),\n\t monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split(\n\t '_'\n\t ),\n\t weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n\t weekdaysShort: '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n\t weekdaysMin: '日_一_二_三_四_五_六'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'DD/MM/YYYY',\n\t LL: 'YYYY年M月D日',\n\t LLL: 'YYYY年M月D日 HH:mm',\n\t LLLL: 'YYYY年M月D日dddd HH:mm',\n\t l: 'D/M/YYYY',\n\t ll: 'YYYY年M月D日',\n\t lll: 'YYYY年M月D日 HH:mm',\n\t llll: 'YYYY年M月D日dddd HH:mm',\n\t },\n\t meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n\t meridiemHour: function (hour, meridiem) {\n\t if (hour === 12) {\n\t hour = 0;\n\t }\n\t if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n\t return hour;\n\t } else if (meridiem === '中午') {\n\t return hour >= 11 ? hour : hour + 12;\n\t } else if (meridiem === '下午' || meridiem === '晚上') {\n\t return hour + 12;\n\t }\n\t },\n\t meridiem: function (hour, minute, isLower) {\n\t var hm = hour * 100 + minute;\n\t if (hm < 600) {\n\t return '凌晨';\n\t } else if (hm < 900) {\n\t return '早上';\n\t } else if (hm < 1130) {\n\t return '上午';\n\t } else if (hm < 1230) {\n\t return '中午';\n\t } else if (hm < 1800) {\n\t return '下午';\n\t } else {\n\t return '晚上';\n\t }\n\t },\n\t calendar: {\n\t sameDay: '[今天] LT',\n\t nextDay: '[明天] LT',\n\t nextWeek: '[下]dddd LT',\n\t lastDay: '[昨天] LT',\n\t lastWeek: '[上]dddd LT',\n\t sameElse: 'L',\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n\t ordinal: function (number, period) {\n\t switch (period) {\n\t case 'd':\n\t case 'D':\n\t case 'DDD':\n\t return number + '日';\n\t case 'M':\n\t return number + '月';\n\t case 'w':\n\t case 'W':\n\t return number + '週';\n\t default:\n\t return number;\n\t }\n\t },\n\t relativeTime: {\n\t future: '%s內',\n\t past: '%s前',\n\t s: '幾秒',\n\t ss: '%d 秒',\n\t m: '1 分鐘',\n\t mm: '%d 分鐘',\n\t h: '1 小時',\n\t hh: '%d 小時',\n\t d: '1 天',\n\t dd: '%d 天',\n\t M: '1 個月',\n\t MM: '%d 個月',\n\t y: '1 年',\n\t yy: '%d 年',\n\t },\n\t });\n\t\n\t return zhMo;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 439:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t//! moment.js locale configuration\n\t//! locale : Chinese (Taiwan) [zh-tw]\n\t//! author : Ben : https://github.com/ben-lin\n\t//! author : Chris Lam : https://github.com/hehachris\n\t\n\t;(function (global, factory) {\n\t true ? factory(__webpack_require__(1)) :\n\t typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n\t factory(global.moment)\n\t}(this, (function (moment) { 'use strict';\n\t\n\t //! moment.js locale configuration\n\t\n\t var zhTw = moment.defineLocale('zh-tw', {\n\t months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split(\n\t '_'\n\t ),\n\t monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split(\n\t '_'\n\t ),\n\t weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n\t weekdaysShort: '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n\t weekdaysMin: '日_一_二_三_四_五_六'.split('_'),\n\t longDateFormat: {\n\t LT: 'HH:mm',\n\t LTS: 'HH:mm:ss',\n\t L: 'YYYY/MM/DD',\n\t LL: 'YYYY年M月D日',\n\t LLL: 'YYYY年M月D日 HH:mm',\n\t LLLL: 'YYYY年M月D日dddd HH:mm',\n\t l: 'YYYY/M/D',\n\t ll: 'YYYY年M月D日',\n\t lll: 'YYYY年M月D日 HH:mm',\n\t llll: 'YYYY年M月D日dddd HH:mm',\n\t },\n\t meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n\t meridiemHour: function (hour, meridiem) {\n\t if (hour === 12) {\n\t hour = 0;\n\t }\n\t if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n\t return hour;\n\t } else if (meridiem === '中午') {\n\t return hour >= 11 ? hour : hour + 12;\n\t } else if (meridiem === '下午' || meridiem === '晚上') {\n\t return hour + 12;\n\t }\n\t },\n\t meridiem: function (hour, minute, isLower) {\n\t var hm = hour * 100 + minute;\n\t if (hm < 600) {\n\t return '凌晨';\n\t } else if (hm < 900) {\n\t return '早上';\n\t } else if (hm < 1130) {\n\t return '上午';\n\t } else if (hm < 1230) {\n\t return '中午';\n\t } else if (hm < 1800) {\n\t return '下午';\n\t } else {\n\t return '晚上';\n\t }\n\t },\n\t calendar: {\n\t sameDay: '[今天] LT',\n\t nextDay: '[明天] LT',\n\t nextWeek: '[下]dddd LT',\n\t lastDay: '[昨天] LT',\n\t lastWeek: '[上]dddd LT',\n\t sameElse: 'L',\n\t },\n\t dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n\t ordinal: function (number, period) {\n\t switch (period) {\n\t case 'd':\n\t case 'D':\n\t case 'DDD':\n\t return number + '日';\n\t case 'M':\n\t return number + '月';\n\t case 'w':\n\t case 'W':\n\t return number + '週';\n\t default:\n\t return number;\n\t }\n\t },\n\t relativeTime: {\n\t future: '%s後',\n\t past: '%s前',\n\t s: '幾秒',\n\t ss: '%d 秒',\n\t m: '1 分鐘',\n\t mm: '%d 分鐘',\n\t h: '1 小時',\n\t hh: '%d 小時',\n\t d: '1 天',\n\t dd: '%d 天',\n\t M: '1 個月',\n\t MM: '%d 個月',\n\t y: '1 年',\n\t yy: '%d 年',\n\t },\n\t });\n\t\n\t return zhTw;\n\t\n\t})));\n\n\n/***/ }),\n\n/***/ 467:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar map = {\n\t\t\"./af\": 306,\n\t\t\"./af.js\": 306,\n\t\t\"./ar\": 313,\n\t\t\"./ar-dz\": 307,\n\t\t\"./ar-dz.js\": 307,\n\t\t\"./ar-kw\": 308,\n\t\t\"./ar-kw.js\": 308,\n\t\t\"./ar-ly\": 309,\n\t\t\"./ar-ly.js\": 309,\n\t\t\"./ar-ma\": 310,\n\t\t\"./ar-ma.js\": 310,\n\t\t\"./ar-sa\": 311,\n\t\t\"./ar-sa.js\": 311,\n\t\t\"./ar-tn\": 312,\n\t\t\"./ar-tn.js\": 312,\n\t\t\"./ar.js\": 313,\n\t\t\"./az\": 314,\n\t\t\"./az.js\": 314,\n\t\t\"./be\": 315,\n\t\t\"./be.js\": 315,\n\t\t\"./bg\": 316,\n\t\t\"./bg.js\": 316,\n\t\t\"./bm\": 317,\n\t\t\"./bm.js\": 317,\n\t\t\"./bn\": 319,\n\t\t\"./bn-bd\": 318,\n\t\t\"./bn-bd.js\": 318,\n\t\t\"./bn.js\": 319,\n\t\t\"./bo\": 320,\n\t\t\"./bo.js\": 320,\n\t\t\"./br\": 321,\n\t\t\"./br.js\": 321,\n\t\t\"./bs\": 322,\n\t\t\"./bs.js\": 322,\n\t\t\"./ca\": 323,\n\t\t\"./ca.js\": 323,\n\t\t\"./cs\": 324,\n\t\t\"./cs.js\": 324,\n\t\t\"./cv\": 325,\n\t\t\"./cv.js\": 325,\n\t\t\"./cy\": 326,\n\t\t\"./cy.js\": 326,\n\t\t\"./da\": 327,\n\t\t\"./da.js\": 327,\n\t\t\"./de\": 330,\n\t\t\"./de-at\": 328,\n\t\t\"./de-at.js\": 328,\n\t\t\"./de-ch\": 329,\n\t\t\"./de-ch.js\": 329,\n\t\t\"./de.js\": 330,\n\t\t\"./dv\": 331,\n\t\t\"./dv.js\": 331,\n\t\t\"./el\": 332,\n\t\t\"./el.js\": 332,\n\t\t\"./en-au\": 333,\n\t\t\"./en-au.js\": 333,\n\t\t\"./en-ca\": 334,\n\t\t\"./en-ca.js\": 334,\n\t\t\"./en-gb\": 335,\n\t\t\"./en-gb.js\": 335,\n\t\t\"./en-ie\": 336,\n\t\t\"./en-ie.js\": 336,\n\t\t\"./en-il\": 337,\n\t\t\"./en-il.js\": 337,\n\t\t\"./en-in\": 338,\n\t\t\"./en-in.js\": 338,\n\t\t\"./en-nz\": 339,\n\t\t\"./en-nz.js\": 339,\n\t\t\"./en-sg\": 340,\n\t\t\"./en-sg.js\": 340,\n\t\t\"./eo\": 341,\n\t\t\"./eo.js\": 341,\n\t\t\"./es\": 345,\n\t\t\"./es-do\": 342,\n\t\t\"./es-do.js\": 342,\n\t\t\"./es-mx\": 343,\n\t\t\"./es-mx.js\": 343,\n\t\t\"./es-us\": 344,\n\t\t\"./es-us.js\": 344,\n\t\t\"./es.js\": 345,\n\t\t\"./et\": 346,\n\t\t\"./et.js\": 346,\n\t\t\"./eu\": 347,\n\t\t\"./eu.js\": 347,\n\t\t\"./fa\": 348,\n\t\t\"./fa.js\": 348,\n\t\t\"./fi\": 349,\n\t\t\"./fi.js\": 349,\n\t\t\"./fil\": 350,\n\t\t\"./fil.js\": 350,\n\t\t\"./fo\": 351,\n\t\t\"./fo.js\": 351,\n\t\t\"./fr\": 354,\n\t\t\"./fr-ca\": 352,\n\t\t\"./fr-ca.js\": 352,\n\t\t\"./fr-ch\": 353,\n\t\t\"./fr-ch.js\": 353,\n\t\t\"./fr.js\": 354,\n\t\t\"./fy\": 355,\n\t\t\"./fy.js\": 355,\n\t\t\"./ga\": 356,\n\t\t\"./ga.js\": 356,\n\t\t\"./gd\": 357,\n\t\t\"./gd.js\": 357,\n\t\t\"./gl\": 358,\n\t\t\"./gl.js\": 358,\n\t\t\"./gom-deva\": 359,\n\t\t\"./gom-deva.js\": 359,\n\t\t\"./gom-latn\": 360,\n\t\t\"./gom-latn.js\": 360,\n\t\t\"./gu\": 361,\n\t\t\"./gu.js\": 361,\n\t\t\"./he\": 362,\n\t\t\"./he.js\": 362,\n\t\t\"./hi\": 363,\n\t\t\"./hi.js\": 363,\n\t\t\"./hr\": 364,\n\t\t\"./hr.js\": 364,\n\t\t\"./hu\": 365,\n\t\t\"./hu.js\": 365,\n\t\t\"./hy-am\": 366,\n\t\t\"./hy-am.js\": 366,\n\t\t\"./id\": 367,\n\t\t\"./id.js\": 367,\n\t\t\"./is\": 368,\n\t\t\"./is.js\": 368,\n\t\t\"./it\": 370,\n\t\t\"./it-ch\": 369,\n\t\t\"./it-ch.js\": 369,\n\t\t\"./it.js\": 370,\n\t\t\"./ja\": 286,\n\t\t\"./ja.js\": 286,\n\t\t\"./jv\": 371,\n\t\t\"./jv.js\": 371,\n\t\t\"./ka\": 372,\n\t\t\"./ka.js\": 372,\n\t\t\"./kk\": 373,\n\t\t\"./kk.js\": 373,\n\t\t\"./km\": 374,\n\t\t\"./km.js\": 374,\n\t\t\"./kn\": 375,\n\t\t\"./kn.js\": 375,\n\t\t\"./ko\": 376,\n\t\t\"./ko.js\": 376,\n\t\t\"./ku\": 377,\n\t\t\"./ku.js\": 377,\n\t\t\"./ky\": 378,\n\t\t\"./ky.js\": 378,\n\t\t\"./lb\": 379,\n\t\t\"./lb.js\": 379,\n\t\t\"./lo\": 380,\n\t\t\"./lo.js\": 380,\n\t\t\"./lt\": 381,\n\t\t\"./lt.js\": 381,\n\t\t\"./lv\": 382,\n\t\t\"./lv.js\": 382,\n\t\t\"./me\": 383,\n\t\t\"./me.js\": 383,\n\t\t\"./mi\": 384,\n\t\t\"./mi.js\": 384,\n\t\t\"./mk\": 385,\n\t\t\"./mk.js\": 385,\n\t\t\"./ml\": 386,\n\t\t\"./ml.js\": 386,\n\t\t\"./mn\": 387,\n\t\t\"./mn.js\": 387,\n\t\t\"./mr\": 388,\n\t\t\"./mr.js\": 388,\n\t\t\"./ms\": 390,\n\t\t\"./ms-my\": 389,\n\t\t\"./ms-my.js\": 389,\n\t\t\"./ms.js\": 390,\n\t\t\"./mt\": 391,\n\t\t\"./mt.js\": 391,\n\t\t\"./my\": 392,\n\t\t\"./my.js\": 392,\n\t\t\"./nb\": 393,\n\t\t\"./nb.js\": 393,\n\t\t\"./ne\": 394,\n\t\t\"./ne.js\": 394,\n\t\t\"./nl\": 396,\n\t\t\"./nl-be\": 395,\n\t\t\"./nl-be.js\": 395,\n\t\t\"./nl.js\": 396,\n\t\t\"./nn\": 397,\n\t\t\"./nn.js\": 397,\n\t\t\"./oc-lnc\": 398,\n\t\t\"./oc-lnc.js\": 398,\n\t\t\"./pa-in\": 399,\n\t\t\"./pa-in.js\": 399,\n\t\t\"./pl\": 400,\n\t\t\"./pl.js\": 400,\n\t\t\"./pt\": 402,\n\t\t\"./pt-br\": 401,\n\t\t\"./pt-br.js\": 401,\n\t\t\"./pt.js\": 402,\n\t\t\"./ro\": 403,\n\t\t\"./ro.js\": 403,\n\t\t\"./ru\": 404,\n\t\t\"./ru.js\": 404,\n\t\t\"./sd\": 405,\n\t\t\"./sd.js\": 405,\n\t\t\"./se\": 406,\n\t\t\"./se.js\": 406,\n\t\t\"./si\": 407,\n\t\t\"./si.js\": 407,\n\t\t\"./sk\": 408,\n\t\t\"./sk.js\": 408,\n\t\t\"./sl\": 409,\n\t\t\"./sl.js\": 409,\n\t\t\"./sq\": 410,\n\t\t\"./sq.js\": 410,\n\t\t\"./sr\": 412,\n\t\t\"./sr-cyrl\": 411,\n\t\t\"./sr-cyrl.js\": 411,\n\t\t\"./sr.js\": 412,\n\t\t\"./ss\": 413,\n\t\t\"./ss.js\": 413,\n\t\t\"./sv\": 414,\n\t\t\"./sv.js\": 414,\n\t\t\"./sw\": 415,\n\t\t\"./sw.js\": 415,\n\t\t\"./ta\": 416,\n\t\t\"./ta.js\": 416,\n\t\t\"./te\": 417,\n\t\t\"./te.js\": 417,\n\t\t\"./tet\": 418,\n\t\t\"./tet.js\": 418,\n\t\t\"./tg\": 419,\n\t\t\"./tg.js\": 419,\n\t\t\"./th\": 420,\n\t\t\"./th.js\": 420,\n\t\t\"./tk\": 421,\n\t\t\"./tk.js\": 421,\n\t\t\"./tl-ph\": 422,\n\t\t\"./tl-ph.js\": 422,\n\t\t\"./tlh\": 423,\n\t\t\"./tlh.js\": 423,\n\t\t\"./tr\": 424,\n\t\t\"./tr.js\": 424,\n\t\t\"./tzl\": 425,\n\t\t\"./tzl.js\": 425,\n\t\t\"./tzm\": 427,\n\t\t\"./tzm-latn\": 426,\n\t\t\"./tzm-latn.js\": 426,\n\t\t\"./tzm.js\": 427,\n\t\t\"./ug-cn\": 428,\n\t\t\"./ug-cn.js\": 428,\n\t\t\"./uk\": 429,\n\t\t\"./uk.js\": 429,\n\t\t\"./ur\": 430,\n\t\t\"./ur.js\": 430,\n\t\t\"./uz\": 432,\n\t\t\"./uz-latn\": 431,\n\t\t\"./uz-latn.js\": 431,\n\t\t\"./uz.js\": 432,\n\t\t\"./vi\": 433,\n\t\t\"./vi.js\": 433,\n\t\t\"./x-pseudo\": 434,\n\t\t\"./x-pseudo.js\": 434,\n\t\t\"./yo\": 435,\n\t\t\"./yo.js\": 435,\n\t\t\"./zh-cn\": 436,\n\t\t\"./zh-cn.js\": 436,\n\t\t\"./zh-hk\": 437,\n\t\t\"./zh-hk.js\": 437,\n\t\t\"./zh-mo\": 438,\n\t\t\"./zh-mo.js\": 438,\n\t\t\"./zh-tw\": 439,\n\t\t\"./zh-tw.js\": 439\n\t};\n\tfunction webpackContext(req) {\n\t\treturn __webpack_require__(webpackContextResolve(req));\n\t};\n\tfunction webpackContextResolve(req) {\n\t\treturn map[req] || (function() { throw new Error(\"Cannot find module '\" + req + \"'.\") }());\n\t};\n\twebpackContext.keys = function webpackContextKeys() {\n\t\treturn Object.keys(map);\n\t};\n\twebpackContext.resolve = webpackContextResolve;\n\tmodule.exports = webpackContext;\n\twebpackContext.id = 467;\n\n\n/***/ }),\n\n/***/ 885:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(console) {'use strict';\n\t\n\t/* eslint-disable */\n\t/* スマホ・タブレット利用制限処理 */\n\t$(document).ready(function () {\n\t\t// ページ読み込み時に実行したい処理\n\t\t// Ajax通信を開始\n\t\tif (window.getUtilizationTimeInfo === undefined) {\n\t\t\treturn;\n\t\t}\n\t\t$.ajax({\n\t\t\turl: window.getUtilizationTimeInfo,\n\t\t\ttype: 'GET',\n\t\t\tdataType: 'json',\n\t\t\t// フォーム要素の内容をハッシュ形式に変換\n\t\t\t//data: $('form').serializeArray(),\n\t\t\t//timeout: 5000,\n\t\t\tsuccess: function success(data) {\n\t\t\t\t// 通信成功時の処理を記述\n\t\t\t\tconsole.log('success');\n\t\t\t\tif (data.result) {\n\t\t\t\t\tif (data.logout) {\n\t\t\t\t\t\twindow.location = data.logout_url;\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\talert(\"利用権限情報の取得に失敗しました。\");\n\t\t\t\t};\n\t\t\t},\n\t\t\terror: function error() {\n\t\t\t\t// 通信失敗時の処理を記述\n\t\t\t\talert(\"利用権限情報の取得に失敗しました。\");\n\t\t\t}\n\t\t});\n\t});\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(7)))\n\n/***/ }),\n\n/***/ 890:\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\t__webpack_require__(695);\n\t\n\t__webpack_require__(1140);\n\t\n\t__webpack_require__(1142);\n\t\n\t__webpack_require__(1146);\n\t\n\t__webpack_require__(885);\n\n/***/ }),\n\n/***/ 1140:\n/***/ (function(module, exports) {\n\n\t/**\n\t * Created with IntelliJ IDEA.\n\t * User: takeo\n\t * Date: 2012/12/27\n\t * Time: 18:03\n\t * To change this template use File | Settings | File Templates.\n\t */\n\t\n\t\n\t\n\t$(function () {\n\t $(\"a[rel='popover']\").popover({\n\t offset: 10\n\t });\n\t $(\"a[rel='popover']\").on('click', function(e) {\n\t e.preventDefault();\n\t return true;\n\t });\n\t});\n\t\n\n\n/***/ }),\n\n/***/ 1142:\n/***/ (function(module, exports) {\n\n\t/**\n\t * 外部ウィンドウを開く\n\t * @param {Object} url\n\t * @param {Object} options\n\t */\n\tfunction openWindow(url, options){\n\t var setting = {\n\t //TODO ウィンドウ名は乱数で払いだすこと。\n\t name: 'newWindow',\n\t width: 800,\n\t height: 600\n\t };\n\t\n\t //オプションをマージする\n\t if (options) {\n\t setting = jQuery.extend(setting, options)\n\t };\n\t\n\t var nWindow = window.open(url, setting.name, 'width=' + setting.width + ', height=' + setting.height + ', menubar=no, toolbar=no, scrollbars=yes, resizable=yes');\n\t nWindow.focus();\n\t\n\t}\n\t\n\t/**\n\t * VCET受験画面を開く\n\t * @param assign_no\n\t * @return\n\t */\n\tfunction openVcetWindow(SUPER_EIGO_CONTEXT_PATH,assign_no,isPreview){\n\t var url = '/'+SUPER_EIGO_CONTEXT_PATH+'/lplayer/index.cfm?visionary=vcet&assign_no='+assign_no + '&previewType=assign_vc&isPreview='+isPreview;\n\t var options = {\n\t name: 'mywindow2',\n\t width: 1024,\n\t height: 700\n\t };\n\t openWindow(url, options);\n\t}\n\n\n/***/ }),\n\n/***/ 1146:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n\t * <%= meta.title %> v<%= meta.version %>\n\t * Docs & License: <%= meta.homepage %>\n\t * (c) <%= meta.copyright %>\n\t */\n\t\n\t(function(factory) {\n\t\tif (true) {\n\t\t\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(10), __webpack_require__(1) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t\t}\n\t\telse if (typeof exports === 'object') { // Node/CommonJS\n\t\t\tmodule.exports = factory(require('jquery'), require('moment'));\n\t\t}\n\t\telse {\n\t\t\tfactory(jQuery, moment);\n\t\t}\n\t})(function($, moment) {\n\t\n\t;;\n\t\n\tvar FC = $.fullCalendar = {\n\t\tversion: \"<%= meta.version %>\",\n\t\tinternalApiVersion: 5\n\t};\n\tvar fcViews = FC.views = {};\n\t\n\t\n\t$.fn.fullCalendar = function(options) {\n\t\tvar args = Array.prototype.slice.call(arguments, 1); // for a possible method call\n\t\tvar res = this; // what this function will return (this jQuery object by default)\n\t\n\t\tthis.each(function(i, _element) { // loop each DOM element involved\n\t\t\tvar element = $(_element);\n\t\t\tvar calendar = element.data('fullCalendar'); // get the existing calendar object (if any)\n\t\t\tvar singleRes; // the returned value of this single method call\n\t\n\t\t\t// a method call\n\t\t\tif (typeof options === 'string') {\n\t\t\t\tif (calendar && $.isFunction(calendar[options])) {\n\t\t\t\t\tsingleRes = calendar[options].apply(calendar, args);\n\t\t\t\t\tif (!i) {\n\t\t\t\t\t\tres = singleRes; // record the first method call result\n\t\t\t\t\t}\n\t\t\t\t\tif (options === 'destroy') { // for the destroy method, must remove Calendar object data\n\t\t\t\t\t\telement.removeData('fullCalendar');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// a new calendar initialization\n\t\t\telse if (!calendar) { // don't initialize twice\n\t\t\t\tcalendar = new Calendar(element, options);\n\t\t\t\telement.data('fullCalendar', calendar);\n\t\t\t\tcalendar.render();\n\t\t\t}\n\t\t});\n\t\t\n\t\treturn res;\n\t};\n\t\n\t\n\tvar complexOptions = [ // names of options that are objects whose properties should be combined\n\t\t'header',\n\t\t'buttonText',\n\t\t'buttonIcons',\n\t\t'themeButtonIcons'\n\t];\n\t\n\t\n\t// Merges an array of option objects into a single object\n\tfunction mergeOptions(optionObjs) {\n\t\treturn mergeProps(optionObjs, complexOptions);\n\t}\n\t\n\t\n\t// Given options specified for the calendar's constructor, massages any legacy options into a non-legacy form.\n\t// Converts View-Option-Hashes into the View-Specific-Options format.\n\tfunction massageOverrides(input) {\n\t\tvar overrides = { views: input.views || {} }; // the output. ensure a `views` hash\n\t\tvar subObj;\n\t\n\t\t// iterate through all option override properties (except `views`)\n\t\t$.each(input, function(name, val) {\n\t\t\tif (name != 'views') {\n\t\n\t\t\t\t// could the value be a legacy View-Option-Hash?\n\t\t\t\tif (\n\t\t\t\t\t$.isPlainObject(val) &&\n\t\t\t\t\t!/(time|duration|interval)$/i.test(name) && // exclude duration options. might be given as objects\n\t\t\t\t\t$.inArray(name, complexOptions) == -1 // complex options aren't allowed to be View-Option-Hashes\n\t\t\t\t) {\n\t\t\t\t\tsubObj = null;\n\t\n\t\t\t\t\t// iterate through the properties of this possible View-Option-Hash value\n\t\t\t\t\t$.each(val, function(subName, subVal) {\n\t\n\t\t\t\t\t\t// is the property targeting a view?\n\t\t\t\t\t\tif (/^(month|week|day|default|basic(Week|Day)?|agenda(Week|Day)?)$/.test(subName)) {\n\t\t\t\t\t\t\tif (!overrides.views[subName]) { // ensure the view-target entry exists\n\t\t\t\t\t\t\t\toverrides.views[subName] = {};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\toverrides.views[subName][name] = subVal; // record the value in the `views` object\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse { // a non-View-Option-Hash property\n\t\t\t\t\t\t\tif (!subObj) {\n\t\t\t\t\t\t\t\tsubObj = {};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsubObj[subName] = subVal; // accumulate these unrelated values for later\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\n\t\t\t\t\tif (subObj) { // non-View-Option-Hash properties? transfer them as-is\n\t\t\t\t\t\toverrides[name] = subObj;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\toverrides[name] = val; // transfer normal options as-is\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\n\t\treturn overrides;\n\t}\n\t\n\t;;\n\t\n\t// exports\n\tFC.intersectRanges = intersectRanges;\n\tFC.applyAll = applyAll;\n\tFC.debounce = debounce;\n\tFC.isInt = isInt;\n\tFC.htmlEscape = htmlEscape;\n\tFC.cssToStr = cssToStr;\n\tFC.proxy = proxy;\n\tFC.capitaliseFirstLetter = capitaliseFirstLetter;\n\t\n\t\n\t/* FullCalendar-specific DOM Utilities\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t// Given the scrollbar widths of some other container, create borders/margins on rowEls in order to match the left\n\t// and right space that was offset by the scrollbars. A 1-pixel border first, then margin beyond that.\n\tfunction compensateScroll(rowEls, scrollbarWidths) {\n\t\tif (scrollbarWidths.left) {\n\t\t\trowEls.css({\n\t\t\t\t'border-left-width': 1,\n\t\t\t\t'margin-left': scrollbarWidths.left - 1\n\t\t\t});\n\t\t}\n\t\tif (scrollbarWidths.right) {\n\t\t\trowEls.css({\n\t\t\t\t'border-right-width': 1,\n\t\t\t\t'margin-right': scrollbarWidths.right - 1\n\t\t\t});\n\t\t}\n\t}\n\t\n\t\n\t// Undoes compensateScroll and restores all borders/margins\n\tfunction uncompensateScroll(rowEls) {\n\t\trowEls.css({\n\t\t\t'margin-left': '',\n\t\t\t'margin-right': '',\n\t\t\t'border-left-width': '',\n\t\t\t'border-right-width': ''\n\t\t});\n\t}\n\t\n\t\n\t// Make the mouse cursor express that an event is not allowed in the current area\n\tfunction disableCursor() {\n\t\t$('body').addClass('fc-not-allowed');\n\t}\n\t\n\t\n\t// Returns the mouse cursor to its original look\n\tfunction enableCursor() {\n\t\t$('body').removeClass('fc-not-allowed');\n\t}\n\t\n\t\n\t// Given a total available height to fill, have `els` (essentially child rows) expand to accomodate.\n\t// By default, all elements that are shorter than the recommended height are expanded uniformly, not considering\n\t// any other els that are already too tall. if `shouldRedistribute` is on, it considers these tall rows and \n\t// reduces the available height.\n\tfunction distributeHeight(els, availableHeight, shouldRedistribute) {\n\t\n\t\t// *FLOORING NOTE*: we floor in certain places because zoom can give inaccurate floating-point dimensions,\n\t\t// and it is better to be shorter than taller, to avoid creating unnecessary scrollbars.\n\t\n\t\tvar minOffset1 = Math.floor(availableHeight / els.length); // for non-last element\n\t\tvar minOffset2 = Math.floor(availableHeight - minOffset1 * (els.length - 1)); // for last element *FLOORING NOTE*\n\t\tvar flexEls = []; // elements that are allowed to expand. array of DOM nodes\n\t\tvar flexOffsets = []; // amount of vertical space it takes up\n\t\tvar flexHeights = []; // actual css height\n\t\tvar usedHeight = 0;\n\t\n\t\tundistributeHeight(els); // give all elements their natural height\n\t\n\t\t// find elements that are below the recommended height (expandable).\n\t\t// important to query for heights in a single first pass (to avoid reflow oscillation).\n\t\tels.each(function(i, el) {\n\t\t\tvar minOffset = i === els.length - 1 ? minOffset2 : minOffset1;\n\t\t\tvar naturalOffset = $(el).outerHeight(true);\n\t\n\t\t\tif (naturalOffset < minOffset) {\n\t\t\t\tflexEls.push(el);\n\t\t\t\tflexOffsets.push(naturalOffset);\n\t\t\t\tflexHeights.push($(el).height());\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// this element stretches past recommended height (non-expandable). mark the space as occupied.\n\t\t\t\tusedHeight += naturalOffset;\n\t\t\t}\n\t\t});\n\t\n\t\t// readjust the recommended height to only consider the height available to non-maxed-out rows.\n\t\tif (shouldRedistribute) {\n\t\t\tavailableHeight -= usedHeight;\n\t\t\tminOffset1 = Math.floor(availableHeight / flexEls.length);\n\t\t\tminOffset2 = Math.floor(availableHeight - minOffset1 * (flexEls.length - 1)); // *FLOORING NOTE*\n\t\t}\n\t\n\t\t// assign heights to all expandable elements\n\t\t$(flexEls).each(function(i, el) {\n\t\t\tvar minOffset = i === flexEls.length - 1 ? minOffset2 : minOffset1;\n\t\t\tvar naturalOffset = flexOffsets[i];\n\t\t\tvar naturalHeight = flexHeights[i];\n\t\t\tvar newHeight = minOffset - (naturalOffset - naturalHeight); // subtract the margin/padding\n\t\n\t\t\tif (naturalOffset < minOffset) { // we check this again because redistribution might have changed things\n\t\t\t\t$(el).height(newHeight);\n\t\t\t}\n\t\t});\n\t}\n\t\n\t\n\t// Undoes distrubuteHeight, restoring all els to their natural height\n\tfunction undistributeHeight(els) {\n\t\tels.height('');\n\t}\n\t\n\t\n\t// Given `els`, a jQuery set of cells, find the cell with the largest natural width and set the widths of all the\n\t// cells to be that width.\n\t// PREREQUISITE: if you want a cell to take up width, it needs to have a single inner element w/ display:inline\n\tfunction matchCellWidths(els) {\n\t\tvar maxInnerWidth = 0;\n\t\n\t\tels.find('> span').each(function(i, innerEl) {\n\t\t\tvar innerWidth = $(innerEl).outerWidth();\n\t\t\tif (innerWidth > maxInnerWidth) {\n\t\t\t\tmaxInnerWidth = innerWidth;\n\t\t\t}\n\t\t});\n\t\n\t\tmaxInnerWidth++; // sometimes not accurate of width the text needs to stay on one line. insurance\n\t\n\t\tels.width(maxInnerWidth);\n\t\n\t\treturn maxInnerWidth;\n\t}\n\t\n\t\n\t// Given one element that resides inside another,\n\t// Subtracts the height of the inner element from the outer element.\n\tfunction subtractInnerElHeight(outerEl, innerEl) {\n\t\tvar both = outerEl.add(innerEl);\n\t\tvar diff;\n\t\n\t\t// effin' 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\tdiff = outerEl.outerHeight() - innerEl.outerHeight(); // grab the dimensions\n\t\tboth.css({ position: '', left: '' }); // undo hack\n\t\n\t\treturn diff;\n\t}\n\t\n\t\n\t/* Element Geom Utilities\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\tFC.getOuterRect = getOuterRect;\n\tFC.getClientRect = getClientRect;\n\tFC.getContentRect = getContentRect;\n\tFC.getScrollbarWidths = getScrollbarWidths;\n\t\n\t\n\t// borrowed from https://github.com/jquery/jquery-ui/blob/1.11.0/ui/core.js#L51\n\tfunction getScrollParent(el) {\n\t\tvar position = el.css('position'),\n\t\t\tscrollParent = el.parents().filter(function() {\n\t\t\t\tvar parent = $(this);\n\t\t\t\treturn (/(auto|scroll)/).test(\n\t\t\t\t\tparent.css('overflow') + parent.css('overflow-y') + parent.css('overflow-x')\n\t\t\t\t);\n\t\t\t}).eq(0);\n\t\n\t\treturn position === 'fixed' || !scrollParent.length ? $(el[0].ownerDocument || document) : scrollParent;\n\t}\n\t\n\t\n\t// Queries the outer bounding area of a jQuery element.\n\t// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).\n\t// Origin is optional.\n\tfunction getOuterRect(el, origin) {\n\t\tvar offset = el.offset();\n\t\tvar left = offset.left - (origin ? origin.left : 0);\n\t\tvar top = offset.top - (origin ? origin.top : 0);\n\t\n\t\treturn {\n\t\t\tleft: left,\n\t\t\tright: left + el.outerWidth(),\n\t\t\ttop: top,\n\t\t\tbottom: top + el.outerHeight()\n\t\t};\n\t}\n\t\n\t\n\t// Queries the area within the margin/border/scrollbars of a jQuery element. Does not go within the padding.\n\t// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).\n\t// Origin is optional.\n\t// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser.\n\tfunction getClientRect(el, origin) {\n\t\tvar offset = el.offset();\n\t\tvar scrollbarWidths = getScrollbarWidths(el);\n\t\tvar left = offset.left + getCssFloat(el, 'border-left-width') + scrollbarWidths.left - (origin ? origin.left : 0);\n\t\tvar top = offset.top + getCssFloat(el, 'border-top-width') + scrollbarWidths.top - (origin ? origin.top : 0);\n\t\n\t\treturn {\n\t\t\tleft: left,\n\t\t\tright: left + el[0].clientWidth, // clientWidth includes padding but NOT scrollbars\n\t\t\ttop: top,\n\t\t\tbottom: top + el[0].clientHeight // clientHeight includes padding but NOT scrollbars\n\t\t};\n\t}\n\t\n\t\n\t// Queries the area within the margin/border/padding of a jQuery element. Assumed not to have scrollbars.\n\t// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).\n\t// Origin is optional.\n\tfunction getContentRect(el, origin) {\n\t\tvar offset = el.offset(); // just outside of border, margin not included\n\t\tvar left = offset.left + getCssFloat(el, 'border-left-width') + getCssFloat(el, 'padding-left') -\n\t\t\t(origin ? origin.left : 0);\n\t\tvar top = offset.top + getCssFloat(el, 'border-top-width') + getCssFloat(el, 'padding-top') -\n\t\t\t(origin ? origin.top : 0);\n\t\n\t\treturn {\n\t\t\tleft: left,\n\t\t\tright: left + el.width(),\n\t\t\ttop: top,\n\t\t\tbottom: top + el.height()\n\t\t};\n\t}\n\t\n\t\n\t// Returns the computed left/right/top/bottom scrollbar widths for the given jQuery element.\n\t// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser.\n\tfunction getScrollbarWidths(el) {\n\t\tvar leftRightWidth = el.innerWidth() - el[0].clientWidth; // the paddings cancel out, leaving the scrollbars\n\t\tvar widths = {\n\t\t\tleft: 0,\n\t\t\tright: 0,\n\t\t\ttop: 0,\n\t\t\tbottom: el.innerHeight() - el[0].clientHeight // the paddings cancel out, leaving the bottom scrollbar\n\t\t};\n\t\n\t\tif (getIsLeftRtlScrollbars() && el.css('direction') == 'rtl') { // is the scrollbar on the left side?\n\t\t\twidths.left = leftRightWidth;\n\t\t}\n\t\telse {\n\t\t\twidths.right = leftRightWidth;\n\t\t}\n\t\n\t\treturn widths;\n\t}\n\t\n\t\n\t// Logic for determining if, when the element is right-to-left, the scrollbar appears on the left side\n\t\n\tvar _isLeftRtlScrollbars = null;\n\t\n\tfunction getIsLeftRtlScrollbars() { // responsible for caching the computation\n\t\tif (_isLeftRtlScrollbars === null) {\n\t\t\t_isLeftRtlScrollbars = computeIsLeftRtlScrollbars();\n\t\t}\n\t\treturn _isLeftRtlScrollbars;\n\t}\n\t\n\tfunction computeIsLeftRtlScrollbars() { // creates an offscreen test element, then removes it\n\t\tvar el = $('')\n\t\t\t.css({\n\t\t\t\tposition: 'absolute',\n\t\t\t\ttop: -1000,\n\t\t\t\tleft: 0,\n\t\t\t\tborder: 0,\n\t\t\t\tpadding: 0,\n\t\t\t\toverflow: 'scroll',\n\t\t\t\tdirection: 'rtl'\n\t\t\t})\n\t\t\t.appendTo('body');\n\t\tvar innerEl = el.children();\n\t\tvar res = innerEl.offset().left > el.offset().left; // is the inner div shifted to accommodate a left scrollbar?\n\t\tel.remove();\n\t\treturn res;\n\t}\n\t\n\t\n\t// Retrieves a jQuery element's computed CSS value as a floating-point number.\n\t// If the queried value is non-numeric (ex: IE can return \"medium\" for border width), will just return zero.\n\tfunction getCssFloat(el, prop) {\n\t\treturn parseFloat(el.css(prop)) || 0;\n\t}\n\t\n\t\n\t/* Mouse / Touch Utilities\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\tFC.preventDefault = preventDefault;\n\t\n\t\n\t// Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)\n\tfunction isPrimaryMouseButton(ev) {\n\t\treturn ev.which == 1 && !ev.ctrlKey;\n\t}\n\t\n\t\n\tfunction getEvX(ev) {\n\t\tif (ev.pageX !== undefined) {\n\t\t\treturn ev.pageX;\n\t\t}\n\t\tvar touches = ev.originalEvent.touches;\n\t\tif (touches) {\n\t\t\treturn touches[0].pageX;\n\t\t}\n\t}\n\t\n\t\n\tfunction getEvY(ev) {\n\t\tif (ev.pageY !== undefined) {\n\t\t\treturn ev.pageY;\n\t\t}\n\t\tvar touches = ev.originalEvent.touches;\n\t\tif (touches) {\n\t\t\treturn touches[0].pageY;\n\t\t}\n\t}\n\t\n\t\n\tfunction getEvIsTouch(ev) {\n\t\treturn /^touch/.test(ev.type);\n\t}\n\t\n\t\n\tfunction preventSelection(el) {\n\t\tel.addClass('fc-unselectable')\n\t\t\t.on('selectstart', preventDefault);\n\t}\n\t\n\t\n\t// Stops a mouse/touch event from doing it's native browser action\n\tfunction preventDefault(ev) {\n\t\tev.preventDefault();\n\t}\n\t\n\t\n\t// attach a handler to get called when ANY scroll action happens on the page.\n\t// this was impossible to do with normal on/off because 'scroll' doesn't bubble.\n\t// http://stackoverflow.com/a/32954565/96342\n\t// returns `true` on success.\n\tfunction bindAnyScroll(handler) {\n\t\tif (window.addEventListener) {\n\t\t\twindow.addEventListener('scroll', handler, true); // useCapture=true\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t\n\t// undoes bindAnyScroll. must pass in the original function.\n\t// returns `true` on success.\n\tfunction unbindAnyScroll(handler) {\n\t\tif (window.removeEventListener) {\n\t\t\twindow.removeEventListener('scroll', handler, true); // useCapture=true\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t\n\t/* General Geometry Utils\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\tFC.intersectRects = intersectRects;\n\t\n\t// Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false\n\tfunction intersectRects(rect1, rect2) {\n\t\tvar res = {\n\t\t\tleft: Math.max(rect1.left, rect2.left),\n\t\t\tright: Math.min(rect1.right, rect2.right),\n\t\t\ttop: Math.max(rect1.top, rect2.top),\n\t\t\tbottom: Math.min(rect1.bottom, rect2.bottom)\n\t\t};\n\t\n\t\tif (res.left < res.right && res.top < res.bottom) {\n\t\t\treturn res;\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t\n\t// Returns a new point that will have been moved to reside within the given rectangle\n\tfunction constrainPoint(point, rect) {\n\t\treturn {\n\t\t\tleft: Math.min(Math.max(point.left, rect.left), rect.right),\n\t\t\ttop: Math.min(Math.max(point.top, rect.top), rect.bottom)\n\t\t};\n\t}\n\t\n\t\n\t// Returns a point that is the center of the given rectangle\n\tfunction getRectCenter(rect) {\n\t\treturn {\n\t\t\tleft: (rect.left + rect.right) / 2,\n\t\t\ttop: (rect.top + rect.bottom) / 2\n\t\t};\n\t}\n\t\n\t\n\t// Subtracts point2's coordinates from point1's coordinates, returning a delta\n\tfunction diffPoints(point1, point2) {\n\t\treturn {\n\t\t\tleft: point1.left - point2.left,\n\t\t\ttop: point1.top - point2.top\n\t\t};\n\t}\n\t\n\t\n\t/* Object Ordering by Field\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\tFC.parseFieldSpecs = parseFieldSpecs;\n\tFC.compareByFieldSpecs = compareByFieldSpecs;\n\tFC.compareByFieldSpec = compareByFieldSpec;\n\tFC.flexibleCompare = flexibleCompare;\n\t\n\t\n\tfunction parseFieldSpecs(input) {\n\t\tvar specs = [];\n\t\tvar tokens = [];\n\t\tvar i, token;\n\t\n\t\tif (typeof input === 'string') {\n\t\t\ttokens = input.split(/\\s*,\\s*/);\n\t\t}\n\t\telse if (typeof input === 'function') {\n\t\t\ttokens = [ input ];\n\t\t}\n\t\telse if ($.isArray(input)) {\n\t\t\ttokens = input;\n\t\t}\n\t\n\t\tfor (i = 0; i < tokens.length; i++) {\n\t\t\ttoken = tokens[i];\n\t\n\t\t\tif (typeof token === 'string') {\n\t\t\t\tspecs.push(\n\t\t\t\t\ttoken.charAt(0) == '-' ?\n\t\t\t\t\t\t{ field: token.substring(1), order: -1 } :\n\t\t\t\t\t\t{ field: token, order: 1 }\n\t\t\t\t);\n\t\t\t}\n\t\t\telse if (typeof token === 'function') {\n\t\t\t\tspecs.push({ func: token });\n\t\t\t}\n\t\t}\n\t\n\t\treturn specs;\n\t}\n\t\n\t\n\tfunction compareByFieldSpecs(obj1, obj2, fieldSpecs) {\n\t\tvar i;\n\t\tvar cmp;\n\t\n\t\tfor (i = 0; i < fieldSpecs.length; i++) {\n\t\t\tcmp = compareByFieldSpec(obj1, obj2, fieldSpecs[i]);\n\t\t\tif (cmp) {\n\t\t\t\treturn cmp;\n\t\t\t}\n\t\t}\n\t\n\t\treturn 0;\n\t}\n\t\n\t\n\tfunction compareByFieldSpec(obj1, obj2, fieldSpec) {\n\t\tif (fieldSpec.func) {\n\t\t\treturn fieldSpec.func(obj1, obj2);\n\t\t}\n\t\treturn flexibleCompare(obj1[fieldSpec.field], obj2[fieldSpec.field]) *\n\t\t\t(fieldSpec.order || 1);\n\t}\n\t\n\t\n\tfunction flexibleCompare(a, b) {\n\t\tif (!a && !b) {\n\t\t\treturn 0;\n\t\t}\n\t\tif (b == null) {\n\t\t\treturn -1;\n\t\t}\n\t\tif (a == null) {\n\t\t\treturn 1;\n\t\t}\n\t\tif ($.type(a) === 'string' || $.type(b) === 'string') {\n\t\t\treturn String(a).localeCompare(String(b));\n\t\t}\n\t\treturn a - b;\n\t}\n\t\n\t\n\t/* FullCalendar-specific Misc Utilities\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t// Computes the intersection of the two ranges. Returns undefined if no intersection.\n\t// Expects all dates to be normalized to the same timezone beforehand.\n\t// TODO: move to date section?\n\tfunction intersectRanges(subjectRange, constraintRange) {\n\t\tvar subjectStart = subjectRange.start;\n\t\tvar subjectEnd = subjectRange.end;\n\t\tvar constraintStart = constraintRange.start;\n\t\tvar constraintEnd = constraintRange.end;\n\t\tvar segStart, segEnd;\n\t\tvar isStart, isEnd;\n\t\n\t\tif (subjectEnd > constraintStart && subjectStart < constraintEnd) { // in bounds at all?\n\t\n\t\t\tif (subjectStart >= constraintStart) {\n\t\t\t\tsegStart = subjectStart.clone();\n\t\t\t\tisStart = true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tsegStart = constraintStart.clone();\n\t\t\t\tisStart = false;\n\t\t\t}\n\t\n\t\t\tif (subjectEnd <= constraintEnd) {\n\t\t\t\tsegEnd = subjectEnd.clone();\n\t\t\t\tisEnd = true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tsegEnd = constraintEnd.clone();\n\t\t\t\tisEnd = false;\n\t\t\t}\n\t\n\t\t\treturn {\n\t\t\t\tstart: segStart,\n\t\t\t\tend: segEnd,\n\t\t\t\tisStart: isStart,\n\t\t\t\tisEnd: isEnd\n\t\t\t};\n\t\t}\n\t}\n\t\n\t\n\t/* Date Utilities\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\tFC.computeIntervalUnit = computeIntervalUnit;\n\tFC.divideRangeByDuration = divideRangeByDuration;\n\tFC.divideDurationByDuration = divideDurationByDuration;\n\tFC.multiplyDuration = multiplyDuration;\n\tFC.durationHasTime = durationHasTime;\n\t\n\tvar dayIDs = [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ];\n\tvar intervalUnits = [ 'year', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond' ];\n\t\n\t\n\t// Diffs the two moments into a Duration where full-days are recorded first, then the remaining time.\n\t// Moments will have their timezones normalized.\n\tfunction diffDayTime(a, b) {\n\t\treturn moment.duration({\n\t\t\tdays: a.clone().stripTime().diff(b.clone().stripTime(), 'days'),\n\t\t\tms: a.time() - b.time() // time-of-day from day start. disregards timezone\n\t\t});\n\t}\n\t\n\t\n\t// Diffs the two moments via their start-of-day (regardless of timezone). Produces whole-day durations.\n\tfunction diffDay(a, b) {\n\t\treturn moment.duration({\n\t\t\tdays: a.clone().stripTime().diff(b.clone().stripTime(), 'days')\n\t\t});\n\t}\n\t\n\t\n\t// Diffs two moments, producing a duration, made of a whole-unit-increment of the given unit. Uses rounding.\n\tfunction diffByUnit(a, b, unit) {\n\t\treturn moment.duration(\n\t\t\tMath.round(a.diff(b, unit, true)), // returnFloat=true\n\t\t\tunit\n\t\t);\n\t}\n\t\n\t\n\t// Computes the unit name of the largest whole-unit period of time.\n\t// For example, 48 hours will be \"days\" whereas 49 hours will be \"hours\".\n\t// Accepts start/end, a range object, or an original duration object.\n\tfunction computeIntervalUnit(start, end) {\n\t\tvar i, unit;\n\t\tvar val;\n\t\n\t\tfor (i = 0; i < intervalUnits.length; i++) {\n\t\t\tunit = intervalUnits[i];\n\t\t\tval = computeRangeAs(unit, start, end);\n\t\n\t\t\tif (val >= 1 && isInt(val)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\n\t\treturn unit; // will be \"milliseconds\" if nothing else matches\n\t}\n\t\n\t\n\t// Computes the number of units (like \"hours\") in the given range.\n\t// Range can be a {start,end} object, separate start/end args, or a Duration.\n\t// Results are based on Moment's .as() and .diff() methods, so results can depend on internal handling\n\t// of month-diffing logic (which tends to vary from version to version).\n\tfunction computeRangeAs(unit, start, end) {\n\t\n\t\tif (end != null) { // given start, end\n\t\t\treturn end.diff(start, unit, true);\n\t\t}\n\t\telse if (moment.isDuration(start)) { // given duration\n\t\t\treturn start.as(unit);\n\t\t}\n\t\telse { // given { start, end } range object\n\t\t\treturn start.end.diff(start.start, unit, true);\n\t\t}\n\t}\n\t\n\t\n\t// Intelligently divides a range (specified by a start/end params) by a duration\n\tfunction divideRangeByDuration(start, end, dur) {\n\t\tvar months;\n\t\n\t\tif (durationHasTime(dur)) {\n\t\t\treturn (end - start) / dur;\n\t\t}\n\t\tmonths = dur.asMonths();\n\t\tif (Math.abs(months) >= 1 && isInt(months)) {\n\t\t\treturn end.diff(start, 'months', true) / months;\n\t\t}\n\t\treturn end.diff(start, 'days', true) / dur.asDays();\n\t}\n\t\n\t\n\t// Intelligently divides one duration by another\n\tfunction divideDurationByDuration(dur1, dur2) {\n\t\tvar months1, months2;\n\t\n\t\tif (durationHasTime(dur1) || durationHasTime(dur2)) {\n\t\t\treturn dur1 / dur2;\n\t\t}\n\t\tmonths1 = dur1.asMonths();\n\t\tmonths2 = dur2.asMonths();\n\t\tif (\n\t\t\tMath.abs(months1) >= 1 && isInt(months1) &&\n\t\t\tMath.abs(months2) >= 1 && isInt(months2)\n\t\t) {\n\t\t\treturn months1 / months2;\n\t\t}\n\t\treturn dur1.asDays() / dur2.asDays();\n\t}\n\t\n\t\n\t// Intelligently multiplies a duration by a number\n\tfunction multiplyDuration(dur, n) {\n\t\tvar months;\n\t\n\t\tif (durationHasTime(dur)) {\n\t\t\treturn moment.duration(dur * n);\n\t\t}\n\t\tmonths = dur.asMonths();\n\t\tif (Math.abs(months) >= 1 && isInt(months)) {\n\t\t\treturn moment.duration({ months: months * n });\n\t\t}\n\t\treturn moment.duration({ days: dur.asDays() * n });\n\t}\n\t\n\t\n\t// Returns a boolean about whether the given duration has any time parts (hours/minutes/seconds/ms)\n\tfunction durationHasTime(dur) {\n\t\treturn Boolean(dur.hours() || dur.minutes() || dur.seconds() || dur.milliseconds());\n\t}\n\t\n\t\n\tfunction isNativeDate(input) {\n\t\treturn Object.prototype.toString.call(input) === '[object Date]' || input instanceof Date;\n\t}\n\t\n\t\n\t// Returns a boolean about whether the given input is a time string, like \"06:40:00\" or \"06:00\"\n\tfunction isTimeString(str) {\n\t\treturn /^\\d+\\:\\d+(?:\\:\\d+\\.?(?:\\d{3})?)?$/.test(str);\n\t}\n\t\n\t\n\t/* Logging and Debug\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\tFC.log = function() {\n\t\tvar console = window.console;\n\t\n\t\tif (console && console.log) {\n\t\t\treturn console.log.apply(console, arguments);\n\t\t}\n\t};\n\t\n\tFC.warn = function() {\n\t\tvar console = window.console;\n\t\n\t\tif (console && console.warn) {\n\t\t\treturn console.warn.apply(console, arguments);\n\t\t}\n\t\telse {\n\t\t\treturn FC.log.apply(FC, arguments);\n\t\t}\n\t};\n\t\n\t\n\t/* General Utilities\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\tvar hasOwnPropMethod = {}.hasOwnProperty;\n\t\n\t\n\t// Merges an array of objects into a single object.\n\t// The second argument allows for an array of property names who's object values will be merged together.\n\tfunction mergeProps(propObjs, complexProps) {\n\t\tvar dest = {};\n\t\tvar i, name;\n\t\tvar complexObjs;\n\t\tvar j, val;\n\t\tvar props;\n\t\n\t\tif (complexProps) {\n\t\t\tfor (i = 0; i < complexProps.length; i++) {\n\t\t\t\tname = complexProps[i];\n\t\t\t\tcomplexObjs = [];\n\t\n\t\t\t\t// collect the trailing object values, stopping when a non-object is discovered\n\t\t\t\tfor (j = propObjs.length - 1; j >= 0; j--) {\n\t\t\t\t\tval = propObjs[j][name];\n\t\n\t\t\t\t\tif (typeof val === 'object') {\n\t\t\t\t\t\tcomplexObjs.unshift(val);\n\t\t\t\t\t}\n\t\t\t\t\telse if (val !== undefined) {\n\t\t\t\t\t\tdest[name] = val; // if there were no objects, this value will be used\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\t// if the trailing values were objects, use the merged value\n\t\t\t\tif (complexObjs.length) {\n\t\t\t\t\tdest[name] = mergeProps(complexObjs);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\t// copy values into the destination, going from last to first\n\t\tfor (i = propObjs.length - 1; i >= 0; i--) {\n\t\t\tprops = propObjs[i];\n\t\n\t\t\tfor (name in props) {\n\t\t\t\tif (!(name in dest)) { // if already assigned by previous props or complex props, don't reassign\n\t\t\t\t\tdest[name] = props[name];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\treturn dest;\n\t}\n\t\n\t\n\t// Create an object that has the given prototype. Just like Object.create\n\tfunction createObject(proto) {\n\t\tvar f = function() {};\n\t\tf.prototype = proto;\n\t\treturn new f();\n\t}\n\t\n\t\n\tfunction copyOwnProps(src, dest) {\n\t\tfor (var name in src) {\n\t\t\tif (hasOwnProp(src, name)) {\n\t\t\t\tdest[name] = src[name];\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t// Copies over certain methods with the same names as Object.prototype methods. Overcomes an IE<=8 bug:\n\t// https://developer.mozilla.org/en-US/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug\n\tfunction copyNativeMethods(src, dest) {\n\t\tvar names = [ 'constructor', 'toString', 'valueOf' ];\n\t\tvar i, name;\n\t\n\t\tfor (i = 0; i < names.length; i++) {\n\t\t\tname = names[i];\n\t\n\t\t\tif (src[name] !== Object.prototype[name]) {\n\t\t\t\tdest[name] = src[name];\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\tfunction hasOwnProp(obj, name) {\n\t\treturn hasOwnPropMethod.call(obj, name);\n\t}\n\t\n\t\n\t// Is the given value a non-object non-function value?\n\tfunction isAtomic(val) {\n\t\treturn /undefined|null|boolean|number|string/.test($.type(val));\n\t}\n\t\n\t\n\tfunction applyAll(functions, thisObj, args) {\n\t\tif ($.isFunction(functions)) {\n\t\t\tfunctions = [ functions ];\n\t\t}\n\t\tif (functions) {\n\t\t\tvar i;\n\t\t\tvar ret;\n\t\t\tfor (i=0; i/g, '>')\n\t\t\t.replace(/'/g, ''')\n\t\t\t.replace(/\"/g, '"')\n\t\t\t.replace(/\\n/g, ' ');\n\t}\n\t\n\t\n\tfunction stripHtmlEntities(text) {\n\t\treturn text.replace(/&.*?;/g, '');\n\t}\n\t\n\t\n\t// Given a hash of CSS properties, returns a string of CSS.\n\t// Uses property names as-is (no camel-case conversion). Will not make statements for null/undefined values.\n\tfunction cssToStr(cssProps) {\n\t\tvar statements = [];\n\t\n\t\t$.each(cssProps, function(name, val) {\n\t\t\tif (val != null) {\n\t\t\t\tstatements.push(name + ':' + val);\n\t\t\t}\n\t\t});\n\t\n\t\treturn statements.join(';');\n\t}\n\t\n\t\n\tfunction capitaliseFirstLetter(str) {\n\t\treturn str.charAt(0).toUpperCase() + str.slice(1);\n\t}\n\t\n\t\n\tfunction compareNumbers(a, b) { // for .sort()\n\t\treturn a - b;\n\t}\n\t\n\t\n\tfunction isInt(n) {\n\t\treturn n % 1 === 0;\n\t}\n\t\n\t\n\t// Returns a method bound to the given object context.\n\t// Just like one of the jQuery.proxy signatures, but without the undesired behavior of treating the same method with\n\t// different contexts as identical when binding/unbinding events.\n\tfunction proxy(obj, methodName) {\n\t\tvar method = obj[methodName];\n\t\n\t\treturn function() {\n\t\t\treturn method.apply(obj, arguments);\n\t\t};\n\t}\n\t\n\t\n\t// Returns a function, that, as long as it continues to be invoked, will not\n\t// be triggered. The function will be called after it stops being called for\n\t// N milliseconds. If `immediate` is passed, trigger the function on the\n\t// leading edge, instead of the trailing.\n\t// https://github.com/jashkenas/underscore/blob/1.6.0/underscore.js#L714\n\tfunction debounce(func, wait, immediate) {\n\t\tvar timeout, args, context, timestamp, result;\n\t\n\t\tvar later = function() {\n\t\t\tvar last = +new Date() - timestamp;\n\t\t\tif (last < wait) {\n\t\t\t\ttimeout = setTimeout(later, wait - last);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttimeout = null;\n\t\t\t\tif (!immediate) {\n\t\t\t\t\tresult = func.apply(context, args);\n\t\t\t\t\tcontext = args = null;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\n\t\treturn function() {\n\t\t\tcontext = this;\n\t\t\targs = arguments;\n\t\t\ttimestamp = +new Date();\n\t\t\tvar callNow = immediate && !timeout;\n\t\t\tif (!timeout) {\n\t\t\t\ttimeout = setTimeout(later, wait);\n\t\t\t}\n\t\t\tif (callNow) {\n\t\t\t\tresult = func.apply(context, args);\n\t\t\t\tcontext = args = null;\n\t\t\t}\n\t\t\treturn result;\n\t\t};\n\t}\n\t\n\t\n\t// HACK around jQuery's now A+ promises: execute callback synchronously if already resolved.\n\t// thenFunc shouldn't accept args.\n\t// similar to whenResources in Scheduler plugin.\n\tfunction syncThen(promise, thenFunc) {\n\t\t// not a promise, or an already-resolved promise?\n\t\tif (!promise || !promise.then || promise.state() === 'resolved') {\n\t\t\treturn $.when(thenFunc()); // resolve immediately\n\t\t}\n\t\telse if (thenFunc) {\n\t\t\treturn promise.then(thenFunc);\n\t\t}\n\t}\n\t\n\t;;\n\t\n\tvar ambigDateOfMonthRegex = /^\\s*\\d{4}-\\d\\d$/;\n\tvar ambigTimeOrZoneRegex =\n\t\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+)?)?)?)?)?$/;\n\tvar newMomentProto = moment.fn; // where we will attach our new methods\n\tvar oldMomentProto = $.extend({}, newMomentProto); // copy of original moment methods\n\tvar allowValueOptimization;\n\tvar setUTCValues; // function defined below\n\tvar setLocalValues; // function defined below\n\t\n\t\n\t// Creating\n\t// -------------------------------------------------------------------------------------------------\n\t\n\t// Creates a new moment, similar to the vanilla moment(...) constructor, but with\n\t// extra features (ambiguous time, enhanced formatting). When given an existing moment,\n\t// it will function as a clone (and retain the zone of the moment). Anything else will\n\t// result in a moment in the local zone.\n\tFC.moment = function() {\n\t\treturn makeMoment(arguments);\n\t};\n\t\n\t// Sames as FC.moment, but forces the resulting moment to be in the UTC timezone.\n\tFC.moment.utc = function() {\n\t\tvar mom = makeMoment(arguments, true);\n\t\n\t\t// Force it into UTC because makeMoment doesn't guarantee it\n\t\t// (if given a pre-existing moment for example)\n\t\tif (mom.hasTime()) { // don't give ambiguously-timed moments a UTC zone\n\t\t\tmom.utc();\n\t\t}\n\t\n\t\treturn mom;\n\t};\n\t\n\t// Same as FC.moment, but when given an ISO8601 string, the timezone offset is preserved.\n\t// ISO8601 strings with no timezone offset will become ambiguously zoned.\n\tFC.moment.parseZone = function() {\n\t\treturn makeMoment(arguments, true, true);\n\t};\n\t\n\t// Builds an enhanced moment from args. When given an existing moment, it clones. When given a\n\t// native Date, or called with no arguments (the current time), the resulting moment will be local.\n\t// Anything else needs to be \"parsed\" (a string or an array), and will be affected by:\n\t// parseAsUTC - if there is no zone information, should we parse the input in UTC?\n\t// parseZone - if there is zone information, should we force the zone of the moment?\n\tfunction makeMoment(args, parseAsUTC, parseZone) {\n\t\tvar input = args[0];\n\t\tvar isSingleString = args.length == 1 && typeof input === 'string';\n\t\tvar isAmbigTime;\n\t\tvar isAmbigZone;\n\t\tvar ambigMatch;\n\t\tvar mom;\n\t\n\t\tif (moment.isMoment(input)) {\n\t\t\tmom = moment.apply(null, args); // clone it\n\t\t\ttransferAmbigs(input, mom); // the ambig flags weren't transfered with the clone\n\t\t}\n\t\telse if (isNativeDate(input) || input === undefined) {\n\t\t\tmom = moment.apply(null, args); // will be local\n\t\t}\n\t\telse { // \"parsing\" is required\n\t\t\tisAmbigTime = false;\n\t\t\tisAmbigZone = false;\n\t\n\t\t\tif (isSingleString) {\n\t\t\t\tif (ambigDateOfMonthRegex.test(input)) {\n\t\t\t\t\t// accept strings like '2014-05', but convert to the first of the month\n\t\t\t\t\tinput += '-01';\n\t\t\t\t\targs = [ input ]; // for when we pass it on to moment's constructor\n\t\t\t\t\tisAmbigTime = true;\n\t\t\t\t\tisAmbigZone = true;\n\t\t\t\t}\n\t\t\t\telse if ((ambigMatch = ambigTimeOrZoneRegex.exec(input))) {\n\t\t\t\t\tisAmbigTime = !ambigMatch[5]; // no time part?\n\t\t\t\t\tisAmbigZone = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ($.isArray(input)) {\n\t\t\t\t// arrays have no timezone information, so assume ambiguous zone\n\t\t\t\tisAmbigZone = true;\n\t\t\t}\n\t\t\t// otherwise, probably a string with a format\n\t\n\t\t\tif (parseAsUTC || isAmbigTime) {\n\t\t\t\tmom = moment.utc.apply(moment, args);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tmom = moment.apply(null, args);\n\t\t\t}\n\t\n\t\t\tif (isAmbigTime) {\n\t\t\t\tmom._ambigTime = true;\n\t\t\t\tmom._ambigZone = true; // ambiguous time always means ambiguous zone\n\t\t\t}\n\t\t\telse if (parseZone) { // let's record the inputted zone somehow\n\t\t\t\tif (isAmbigZone) {\n\t\t\t\t\tmom._ambigZone = true;\n\t\t\t\t}\n\t\t\t\telse if (isSingleString) {\n\t\t\t\t\tif (mom.utcOffset) {\n\t\t\t\t\t\tmom.utcOffset(input); // if not a valid zone, will assign UTC\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tmom.zone(input); // for moment-pre-2.9\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\tmom._fullCalendar = true; // flag for extended functionality\n\t\n\t\treturn mom;\n\t}\n\t\n\t\n\t// A clone method that works with the flags related to our enhanced functionality.\n\t// In the future, use moment.momentProperties\n\tnewMomentProto.clone = function() {\n\t\tvar mom = oldMomentProto.clone.apply(this, arguments);\n\t\n\t\t// these flags weren't transfered with the clone\n\t\ttransferAmbigs(this, mom);\n\t\tif (this._fullCalendar) {\n\t\t\tmom._fullCalendar = true;\n\t\t}\n\t\n\t\treturn mom;\n\t};\n\t\n\t\n\t// Week Number\n\t// -------------------------------------------------------------------------------------------------\n\t\n\t\n\t// Returns the week number, considering the locale's custom week number calcuation\n\t// `weeks` is an alias for `week`\n\tnewMomentProto.week = newMomentProto.weeks = function(input) {\n\t\tvar weekCalc = (this._locale || this._lang) // works pre-moment-2.8\n\t\t\t._fullCalendar_weekCalc;\n\t\n\t\tif (input == null && typeof weekCalc === 'function') { // custom function only works for getter\n\t\t\treturn weekCalc(this);\n\t\t}\n\t\telse if (weekCalc === 'ISO') {\n\t\t\treturn oldMomentProto.isoWeek.apply(this, arguments); // ISO getter/setter\n\t\t}\n\t\n\t\treturn oldMomentProto.week.apply(this, arguments); // local getter/setter\n\t};\n\t\n\t\n\t// Time-of-day\n\t// -------------------------------------------------------------------------------------------------\n\t\n\t// GETTER\n\t// Returns a Duration with the hours/minutes/seconds/ms values of the moment.\n\t// If the moment has an ambiguous time, a duration of 00:00 will be returned.\n\t//\n\t// SETTER\n\t// You can supply a Duration, a Moment, or a Duration-like argument.\n\t// When setting the time, and the moment has an ambiguous time, it then becomes unambiguous.\n\tnewMomentProto.time = function(time) {\n\t\n\t\t// Fallback to the original method (if there is one) if this moment wasn't created via FullCalendar.\n\t\t// `time` is a generic enough method name where this precaution is necessary to avoid collisions w/ other plugins.\n\t\tif (!this._fullCalendar) {\n\t\t\treturn oldMomentProto.time.apply(this, arguments);\n\t\t}\n\t\n\t\tif (time == null) { // getter\n\t\t\treturn moment.duration({\n\t\t\t\thours: this.hours(),\n\t\t\t\tminutes: this.minutes(),\n\t\t\t\tseconds: this.seconds(),\n\t\t\t\tmilliseconds: this.milliseconds()\n\t\t\t});\n\t\t}\n\t\telse { // setter\n\t\n\t\t\tthis._ambigTime = false; // mark that the moment now has a time\n\t\n\t\t\tif (!moment.isDuration(time) && !moment.isMoment(time)) {\n\t\t\t\ttime = moment.duration(time);\n\t\t\t}\n\t\n\t\t\t// The day value should cause overflow (so 24 hours becomes 00:00:00 of next day).\n\t\t\t// Only for Duration times, not Moment times.\n\t\t\tvar dayHours = 0;\n\t\t\tif (moment.isDuration(time)) {\n\t\t\t\tdayHours = Math.floor(time.asDays()) * 24;\n\t\t\t}\n\t\n\t\t\t// We need to set the individual fields.\n\t\t\t// Can't use startOf('day') then add duration. In case of DST at start of day.\n\t\t\treturn this.hours(dayHours + time.hours())\n\t\t\t\t.minutes(time.minutes())\n\t\t\t\t.seconds(time.seconds())\n\t\t\t\t.milliseconds(time.milliseconds());\n\t\t}\n\t};\n\t\n\t// Converts the moment to UTC, stripping out its time-of-day and timezone offset,\n\t// but preserving its YMD. A moment with a stripped time will display no time\n\t// nor timezone offset when .format() is called.\n\tnewMomentProto.stripTime = function() {\n\t\tvar a;\n\t\n\t\tif (!this._ambigTime) {\n\t\n\t\t\t// get the values before any conversion happens\n\t\t\ta = this.toArray(); // array of y/m/d/h/m/s/ms\n\t\n\t\t\t// TODO: use keepLocalTime in the future\n\t\t\tthis.utc(); // set the internal UTC flag (will clear the ambig flags)\n\t\t\tsetUTCValues(this, a.slice(0, 3)); // set the year/month/date. time will be zero\n\t\n\t\t\t// Mark the time as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(),\n\t\t\t// which clears all ambig flags. Same with setUTCValues with moment-timezone.\n\t\t\tthis._ambigTime = true;\n\t\t\tthis._ambigZone = true; // if ambiguous time, also ambiguous timezone offset\n\t\t}\n\t\n\t\treturn this; // for chaining\n\t};\n\t\n\t// Returns if the moment has a non-ambiguous time (boolean)\n\tnewMomentProto.hasTime = function() {\n\t\treturn !this._ambigTime;\n\t};\n\t\n\t\n\t// Timezone\n\t// -------------------------------------------------------------------------------------------------\n\t\n\t// Converts the moment to UTC, stripping out its timezone offset, but preserving its\n\t// YMD and time-of-day. A moment with a stripped timezone offset will display no\n\t// timezone offset when .format() is called.\n\t// TODO: look into Moment's keepLocalTime functionality\n\tnewMomentProto.stripZone = function() {\n\t\tvar a, wasAmbigTime;\n\t\n\t\tif (!this._ambigZone) {\n\t\n\t\t\t// get the values before any conversion happens\n\t\t\ta = this.toArray(); // array of y/m/d/h/m/s/ms\n\t\t\twasAmbigTime = this._ambigTime;\n\t\n\t\t\tthis.utc(); // set the internal UTC flag (might clear the ambig flags, depending on Moment internals)\n\t\t\tsetUTCValues(this, a); // will set the year/month/date/hours/minutes/seconds/ms\n\t\n\t\t\t// the above call to .utc()/.utcOffset() unfortunately might clear the ambig flags, so restore\n\t\t\tthis._ambigTime = wasAmbigTime || false;\n\t\n\t\t\t// Mark the zone as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(),\n\t\t\t// which clears the ambig flags. Same with setUTCValues with moment-timezone.\n\t\t\tthis._ambigZone = true;\n\t\t}\n\t\n\t\treturn this; // for chaining\n\t};\n\t\n\t// Returns of the moment has a non-ambiguous timezone offset (boolean)\n\tnewMomentProto.hasZone = function() {\n\t\treturn !this._ambigZone;\n\t};\n\t\n\t\n\t// this method implicitly marks a zone\n\tnewMomentProto.local = function() {\n\t\tvar a = this.toArray(); // year,month,date,hours,minutes,seconds,ms as an array\n\t\tvar wasAmbigZone = this._ambigZone;\n\t\n\t\toldMomentProto.local.apply(this, arguments);\n\t\n\t\t// ensure non-ambiguous\n\t\t// this probably already happened via local() -> utcOffset(), but don't rely on Moment's internals\n\t\tthis._ambigTime = false;\n\t\tthis._ambigZone = false;\n\t\n\t\tif (wasAmbigZone) {\n\t\t\t// If the moment was ambiguously zoned, the date fields were stored as UTC.\n\t\t\t// We want to preserve these, but in local time.\n\t\t\t// TODO: look into Moment's keepLocalTime functionality\n\t\t\tsetLocalValues(this, a);\n\t\t}\n\t\n\t\treturn this; // for chaining\n\t};\n\t\n\t\n\t// implicitly marks a zone\n\tnewMomentProto.utc = function() {\n\t\toldMomentProto.utc.apply(this, arguments);\n\t\n\t\t// ensure non-ambiguous\n\t\t// this probably already happened via utc() -> utcOffset(), but don't rely on Moment's internals\n\t\tthis._ambigTime = false;\n\t\tthis._ambigZone = false;\n\t\n\t\treturn this;\n\t};\n\t\n\t\n\t// methods for arbitrarily manipulating timezone offset.\n\t// should clear time/zone ambiguity when called.\n\t$.each([\n\t\t'zone', // only in moment-pre-2.9. deprecated afterwards\n\t\t'utcOffset'\n\t], function(i, name) {\n\t\tif (oldMomentProto[name]) { // original method exists?\n\t\n\t\t\t// this method implicitly marks a zone (will probably get called upon .utc() and .local())\n\t\t\tnewMomentProto[name] = function(tzo) {\n\t\n\t\t\t\tif (tzo != null) { // setter\n\t\t\t\t\t// these assignments needs to happen before the original zone method is called.\n\t\t\t\t\t// I forget why, something to do with a browser crash.\n\t\t\t\t\tthis._ambigTime = false;\n\t\t\t\t\tthis._ambigZone = false;\n\t\t\t\t}\n\t\n\t\t\t\treturn oldMomentProto[name].apply(this, arguments);\n\t\t\t};\n\t\t}\n\t});\n\t\n\t\n\t// Formatting\n\t// -------------------------------------------------------------------------------------------------\n\t\n\tnewMomentProto.format = function() {\n\t\tif (this._fullCalendar && arguments[0]) { // an enhanced moment? and a format string provided?\n\t\t\treturn formatDate(this, arguments[0]); // our extended formatting\n\t\t}\n\t\tif (this._ambigTime) {\n\t\t\treturn oldMomentFormat(this, 'YYYY-MM-DD');\n\t\t}\n\t\tif (this._ambigZone) {\n\t\t\treturn oldMomentFormat(this, 'YYYY-MM-DD[T]HH:mm:ss');\n\t\t}\n\t\treturn oldMomentProto.format.apply(this, arguments);\n\t};\n\t\n\tnewMomentProto.toISOString = function() {\n\t\tif (this._ambigTime) {\n\t\t\treturn oldMomentFormat(this, 'YYYY-MM-DD');\n\t\t}\n\t\tif (this._ambigZone) {\n\t\t\treturn oldMomentFormat(this, 'YYYY-MM-DD[T]HH:mm:ss');\n\t\t}\n\t\treturn oldMomentProto.toISOString.apply(this, arguments);\n\t};\n\t\n\t\n\t// Querying\n\t// -------------------------------------------------------------------------------------------------\n\t\n\t// Is the moment within the specified range? `end` is exclusive.\n\t// FYI, this method is not a standard Moment method, so always do our enhanced logic.\n\tnewMomentProto.isWithin = function(start, end) {\n\t\tvar a = commonlyAmbiguate([ this, start, end ]);\n\t\treturn a[0] >= a[1] && a[0] < a[2];\n\t};\n\t\n\t// When isSame is called with units, timezone ambiguity is normalized before the comparison happens.\n\t// If no units specified, the two moments must be identically the same, with matching ambig flags.\n\tnewMomentProto.isSame = function(input, units) {\n\t\tvar a;\n\t\n\t\t// only do custom logic if this is an enhanced moment\n\t\tif (!this._fullCalendar) {\n\t\t\treturn oldMomentProto.isSame.apply(this, arguments);\n\t\t}\n\t\n\t\tif (units) {\n\t\t\ta = commonlyAmbiguate([ this, input ], true); // normalize timezones but don't erase times\n\t\t\treturn oldMomentProto.isSame.call(a[0], a[1], units);\n\t\t}\n\t\telse {\n\t\t\tinput = FC.moment.parseZone(input); // normalize input\n\t\t\treturn oldMomentProto.isSame.call(this, input) &&\n\t\t\t\tBoolean(this._ambigTime) === Boolean(input._ambigTime) &&\n\t\t\t\tBoolean(this._ambigZone) === Boolean(input._ambigZone);\n\t\t}\n\t};\n\t\n\t// Make these query methods work with ambiguous moments\n\t$.each([\n\t\t'isBefore',\n\t\t'isAfter'\n\t], function(i, methodName) {\n\t\tnewMomentProto[methodName] = function(input, units) {\n\t\t\tvar a;\n\t\n\t\t\t// only do custom logic if this is an enhanced moment\n\t\t\tif (!this._fullCalendar) {\n\t\t\t\treturn oldMomentProto[methodName].apply(this, arguments);\n\t\t\t}\n\t\n\t\t\ta = commonlyAmbiguate([ this, input ]);\n\t\t\treturn oldMomentProto[methodName].call(a[0], a[1], units);\n\t\t};\n\t});\n\t\n\t\n\t// Misc Internals\n\t// -------------------------------------------------------------------------------------------------\n\t\n\t// given an array of moment-like inputs, return a parallel array w/ moments similarly ambiguated.\n\t// for example, of one moment has ambig time, but not others, all moments will have their time stripped.\n\t// set `preserveTime` to `true` to keep times, but only normalize zone ambiguity.\n\t// returns the original moments if no modifications are necessary.\n\tfunction commonlyAmbiguate(inputs, preserveTime) {\n\t\tvar anyAmbigTime = false;\n\t\tvar anyAmbigZone = false;\n\t\tvar len = inputs.length;\n\t\tvar moms = [];\n\t\tvar i, mom;\n\t\n\t\t// parse inputs into real moments and query their ambig flags\n\t\tfor (i = 0; i < len; i++) {\n\t\t\tmom = inputs[i];\n\t\t\tif (!moment.isMoment(mom)) {\n\t\t\t\tmom = FC.moment.parseZone(mom);\n\t\t\t}\n\t\t\tanyAmbigTime = anyAmbigTime || mom._ambigTime;\n\t\t\tanyAmbigZone = anyAmbigZone || mom._ambigZone;\n\t\t\tmoms.push(mom);\n\t\t}\n\t\n\t\t// strip each moment down to lowest common ambiguity\n\t\t// use clones to avoid modifying the original moments\n\t\tfor (i = 0; i < len; i++) {\n\t\t\tmom = moms[i];\n\t\t\tif (!preserveTime && anyAmbigTime && !mom._ambigTime) {\n\t\t\t\tmoms[i] = mom.clone().stripTime();\n\t\t\t}\n\t\t\telse if (anyAmbigZone && !mom._ambigZone) {\n\t\t\t\tmoms[i] = mom.clone().stripZone();\n\t\t\t}\n\t\t}\n\t\n\t\treturn moms;\n\t}\n\t\n\t// Transfers all the flags related to ambiguous time/zone from the `src` moment to the `dest` moment\n\t// TODO: look into moment.momentProperties for this.\n\tfunction transferAmbigs(src, dest) {\n\t\tif (src._ambigTime) {\n\t\t\tdest._ambigTime = true;\n\t\t}\n\t\telse if (dest._ambigTime) {\n\t\t\tdest._ambigTime = false;\n\t\t}\n\t\n\t\tif (src._ambigZone) {\n\t\t\tdest._ambigZone = true;\n\t\t}\n\t\telse if (dest._ambigZone) {\n\t\t\tdest._ambigZone = false;\n\t\t}\n\t}\n\t\n\t\n\t// Sets the year/month/date/etc values of the moment from the given array.\n\t// Inefficient because it calls each individual setter.\n\tfunction setMomentValues(mom, a) {\n\t\tmom.year(a[0] || 0)\n\t\t\t.month(a[1] || 0)\n\t\t\t.date(a[2] || 0)\n\t\t\t.hours(a[3] || 0)\n\t\t\t.minutes(a[4] || 0)\n\t\t\t.seconds(a[5] || 0)\n\t\t\t.milliseconds(a[6] || 0);\n\t}\n\t\n\t// Can we set the moment's internal date directly?\n\tallowValueOptimization = '_d' in moment() && 'updateOffset' in moment;\n\t\n\t// Utility function. Accepts a moment and an array of the UTC year/month/date/etc values to set.\n\t// Assumes the given moment is already in UTC mode.\n\tsetUTCValues = allowValueOptimization ? function(mom, a) {\n\t\t// simlate what moment's accessors do\n\t\tmom._d.setTime(Date.UTC.apply(Date, a));\n\t\tmoment.updateOffset(mom, false); // keepTime=false\n\t} : setMomentValues;\n\t\n\t// Utility function. Accepts a moment and an array of the local year/month/date/etc values to set.\n\t// Assumes the given moment is already in local mode.\n\tsetLocalValues = allowValueOptimization ? function(mom, a) {\n\t\t// simlate what moment's accessors do\n\t\tmom._d.setTime(+new Date( // FYI, there is now way to apply an array of args to a constructor\n\t\t\ta[0] || 0,\n\t\t\ta[1] || 0,\n\t\t\ta[2] || 0,\n\t\t\ta[3] || 0,\n\t\t\ta[4] || 0,\n\t\t\ta[5] || 0,\n\t\t\ta[6] || 0\n\t\t));\n\t\tmoment.updateOffset(mom, false); // keepTime=false\n\t} : setMomentValues;\n\t\n\t;;\n\t\n\t// Single Date Formatting\n\t// -------------------------------------------------------------------------------------------------\n\t\n\t\n\t// call this if you want Moment's original format method to be used\n\tfunction oldMomentFormat(mom, formatStr) {\n\t\treturn oldMomentProto.format.call(mom, formatStr); // oldMomentProto defined in moment-ext.js\n\t}\n\t\n\t\n\t// Formats `date` with a Moment formatting string, but allow our non-zero areas and\n\t// additional token.\n\tfunction formatDate(date, formatStr) {\n\t\treturn formatDateWithChunks(date, getFormatStringChunks(formatStr));\n\t}\n\t\n\t\n\tfunction formatDateWithChunks(date, chunks) {\n\t\tvar s = '';\n\t\tvar i;\n\t\n\t\tfor (i=0; i \"MMMM D YYYY\"\n\t\tformatStr = localeData.longDateFormat(formatStr) || formatStr;\n\t\t// BTW, this is not important for `formatDate` because it is impossible to put custom tokens\n\t\t// or non-zero areas in Moment's localized format strings.\n\t\n\t\tseparator = separator || ' - ';\n\t\n\t\treturn formatRangeWithChunks(\n\t\t\tdate1,\n\t\t\tdate2,\n\t\t\tgetFormatStringChunks(formatStr),\n\t\t\tseparator,\n\t\t\tisRTL\n\t\t);\n\t}\n\tFC.formatRange = formatRange; // expose\n\t\n\t\n\tfunction formatRangeWithChunks(date1, date2, chunks, separator, isRTL) {\n\t\tvar unzonedDate1 = date1.clone().stripZone(); // for formatSimilarChunk\n\t\tvar unzonedDate2 = date2.clone().stripZone(); // \"\n\t\tvar chunkStr; // the rendering of the chunk\n\t\tvar leftI;\n\t\tvar leftStr = '';\n\t\tvar rightI;\n\t\tvar rightStr = '';\n\t\tvar middleI;\n\t\tvar middleStr1 = '';\n\t\tvar middleStr2 = '';\n\t\tvar middleStr = '';\n\t\n\t\t// Start at the leftmost side of the formatting string and continue until you hit a token\n\t\t// that is not the same between dates.\n\t\tfor (leftI=0; leftIleftI; rightI--) {\n\t\t\tchunkStr = formatSimilarChunk(date1, date2, unzonedDate1, unzonedDate2, chunks[rightI]);\n\t\t\tif (chunkStr === false) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\trightStr = chunkStr + rightStr;\n\t\t}\n\t\n\t\t// The area in the middle is different for both of the dates.\n\t\t// Collect them distinctly so we can jam them together later.\n\t\tfor (middleI=leftI; middleI<=rightI; middleI++) {\n\t\t\tmiddleStr1 += formatDateWithChunk(date1, chunks[middleI]);\n\t\t\tmiddleStr2 += formatDateWithChunk(date2, chunks[middleI]);\n\t\t}\n\t\n\t\tif (middleStr1 || middleStr2) {\n\t\t\tif (isRTL) {\n\t\t\t\tmiddleStr = middleStr2 + separator + middleStr1;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tmiddleStr = middleStr1 + separator + middleStr2;\n\t\t\t}\n\t\t}\n\t\n\t\treturn leftStr + middleStr + rightStr;\n\t}\n\t\n\t\n\tvar similarUnitMap = {\n\t\tY: 'year',\n\t\tM: 'month',\n\t\tD: 'day', // day of month\n\t\td: 'day', // day of week\n\t\t// prevents a separator between anything time-related...\n\t\tA: 'second', // AM/PM\n\t\ta: 'second', // am/pm\n\t\tT: 'second', // A/P\n\t\tt: 'second', // a/p\n\t\tH: 'second', // hour (24)\n\t\th: 'second', // hour (12)\n\t\tm: 'second', // minute\n\t\ts: 'second' // second\n\t};\n\t// TODO: week maybe?\n\t\n\t\n\t// Given a formatting chunk, and given that both dates are similar in the regard the\n\t// formatting chunk is concerned, format date1 against `chunk`. Otherwise, return `false`.\n\tfunction formatSimilarChunk(date1, date2, unzonedDate1, unzonedDate2, chunk) {\n\t\tvar token;\n\t\tvar unit;\n\t\n\t\tif (typeof chunk === 'string') { // a literal string\n\t\t\treturn chunk;\n\t\t}\n\t\telse if ((token = chunk.token)) {\n\t\t\tunit = similarUnitMap[token.charAt(0)];\n\t\n\t\t\t// are the dates the same for this unit of measurement?\n\t\t\t// use the unzoned dates for this calculation because unreliable when near DST (bug #2396)\n\t\t\tif (unit && unzonedDate1.isSame(unzonedDate2, unit)) {\n\t\t\t\treturn oldMomentFormat(date1, token); // would be the same if we used `date2`\n\t\t\t\t// BTW, don't support custom tokens\n\t\t\t}\n\t\t}\n\t\n\t\treturn false; // the chunk is NOT the same for the two dates\n\t\t// BTW, don't support splitting on non-zero areas\n\t}\n\t\n\t\n\t// Chunking Utils\n\t// -------------------------------------------------------------------------------------------------\n\t\n\t\n\tvar formatStringChunkCache = {};\n\t\n\t\n\tfunction getFormatStringChunks(formatStr) {\n\t\tif (formatStr in formatStringChunkCache) {\n\t\t\treturn formatStringChunkCache[formatStr];\n\t\t}\n\t\treturn (formatStringChunkCache[formatStr] = chunkFormatString(formatStr));\n\t}\n\t\n\t\n\t// Break the formatting string into an array of chunks\n\tfunction chunkFormatString(formatStr) {\n\t\tvar chunks = [];\n\t\tvar chunker = /\\[([^\\]]*)\\]|\\(([^\\)]*)\\)|(LTS|LT|(\\w)\\4*o?)|([^\\w\\[\\(]+)/g; // TODO: more descrimination\n\t\tvar match;\n\t\n\t\twhile ((match = chunker.exec(formatStr))) {\n\t\t\tif (match[1]) { // a literal string inside [ ... ]\n\t\t\t\tchunks.push(match[1]);\n\t\t\t}\n\t\t\telse if (match[2]) { // non-zero formatting inside ( ... )\n\t\t\t\tchunks.push({ maybe: chunkFormatString(match[2]) });\n\t\t\t}\n\t\t\telse if (match[3]) { // a formatting token\n\t\t\t\tchunks.push({ token: match[3] });\n\t\t\t}\n\t\t\telse if (match[5]) { // an unenclosed literal string\n\t\t\t\tchunks.push(match[5]);\n\t\t\t}\n\t\t}\n\t\n\t\treturn chunks;\n\t}\n\t\n\t;;\n\t\n\tFC.Class = Class; // export\n\t\n\t// Class that all other classes will inherit from\n\tfunction Class() { }\n\t\n\t\n\t// Called on a class to create a subclass.\n\t// Last argument contains instance methods. Any argument before the last are considered mixins.\n\tClass.extend = function() {\n\t\tvar len = arguments.length;\n\t\tvar i;\n\t\tvar members;\n\t\n\t\tfor (i = 0; i < len; i++) {\n\t\t\tmembers = arguments[i];\n\t\t\tif (i < len - 1) { // not the last argument?\n\t\t\t\tmixIntoClass(this, members);\n\t\t\t}\n\t\t}\n\t\n\t\treturn extendClass(this, members || {}); // members will be undefined if no arguments\n\t};\n\t\n\t\n\t// Adds new member variables/methods to the class's prototype.\n\t// Can be called with another class, or a plain object hash containing new members.\n\tClass.mixin = function(members) {\n\t\tmixIntoClass(this, members);\n\t};\n\t\n\t\n\tfunction extendClass(superClass, members) {\n\t\tvar subClass;\n\t\n\t\t// ensure a constructor for the subclass, forwarding all arguments to the super-constructor if it doesn't exist\n\t\tif (hasOwnProp(members, 'constructor')) {\n\t\t\tsubClass = members.constructor;\n\t\t}\n\t\tif (typeof subClass !== 'function') {\n\t\t\tsubClass = members.constructor = function() {\n\t\t\t\tsuperClass.apply(this, arguments);\n\t\t\t};\n\t\t}\n\t\n\t\t// build the base prototype for the subclass, which is an new object chained to the superclass's prototype\n\t\tsubClass.prototype = createObject(superClass.prototype);\n\t\n\t\t// copy each member variable/method onto the the subclass's prototype\n\t\tcopyOwnProps(members, subClass.prototype);\n\t\tcopyNativeMethods(members, subClass.prototype); // hack for IE8\n\t\n\t\t// copy over all class variables/methods to the subclass, such as `extend` and `mixin`\n\t\tcopyOwnProps(superClass, subClass);\n\t\n\t\treturn subClass;\n\t}\n\t\n\t\n\tfunction mixIntoClass(theClass, members) {\n\t\tcopyOwnProps(members, theClass.prototype); // TODO: copyNativeMethods?\n\t}\n\t;;\n\t\n\tvar EmitterMixin = FC.EmitterMixin = {\n\t\n\t\t// jQuery-ification via $(this) allows a non-DOM object to have\n\t\t// the same event handling capabilities (including namespaces).\n\t\n\t\n\t\ton: function(types, handler) {\n\t\n\t\t\t// handlers are always called with an \"event\" object as their first param.\n\t\t\t// sneak the `this` context and arguments into the extra parameter object\n\t\t\t// and forward them on to the original handler.\n\t\t\tvar intercept = function(ev, extra) {\n\t\t\t\treturn handler.apply(\n\t\t\t\t\textra.context || this,\n\t\t\t\t\textra.args || []\n\t\t\t\t);\n\t\t\t};\n\t\n\t\t\t// mimick jQuery's internal \"proxy\" system (risky, I know)\n\t\t\t// causing all functions with the same .guid to appear to be the same.\n\t\t\t// https://github.com/jquery/jquery/blob/2.2.4/src/core.js#L448\n\t\t\t// this is needed for calling .off with the original non-intercept handler.\n\t\t\tif (!handler.guid) {\n\t\t\t\thandler.guid = $.guid++;\n\t\t\t}\n\t\t\tintercept.guid = handler.guid;\n\t\n\t\t\t$(this).on(types, intercept);\n\t\n\t\t\treturn this; // for chaining\n\t\t},\n\t\n\t\n\t\toff: function(types, handler) {\n\t\t\t$(this).off(types, handler);\n\t\n\t\t\treturn this; // for chaining\n\t\t},\n\t\n\t\n\t\ttrigger: function(types) {\n\t\t\tvar args = Array.prototype.slice.call(arguments, 1); // arguments after the first\n\t\n\t\t\t// pass in \"extra\" info to the intercept\n\t\t\t$(this).triggerHandler(types, { args: args });\n\t\n\t\t\treturn this; // for chaining\n\t\t},\n\t\n\t\n\t\ttriggerWith: function(types, context, args) {\n\t\n\t\t\t// `triggerHandler` is less reliant on the DOM compared to `trigger`.\n\t\t\t// pass in \"extra\" info to the intercept.\n\t\t\t$(this).triggerHandler(types, { context: context, args: args });\n\t\n\t\t\treturn this; // for chaining\n\t\t}\n\t\n\t};\n\t\n\t;;\n\t\n\t/*\n\tUtility methods for easily listening to events on another object,\n\tand more importantly, easily unlistening from them.\n\t*/\n\tvar ListenerMixin = FC.ListenerMixin = (function() {\n\t\tvar guid = 0;\n\t\tvar ListenerMixin = {\n\t\n\t\t\tlistenerId: null,\n\t\n\t\t\t/*\n\t\t\tGiven an `other` object that has on/off methods, bind the given `callback` to an event by the given name.\n\t\t\tThe `callback` will be called with the `this` context of the object that .listenTo is being called on.\n\t\t\tCan be called:\n\t\t\t\t.listenTo(other, eventName, callback)\n\t\t\tOR\n\t\t\t\t.listenTo(other, {\n\t\t\t\t\teventName1: callback1,\n\t\t\t\t\teventName2: callback2\n\t\t\t\t})\n\t\t\t*/\n\t\t\tlistenTo: function(other, arg, callback) {\n\t\t\t\tif (typeof arg === 'object') { // given dictionary of callbacks\n\t\t\t\t\tfor (var eventName in arg) {\n\t\t\t\t\t\tif (arg.hasOwnProperty(eventName)) {\n\t\t\t\t\t\t\tthis.listenTo(other, eventName, arg[eventName]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (typeof arg === 'string') {\n\t\t\t\t\tother.on(\n\t\t\t\t\t\targ + '.' + this.getListenerNamespace(), // use event namespacing to identify this object\n\t\t\t\t\t\t$.proxy(callback, this) // always use `this` context\n\t\t\t\t\t\t\t// the usually-undesired jQuery guid behavior doesn't matter,\n\t\t\t\t\t\t\t// because we always unbind via namespace\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\n\t\t\t/*\n\t\t\tCauses the current object to stop listening to events on the `other` object.\n\t\t\t`eventName` is optional. If omitted, will stop listening to ALL events on `other`.\n\t\t\t*/\n\t\t\tstopListeningTo: function(other, eventName) {\n\t\t\t\tother.off((eventName || '') + '.' + this.getListenerNamespace());\n\t\t\t},\n\t\n\t\t\t/*\n\t\t\tReturns a string, unique to this object, to be used for event namespacing\n\t\t\t*/\n\t\t\tgetListenerNamespace: function() {\n\t\t\t\tif (this.listenerId == null) {\n\t\t\t\t\tthis.listenerId = guid++;\n\t\t\t\t}\n\t\t\t\treturn '_listener' + this.listenerId;\n\t\t\t}\n\t\n\t\t};\n\t\treturn ListenerMixin;\n\t})();\n\t;;\n\t\n\t// simple class for toggle a `isIgnoringMouse` flag on delay\n\t// initMouseIgnoring must first be called, with a millisecond delay setting.\n\tvar MouseIgnorerMixin = {\n\t\n\t\tisIgnoringMouse: false, // bool\n\t\tdelayUnignoreMouse: null, // method\n\t\n\t\n\t\tinitMouseIgnoring: function(delay) {\n\t\t\tthis.delayUnignoreMouse = debounce(proxy(this, 'unignoreMouse'), delay || 1000);\n\t\t},\n\t\n\t\n\t\t// temporarily ignore mouse actions on segments\n\t\ttempIgnoreMouse: function() {\n\t\t\tthis.isIgnoringMouse = true;\n\t\t\tthis.delayUnignoreMouse();\n\t\t},\n\t\n\t\n\t\t// delayUnignoreMouse eventually calls this\n\t\tunignoreMouse: function() {\n\t\t\tthis.isIgnoringMouse = false;\n\t\t}\n\t\n\t};\n\t\n\t;;\n\t\n\t/* A rectangular panel that is absolutely positioned over other content\n\t------------------------------------------------------------------------------------------------------------------------\n\tOptions:\n\t\t- className (string)\n\t\t- content (HTML string or jQuery element set)\n\t\t- parentEl\n\t\t- top\n\t\t- left\n\t\t- right (the x coord of where the right edge should be. not a \"CSS\" right)\n\t\t- autoHide (boolean)\n\t\t- show (callback)\n\t\t- hide (callback)\n\t*/\n\t\n\tvar Popover = Class.extend(ListenerMixin, {\n\t\n\t\tisHidden: true,\n\t\toptions: null,\n\t\tel: null, // the container element for the popover. generated by this object\n\t\tmargin: 10, // the space required between the popover and the edges of the scroll container\n\t\n\t\n\t\tconstructor: function(options) {\n\t\t\tthis.options = options || {};\n\t\t},\n\t\n\t\n\t\t// Shows the popover on the specified position. Renders it if not already\n\t\tshow: function() {\n\t\t\tif (this.isHidden) {\n\t\t\t\tif (!this.el) {\n\t\t\t\t\tthis.render();\n\t\t\t\t}\n\t\t\t\tthis.el.show();\n\t\t\t\tthis.position();\n\t\t\t\tthis.isHidden = false;\n\t\t\t\tthis.trigger('show');\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Hides the popover, through CSS, but does not remove it from the DOM\n\t\thide: function() {\n\t\t\tif (!this.isHidden) {\n\t\t\t\tthis.el.hide();\n\t\t\t\tthis.isHidden = true;\n\t\t\t\tthis.trigger('hide');\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Creates `this.el` and renders content inside of it\n\t\trender: function() {\n\t\t\tvar _this = this;\n\t\t\tvar options = this.options;\n\t\n\t\t\tthis.el = $('')\n\t\t\t\t.addClass(options.className || '')\n\t\t\t\t.css({\n\t\t\t\t\t// position initially to the top left to avoid creating scrollbars\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: 0\n\t\t\t\t})\n\t\t\t\t.append(options.content)\n\t\t\t\t.appendTo(options.parentEl);\n\t\n\t\t\t// when a click happens on anything inside with a 'fc-close' className, hide the popover\n\t\t\tthis.el.on('click', '.fc-close', function() {\n\t\t\t\t_this.hide();\n\t\t\t});\n\t\n\t\t\tif (options.autoHide) {\n\t\t\t\tthis.listenTo($(document), 'mousedown', this.documentMousedown);\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Triggered when the user clicks *anywhere* in the document, for the autoHide feature\n\t\tdocumentMousedown: function(ev) {\n\t\t\t// only hide the popover if the click happened outside the popover\n\t\t\tif (this.el && !$(ev.target).closest(this.el).length) {\n\t\t\t\tthis.hide();\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Hides and unregisters any handlers\n\t\tremoveElement: function() {\n\t\t\tthis.hide();\n\t\n\t\t\tif (this.el) {\n\t\t\t\tthis.el.remove();\n\t\t\t\tthis.el = null;\n\t\t\t}\n\t\n\t\t\tthis.stopListeningTo($(document), 'mousedown');\n\t\t},\n\t\n\t\n\t\t// Positions the popover optimally, using the top/left/right options\n\t\tposition: function() {\n\t\t\tvar options = this.options;\n\t\t\tvar origin = this.el.offsetParent().offset();\n\t\t\tvar width = this.el.outerWidth();\n\t\t\tvar height = this.el.outerHeight();\n\t\t\tvar windowEl = $(window);\n\t\t\tvar viewportEl = getScrollParent(this.el);\n\t\t\tvar viewportTop;\n\t\t\tvar viewportLeft;\n\t\t\tvar viewportOffset;\n\t\t\tvar top; // the \"position\" (not \"offset\") values for the popover\n\t\t\tvar left; //\n\t\n\t\t\t// compute top and left\n\t\t\ttop = options.top || 0;\n\t\t\tif (options.left !== undefined) {\n\t\t\t\tleft = options.left;\n\t\t\t}\n\t\t\telse if (options.right !== undefined) {\n\t\t\t\tleft = options.right - width; // derive the left value from the right value\n\t\t\t}\n\t\t\telse {\n\t\t\t\tleft = 0;\n\t\t\t}\n\t\n\t\t\tif (viewportEl.is(window) || viewportEl.is(document)) { // normalize getScrollParent's result\n\t\t\t\tviewportEl = windowEl;\n\t\t\t\tviewportTop = 0; // the window is always at the top left\n\t\t\t\tviewportLeft = 0; // (and .offset() won't work if called here)\n\t\t\t}\n\t\t\telse {\n\t\t\t\tviewportOffset = viewportEl.offset();\n\t\t\t\tviewportTop = viewportOffset.top;\n\t\t\t\tviewportLeft = viewportOffset.left;\n\t\t\t}\n\t\n\t\t\t// if the window is scrolled, it causes the visible area to be further down\n\t\t\tviewportTop += windowEl.scrollTop();\n\t\t\tviewportLeft += windowEl.scrollLeft();\n\t\n\t\t\t// constrain to the view port. if constrained by two edges, give precedence to top/left\n\t\t\tif (options.viewportConstrain !== false) {\n\t\t\t\ttop = Math.min(top, viewportTop + viewportEl.outerHeight() - height - this.margin);\n\t\t\t\ttop = Math.max(top, viewportTop + this.margin);\n\t\t\t\tleft = Math.min(left, viewportLeft + viewportEl.outerWidth() - width - this.margin);\n\t\t\t\tleft = Math.max(left, viewportLeft + this.margin);\n\t\t\t}\n\t\n\t\t\tthis.el.css({\n\t\t\t\ttop: top - origin.top,\n\t\t\t\tleft: left - origin.left\n\t\t\t});\n\t\t},\n\t\n\t\n\t\t// Triggers a callback. Calls a function in the option hash of the same name.\n\t\t// Arguments beyond the first `name` are forwarded on.\n\t\t// TODO: better code reuse for this. Repeat code\n\t\ttrigger: function(name) {\n\t\t\tif (this.options[name]) {\n\t\t\t\tthis.options[name].apply(this, Array.prototype.slice.call(arguments, 1));\n\t\t\t}\n\t\t}\n\t\n\t});\n\t\n\t;;\n\t\n\t/*\n\tA cache for the left/right/top/bottom/width/height values for one or more elements.\n\tWorks with both offset (from topleft document) and position (from offsetParent).\n\t\n\toptions:\n\t- els\n\t- isHorizontal\n\t- isVertical\n\t*/\n\tvar CoordCache = FC.CoordCache = Class.extend({\n\t\n\t\tels: null, // jQuery set (assumed to be siblings)\n\t\tforcedOffsetParentEl: null, // options can override the natural offsetParent\n\t\torigin: null, // {left,top} position of offsetParent of els\n\t\tboundingRect: null, // constrain cordinates to this rectangle. {left,right,top,bottom} or null\n\t\tisHorizontal: false, // whether to query for left/right/width\n\t\tisVertical: false, // whether to query for top/bottom/height\n\t\n\t\t// arrays of coordinates (offsets from topleft of document)\n\t\tlefts: null,\n\t\trights: null,\n\t\ttops: null,\n\t\tbottoms: null,\n\t\n\t\n\t\tconstructor: function(options) {\n\t\t\tthis.els = $(options.els);\n\t\t\tthis.isHorizontal = options.isHorizontal;\n\t\t\tthis.isVertical = options.isVertical;\n\t\t\tthis.forcedOffsetParentEl = options.offsetParent ? $(options.offsetParent) : null;\n\t\t},\n\t\n\t\n\t\t// Queries the els for coordinates and stores them.\n\t\t// Call this method before using and of the get* methods below.\n\t\tbuild: function() {\n\t\t\tvar offsetParentEl = this.forcedOffsetParentEl || this.els.eq(0).offsetParent();\n\t\n\t\t\tthis.origin = offsetParentEl.offset();\n\t\t\tthis.boundingRect = this.queryBoundingRect();\n\t\n\t\t\tif (this.isHorizontal) {\n\t\t\t\tthis.buildElHorizontals();\n\t\t\t}\n\t\t\tif (this.isVertical) {\n\t\t\t\tthis.buildElVerticals();\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Destroys all internal data about coordinates, freeing memory\n\t\tclear: function() {\n\t\t\tthis.origin = null;\n\t\t\tthis.boundingRect = null;\n\t\t\tthis.lefts = null;\n\t\t\tthis.rights = null;\n\t\t\tthis.tops = null;\n\t\t\tthis.bottoms = null;\n\t\t},\n\t\n\t\n\t\t// When called, if coord caches aren't built, builds them\n\t\tensureBuilt: function() {\n\t\t\tif (!this.origin) {\n\t\t\t\tthis.build();\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Populates the left/right internal coordinate arrays\n\t\tbuildElHorizontals: function() {\n\t\t\tvar lefts = [];\n\t\t\tvar rights = [];\n\t\n\t\t\tthis.els.each(function(i, node) {\n\t\t\t\tvar el = $(node);\n\t\t\t\tvar left = el.offset().left;\n\t\t\t\tvar width = el.outerWidth();\n\t\n\t\t\t\tlefts.push(left);\n\t\t\t\trights.push(left + width);\n\t\t\t});\n\t\n\t\t\tthis.lefts = lefts;\n\t\t\tthis.rights = rights;\n\t\t},\n\t\n\t\n\t\t// Populates the top/bottom internal coordinate arrays\n\t\tbuildElVerticals: function() {\n\t\t\tvar tops = [];\n\t\t\tvar bottoms = [];\n\t\n\t\t\tthis.els.each(function(i, node) {\n\t\t\t\tvar el = $(node);\n\t\t\t\tvar top = el.offset().top;\n\t\t\t\tvar height = el.outerHeight();\n\t\n\t\t\t\ttops.push(top);\n\t\t\t\tbottoms.push(top + height);\n\t\t\t});\n\t\n\t\t\tthis.tops = tops;\n\t\t\tthis.bottoms = bottoms;\n\t\t},\n\t\n\t\n\t\t// Given a left offset (from document left), returns the index of the el that it horizontally intersects.\n\t\t// If no intersection is made, returns undefined.\n\t\tgetHorizontalIndex: function(leftOffset) {\n\t\t\tthis.ensureBuilt();\n\t\n\t\t\tvar lefts = this.lefts;\n\t\t\tvar rights = this.rights;\n\t\t\tvar len = lefts.length;\n\t\t\tvar i;\n\t\n\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\tif (leftOffset >= lefts[i] && leftOffset < rights[i]) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Given a top offset (from document top), returns the index of the el that it vertically intersects.\n\t\t// If no intersection is made, returns undefined.\n\t\tgetVerticalIndex: function(topOffset) {\n\t\t\tthis.ensureBuilt();\n\t\n\t\t\tvar tops = this.tops;\n\t\t\tvar bottoms = this.bottoms;\n\t\t\tvar len = tops.length;\n\t\t\tvar i;\n\t\n\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\tif (topOffset >= tops[i] && topOffset < bottoms[i]) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Gets the left offset (from document left) of the element at the given index\n\t\tgetLeftOffset: function(leftIndex) {\n\t\t\tthis.ensureBuilt();\n\t\t\treturn this.lefts[leftIndex];\n\t\t},\n\t\n\t\n\t\t// Gets the left position (from offsetParent left) of the element at the given index\n\t\tgetLeftPosition: function(leftIndex) {\n\t\t\tthis.ensureBuilt();\n\t\t\treturn this.lefts[leftIndex] - this.origin.left;\n\t\t},\n\t\n\t\n\t\t// Gets the right offset (from document left) of the element at the given index.\n\t\t// This value is NOT relative to the document's right edge, like the CSS concept of \"right\" would be.\n\t\tgetRightOffset: function(leftIndex) {\n\t\t\tthis.ensureBuilt();\n\t\t\treturn this.rights[leftIndex];\n\t\t},\n\t\n\t\n\t\t// Gets the right position (from offsetParent left) of the element at the given index.\n\t\t// This value is NOT relative to the offsetParent's right edge, like the CSS concept of \"right\" would be.\n\t\tgetRightPosition: function(leftIndex) {\n\t\t\tthis.ensureBuilt();\n\t\t\treturn this.rights[leftIndex] - this.origin.left;\n\t\t},\n\t\n\t\n\t\t// Gets the width of the element at the given index\n\t\tgetWidth: function(leftIndex) {\n\t\t\tthis.ensureBuilt();\n\t\t\treturn this.rights[leftIndex] - this.lefts[leftIndex];\n\t\t},\n\t\n\t\n\t\t// Gets the top offset (from document top) of the element at the given index\n\t\tgetTopOffset: function(topIndex) {\n\t\t\tthis.ensureBuilt();\n\t\t\treturn this.tops[topIndex];\n\t\t},\n\t\n\t\n\t\t// Gets the top position (from offsetParent top) of the element at the given position\n\t\tgetTopPosition: function(topIndex) {\n\t\t\tthis.ensureBuilt();\n\t\t\treturn this.tops[topIndex] - this.origin.top;\n\t\t},\n\t\n\t\t// Gets the bottom offset (from the document top) of the element at the given index.\n\t\t// This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of \"bottom\" would be.\n\t\tgetBottomOffset: function(topIndex) {\n\t\t\tthis.ensureBuilt();\n\t\t\treturn this.bottoms[topIndex];\n\t\t},\n\t\n\t\n\t\t// Gets the bottom position (from the offsetParent top) of the element at the given index.\n\t\t// This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of \"bottom\" would be.\n\t\tgetBottomPosition: function(topIndex) {\n\t\t\tthis.ensureBuilt();\n\t\t\treturn this.bottoms[topIndex] - this.origin.top;\n\t\t},\n\t\n\t\n\t\t// Gets the height of the element at the given index\n\t\tgetHeight: function(topIndex) {\n\t\t\tthis.ensureBuilt();\n\t\t\treturn this.bottoms[topIndex] - this.tops[topIndex];\n\t\t},\n\t\n\t\n\t\t// Bounding Rect\n\t\t// TODO: decouple this from CoordCache\n\t\n\t\t// Compute and return what the elements' bounding rectangle is, from the user's perspective.\n\t\t// Right now, only returns a rectangle if constrained by an overflow:scroll element.\n\t\tqueryBoundingRect: function() {\n\t\t\tvar scrollParentEl = getScrollParent(this.els.eq(0));\n\t\n\t\t\tif (!scrollParentEl.is(document)) {\n\t\t\t\treturn getClientRect(scrollParentEl);\n\t\t\t}\n\t\t},\n\t\n\t\tisPointInBounds: function(leftOffset, topOffset) {\n\t\t\treturn this.isLeftInBounds(leftOffset) && this.isTopInBounds(topOffset);\n\t\t},\n\t\n\t\tisLeftInBounds: function(leftOffset) {\n\t\t\treturn !this.boundingRect || (leftOffset >= this.boundingRect.left && leftOffset < this.boundingRect.right);\n\t\t},\n\t\n\t\tisTopInBounds: function(topOffset) {\n\t\t\treturn !this.boundingRect || (topOffset >= this.boundingRect.top && topOffset < this.boundingRect.bottom);\n\t\t}\n\t\n\t});\n\t\n\t;;\n\t\n\t/* Tracks a drag's mouse movement, firing various handlers\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t// TODO: use Emitter\n\t\n\tvar DragListener = FC.DragListener = Class.extend(ListenerMixin, MouseIgnorerMixin, {\n\t\n\t\toptions: null,\n\t\n\t\t// for IE8 bug-fighting behavior\n\t\tsubjectEl: null,\n\t\tsubjectHref: null,\n\t\n\t\t// coordinates of the initial mousedown\n\t\toriginX: null,\n\t\toriginY: null,\n\t\n\t\t// the wrapping element that scrolls, or MIGHT scroll if there's overflow.\n\t\t// TODO: do this for wrappers that have overflow:hidden as well.\n\t\tscrollEl: null,\n\t\n\t\tisInteracting: false,\n\t\tisDistanceSurpassed: false,\n\t\tisDelayEnded: false,\n\t\tisDragging: false,\n\t\tisTouch: false,\n\t\n\t\tdelay: null,\n\t\tdelayTimeoutId: null,\n\t\tminDistance: null,\n\t\n\t\thandleTouchScrollProxy: null, // calls handleTouchScroll, always bound to `this`\n\t\n\t\n\t\tconstructor: function(options) {\n\t\t\tthis.options = options || {};\n\t\t\tthis.handleTouchScrollProxy = proxy(this, 'handleTouchScroll');\n\t\t\tthis.initMouseIgnoring(500);\n\t\t},\n\t\n\t\n\t\t// Interaction (high-level)\n\t\t// -----------------------------------------------------------------------------------------------------------------\n\t\n\t\n\t\tstartInteraction: function(ev, extraOptions) {\n\t\t\tvar isTouch = getEvIsTouch(ev);\n\t\n\t\t\tif (ev.type === 'mousedown') {\n\t\t\t\tif (this.isIgnoringMouse) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse if (!isPrimaryMouseButton(ev)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tev.preventDefault(); // prevents native selection in most browsers\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif (!this.isInteracting) {\n\t\n\t\t\t\t// process options\n\t\t\t\textraOptions = extraOptions || {};\n\t\t\t\tthis.delay = firstDefined(extraOptions.delay, this.options.delay, 0);\n\t\t\t\tthis.minDistance = firstDefined(extraOptions.distance, this.options.distance, 0);\n\t\t\t\tthis.subjectEl = this.options.subjectEl;\n\t\n\t\t\t\tthis.isInteracting = true;\n\t\t\t\tthis.isTouch = isTouch;\n\t\t\t\tthis.isDelayEnded = false;\n\t\t\t\tthis.isDistanceSurpassed = false;\n\t\n\t\t\t\tthis.originX = getEvX(ev);\n\t\t\t\tthis.originY = getEvY(ev);\n\t\t\t\tthis.scrollEl = getScrollParent($(ev.target));\n\t\n\t\t\t\tthis.bindHandlers();\n\t\t\t\tthis.initAutoScroll();\n\t\t\t\tthis.handleInteractionStart(ev);\n\t\t\t\tthis.startDelay(ev);\n\t\n\t\t\t\tif (!this.minDistance) {\n\t\t\t\t\tthis.handleDistanceSurpassed(ev);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\n\t\n\t\thandleInteractionStart: function(ev) {\n\t\t\tthis.trigger('interactionStart', ev);\n\t\t},\n\t\n\t\n\t\tendInteraction: function(ev, isCancelled) {\n\t\t\tif (this.isInteracting) {\n\t\t\t\tthis.endDrag(ev);\n\t\n\t\t\t\tif (this.delayTimeoutId) {\n\t\t\t\t\tclearTimeout(this.delayTimeoutId);\n\t\t\t\t\tthis.delayTimeoutId = null;\n\t\t\t\t}\n\t\n\t\t\t\tthis.destroyAutoScroll();\n\t\t\t\tthis.unbindHandlers();\n\t\n\t\t\t\tthis.isInteracting = false;\n\t\t\t\tthis.handleInteractionEnd(ev, isCancelled);\n\t\n\t\t\t\t// a touchstart+touchend on the same element will result in the following addition simulated events:\n\t\t\t\t// mouseover + mouseout + click\n\t\t\t\t// let's ignore these bogus events\n\t\t\t\tif (this.isTouch) {\n\t\t\t\t\tthis.tempIgnoreMouse();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\n\t\n\t\thandleInteractionEnd: function(ev, isCancelled) {\n\t\t\tthis.trigger('interactionEnd', ev, isCancelled || false);\n\t\t},\n\t\n\t\n\t\t// Binding To DOM\n\t\t// -----------------------------------------------------------------------------------------------------------------\n\t\n\t\n\t\tbindHandlers: function() {\n\t\t\tvar _this = this;\n\t\t\tvar touchStartIgnores = 1;\n\t\n\t\t\tif (this.isTouch) {\n\t\t\t\tthis.listenTo($(document), {\n\t\t\t\t\ttouchmove: this.handleTouchMove,\n\t\t\t\t\ttouchend: this.endInteraction,\n\t\t\t\t\ttouchcancel: this.endInteraction,\n\t\n\t\t\t\t\t// Sometimes touchend doesn't fire\n\t\t\t\t\t// (can't figure out why. touchcancel doesn't fire either. has to do with scrolling?)\n\t\t\t\t\t// If another touchstart happens, we know it's bogus, so cancel the drag.\n\t\t\t\t\t// touchend will continue to be broken until user does a shorttap/scroll, but this is best we can do.\n\t\t\t\t\ttouchstart: function(ev) {\n\t\t\t\t\t\tif (touchStartIgnores) { // bindHandlers is called from within a touchstart,\n\t\t\t\t\t\t\ttouchStartIgnores--; // and we don't want this to fire immediately, so ignore.\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t_this.endInteraction(ev, true); // isCancelled=true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\n\t\t\t\t// listen to ALL scroll actions on the page\n\t\t\t\tif (\n\t\t\t\t\t!bindAnyScroll(this.handleTouchScrollProxy) && // hopefully this works and short-circuits the rest\n\t\t\t\t\tthis.scrollEl // otherwise, attach a single handler to this\n\t\t\t\t) {\n\t\t\t\t\tthis.listenTo(this.scrollEl, 'scroll', this.handleTouchScroll);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.listenTo($(document), {\n\t\t\t\t\tmousemove: this.handleMouseMove,\n\t\t\t\t\tmouseup: this.endInteraction\n\t\t\t\t});\n\t\t\t}\n\t\n\t\t\tthis.listenTo($(document), {\n\t\t\t\tselectstart: preventDefault, // don't allow selection while dragging\n\t\t\t\tcontextmenu: preventDefault // long taps would open menu on Chrome dev tools\n\t\t\t});\n\t\t},\n\t\n\t\n\t\tunbindHandlers: function() {\n\t\t\tthis.stopListeningTo($(document));\n\t\n\t\t\t// unbind scroll listening\n\t\t\tunbindAnyScroll(this.handleTouchScrollProxy);\n\t\t\tif (this.scrollEl) {\n\t\t\t\tthis.stopListeningTo(this.scrollEl, 'scroll');\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Drag (high-level)\n\t\t// -----------------------------------------------------------------------------------------------------------------\n\t\n\t\n\t\t// extraOptions ignored if drag already started\n\t\tstartDrag: function(ev, extraOptions) {\n\t\t\tthis.startInteraction(ev, extraOptions); // ensure interaction began\n\t\n\t\t\tif (!this.isDragging) {\n\t\t\t\tthis.isDragging = true;\n\t\t\t\tthis.handleDragStart(ev);\n\t\t\t}\n\t\t},\n\t\n\t\n\t\thandleDragStart: function(ev) {\n\t\t\tthis.trigger('dragStart', ev);\n\t\t\tthis.initHrefHack();\n\t\t},\n\t\n\t\n\t\thandleMove: function(ev) {\n\t\t\tvar dx = getEvX(ev) - this.originX;\n\t\t\tvar dy = getEvY(ev) - this.originY;\n\t\t\tvar minDistance = this.minDistance;\n\t\t\tvar distanceSq; // current distance from the origin, squared\n\t\n\t\t\tif (!this.isDistanceSurpassed) {\n\t\t\t\tdistanceSq = dx * dx + dy * dy;\n\t\t\t\tif (distanceSq >= minDistance * minDistance) { // use pythagorean theorem\n\t\t\t\t\tthis.handleDistanceSurpassed(ev);\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif (this.isDragging) {\n\t\t\t\tthis.handleDrag(dx, dy, ev);\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Called while the mouse is being moved and when we know a legitimate drag is taking place\n\t\thandleDrag: function(dx, dy, ev) {\n\t\t\tthis.trigger('drag', dx, dy, ev);\n\t\t\tthis.updateAutoScroll(ev); // will possibly cause scrolling\n\t\t},\n\t\n\t\n\t\tendDrag: function(ev) {\n\t\t\tif (this.isDragging) {\n\t\t\t\tthis.isDragging = false;\n\t\t\t\tthis.handleDragEnd(ev);\n\t\t\t}\n\t\t},\n\t\n\t\n\t\thandleDragEnd: function(ev) {\n\t\t\tthis.trigger('dragEnd', ev);\n\t\t\tthis.destroyHrefHack();\n\t\t},\n\t\n\t\n\t\t// Delay\n\t\t// -----------------------------------------------------------------------------------------------------------------\n\t\n\t\n\t\tstartDelay: function(initialEv) {\n\t\t\tvar _this = this;\n\t\n\t\t\tif (this.delay) {\n\t\t\t\tthis.delayTimeoutId = setTimeout(function() {\n\t\t\t\t\t_this.handleDelayEnd(initialEv);\n\t\t\t\t}, this.delay);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.handleDelayEnd(initialEv);\n\t\t\t}\n\t\t},\n\t\n\t\n\t\thandleDelayEnd: function(initialEv) {\n\t\t\tthis.isDelayEnded = true;\n\t\n\t\t\tif (this.isDistanceSurpassed) {\n\t\t\t\tthis.startDrag(initialEv);\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Distance\n\t\t// -----------------------------------------------------------------------------------------------------------------\n\t\n\t\n\t\thandleDistanceSurpassed: function(ev) {\n\t\t\tthis.isDistanceSurpassed = true;\n\t\n\t\t\tif (this.isDelayEnded) {\n\t\t\t\tthis.startDrag(ev);\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Mouse / Touch\n\t\t// -----------------------------------------------------------------------------------------------------------------\n\t\n\t\n\t\thandleTouchMove: function(ev) {\n\t\t\t// prevent inertia and touchmove-scrolling while dragging\n\t\t\tif (this.isDragging) {\n\t\t\t\tev.preventDefault();\n\t\t\t}\n\t\n\t\t\tthis.handleMove(ev);\n\t\t},\n\t\n\t\n\t\thandleMouseMove: function(ev) {\n\t\t\tthis.handleMove(ev);\n\t\t},\n\t\n\t\n\t\t// Scrolling (unrelated to auto-scroll)\n\t\t// -----------------------------------------------------------------------------------------------------------------\n\t\n\t\n\t\thandleTouchScroll: function(ev) {\n\t\t\t// if the drag is being initiated by touch, but a scroll happens before\n\t\t\t// the drag-initiating delay is over, cancel the drag\n\t\t\tif (!this.isDragging) {\n\t\t\t\tthis.endInteraction(ev, true); // isCancelled=true\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// HREF Hack\n\t\t// -----------------------------------------------------------------------------------------------------------------\n\t\n\t\n\t\tinitHrefHack: function() {\n\t\t\tvar subjectEl = this.subjectEl;\n\t\n\t\t\t// remove a mousedown'd 's href so it is not visited (IE8 bug)\n\t\t\tif ((this.subjectHref = subjectEl ? subjectEl.attr('href') : null)) {\n\t\t\t\tsubjectEl.removeAttr('href');\n\t\t\t}\n\t\t},\n\t\n\t\n\t\tdestroyHrefHack: function() {\n\t\t\tvar subjectEl = this.subjectEl;\n\t\t\tvar subjectHref = this.subjectHref;\n\t\n\t\t\t// restore a mousedown'd 's href (for IE8 bug)\n\t\t\tsetTimeout(function() { // must be outside of the click's execution\n\t\t\t\tif (subjectHref) {\n\t\t\t\t\tsubjectEl.attr('href', subjectHref);\n\t\t\t\t}\n\t\t\t}, 0);\n\t\t},\n\t\n\t\n\t\t// Utils\n\t\t// -----------------------------------------------------------------------------------------------------------------\n\t\n\t\n\t\t// Triggers a callback. Calls a function in the option hash of the same name.\n\t\t// Arguments beyond the first `name` are forwarded on.\n\t\ttrigger: function(name) {\n\t\t\tif (this.options[name]) {\n\t\t\t\tthis.options[name].apply(this, Array.prototype.slice.call(arguments, 1));\n\t\t\t}\n\t\t\t// makes _methods callable by event name. TODO: kill this\n\t\t\tif (this['_' + name]) {\n\t\t\t\tthis['_' + name].apply(this, Array.prototype.slice.call(arguments, 1));\n\t\t\t}\n\t\t}\n\t\n\t\n\t});\n\t\n\t;;\n\t/*\n\tthis.scrollEl is set in DragListener\n\t*/\n\tDragListener.mixin({\n\t\n\t\tisAutoScroll: false,\n\t\n\t\tscrollBounds: null, // { top, bottom, left, right }\n\t\tscrollTopVel: null, // pixels per second\n\t\tscrollLeftVel: null, // pixels per second\n\t\tscrollIntervalId: null, // ID of setTimeout for scrolling animation loop\n\t\n\t\t// defaults\n\t\tscrollSensitivity: 30, // pixels from edge for scrolling to start\n\t\tscrollSpeed: 200, // pixels per second, at maximum speed\n\t\tscrollIntervalMs: 50, // millisecond wait between scroll increment\n\t\n\t\n\t\tinitAutoScroll: function() {\n\t\t\tvar scrollEl = this.scrollEl;\n\t\n\t\t\tthis.isAutoScroll =\n\t\t\t\tthis.options.scroll &&\n\t\t\t\tscrollEl &&\n\t\t\t\t!scrollEl.is(window) &&\n\t\t\t\t!scrollEl.is(document);\n\t\n\t\t\tif (this.isAutoScroll) {\n\t\t\t\t// debounce makes sure rapid calls don't happen\n\t\t\t\tthis.listenTo(scrollEl, 'scroll', debounce(this.handleDebouncedScroll, 100));\n\t\t\t}\n\t\t},\n\t\n\t\n\t\tdestroyAutoScroll: function() {\n\t\t\tthis.endAutoScroll(); // kill any animation loop\n\t\n\t\t\t// remove the scroll handler if there is a scrollEl\n\t\t\tif (this.isAutoScroll) {\n\t\t\t\tthis.stopListeningTo(this.scrollEl, 'scroll'); // will probably get removed by unbindHandlers too :(\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Computes and stores the bounding rectangle of scrollEl\n\t\tcomputeScrollBounds: function() {\n\t\t\tif (this.isAutoScroll) {\n\t\t\t\tthis.scrollBounds = getOuterRect(this.scrollEl);\n\t\t\t\t// TODO: use getClientRect in future. but prevents auto scrolling when on top of scrollbars\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Called when the dragging is in progress and scrolling should be updated\n\t\tupdateAutoScroll: function(ev) {\n\t\t\tvar sensitivity = this.scrollSensitivity;\n\t\t\tvar bounds = this.scrollBounds;\n\t\t\tvar topCloseness, bottomCloseness;\n\t\t\tvar leftCloseness, rightCloseness;\n\t\t\tvar topVel = 0;\n\t\t\tvar leftVel = 0;\n\t\n\t\t\tif (bounds) { // only scroll if scrollEl exists\n\t\n\t\t\t\t// compute closeness to edges. valid range is from 0.0 - 1.0\n\t\t\t\ttopCloseness = (sensitivity - (getEvY(ev) - bounds.top)) / sensitivity;\n\t\t\t\tbottomCloseness = (sensitivity - (bounds.bottom - getEvY(ev))) / sensitivity;\n\t\t\t\tleftCloseness = (sensitivity - (getEvX(ev) - bounds.left)) / sensitivity;\n\t\t\t\trightCloseness = (sensitivity - (bounds.right - getEvX(ev))) / sensitivity;\n\t\n\t\t\t\t// translate vertical closeness into velocity.\n\t\t\t\t// mouse must be completely in bounds for velocity to happen.\n\t\t\t\tif (topCloseness >= 0 && topCloseness <= 1) {\n\t\t\t\t\ttopVel = topCloseness * this.scrollSpeed * -1; // negative. for scrolling up\n\t\t\t\t}\n\t\t\t\telse if (bottomCloseness >= 0 && bottomCloseness <= 1) {\n\t\t\t\t\ttopVel = bottomCloseness * this.scrollSpeed;\n\t\t\t\t}\n\t\n\t\t\t\t// translate horizontal closeness into velocity\n\t\t\t\tif (leftCloseness >= 0 && leftCloseness <= 1) {\n\t\t\t\t\tleftVel = leftCloseness * this.scrollSpeed * -1; // negative. for scrolling left\n\t\t\t\t}\n\t\t\t\telse if (rightCloseness >= 0 && rightCloseness <= 1) {\n\t\t\t\t\tleftVel = rightCloseness * this.scrollSpeed;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tthis.setScrollVel(topVel, leftVel);\n\t\t},\n\t\n\t\n\t\t// Sets the speed-of-scrolling for the scrollEl\n\t\tsetScrollVel: function(topVel, leftVel) {\n\t\n\t\t\tthis.scrollTopVel = topVel;\n\t\t\tthis.scrollLeftVel = leftVel;\n\t\n\t\t\tthis.constrainScrollVel(); // massages into realistic values\n\t\n\t\t\t// if there is non-zero velocity, and an animation loop hasn't already started, then START\n\t\t\tif ((this.scrollTopVel || this.scrollLeftVel) && !this.scrollIntervalId) {\n\t\t\t\tthis.scrollIntervalId = setInterval(\n\t\t\t\t\tproxy(this, 'scrollIntervalFunc'), // scope to `this`\n\t\t\t\t\tthis.scrollIntervalMs\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Forces scrollTopVel and scrollLeftVel to be zero if scrolling has already gone all the way\n\t\tconstrainScrollVel: function() {\n\t\t\tvar el = this.scrollEl;\n\t\n\t\t\tif (this.scrollTopVel < 0) { // scrolling up?\n\t\t\t\tif (el.scrollTop() <= 0) { // already scrolled all the way up?\n\t\t\t\t\tthis.scrollTopVel = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (this.scrollTopVel > 0) { // scrolling down?\n\t\t\t\tif (el.scrollTop() + el[0].clientHeight >= el[0].scrollHeight) { // already scrolled all the way down?\n\t\t\t\t\tthis.scrollTopVel = 0;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif (this.scrollLeftVel < 0) { // scrolling left?\n\t\t\t\tif (el.scrollLeft() <= 0) { // already scrolled all the left?\n\t\t\t\t\tthis.scrollLeftVel = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (this.scrollLeftVel > 0) { // scrolling right?\n\t\t\t\tif (el.scrollLeft() + el[0].clientWidth >= el[0].scrollWidth) { // already scrolled all the way right?\n\t\t\t\t\tthis.scrollLeftVel = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// This function gets called during every iteration of the scrolling animation loop\n\t\tscrollIntervalFunc: function() {\n\t\t\tvar el = this.scrollEl;\n\t\t\tvar frac = this.scrollIntervalMs / 1000; // considering animation frequency, what the vel should be mult'd by\n\t\n\t\t\t// change the value of scrollEl's scroll\n\t\t\tif (this.scrollTopVel) {\n\t\t\t\tel.scrollTop(el.scrollTop() + this.scrollTopVel * frac);\n\t\t\t}\n\t\t\tif (this.scrollLeftVel) {\n\t\t\t\tel.scrollLeft(el.scrollLeft() + this.scrollLeftVel * frac);\n\t\t\t}\n\t\n\t\t\tthis.constrainScrollVel(); // since the scroll values changed, recompute the velocities\n\t\n\t\t\t// if scrolled all the way, which causes the vels to be zero, stop the animation loop\n\t\t\tif (!this.scrollTopVel && !this.scrollLeftVel) {\n\t\t\t\tthis.endAutoScroll();\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Kills any existing scrolling animation loop\n\t\tendAutoScroll: function() {\n\t\t\tif (this.scrollIntervalId) {\n\t\t\t\tclearInterval(this.scrollIntervalId);\n\t\t\t\tthis.scrollIntervalId = null;\n\t\n\t\t\t\tthis.handleScrollEnd();\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Get called when the scrollEl is scrolled (NOTE: this is delayed via debounce)\n\t\thandleDebouncedScroll: function() {\n\t\t\t// recompute all coordinates, but *only* if this is *not* part of our scrolling animation\n\t\t\tif (!this.scrollIntervalId) {\n\t\t\t\tthis.handleScrollEnd();\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Called when scrolling has stopped, whether through auto scroll, or the user scrolling\n\t\thandleScrollEnd: function() {\n\t\t}\n\t\n\t});\n\t;;\n\t\n\t/* Tracks mouse movements over a component and raises events about which hit the mouse is over.\n\t------------------------------------------------------------------------------------------------------------------------\n\toptions:\n\t- subjectEl\n\t- subjectCenter\n\t*/\n\t\n\tvar HitDragListener = DragListener.extend({\n\t\n\t\tcomponent: null, // converts coordinates to hits\n\t\t\t// methods: prepareHits, releaseHits, queryHit\n\t\n\t\torigHit: null, // the hit the mouse was over when listening started\n\t\thit: null, // the hit the mouse is over\n\t\tcoordAdjust: null, // delta that will be added to the mouse coordinates when computing collisions\n\t\n\t\n\t\tconstructor: function(component, options) {\n\t\t\tDragListener.call(this, options); // call the super-constructor\n\t\n\t\t\tthis.component = component;\n\t\t},\n\t\n\t\n\t\t// Called when drag listening starts (but a real drag has not necessarily began).\n\t\t// ev might be undefined if dragging was started manually.\n\t\thandleInteractionStart: function(ev) {\n\t\t\tvar subjectEl = this.subjectEl;\n\t\t\tvar subjectRect;\n\t\t\tvar origPoint;\n\t\t\tvar point;\n\t\n\t\t\tthis.computeCoords();\n\t\n\t\t\tif (ev) {\n\t\t\t\torigPoint = { left: getEvX(ev), top: getEvY(ev) };\n\t\t\t\tpoint = origPoint;\n\t\n\t\t\t\t// constrain the point to bounds of the element being dragged\n\t\t\t\tif (subjectEl) {\n\t\t\t\t\tsubjectRect = getOuterRect(subjectEl); // used for centering as well\n\t\t\t\t\tpoint = constrainPoint(point, subjectRect);\n\t\t\t\t}\n\t\n\t\t\t\tthis.origHit = this.queryHit(point.left, point.top);\n\t\n\t\t\t\t// treat the center of the subject as the collision point?\n\t\t\t\tif (subjectEl && this.options.subjectCenter) {\n\t\n\t\t\t\t\t// only consider the area the subject overlaps the hit. best for large subjects.\n\t\t\t\t\t// TODO: skip this if hit didn't supply left/right/top/bottom\n\t\t\t\t\tif (this.origHit) {\n\t\t\t\t\t\tsubjectRect = intersectRects(this.origHit, subjectRect) ||\n\t\t\t\t\t\t\tsubjectRect; // in case there is no intersection\n\t\t\t\t\t}\n\t\n\t\t\t\t\tpoint = getRectCenter(subjectRect);\n\t\t\t\t}\n\t\n\t\t\t\tthis.coordAdjust = diffPoints(point, origPoint); // point - origPoint\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.origHit = null;\n\t\t\t\tthis.coordAdjust = null;\n\t\t\t}\n\t\n\t\t\t// call the super-method. do it after origHit has been computed\n\t\t\tDragListener.prototype.handleInteractionStart.apply(this, arguments);\n\t\t},\n\t\n\t\n\t\t// Recomputes the drag-critical positions of elements\n\t\tcomputeCoords: function() {\n\t\t\tthis.component.prepareHits();\n\t\t\tthis.computeScrollBounds(); // why is this here??????\n\t\t},\n\t\n\t\n\t\t// Called when the actual drag has started\n\t\thandleDragStart: function(ev) {\n\t\t\tvar hit;\n\t\n\t\t\tDragListener.prototype.handleDragStart.apply(this, arguments); // call the super-method\n\t\n\t\t\t// might be different from this.origHit if the min-distance is large\n\t\t\thit = this.queryHit(getEvX(ev), getEvY(ev));\n\t\n\t\t\t// report the initial hit the mouse is over\n\t\t\t// especially important if no min-distance and drag starts immediately\n\t\t\tif (hit) {\n\t\t\t\tthis.handleHitOver(hit);\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Called when the drag moves\n\t\thandleDrag: function(dx, dy, ev) {\n\t\t\tvar hit;\n\t\n\t\t\tDragListener.prototype.handleDrag.apply(this, arguments); // call the super-method\n\t\n\t\t\thit = this.queryHit(getEvX(ev), getEvY(ev));\n\t\n\t\t\tif (!isHitsEqual(hit, this.hit)) { // a different hit than before?\n\t\t\t\tif (this.hit) {\n\t\t\t\t\tthis.handleHitOut();\n\t\t\t\t}\n\t\t\t\tif (hit) {\n\t\t\t\t\tthis.handleHitOver(hit);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Called when dragging has been stopped\n\t\thandleDragEnd: function() {\n\t\t\tthis.handleHitDone();\n\t\t\tDragListener.prototype.handleDragEnd.apply(this, arguments); // call the super-method\n\t\t},\n\t\n\t\n\t\t// Called when a the mouse has just moved over a new hit\n\t\thandleHitOver: function(hit) {\n\t\t\tvar isOrig = isHitsEqual(hit, this.origHit);\n\t\n\t\t\tthis.hit = hit;\n\t\n\t\t\tthis.trigger('hitOver', this.hit, isOrig, this.origHit);\n\t\t},\n\t\n\t\n\t\t// Called when the mouse has just moved out of a hit\n\t\thandleHitOut: function() {\n\t\t\tif (this.hit) {\n\t\t\t\tthis.trigger('hitOut', this.hit);\n\t\t\t\tthis.handleHitDone();\n\t\t\t\tthis.hit = null;\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Called after a hitOut. Also called before a dragStop\n\t\thandleHitDone: function() {\n\t\t\tif (this.hit) {\n\t\t\t\tthis.trigger('hitDone', this.hit);\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Called when the interaction ends, whether there was a real drag or not\n\t\thandleInteractionEnd: function() {\n\t\t\tDragListener.prototype.handleInteractionEnd.apply(this, arguments); // call the super-method\n\t\n\t\t\tthis.origHit = null;\n\t\t\tthis.hit = null;\n\t\n\t\t\tthis.component.releaseHits();\n\t\t},\n\t\n\t\n\t\t// Called when scrolling has stopped, whether through auto scroll, or the user scrolling\n\t\thandleScrollEnd: function() {\n\t\t\tDragListener.prototype.handleScrollEnd.apply(this, arguments); // call the super-method\n\t\n\t\t\tthis.computeCoords(); // hits' absolute positions will be in new places. recompute\n\t\t},\n\t\n\t\n\t\t// Gets the hit underneath the coordinates for the given mouse event\n\t\tqueryHit: function(left, top) {\n\t\n\t\t\tif (this.coordAdjust) {\n\t\t\t\tleft += this.coordAdjust.left;\n\t\t\t\ttop += this.coordAdjust.top;\n\t\t\t}\n\t\n\t\t\treturn this.component.queryHit(left, top);\n\t\t}\n\t\n\t});\n\t\n\t\n\t// Returns `true` if the hits are identically equal. `false` otherwise. Must be from the same component.\n\t// Two null values will be considered equal, as two \"out of the component\" states are the same.\n\tfunction isHitsEqual(hit0, hit1) {\n\t\n\t\tif (!hit0 && !hit1) {\n\t\t\treturn true;\n\t\t}\n\t\n\t\tif (hit0 && hit1) {\n\t\t\treturn hit0.component === hit1.component &&\n\t\t\t\tisHitPropsWithin(hit0, hit1) &&\n\t\t\t\tisHitPropsWithin(hit1, hit0); // ensures all props are identical\n\t\t}\n\t\n\t\treturn false;\n\t}\n\t\n\t\n\t// Returns true if all of subHit's non-standard properties are within superHit\n\tfunction isHitPropsWithin(subHit, superHit) {\n\t\tfor (var propName in subHit) {\n\t\t\tif (!/^(component|left|right|top|bottom)$/.test(propName)) {\n\t\t\t\tif (subHit[propName] !== superHit[propName]) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\t\n\t;;\n\t\n\t/* Creates a clone of an element and lets it track the mouse as it moves\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\tvar MouseFollower = Class.extend(ListenerMixin, {\n\t\n\t\toptions: null,\n\t\n\t\tsourceEl: null, // the element that will be cloned and made to look like it is dragging\n\t\tel: null, // the clone of `sourceEl` that will track the mouse\n\t\tparentEl: null, // the element that `el` (the clone) will be attached to\n\t\n\t\t// the initial position of el, relative to the offset parent. made to match the initial offset of sourceEl\n\t\ttop0: null,\n\t\tleft0: null,\n\t\n\t\t// the absolute coordinates of the initiating touch/mouse action\n\t\ty0: null,\n\t\tx0: null,\n\t\n\t\t// the number of pixels the mouse has moved from its initial position\n\t\ttopDelta: null,\n\t\tleftDelta: null,\n\t\n\t\tisFollowing: false,\n\t\tisHidden: false,\n\t\tisAnimating: false, // doing the revert animation?\n\t\n\t\tconstructor: function(sourceEl, options) {\n\t\t\tthis.options = options = options || {};\n\t\t\tthis.sourceEl = sourceEl;\n\t\t\tthis.parentEl = options.parentEl ? $(options.parentEl) : sourceEl.parent(); // default to sourceEl's parent\n\t\t},\n\t\n\t\n\t\t// Causes the element to start following the mouse\n\t\tstart: function(ev) {\n\t\t\tif (!this.isFollowing) {\n\t\t\t\tthis.isFollowing = true;\n\t\n\t\t\t\tthis.y0 = getEvY(ev);\n\t\t\t\tthis.x0 = getEvX(ev);\n\t\t\t\tthis.topDelta = 0;\n\t\t\t\tthis.leftDelta = 0;\n\t\n\t\t\t\tif (!this.isHidden) {\n\t\t\t\t\tthis.updatePosition();\n\t\t\t\t}\n\t\n\t\t\t\tif (getEvIsTouch(ev)) {\n\t\t\t\t\tthis.listenTo($(document), 'touchmove', this.handleMove);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.listenTo($(document), 'mousemove', this.handleMove);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Causes the element to stop following the mouse. If shouldRevert is true, will animate back to original position.\n\t\t// `callback` gets invoked when the animation is complete. If no animation, it is invoked immediately.\n\t\tstop: function(shouldRevert, callback) {\n\t\t\tvar _this = this;\n\t\t\tvar revertDuration = this.options.revertDuration;\n\t\n\t\t\tfunction complete() { // might be called by .animate(), which might change `this` context\n\t\t\t\t_this.isAnimating = false;\n\t\t\t\t_this.removeElement();\n\t\n\t\t\t\t_this.top0 = _this.left0 = null; // reset state for future updatePosition calls\n\t\n\t\t\t\tif (callback) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif (this.isFollowing && !this.isAnimating) { // disallow more than one stop animation at a time\n\t\t\t\tthis.isFollowing = false;\n\t\n\t\t\t\tthis.stopListeningTo($(document));\n\t\n\t\t\t\tif (shouldRevert && revertDuration && !this.isHidden) { // do a revert animation?\n\t\t\t\t\tthis.isAnimating = true;\n\t\t\t\t\tthis.el.animate({\n\t\t\t\t\t\ttop: this.top0,\n\t\t\t\t\t\tleft: this.left0\n\t\t\t\t\t}, {\n\t\t\t\t\t\tduration: revertDuration,\n\t\t\t\t\t\tcomplete: complete\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tcomplete();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Gets the tracking element. Create it if necessary\n\t\tgetEl: function() {\n\t\t\tvar el = this.el;\n\t\n\t\t\tif (!el) {\n\t\t\t\tthis.sourceEl.width(); // hack to force IE8 to compute correct bounding box\n\t\t\t\tel = this.el = this.sourceEl.clone()\n\t\t\t\t\t.addClass(this.options.additionalClass || '')\n\t\t\t\t\t.css({\n\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\tvisibility: '', // in case original element was hidden (commonly through hideEvents())\n\t\t\t\t\t\tdisplay: this.isHidden ? 'none' : '', // for when initially hidden\n\t\t\t\t\t\tmargin: 0,\n\t\t\t\t\t\tright: 'auto', // erase and set width instead\n\t\t\t\t\t\tbottom: 'auto', // erase and set height instead\n\t\t\t\t\t\twidth: this.sourceEl.width(), // explicit height in case there was a 'right' value\n\t\t\t\t\t\theight: this.sourceEl.height(), // explicit width in case there was a 'bottom' value\n\t\t\t\t\t\topacity: this.options.opacity || '',\n\t\t\t\t\t\tzIndex: this.options.zIndex\n\t\t\t\t\t});\n\t\n\t\t\t\t// we don't want long taps or any mouse interaction causing selection/menus.\n\t\t\t\t// would use preventSelection(), but that prevents selectstart, causing problems.\n\t\t\t\tel.addClass('fc-unselectable');\n\t\n\t\t\t\tel.appendTo(this.parentEl);\n\t\t\t}\n\t\n\t\t\treturn el;\n\t\t},\n\t\n\t\n\t\t// Removes the tracking element if it has already been created\n\t\tremoveElement: function() {\n\t\t\tif (this.el) {\n\t\t\t\tthis.el.remove();\n\t\t\t\tthis.el = null;\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Update the CSS position of the tracking element\n\t\tupdatePosition: function() {\n\t\t\tvar sourceOffset;\n\t\t\tvar origin;\n\t\n\t\t\tthis.getEl(); // ensure this.el\n\t\n\t\t\t// make sure origin info was computed\n\t\t\tif (this.top0 === null) {\n\t\t\t\tthis.sourceEl.width(); // hack to force IE8 to compute correct bounding box\n\t\t\t\tsourceOffset = this.sourceEl.offset();\n\t\t\t\torigin = this.el.offsetParent().offset();\n\t\t\t\tthis.top0 = sourceOffset.top - origin.top;\n\t\t\t\tthis.left0 = sourceOffset.left - origin.left;\n\t\t\t}\n\t\n\t\t\tthis.el.css({\n\t\t\t\ttop: this.top0 + this.topDelta,\n\t\t\t\tleft: this.left0 + this.leftDelta\n\t\t\t});\n\t\t},\n\t\n\t\n\t\t// Gets called when the user moves the mouse\n\t\thandleMove: function(ev) {\n\t\t\tthis.topDelta = getEvY(ev) - this.y0;\n\t\t\tthis.leftDelta = getEvX(ev) - this.x0;\n\t\n\t\t\tif (!this.isHidden) {\n\t\t\t\tthis.updatePosition();\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Temporarily makes the tracking element invisible. Can be called before following starts\n\t\thide: function() {\n\t\t\tif (!this.isHidden) {\n\t\t\t\tthis.isHidden = true;\n\t\t\t\tif (this.el) {\n\t\t\t\t\tthis.el.hide();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Show the tracking element after it has been temporarily hidden\n\t\tshow: function() {\n\t\t\tif (this.isHidden) {\n\t\t\t\tthis.isHidden = false;\n\t\t\t\tthis.updatePosition();\n\t\t\t\tthis.getEl().show();\n\t\t\t}\n\t\t}\n\t\n\t});\n\t\n\t;;\n\t\n\t/* An abstract class comprised of a \"grid\" of areas that each represent a specific datetime\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\tvar Grid = FC.Grid = Class.extend(ListenerMixin, MouseIgnorerMixin, {\n\t\n\t\tview: null, // a View object\n\t\tisRTL: null, // shortcut to the view's isRTL option\n\t\n\t\tstart: null,\n\t\tend: null,\n\t\n\t\tel: null, // the containing element\n\t\telsByFill: null, // a hash of jQuery element sets used for rendering each fill. Keyed by fill name.\n\t\n\t\t// derived from options\n\t\teventTimeFormat: null,\n\t\tdisplayEventTime: null,\n\t\tdisplayEventEnd: null,\n\t\n\t\tminResizeDuration: null, // TODO: hack. set by subclasses. minumum event resize duration\n\t\n\t\t// if defined, holds the unit identified (ex: \"year\" or \"month\") that determines the level of granularity\n\t\t// of the date areas. if not defined, assumes to be day and time granularity.\n\t\t// TODO: port isTimeScale into same system?\n\t\tlargeUnit: null,\n\t\n\t\tdayDragListener: null,\n\t\tsegDragListener: null,\n\t\tsegResizeListener: null,\n\t\texternalDragListener: null,\n\t\n\t\n\t\tconstructor: function(view) {\n\t\t\tthis.view = view;\n\t\t\tthis.isRTL = view.opt('isRTL');\n\t\t\tthis.elsByFill = {};\n\t\n\t\t\tthis.dayDragListener = this.buildDayDragListener();\n\t\t\tthis.initMouseIgnoring();\n\t\t},\n\t\n\t\n\t\t/* Options\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Generates the format string used for event time text, if not explicitly defined by 'timeFormat'\n\t\tcomputeEventTimeFormat: function() {\n\t\t\treturn this.view.opt('smallTimeFormat');\n\t\t},\n\t\n\t\n\t\t// Determines whether events should have their end times displayed, if not explicitly defined by 'displayEventTime'.\n\t\t// Only applies to non-all-day events.\n\t\tcomputeDisplayEventTime: function() {\n\t\t\treturn true;\n\t\t},\n\t\n\t\n\t\t// Determines whether events should have their end times displayed, if not explicitly defined by 'displayEventEnd'\n\t\tcomputeDisplayEventEnd: function() {\n\t\t\treturn true;\n\t\t},\n\t\n\t\n\t\t/* Dates\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Tells the grid about what period of time to display.\n\t\t// Any date-related internal data should be generated.\n\t\tsetRange: function(range) {\n\t\t\tthis.start = range.start.clone();\n\t\t\tthis.end = range.end.clone();\n\t\n\t\t\tthis.rangeUpdated();\n\t\t\tthis.processRangeOptions();\n\t\t},\n\t\n\t\n\t\t// Called when internal variables that rely on the range should be updated\n\t\trangeUpdated: function() {\n\t\t},\n\t\n\t\n\t\t// Updates values that rely on options and also relate to range\n\t\tprocessRangeOptions: function() {\n\t\t\tvar view = this.view;\n\t\t\tvar displayEventTime;\n\t\t\tvar displayEventEnd;\n\t\n\t\t\tthis.eventTimeFormat =\n\t\t\t\tview.opt('eventTimeFormat') ||\n\t\t\t\tview.opt('timeFormat') || // deprecated\n\t\t\t\tthis.computeEventTimeFormat();\n\t\n\t\t\tdisplayEventTime = view.opt('displayEventTime');\n\t\t\tif (displayEventTime == null) {\n\t\t\t\tdisplayEventTime = this.computeDisplayEventTime(); // might be based off of range\n\t\t\t}\n\t\n\t\t\tdisplayEventEnd = view.opt('displayEventEnd');\n\t\t\tif (displayEventEnd == null) {\n\t\t\t\tdisplayEventEnd = this.computeDisplayEventEnd(); // might be based off of range\n\t\t\t}\n\t\n\t\t\tthis.displayEventTime = displayEventTime;\n\t\t\tthis.displayEventEnd = displayEventEnd;\n\t\t},\n\t\n\t\n\t\t// Converts a span (has unzoned start/end and any other grid-specific location information)\n\t\t// into an array of segments (pieces of events whose format is decided by the grid).\n\t\tspanToSegs: function(span) {\n\t\t\t// subclasses must implement\n\t\t},\n\t\n\t\n\t\t// Diffs the two dates, returning a duration, based on granularity of the grid\n\t\t// TODO: port isTimeScale into this system?\n\t\tdiffDates: function(a, b) {\n\t\t\tif (this.largeUnit) {\n\t\t\t\treturn diffByUnit(a, b, this.largeUnit);\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn diffDayTime(a, b);\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t/* Hit Area\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Called before one or more queryHit calls might happen. Should prepare any cached coordinates for queryHit\n\t\tprepareHits: function() {\n\t\t},\n\t\n\t\n\t\t// Called when queryHit calls have subsided. Good place to clear any coordinate caches.\n\t\treleaseHits: function() {\n\t\t},\n\t\n\t\n\t\t// Given coordinates from the topleft of the document, return data about the date-related area underneath.\n\t\t// Can return an object with arbitrary properties (although top/right/left/bottom are encouraged).\n\t\t// Must have a `grid` property, a reference to this current grid. TODO: avoid this\n\t\t// The returned object will be processed by getHitSpan and getHitEl.\n\t\tqueryHit: function(leftOffset, topOffset) {\n\t\t},\n\t\n\t\n\t\t// Given position-level information about a date-related area within the grid,\n\t\t// should return an object with at least a start/end date. Can provide other information as well.\n\t\tgetHitSpan: function(hit) {\n\t\t},\n\t\n\t\n\t\t// Given position-level information about a date-related area within the grid,\n\t\t// should return a jQuery element that best represents it. passed to dayClick callback.\n\t\tgetHitEl: function(hit) {\n\t\t},\n\t\n\t\n\t\t/* Rendering\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Sets the container element that the grid should render inside of.\n\t\t// Does other DOM-related initializations.\n\t\tsetElement: function(el) {\n\t\t\tthis.el = el;\n\t\t\tpreventSelection(el);\n\t\n\t\t\tthis.bindDayHandler('touchstart', this.dayTouchStart);\n\t\t\tthis.bindDayHandler('mousedown', this.dayMousedown);\n\t\n\t\t\t// attach event-element-related handlers. in Grid.events\n\t\t\t// same garbage collection note as above.\n\t\t\tthis.bindSegHandlers();\n\t\n\t\t\tthis.bindGlobalHandlers();\n\t\t},\n\t\n\t\n\t\tbindDayHandler: function(name, handler) {\n\t\t\tvar _this = this;\n\t\n\t\t\t// attach a handler to the grid's root element.\n\t\t\t// jQuery will take care of unregistering them when removeElement gets called.\n\t\t\tthis.el.on(name, function(ev) {\n\t\t\t\tif (\n\t\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) {\n\t\t\t\t\treturn handler.call(_this, ev);\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\n\t\n\t\t// Removes the grid's container element from the DOM. Undoes any other DOM-related attachments.\n\t\t// DOES NOT remove any content beforehand (doesn't clear events or call unrenderDates), unlike View\n\t\tremoveElement: function() {\n\t\t\tthis.unbindGlobalHandlers();\n\t\t\tthis.clearDragListeners();\n\t\n\t\t\tthis.el.remove();\n\t\n\t\t\t// NOTE: we don't null-out this.el for the same reasons we don't do it within View::removeElement\n\t\t},\n\t\n\t\n\t\t// Renders the basic structure of grid view before any content is rendered\n\t\trenderSkeleton: function() {\n\t\t\t// subclasses should implement\n\t\t},\n\t\n\t\n\t\t// Renders the grid's date-related content (like areas that represent days/times).\n\t\t// Assumes setRange has already been called and the skeleton has already been rendered.\n\t\trenderDates: function() {\n\t\t\t// subclasses should implement\n\t\t},\n\t\n\t\n\t\t// Unrenders the grid's date-related content\n\t\tunrenderDates: function() {\n\t\t\t// subclasses should implement\n\t\t},\n\t\n\t\n\t\t/* Handlers\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Binds DOM handlers to elements that reside outside the grid, such as the document\n\t\tbindGlobalHandlers: function() {\n\t\t\tthis.listenTo($(document), {\n\t\t\t\tdragstart: this.externalDragStart, // jqui\n\t\t\t\tsortstart: this.externalDragStart // jqui\n\t\t\t});\n\t\t},\n\t\n\t\n\t\t// Unbinds DOM handlers from elements that reside outside the grid\n\t\tunbindGlobalHandlers: function() {\n\t\t\tthis.stopListeningTo($(document));\n\t\t},\n\t\n\t\n\t\t// Process a mousedown on an element that represents a day. For day clicking and selecting.\n\t\tdayMousedown: function(ev) {\n\t\t\tif (!this.isIgnoringMouse) {\n\t\t\t\tthis.dayDragListener.startInteraction(ev, {\n\t\t\t\t\t//distance: 5, // needs more work if we want dayClick to fire correctly\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\n\t\n\t\tdayTouchStart: function(ev) {\n\t\t\tvar view = this.view;\n\t\n\t\t\t// HACK to prevent a user's clickaway for unselecting a range or an event\n\t\t\t// from causing a dayClick.\n\t\t\tif (view.isSelected || view.selectedEvent) {\n\t\t\t\tthis.tempIgnoreMouse();\n\t\t\t}\n\t\n\t\t\tthis.dayDragListener.startInteraction(ev, {\n\t\t\t\tdelay: this.view.opt('longPressDelay')\n\t\t\t});\n\t\t},\n\t\n\t\n\t\t// Creates a listener that tracks the user's drag across day elements.\n\t\t// For day clicking and selecting.\n\t\tbuildDayDragListener: function() {\n\t\t\tvar _this = this;\n\t\t\tvar view = this.view;\n\t\t\tvar isSelectable = view.opt('selectable');\n\t\t\tvar dayClickHit; // null if invalid dayClick\n\t\t\tvar selectionSpan; // null if invalid selection\n\t\n\t\t\t// this listener tracks a mousedown on a day element, and a subsequent drag.\n\t\t\t// if the drag ends on the same day, it is a 'dayClick'.\n\t\t\t// if 'selectable' is enabled, this listener also detects selections.\n\t\t\tvar dragListener = new HitDragListener(this, {\n\t\t\t\tscroll: view.opt('dragScroll'),\n\t\t\t\tinteractionStart: function() {\n\t\t\t\t\tdayClickHit = dragListener.origHit; // for dayClick, where no dragging happens\n\t\t\t\t\tselectionSpan = null;\n\t\t\t\t},\n\t\t\t\tdragStart: function() {\n\t\t\t\t\tview.unselect(); // since we could be rendering a new selection, we want to clear any old one\n\t\t\t\t},\n\t\t\t\thitOver: function(hit, isOrig, origHit) {\n\t\t\t\t\tif (origHit) { // click needs to have started on a hit\n\t\n\t\t\t\t\t\t// if user dragged to another cell at any point, it can no longer be a dayClick\n\t\t\t\t\t\tif (!isOrig) {\n\t\t\t\t\t\t\tdayClickHit = null;\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tif (isSelectable) {\n\t\t\t\t\t\t\tselectionSpan = _this.computeSelection(\n\t\t\t\t\t\t\t\t_this.getHitSpan(origHit),\n\t\t\t\t\t\t\t\t_this.getHitSpan(hit)\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (selectionSpan) {\n\t\t\t\t\t\t\t\t_this.renderSelection(selectionSpan);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (selectionSpan === false) {\n\t\t\t\t\t\t\t\tdisableCursor();\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\thitOut: function() { // called before mouse moves to a different hit OR moved out of all hits\n\t\t\t\t\tdayClickHit = null;\n\t\t\t\t\tselectionSpan = null;\n\t\t\t\t\t_this.unrenderSelection();\n\t\t\t\t},\n\t\t\t\thitDone: function() { // called after a hitOut OR before a dragEnd\n\t\t\t\t\tenableCursor();\n\t\t\t\t},\n\t\t\t\tinteractionEnd: function(ev, isCancelled) {\n\t\t\t\t\tif (!isCancelled) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tdayClickHit &&\n\t\t\t\t\t\t\t!_this.isIgnoringMouse // see hack in dayTouchStart\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tview.triggerDayClick(\n\t\t\t\t\t\t\t\t_this.getHitSpan(dayClickHit),\n\t\t\t\t\t\t\t\t_this.getHitEl(dayClickHit),\n\t\t\t\t\t\t\t\tev\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (selectionSpan) {\n\t\t\t\t\t\t\t// the selection will already have been rendered. just report it\n\t\t\t\t\t\t\tview.reportSelection(selectionSpan, ev);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\n\t\t\treturn dragListener;\n\t\t},\n\t\n\t\n\t\t// Kills all in-progress dragging.\n\t\t// Useful for when public API methods that result in re-rendering are invoked during a drag.\n\t\t// Also useful for when touch devices misbehave and don't fire their touchend.\n\t\tclearDragListeners: function() {\n\t\t\tthis.dayDragListener.endInteraction();\n\t\n\t\t\tif (this.segDragListener) {\n\t\t\t\tthis.segDragListener.endInteraction(); // will clear this.segDragListener\n\t\t\t}\n\t\t\tif (this.segResizeListener) {\n\t\t\t\tthis.segResizeListener.endInteraction(); // will clear this.segResizeListener\n\t\t\t}\n\t\t\tif (this.externalDragListener) {\n\t\t\t\tthis.externalDragListener.endInteraction(); // will clear this.externalDragListener\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t/* Event Helper\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\t// TODO: should probably move this to Grid.events, like we did event dragging / resizing\n\t\n\t\n\t\t// Renders a mock event at the given event location, which contains zoned start/end properties.\n\t\t// Returns all mock event elements.\n\t\trenderEventLocationHelper: function(eventLocation, sourceSeg) {\n\t\t\tvar fakeEvent = this.fabricateHelperEvent(eventLocation, sourceSeg);\n\t\n\t\t\treturn this.renderHelper(fakeEvent, sourceSeg); // do the actual rendering\n\t\t},\n\t\n\t\n\t\t// Builds a fake event given zoned event date properties and a segment is should be inspired from.\n\t\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\t// `sourceSeg` is the internal segment object involved in the drag. If null, something external is dragging.\n\t\tfabricateHelperEvent: function(eventLocation, sourceSeg) {\n\t\t\tvar fakeEvent = sourceSeg ? createObject(sourceSeg.event) : {}; // mask the original event object if possible\n\t\n\t\t\tfakeEvent.start = eventLocation.start.clone();\n\t\t\tfakeEvent.end = eventLocation.end ? eventLocation.end.clone() : null;\n\t\t\tfakeEvent.allDay = null; // force it to be freshly computed by normalizeEventDates\n\t\t\tthis.view.calendar.normalizeEventDates(fakeEvent);\n\t\n\t\t\t// this extra className will be useful for differentiating real events from mock events in CSS\n\t\t\tfakeEvent.className = (fakeEvent.className || []).concat('fc-helper');\n\t\n\t\t\t// if something external is being dragged in, don't render a resizer\n\t\t\tif (!sourceSeg) {\n\t\t\t\tfakeEvent.editable = false;\n\t\t\t}\n\t\n\t\t\treturn fakeEvent;\n\t\t},\n\t\n\t\n\t\t// Renders a mock event. Given zoned event date properties.\n\t\t// Must return all mock event elements.\n\t\trenderHelper: function(eventLocation, sourceSeg) {\n\t\t\t// subclasses must implement\n\t\t},\n\t\n\t\n\t\t// Unrenders a mock event\n\t\tunrenderHelper: function() {\n\t\t\t// subclasses must implement\n\t\t},\n\t\n\t\n\t\t/* Selection\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Renders a visual indication of a selection. Will highlight by default but can be overridden by subclasses.\n\t\t// Given a span (unzoned start/end and other misc data)\n\t\trenderSelection: function(span) {\n\t\t\tthis.renderHighlight(span);\n\t\t},\n\t\n\t\n\t\t// Unrenders any visual indications of a selection. Will unrender a highlight by default.\n\t\tunrenderSelection: function() {\n\t\t\tthis.unrenderHighlight();\n\t\t},\n\t\n\t\n\t\t// Given the first and last date-spans of a selection, returns another date-span object.\n\t\t// Subclasses can override and provide additional data in the span object. Will be passed to renderSelection().\n\t\t// Will return false if the selection is invalid and this should be indicated to the user.\n\t\t// Will return null/undefined if a selection invalid but no error should be reported.\n\t\tcomputeSelection: function(span0, span1) {\n\t\t\tvar span = this.computeSelectionSpan(span0, span1);\n\t\n\t\t\tif (span && !this.view.calendar.isSelectionSpanAllowed(span)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\n\t\t\treturn span;\n\t\t},\n\t\n\t\n\t\t// Given two spans, must return the combination of the two.\n\t\t// TODO: do this separation of concerns (combining VS validation) for event dnd/resize too.\n\t\tcomputeSelectionSpan: function(span0, span1) {\n\t\t\tvar dates = [ span0.start, span0.end, span1.start, span1.end ];\n\t\n\t\t\tdates.sort(compareNumbers); // sorts chronologically. works with Moments\n\t\n\t\t\treturn { start: dates[0].clone(), end: dates[3].clone() };\n\t\t},\n\t\n\t\n\t\t/* Highlight\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Renders an emphasis on the given date range. Given a span (unzoned start/end and other misc data)\n\t\trenderHighlight: function(span) {\n\t\t\tthis.renderFill('highlight', this.spanToSegs(span));\n\t\t},\n\t\n\t\n\t\t// Unrenders the emphasis on a date range\n\t\tunrenderHighlight: function() {\n\t\t\tthis.unrenderFill('highlight');\n\t\t},\n\t\n\t\n\t\t// Generates an array of classNames for rendering the highlight. Used by the fill system.\n\t\thighlightSegClasses: function() {\n\t\t\treturn [ 'fc-highlight' ];\n\t\t},\n\t\n\t\n\t\t/* Business Hours\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\trenderBusinessHours: function() {\n\t\t},\n\t\n\t\n\t\tunrenderBusinessHours: function() {\n\t\t},\n\t\n\t\n\t\t/* Now Indicator\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\tgetNowIndicatorUnit: function() {\n\t\t},\n\t\n\t\n\t\trenderNowIndicator: function(date) {\n\t\t},\n\t\n\t\n\t\tunrenderNowIndicator: function() {\n\t\t},\n\t\n\t\n\t\t/* Fill System (highlight, background events, business hours)\n\t\t--------------------------------------------------------------------------------------------------------------------\n\t\tTODO: remove this system. like we did in TimeGrid\n\t\t*/\n\t\n\t\n\t\t// Renders a set of rectangles over the given segments of time.\n\t\t// MUST RETURN a subset of segs, the segs that were actually rendered.\n\t\t// Responsible for populating this.elsByFill. TODO: better API for expressing this requirement\n\t\trenderFill: function(type, segs) {\n\t\t\t// subclasses must implement\n\t\t},\n\t\n\t\n\t\t// Unrenders a specific type of fill that is currently rendered on the grid\n\t\tunrenderFill: function(type) {\n\t\t\tvar el = this.elsByFill[type];\n\t\n\t\t\tif (el) {\n\t\t\t\tel.remove();\n\t\t\t\tdelete this.elsByFill[type];\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Renders and assigns an `el` property for each fill segment. Generic enough to work with different types.\n\t\t// Only returns segments that successfully rendered.\n\t\t// To be harnessed by renderFill (implemented by subclasses).\n\t\t// Analagous to renderFgSegEls.\n\t\trenderFillSegEls: function(type, segs) {\n\t\t\tvar _this = this;\n\t\t\tvar segElMethod = this[type + 'SegEl'];\n\t\t\tvar html = '';\n\t\t\tvar renderedSegs = [];\n\t\t\tvar i;\n\t\n\t\t\tif (segs.length) {\n\t\n\t\t\t\t// build a large concatenation of segment HTML\n\t\t\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\t\t\thtml += this.fillSegHtml(type, segs[i]);\n\t\t\t\t}\n\t\n\t\t\t\t// Grab individual elements from the combined HTML string. Use each as the default rendering.\n\t\t\t\t// Then, compute the 'el' for each segment.\n\t\t\t\t$(html).each(function(i, node) {\n\t\t\t\t\tvar seg = segs[i];\n\t\t\t\t\tvar el = $(node);\n\t\n\t\t\t\t\t// allow custom filter methods per-type\n\t\t\t\t\tif (segElMethod) {\n\t\t\t\t\t\tel = segElMethod.call(_this, seg, el);\n\t\t\t\t\t}\n\t\n\t\t\t\t\tif (el) { // custom filters did not cancel the render\n\t\t\t\t\t\tel = $(el); // allow custom filter to return raw DOM node\n\t\n\t\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\t\tif (el.is(_this.fillSegTag)) {\n\t\t\t\t\t\t\tseg.el = el;\n\t\t\t\t\t\t\trenderedSegs.push(seg);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\n\t\t\treturn renderedSegs;\n\t\t},\n\t\n\t\n\t\tfillSegTag: 'div', // subclasses can override\n\t\n\t\n\t\t// Builds the HTML needed for one fill segment. Generic enough to work with different types.\n\t\tfillSegHtml: function(type, seg) {\n\t\n\t\t\t// custom hooks per-type\n\t\t\tvar classesMethod = this[type + 'SegClasses'];\n\t\t\tvar cssMethod = this[type + 'SegCss'];\n\t\n\t\t\tvar classes = classesMethod ? classesMethod.call(this, seg) : [];\n\t\t\tvar css = cssToStr(cssMethod ? cssMethod.call(this, seg) : {});\n\t\n\t\t\treturn '<' + this.fillSegTag +\n\t\t\t\t(classes.length ? ' class=\"' + classes.join(' ') + '\"' : '') +\n\t\t\t\t(css ? ' style=\"' + css + '\"' : '') +\n\t\t\t\t' />';\n\t\t},\n\t\n\t\n\t\n\t\t/* Generic rendering utilities for subclasses\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Computes HTML classNames for a single-day element\n\t\tgetDayClasses: function(date) {\n\t\t\tvar view = this.view;\n\t\t\tvar today = view.calendar.getNow();\n\t\t\tvar classes = [ 'fc-' + dayIDs[date.day()] ];\n\t\n\t\t\tif (\n\t\t\t\tview.intervalDuration.as('months') == 1 &&\n\t\t\t\tdate.month() != view.intervalStart.month()\n\t\t\t) {\n\t\t\t\tclasses.push('fc-other-month');\n\t\t\t}\n\t\n\t\t\tif (date.isSame(today, 'day')) {\n\t\t\t\tclasses.push(\n\t\t\t\t\t'fc-today',\n\t\t\t\t\tview.highlightStateClass\n\t\t\t\t);\n\t\t\t}\n\t\t\telse if (date < today) {\n\t\t\t\tclasses.push('fc-past');\n\t\t\t}\n\t\t\telse {\n\t\t\t\tclasses.push('fc-future');\n\t\t\t}\n\t\n\t\t\treturn classes;\n\t\t}\n\t\n\t});\n\t\n\t;;\n\t\n\t/* Event-rendering and event-interaction methods for the abstract Grid class\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\tGrid.mixin({\n\t\n\t\tmousedOverSeg: null, // the segment object the user's mouse is over. null if over nothing\n\t\tisDraggingSeg: false, // is a segment being dragged? boolean\n\t\tisResizingSeg: false, // is a segment being resized? boolean\n\t\tisDraggingExternal: false, // jqui-dragging an external element? boolean\n\t\tsegs: null, // the *event* segments currently rendered in the grid. TODO: rename to `eventSegs`\n\t\n\t\n\t\t// Renders the given events onto the grid\n\t\trenderEvents: function(events) {\n\t\t\tvar bgEvents = [];\n\t\t\tvar fgEvents = [];\n\t\t\tvar i;\n\t\n\t\t\tfor (i = 0; i < events.length; i++) {\n\t\t\t\t(isBgEvent(events[i]) ? bgEvents : fgEvents).push(events[i]);\n\t\t\t}\n\t\n\t\t\tthis.segs = [].concat( // record all segs\n\t\t\t\tthis.renderBgEvents(bgEvents),\n\t\t\t\tthis.renderFgEvents(fgEvents)\n\t\t\t);\n\t\t},\n\t\n\t\n\t\trenderBgEvents: function(events) {\n\t\t\tvar segs = this.eventsToSegs(events);\n\t\n\t\t\t// renderBgSegs might return a subset of segs, segs that were actually rendered\n\t\t\treturn this.renderBgSegs(segs) || segs;\n\t\t},\n\t\n\t\n\t\trenderFgEvents: function(events) {\n\t\t\tvar segs = this.eventsToSegs(events);\n\t\n\t\t\t// renderFgSegs might return a subset of segs, segs that were actually rendered\n\t\t\treturn this.renderFgSegs(segs) || segs;\n\t\t},\n\t\n\t\n\t\t// Unrenders all events currently rendered on the grid\n\t\tunrenderEvents: function() {\n\t\t\tthis.handleSegMouseout(); // trigger an eventMouseout if user's mouse is over an event\n\t\t\tthis.clearDragListeners();\n\t\n\t\t\tthis.unrenderFgSegs();\n\t\t\tthis.unrenderBgSegs();\n\t\n\t\t\tthis.segs = null;\n\t\t},\n\t\n\t\n\t\t// Retrieves all rendered segment objects currently rendered on the grid\n\t\tgetEventSegs: function() {\n\t\t\treturn this.segs || [];\n\t\t},\n\t\n\t\n\t\t/* Foreground Segment Rendering\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Renders foreground event segments onto the grid. May return a subset of segs that were rendered.\n\t\trenderFgSegs: function(segs) {\n\t\t\t// subclasses must implement\n\t\t},\n\t\n\t\n\t\t// Unrenders all currently rendered foreground segments\n\t\tunrenderFgSegs: function() {\n\t\t\t// subclasses must implement\n\t\t},\n\t\n\t\n\t\t// Renders and assigns an `el` property for each foreground event segment.\n\t\t// Only returns segments that successfully rendered.\n\t\t// A utility that subclasses may use.\n\t\trenderFgSegEls: function(segs, disableResizing) {\n\t\t\tvar view = this.view;\n\t\t\tvar html = '';\n\t\t\tvar renderedSegs = [];\n\t\t\tvar i;\n\t\n\t\t\tif (segs.length) { // don't build an empty html string\n\t\n\t\t\t\t// build a large concatenation of event segment HTML\n\t\t\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\t\t\thtml += this.fgSegHtml(segs[i], disableResizing);\n\t\t\t\t}\n\t\n\t\t\t\t// Grab individual elements from the combined HTML string. Use each as the default rendering.\n\t\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\t$(html).each(function(i, node) {\n\t\t\t\t\tvar seg = segs[i];\n\t\t\t\t\tvar el = view.resolveEventEl(seg.event, $(node));\n\t\n\t\t\t\t\tif (el) {\n\t\t\t\t\t\tel.data('fc-seg', seg); // used by handlers\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\n\t\t\treturn renderedSegs;\n\t\t},\n\t\n\t\n\t\t// Generates the HTML for the default rendering of a foreground event segment. Used by renderFgSegEls()\n\t\tfgSegHtml: function(seg, disableResizing) {\n\t\t\t// subclasses should implement\n\t\t},\n\t\n\t\n\t\t/* Background Segment Rendering\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Renders the given background event segments onto the grid.\n\t\t// Returns a subset of the segs that were actually rendered.\n\t\trenderBgSegs: function(segs) {\n\t\t\treturn this.renderFill('bgEvent', segs);\n\t\t},\n\t\n\t\n\t\t// Unrenders all the currently rendered background event segments\n\t\tunrenderBgSegs: function() {\n\t\t\tthis.unrenderFill('bgEvent');\n\t\t},\n\t\n\t\n\t\t// Renders a background event element, given the default rendering. Called by the fill system.\n\t\tbgEventSegEl: function(seg, el) {\n\t\t\treturn this.view.resolveEventEl(seg.event, el); // will filter through eventRender\n\t\t},\n\t\n\t\n\t\t// Generates an array of classNames to be used for the default rendering of a background event.\n\t\t// Called by fillSegHtml.\n\t\tbgEventSegClasses: function(seg) {\n\t\t\tvar event = seg.event;\n\t\t\tvar source = event.source || {};\n\t\n\t\t\treturn [ 'fc-bgevent' ].concat(\n\t\t\t\tevent.className,\n\t\t\t\tsource.className || []\n\t\t\t);\n\t\t},\n\t\n\t\n\t\t// Generates a semicolon-separated CSS string to be used for the default rendering of a background event.\n\t\t// Called by fillSegHtml.\n\t\tbgEventSegCss: function(seg) {\n\t\t\treturn {\n\t\t\t\t'background-color': this.getSegSkinCss(seg)['background-color']\n\t\t\t};\n\t\t},\n\t\n\t\n\t\t// Generates an array of classNames to be used for the rendering business hours overlay. Called by the fill system.\n\t\t// Called by fillSegHtml.\n\t\tbusinessHoursSegClasses: function(seg) {\n\t\t\treturn [ 'fc-nonbusiness', 'fc-bgevent' ];\n\t\t},\n\t\n\t\n\t\t/* Business Hours\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Compute business hour segs for the grid's current date range.\n\t\t// Caller must ask if whole-day business hours are needed.\n\t\tbuildBusinessHourSegs: function(wholeDay) {\n\t\t\tvar events = this.view.calendar.getCurrentBusinessHourEvents(wholeDay);\n\t\n\t\t\t// HACK. Eventually refactor business hours \"events\" system.\n\t\t\t// If no events are given, but businessHours is activated, this means the entire visible range should be\n\t\t\t// marked as *not* business-hours, via inverse-background rendering.\n\t\t\tif (\n\t\t\t\t!events.length &&\n\t\t\t\tthis.view.calendar.options.businessHours // don't access view option. doesn't update with dynamic options\n\t\t\t) {\n\t\t\t\tevents = [\n\t\t\t\t\t$.extend({}, BUSINESS_HOUR_EVENT_DEFAULTS, {\n\t\t\t\t\t\tstart: this.view.end, // guaranteed out-of-range\n\t\t\t\t\t\tend: this.view.end, // \"\n\t\t\t\t\t\tdow: null\n\t\t\t\t\t})\n\t\t\t\t];\n\t\t\t}\n\t\n\t\t\treturn this.eventsToSegs(events);\n\t\t},\n\t\n\t\n\t\t/* Handlers\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Attaches event-element-related handlers for *all* rendered event segments of the view.\n\t\tbindSegHandlers: function() {\n\t\t\tthis.bindSegHandlersToEl(this.el);\n\t\t},\n\t\n\t\n\t\t// Attaches event-element-related handlers to an arbitrary container element. leverages bubbling.\n\t\tbindSegHandlersToEl: function(el) {\n\t\t\tthis.bindSegHandlerToEl(el, 'touchstart', this.handleSegTouchStart);\n\t\t\tthis.bindSegHandlerToEl(el, 'touchend', this.handleSegTouchEnd);\n\t\t\tthis.bindSegHandlerToEl(el, 'mouseenter', this.handleSegMouseover);\n\t\t\tthis.bindSegHandlerToEl(el, 'mouseleave', this.handleSegMouseout);\n\t\t\tthis.bindSegHandlerToEl(el, 'mousedown', this.handleSegMousedown);\n\t\t\tthis.bindSegHandlerToEl(el, 'click', this.handleSegClick);\n\t\t},\n\t\n\t\n\t\t// Executes a handler for any a user-interaction on a segment.\n\t\t// Handler gets called with (seg, ev), and with the `this` context of the Grid\n\t\tbindSegHandlerToEl: function(el, name, handler) {\n\t\t\tvar _this = this;\n\t\n\t\t\tel.on(name, '.fc-event-container > *', function(ev) {\n\t\t\t\tvar seg = $(this).data('fc-seg'); // grab segment data. put there by View::renderEvents\n\t\n\t\t\t\t// only call the handlers if there is not a drag/resize in progress\n\t\t\t\tif (seg && !_this.isDraggingSeg && !_this.isResizingSeg) {\n\t\t\t\t\treturn handler.call(_this, seg, ev); // context will be the Grid\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\n\t\n\t\thandleSegClick: function(seg, ev) {\n\t\t\treturn this.view.trigger('eventClick', seg.el[0], seg.event, ev); // can return `false` to cancel\n\t\t},\n\t\n\t\n\t\t// Updates internal state and triggers handlers for when an event element is moused over\n\t\thandleSegMouseover: function(seg, ev) {\n\t\t\tif (\n\t\t\t\t!this.isIgnoringMouse &&\n\t\t\t\t!this.mousedOverSeg\n\t\t\t) {\n\t\t\t\tthis.mousedOverSeg = seg;\n\t\t\t\tseg.el.addClass('fc-allow-mouse-resize');\n\t\t\t\tthis.view.trigger('eventMouseover', seg.el[0], seg.event, ev);\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Updates internal state and triggers handlers for when an event element is moused out.\n\t\t// Can be given no arguments, in which case it will mouseout the segment that was previously moused over.\n\t\thandleSegMouseout: function(seg, ev) {\n\t\t\tev = ev || {}; // if given no args, make a mock mouse event\n\t\n\t\t\tif (this.mousedOverSeg) {\n\t\t\t\tseg = seg || this.mousedOverSeg; // if given no args, use the currently moused-over segment\n\t\t\t\tthis.mousedOverSeg = null;\n\t\t\t\tseg.el.removeClass('fc-allow-mouse-resize');\n\t\t\t\tthis.view.trigger('eventMouseout', seg.el[0], seg.event, ev);\n\t\t\t}\n\t\t},\n\t\n\t\n\t\thandleSegMousedown: function(seg, ev) {\n\t\t\tvar isResizing = this.startSegResize(seg, ev, { distance: 5 });\n\t\n\t\t\tif (!isResizing && this.view.isEventDraggable(seg.event)) {\n\t\t\t\tthis.buildSegDragListener(seg)\n\t\t\t\t\t.startInteraction(ev, {\n\t\t\t\t\t\tdistance: 5\n\t\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\n\t\n\t\thandleSegTouchStart: function(seg, ev) {\n\t\t\tvar view = this.view;\n\t\t\tvar event = seg.event;\n\t\t\tvar isSelected = view.isEventSelected(event);\n\t\t\tvar isDraggable = view.isEventDraggable(event);\n\t\t\tvar isResizable = view.isEventResizable(event);\n\t\t\tvar isResizing = false;\n\t\t\tvar dragListener;\n\t\n\t\t\tif (isSelected && isResizable) {\n\t\t\t\t// only allow resizing of the event is selected\n\t\t\t\tisResizing = this.startSegResize(seg, ev);\n\t\t\t}\n\t\n\t\t\tif (!isResizing && (isDraggable || isResizable)) { // allowed to be selected?\n\t\n\t\t\t\tdragListener = isDraggable ?\n\t\t\t\t\tthis.buildSegDragListener(seg) :\n\t\t\t\t\tthis.buildSegSelectListener(seg); // seg isn't draggable, but still needs to be selected\n\t\n\t\t\t\tdragListener.startInteraction(ev, { // won't start if already started\n\t\t\t\t\tdelay: isSelected ? 0 : this.view.opt('longPressDelay') // do delay if not already selected\n\t\t\t\t});\n\t\t\t}\n\t\n\t\t\t// a long tap simulates a mouseover. ignore this bogus mouseover.\n\t\t\tthis.tempIgnoreMouse();\n\t\t},\n\t\n\t\n\t\thandleSegTouchEnd: function(seg, ev) {\n\t\t\t// touchstart+touchend = click, which simulates a mouseover.\n\t\t\t// ignore this bogus mouseover.\n\t\t\tthis.tempIgnoreMouse();\n\t\t},\n\t\n\t\n\t\t// returns boolean whether resizing actually started or not.\n\t\t// assumes the seg allows resizing.\n\t\t// `dragOptions` are optional.\n\t\tstartSegResize: function(seg, ev, dragOptions) {\n\t\t\tif ($(ev.target).is('.fc-resizer')) {\n\t\t\t\tthis.buildSegResizeListener(seg, $(ev.target).is('.fc-start-resizer'))\n\t\t\t\t\t.startInteraction(ev, dragOptions);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\n\t\n\t\n\t\t/* Event Dragging\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Builds a listener that will track user-dragging on an event segment.\n\t\t// Generic enough to work with any type of Grid.\n\t\t// Has side effect of setting/unsetting `segDragListener`\n\t\tbuildSegDragListener: function(seg) {\n\t\t\tvar _this = this;\n\t\t\tvar view = this.view;\n\t\t\tvar calendar = view.calendar;\n\t\t\tvar el = seg.el;\n\t\t\tvar event = seg.event;\n\t\t\tvar isDragging;\n\t\t\tvar mouseFollower; // A clone of the original element that will move with the mouse\n\t\t\tvar dropLocation; // zoned event date properties\n\t\n\t\t\tif (this.segDragListener) {\n\t\t\t\treturn this.segDragListener;\n\t\t\t}\n\t\n\t\t\t// Tracks mouse movement over the *view's* coordinate map. Allows dragging and dropping between subcomponents\n\t\t\t// of the view.\n\t\t\tvar dragListener = this.segDragListener = new HitDragListener(view, {\n\t\t\t\tscroll: view.opt('dragScroll'),\n\t\t\t\tsubjectEl: el,\n\t\t\t\tsubjectCenter: true,\n\t\t\t\tinteractionStart: function(ev) {\n\t\t\t\t\tseg.component = _this; // for renderDrag\n\t\t\t\t\tisDragging = false;\n\t\t\t\t\tmouseFollower = new MouseFollower(seg.el, {\n\t\t\t\t\t\tadditionalClass: 'fc-dragging',\n\t\t\t\t\t\tparentEl: view.el,\n\t\t\t\t\t\topacity: dragListener.isTouch ? null : view.opt('dragOpacity'),\n\t\t\t\t\t\trevertDuration: view.opt('dragRevertDuration'),\n\t\t\t\t\t\tzIndex: 2 // one above the .fc-view\n\t\t\t\t\t});\n\t\t\t\t\tmouseFollower.hide(); // don't show until we know this is a real drag\n\t\t\t\t\tmouseFollower.start(ev);\n\t\t\t\t},\n\t\t\t\tdragStart: function(ev) {\n\t\t\t\t\tif (dragListener.isTouch && !view.isEventSelected(event)) {\n\t\t\t\t\t\t// if not previously selected, will fire after a delay. then, select the event\n\t\t\t\t\t\tview.selectEvent(event);\n\t\t\t\t\t}\n\t\t\t\t\tisDragging = true;\n\t\t\t\t\t_this.handleSegMouseout(seg, ev); // ensure a mouseout on the manipulated event has been reported\n\t\t\t\t\t_this.segDragStart(seg, ev);\n\t\t\t\t\tview.hideEvent(event); // hide all event segments. our mouseFollower will take over\n\t\t\t\t},\n\t\t\t\thitOver: function(hit, isOrig, origHit) {\n\t\t\t\t\tvar dragHelperEls;\n\t\n\t\t\t\t\t// starting hit could be forced (DayGrid.limit)\n\t\t\t\t\tif (seg.hit) {\n\t\t\t\t\t\torigHit = seg.hit;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// since we are querying the parent view, might not belong to this grid\n\t\t\t\t\tdropLocation = _this.computeEventDrop(\n\t\t\t\t\t\torigHit.component.getHitSpan(origHit),\n\t\t\t\t\t\thit.component.getHitSpan(hit),\n\t\t\t\t\t\tevent\n\t\t\t\t\t);\n\t\n\t\t\t\t\tif (dropLocation && !calendar.isEventSpanAllowed(_this.eventToSpan(dropLocation), event)) {\n\t\t\t\t\t\tdisableCursor();\n\t\t\t\t\t\tdropLocation = null;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// if a valid drop location, have the subclass render a visual indication\n\t\t\t\t\tif (dropLocation && (dragHelperEls = view.renderDrag(dropLocation, seg))) {\n\t\n\t\t\t\t\t\tdragHelperEls.addClass('fc-dragging');\n\t\t\t\t\t\tif (!dragListener.isTouch) {\n\t\t\t\t\t\t\t_this.applyDragOpacity(dragHelperEls);\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tmouseFollower.hide(); // if the subclass is already using a mock event \"helper\", hide our own\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tmouseFollower.show(); // otherwise, have the helper follow the mouse (no snapping)\n\t\t\t\t\t}\n\t\n\t\t\t\t\tif (isOrig) {\n\t\t\t\t\t\tdropLocation = null; // needs to have moved hits to be a valid drop\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\thitOut: function() { // called before mouse moves to a different hit OR moved out of all hits\n\t\t\t\t\tview.unrenderDrag(); // unrender whatever was done in renderDrag\n\t\t\t\t\tmouseFollower.show(); // show in case we are moving out of all hits\n\t\t\t\t\tdropLocation = null;\n\t\t\t\t},\n\t\t\t\thitDone: function() { // Called after a hitOut OR before a dragEnd\n\t\t\t\t\tenableCursor();\n\t\t\t\t},\n\t\t\t\tinteractionEnd: function(ev) {\n\t\t\t\t\tdelete seg.component; // prevent side effects\n\t\n\t\t\t\t\t// do revert animation if hasn't changed. calls a callback when finished (whether animation or not)\n\t\t\t\t\tmouseFollower.stop(!dropLocation, function() {\n\t\t\t\t\t\tif (isDragging) {\n\t\t\t\t\t\t\tview.unrenderDrag();\n\t\t\t\t\t\t\tview.showEvent(event);\n\t\t\t\t\t\t\t_this.segDragStop(seg, ev);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (dropLocation) {\n\t\t\t\t\t\t\tview.reportEventDrop(event, dropLocation, this.largeUnit, el, ev);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\t_this.segDragListener = null;\n\t\t\t\t}\n\t\t\t});\n\t\n\t\t\treturn dragListener;\n\t\t},\n\t\n\t\n\t\t// seg isn't draggable, but let's use a generic DragListener\n\t\t// simply for the delay, so it can be selected.\n\t\t// Has side effect of setting/unsetting `segDragListener`\n\t\tbuildSegSelectListener: function(seg) {\n\t\t\tvar _this = this;\n\t\t\tvar view = this.view;\n\t\t\tvar event = seg.event;\n\t\n\t\t\tif (this.segDragListener) {\n\t\t\t\treturn this.segDragListener;\n\t\t\t}\n\t\n\t\t\tvar dragListener = this.segDragListener = new DragListener({\n\t\t\t\tdragStart: function(ev) {\n\t\t\t\t\tif (dragListener.isTouch && !view.isEventSelected(event)) {\n\t\t\t\t\t\t// if not previously selected, will fire after a delay. then, select the event\n\t\t\t\t\t\tview.selectEvent(event);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tinteractionEnd: function(ev) {\n\t\t\t\t\t_this.segDragListener = null;\n\t\t\t\t}\n\t\t\t});\n\t\n\t\t\treturn dragListener;\n\t\t},\n\t\n\t\n\t\t// Called before event segment dragging starts\n\t\tsegDragStart: function(seg, ev) {\n\t\t\tthis.isDraggingSeg = true;\n\t\t\tthis.view.trigger('eventDragStart', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy\n\t\t},\n\t\n\t\n\t\t// Called after event segment dragging stops\n\t\tsegDragStop: function(seg, ev) {\n\t\t\tthis.isDraggingSeg = false;\n\t\t\tthis.view.trigger('eventDragStop', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy\n\t\t},\n\t\n\t\n\t\t// Given the spans an event drag began, and the span event was dropped, calculates the new zoned start/end/allDay\n\t\t// values for the event. Subclasses may override and set additional properties to be used by renderDrag.\n\t\t// A falsy returned value indicates an invalid drop.\n\t\t// DOES NOT consider overlap/constraint.\n\t\tcomputeEventDrop: function(startSpan, endSpan, event) {\n\t\t\tvar calendar = this.view.calendar;\n\t\t\tvar dragStart = startSpan.start;\n\t\t\tvar dragEnd = endSpan.start;\n\t\t\tvar delta;\n\t\t\tvar dropLocation; // zoned event date properties\n\t\n\t\t\tif (dragStart.hasTime() === dragEnd.hasTime()) {\n\t\t\t\tdelta = this.diffDates(dragEnd, dragStart);\n\t\n\t\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\t// guarantee an end and adjust start/end to have times\n\t\t\t\tif (event.allDay && durationHasTime(delta)) {\n\t\t\t\t\tdropLocation = {\n\t\t\t\t\t\tstart: event.start.clone(),\n\t\t\t\t\t\tend: calendar.getEventEnd(event), // will be an ambig day\n\t\t\t\t\t\tallDay: false // for normalizeEventTimes\n\t\t\t\t\t};\n\t\t\t\t\tcalendar.normalizeEventTimes(dropLocation);\n\t\t\t\t}\n\t\t\t\t// othewise, work off existing values\n\t\t\t\telse {\n\t\t\t\t\tdropLocation = {\n\t\t\t\t\t\tstart: event.start.clone(),\n\t\t\t\t\t\tend: event.end ? event.end.clone() : null,\n\t\t\t\t\t\tallDay: event.allDay // keep it the same\n\t\t\t\t\t};\n\t\t\t\t}\n\t\n\t\t\t\tdropLocation.start.add(delta);\n\t\t\t\tif (dropLocation.end) {\n\t\t\t\t\tdropLocation.end.add(delta);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// if switching from day <-> timed, start should be reset to the dropped date, and the end cleared\n\t\t\t\tdropLocation = {\n\t\t\t\t\tstart: dragEnd.clone(),\n\t\t\t\t\tend: null, // end should be cleared\n\t\t\t\t\tallDay: !dragEnd.hasTime()\n\t\t\t\t};\n\t\t\t}\n\t\n\t\t\treturn dropLocation;\n\t\t},\n\t\n\t\n\t\t// Utility for apply dragOpacity to a jQuery set\n\t\tapplyDragOpacity: function(els) {\n\t\t\tvar opacity = this.view.opt('dragOpacity');\n\t\n\t\t\tif (opacity != null) {\n\t\t\t\tels.each(function(i, node) {\n\t\t\t\t\t// Don't use jQuery (will set an IE filter), do it the old fashioned way.\n\t\t\t\t\t// In IE8, a helper element will disappears if there's a filter.\n\t\t\t\t\tnode.style.opacity = opacity;\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t/* External Element Dragging\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Called when a jQuery UI drag is initiated anywhere in the DOM\n\t\texternalDragStart: function(ev, ui) {\n\t\t\tvar view = this.view;\n\t\t\tvar el;\n\t\t\tvar accept;\n\t\n\t\t\tif (view.opt('droppable')) { // only listen if this setting is on\n\t\t\t\tel = $((ui ? ui.item : null) || ev.target);\n\t\n\t\t\t\t// Test that the dragged element passes the dropAccept selector or filter function.\n\t\t\t\t// FYI, the default is \"*\" (matches all)\n\t\t\t\taccept = view.opt('dropAccept');\n\t\t\t\tif ($.isFunction(accept) ? accept.call(el[0], el) : el.is(accept)) {\n\t\t\t\t\tif (!this.isDraggingExternal) { // prevent double-listening if fired twice\n\t\t\t\t\t\tthis.listenToExternalDrag(el, ev, ui);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Called when a jQuery UI drag starts and it needs to be monitored for dropping\n\t\tlistenToExternalDrag: function(el, ev, ui) {\n\t\t\tvar _this = this;\n\t\t\tvar calendar = this.view.calendar;\n\t\t\tvar meta = getDraggedElMeta(el); // extra data about event drop, including possible event to create\n\t\t\tvar dropLocation; // a null value signals an unsuccessful drag\n\t\n\t\t\t// listener that tracks mouse movement over date-associated pixel regions\n\t\t\tvar dragListener = _this.externalDragListener = new HitDragListener(this, {\n\t\t\t\tinteractionStart: function() {\n\t\t\t\t\t_this.isDraggingExternal = true;\n\t\t\t\t},\n\t\t\t\thitOver: function(hit) {\n\t\t\t\t\tdropLocation = _this.computeExternalDrop(\n\t\t\t\t\t\thit.component.getHitSpan(hit), // since we are querying the parent view, might not belong to this grid\n\t\t\t\t\t\tmeta\n\t\t\t\t\t);\n\t\n\t\t\t\t\tif ( // invalid hit?\n\t\t\t\t\t\tdropLocation &&\n\t\t\t\t\t\t!calendar.isExternalSpanAllowed(_this.eventToSpan(dropLocation), dropLocation, meta.eventProps)\n\t\t\t\t\t) {\n\t\t\t\t\t\tdisableCursor();\n\t\t\t\t\t\tdropLocation = null;\n\t\t\t\t\t}\n\t\n\t\t\t\t\tif (dropLocation) {\n\t\t\t\t\t\t_this.renderDrag(dropLocation); // called without a seg parameter\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\thitOut: function() {\n\t\t\t\t\tdropLocation = null; // signal unsuccessful\n\t\t\t\t},\n\t\t\t\thitDone: function() { // Called after a hitOut OR before a dragEnd\n\t\t\t\t\tenableCursor();\n\t\t\t\t\t_this.unrenderDrag();\n\t\t\t\t},\n\t\t\t\tinteractionEnd: function(ev) {\n\t\t\t\t\tif (dropLocation) { // element was dropped on a valid hit\n\t\t\t\t\t\t_this.view.reportExternalDrop(meta, dropLocation, el, ev, ui);\n\t\t\t\t\t}\n\t\t\t\t\t_this.isDraggingExternal = false;\n\t\t\t\t\t_this.externalDragListener = null;\n\t\t\t\t}\n\t\t\t});\n\t\n\t\t\tdragListener.startDrag(ev); // start listening immediately\n\t\t},\n\t\n\t\n\t\t// Given a hit to be dropped upon, and misc data associated with the jqui drag (guaranteed to be a plain object),\n\t\t// returns the zoned start/end dates for the event that would result from the hypothetical drop. end might be null.\n\t\t// Returning a null value signals an invalid drop hit.\n\t\t// DOES NOT consider overlap/constraint.\n\t\tcomputeExternalDrop: function(span, meta) {\n\t\t\tvar calendar = this.view.calendar;\n\t\t\tvar dropLocation = {\n\t\t\t\tstart: calendar.applyTimezone(span.start), // simulate a zoned event start date\n\t\t\t\tend: null\n\t\t\t};\n\t\n\t\t\t// if dropped on an all-day span, and element's metadata specified a time, set it\n\t\t\tif (meta.startTime && !dropLocation.start.hasTime()) {\n\t\t\t\tdropLocation.start.time(meta.startTime);\n\t\t\t}\n\t\n\t\t\tif (meta.duration) {\n\t\t\t\tdropLocation.end = dropLocation.start.clone().add(meta.duration);\n\t\t\t}\n\t\n\t\t\treturn dropLocation;\n\t\t},\n\t\n\t\n\t\n\t\t/* Drag Rendering (for both events and an external elements)\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Renders a visual indication of an event or external element being dragged.\n\t\t// `dropLocation` contains hypothetical start/end/allDay values the event would have if dropped. end can be null.\n\t\t// `seg` is the internal segment object that is being dragged. If dragging an external element, `seg` is null.\n\t\t// A truthy returned value indicates this method has rendered a helper element.\n\t\t// Must return elements used for any mock events.\n\t\trenderDrag: function(dropLocation, seg) {\n\t\t\t// subclasses must implement\n\t\t},\n\t\n\t\n\t\t// Unrenders a visual indication of an event or external element being dragged\n\t\tunrenderDrag: function() {\n\t\t\t// subclasses must implement\n\t\t},\n\t\n\t\n\t\t/* Resizing\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Creates a listener that tracks the user as they resize an event segment.\n\t\t// Generic enough to work with any type of Grid.\n\t\tbuildSegResizeListener: function(seg, isStart) {\n\t\t\tvar _this = this;\n\t\t\tvar view = this.view;\n\t\t\tvar calendar = view.calendar;\n\t\t\tvar el = seg.el;\n\t\t\tvar event = seg.event;\n\t\t\tvar eventEnd = calendar.getEventEnd(event);\n\t\t\tvar isDragging;\n\t\t\tvar resizeLocation; // zoned event date properties. falsy if invalid resize\n\t\n\t\t\t// Tracks mouse movement over the *grid's* coordinate map\n\t\t\tvar dragListener = this.segResizeListener = new HitDragListener(this, {\n\t\t\t\tscroll: view.opt('dragScroll'),\n\t\t\t\tsubjectEl: el,\n\t\t\t\tinteractionStart: function() {\n\t\t\t\t\tisDragging = false;\n\t\t\t\t},\n\t\t\t\tdragStart: function(ev) {\n\t\t\t\t\tisDragging = true;\n\t\t\t\t\t_this.handleSegMouseout(seg, ev); // ensure a mouseout on the manipulated event has been reported\n\t\t\t\t\t_this.segResizeStart(seg, ev);\n\t\t\t\t},\n\t\t\t\thitOver: function(hit, isOrig, origHit) {\n\t\t\t\t\tvar origHitSpan = _this.getHitSpan(origHit);\n\t\t\t\t\tvar hitSpan = _this.getHitSpan(hit);\n\t\n\t\t\t\t\tresizeLocation = isStart ?\n\t\t\t\t\t\t_this.computeEventStartResize(origHitSpan, hitSpan, event) :\n\t\t\t\t\t\t_this.computeEventEndResize(origHitSpan, hitSpan, event);\n\t\n\t\t\t\t\tif (resizeLocation) {\n\t\t\t\t\t\tif (!calendar.isEventSpanAllowed(_this.eventToSpan(resizeLocation), event)) {\n\t\t\t\t\t\t\tdisableCursor();\n\t\t\t\t\t\t\tresizeLocation = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// no change? (TODO: how does this work with timezones?)\n\t\t\t\t\t\telse if (resizeLocation.start.isSame(event.start) && resizeLocation.end.isSame(eventEnd)) {\n\t\t\t\t\t\t\tresizeLocation = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\n\t\t\t\t\tif (resizeLocation) {\n\t\t\t\t\t\tview.hideEvent(event);\n\t\t\t\t\t\t_this.renderEventResize(resizeLocation, seg);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\thitOut: function() { // called before mouse moves to a different hit OR moved out of all hits\n\t\t\t\t\tresizeLocation = null;\n\t\t\t\t},\n\t\t\t\thitDone: function() { // resets the rendering to show the original event\n\t\t\t\t\t_this.unrenderEventResize();\n\t\t\t\t\tview.showEvent(event);\n\t\t\t\t\tenableCursor();\n\t\t\t\t},\n\t\t\t\tinteractionEnd: function(ev) {\n\t\t\t\t\tif (isDragging) {\n\t\t\t\t\t\t_this.segResizeStop(seg, ev);\n\t\t\t\t\t}\n\t\t\t\t\tif (resizeLocation) { // valid date to resize to?\n\t\t\t\t\t\tview.reportEventResize(event, resizeLocation, this.largeUnit, el, ev);\n\t\t\t\t\t}\n\t\t\t\t\t_this.segResizeListener = null;\n\t\t\t\t}\n\t\t\t});\n\t\n\t\t\treturn dragListener;\n\t\t},\n\t\n\t\n\t\t// Called before event segment resizing starts\n\t\tsegResizeStart: function(seg, ev) {\n\t\t\tthis.isResizingSeg = true;\n\t\t\tthis.view.trigger('eventResizeStart', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy\n\t\t},\n\t\n\t\n\t\t// Called after event segment resizing stops\n\t\tsegResizeStop: function(seg, ev) {\n\t\t\tthis.isResizingSeg = false;\n\t\t\tthis.view.trigger('eventResizeStop', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy\n\t\t},\n\t\n\t\n\t\t// Returns new date-information for an event segment being resized from its start\n\t\tcomputeEventStartResize: function(startSpan, endSpan, event) {\n\t\t\treturn this.computeEventResize('start', startSpan, endSpan, event);\n\t\t},\n\t\n\t\n\t\t// Returns new date-information for an event segment being resized from its end\n\t\tcomputeEventEndResize: function(startSpan, endSpan, event) {\n\t\t\treturn this.computeEventResize('end', startSpan, endSpan, event);\n\t\t},\n\t\n\t\n\t\t// Returns new zoned date information for an event segment being resized from its start OR end\n\t\t// `type` is either 'start' or 'end'.\n\t\t// DOES NOT consider overlap/constraint.\n\t\tcomputeEventResize: function(type, startSpan, endSpan, event) {\n\t\t\tvar calendar = this.view.calendar;\n\t\t\tvar delta = this.diffDates(endSpan[type], startSpan[type]);\n\t\t\tvar resizeLocation; // zoned event date properties\n\t\t\tvar defaultDuration;\n\t\n\t\t\t// build original values to work from, guaranteeing a start and end\n\t\t\tresizeLocation = {\n\t\t\t\tstart: event.start.clone(),\n\t\t\t\tend: calendar.getEventEnd(event),\n\t\t\t\tallDay: event.allDay\n\t\t\t};\n\t\n\t\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\t\tif (resizeLocation.allDay && durationHasTime(delta)) {\n\t\t\t\tresizeLocation.allDay = false;\n\t\t\t\tcalendar.normalizeEventTimes(resizeLocation);\n\t\t\t}\n\t\n\t\t\tresizeLocation[type].add(delta); // apply delta to start or end\n\t\n\t\t\t// if the event was compressed too small, find a new reasonable duration for it\n\t\t\tif (!resizeLocation.start.isBefore(resizeLocation.end)) {\n\t\n\t\t\t\tdefaultDuration =\n\t\t\t\t\tthis.minResizeDuration || // TODO: hack\n\t\t\t\t\t(event.allDay ?\n\t\t\t\t\t\tcalendar.defaultAllDayEventDuration :\n\t\t\t\t\t\tcalendar.defaultTimedEventDuration);\n\t\n\t\t\t\tif (type == 'start') { // resizing the start?\n\t\t\t\t\tresizeLocation.start = resizeLocation.end.clone().subtract(defaultDuration);\n\t\t\t\t}\n\t\t\t\telse { // resizing the end?\n\t\t\t\t\tresizeLocation.end = resizeLocation.start.clone().add(defaultDuration);\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn resizeLocation;\n\t\t},\n\t\n\t\n\t\t// Renders a visual indication of an event being resized.\n\t\t// `range` has the updated dates of the event. `seg` is the original segment object involved in the drag.\n\t\t// Must return elements used for any mock events.\n\t\trenderEventResize: function(range, seg) {\n\t\t\t// subclasses must implement\n\t\t},\n\t\n\t\n\t\t// Unrenders a visual indication of an event being resized.\n\t\tunrenderEventResize: function() {\n\t\t\t// subclasses must implement\n\t\t},\n\t\n\t\n\t\t/* Rendering Utils\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Compute the text that should be displayed on an event's element.\n\t\t// `range` can be the Event object itself, or something range-like, with at least a `start`.\n\t\t// If event times are disabled, or the event has no time, will return a blank string.\n\t\t// If not specified, formatStr will default to the eventTimeFormat setting,\n\t\t// and displayEnd will default to the displayEventEnd setting.\n\t\tgetEventTimeText: function(range, formatStr, displayEnd) {\n\t\n\t\t\tif (formatStr == null) {\n\t\t\t\tformatStr = this.eventTimeFormat;\n\t\t\t}\n\t\n\t\t\tif (displayEnd == null) {\n\t\t\t\tdisplayEnd = this.displayEventEnd;\n\t\t\t}\n\t\n\t\t\tif (this.displayEventTime && range.start.hasTime()) {\n\t\t\t\tif (displayEnd && range.end) {\n\t\t\t\t\treturn this.view.formatRange(range, formatStr);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn range.start.format(formatStr);\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn '';\n\t\t},\n\t\n\t\n\t\t// Generic utility for generating the HTML classNames for an event segment's element\n\t\tgetSegClasses: function(seg, isDraggable, isResizable) {\n\t\t\tvar view = this.view;\n\t\t\tvar event = seg.event;\n\t\t\tvar classes = [\n\t\t\t\t'fc-event',\n\t\t\t\tseg.isStart ? 'fc-start' : 'fc-not-start',\n\t\t\t\tseg.isEnd ? 'fc-end' : 'fc-not-end'\n\t\t\t].concat(\n\t\t\t\tevent.className,\n\t\t\t\tevent.source ? event.source.className : []\n\t\t\t);\n\t\n\t\t\tif (isDraggable) {\n\t\t\t\tclasses.push('fc-draggable');\n\t\t\t}\n\t\t\tif (isResizable) {\n\t\t\t\tclasses.push('fc-resizable');\n\t\t\t}\n\t\n\t\t\t// event is currently selected? attach a className.\n\t\t\tif (view.isEventSelected(event)) {\n\t\t\t\tclasses.push('fc-selected');\n\t\t\t}\n\t\n\t\t\treturn classes;\n\t\t},\n\t\n\t\n\t\t// Utility for generating event skin-related CSS properties\n\t\tgetSegSkinCss: function(seg) {\n\t\t\tvar event = seg.event;\n\t\t\tvar view = this.view;\n\t\t\tvar source = event.source || {};\n\t\t\tvar eventColor = event.color;\n\t\t\tvar sourceColor = source.color;\n\t\t\tvar optionColor = view.opt('eventColor');\n\t\n\t\t\treturn {\n\t\t\t\t'background-color':\n\t\t\t\t\tevent.backgroundColor ||\n\t\t\t\t\teventColor ||\n\t\t\t\t\tsource.backgroundColor ||\n\t\t\t\t\tsourceColor ||\n\t\t\t\t\tview.opt('eventBackgroundColor') ||\n\t\t\t\t\toptionColor,\n\t\t\t\t'border-color':\n\t\t\t\t\tevent.borderColor ||\n\t\t\t\t\teventColor ||\n\t\t\t\t\tsource.borderColor ||\n\t\t\t\t\tsourceColor ||\n\t\t\t\t\tview.opt('eventBorderColor') ||\n\t\t\t\t\toptionColor,\n\t\t\t\tcolor:\n\t\t\t\t\tevent.textColor ||\n\t\t\t\t\tsource.textColor ||\n\t\t\t\t\tview.opt('eventTextColor')\n\t\t\t};\n\t\t},\n\t\n\t\n\t\t/* Converting events -> eventRange -> eventSpan -> eventSegs\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Generates an array of segments for the given single event\n\t\t// Can accept an event \"location\" as well (which only has start/end and no allDay)\n\t\teventToSegs: function(event) {\n\t\t\treturn this.eventsToSegs([ event ]);\n\t\t},\n\t\n\t\n\t\teventToSpan: function(event) {\n\t\t\treturn this.eventToSpans(event)[0];\n\t\t},\n\t\n\t\n\t\t// Generates spans (always unzoned) for the given event.\n\t\t// Does not do any inverting for inverse-background events.\n\t\t// Can accept an event \"location\" as well (which only has start/end and no allDay)\n\t\teventToSpans: function(event) {\n\t\t\tvar range = this.eventToRange(event);\n\t\t\treturn this.eventRangeToSpans(range, event);\n\t\t},\n\t\n\t\n\t\n\t\t// Converts an array of event objects into an array of event segment objects.\n\t\t// A custom `segSliceFunc` may be given for arbitrarily slicing up events.\n\t\t// Doesn't guarantee an order for the resulting array.\n\t\teventsToSegs: function(allEvents, segSliceFunc) {\n\t\t\tvar _this = this;\n\t\t\tvar eventsById = groupEventsById(allEvents);\n\t\t\tvar segs = [];\n\t\n\t\t\t$.each(eventsById, function(id, events) {\n\t\t\t\tvar ranges = [];\n\t\t\t\tvar i;\n\t\n\t\t\t\tfor (i = 0; i < events.length; i++) {\n\t\t\t\t\tranges.push(_this.eventToRange(events[i]));\n\t\t\t\t}\n\t\n\t\t\t\t// inverse-background events (utilize only the first event in calculations)\n\t\t\t\tif (isInverseBgEvent(events[0])) {\n\t\t\t\t\tranges = _this.invertRanges(ranges);\n\t\n\t\t\t\t\tfor (i = 0; i < ranges.length; i++) {\n\t\t\t\t\t\tsegs.push.apply(segs, // append to\n\t\t\t\t\t\t\t_this.eventRangeToSegs(ranges[i], events[0], segSliceFunc));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// normal event ranges\n\t\t\t\telse {\n\t\t\t\t\tfor (i = 0; i < ranges.length; i++) {\n\t\t\t\t\t\tsegs.push.apply(segs, // append to\n\t\t\t\t\t\t\t_this.eventRangeToSegs(ranges[i], events[i], segSliceFunc));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\n\t\t\treturn segs;\n\t\t},\n\t\n\t\n\t\t// Generates the unzoned start/end dates an event appears to occupy\n\t\t// Can accept an event \"location\" as well (which only has start/end and no allDay)\n\t\teventToRange: function(event) {\n\t\t\treturn {\n\t\t\t\tstart: event.start.clone().stripZone(),\n\t\t\t\tend: (\n\t\t\t\t\tevent.end ?\n\t\t\t\t\t\tevent.end.clone() :\n\t\t\t\t\t\t// derive the end from the start and allDay. compute allDay if necessary\n\t\t\t\t\t\tthis.view.calendar.getDefaultEventEnd(\n\t\t\t\t\t\t\tevent.allDay != null ?\n\t\t\t\t\t\t\t\tevent.allDay :\n\t\t\t\t\t\t\t\t!event.start.hasTime(),\n\t\t\t\t\t\t\tevent.start\n\t\t\t\t\t\t)\n\t\t\t\t).stripZone()\n\t\t\t};\n\t\t},\n\t\n\t\n\t\t// Given an event's range (unzoned start/end), and the event itself,\n\t\t// slice into segments (using the segSliceFunc function if specified)\n\t\teventRangeToSegs: function(range, event, segSliceFunc) {\n\t\t\tvar spans = this.eventRangeToSpans(range, event);\n\t\t\tvar segs = [];\n\t\t\tvar i;\n\t\n\t\t\tfor (i = 0; i < spans.length; i++) {\n\t\t\t\tsegs.push.apply(segs, // append to\n\t\t\t\t\tthis.eventSpanToSegs(spans[i], event, segSliceFunc));\n\t\t\t}\n\t\n\t\t\treturn segs;\n\t\t},\n\t\n\t\n\t\t// Given an event's unzoned date range, return an array of \"span\" objects.\n\t\t// Subclasses can override.\n\t\teventRangeToSpans: function(range, event) {\n\t\t\treturn [ $.extend({}, range) ]; // copy into a single-item array\n\t\t},\n\t\n\t\n\t\t// Given an event's span (unzoned start/end and other misc data), and the event itself,\n\t\t// slices into segments and attaches event-derived properties to them.\n\t\teventSpanToSegs: function(span, event, segSliceFunc) {\n\t\t\tvar segs = segSliceFunc ? segSliceFunc(span) : this.spanToSegs(span);\n\t\t\tvar i, seg;\n\t\n\t\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\t\tseg = segs[i];\n\t\t\t\tseg.event = event;\n\t\t\t\tseg.eventStartMS = +span.start; // TODO: not the best name after making spans unzoned\n\t\t\t\tseg.eventDurationMS = span.end - span.start;\n\t\t\t}\n\t\n\t\t\treturn segs;\n\t\t},\n\t\n\t\n\t\t// Produces a new array of range objects that will cover all the time NOT covered by the given ranges.\n\t\t// SIDE EFFECT: will mutate the given array and will use its date references.\n\t\tinvertRanges: function(ranges) {\n\t\t\tvar view = this.view;\n\t\t\tvar viewStart = view.start.clone(); // need a copy\n\t\t\tvar viewEnd = view.end.clone(); // need a copy\n\t\t\tvar inverseRanges = [];\n\t\t\tvar start = viewStart; // the end of the previous range. the start of the new range\n\t\t\tvar i, range;\n\t\n\t\t\t// ranges need to be in order. required for our date-walking algorithm\n\t\t\tranges.sort(compareRanges);\n\t\n\t\t\tfor (i = 0; i < ranges.length; i++) {\n\t\t\t\trange = ranges[i];\n\t\n\t\t\t\t// add the span of time before the event (if there is any)\n\t\t\t\tif (range.start > start) { // compare millisecond time (skip any ambig logic)\n\t\t\t\t\tinverseRanges.push({\n\t\t\t\t\t\tstart: start,\n\t\t\t\t\t\tend: range.start\n\t\t\t\t\t});\n\t\t\t\t}\n\t\n\t\t\t\tstart = range.end;\n\t\t\t}\n\t\n\t\t\t// add the span of time after the last event (if there is any)\n\t\t\tif (start < viewEnd) { // compare millisecond time (skip any ambig logic)\n\t\t\t\tinverseRanges.push({\n\t\t\t\t\tstart: start,\n\t\t\t\t\tend: viewEnd\n\t\t\t\t});\n\t\t\t}\n\t\n\t\t\treturn inverseRanges;\n\t\t},\n\t\n\t\n\t\tsortEventSegs: function(segs) {\n\t\t\tsegs.sort(proxy(this, 'compareEventSegs'));\n\t\t},\n\t\n\t\n\t\t// A cmp function for determining which segments should take visual priority\n\t\tcompareEventSegs: function(seg1, seg2) {\n\t\t\treturn seg1.eventStartMS - seg2.eventStartMS || // earlier events go first\n\t\t\t\tseg2.eventDurationMS - seg1.eventDurationMS || // tie? longer events go first\n\t\t\t\tseg2.event.allDay - seg1.event.allDay || // tie? put all-day events first (booleans cast to 0/1)\n\t\t\t\tcompareByFieldSpecs(seg1.event, seg2.event, this.view.eventOrderSpecs);\n\t\t}\n\t\n\t});\n\t\n\t\n\t/* Utilities\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\tfunction isBgEvent(event) { // returns true if background OR inverse-background\n\t\tvar rendering = getEventRendering(event);\n\t\treturn rendering === 'background' || rendering === 'inverse-background';\n\t}\n\tFC.isBgEvent = isBgEvent; // export\n\t\n\t\n\tfunction isInverseBgEvent(event) {\n\t\treturn getEventRendering(event) === 'inverse-background';\n\t}\n\t\n\t\n\tfunction getEventRendering(event) {\n\t\treturn firstDefined((event.source || {}).rendering, event.rendering);\n\t}\n\t\n\t\n\tfunction groupEventsById(events) {\n\t\tvar eventsById = {};\n\t\tvar i, event;\n\t\n\t\tfor (i = 0; i < events.length; i++) {\n\t\t\tevent = events[i];\n\t\t\t(eventsById[event._id] || (eventsById[event._id] = [])).push(event);\n\t\t}\n\t\n\t\treturn eventsById;\n\t}\n\t\n\t\n\t// A cmp function for determining which non-inverted \"ranges\" (see above) happen earlier\n\tfunction compareRanges(range1, range2) {\n\t\treturn range1.start - range2.start; // earlier ranges go first\n\t}\n\t\n\t\n\t/* External-Dragging-Element Data\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\t// Require all HTML5 data-* attributes used by FullCalendar to have this prefix.\n\t// A value of '' will query attributes like data-event. A value of 'fc' will query attributes like data-fc-event.\n\tFC.dataAttrPrefix = '';\n\t\n\t// Given a jQuery element that might represent a dragged FullCalendar event, returns an intermediate data structure\n\t// to be used for Event Object creation.\n\t// A defined `.eventProps`, even when empty, indicates that an event should be created.\n\tfunction getDraggedElMeta(el) {\n\t\tvar prefix = FC.dataAttrPrefix;\n\t\tvar eventProps; // properties for creating the event, not related to date/time\n\t\tvar startTime; // a Duration\n\t\tvar duration;\n\t\tvar stick;\n\t\n\t\tif (prefix) { prefix += '-'; }\n\t\teventProps = el.data(prefix + 'event') || null;\n\t\n\t\tif (eventProps) {\n\t\t\tif (typeof eventProps === 'object') {\n\t\t\t\teventProps = $.extend({}, eventProps); // make a copy\n\t\t\t}\n\t\t\telse { // something like 1 or true. still signal event creation\n\t\t\t\teventProps = {};\n\t\t\t}\n\t\n\t\t\t// pluck special-cased date/time properties\n\t\t\tstartTime = eventProps.start;\n\t\t\tif (startTime == null) { startTime = eventProps.time; } // accept 'time' as well\n\t\t\tduration = eventProps.duration;\n\t\t\tstick = eventProps.stick;\n\t\t\tdelete eventProps.start;\n\t\t\tdelete eventProps.time;\n\t\t\tdelete eventProps.duration;\n\t\t\tdelete eventProps.stick;\n\t\t}\n\t\n\t\t// fallback to standalone attribute values for each of the date/time properties\n\t\tif (startTime == null) { startTime = el.data(prefix + 'start'); }\n\t\tif (startTime == null) { startTime = el.data(prefix + 'time'); } // accept 'time' as well\n\t\tif (duration == null) { duration = el.data(prefix + 'duration'); }\n\t\tif (stick == null) { stick = el.data(prefix + 'stick'); }\n\t\n\t\t// massage into correct data types\n\t\tstartTime = startTime != null ? moment.duration(startTime) : null;\n\t\tduration = duration != null ? moment.duration(duration) : null;\n\t\tstick = Boolean(stick);\n\t\n\t\treturn { eventProps: eventProps, startTime: startTime, duration: duration, stick: stick };\n\t}\n\t\n\t\n\t;;\n\t\n\t/*\n\tA set of rendering and date-related methods for a visual component comprised of one or more rows of day columns.\n\tPrerequisite: the object being mixed into needs to be a *Grid*\n\t*/\n\tvar DayTableMixin = FC.DayTableMixin = {\n\t\n\t\tbreakOnWeeks: false, // should create a new row for each week?\n\t\tdayDates: null, // whole-day dates for each column. left to right\n\t\tdayIndices: null, // for each day from start, the offset\n\t\tdaysPerRow: null,\n\t\trowCnt: null,\n\t\tcolCnt: null,\n\t\tcolHeadFormat: null,\n\t\n\t\n\t\t// Populates internal variables used for date calculation and rendering\n\t\tupdateDayTable: function() {\n\t\t\tvar view = this.view;\n\t\t\tvar date = this.start.clone();\n\t\t\tvar dayIndex = -1;\n\t\t\tvar dayIndices = [];\n\t\t\tvar dayDates = [];\n\t\t\tvar daysPerRow;\n\t\t\tvar firstDay;\n\t\t\tvar rowCnt;\n\t\n\t\t\twhile (date.isBefore(this.end)) { // loop each day from start to end\n\t\t\t\tif (view.isHiddenDay(date)) {\n\t\t\t\t\tdayIndices.push(dayIndex + 0.5); // mark that it's between indices\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tdayIndex++;\n\t\t\t\t\tdayIndices.push(dayIndex);\n\t\t\t\t\tdayDates.push(date.clone());\n\t\t\t\t}\n\t\t\t\tdate.add(1, 'days');\n\t\t\t}\n\t\n\t\t\tif (this.breakOnWeeks) {\n\t\t\t\t// count columns until the day-of-week repeats\n\t\t\t\tfirstDay = dayDates[0].day();\n\t\t\t\tfor (daysPerRow = 1; daysPerRow < dayDates.length; daysPerRow++) {\n\t\t\t\t\tif (dayDates[daysPerRow].day() == firstDay) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\trowCnt = Math.ceil(dayDates.length / daysPerRow);\n\t\t\t}\n\t\t\telse {\n\t\t\t\trowCnt = 1;\n\t\t\t\tdaysPerRow = dayDates.length;\n\t\t\t}\n\t\n\t\t\tthis.dayDates = dayDates;\n\t\t\tthis.dayIndices = dayIndices;\n\t\t\tthis.daysPerRow = daysPerRow;\n\t\t\tthis.rowCnt = rowCnt;\n\t\t\t\n\t\t\tthis.updateDayTableCols();\n\t\t},\n\t\n\t\n\t\t// Computes and assigned the colCnt property and updates any options that may be computed from it\n\t\tupdateDayTableCols: function() {\n\t\t\tthis.colCnt = this.computeColCnt();\n\t\t\tthis.colHeadFormat = this.view.opt('columnFormat') || this.computeColHeadFormat();\n\t\t},\n\t\n\t\n\t\t// Determines how many columns there should be in the table\n\t\tcomputeColCnt: function() {\n\t\t\treturn this.daysPerRow;\n\t\t},\n\t\n\t\n\t\t// Computes the ambiguously-timed moment for the given cell\n\t\tgetCellDate: function(row, col) {\n\t\t\treturn this.dayDates[\n\t\t\t\t\tthis.getCellDayIndex(row, col)\n\t\t\t\t].clone();\n\t\t},\n\t\n\t\n\t\t// Computes the ambiguously-timed date range for the given cell\n\t\tgetCellRange: function(row, col) {\n\t\t\tvar start = this.getCellDate(row, col);\n\t\t\tvar end = start.clone().add(1, 'days');\n\t\n\t\t\treturn { start: start, end: end };\n\t\t},\n\t\n\t\n\t\t// Returns the number of day cells, chronologically, from the first of the grid (0-based)\n\t\tgetCellDayIndex: function(row, col) {\n\t\t\treturn row * this.daysPerRow + this.getColDayIndex(col);\n\t\t},\n\t\n\t\n\t\t// Returns the numner of day cells, chronologically, from the first cell in *any given row*\n\t\tgetColDayIndex: function(col) {\n\t\t\tif (this.isRTL) {\n\t\t\t\treturn this.colCnt - 1 - col;\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn col;\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Given a date, returns its chronolocial cell-index from the first cell of the grid.\n\t\t// If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.\n\t\t// If before the first offset, returns a negative number.\n\t\t// If after the last offset, returns an offset past the last cell offset.\n\t\t// Only works for *start* dates of cells. Will not work for exclusive end dates for cells.\n\t\tgetDateDayIndex: function(date) {\n\t\t\tvar dayIndices = this.dayIndices;\n\t\t\tvar dayOffset = date.diff(this.start, 'days');\n\t\n\t\t\tif (dayOffset < 0) {\n\t\t\t\treturn dayIndices[0] - 1;\n\t\t\t}\n\t\t\telse if (dayOffset >= dayIndices.length) {\n\t\t\t\treturn dayIndices[dayIndices.length - 1] + 1;\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn dayIndices[dayOffset];\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t/* Options\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Computes a default column header formatting string if `colFormat` is not explicitly defined\n\t\tcomputeColHeadFormat: function() {\n\t\t\t// if more than one week row, or if there are a lot of columns with not much space,\n\t\t\t// put just the day numbers will be in each cell\n\t\t\tif (this.rowCnt > 1 || this.colCnt > 10) {\n\t\t\t\treturn 'ddd'; // \"Sat\"\n\t\t\t}\n\t\t\t// multiple days, so full single date string WON'T be in title text\n\t\t\telse if (this.colCnt > 1) {\n\t\t\t\treturn this.view.opt('dayOfMonthFormat'); // \"Sat 12/10\"\n\t\t\t}\n\t\t\t// single day, so full single date string will probably be in title text\n\t\t\telse {\n\t\t\t\treturn 'dddd'; // \"Saturday\"\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t/* Slicing\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Slices up a date range into a segment for every week-row it intersects with\n\t\tsliceRangeByRow: function(range) {\n\t\t\tvar daysPerRow = this.daysPerRow;\n\t\t\tvar normalRange = this.view.computeDayRange(range); // make whole-day range, considering nextDayThreshold\n\t\t\tvar rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index\n\t\t\tvar rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index\n\t\t\tvar segs = [];\n\t\t\tvar row;\n\t\t\tvar rowFirst, rowLast; // inclusive day-index range for current row\n\t\t\tvar segFirst, segLast; // inclusive day-index range for segment\n\t\n\t\t\tfor (row = 0; row < this.rowCnt; row++) {\n\t\t\t\trowFirst = row * daysPerRow;\n\t\t\t\trowLast = rowFirst + daysPerRow - 1;\n\t\n\t\t\t\t// intersect segment's offset range with the row's\n\t\t\t\tsegFirst = Math.max(rangeFirst, rowFirst);\n\t\t\t\tsegLast = Math.min(rangeLast, rowLast);\n\t\n\t\t\t\t// deal with in-between indices\n\t\t\t\tsegFirst = Math.ceil(segFirst); // in-between starts round to next cell\n\t\t\t\tsegLast = Math.floor(segLast); // in-between ends round to prev cell\n\t\n\t\t\t\tif (segFirst <= segLast) { // was there any intersection with the current row?\n\t\t\t\t\tsegs.push({\n\t\t\t\t\t\trow: row,\n\t\n\t\t\t\t\t\t// normalize to start of row\n\t\t\t\t\t\tfirstRowDayIndex: segFirst - rowFirst,\n\t\t\t\t\t\tlastRowDayIndex: segLast - rowFirst,\n\t\n\t\t\t\t\t\t// must be matching integers to be the segment's start/end\n\t\t\t\t\t\tisStart: segFirst === rangeFirst,\n\t\t\t\t\t\tisEnd: segLast === rangeLast\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn segs;\n\t\t},\n\t\n\t\n\t\t// Slices up a date range into a segment for every day-cell it intersects with.\n\t\t// TODO: make more DRY with sliceRangeByRow somehow.\n\t\tsliceRangeByDay: function(range) {\n\t\t\tvar daysPerRow = this.daysPerRow;\n\t\t\tvar normalRange = this.view.computeDayRange(range); // make whole-day range, considering nextDayThreshold\n\t\t\tvar rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index\n\t\t\tvar rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index\n\t\t\tvar segs = [];\n\t\t\tvar row;\n\t\t\tvar rowFirst, rowLast; // inclusive day-index range for current row\n\t\t\tvar i;\n\t\t\tvar segFirst, segLast; // inclusive day-index range for segment\n\t\n\t\t\tfor (row = 0; row < this.rowCnt; row++) {\n\t\t\t\trowFirst = row * daysPerRow;\n\t\t\t\trowLast = rowFirst + daysPerRow - 1;\n\t\n\t\t\t\tfor (i = rowFirst; i <= rowLast; i++) {\n\t\n\t\t\t\t\t// intersect segment's offset range with the row's\n\t\t\t\t\tsegFirst = Math.max(rangeFirst, i);\n\t\t\t\t\tsegLast = Math.min(rangeLast, i);\n\t\n\t\t\t\t\t// deal with in-between indices\n\t\t\t\t\tsegFirst = Math.ceil(segFirst); // in-between starts round to next cell\n\t\t\t\t\tsegLast = Math.floor(segLast); // in-between ends round to prev cell\n\t\n\t\t\t\t\tif (segFirst <= segLast) { // was there any intersection with the current row?\n\t\t\t\t\t\tsegs.push({\n\t\t\t\t\t\t\trow: row,\n\t\n\t\t\t\t\t\t\t// normalize to start of row\n\t\t\t\t\t\t\tfirstRowDayIndex: segFirst - rowFirst,\n\t\t\t\t\t\t\tlastRowDayIndex: segLast - rowFirst,\n\t\n\t\t\t\t\t\t\t// must be matching integers to be the segment's start/end\n\t\t\t\t\t\t\tisStart: segFirst === rangeFirst,\n\t\t\t\t\t\t\tisEnd: segLast === rangeLast\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn segs;\n\t\t},\n\t\n\t\n\t\t/* Header Rendering\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\trenderHeadHtml: function() {\n\t\t\tvar view = this.view;\n\t\n\t\t\treturn '' +\n\t\t\t\t'' +\n\t\t\t\t\t' ' +\n\t\t\t\t\t\t'' +\n\t\t\t\t\t\t\tthis.renderHeadTrHtml() +\n\t\t\t\t\t\t'' +\n\t\t\t\t\t' ' +\n\t\t\t\t' ';\n\t\t},\n\t\n\t\n\t\trenderHeadIntroHtml: function() {\n\t\t\treturn this.renderIntroHtml(); // fall back to generic\n\t\t},\n\t\n\t\n\t\trenderHeadTrHtml: function() {\n\t\t\treturn '' +\n\t\t\t\t'' +\n\t\t\t\t\t(this.isRTL ? '' : this.renderHeadIntroHtml()) +\n\t\t\t\t\tthis.renderHeadDateCellsHtml() +\n\t\t\t\t\t(this.isRTL ? this.renderHeadIntroHtml() : '') +\n\t\t\t\t' ';\n\t\t},\n\t\n\t\n\t\trenderHeadDateCellsHtml: function() {\n\t\t\tvar htmls = [];\n\t\t\tvar col, date;\n\t\n\t\t\tfor (col = 0; col < this.colCnt; col++) {\n\t\t\t\tdate = this.getCellDate(0, col);\n\t\t\t\thtmls.push(this.renderHeadDateCellHtml(date));\n\t\t\t}\n\t\n\t\t\treturn htmls.join('');\n\t\t},\n\t\n\t\n\t\t// TODO: when internalApiVersion, accept an object for HTML attributes\n\t\t// (colspan should be no different)\n\t\trenderHeadDateCellHtml: function(date, colspan, otherAttrs) {\n\t\t\tvar view = this.view;\n\t\n\t\t\treturn '' +\n\t\t\t\t'';\n\t\t},\n\t\n\t\n\t\t/* Background Rendering\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\trenderBgTrHtml: function(row) {\n\t\t\treturn '' +\n\t\t\t\t' ' +\n\t\t\t\t\t(this.isRTL ? '' : this.renderBgIntroHtml(row)) +\n\t\t\t\t\tthis.renderBgCellsHtml(row) +\n\t\t\t\t\t(this.isRTL ? this.renderBgIntroHtml(row) : '') +\n\t\t\t\t' ';\n\t\t},\n\t\n\t\n\t\trenderBgIntroHtml: function(row) {\n\t\t\treturn this.renderIntroHtml(); // fall back to generic\n\t\t},\n\t\n\t\n\t\trenderBgCellsHtml: function(row) {\n\t\t\tvar htmls = [];\n\t\t\tvar col, date;\n\t\n\t\t\tfor (col = 0; col < this.colCnt; col++) {\n\t\t\t\tdate = this.getCellDate(row, col);\n\t\t\t\thtmls.push(this.renderBgCellHtml(date));\n\t\t\t}\n\t\n\t\t\treturn htmls.join('');\n\t\t},\n\t\n\t\n\t\trenderBgCellHtml: function(date, otherAttrs) {\n\t\t\tvar view = this.view;\n\t\t\tvar classes = this.getDayClasses(date);\n\t\n\t\t\tclasses.unshift('fc-day', view.widgetContentClass);\n\t\n\t\t\treturn ' | ';\n\t\t},\n\t\n\t\n\t\t/* Generic\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Generates the default HTML intro for any row. User classes should override\n\t\trenderIntroHtml: function() {\n\t\t},\n\t\n\t\n\t\t// TODO: a generic method for dealing with , RTL, intro\n\t\t// when increment internalApiVersion\n\t\t// wrapTr (scheduler)\n\t\n\t\n\t\t/* Utils\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Applies the generic \"intro\" and \"outro\" HTML to the given cells.\n\t\t// Intro means the leftmost cell when the calendar is LTR and the rightmost cell when RTL. Vice-versa for outro.\n\t\tbookendCells: function(trEl) {\n\t\t\tvar introHtml = this.renderIntroHtml();\n\t\n\t\t\tif (introHtml) {\n\t\t\t\tif (this.isRTL) {\n\t\t\t\t\ttrEl.append(introHtml);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ttrEl.prepend(introHtml);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t};\n\t\n\t;;\n\t\n\t/* A component that renders a grid of whole-days that runs horizontally. There can be multiple rows, one per week.\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\tvar DayGrid = FC.DayGrid = Grid.extend(DayTableMixin, {\n\t\n\t\tnumbersVisible: false, // should render a row for day/week numbers? set by outside view. TODO: make internal\n\t\tbottomCoordPadding: 0, // hack for extending the hit area for the last row of the coordinate grid\n\t\n\t\trowEls: null, // set of fake row elements\n\t\tcellEls: null, // set of whole-day elements comprising the row's background\n\t\thelperEls: null, // set of cell skeleton elements for rendering the mock event \"helper\"\n\t\n\t\trowCoordCache: null,\n\t\tcolCoordCache: null,\n\t\n\t\n\t\t// Renders the rows and columns into the component's `this.el`, which should already be assigned.\n\t\t// isRigid determins whether the individual rows should ignore the contents and be a constant height.\n\t\t// Relies on the view's colCnt and rowCnt. In the future, this component should probably be self-sufficient.\n\t\trenderDates: function(isRigid) {\n\t\t\tvar view = this.view;\n\t\t\tvar rowCnt = this.rowCnt;\n\t\t\tvar colCnt = this.colCnt;\n\t\t\tvar html = '';\n\t\t\tvar row;\n\t\t\tvar col;\n\t\n\t\t\tfor (row = 0; row < rowCnt; row++) {\n\t\t\t\thtml += this.renderDayRowHtml(row, isRigid);\n\t\t\t}\n\t\t\tthis.el.html(html);\n\t\n\t\t\tthis.rowEls = this.el.find('.fc-row');\n\t\t\tthis.cellEls = this.el.find('.fc-day');\n\t\n\t\t\tthis.rowCoordCache = new CoordCache({\n\t\t\t\tels: this.rowEls,\n\t\t\t\tisVertical: true\n\t\t\t});\n\t\t\tthis.colCoordCache = new CoordCache({\n\t\t\t\tels: this.cellEls.slice(0, this.colCnt), // only the first row\n\t\t\t\tisHorizontal: true\n\t\t\t});\n\t\n\t\t\t// trigger dayRender with each cell's element\n\t\t\tfor (row = 0; row < rowCnt; row++) {\n\t\t\t\tfor (col = 0; col < colCnt; col++) {\n\t\t\t\t\tview.trigger(\n\t\t\t\t\t\t'dayRender',\n\t\t\t\t\t\tnull,\n\t\t\t\t\t\tthis.getCellDate(row, col),\n\t\t\t\t\t\tthis.getCellEl(row, col)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\n\t\n\t\tunrenderDates: function() {\n\t\t\tthis.removeSegPopover();\n\t\t},\n\t\n\t\n\t\trenderBusinessHours: function() {\n\t\t\tvar segs = this.buildBusinessHourSegs(true); // wholeDay=true\n\t\t\tthis.renderFill('businessHours', segs, 'bgevent');\n\t\t},\n\t\n\t\n\t\tunrenderBusinessHours: function() {\n\t\t\tthis.unrenderFill('businessHours');\n\t\t},\n\t\n\t\n\t\t// Generates the HTML for a single row, which is a div that wraps a table.\n\t\t// `row` is the row number.\n\t\trenderDayRowHtml: function(row, isRigid) {\n\t\t\tvar view = this.view;\n\t\t\tvar classes = [ 'fc-row', 'fc-week', view.widgetContentClass ];\n\t\n\t\t\tif (isRigid) {\n\t\t\t\tclasses.push('fc-rigid');\n\t\t\t}\n\t\n\t\t\treturn '' +\n\t\t\t\t'' +\n\t\t\t\t\t' ' +\n\t\t\t\t\t\t' ' +\n\t\t\t\t\t\t\tthis.renderBgTrHtml(row) +\n\t\t\t\t\t\t' ' +\n\t\t\t\t\t' ' +\n\t\t\t\t\t' ' +\n\t\t\t\t\t\t' ' +\n\t\t\t\t\t\t\t(this.numbersVisible ?\n\t\t\t\t\t\t\t\t'' +\n\t\t\t\t\t\t\t\t\tthis.renderNumberTrHtml(row) +\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' ' +\n\t\t\t\t\t' ' +\n\t\t\t\t' ';\n\t\t},\n\t\n\t\n\t\t/* Grid Number Rendering\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\trenderNumberTrHtml: function(row) {\n\t\t\treturn '' +\n\t\t\t\t' ' +\n\t\t\t\t\t(this.isRTL ? '' : this.renderNumberIntroHtml(row)) +\n\t\t\t\t\tthis.renderNumberCellsHtml(row) +\n\t\t\t\t\t(this.isRTL ? this.renderNumberIntroHtml(row) : '') +\n\t\t\t\t' ';\n\t\t},\n\t\n\t\n\t\trenderNumberIntroHtml: function(row) {\n\t\t\treturn this.renderIntroHtml();\n\t\t},\n\t\n\t\n\t\trenderNumberCellsHtml: function(row) {\n\t\t\tvar htmls = [];\n\t\t\tvar col, date;\n\t\n\t\t\tfor (col = 0; col < this.colCnt; col++) {\n\t\t\t\tdate = this.getCellDate(row, col);\n\t\t\t\thtmls.push(this.renderNumberCellHtml(date));\n\t\t\t}\n\t\n\t\t\treturn htmls.join('');\n\t\t},\n\t\n\t\n\t\t// Generates the HTML for the s of the \"number\" row in the DayGrid's content skeleton.\n\t\t// The number row will only exist if either day numbers or week numbers are turned on.\n\t\trenderNumberCellHtml: function(date) {\n\t\t\tvar classes;\n\t\n\t\t\tif (!this.view.dayNumbersVisible) { // if there are week numbers but not day numbers\n\t\t\t\treturn ' | | '; // will create an empty space above events :(\n\t\t\t}\n\t\n\t\t\tclasses = this.getDayClasses(date);\n\t\t\tclasses.unshift('fc-day-number');\n\t\n\t\t\treturn '' +\n\t\t\t\t' ' +\n\t\t\t\t\tdate.date() +\n\t\t\t\t' | ';\n\t\t},\n\t\n\t\n\t\t/* Options\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Computes a default event time formatting string if `timeFormat` is not explicitly defined\n\t\tcomputeEventTimeFormat: function() {\n\t\t\treturn this.view.opt('extraSmallTimeFormat'); // like \"6p\" or \"6:30p\"\n\t\t},\n\t\n\t\n\t\t// Computes a default `displayEventEnd` value if one is not expliclty defined\n\t\tcomputeDisplayEventEnd: function() {\n\t\t\treturn this.colCnt == 1; // we'll likely have space if there's only one day\n\t\t},\n\t\n\t\n\t\t/* Dates\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\trangeUpdated: function() {\n\t\t\tthis.updateDayTable();\n\t\t},\n\t\n\t\n\t\t// Slices up the given span (unzoned start/end with other misc data) into an array of segments\n\t\tspanToSegs: function(span) {\n\t\t\tvar segs = this.sliceRangeByRow(span);\n\t\t\tvar i, seg;\n\t\n\t\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\t\tseg = segs[i];\n\t\t\t\tif (this.isRTL) {\n\t\t\t\t\tseg.leftCol = this.daysPerRow - 1 - seg.lastRowDayIndex;\n\t\t\t\t\tseg.rightCol = this.daysPerRow - 1 - seg.firstRowDayIndex;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tseg.leftCol = seg.firstRowDayIndex;\n\t\t\t\t\tseg.rightCol = seg.lastRowDayIndex;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn segs;\n\t\t},\n\t\n\t\n\t\t/* Hit System\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\tprepareHits: function() {\n\t\t\tthis.colCoordCache.build();\n\t\t\tthis.rowCoordCache.build();\n\t\t\tthis.rowCoordCache.bottoms[this.rowCnt - 1] += this.bottomCoordPadding; // hack\n\t\t},\n\t\n\t\n\t\treleaseHits: function() {\n\t\t\tthis.colCoordCache.clear();\n\t\t\tthis.rowCoordCache.clear();\n\t\t},\n\t\n\t\n\t\tqueryHit: function(leftOffset, topOffset) {\n\t\t\tif (this.colCoordCache.isLeftInBounds(leftOffset) && this.rowCoordCache.isTopInBounds(topOffset)) {\n\t\t\t\tvar col = this.colCoordCache.getHorizontalIndex(leftOffset);\n\t\t\t\tvar row = this.rowCoordCache.getVerticalIndex(topOffset);\n\t\n\t\t\t\tif (row != null && col != null) {\n\t\t\t\t\treturn this.getCellHit(row, col);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\n\t\n\t\tgetHitSpan: function(hit) {\n\t\t\treturn this.getCellRange(hit.row, hit.col);\n\t\t},\n\t\n\t\n\t\tgetHitEl: function(hit) {\n\t\t\treturn this.getCellEl(hit.row, hit.col);\n\t\t},\n\t\n\t\n\t\t/* Cell System\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\t// FYI: the first column is the leftmost column, regardless of date\n\t\n\t\n\t\tgetCellHit: function(row, col) {\n\t\t\treturn {\n\t\t\t\trow: row,\n\t\t\t\tcol: col,\n\t\t\t\tcomponent: this, // needed unfortunately :(\n\t\t\t\tleft: this.colCoordCache.getLeftOffset(col),\n\t\t\t\tright: this.colCoordCache.getRightOffset(col),\n\t\t\t\ttop: this.rowCoordCache.getTopOffset(row),\n\t\t\t\tbottom: this.rowCoordCache.getBottomOffset(row)\n\t\t\t};\n\t\t},\n\t\n\t\n\t\tgetCellEl: function(row, col) {\n\t\t\treturn this.cellEls.eq(row * this.colCnt + col);\n\t\t},\n\t\n\t\n\t\t/* Event Drag Visualization\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\t// TODO: move to DayGrid.event, similar to what we did with Grid's drag methods\n\t\n\t\n\t\t// Renders a visual indication of an event or external element being dragged.\n\t\t// `eventLocation` has zoned start and end (optional)\n\t\trenderDrag: function(eventLocation, seg) {\n\t\n\t\t\t// always render a highlight underneath\n\t\t\tthis.renderHighlight(this.eventToSpan(eventLocation));\n\t\n\t\t\t// if a segment from the same calendar but another component is being dragged, render a helper event\n\t\t\tif (seg && seg.component !== this) {\n\t\t\t\treturn this.renderEventLocationHelper(eventLocation, seg); // returns mock event elements\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Unrenders any visual indication of a hovering event\n\t\tunrenderDrag: function() {\n\t\t\tthis.unrenderHighlight();\n\t\t\tthis.unrenderHelper();\n\t\t},\n\t\n\t\n\t\t/* Event Resize Visualization\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Renders a visual indication of an event being resized\n\t\trenderEventResize: function(eventLocation, seg) {\n\t\t\tthis.renderHighlight(this.eventToSpan(eventLocation));\n\t\t\treturn this.renderEventLocationHelper(eventLocation, seg); // returns mock event elements\n\t\t},\n\t\n\t\n\t\t// Unrenders a visual indication of an event being resized\n\t\tunrenderEventResize: function() {\n\t\t\tthis.unrenderHighlight();\n\t\t\tthis.unrenderHelper();\n\t\t},\n\t\n\t\n\t\t/* Event Helper\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\t// Renders a mock \"helper\" event. `sourceSeg` is the associated internal segment object. It can be null.\n\t\trenderHelper: function(event, sourceSeg) {\n\t\t\tvar helperNodes = [];\n\t\t\tvar segs = this.eventToSegs(event);\n\t\t\tvar rowStructs;\n\t\n\t\t\tsegs = this.renderFgSegEls(segs); // assigns each seg's el and returns a subset of segs that were rendered\n\t\t\trowStructs = this.renderSegRows(segs);\n\t\n\t\t\t// inject each new event skeleton into each associated row\n\t\t\tthis.rowEls.each(function(row, rowNode) {\n\t\t\t\tvar rowEl = $(rowNode); // the .fc-row\n\t\t\t\tvar skeletonEl = $(' '); // will be absolutely positioned\n\t\t\t\tvar skeletonTop;\n\t\n\t\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\t\tif (sourceSeg && sourceSeg.row === row) {\n\t\t\t\t\tskeletonTop = sourceSeg.el.position().top;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tskeletonTop = rowEl.find('.fc-content-skeleton tbody').position().top;\n\t\t\t\t}\n\t\n\t\t\t\tskeletonEl.css('top', skeletonTop)\n\t\t\t\t\t.find('table')\n\t\t\t\t\t\t.append(rowStructs[row].tbodyEl);\n\t\n\t\t\t\trowEl.append(skeletonEl);\n\t\t\t\thelperNodes.push(skeletonEl[0]);\n\t\t\t});\n\t\n\t\t\treturn ( // must return the elements rendered\n\t\t\t\tthis.helperEls = $(helperNodes) // array -> jQuery set\n\t\t\t);\n\t\t},\n\t\n\t\n\t\t// Unrenders any visual indication of a mock helper event\n\t\tunrenderHelper: function() {\n\t\t\tif (this.helperEls) {\n\t\t\t\tthis.helperEls.remove();\n\t\t\t\tthis.helperEls = null;\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t/* Fill System (highlight, background events, business hours)\n\t\t------------------------------------------------------------------------------------------------------------------*/\n\t\n\t\n\t\tfillSegTag: 'td', // override the default tag name\n\t\n\t\n\t\t// Renders a set of rectangles over the given segments of days.\n\t\t// Only returns segments that successfully rendered.\n\t\trenderFill: function(type, segs, className) {\n\t\t\tvar nodes = [];\n\t\t\tvar i, seg;\n\t\t\tvar skeletonEl;\n\t\n\t\t\tsegs = this.renderFillSegEls(type, segs); // assignes `.el` to each seg. returns successfully rendered segs\n\t\n\t\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\t\tseg = segs[i];\n\t\t\t\tskeletonEl = this.renderFillRow(type, seg, className);\n\t\t\t\tthis.rowEls.eq(seg.row).append(skeletonEl);\n\t\t\t\tnodes.push(skeletonEl[0]);\n\t\t\t}\n\t\n\t\t\tthis.elsByFill[type] = $(nodes);\n\t\n\t\t\treturn segs;\n\t\t},\n\t\n\t\n\t\t// Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered.\n\t\trenderFillRow: function(type, seg, className) {\n\t\t\tvar colCnt = this.colCnt;\n\t\t\tvar startCol = seg.leftCol;\n\t\t\tvar endCol = seg.rightCol + 1;\n\t\t\tvar skeletonEl;\n\t\t\tvar trEl;\n\t\n\t\t\tclassName = className || type.toLowerCase();\n\t\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\t\n\t\t\tif (startCol > 0) {\n\t\t\t\ttrEl.append(' | ');\n\t\t\t}\n\t\n\t\t\ttrEl.append(\n\t\t\t\tseg.el.attr('colspan', endCol - startCol)\n\t\t\t);\n\t\n\t\t\tif (endCol < colCnt) {\n\t\t\t\ttrEl.append(' | ');\n\t\t\t}\n\t\n\t\t\tthis.bookendCells(trEl);\n\t\n\t\t\treturn skeletonEl;\n\t\t}\n\t\n\t});\n\t\n\t;;\n\t\n\t/* Event-rendering methods for the DayGrid class\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t\n\tDayGrid.mixin({\n\t\n\t\trowStructs: null, // an array of objects, each holding information about a row's foreground event-rendering\n\t\n\t\n\t\t// Unrenders all events currently rendered on the grid\n\t\tunrenderEvents: function() {\n\t\t\tthis.removeSegPopover(); // removes the \"more..\" events popover\n\t\t\tGrid.prototype.unrenderEvents.apply(this, arguments); // calls the super-method\n\t\t},\n\t\n\t\n\t\t// Retrieves all rendered segment objects currently rendered on the grid\n\t\tgetEventSegs: function() {\n\t\t\treturn Grid.prototype.getEventSegs.call(this) // get the segments from the super-method\n\t\t\t\t.concat(this.popoverSegs || []); // append the segments from the \"more...\" popover\n\t\t},\n\t\n\t\n\t\t// Renders the given background event segments onto the grid\n\t\trenderBgSegs: function(segs) {\n\t\n\t\t\t// don't render timed background events\n\t\t\tvar allDaySegs = $.grep(segs, function(seg) {\n\t\t\t\treturn seg.event.allDay;\n\t\t\t});\n\t\n\t\t\treturn Grid.prototype.renderBgSegs.call(this, allDaySegs); // call the super-method\n\t\t},\n\t\n\t\n\t\t// Renders the given foreground event segments onto the grid\n\t\trenderFgSegs: function(segs) {\n\t\t\tvar rowStructs;\n\t\n\t\t\t// render an `.el` on each seg\n\t\t\t// returns a subset of the segs. segs that were actually rendered\n\t\t\tsegs = this.renderFgSegEls(segs);\n\t\n\t\t\trowStructs = this.rowStructs = this.renderSegRows(segs);\n\t\n\t\t\t// append to each row's content skeleton\n\t\t\tthis.rowEls.each(function(i, rowNode) {\n\t\t\t\t$(rowNode).find('.fc-content-skeleton > table').append(\n\t\t\t\t\trowStructs[i].tbodyEl\n\t\t\t\t);\n\t\t\t});\n\t\n\t\t\treturn segs; // return only the segs that were actually rendered\n\t\t},\n\t\n\t\n\t\t// Unrenders all currently rendered foreground event segments\n\t\tunrenderFgSegs: function() {\n\t\t\tvar rowStructs = this.rowStructs || [];\n\t\t\tvar rowStruct;\n\t\n\t\t\twhile ((rowStruct = rowStructs.pop())) {\n\t\t\t\trowStruct.tbodyEl.remove();\n\t\t\t}\n\t\n\t\t\tthis.rowStructs = null;\n\t\t},\n\t\n\t\n\t\t// Uses the given events array to generate elements that should be appended to each row's content skeleton.\n\t\t// Returns an array of rowStruct objects (see the bottom of `renderSegRow`).\n\t\t// PRECONDITION: each segment shoud already have a rendered and assigned `.el`\n\t\trenderSegRows: function(segs) {\n\t\t\tvar rowStructs = [];\n\t\t\tvar segRows;\n\t\t\tvar row;\n\t\n\t\t\tsegRows = this.groupSegRows(segs); // group into nested arrays\n\t\n\t\t\t// iterate each row of segment groupings\n\t\t\tfor (row = 0; row < segRows.length; row++) {\n\t\t\t\trowStructs.push(\n\t\t\t\t\tthis.renderSegRow(row, segRows[row])\n\t\t\t\t);\n\t\t\t}\n\t\n\t\t\treturn rowStructs;\n\t\t},\n\t\n\t\n\t\t// Builds the HTML to be used for the default element for an individual segment\n\t\tfgSegHtml: function(seg, disableResizing) {\n\t\t\tvar view = this.view;\n\t\t\tvar event = seg.event;\n\t\t\tvar isDraggable = view.isEventDraggable(event);\n\t\t\tvar isResizableFromStart = !disableResizing && event.allDay &&\n\t\t\t\tseg.isStart && view.isEventResizableFromStart(event);\n\t\t\tvar isResizableFromEnd = !disableResizing && event.allDay &&\n\t\t\t\tseg.isEnd && view.isEventResizableFromEnd(event);\n\t\t\tvar classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd);\n\t\t\tvar skinCss = cssToStr(this.getSegSkinCss(seg));\n\t\t\tvar timeHtml = '';\n\t\t\tvar timeText;\n\t\t\tvar titleHtml;\n\t\n\t\t\tclasses.unshift('fc-day-grid-event', 'fc-h-event');\n\t\n\t\t\t// Only display a timed events time if it is the starting segment\n\t\t\tif (seg.isStart) {\n\t\t\t\ttimeText = this.getEventTimeText(event);\n\t\t\t\tif (timeText) {\n\t\t\t\t\ttimeHtml = '' + htmlEscape(timeText) + '';\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\ttitleHtml =\n\t\t\t\t'' +\n\t\t\t\t\t(htmlEscape(event.title || '') || ' ') + // we always want one line of height\n\t\t\t\t'';\n\t\t\t\n\t\t\treturn '' +\n\t\t\t\t\t'' +\n\t\t\t\t\t\t(this.isRTL ?\n\t\t\t\t\t\t\ttitleHtml + ' ' + timeHtml : // put a natural space in between\n\t\t\t\t\t\t\ttimeHtml + ' ' + titleHtml //\n\t\t\t\t\t\t\t) +\n\t\t\t\t\t' ' +\n\t\t\t\t\t(isResizableFromStart ?\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(isResizableFromEnd ?\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},\n\t\n\t\n\t\t// Given a row # and an array of segments all in the same row, render a element, a skeleton that contains\n\t\t// the segments. Returns object with a bunch of internal data about how the render was calculated.\n\t\t// NOTE: modifies rowSegs\n\t\trenderSegRow: function(row, rowSegs) {\n\t\t\tvar colCnt = this.colCnt;\n\t\t\tvar segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels\n\t\t\tvar levelCnt = Math.max(1, segLevels.length); // ensure at least one level\n\t\t\tvar tbody = $('');\n\t\t\tvar segMatrix = []; // lookup for which segments are rendered into which level+col cells\n\t\t\tvar cellMatrix = []; // lookup for all elements of the level+col matrix\n\t\t\tvar loneCellMatrix = []; // lookup for | elements that only take up a single column\n\t\t\tvar i, levelSegs;\n\t\t\tvar col;\n\t\t\tvar tr;\n\t\t\tvar j, seg;\n\t\t\tvar td;\n\t\n\t\t\t// populates empty cells from the current column (`col`) to `endCol`\n\t\t\tfunction emptyCellsUntil(endCol) {\n\t\t\t\twhile (col < endCol) {\n\t\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\t\ttd = (loneCellMatrix[i - 1] || [])[col];\n\t\t\t\t\tif (td) {\n\t\t\t\t\t\ttd.attr(\n\t\t\t\t\t\t\t'rowspan',\n\t\t\t\t\t\t\tparseInt(td.attr('rowspan') || 1, 10) + 1\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\ttd = $(' | | ');\n\t\t\t\t\t\ttr.append(td);\n\t\t\t\t\t}\n\t\t\t\t\tcellMatrix[i][col] = td;\n\t\t\t\t\tloneCellMatrix[i][col] = td;\n\t\t\t\t\tcol++;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tfor (i = 0; i < levelCnt; i++) { // iterate through all levels\n\t\t\t\tlevelSegs = segLevels[i];\n\t\t\t\tcol = 0;\n\t\t\t\ttr = $(' |
');\n\t\n\t\t\t\tsegMatrix.push([]);\n\t\t\t\tcellMatrix.push([]);\n\t\t\t\tloneCellMatrix.push([]);\n\t\n\t\t\t\t// levelCnt might be 1 even though there are no actual levels. protect against this.\n\t\t\t\t// this single empty row is useful for styling.\n\t\t\t\tif (levelSegs) {\n\t\t\t\t\tfor (j = 0; j < levelSegs.length; j++) { // iterate through segments in level\n\t\t\t\t\t\tseg = levelSegs[j];\n\t\n\t\t\t\t\t\temptyCellsUntil(seg.leftCol);\n\t\n\t\t\t\t\t\t// create a container that occupies or more columns. append the event element.\n\t\t\t\t\t\ttd = $(' ').append(seg.el);\n\t\t\t\t\t\tif (seg.leftCol != seg.rightCol) {\n\t\t\t\t\t\t\ttd.attr('colspan', seg.rightCol - seg.leftCol + 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse { // a single-column segment\n\t\t\t\t\t\t\tloneCellMatrix[i][col] = td;\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\twhile (col <= seg.rightCol) {\n\t\t\t\t\t\t\tcellMatrix[i][col] = td;\n\t\t\t\t\t\t\tsegMatrix[i][col] = seg;\n\t\t\t\t\t\t\tcol++;\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\ttr.append(td);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\temptyCellsUntil(colCnt); // finish off the row\n\t\t\t\tthis.bookendCells(tr);\n\t\t\t\ttbody.append(tr);\n\t\t\t}\n\t\n\t\t\treturn { // a \"rowStruct\"\n\t\t\t\trow: row, // the row number\n\t\t\t\ttbodyEl: tbody,\n\t\t\t\tcellMatrix: cellMatrix,\n\t\t\t\tsegMatrix: segMatrix,\n\t\t\t\tsegLevels: segLevels,\n\t\t\t\tsegs: rowSegs\n\t\t\t};\n\t\t},\n\t\n\t\n\t\t// Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels.\n\t\t// NOTE: modifies segs\n\t\tbuildSegLevels: function(segs) {\n\t\t\tvar levels = [];\n\t\t\tvar i, seg;\n\t\t\tvar j;\n\t\n\t\t\t// Give preference to elements with certain criteria, so they have\n\t\t\t// a chance to be closer to the top.\n\t\t\tthis.sortEventSegs(segs);\n\t\t\t\n\t\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\t\tseg = segs[i];\n\t\n\t\t\t\t// loop through levels, starting with the topmost, until the segment doesn't collide with other segments\n\t\t\t\tfor (j = 0; j < levels.length; j++) {\n\t\t\t\t\tif (!isDaySegCollision(seg, levels[j])) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// `j` now holds the desired subrow index\n\t\t\t\tseg.level = j;\n\t\n\t\t\t\t// create new level array if needed and append segment\n\t\t\t\t(levels[j] || (levels[j] = [])).push(seg);\n\t\t\t}\n\t\n\t\t\t// order segments left-to-right. very important if calendar is RTL\n\t\t\tfor (j = 0; j < levels.length; j++) {\n\t\t\t\tlevels[j].sort(compareDaySegCols);\n\t\t\t}\n\t\n\t\t\treturn levels;\n\t\t},\n\t\n\t\n\t\t// Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row\n\t\tgroupSegRows: function(segs) {\n\t\t\tvar segRows = [];\n\t\t\tvar i;\n\t\n\t\t\tfor (i = 0; i < this.rowCnt; i++) {\n\t\t\t\tsegRows.push([]);\n\t\t\t}\n\t\n\t\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\t\tsegRows[segs[i].row].push(segs[i]);\n\t\t\t}\n\t\n\t\t\treturn segRows;\n\t\t}\n\t\n\t});\n\t\n\t\n\t// Computes whether two segments' columns collide. They are assumed to be in the same row.\n\tfunction isDaySegCollision(seg, otherSegs) {\n\t\tvar i, otherSeg;\n\t\n\t\tfor (i = 0; i < otherSegs.length; i++) {\n\t\t\totherSeg = otherSegs[i];\n\t\n\t\t\tif (\n\t\t\t\totherSeg.leftCol <= seg.rightCol &&\n\t\t\t\totherSeg.rightCol >= seg.leftCol\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\n\t\treturn false;\n\t}\n\t\n\t\n\t// A cmp function for determining the leftmost event\n\tfunction compareDaySegCols(a, b) {\n\t\treturn a.leftCol - b.leftCol;\n\t}\n\t\n\t;;\n\t\n\t/* Methods relate to limiting the number events for a given day on a DayGrid\n\t----------------------------------------------------------------------------------------------------------------------*/\n\t// NOTE: all the segs being passed around in here are foreground segs\n\t\n\tDayGrid.mixin({\n\t\n\t\tsegPopover: null, // the Popover that holds events that can't fit in a cell. null when not visible\n\t\tpopoverSegs: null, // an array of segment objects that the segPopover holds. null when not visible\n\t\n\t\n\t\tremoveSegPopover: function() {\n\t\t\tif (this.segPopover) {\n\t\t\t\tthis.segPopover.hide(); // in handler, will call segPopover's removeElement\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Limits the number of \"levels\" (vertically stacking layers of events) for each row of the grid.\n\t\t// `levelLimit` can be false (don't limit), a number, or true (should be computed).\n\t\tlimitRows: function(levelLimit) {\n\t\t\tvar rowStructs = this.rowStructs || [];\n\t\t\tvar row; // row #\n\t\t\tvar rowLevelLimit;\n\t\n\t\t\tfor (row = 0; row < rowStructs.length; row++) {\n\t\t\t\tthis.unlimitRow(row);\n\t\n\t\t\t\tif (!levelLimit) {\n\t\t\t\t\trowLevelLimit = false;\n\t\t\t\t}\n\t\t\t\telse if (typeof levelLimit === 'number') {\n\t\t\t\t\trowLevelLimit = levelLimit;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\trowLevelLimit = this.computeRowLevelLimit(row);\n\t\t\t\t}\n\t\n\t\t\t\tif (rowLevelLimit !== false) {\n\t\t\t\t\tthis.limitRow(row, rowLevelLimit);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Computes the number of levels a row will accomodate without going outside its bounds.\n\t\t// Assumes the row is \"rigid\" (maintains a constant height regardless of what is inside).\n\t\t// `row` is the row number.\n\t\tcomputeRowLevelLimit: function(row) {\n\t\t\tvar rowEl = this.rowEls.eq(row); // the containing \"fake\" row div\n\t\t\tvar rowHeight = rowEl.height(); // TODO: cache somehow?\n\t\t\tvar trEls = this.rowStructs[row].tbodyEl.children();\n\t\t\tvar i, trEl;\n\t\t\tvar trHeight;\n\t\n\t\t\tfunction iterInnerHeights(i, childNode) {\n\t\t\t\ttrHeight = Math.max(trHeight, $(childNode).outerHeight());\n\t\t\t}\n\t\n\t\t\t// Reveal one level | at a time and stop when we find one out of bounds\n\t\t\tfor (i = 0; i < trEls.length; i++) {\n\t\t\t\ttrEl = trEls.eq(i).removeClass('fc-limited'); // reset to original state (reveal)\n\t\n\t\t\t\t// with rowspans>1 and IE8, trEl.outerHeight() would return the height of the largest cell,\n\t\t\t\t// so instead, find the tallest inner content element.\n\t\t\t\ttrHeight = 0;\n\t\t\t\ttrEl.find('> td > :first-child').each(iterInnerHeights);\n\t\n\t\t\t\tif (trEl.position().top + trHeight > rowHeight) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn false; // should not limit at all\n\t\t},\n\t\n\t\n\t\t// Limits the given grid row to the maximum number of levels and injects \"more\" links if necessary.\n\t\t// `row` is the row number.\n\t\t// `levelLimit` is a number for the maximum (inclusive) number of levels allowed.\n\t\tlimitRow: function(row, levelLimit) {\n\t\t\tvar _this = this;\n\t\t\tvar rowStruct = this.rowStructs[row];\n\t\t\tvar moreNodes = []; // array of \"more\" links and DOM nodes\n\t\t\tvar col = 0; // col #, left-to-right (not chronologically)\n\t\t\tvar levelSegs; // array of segment objects in the last allowable level, ordered left-to-right\n\t\t\tvar cellMatrix; // a matrix (by level, then column) of all | jQuery elements in the row\n\t\t\tvar limitedNodes; // array of temporarily hidden level | and segment DOM nodes\n\t\t\tvar i, seg;\n\t\t\tvar segsBelow; // array of segment objects below `seg` in the current `col`\n\t\t\tvar totalSegsBelow; // total number of segments below `seg` in any of the columns `seg` occupies\n\t\t\tvar colSegsBelow; // array of segment arrays, below seg, one for each column (offset from segs's first column)\n\t\t\tvar td, rowspan;\n\t\t\tvar segMoreNodes; // array of \"more\" | cells that will stand-in for the current seg's cell\n\t\t\tvar j;\n\t\t\tvar moreTd, moreWrap, moreLink;\n\t\n\t\t\t// Iterates through empty level cells and places \"more\" links inside if need be\n\t\t\tfunction emptyCellsUntil(endCol) { // goes from current `col` to `endCol`\n\t\t\t\twhile (col < endCol) {\n\t\t\t\t\tsegsBelow = _this.getCellSegs(row, col, levelLimit);\n\t\t\t\t\tif (segsBelow.length) {\n\t\t\t\t\t\ttd = cellMatrix[levelLimit - 1][col];\n\t\t\t\t\t\tmoreLink = _this.renderMoreLink(row, col, segsBelow);\n\t\t\t\t\t\tmoreWrap = $('').append(moreLink);\n\t\t\t\t\t\ttd.append(moreWrap);\n\t\t\t\t\t\tmoreNodes.push(moreWrap[0]);\n\t\t\t\t\t}\n\t\t\t\t\tcol++;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif (levelLimit && levelLimit < rowStruct.segLevels.length) { // is it actually over the limit?\n\t\t\t\tlevelSegs = rowStruct.segLevels[levelLimit - 1];\n\t\t\t\tcellMatrix = rowStruct.cellMatrix;\n\t\n\t\t\t\tlimitedNodes = rowStruct.tbodyEl.children().slice(levelLimit) // get level | elements past the limit\n\t\t\t\t\t.addClass('fc-limited').get(); // hide elements and get a simple DOM-nodes array\n\t\n\t\t\t\t// iterate though segments in the last allowable level\n\t\t\t\tfor (i = 0; i < levelSegs.length; i++) {\n\t\t\t\t\tseg = levelSegs[i];\n\t\t\t\t\temptyCellsUntil(seg.leftCol); // process empty cells before the segment\n\t\n\t\t\t\t\t// determine *all* segments below `seg` that occupy the same columns\n\t\t\t\t\tcolSegsBelow = [];\n\t\t\t\t\ttotalSegsBelow = 0;\n\t\t\t\t\twhile (col <= seg.rightCol) {\n\t\t\t\t\t\tsegsBelow = this.getCellSegs(row, col, levelLimit);\n\t\t\t\t\t\tcolSegsBelow.push(segsBelow);\n\t\t\t\t\t\ttotalSegsBelow += segsBelow.length;\n\t\t\t\t\t\tcol++;\n\t\t\t\t\t}\n\t\n\t\t\t\t\tif (totalSegsBelow) { // do we need to replace this segment with one or many \"more\" links?\n\t\t\t\t\t\ttd = cellMatrix[levelLimit - 1][seg.leftCol]; // the segment's parent cell\n\t\t\t\t\t\trowspan = td.attr('rowspan') || 1;\n\t\t\t\t\t\tsegMoreNodes = [];\n\t\n\t\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\t\tfor (j = 0; j < colSegsBelow.length; j++) {\n\t\t\t\t\t\t\tmoreTd = $(' | ').attr('rowspan', rowspan);\n\t\t\t\t\t\t\tsegsBelow = colSegsBelow[j];\n\t\t\t\t\t\t\tmoreLink = this.renderMoreLink(\n\t\t\t\t\t\t\t\trow,\n\t\t\t\t\t\t\t\tseg.leftCol + j,\n\t\t\t\t\t\t\t\t[ seg ].concat(segsBelow) // count seg as hidden too\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tmoreWrap = $('').append(moreLink);\n\t\t\t\t\t\t\tmoreTd.append(moreWrap);\n\t\t\t\t\t\t\tsegMoreNodes.push(moreTd[0]);\n\t\t\t\t\t\t\tmoreNodes.push(moreTd[0]);\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\ttd.addClass('fc-limited').after($(segMoreNodes)); // hide original | and inject replacements\n\t\t\t\t\t\tlimitedNodes.push(td[0]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\temptyCellsUntil(this.colCnt); // finish off the level\n\t\t\t\trowStruct.moreEls = $(moreNodes); // for easy undoing later\n\t\t\t\trowStruct.limitedEls = $(limitedNodes); // for easy undoing later\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Reveals all levels and removes all \"more\"-related elements for a grid's row.\n\t\t// `row` is a row number.\n\t\tunlimitRow: function(row) {\n\t\t\tvar rowStruct = this.rowStructs[row];\n\t\n\t\t\tif (rowStruct.moreEls) {\n\t\t\t\trowStruct.moreEls.remove();\n\t\t\t\trowStruct.moreEls = null;\n\t\t\t}\n\t\n\t\t\tif (rowStruct.limitedEls) {\n\t\t\t\trowStruct.limitedEls.removeClass('fc-limited');\n\t\t\t\trowStruct.limitedEls = null;\n\t\t\t}\n\t\t},\n\t\n\t\n\t\t// Renders an element that represents hidden event element for a cell.\n\t\t// Responsible for attaching click handler as well.\n\t\trenderMoreLink: function(row, col, hiddenSegs) {\n\t\t\tvar _this = this;\n\t\t\tvar view = this.view;\n\t\n\t\t\treturn $('')\n\t\t\t\t.text(\n\t\t\t\t\tthis.getMoreLinkText(hiddenSegs.length)\n\t\t\t\t)\n\t\t\t\t.on('click', function(ev) {\n\t\t\t\t\tvar clickOption = view.opt('eventLimitClick');\n\t\t\t\t\tvar date = _this.getCellDate(row, col);\n\t\t\t\t\tvar moreEl = $(this);\n\t\t\t\t\tvar dayEl = _this.getCellEl(row, col);\n\t\t\t\t\tvar allSegs = _this.getCellSegs(row, col);\n\t\n\t\t\t\t\t// rescope the segments to be within the cell's date\n\t\t\t\t\tvar reslicedAllSegs = _this.resliceDaySegs(allSegs, date);\n\t\t\t\t\tvar reslicedHiddenSegs = _this.resliceDaySegs(hiddenSegs, date);\n\t\n\t\t\t\t\tif (typeof clickOption === 'function') {\n\t\t\t\t\t\t// the returned value can be an atomic option\n\t\t\t\t\t\tclickOption = view.trigger('eventLimitClick', null, {\n\t\t\t\t\t\t\tdate: date,\n\t\t\t\t\t\t\tdayEl: dayEl,\n\t\t\t\t\t\t\tmoreEl: moreEl,\n\t\t\t\t\t\t\tsegs: reslicedAllSegs,\n\t\t\t\t\t\t\thiddenSegs: reslicedHiddenSegs\n\t\t\t\t\t\t}, ev);\n\t\t\t\t\t}\n\t\n\t\t\t\t\tif (clickOption === 'popover') {\n\t\t\t\t\t\t_this.showSegPopover(row, col, moreEl, reslicedAllSegs);\n\t\t\t\t\t}\n\t\t\t\t\telse if (typeof clickOption === 'string') { // a view name\n\t\t\t\t\t\tview.calendar.zoomTo(date, clickOption);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t},\n\t\n\t\n\t\t// Reveals the popover that displays all events within a cell\n\t\tshowSegPopover: function(row, col, moreLink, segs) {\n\t\t\tvar _this = this;\n\t\t\tvar view = this.view;\n\t\t\tvar moreWrap = moreLink.parent(); // the wrapper around the \n\t\t\tvar topEl; // the element we want to match the top coordinate of\n\t\t\tvar options;\n\t\n\t\t\tif (this.rowCnt == 1) {\n\t\t\t\ttopEl = view.el; // will cause the popover to cover any sort of header\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttopEl = this.rowEls.eq(row); // will align with top of row\n\t\t\t}\n\t\n\t\t\toptions = {\n\t\t\t\tclassName: 'fc-more-popover',\n\t\t\t\tcontent: this.renderSegPopoverContent(row, col, segs),\n\t\t\t\tparentEl: this.view.el, // attach to root of view. guarantees outside of scrollbars.\n\t\t\t\ttop: topEl.offset().top,\n\t\t\t\tautoHide: true, // when the user clicks elsewhere, hide the popover\n\t\t\t\tviewportConstrain: view.opt('popoverViewportConstrain'),\n\t\t\t\thide: function() {\n\t\t\t\t\t// kill everything when the popover is hidden\n\t\t\t\t\t_this.segPopover.removeElement();\n\t\t\t\t\t_this.segPopover = null;\n\t\t\t\t\t_this.popoverSegs = null;\n\t\t\t\t}\n\t\t\t};\n\t\n\t\t\t// Determine horizontal coordinate.\n\t\t\t// We use the moreWrap instead of the to avoid border confusion.\n\t\t\tif (this.isRTL) {\n\t\t\t\toptions.right = moreWrap.offset().left + moreWrap.outerWidth() + 1; // +1 to be over cell border\n\t\t\t}\n\t\t\telse {\n\t\t\t\toptions.left = moreWrap.offset().left - 1; // -1 to be over cell border\n\t\t\t}\n\t\n\t\t\tthis.segPopover = new Popover(options);\n\t\t\tthis.segPopover.show();\n\t\n\t\t\t// the popover doesn't live within the grid's container element, and thus won't get the event\n\t\t\t// delegated-handlers for free. attach event-related handlers to the popover.\n\t\t\tthis.bindSegHandlersToEl(this.segPopover.el);\n\t\t},\n\t\n\t\n\t\t// Builds the inner DOM contents of the segment popover\n\t\trenderSegPopoverContent: function(row, col, segs) {\n\t\t\tvar view = this.view;\n\t\t\tvar isTheme = view.opt('theme');\n\t\t\tvar title = this.getCellDate(row, col).format(view.opt('dayPopoverFormat'));\n\t\t\tvar content = $(\n\t\t\t\t' | | |