PageSourceSearch

https://androidforum.mojandroid.sk/wp-content/plugins/buddypress-p…/js/jquery.datetimepicker.js?ver=1790855051

js mojandroid.sk collected 2026-10-01 11:45:27 UTC 96,631 bytes, 2,790 lines download raw bytes

1/**
2 * @preserve jQuery DateTimePicker
3 * @homepage http://xdsoft.net/jqplugins/datetimepicker/
4 * @author Chupurnov Valeriy (<[email protected]>)
5 */
6
7/**
8 * @param {jQuery} $
9 */
10var datetimepickerFactory = function ($) {
11	'use strict';
12
13	var default_options
vendor: 23,486 bytes, lines 13-554
13 = {
14		i18n: {
15			ar: { // Arabic
16				months: [
17					"كانون الثاني", "شباط", "آذار", "نيسان", "مايو", "حزيران", "تموز", "آب", "أيلول", "تشرين الأول", "تشرين الثاني", "كانون الأول"
18				],
19				dayOfWeekShort: [
20					"ن", "ث", "ع", "خ", "ج", "س", "ح"
21				],
22				dayOfWeek: ["الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت", "الأحد"]
23			},
24			ro: { // Romanian
25				months: [
26					"Ianuarie", "Februarie", "Martie", "Aprilie", "Mai", "Iunie", "Iulie", "August", "Septembrie", "Octombrie", "Noiembrie", "Decembrie"
27				],
28				dayOfWeekShort: [
29					"Du", "Lu", "Ma", "Mi", "Jo", "Vi", "Sâ"
30				],
31				dayOfWeek: ["Duminică", "Luni", "Marţi", "Miercuri", "Joi", "Vineri", "Sâmbătă"]
32			},
33			id: { // Indonesian
34				months: [
35					"Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"
36				],
37				dayOfWeekShort: [
38					"Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab"
39				],
40				dayOfWeek: ["Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"]
41			},
42			is: { // Icelandic
43				months: [
44					"Janúar", "Febrúar", "Mars", "Apríl", "Maí", "Júní", "Júlí", "Ágúst", "September", "Október", "Nóvember", "Desember"
45				],
46				dayOfWeekShort: [
47					"Sun", "Mán", "Þrið", "Mið", "Fim", "Fös", "Lau"
48				],
49				dayOfWeek: ["Sunnudagur", "Mánudagur", "Þriðjudagur", "Miðvikudagur", "Fimmtudagur", "Föstudagur", "Laugardagur"]
50			},
51			bg: { // Bulgarian
52				months: [
53					"Януари", "Февруари", "Март", "Април", "Май", "Юни", "Юли", "Август", "Септември", "Октомври", "Ноември", "Декември"
54				],
55				dayOfWeekShort: [
56					"Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"
57				],
58				dayOfWeek: ["Неделя", "Понеделник", "Вторник", "Сряда", "Четвъртък", "Петък", "Събота"]
59			},
60			fa: { // Persian/Farsi
61				months: [
62					'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'
63				],
64				dayOfWeekShort: [
65					'یکشنبه', 'دوشنبه', 'سه شنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه'
66				],
67				dayOfWeek: ["یک‌شنبه", "دوشنبه", "سه‌شنبه", "چهارشنبه", "پنج‌شنبه", "جمعه", "شنبه", "یک‌شنبه"]
68			},
69			ru: { // Russian
70				months: [
71					'Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'
72				],
73				dayOfWeekShort: [
74					"Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"
75				],
76				dayOfWeek: ["Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"]
77			},
78			uk: { // Ukrainian
79				months: [
80					'Січень', 'Лютий', 'Березень', 'Квітень', 'Травень', 'Червень', 'Липень', 'Серпень', 'Вересень', 'Жовтень', 'Листопад', 'Грудень'
81				],
82				dayOfWeekShort: [
83					"Ндл", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Сбт"
84				],
85				dayOfWeek: ["Неділя", "Понеділок", "Вівторок", "Середа", "Четвер", "П'ятниця", "Субота"]
86			},
87			en: { // English
88				months: [
89					"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
90				],
91				dayOfWeekShort: [
92					"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
93				],
94				dayOfWeek: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
95			},
96			el: { // Ελληνικά
97				months: [
98					"Ιανουάριος", "Φεβρουάριος", "Μάρτιος", "Απρίλιος", "Μάιος", "Ιούνιος", "Ιούλιος", "Αύγουστος", "Σεπτέμβριος", "Οκτώβριος", "Νοέμβριος", "Δεκέμβριος"
99				],
100				dayOfWeekShort: [
101					"Κυρ", "Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ"
102				],
103				dayOfWeek: ["Κυριακή", "Δευτέρα", "Τρίτη", "Τετάρτη", "Πέμπτη", "Παρασκευή", "Σάββατο"]
104			},
105			de: { // German
106				months: [
107					'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'
108				],
109				dayOfWeekShort: [
110					"So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"
111				],
112				dayOfWeek: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"]
113			},
114			nl: { // Dutch
115				months: [
116					"januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"
117				],
118				dayOfWeekShort: [
119					"zo", "ma", "di", "wo", "do", "vr", "za"
120				],
121				dayOfWeek: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"]
122			},
123			tr: { // Turkish
124				months: [
125					"Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık"
126				],
127				dayOfWeekShort: [
128					"Paz", "Pts", "Sal", "Çar", "Per", "Cum", "Cts"
129				],
130				dayOfWeek: ["Pazar", "Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi"]
131			},
132			fr: { //French
133				months: [
134					"Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"
135				],
136				dayOfWeekShort: [
137					"Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"
138				],
139				dayOfWeek: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"]
140			},
141			es: { // Spanish
142				months: [
143					"Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"
144				],
145				dayOfWeekShort: [
146					"Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"
147				],
148				dayOfWeek: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"]
149			},
150			th: { // Thai
151				months: [
152					'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'
153				],
154				dayOfWeekShort: [
155					'อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'
156				],
157				dayOfWeek: ["อาทิตย์", "จันทร์", "อังคาร", "พุธ", "พฤหัส", "ศุกร์", "เสาร์", "อาทิตย์"]
158			},
159			pl: { // Polish
160				months: [
161					"styczeń", "luty", "marzec", "kwiecień", "maj", "czerwiec", "lipiec", "sierpień", "wrzesień", "październik", "listopad", "grudzień"
162				],
163				dayOfWeekShort: [
164					"nd", "pn", "wt", "śr", "cz", "pt", "sb"
165				],
166				dayOfWeek: ["niedziela", "poniedziałek", "wtorek", "środa", "czwartek", "piątek", "sobota"]
167			},
168			pt: { // Portuguese
169				months: [
170					"Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
171				],
172				dayOfWeekShort: [
173					"Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"
174				],
175				dayOfWeek: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"]
176			},
177			ch: { // Simplified Chinese
178				months: [
179					"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
180				],
181				dayOfWeekShort: [
182					"日", "一", "二", "三", "四", "五", "六"
183				]
184			},
185			se: { // Swedish
186				months: [
187					"Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September",  "Oktober", "November", "December"
188				],
189				dayOfWeekShort: [
190					"Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"
191				]
192			},
193			km: { // Khmer (ភាសាខ្មែរ)
194				months: [
195					"មករា​", "កុម្ភៈ", "មិនា​", "មេសា​", "ឧសភា​", "មិថុនា​", "កក្កដា​", "សីហា​", "កញ្ញា​", "តុលា​", "វិច្ឆិកា", "ធ្នូ​"
196				],
197				dayOfWeekShort: ["អាទិ​", "ច័ន្ទ​", "អង្គារ​", "ពុធ​", "ព្រហ​​", "សុក្រ​", "សៅរ៍"],
198				dayOfWeek: ["អាទិត្យ​", "ច័ន្ទ​", "អង្គារ​", "ពុធ​", "ព្រហស្បតិ៍​", "សុក្រ​", "សៅរ៍"]
199			},
200			kr: { // Korean
201				months: [
202					"1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"
203				],
204				dayOfWeekShort: [
205					"일", "월", "화", "수", "목", "금", "토"
206				],
207				dayOfWeek: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"]
208			},
209			it: { // Italian
210				months: [
211					"Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"
212				],
213				dayOfWeekShort: [
214					"Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"
215				],
216				dayOfWeek: ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"]
217			},
218			da: { // Dansk
219				months: [
220					"Januar", "Februar", "Marts", "April", "Maj", "Juni", "Juli", "August", "September", "Oktober", "November", "December"
221				],
222				dayOfWeekShort: [
223					"Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"
224				],
225				dayOfWeek: ["søndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "lørdag"]
226			},
227			no: { // Norwegian
228				months: [
229					"Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember"
230				],
231				dayOfWeekShort: [
232					"Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"
233				],
234				dayOfWeek: ['Søndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lørdag']
235			},
236			ja: { // Japanese
237				months: [
238					"1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"
239				],
240				dayOfWeekShort: [
241					"日", "月", "火", "水", "木", "金", "土"
242				],
243				dayOfWeek: ["日曜", "月曜", "火曜", "水曜", "木曜", "金曜", "土曜"]
244			},
245			vi: { // Vietnamese
246				months: [
247					"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"
248				],
249				dayOfWeekShort: [
250					"CN", "T2", "T3", "T4", "T5", "T6", "T7"
251				],
252				dayOfWeek: ["Chủ nhật", "Thứ hai", "Thứ ba", "Thứ tư", "Thứ năm", "Thứ sáu", "Thứ bảy"]
253			},
254			sl: { // Slovenščina
255				months: [
256					"Januar", "Februar", "Marec", "April", "Maj", "Junij", "Julij", "Avgust", "September", "Oktober", "November", "December"
257				],
258				dayOfWeekShort: [
259					"Ned", "Pon", "Tor", "Sre", "Čet", "Pet", "Sob"
260				],
261				dayOfWeek: ["Nedelja", "Ponedeljek", "Torek", "Sreda", "Četrtek", "Petek", "Sobota"]
262			},
263			cs: { // Čeština
264				months: [
265					"Leden", "Únor", "Březen", "Duben", "Květen", "Červen", "Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec"
266				],
267				dayOfWeekShort: [
268					"Ne", "Po", "Út", "St", "Čt", "Pá", "So"
269				]
270			},
271			hu: { // Hungarian
272				months: [
273					"Január", "Február", "Március", "Április", "Május", "Június", "Július", "Augusztus", "Szeptember", "Október", "November", "December"
274				],
275				dayOfWeekShort: [
276					"Va", "Hé", "Ke", "Sze", "Cs", "Pé", "Szo"
277				],
278				dayOfWeek: ["vasárnap", "hétfő", "kedd", "szerda", "csütörtök", "péntek", "szombat"]
279			},
280			az: { //Azerbaijanian (Azeri)
281				months: [
282					"Yanvar", "Fevral", "Mart", "Aprel", "May", "Iyun", "Iyul", "Avqust", "Sentyabr", "Oktyabr", "Noyabr", "Dekabr"
283				],
284				dayOfWeekShort: [
285					"B", "Be", "Ça", "Ç", "Ca", "C", "Ş"
286				],
287				dayOfWeek: ["Bazar", "Bazar ertəsi", "Çərşənbə axşamı", "Çərşənbə", "Cümə axşamı", "Cümə", "Şənbə"]
288			},
289			bs: { //Bosanski
290				months: [
291					"Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"
292				],
293				dayOfWeekShort: [
294					"Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"
295				],
296				dayOfWeek: ["Nedjelja","Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota"]
297			},
298			ca: { //Català
299				months: [
300					"Gener", "Febrer", "Març", "Abril", "Maig", "Juny", "Juliol", "Agost", "Setembre", "Octubre", "Novembre", "Desembre"
301				],
302				dayOfWeekShort: [
303					"Dg", "Dl", "Dt", "Dc", "Dj", "Dv", "Ds"
304				],
305				dayOfWeek: ["Diumenge", "Dilluns", "Dimarts", "Dimecres", "Dijous", "Divendres", "Dissabte"]
306			},
307			'en-GB': { //English (British)
308				months: [
309					"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
310				],
311				dayOfWeekShort: [
312					"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
313				],
314				dayOfWeek: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
315			},
316			et: { //"Eesti"
317				months: [
318					"Jaanuar", "Veebruar", "Märts", "Aprill", "Mai", "Juuni", "Juuli", "August", "September", "Oktoober", "November", "Detsember"
319				],
320				dayOfWeekShort: [
321					"P", "E", "T", "K", "N", "R", "L"
322				],
323				dayOfWeek: ["Pühapäev", "Esmaspäev", "Teisipäev", "Kolmapäev", "Neljapäev", "Reede", "Laupäev"]
324			},
325			eu: { //Euskara
326				months: [
327					"Urtarrila", "Otsaila", "Martxoa", "Apirila", "Maiatza", "Ekaina", "Uztaila", "Abuztua", "Iraila", "Urria", "Azaroa", "Abendua"
328				],
329				dayOfWeekShort: [
330					"Ig.", "Al.", "Ar.", "Az.", "Og.", "Or.", "La."
331				],
332				dayOfWeek: ['Igandea', 'Astelehena', 'Asteartea', 'Asteazkena', 'Osteguna', 'Ostirala', 'Larunbata']
333			},
334			fi: { //Finnish (Suomi)
335				months: [
336					"Tammikuu", "Helmikuu", "Maaliskuu", "Huhtikuu", "Toukokuu", "Kesäkuu", "Heinäkuu", "Elokuu", "Syyskuu", "Lokakuu", "Marraskuu", "Joulukuu"
337				],
338				dayOfWeekShort: [
339					"Su", "Ma", "Ti", "Ke", "To", "Pe", "La"
340				],
341				dayOfWeek: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai"]
342			},
343			gl: { //Galego
344				months: [
345					"Xan", "Feb", "Maz", "Abr", "Mai", "Xun", "Xul", "Ago", "Set", "Out", "Nov", "Dec"
346				],
347				dayOfWeekShort: [
348					"Dom", "Lun", "Mar", "Mer", "Xov", "Ven", "Sab"
349				],
350				dayOfWeek: ["Domingo", "Luns", "Martes", "Mércores", "Xoves", "Venres", "Sábado"]
351			},
352			hr: { //Hrvatski
353				months: [
354					"Siječanj", "Veljača", "Ožujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac"
355				],
356				dayOfWeekShort: [
357					"Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"
358				],
359				dayOfWeek: ["Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota"]
360			},
361			ko: { //Korean (한국어)
362				months: [
363					"1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"
364				],
365				dayOfWeekShort: [
366					"일", "월", "화", "수", "목", "금", "토"
367				],
368				dayOfWeek: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"]
369			},
370			lt: { //Lithuanian (lietuvių)
371				months: [
372					"Sausio", "Vasario", "Kovo", "Balandžio", "Gegužės", "Birželio", "Liepos", "Rugpjūčio", "Rugsėjo", "Spalio", "Lapkričio", "Gruodžio"
373				],
374				dayOfWeekShort: [
375					"Sek", "Pir", "Ant", "Tre", "Ket", "Pen", "Šeš"
376				],
377				dayOfWeek: ["Sekmadienis", "Pirmadienis", "Antradienis", "Trečiadienis", "Ketvirtadienis", "Penktadienis", "Šeštadienis"]
378			},
379			lv: { //Latvian (Latviešu)
380				months: [
381					"Janvāris", "Februāris", "Marts", "Aprīlis ", "Maijs", "Jūnijs", "Jūlijs", "Augusts", "Septembris", "Oktobris", "Novembris", "Decembris"
382				],
383				dayOfWeekShort: [
384					"Sv", "Pr", "Ot", "Tr", "Ct", "Pk", "St"
385				],
386				dayOfWeek: ["Svētdiena", "Pirmdiena", "Otrdiena", "Trešdiena", "Ceturtdiena", "Piektdiena", "Sestdiena"]
387			},
388			mk: { //Macedonian (Македонски)
389				months: [
390					"јануари", "февруари", "март", "април", "мај", "јуни", "јули", "август", "септември", "октомври", "ноември", "декември"
391				],
392				dayOfWeekShort: [
393					"нед", "пон", "вто", "сре", "чет", "пет", "саб"
394				],
395				dayOfWeek: ["Недела", "Понеделник", "Вторник", "Среда", "Четврток", "Петок", "Сабота"]
396			},
397			mn: { //Mongolian (Монгол)
398				months: [
399					"1-р сар", "2-р сар", "3-р сар", "4-р сар", "5-р сар", "6-р сар", "7-р сар", "8-р сар", "9-р сар", "10-р сар", "11-р сар", "12-р сар"
400				],
401				dayOfWeekShort: [
402					"Дав", "Мяг", "Лха", "Пүр", "Бсн", "Бям", "Ням"
403				],
404				dayOfWeek: ["Даваа", "Мягмар", "Лхагва", "Пүрэв", "Баасан", "Бямба", "Ням"]
405			},
406			'pt-BR': { //Português(Brasil)
407				months: [
408					"Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
409				],
410				dayOfWeekShort: [
411					"Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"
412				],
413				dayOfWeek: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"]
414			},
415			sk: { //Slovenčina
416				months: [
417					"Január", "Február", "Marec", "Apríl", "Máj", "Jún", "Júl", "August", "September", "Október", "November", "December"
418				],
419				dayOfWeekShort: [
420					"Ne", "Po", "Ut", "St", "Å t", "Pi", "So"
421				],
422				dayOfWeek: ["Nedeľa", "Pondelok", "Utorok", "Streda", "Štvrtok", "Piatok", "Sobota"]
423			},
424			sq: { //Albanian (Shqip)
425				months: [
426					"Janar", "Shkurt", "Mars", "Prill", "Maj", "Qershor", "Korrik", "Gusht", "Shtator", "Tetor", "Nëntor", "Dhjetor"
427				],
428				dayOfWeekShort: [
429					"Die", "Hën", "Mar", "Mër", "Enj", "Pre", "Shtu"
430				],
431				dayOfWeek: ["E Diel", "E Hënë", "E Martē", "E Mërkurë", "E Enjte", "E Premte", "E Shtunë"]
432			},
433			'sr-YU': { //Serbian (Srpski)
434				months: [
435					"Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"
436				],
437				dayOfWeekShort: [
438					"Ned", "Pon", "Uto", "Sre", "čet", "Pet", "Sub"
439				],
440				dayOfWeek: ["Nedelja","Ponedeljak", "Utorak", "Sreda", "Četvrtak", "Petak", "Subota"]
441			},
442			sr: { //Serbian Cyrillic (Српски)
443				months: [
444					"јануар", "фебруар", "март", "април", "мај", "јун", "јул", "август", "септембар", "октобар", "новембар", "децембар"
445				],
446				dayOfWeekShort: [
447					"нед", "пон", "уто", "сре", "чет", "пет", "суб"
448				],
449				dayOfWeek: ["Недеља","Понедељак", "Уторак", "Среда", "Четвртак", "Петак", "Субота"]
450			},
451			sv: { //Svenska
452				months: [
453					"Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"
454				],
455				dayOfWeekShort: [
456					"Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"
457				],
458				dayOfWeek: ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"]
459			},
460			'zh-TW': { //Traditional Chinese (繁體中文)
461				months: [
462					"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
463				],
464				dayOfWeekShort: [
465					"日", "一", "二", "三", "四", "五", "六"
466				],
467				dayOfWeek: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
468			},
469			zh: { //Simplified Chinese (简体中文)
470				months: [
471					"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
472				],
473				dayOfWeekShort: [
474					"日", "一", "二", "三", "四", "五", "六"
475				],
476				dayOfWeek: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
477			},
478			ug:{ // Uyghur(ئۇيغۇرچە)
479				months: [
480					"1-ئاي","2-ئاي","3-ئاي","4-ئاي","5-ئاي","6-ئاي","7-ئاي","8-ئاي","9-ئاي","10-ئاي","11-ئاي","12-ئاي"
481				],
482				dayOfWeek: [
483					"يەكشەنبە", "دۈشەنبە","سەيشەنبە","چارشەنبە","پەيشەنبە","جۈمە","شەنبە"
484				]
485			},
486			he: { //Hebrew (עברית)
487				months: [
488					'ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'
489				],
490				dayOfWeekShort: [
491					'א\'', 'ב\'', 'ג\'', 'ד\'', 'ה\'', 'ו\'', 'שבת'
492				],
493				dayOfWeek: ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת", "ראשון"]
494			},
495			hy: { // Armenian
496				months: [
497					"Հունվար", "Փետրվար", "Մարտ", "Ապրիլ", "Մայիս", "Հունիս", "Հուլիս", "Օգոստոս", "Սեպտեմբեր", "Հոկտեմբեր", "Նոյեմբեր", "Դեկտեմբեր"
498				],
499				dayOfWeekShort: [
500					"Կի", "Երկ", "Երք", "Չոր", "Հնգ", "Ուրբ", "Շբթ"
501				],
502				dayOfWeek: ["Կիրակի", "Երկուշաբթի", "Երեքշաբթի", "Չորեքշաբթի", "Հինգշաբթի", "Ուրբաթ", "Շաբաթ"]
503			},
504			kg: { // Kyrgyz
505				months: [
506					'Үчтүн айы', 'Бирдин айы', 'Жалган Куран', 'Чын Куран', 'Бугу', 'Кулжа', 'Теке', 'Баш Оона', 'Аяк Оона', 'Тогуздун айы', 'Жетинин айы', 'Бештин айы'
507				],
508				dayOfWeekShort: [
509					"Жек", "Дүй", "Шей", "Шар", "Бей", "Жум", "Ише"
510				],
511				dayOfWeek: [
512					"Жекшемб", "Дүйшөмб", "Шейшемб", "Шаршемб", "Бейшемби", "Жума", "Ишенб"
513				]
514			},
515			rm: { // Romansh
516				months: [
517					"Schaner", "Favrer", "Mars", "Avrigl", "Matg", "Zercladur", "Fanadur", "Avust", "Settember", "October", "November", "December"
518				],
519				dayOfWeekShort: [
520					"Du", "Gli", "Ma", "Me", "Gie", "Ve", "So"
521				],
522				dayOfWeek: [
523					"Dumengia", "Glindesdi", "Mardi", "Mesemna", "Gievgia", "Venderdi", "Sonda"
524				]
525			},
526			ka: { // Georgian
527				months: [
528					'იანვარი', 'თებერვალი', 'მარტი', 'აპრილი', 'მაისი', 'ივნისი', 'ივლისი', 'აგვისტო', 'სექტემბერი', 'ოქტომბერი', 'ნოემბერი', 'დეკემბერი'
529				],
530				dayOfWeekShort: [
531					"კვ", "ორშ", "სამშ", "ოთხ", "ხუთ", "პარ", "შაბ"
532				],
533				dayOfWeek: ["კვირა", "ორშაბათი", "სამშაბათი", "ოთხშაბათი", "ხუთშაბათი", "პარასკევი", "შაბათი"]
534			}
535		},
536
537		ownerDocument: document,
538		contentWindow: window,
539
540		value: '',
541		rtl: false,
542
543		format:	'Y/m/d H:i',
544		formatTime:	'H:i',
545		formatDate:	'Y/m/d',
546
547		startDate:	false, // new Date(), '1986/12/08', '-1970/01/05','-1970/01/05',
548		step: 60,
549		monthChangeSpinner: true,
550
551		closeOnDateSelect: false,
552		closeOnTimeSelect: true,
553		closeOnWithoutClick: true,
554		closeOnInputClick: true,
vendor: 8,698 bytes, lines 555-879
555		openOnFocus: true,
556
557		timepicker: true,
558		datepicker: true,
559		weeks: false,
560
561		defaultTime: false,	// use formatTime format (ex. '10:00' for formatTime:	'H:i')
562		defaultDate: false,	// use formatDate format (ex new Date() or '1986/12/08' or '-1970/01/05' or '-1970/01/05')
563
564		minDate: false,
565		maxDate: false,
566		minTime: false,
567		maxTime: false,
568		minDateTime: false,
569
570		disabledMinTime: false,
571		disabledMaxTime: false,
572
573		allowTimes: [],
574		opened: false,
575		initTime: true,
576		inline: false,
577		theme: '',
578		touchMovedThreshold: 5,
579
580		onSelectDate: function () {},
581		onSelectTime: function () {},
582		onChangeMonth: function () {},
583		onGetWeekOfYear: function () {},
584		onChangeYear: function () {},
585		onChangeDateTime: function () {},
586		onShow: function () {},
587		onClose: function () {},
588		onGenerate: function () {},
589
590		withoutCopyright: true,
591		inverseButton: false,
592		hours12: false,
593		next: 'xdsoft_next',
594		prev : 'xdsoft_prev',
595		dayOfWeekStart: 0,
596		parentID: 'body',
597		timeHeightInTimePicker: 25,
598		timepickerScrollbar: true,
599		todayButton: true,
600		prevButton: true,
601		nextButton: true,
602		defaultSelect: true,
603
604		scrollMonth: true,
605		scrollTime: true,
606		scrollInput: true,
607
608		lazyInit: false,
609		mask: false,
610		validateOnBlur: true,
611		allowBlank: true,
612		yearStart: 1950,
613		yearEnd: 2050,
614		monthStart: 0,
615		monthEnd: 11,
616		style: '',
617		id: '',
618		fixed: false,
619		roundTime: 'round', // ceil, floor
620		className: '',
621		weekends: [],
622		highlightedDates: [],
623		highlightedPeriods: [],
624		allowDates : [],
625		allowDateRe : null,
626		disabledDates : [],
627		disabledWeekDays: [],
628		yearOffset: 0,
629		beforeShowDay: null,
630
631		enterLikeTab: true,
632		showApplyButton: false
633	};
634
635	var dateHelper          = null,
636		defaultDateHelper   = null,
637		globalLocaleDefault = 'en',
638		globalLocale        = 'en';
639
640	var dateFormatterOptionsDefault = {
641		meridiem: ['AM', 'PM']
642	};
643
644	var initDateFormatter = function(){
645		var locale = default_options.i18n[globalLocale],
646			opts   = {
647				days: locale.dayOfWeek,
648				daysShort: locale.dayOfWeekShort,
649				months: locale.months,
650				monthsShort: $.map( locale.months, function(n){ return n.substring( 0, 3 ) } )
651		};
652
653		if (typeof DateFormatter === 'function') {
654			dateHelper = defaultDateHelper = new DateFormatter(
655				{
656					dateSettings: $.extend( {}, dateFormatterOptionsDefault, opts )
657				}
658			);
659		}
660	};
661
662	var dateFormatters = {
663		moment: {
664			default_options:{
665				format: 'YYYY/MM/DD HH:mm',
666				formatDate: 'YYYY/MM/DD',
667				formatTime: 'HH:mm',
668			},
669			formatter: {
670				parseDate: function (date, format) {
671					if (isFormatStandard( format )) {
672						return defaultDateHelper.parseDate( date, format );
673					}
674					var d = moment( date, format );
675					return d.isValid() ? d.toDate() : false;
676				},
677
678				formatDate: function (date, format) {
679					if (isFormatStandard( format )) {
680						return defaultDateHelper.formatDate( date, format );
681					}
682					return moment( date ).format( format );
683				},
684
685				formatMask: function(format){
686					return format
687						.replace( /Y{4}/g, '9999' )
688						.replace( /Y{2}/g, '99' )
689						.replace( /M{2}/g, '19' )
690						.replace( /D{2}/g, '39' )
691						.replace( /H{2}/g, '29' )
692						.replace( /m{2}/g, '59' )
693						.replace( /s{2}/g, '59' );
694				},
695			}
696		}
697	}
698
699	// for locale settings
700	$.datetimepicker = {
701		setLocale: function(locale){
702			var newLocale = default_options.i18n[locale] ? locale : globalLocaleDefault;
703			if (globalLocale !== newLocale) {
704				globalLocale = newLocale;
705				// reinit date formatter
706				initDateFormatter();
707			}
708		},
709
710		setDateFormatter: function(dateFormatter) {
711			if (typeof dateFormatter === 'string' && dateFormatters.hasOwnProperty( dateFormatter )) {
712				var df = dateFormatters[dateFormatter];
713				$.extend( default_options, df.default_options );
714				dateHelper = df.formatter;
715			} else {
716				dateHelper = dateFormatter;
717			}
718		},
719	};
720
721	var standardFormats = {
722		RFC_2822: 'D, d M Y H:i:s O',
723		ATOM: 'Y-m-d\TH:i:sP',
724		ISO_8601: 'Y-m-d\TH:i:sO',
725		RFC_822: 'D, d M y H:i:s O',
726		RFC_850: 'l, d-M-y H:i:s T',
727		RFC_1036: 'D, d M y H:i:s O',
728		RFC_1123: 'D, d M Y H:i:s O',
729		RSS: 'D, d M Y H:i:s O',
730		W3C: 'Y-m-d\TH:i:sP'
731	}
732
733	var isFormatStandard = function(format){
734		return Object.values( standardFormats ).indexOf( format ) === -1 ? false : true;
735	}
736
737	$.extend( $.datetimepicker, standardFormats );
738
739	// first init date formatter
740	initDateFormatter();
741
742	// fix for ie8
743	if ( ! window.getComputedStyle) {
744		window.getComputedStyle = function (el) {
745			this.el               = el;
746			this.getPropertyValue = function (prop) {
747				var re = /(-([a-z]))/g;
748				if (prop === 'float') {
749					prop = 'styleFloat';
750				}
751				if (re.test( prop )) {
752					prop = prop.replace(
753						re,
754						function (a, b, c) {
755							return c.toUpperCase();
756						}
757					);
758				}
759				return el.currentStyle[prop] || null;
760			};
761			return this;
762		};
763	}
764	if ( ! Array.prototype.indexOf) {
765		Array.prototype.indexOf = function (obj, start) {
766			var i, j;
767			for (i = (start || 0), j = this.length; i < j; i += 1) {
768				if (this[i] === obj) {
769					return i; }
770			}
771			return -1;
772		};
773	}
774
775	Date.prototype.countDaysInMonth = function () {
776		return new Date( this.getFullYear(), this.getMonth() + 1, 0 ).getDate();
777	};
778
779	$.fn.xdsoftScroller = function (options, percent) {
780		return this.each(
781			function () {
782				var timeboxparent = $( this ),
783				pointerEventToXY  = function (e) {
784					var out = {x: 0, y: 0},
785						touch;
786					if (e.type === 'touchstart' || e.type === 'touchmove' || e.type === 'touchend' || e.type === 'touchcancel') {
787						touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
788						out.x = touch.clientX;
789						out.y = touch.clientY;
790					} else if (e.type === 'mousedown' || e.type === 'mouseup' || e.type === 'mousemove' || e.type === 'mouseover' || e.type === 'mouseout' || e.type === 'mouseenter' || e.type === 'mouseleave') {
791						out.x = e.clientX;
792						out.y = e.clientY;
793					}
794					return out;
795				},
796				timebox,
797				parentHeight,
798				height,
799				scrollbar,
800				scroller,
801				maximumOffset     = 100,
802				start             = false,
803				startY            = 0,
804				startTop          = 0,
805				h1                = 0,
806				touchStart        = false,
807				startTopScroll    = 0,
808				calcOffset        = function () {};
809
810				if (percent === 'hide') {
811					timeboxparent.find( '.xdsoft_scrollbar' ).hide();
812					return;
813				}
814
815				if ( ! $( this ).hasClass( 'xdsoft_scroller_box' )) {
816					timebox      = timeboxparent.children().eq( 0 );
817					parentHeight = timeboxparent[0].clientHeight;
818					height       = timebox[0].offsetHeight;
819					scrollbar    = $( '<div class="xdsoft_scrollbar"></div>' );
820					scroller     = $( '<div class="xdsoft_scroller"></div>' );
821					scrollbar.append( scroller );
822
823					timeboxparent.addClass( 'xdsoft_scroller_box' ).append( scrollbar );
824					calcOffset = function calcOffset(event) {
825						var offset = pointerEventToXY( event ).y - startY + startTopScroll;
826						if (offset < 0) {
827							offset = 0;
828						}
829						if (offset + scroller[0].offsetHeight > h1) {
830							offset = h1 - scroller[0].offsetHeight;
831						}
832						timeboxparent.trigger( 'scroll_element.xdsoft_scroller', [maximumOffset ? offset / maximumOffset : 0] );
833					};
834
835					scroller
836					.on(
837						'touchstart.xdsoft_scroller mousedown.xdsoft_scroller',
838						function (event) {
839							if ( ! parentHeight) {
840								timeboxparent.trigger( 'resize_scroll.xdsoft_scroller', [percent] );
841							}
842
843							startY         = pointerEventToXY( event ).y;
844							startTopScroll = parseInt( scroller.css( 'margin-top' ), 10 );
845							h1             = scrollbar[0].offsetHeight;
846
847							if (event.type === 'mousedown' || event.type === 'touchstart') {
848								if (options.ownerDocument) {
849									$( options.ownerDocument.body ).addClass( 'xdsoft_noselect' );
850								}
851								$( [options.ownerDocument.body, options.contentWindow] ).on(
852									'touchend mouseup.xdsoft_scroller',
853									function arguments_callee() {
854										$( [options.ownerDocument.body, options.contentWindow] ).off( 'touchend mouseup.xdsoft_scroller', arguments_callee )
855										.off( 'mousemove.xdsoft_scroller', calcOffset )
856										.removeClass( 'xdsoft_noselect' );
857									}
858								);
859								$( options.ownerDocument.body ).on( 'mousemove.xdsoft_scroller', calcOffset );
860							} else {
861								touchStart = true;
862								event.stopPropagation();
863								event.preventDefault();
864							}
865						}
866					)
867						.on(
868							'touchmove',
869							function (event) {
870								if (touchStart) {
871									event.preventDefault();
872									calcOffset( event );
873								}
874							}
875						)
876						.on(
877							'touchend touchcancel',
878							function () {
879								touchStart     = false;
vendor: 5,310 bytes, lines 880-1040
880								startTopScroll = 0;
881							}
882						);
883
884					timeboxparent
885						.on(
886							'scroll_element.xdsoft_scroller',
887							function (event, percentage) {
888								if ( ! parentHeight) {
889									timeboxparent.trigger( 'resize_scroll.xdsoft_scroller', [percentage, true] );
890								}
891								percentage = percentage > 1 ? 1 : (percentage < 0 || isNaN( percentage )) ? 0 : percentage;
892
893								scroller.css( 'margin-top', maximumOffset * percentage );
894
895								setTimeout(
896									function () {
897										timebox.css( 'marginTop', -parseInt( (timebox[0].offsetHeight - parentHeight) * percentage, 10 ) );
898									},
899									10
900								);
901							}
902						)
903						.on(
904							'resize_scroll.xdsoft_scroller',
905							function (event, percentage, noTriggerScroll) {
906								var percent, sh;
907								parentHeight = timeboxparent[0].clientHeight;
908								height       = timebox[0].offsetHeight;
909								percent      = parentHeight / height;
910								sh           = percent * scrollbar[0].offsetHeight;
911								if (percent > 1) {
912									scroller.hide();
913								} else {
914									scroller.show();
915									scroller.css( 'height', parseInt( sh > 10 ? sh : 10, 10 ) );
916									maximumOffset = scrollbar[0].offsetHeight - scroller[0].offsetHeight;
917									if (noTriggerScroll !== true) {
918										timeboxparent.trigger( 'scroll_element.xdsoft_scroller', [percentage || Math.abs( parseInt( timebox.css( 'marginTop' ), 10 ) ) / (height - parentHeight)] );
919									}
920								}
921							}
922						);
923
924					timeboxparent.on(
925						'mousewheel',
926						function (event) {
927							var top = Math.abs( parseInt( timebox.css( 'marginTop' ), 10 ) );
928
929							top = top - (event.deltaY * 20);
930							if (top < 0) {
931								top = 0;
932							}
933
934							timeboxparent.trigger( 'scroll_element.xdsoft_scroller', [top / (height - parentHeight)] );
935							event.stopPropagation();
936							return false;
937						}
938					);
939
940					timeboxparent.on(
941						'touchstart',
942						function (event) {
943							start    = pointerEventToXY( event );
944							startTop = Math.abs( parseInt( timebox.css( 'marginTop' ), 10 ) );
945						}
946					);
947
948					timeboxparent.on(
949						'touchmove',
950						function (event) {
951							if (start) {
952								event.preventDefault();
953								var coord = pointerEventToXY( event );
954								timeboxparent.trigger( 'scroll_element.xdsoft_scroller', [(startTop - (coord.y - start.y)) / (height - parentHeight)] );
955							}
956						}
957					);
958
959					timeboxparent.on(
960						'touchend touchcancel',
961						function () {
962							start    = false;
963							startTop = 0;
964						}
965					);
966				}
967				timeboxparent.trigger( 'resize_scroll.xdsoft_scroller', [percent] );
968			}
969		);
970	};
971
972	$.fn.datetimepicker = function (opt, opt2) {
973		var result     = this,
974			KEY0       = 48,
975			KEY9       = 57,
976			_KEY0      = 96,
977			_KEY9      = 105,
978			CTRLKEY    = 17,
979			DEL        = 46,
980			ENTER      = 13,
981			ESC        = 27,
982			BACKSPACE  = 8,
983			ARROWLEFT  = 37,
984			ARROWUP    = 38,
985			ARROWRIGHT = 39,
986			ARROWDOWN  = 40,
987			TAB        = 9,
988			F5         = 116,
989			AKEY       = 65,
990			CKEY       = 67,
991			VKEY       = 86,
992			ZKEY       = 90,
993			YKEY       = 89,
994			ctrlDown   = false,
995			options    = ($.isPlainObject( opt ) || ! opt) ? $.extend( true, {}, default_options, opt ) : $.extend( true, {}, default_options ),
996
997			lazyInitTimer = 0,
998			createDateTimePicker,
999			destroyDateTimePicker,
1000
1001			lazyInit = function (input) {
1002				input
1003					.on(
1004						'open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart',
1005						function initOnActionCallback() {
1006					if (input.is( ':disabled' ) || input.data( 'xdsoft_datetimepicker' )) {
1007						return;
1008					}
1009						clearTimeout( lazyInitTimer );
1010						lazyInitTimer = setTimeout(
1011							function () {
1012
1013								if ( ! input.data( 'xdsoft_datetimepicker' )) {
1014									createDateTimePicker( input );
1015								}
1016								input
1017								.off( 'open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', initOnActionCallback )
1018								.trigger( 'open.xdsoft' );
1019							},
1020							100
1021						);
1022						}
1023					);
1024			};
1025
1026		createDateTimePicker  = function (input) {
1027			var datetimepicker   = $( '<div class="xdsoft_datetimepicker xdsoft_noselect"></div>' ),
1028				xdsoft_copyright = $( '<div class="xdsoft_copyright"><a target="_blank" href="http://xdsoft.net/jqplugins/datetimepicker/">xdsoft.net</a></div>' ),
1029				datepicker       = $( '<div class="xdsoft_datepicker active"></div>' ),
1030				month_picker     = $(
1031					'<div class="xdsoft_monthpicker"><button type="button" class="xdsoft_prev"></button><button type="button" class="xdsoft_today_button"></button>' +
1032					'<div class="xdsoft_label xdsoft_month"><span></span><i></i></div>' +
1033					'<div class="xdsoft_label xdsoft_year"><span></span><i></i></div>' +
1034					'<button type="button" class="xdsoft_next"></button></div>'
1035				),
1036				calendar         = $( '<div class="xdsoft_calendar"></div>' ),
1037				timepicker       = $( '<div class="xdsoft_timepicker active"><button type="button" class="xdsoft_prev"></button><div class="xdsoft_time_box"></div><button type="button" class="xdsoft_next"></button></div>' ),
1038				timeboxparent    = timepicker.find( '.xdsoft_time_box' ).eq( 0 ),
1039				timebox          = $( '<div class="xdsoft_time_variant"></div>' ),
1040				applyButton      = $( '<button type="button" class="xdsoft_save_selected blue-gradient-button">Save Selected</button>' ),
vendor: 8,787 bytes, lines 1041-1303
1041
1042				monthselect      = $( '<div class="xdsoft_select xdsoft_monthselect"><div></div></div>' ),
1043				yearselect       = $( '<div class="xdsoft_select xdsoft_yearselect"><div></div></div>' ),
1044				triggerAfterOpen = false,
1045				XDSoft_datetime,
1046
1047				xchangeTimer,
1048				timerclick,
1049				current_time_index,
1050				setPos,
1051				timer = 0,
1052				_xdsoft_datetime,
1053				forEachAncestorOf;
1054
1055			if (options.id) {
1056				datetimepicker.attr( 'id', options.id );
1057			}
1058			if (options.style) {
1059				datetimepicker.attr( 'style', options.style );
1060			}
1061			if (options.weeks) {
1062				datetimepicker.addClass( 'xdsoft_showweeks' );
1063			}
1064			if (options.rtl) {
1065				datetimepicker.addClass( 'xdsoft_rtl' );
1066			}
1067
1068			datetimepicker.addClass( 'xdsoft_' + options.theme );
1069			datetimepicker.addClass( options.className );
1070
1071			month_picker
1072				.find( '.xdsoft_month span' )
1073				.after( monthselect );
1074			month_picker
1075				.find( '.xdsoft_year span' )
1076				.after( yearselect );
1077
1078			month_picker
1079				.find( '.xdsoft_month,.xdsoft_year' )
1080				.on(
1081					'touchstart mousedown.xdsoft',
1082					function (event) {
1083						var select = $( this ).find( '.xdsoft_select' ).eq( 0 ),
1084						val        = 0,
1085						top        = 0,
1086						visible    = select.is( ':visible' ),
1087						items,
1088						i;
1089
1090						month_picker
1091						.find( '.xdsoft_select' )
1092						.hide();
1093						if (_xdsoft_datetime.currentTime) {
1094							val = _xdsoft_datetime.currentTime[$( this ).hasClass( 'xdsoft_month' ) ? 'getMonth' : 'getFullYear']();
1095						}
1096
1097						select[visible ? 'hide' : 'show']();
1098						for (items = select.find( 'div.xdsoft_option' ), i = 0; i < items.length; i += 1) {
1099							if (items.eq( i ).data( 'value' ) === val) {
1100								break;
1101							} else {
1102								top += items[0].offsetHeight;
1103							}
1104						}
1105
1106						select.xdsoftScroller( options, top / (select.children()[0].offsetHeight - (select[0].clientHeight)) );
1107						event.stopPropagation();
1108						return false;
1109					}
1110				);
1111
1112			var handleTouchMoved = function (event) {
1113				this.touchStartPosition = this.touchStartPosition || event.originalEvent.touches[0]
1114				var touchPosition       = event.originalEvent.touches[0]
1115				var xMovement           = Math.abs( this.touchStartPosition.clientX - touchPosition.clientX )
1116				var yMovement           = Math.abs( this.touchStartPosition.clientY - touchPosition.clientY )
1117				var distance            = Math.sqrt( xMovement * xMovement + yMovement * yMovement )
1118				if (distance > options.touchMovedThreshold) {
1119					this.touchMoved = true;
1120				}
1121			}
1122
1123			month_picker
1124				.find( '.xdsoft_select' )
1125				.xdsoftScroller( options )
1126				.on(
1127					'touchstart mousedown.xdsoft',
1128					function (event) {
1129						this.touchMoved         = false;
1130						this.touchStartPosition = event.originalEvent.touches[0]
1131						event.stopPropagation();
1132						event.preventDefault();
1133					}
1134				)
1135				.on( 'touchmove', '.xdsoft_option', handleTouchMoved )
1136				.on(
1137					'touchend mousedown.xdsoft',
1138					'.xdsoft_option',
1139					function () {
1140						if ( ! this.touchMoved) {
1141							if (_xdsoft_datetime.currentTime === undefined || _xdsoft_datetime.currentTime === null) {
1142								_xdsoft_datetime.currentTime = _xdsoft_datetime.now();
1143							}
1144
1145							var year = _xdsoft_datetime.currentTime.getFullYear();
1146							if (_xdsoft_datetime && _xdsoft_datetime.currentTime) {
1147								_xdsoft_datetime.currentTime[$( this ).parent().parent().hasClass( 'xdsoft_monthselect' ) ? 'setMonth' : 'setFullYear']( $( this ).data( 'value' ) );
1148							}
1149
1150							$( this ).parent().parent().hide();
1151
1152							datetimepicker.trigger( 'xchange.xdsoft' );
1153							if (options.onChangeMonth && $.isFunction( options.onChangeMonth )) {
1154								options.onChangeMonth.call( datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data( 'input' ) );
1155							}
1156
1157							if (year !== _xdsoft_datetime.currentTime.getFullYear() && $.isFunction( options.onChangeYear )) {
1158								options.onChangeYear.call( datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data( 'input' ) );
1159							}
1160						}
1161					}
1162				);
1163
1164			datetimepicker.getValue = function () {
1165				return _xdsoft_datetime.getCurrentTime();
1166			};
1167
1168			datetimepicker.setOptions = function (_options) {
1169				var highlightedDates = {};
1170
1171				options = $.extend( true, {}, options, _options );
1172
1173				if (_options.allowTimes && $.isArray( _options.allowTimes ) && _options.allowTimes.length) {
1174					options.allowTimes = $.extend( true, [], _options.allowTimes );
1175				}
1176
1177				if (_options.weekends && $.isArray( _options.weekends ) && _options.weekends.length) {
1178					options.weekends = $.extend( true, [], _options.weekends );
1179				}
1180
1181				if (_options.allowDates && $.isArray( _options.allowDates ) && _options.allowDates.length) {
1182					options.allowDates = $.extend( true, [], _options.allowDates );
1183				}
1184
1185				if (_options.allowDateRe && Object.prototype.toString.call( _options.allowDateRe ) === "[object String]") {
1186					options.allowDateRe = new RegExp( _options.allowDateRe );
1187				}
1188
1189				if (_options.highlightedDates && $.isArray( _options.highlightedDates ) && _options.highlightedDates.length) {
1190					$.each(
1191						_options.highlightedDates,
1192						function (index, value) {
1193							var splitData = $.map( value.split( ',' ), $.trim ),
1194							exDesc,
1195							hDate         = new HighlightedDate( dateHelper.parseDate( splitData[0], options.formatDate ), splitData[1], splitData[2] ), // date, desc, style
1196							keyDate       = dateHelper.formatDate( hDate.date, options.formatDate );
1197							if (highlightedDates[keyDate] !== undefined) {
1198								exDesc = highlightedDates[keyDate].desc;
1199								if (exDesc && exDesc.length && hDate.desc && hDate.desc.length) {
1200									highlightedDates[keyDate].desc = exDesc + "\n" + hDate.desc;
1201								}
1202							} else {
1203								highlightedDates[keyDate] = hDate;
1204							}
1205						}
1206					);
1207
1208					options.highlightedDates = $.extend( true, [], highlightedDates );
1209				}
1210
1211				if (_options.highlightedPeriods && $.isArray( _options.highlightedPeriods ) && _options.highlightedPeriods.length) {
1212					highlightedDates = $.extend( true, [], options.highlightedDates );
1213					$.each(
1214						_options.highlightedPeriods,
1215						function (index, value) {
1216							var dateTest, // start date
1217							dateEnd,
1218							desc,
1219							hDate,
1220							keyDate,
1221							exDesc,
1222							style;
1223							if ($.isArray( value )) {
1224								dateTest = value[0];
1225								dateEnd  = value[1];
1226								desc     = value[2];
1227								style    = value[3];
1228							} else {
1229								var splitData = $.map( value.split( ',' ), $.trim );
1230								dateTest      = dateHelper.parseDate( splitData[0], options.formatDate );
1231								dateEnd       = dateHelper.parseDate( splitData[1], options.formatDate );
1232								desc          = splitData[2];
1233								style         = splitData[3];
1234							}
1235
1236							while (dateTest <= dateEnd) {
1237								hDate   = new HighlightedDate( dateTest, desc, style );
1238								keyDate = dateHelper.formatDate( dateTest, options.formatDate );
1239								dateTest.setDate( dateTest.getDate() + 1 );
1240								if (highlightedDates[keyDate] !== undefined) {
1241									exDesc = highlightedDates[keyDate].desc;
1242									if (exDesc && exDesc.length && hDate.desc && hDate.desc.length) {
1243										highlightedDates[keyDate].desc = exDesc + "\n" + hDate.desc;
1244									}
1245								} else {
1246									highlightedDates[keyDate] = hDate;
1247								}
1248							}
1249						}
1250					);
1251
1252					options.highlightedDates = $.extend( true, [], highlightedDates );
1253				}
1254
1255				if (_options.disabledDates && $.isArray( _options.disabledDates ) && _options.disabledDates.length) {
1256					options.disabledDates = $.extend( true, [], _options.disabledDates );
1257				}
1258
1259				if (_options.disabledWeekDays && $.isArray( _options.disabledWeekDays ) && _options.disabledWeekDays.length) {
1260					options.disabledWeekDays = $.extend( true, [], _options.disabledWeekDays );
1261				}
1262
1263				if ((options.open || options.opened) && ( ! options.inline)) {
1264					input.trigger( 'open.xdsoft' );
1265				}
1266
1267				if (options.inline) {
1268					triggerAfterOpen = true;
1269					datetimepicker.addClass( 'xdsoft_inline' );
1270					input.after( datetimepicker ).hide();
1271				}
1272
1273				if (options.inverseButton) {
1274					options.next = 'xdsoft_prev';
1275					options.prev = 'xdsoft_next';
1276				}
1277
1278				if (options.datepicker) {
1279					datepicker.addClass( 'active' );
1280				} else {
1281					datepicker.removeClass( 'active' );
1282				}
1283
1284				if (options.timepicker) {
1285					timepicker.addClass( 'active' );
1286				} else {
1287					timepicker.removeClass( 'active' );
1288				}
1289
1290				if (options.value) {
1291					_xdsoft_datetime.setCurrentTime( options.value );
1292					if (input && input.val) {
1293						input.val( _xdsoft_datetime.str );
1294					}
1295				}
1296
1297				if (isNaN( options.dayOfWeekStart )) {
1298					options.dayOfWeekStart = 0;
1299				} else {
1300					options.dayOfWeekStart = parseInt( options.dayOfWeekStart, 10 ) % 7;
1301				}
1302
1303				if ( ! options.timepickerScrollbar) {
vendor: 4,668 bytes, lines 1304-1450
1304					timeboxparent.xdsoftScroller( options, 'hide' );
1305				}
1306
1307				if (options.minDate && /^[\+\-](.*)$/.test( options.minDate )) {
1308					options.minDate = dateHelper.formatDate( _xdsoft_datetime.strToDateTime( options.minDate ), options.formatDate );
1309				}
1310
1311				if (options.maxDate && /^[\+\-](.*)$/.test( options.maxDate )) {
1312					options.maxDate = dateHelper.formatDate( _xdsoft_datetime.strToDateTime( options.maxDate ), options.formatDate );
1313				}
1314
1315				if (options.minDateTime && /^\+(.*)$/.test( options.minDateTime )) {
1316					options.minDateTime = _xdsoft_datetime.strToDateTime( options.minDateTime ).dateFormat( options.formatDate );
1317				}
1318
1319				applyButton.toggle( options.showApplyButton );
1320
1321				month_picker
1322					.find( '.xdsoft_today_button' )
1323					.css( 'visibility', ! options.todayButton ? 'hidden' : 'visible' );
1324
1325				month_picker
1326					.find( '.' + options.prev )
1327					.css( 'visibility', ! options.prevButton ? 'hidden' : 'visible' );
1328
1329				month_picker
1330					.find( '.' + options.next )
1331					.css( 'visibility', ! options.nextButton ? 'hidden' : 'visible' );
1332
1333				setMask( options );
1334
1335				if (options.validateOnBlur) {
1336					input
1337						.off( 'blur.xdsoft' )
1338						.on(
1339							'blur.xdsoft',
1340							function () {
1341								if (options.allowBlank && ( ! $.trim( $( this ).val() ).length ||
1342									(typeof options.mask === "string" && $.trim( $( this ).val() ) === options.mask.replace( /[0-9]/g, '_' )))) {
1343									$( this ).val( null );
1344									datetimepicker.data( 'xdsoft_datetime' ).empty();
1345								} else {
1346									var d = dateHelper.parseDate( $( this ).val(), options.format );
1347									if (d) { // parseDate() may skip some invalid parts like date or time, so make it clear for user: show parsed date/time
1348										$( this ).val( dateHelper.formatDate( d, options.format ) );
1349									} else {
1350										var splittedHours = +([$( this ).val()[0], $( this ).val()[1]].join( '' )),
1351										splittedMinutes   = +([$( this ).val()[2], $( this ).val()[3]].join( '' ));
1352
1353										// parse the numbers as 0312 => 03:12
1354										if ( ! options.datepicker && options.timepicker && splittedHours >= 0 && splittedHours < 24 && splittedMinutes >= 0 && splittedMinutes < 60) {
1355											$( this ).val(
1356												[splittedHours, splittedMinutes].map(
1357													function (item) {
1358														return item > 9 ? item : '0' + item;
1359													}
1360												).join( ':' )
1361											);
1362										} else {
1363											$( this ).val( dateHelper.formatDate( _xdsoft_datetime.now(), options.format ) );
1364										}
1365									}
1366									datetimepicker.data( 'xdsoft_datetime' ).setCurrentTime( $( this ).val() );
1367								}
1368
1369								datetimepicker.trigger( 'changedatetime.xdsoft' );
1370								datetimepicker.trigger( 'close.xdsoft' );
1371							}
1372						);
1373				}
1374				options.dayOfWeekStartPrev = (options.dayOfWeekStart === 0) ? 6 : options.dayOfWeekStart - 1;
1375
1376				datetimepicker
1377					.trigger( 'xchange.xdsoft' )
1378					.trigger( 'afterOpen.xdsoft' );
1379			};
1380
1381			datetimepicker
1382				.data( 'options', options )
1383				.on(
1384					'touchstart mousedown.xdsoft',
1385					function (event) {
1386						event.stopPropagation();
1387						event.preventDefault();
1388						yearselect.hide();
1389						monthselect.hide();
1390						return false;
1391					}
1392				);
1393
1394			//scroll_element = timepicker.find('.xdsoft_time_box');
1395			timeboxparent.append( timebox );
1396			timeboxparent.xdsoftScroller( options );
1397
1398			datetimepicker.on(
1399				'afterOpen.xdsoft',
1400				function () {
1401					timeboxparent.xdsoftScroller( options );
1402				}
1403			);
1404
1405			datetimepicker
1406				.append( datepicker )
1407				.append( timepicker );
1408
1409			if (options.withoutCopyright !== true) {
1410				datetimepicker
1411					.append( xdsoft_copyright );
1412			}
1413
1414			datepicker
1415				.append( month_picker )
1416				.append( calendar )
1417				.append( applyButton );
1418
1419			$( options.parentID )
1420				.append( datetimepicker );
1421
1422			XDSoft_datetime = function () {
1423				var _this = this;
1424				_this.now = function (norecursion) {
1425					var d = new Date(),
1426						date,
1427						time;
1428
1429					if ( ! norecursion && options.defaultDate) {
1430						date = _this.strToDateTime( options.defaultDate );
1431						d.setFullYear( date.getFullYear() );
1432						d.setMonth( date.getMonth() );
1433						d.setDate( date.getDate() );
1434					}
1435
1436					d.setFullYear( d.getFullYear() );
1437
1438					if ( ! norecursion && options.defaultTime) {
1439						time = _this.strtotime( options.defaultTime );
1440						d.setHours( time.getHours() );
1441						d.setMinutes( time.getMinutes() );
1442						d.setSeconds( time.getSeconds() );
1443						d.setMilliseconds( time.getMilliseconds() );
1444					}
1445					return d;
1446				};
1447
1448				_this.isValidDate = function (d) {
1449					if (Object.prototype.toString.call( d ) !== "[object Date]") {
1450						return false;
vendor: 15,130 bytes, lines 1451-1875
1451					}
1452					return ! isNaN( d.getTime() );
1453				};
1454
1455				_this.setCurrentTime = function (dTime, requireValidDate) {
1456					if (typeof dTime === 'string') {
1457						_this.currentTime = _this.strToDateTime( dTime );
1458					} else if (_this.isValidDate( dTime )) {
1459						_this.currentTime = dTime;
1460					} else if ( ! dTime && ! requireValidDate && options.allowBlank && ! options.inline) {
1461						_this.currentTime = null;
1462					} else {
1463						_this.currentTime = _this.now();
1464					}
1465
1466					datetimepicker.trigger( 'xchange.xdsoft' );
1467				};
1468
1469				_this.empty = function () {
1470					_this.currentTime = null;
1471				};
1472
1473				_this.getCurrentTime = function () {
1474					return _this.currentTime;
1475				};
1476
1477				_this.nextMonth = function () {
1478
1479					if (_this.currentTime === undefined || _this.currentTime === null) {
1480						_this.currentTime = _this.now();
1481					}
1482
1483					var month = _this.currentTime.getMonth() + 1,
1484						year;
1485					if (month === 12) {
1486						_this.currentTime.setFullYear( _this.currentTime.getFullYear() + 1 );
1487						month = 0;
1488					}
1489
1490					year = _this.currentTime.getFullYear();
1491
1492					_this.currentTime.setDate(
1493						Math.min(
1494							new Date( _this.currentTime.getFullYear(), month + 1, 0 ).getDate(),
1495							_this.currentTime.getDate()
1496						)
1497					);
1498					_this.currentTime.setMonth( month );
1499
1500					if (options.onChangeMonth && $.isFunction( options.onChangeMonth )) {
1501						options.onChangeMonth.call( datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data( 'input' ) );
1502					}
1503
1504					if (year !== _this.currentTime.getFullYear() && $.isFunction( options.onChangeYear )) {
1505						options.onChangeYear.call( datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data( 'input' ) );
1506					}
1507
1508					datetimepicker.trigger( 'xchange.xdsoft' );
1509					return month;
1510				};
1511
1512				_this.prevMonth = function () {
1513
1514					if (_this.currentTime === undefined || _this.currentTime === null) {
1515						_this.currentTime = _this.now();
1516					}
1517
1518					var month = _this.currentTime.getMonth() - 1;
1519					if (month === -1) {
1520						_this.currentTime.setFullYear( _this.currentTime.getFullYear() - 1 );
1521						month = 11;
1522					}
1523					_this.currentTime.setDate(
1524						Math.min(
1525							new Date( _this.currentTime.getFullYear(), month + 1, 0 ).getDate(),
1526							_this.currentTime.getDate()
1527						)
1528					);
1529					_this.currentTime.setMonth( month );
1530					if (options.onChangeMonth && $.isFunction( options.onChangeMonth )) {
1531						options.onChangeMonth.call( datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data( 'input' ) );
1532					}
1533					datetimepicker.trigger( 'xchange.xdsoft' );
1534					return month;
1535				};
1536
1537				_this.getWeekOfYear = function (datetime) {
1538					if (options.onGetWeekOfYear && $.isFunction( options.onGetWeekOfYear )) {
1539						var week = options.onGetWeekOfYear.call( datetimepicker, datetime );
1540						if (typeof week !== 'undefined') {
1541							return week;
1542						}
1543					}
1544					var onejan = new Date( datetime.getFullYear(), 0, 1 );
1545
1546					//First week of the year is th one with the first Thursday according to ISO8601
1547					if (onejan.getDay() !== 4) {
1548						onejan.setMonth( 0, 1 + ((4 - onejan.getDay() + 7) % 7) );
1549					}
1550
1551					return Math.ceil( (((datetime - onejan) / 86400000) + onejan.getDay() + 1) / 7 );
1552				};
1553
1554				_this.strToDateTime = function (sDateTime) {
1555					var tmpDate = [], timeOffset, currentTime;
1556
1557					if (sDateTime && sDateTime instanceof Date && _this.isValidDate( sDateTime )) {
1558						return sDateTime;
1559					}
1560
1561					tmpDate = /^([+-]{1})(.*)$/.exec( sDateTime );
1562
1563					if (tmpDate) {
1564						tmpDate[2] = dateHelper.parseDate( tmpDate[2], options.formatDate );
1565					}
1566
1567					if (tmpDate && tmpDate[2]) {
1568						timeOffset  = tmpDate[2].getTime() - (tmpDate[2].getTimezoneOffset()) * 60000;
1569						currentTime = new Date( (_this.now( true )).getTime() + parseInt( tmpDate[1] + '1', 10 ) * timeOffset );
1570					} else {
1571						currentTime = sDateTime ? dateHelper.parseDate( sDateTime, options.format ) : _this.now();
1572					}
1573
1574					if ( ! _this.isValidDate( currentTime )) {
1575						currentTime = _this.now();
1576					}
1577
1578					return currentTime;
1579				};
1580
1581				_this.strToDate = function (sDate) {
1582					if (sDate && sDate instanceof Date && _this.isValidDate( sDate )) {
1583						return sDate;
1584					}
1585
1586					var currentTime = sDate ? dateHelper.parseDate( sDate, options.formatDate ) : _this.now( true );
1587					if ( ! _this.isValidDate( currentTime )) {
1588						currentTime = _this.now( true );
1589					}
1590					return currentTime;
1591				};
1592
1593				_this.strtotime = function (sTime) {
1594					if (sTime && sTime instanceof Date && _this.isValidDate( sTime )) {
1595						return sTime;
1596					}
1597					var currentTime = sTime ? dateHelper.parseDate( sTime, options.formatTime ) : _this.now( true );
1598					if ( ! _this.isValidDate( currentTime )) {
1599						currentTime = _this.now( true );
1600					}
1601					return currentTime;
1602				};
1603
1604				_this.str         = function () {
1605					var format = options.format;
1606					if (options.yearOffset) {
1607						format = format.replace( 'Y', _this.currentTime.getFullYear() + options.yearOffset );
1608						format = format.replace( 'y', String( _this.currentTime.getFullYear() + options.yearOffset ).substring( 2, 4 ) );
1609					}
1610					return dateHelper.formatDate( _this.currentTime, format );
1611				};
1612				_this.currentTime = this.now();
1613			};
1614
1615			_xdsoft_datetime = new XDSoft_datetime();
1616
1617			applyButton.on(
1618				'touchend click',
1619				function (e) {//pathbrite
1620					e.preventDefault();
1621					datetimepicker.data( 'changed', true );
1622					_xdsoft_datetime.setCurrentTime( getCurrentValue() );
1623					input.val( _xdsoft_datetime.str() );
1624					datetimepicker.trigger( 'close.xdsoft' );
1625				}
1626			);
1627			month_picker
1628				.find( '.xdsoft_today_button' )
1629				.on(
1630					'touchend mousedown.xdsoft',
1631					function () {
1632						datetimepicker.data( 'changed', true );
1633						_xdsoft_datetime.setCurrentTime( 0, true );
1634						datetimepicker.trigger( 'afterOpen.xdsoft' );
1635					}
1636				).on(
1637					'dblclick.xdsoft',
1638					function () {
1639						var currentDate = _xdsoft_datetime.getCurrentTime(), minDate, maxDate;
1640						currentDate     = new Date( currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() );
1641						minDate         = _xdsoft_datetime.strToDate( options.minDate );
1642						minDate         = new Date( minDate.getFullYear(), minDate.getMonth(), minDate.getDate() );
1643						if (currentDate < minDate) {
1644							return;
1645						}
1646						maxDate = _xdsoft_datetime.strToDate( options.maxDate );
1647						maxDate = new Date( maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate() );
1648						if (currentDate > maxDate) {
1649							return;
1650						}
1651						input.val( _xdsoft_datetime.str() );
1652						input.trigger( 'change' );
1653						datetimepicker.trigger( 'close.xdsoft' );
1654					}
1655				);
1656			month_picker
1657				.find( '.xdsoft_prev,.xdsoft_next' )
1658				.on(
1659					'touchend mousedown.xdsoft',
1660					function () {
1661						var $this = $( this ),
1662						timer     = 0,
1663						stop      = false;
1664
1665						(function arguments_callee1(v) {
1666							if ($this.hasClass( options.next )) {
1667								_xdsoft_datetime.nextMonth();
1668							} else if ($this.hasClass( options.prev )) {
1669								_xdsoft_datetime.prevMonth();
1670							}
1671							if (options.monthChangeSpinner) {
1672								if ( ! stop) {
1673									timer = setTimeout( arguments_callee1, v || 100 );
1674								}
1675							}
1676						}(500));
1677
1678						$( [options.ownerDocument.body, options.contentWindow] ).on(
1679							'touchend mouseup.xdsoft',
1680							function arguments_callee2() {
1681								clearTimeout( timer );
1682								stop = true;
1683								$( [options.ownerDocument.body, options.contentWindow] ).off( 'touchend mouseup.xdsoft', arguments_callee2 );
1684							}
1685						);
1686					}
1687				);
1688
1689			timepicker
1690				.find( '.xdsoft_prev,.xdsoft_next' )
1691				.on(
1692					'touchend mousedown.xdsoft',
1693					function () {
1694						var $this = $( this ),
1695						timer     = 0,
1696						stop      = false,
1697						period    = 110;
1698						(function arguments_callee4(v) {
1699							var pheight = timeboxparent[0].clientHeight,
1700							height      = timebox[0].offsetHeight,
1701							top         = Math.abs( parseInt( timebox.css( 'marginTop' ), 10 ) );
1702							if ($this.hasClass( options.next ) && (height - pheight) - options.timeHeightInTimePicker >= top) {
1703								timebox.css( 'marginTop', '-' + (top + options.timeHeightInTimePicker) + 'px' );
1704							} else if ($this.hasClass( options.prev ) && top - options.timeHeightInTimePicker >= 0) {
1705								timebox.css( 'marginTop', '-' + (top - options.timeHeightInTimePicker) + 'px' );
1706							}
1707							/**
1708							 * Fixed bug:
1709							 * When using css3 transition, it will cause a bug that you cannot scroll the timepicker list.
1710							 * The reason is that the transition-duration time, if you set it to 0, all things fine, otherwise, this
1711							 * would cause a bug when you use jquery.css method.
1712							 * Let's say: * { transition: all .5s ease; }
1713							 * jquery timebox.css('marginTop') will return the original value which is before you clicking the next/prev button,
1714							 * meanwhile the timebox[0].style.marginTop will return the right value which is after you clicking the
1715							 * next/prev button.
1716							 *
1717							 * What we should do:
1718							 * Replace timebox.css('marginTop') with timebox[0].style.marginTop.
1719							 */
1720							timeboxparent.trigger( 'scroll_element.xdsoft_scroller', [Math.abs( parseInt( timebox[0].style.marginTop, 10 ) / (height - pheight) )] );
1721							period = (period > 10) ? 10 : period - 10;
1722							if ( ! stop) {
1723								timer = setTimeout( arguments_callee4, v || period );
1724							}
1725						}(500));
1726						$( [options.ownerDocument.body, options.contentWindow] ).on(
1727							'touchend mouseup.xdsoft',
1728							function arguments_callee5() {
1729								clearTimeout( timer );
1730								stop = true;
1731								$( [options.ownerDocument.body, options.contentWindow] )
1732								.off( 'touchend mouseup.xdsoft', arguments_callee5 );
1733							}
1734						);
1735					}
1736				);
1737
1738			xchangeTimer = 0;
1739			// base handler - generating a calendar and timepicker
1740			datetimepicker
1741				.on(
1742					'xchange.xdsoft',
1743					function (event) {
1744						clearTimeout( xchangeTimer );
1745						xchangeTimer = setTimeout(
1746							function () {
1747
1748								if (_xdsoft_datetime.currentTime === undefined || _xdsoft_datetime.currentTime === null) {
1749									_xdsoft_datetime.currentTime = _xdsoft_datetime.now();
1750								}
1751
1752								var table   = '',
1753								start       = new Date( _xdsoft_datetime.currentTime.getFullYear(), _xdsoft_datetime.currentTime.getMonth(), 1, 12, 0, 0 ),
1754								i           = 0,
1755								j,
1756								today       = _xdsoft_datetime.now(),
1757								maxDate     = false,
1758								minDate     = false,
1759								minDateTime = false,
1760								hDate,
1761								day,
1762								d,
1763								y,
1764								m,
1765								w,
1766								classes     = [],
1767								customDateSettings,
1768								newRow      = true,
1769								time        = '',
1770								h,
1771								line_time,
1772								description;
1773
1774								while (start.getDay() !== options.dayOfWeekStart) {
1775									start.setDate( start.getDate() - 1 );
1776								}
1777
1778								table += '<table><thead><tr>';
1779
1780								if (options.weeks) {
1781									table += '<th></th>';
1782								}
1783
1784								for (j = 0; j < 7; j += 1) {
1785									table += '<th>' + options.i18n[globalLocale].dayOfWeekShort[(j + options.dayOfWeekStart) % 7] + '</th>';
1786								}
1787
1788								table += '</tr></thead>';
1789								table += '<tbody>';
1790
1791								if (options.maxDate !== false) {
1792									maxDate = _xdsoft_datetime.strToDate( options.maxDate );
1793									maxDate = new Date( maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate(), 23, 59, 59, 999 );
1794								}
1795
1796								if (options.minDate !== false) {
1797									minDate = _xdsoft_datetime.strToDate( options.minDate );
1798									minDate = new Date( minDate.getFullYear(), minDate.getMonth(), minDate.getDate() );
1799								}
1800
1801								if (options.minDateTime !== false) {
1802									minDateTime = _xdsoft_datetime.strToDate( options.minDateTime );
1803									minDateTime = new Date( minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), minDateTime.getHours(), minDateTime.getMinutes(), minDateTime.getSeconds() );
1804								}
1805
1806								while (i < _xdsoft_datetime.currentTime.countDaysInMonth() || start.getDay() !== options.dayOfWeekStart || _xdsoft_datetime.currentTime.getMonth() === start.getMonth()) {
1807									classes = [];
1808									i      += 1;
1809
1810									day         = start.getDay();
1811									d           = start.getDate();
1812									y           = start.getFullYear();
1813									m           = start.getMonth();
1814									w           = _xdsoft_datetime.getWeekOfYear( start );
1815									description = '';
1816
1817									classes.push( 'xdsoft_date' );
1818
1819									if (options.beforeShowDay && $.isFunction( options.beforeShowDay.call )) {
1820										customDateSettings = options.beforeShowDay.call( datetimepicker, start );
1821									} else {
1822										customDateSettings = null;
1823									}
1824
1825									if (options.allowDateRe && Object.prototype.toString.call( options.allowDateRe ) === "[object RegExp]") {
1826										if ( ! options.allowDateRe.test( dateHelper.formatDate( start, options.formatDate ) )) {
1827											classes.push( 'xdsoft_disabled' );
1828										}
1829									}
1830
1831									if (options.allowDates && options.allowDates.length > 0) {
1832										if (options.allowDates.indexOf( dateHelper.formatDate( start, options.formatDate ) ) === -1) {
1833											classes.push( 'xdsoft_disabled' );
1834										}
1835									}
1836
1837									if ((maxDate !== false && start > maxDate) || (minDateTime !== false && start < minDateTime) || (minDate !== false && start < minDate) || (customDateSettings && customDateSettings[0] === false)) {
1838										classes.push( 'xdsoft_disabled' );
1839									}
1840
1841									if (options.disabledDates.indexOf( dateHelper.formatDate( start, options.formatDate ) ) !== -1) {
1842										classes.push( 'xdsoft_disabled' );
1843									}
1844
1845									if (options.disabledWeekDays.indexOf( day ) !== -1) {
1846										classes.push( 'xdsoft_disabled' );
1847									}
1848
1849									if (input.is( '[disabled]' )) {
1850										classes.push( 'xdsoft_disabled' );
1851									}
1852
1853									if (customDateSettings && customDateSettings[1] !== "") {
1854										classes.push( customDateSettings[1] );
1855									}
1856
1857									if (_xdsoft_datetime.currentTime.getMonth() !== m) {
1858										classes.push( 'xdsoft_other_month' );
1859									}
1860
1861									if ((options.defaultSelect || datetimepicker.data( 'changed' )) && dateHelper.formatDate( _xdsoft_datetime.currentTime, options.formatDate ) === dateHelper.formatDate( start, options.formatDate )) {
1862										classes.push( 'xdsoft_current' );
1863									}
1864
1865									if (dateHelper.formatDate( today, options.formatDate ) === dateHelper.formatDate( start, options.formatDate )) {
1866										classes.push( 'xdsoft_today' );
1867									}
1868
1869									if (start.getDay() === 0 || start.getDay() === 6 || options.weekends.indexOf( dateHelper.formatDate( start, options.formatDate ) ) !== -1) {
1870										classes.push( 'xdsoft_weekend' );
1871									}
1872
1873									if (options.highlightedDates[dateHelper.formatDate( start, options.formatDate )] !== undefined) {
1874										hDate = options.highlightedDates[dateHelper.formatDate( start, options.formatDate )];
1875										classes.push( hDate.style === undefined ? 'xdsoft_highlighted_default' : hDate.style );
vendor: 6,892 bytes, lines 1876-2033
1876										description = hDate.desc === undefined ? '' : hDate.desc;
1877									}
1878
1879									if (options.beforeShowDay && $.isFunction( options.beforeShowDay )) {
1880										classes.push( options.beforeShowDay( start ) );
1881									}
1882
1883									if (newRow) {
1884										table += '<tr>';
1885										newRow = false;
1886										if (options.weeks) {
1887											table += '<th>' + w + '</th>';
1888										}
1889									}
1890
1891									table += '<td data-date="' + d + '" data-month="' + m + '" data-year="' + y + '"' + ' class="xdsoft_date xdsoft_day_of_week' + start.getDay() + ' ' + classes.join( ' ' ) + '" title="' + description + '">' +
1892									'<div>' + d + '</div>' +
1893									'</td>';
1894
1895									if (start.getDay() === options.dayOfWeekStartPrev) {
1896										table += '</tr>';
1897										newRow = true;
1898									}
1899
1900									start.setDate( d + 1 );
1901								}
1902								table += '</tbody></table>';
1903
1904								calendar.html( table );
1905
1906								month_picker.find( '.xdsoft_label span' ).eq( 0 ).text( options.i18n[globalLocale].months[_xdsoft_datetime.currentTime.getMonth()] );
1907								month_picker.find( '.xdsoft_label span' ).eq( 1 ).text( _xdsoft_datetime.currentTime.getFullYear() + options.yearOffset );
1908
1909								// generate timebox
1910								time = '';
1911								h    = '';
1912								m    = '';
1913
1914								line_time = function line_time(h, m) {
1915									var now          = _xdsoft_datetime.now(), optionDateTime, current_time,
1916									isALlowTimesInit = options.allowTimes && $.isArray( options.allowTimes ) && options.allowTimes.length;
1917									now.setHours( h );
1918									h = parseInt( now.getHours(), 10 );
1919									now.setMinutes( m );
1920									m              = parseInt( now.getMinutes(), 10 );
1921									optionDateTime = new Date( _xdsoft_datetime.currentTime );
1922									optionDateTime.setHours( h );
1923									optionDateTime.setMinutes( m );
1924									classes = [];
1925									if ((options.minDateTime !== false && options.minDateTime > optionDateTime) || (options.maxTime !== false && _xdsoft_datetime.strtotime( options.maxTime ).getTime() < now.getTime()) || (options.minTime !== false && _xdsoft_datetime.strtotime( options.minTime ).getTime() > now.getTime())) {
1926										classes.push( 'xdsoft_disabled' );
1927									} else if ((options.minDateTime !== false && options.minDateTime > optionDateTime) || ((options.disabledMinTime !== false && now.getTime() > _xdsoft_datetime.strtotime( options.disabledMinTime ).getTime()) && (options.disabledMaxTime !== false && now.getTime() < _xdsoft_datetime.strtotime( options.disabledMaxTime ).getTime()))) {
1928										classes.push( 'xdsoft_disabled' );
1929									} else if (input.is( '[disabled]' )) {
1930										classes.push( 'xdsoft_disabled' );
1931									}
1932
1933									current_time = new Date( _xdsoft_datetime.currentTime );
1934									current_time.setHours( parseInt( _xdsoft_datetime.currentTime.getHours(), 10 ) );
1935
1936									if ( ! isALlowTimesInit) {
1937										current_time.setMinutes( Math[options.roundTime]( _xdsoft_datetime.currentTime.getMinutes() / options.step ) * options.step );
1938									}
1939
1940									if ((options.initTime || options.defaultSelect || datetimepicker.data( 'changed' )) && current_time.getHours() === parseInt( h, 10 ) && (( ! isALlowTimesInit && options.step > 59) || current_time.getMinutes() === parseInt( m, 10 ))) {
1941										if (options.defaultSelect || datetimepicker.data( 'changed' )) {
1942											classes.push( 'xdsoft_current' );
1943										} else if (options.initTime) {
1944											classes.push( 'xdsoft_init_time' );
1945										}
1946									}
1947									if (parseInt( today.getHours(), 10 ) === parseInt( h, 10 ) && parseInt( today.getMinutes(), 10 ) === parseInt( m, 10 )) {
1948										classes.push( 'xdsoft_today' );
1949									}
1950									time += '<div class="xdsoft_time ' + classes.join( ' ' ) + '" data-hour="' + h + '" data-minute="' + m + '">' + dateHelper.formatDate( now, options.formatTime ) + '</div>';
1951								};
1952
1953								if ( ! options.allowTimes || ! $.isArray( options.allowTimes ) || ! options.allowTimes.length) {
1954									for (i = 0, j = 0; i < (options.hours12 ? 12 : 24); i += 1) {
1955										for (j = 0; j < 60; j += options.step) {
1956											h = (i < 10 ? '0' : '') + i;
1957											m = (j < 10 ? '0' : '') + j;
1958											line_time( h, m );
1959										}
1960									}
1961								} else {
1962									for (i = 0; i < options.allowTimes.length; i += 1) {
1963										h = _xdsoft_datetime.strtotime( options.allowTimes[i] ).getHours();
1964										m = _xdsoft_datetime.strtotime( options.allowTimes[i] ).getMinutes();
1965										line_time( h, m );
1966									}
1967								}
1968
1969								timebox.html( time );
1970
1971								opt = '';
1972
1973								for (i = parseInt( options.yearStart, 10 ); i <= parseInt( options.yearEnd, 10 ); i += 1) {
1974									opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getFullYear() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + (i + options.yearOffset) + '</div>';
1975								}
1976								yearselect.children().eq( 0 )
1977								.html( opt );
1978
1979								for (i = parseInt( options.monthStart, 10 ), opt = ''; i <= parseInt( options.monthEnd, 10 ); i += 1) {
1980									opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getMonth() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + options.i18n[globalLocale].months[i] + '</div>';
1981								}
1982								monthselect.children().eq( 0 ).html( opt );
1983								$( datetimepicker )
1984								.trigger( 'generate.xdsoft' );
1985							},
1986							10
1987						);
1988						event.stopPropagation();
1989					}
1990				)
1991				.on(
1992					'afterOpen.xdsoft',
1993					function () {
1994						if (options.timepicker) {
1995							var classType, pheight, height, top;
1996							if (timebox.find( '.xdsoft_current' ).length) {
1997								classType = '.xdsoft_current';
1998							} else if (timebox.find( '.xdsoft_init_time' ).length) {
1999								classType = '.xdsoft_init_time';
2000							}
2001							if (classType) {
2002								pheight = timeboxparent[0].clientHeight;
2003								height  = timebox[0].offsetHeight;
2004								top     = timebox.find( classType ).index() * options.timeHeightInTimePicker + 1;
2005								if ((height - pheight) < top) {
2006									top = height - pheight;
2007								}
2008								timeboxparent.trigger( 'scroll_element.xdsoft_scroller', [parseInt( top, 10 ) / (height - pheight)] );
2009							} else {
2010								timeboxparent.trigger( 'scroll_element.xdsoft_scroller', [0] );
2011							}
2012						}
2013					}
2014				);
2015
2016			timerclick = 0;
2017			calendar
2018				.on(
2019					'touchend click.xdsoft',
2020					'td',
2021					function (xdevent) {
2022						xdevent.stopPropagation();  // Prevents closing of Pop-ups, Modals and Flyouts in Bootstrap
2023						timerclick += 1;
2024						var $this   = $( this ),
2025						currentTime = _xdsoft_datetime.currentTime;
2026
2027						if (currentTime === undefined || currentTime === null) {
2028							_xdsoft_datetime.currentTime = _xdsoft_datetime.now();
2029							currentTime                  = _xdsoft_datetime.currentTime;
2030						}
2031
2032						if ($this.hasClass( 'xdsoft_disabled' )) {
2033							return false;
vendor: 23,398 bytes, lines 2034-2790
2034						}
2035
2036						currentTime.setDate( 1 );
2037						currentTime.setFullYear( $this.data( 'year' ) );
2038						currentTime.setMonth( $this.data( 'month' ) );
2039						currentTime.setDate( $this.data( 'date' ) );
2040
2041						datetimepicker.trigger( 'select.xdsoft', [currentTime] );
2042
2043						input.val( _xdsoft_datetime.str() );
2044
2045						if (options.onSelectDate &&	$.isFunction( options.onSelectDate )) {
2046							options.onSelectDate.call( datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data( 'input' ), xdevent );
2047						}
2048
2049						datetimepicker.data( 'changed', true );
2050						datetimepicker.trigger( 'xchange.xdsoft' );
2051						datetimepicker.trigger( 'changedatetime.xdsoft' );
2052						if ((timerclick > 1 || (options.closeOnDateSelect === true || (options.closeOnDateSelect === false && ! options.timepicker))) && ! options.inline) {
2053							datetimepicker.trigger( 'close.xdsoft' );
2054						}
2055						setTimeout(
2056							function () {
2057								timerclick = 0;
2058							},
2059							200
2060						);
2061					}
2062				);
2063
2064			timebox
2065				.on(
2066					'touchstart',
2067					'div',
2068					function (xdevent) {
2069						this.touchMoved = false;
2070					}
2071				)
2072				.on( 'touchmove', 'div', handleTouchMoved )
2073				.on(
2074					'touchend click.xdsoft',
2075					'div',
2076					function (xdevent) {
2077						if ( ! this.touchMoved) {
2078							xdevent.stopPropagation();
2079							var $this   = $( this ),
2080							currentTime = _xdsoft_datetime.currentTime;
2081
2082							if (currentTime === undefined || currentTime === null) {
2083								_xdsoft_datetime.currentTime = _xdsoft_datetime.now();
2084								currentTime                  = _xdsoft_datetime.currentTime;
2085							}
2086
2087							if ($this.hasClass( 'xdsoft_disabled' )) {
2088								return false;
2089							}
2090							currentTime.setHours( $this.data( 'hour' ) );
2091							currentTime.setMinutes( $this.data( 'minute' ) );
2092							datetimepicker.trigger( 'select.xdsoft', [currentTime] );
2093
2094							datetimepicker.data( 'input' ).val( _xdsoft_datetime.str() );
2095
2096							if (options.onSelectTime && $.isFunction( options.onSelectTime )) {
2097								options.onSelectTime.call( datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data( 'input' ), xdevent );
2098							}
2099							datetimepicker.data( 'changed', true );
2100							datetimepicker.trigger( 'xchange.xdsoft' );
2101							datetimepicker.trigger( 'changedatetime.xdsoft' );
2102							if (options.inline !== true && options.closeOnTimeSelect === true) {
2103								datetimepicker.trigger( 'close.xdsoft' );
2104							}
2105						}
2106					}
2107				);
2108
2109			datepicker
2110				.on(
2111					'mousewheel.xdsoft',
2112					function (event) {
2113						if ( ! options.scrollMonth) {
2114							return true;
2115						}
2116						if (event.deltaY < 0) {
2117							_xdsoft_datetime.nextMonth();
2118						} else {
2119							_xdsoft_datetime.prevMonth();
2120						}
2121						return false;
2122					}
2123				);
2124
2125			input
2126				.on(
2127					'mousewheel.xdsoft',
2128					function (event) {
2129						if ( ! options.scrollInput) {
2130							return true;
2131						}
2132						if ( ! options.datepicker && options.timepicker) {
2133							current_time_index = timebox.find( '.xdsoft_current' ).length ? timebox.find( '.xdsoft_current' ).eq( 0 ).index() : 0;
2134							if (current_time_index + event.deltaY >= 0 && current_time_index + event.deltaY < timebox.children().length) {
2135								current_time_index += event.deltaY;
2136							}
2137							if (timebox.children().eq( current_time_index ).length) {
2138								timebox.children().eq( current_time_index ).trigger( 'mousedown' );
2139							}
2140							return false;
2141						}
2142						if (options.datepicker && ! options.timepicker) {
2143							datepicker.trigger( event, [event.deltaY, event.deltaX, event.deltaY] );
2144							if (input.val) {
2145								input.val( _xdsoft_datetime.str() );
2146							}
2147							datetimepicker.trigger( 'changedatetime.xdsoft' );
2148							return false;
2149						}
2150					}
2151				);
2152
2153			datetimepicker
2154				.on(
2155					'changedatetime.xdsoft',
2156					function (event) {
2157						if (options.onChangeDateTime && $.isFunction( options.onChangeDateTime )) {
2158							var $input = datetimepicker.data( 'input' );
2159							options.onChangeDateTime.call( datetimepicker, _xdsoft_datetime.currentTime, $input, event );
2160							delete options.value;
2161							$input.trigger( 'change' );
2162						}
2163					}
2164				)
2165				.on(
2166					'generate.xdsoft',
2167					function () {
2168						if (options.onGenerate && $.isFunction( options.onGenerate )) {
2169							options.onGenerate.call( datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data( 'input' ) );
2170						}
2171						if (triggerAfterOpen) {
2172							datetimepicker.trigger( 'afterOpen.xdsoft' );
2173							triggerAfterOpen = false;
2174						}
2175					}
2176				)
2177				.on(
2178					'click.xdsoft',
2179					function (xdevent) {
2180						xdevent.stopPropagation();
2181					}
2182				);
2183
2184			current_time_index = 0;
2185
2186			/**
2187			 * Runs the callback for each of the specified node's ancestors.
2188			 *
2189			 * Return FALSE from the callback to stop ascending.
2190			 *
2191			 * @param {DOMNode} node
2192			 * @param {Function} callback
2193			 * @returns {undefined}
2194			 */
2195			forEachAncestorOf = function (node, callback) {
2196				do {
2197					node = node.parentNode;
2198
2199					if ( ! node || callback( node ) === false) {
2200						break;
2201					}
2202				} while (node.nodeName !== 'HTML');
2203			};
2204
2205			/**
2206			 * Sets the position of the picker.
2207			 *
2208			 * @returns {undefined}
2209			 */
2210			setPos = function () {
2211				var dateInputOffset,
2212					dateInputElem,
2213					verticalPosition,
2214					left,
2215					position,
2216					datetimepickerElem,
2217					dateInputHasFixedAncestor,
2218					$dateInput,
2219					windowWidth,
2220					verticalAnchorEdge,
2221					datetimepickerCss,
2222					windowHeight,
2223					windowScrollTop;
2224
2225				$dateInput      = datetimepicker.data( 'input' );
2226				dateInputOffset = $dateInput.offset();
2227				dateInputElem   = $dateInput[0];
2228
2229				verticalAnchorEdge = 'top';
2230				verticalPosition   = (dateInputOffset.top + dateInputElem.offsetHeight) - 1;
2231				left               = dateInputOffset.left;
2232				position           = "absolute";
2233
2234				windowWidth     = $( options.contentWindow ).width();
2235				windowHeight    = $( options.contentWindow ).height();
2236				windowScrollTop = $( options.contentWindow ).scrollTop();
2237
2238				if ((options.ownerDocument.documentElement.clientWidth - dateInputOffset.left) < datepicker.parent().outerWidth( true )) {
2239					var diff = datepicker.parent().outerWidth( true ) - dateInputElem.offsetWidth;
2240					left     = left - diff;
2241				}
2242
2243				if ($dateInput.parent().css( 'direction' ) === 'rtl') {
2244					left -= (datetimepicker.outerWidth() - $dateInput.outerWidth());
2245				}
2246
2247				if (options.fixed) {
2248					verticalPosition -= windowScrollTop;
2249					left             -= $( options.contentWindow ).scrollLeft();
2250					position          = "fixed";
2251				} else {
2252					dateInputHasFixedAncestor = false;
2253
2254					forEachAncestorOf(
2255						dateInputElem,
2256						function (ancestorNode) {
2257							if (ancestorNode === null) {
2258								return false;
2259							}
2260
2261							if (options.contentWindow.getComputedStyle( ancestorNode ).getPropertyValue( 'position' ) === 'fixed') {
2262								dateInputHasFixedAncestor = true;
2263								return false;
2264							}
2265						}
2266					);
2267
2268					if (dateInputHasFixedAncestor) {
2269						position = 'fixed';
2270
2271						//If the picker won't fit entirely within the viewport then display it above the date input.
2272						if (verticalPosition + datetimepicker.outerHeight() > windowHeight + windowScrollTop) {
2273							verticalAnchorEdge = 'bottom';
2274							verticalPosition   = (windowHeight + windowScrollTop) - dateInputOffset.top;
2275						} else {
2276							verticalPosition -= windowScrollTop;
2277						}
2278					} else {
2279						if (verticalPosition + datetimepicker[0].offsetHeight > windowHeight + windowScrollTop) {
2280							verticalPosition = dateInputOffset.top - datetimepicker[0].offsetHeight + 1;
2281						}
2282					}
2283
2284					if (verticalPosition < 0) {
2285						verticalPosition = 0;
2286					}
2287
2288					if (left + dateInputElem.offsetWidth > windowWidth) {
2289						left = windowWidth - dateInputElem.offsetWidth;
2290					}
2291				}
2292
2293				datetimepickerElem = datetimepicker[0];
2294
2295				forEachAncestorOf(
2296					datetimepickerElem,
2297					function (ancestorNode) {
2298						var ancestorNodePosition;
2299
2300						ancestorNodePosition = options.contentWindow.getComputedStyle( ancestorNode ).getPropertyValue( 'position' );
2301
2302						if (ancestorNodePosition === 'relative' && windowWidth >= ancestorNode.offsetWidth) {
2303							left = left - ((windowWidth - ancestorNode.offsetWidth) / 2);
2304							return false;
2305						}
2306					}
2307				);
2308
2309				datetimepickerCss = {
2310					position: position,
2311					left: left,
2312					top: '',  //Initialize to prevent previous values interfering with new ones.
2313					bottom: ''  //Initialize to prevent previous values interfering with new ones.
2314				};
2315
2316				datetimepickerCss[verticalAnchorEdge] = verticalPosition;
2317
2318				datetimepicker.css( datetimepickerCss );
2319			};
2320
2321			datetimepicker
2322				.on(
2323					'open.xdsoft',
2324					function (event) {
2325						var onShow = true;
2326						if (options.onShow && $.isFunction( options.onShow )) {
2327							onShow = options.onShow.call( datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data( 'input' ), event );
2328						}
2329						if (onShow !== false) {
2330							datetimepicker.show();
2331							setPos();
2332							$( options.contentWindow )
2333							.off( 'resize.xdsoft', setPos )
2334							.on( 'resize.xdsoft', setPos );
2335
2336							if (options.closeOnWithoutClick) {
2337								$( [options.ownerDocument.body, options.contentWindow] ).on(
2338									'touchstart mousedown.xdsoft',
2339									function arguments_callee6() {
2340										datetimepicker.trigger( 'close.xdsoft' );
2341										$( [options.ownerDocument.body, options.contentWindow] ).off( 'touchstart mousedown.xdsoft', arguments_callee6 );
2342									}
2343								);
2344							}
2345						}
2346					}
2347				)
2348				.on(
2349					'close.xdsoft',
2350					function (event) {
2351						var onClose = true;
2352						month_picker
2353						.find( '.xdsoft_month,.xdsoft_year' )
2354						.find( '.xdsoft_select' )
2355						.hide();
2356						if (options.onClose && $.isFunction( options.onClose )) {
2357							onClose = options.onClose.call( datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data( 'input' ), event );
2358						}
2359						if (onClose !== false && ! options.opened && ! options.inline) {
2360							datetimepicker.hide();
2361						}
2362						event.stopPropagation();
2363					}
2364				)
2365				.on(
2366					'toggle.xdsoft',
2367					function () {
2368						if (datetimepicker.is( ':visible' )) {
2369							datetimepicker.trigger( 'close.xdsoft' );
2370						} else {
2371							datetimepicker.trigger( 'open.xdsoft' );
2372						}
2373					}
2374				)
2375				.data( 'input', input );
2376
2377			timer = 0;
2378
2379			datetimepicker.data( 'xdsoft_datetime', _xdsoft_datetime );
2380			datetimepicker.setOptions( options );
2381
2382			function getCurrentValue() {
2383				var ct = false, time;
2384
2385				if (options.startDate) {
2386					ct = _xdsoft_datetime.strToDate( options.startDate );
2387				} else {
2388					ct = options.value || ((input && input.val && input.val()) ? input.val() : '');
2389					if (ct) {
2390						ct = _xdsoft_datetime.strToDateTime( ct );
2391						if (options.yearOffset) {
2392							ct = new Date( ct.getFullYear() - options.yearOffset, ct.getMonth(), ct.getDate(), ct.getHours(), ct.getMinutes(), ct.getSeconds(), ct.getMilliseconds() );
2393						}
2394					} else if (options.defaultDate) {
2395						ct = _xdsoft_datetime.strToDateTime( options.defaultDate );
2396						if (options.defaultTime) {
2397							time = _xdsoft_datetime.strtotime( options.defaultTime );
2398							ct.setHours( time.getHours() );
2399							ct.setMinutes( time.getMinutes() );
2400						}
2401					}
2402				}
2403
2404				if (ct && _xdsoft_datetime.isValidDate( ct )) {
2405					datetimepicker.data( 'changed', true );
2406				} else {
2407					ct = '';
2408				}
2409
2410				return ct || 0;
2411			}
2412
2413			function setMask(options) {
2414
2415				var isValidValue = function (mask, value) {
2416						var reg = mask
2417							.replace( /([\[\]\/\{\}\(\)\-\.\+]{1})/g, '\\$1' )
2418							.replace( /_/g, '{digit+}' )
2419							.replace( /([0-9]{1})/g, '{digit$1}' )
2420							.replace( /\{digit([0-9]{1})\}/g, '[0-$1_]{1}' )
2421							.replace( /\{digit[\+]\}/g, '[0-9_]{1}' );
2422						return (new RegExp( reg )).test( value );
2423				},
2424					getCaretPos  = function (input) {
2425						try {
2426							if (options.ownerDocument.selection && options.ownerDocument.selection.createRange) {
2427								var range = options.ownerDocument.selection.createRange();
2428								return range.getBookmark().charCodeAt( 2 ) - 2;
2429							}
2430							if (input.setSelectionRange) {
2431								return input.selectionStart;
2432							}
2433						} catch (e) {
2434							return 0;
2435						}
2436					},
2437					setCaretPos  = function (node, pos) {
2438						node = (typeof node === "string" || node instanceof String) ? options.ownerDocument.getElementById( node ) : node;
2439						if ( ! node) {
2440							return false;
2441						}
2442						if (node.createTextRange) {
2443							var textRange = node.createTextRange();
2444							textRange.collapse( true );
2445							textRange.moveEnd( 'character', pos );
2446							textRange.moveStart( 'character', pos );
2447							textRange.select();
2448							return true;
2449						}
2450						if (node.setSelectionRange) {
2451							node.setSelectionRange( pos, pos );
2452							return true;
2453						}
2454						return false;
2455					};
2456
2457				if (options.mask) {
2458					input.off( 'keydown.xdsoft' );
2459				}
2460
2461				if (options.mask === true) {
2462					if (dateHelper.formatMask) {
2463						options.mask = dateHelper.formatMask( options.format )
2464					} else {
2465						options.mask = options.format
2466							.replace( /Y/g, '9999' )
2467							.replace( /F/g, '9999' )
2468							.replace( /m/g, '19' )
2469							.replace( /d/g, '39' )
2470							.replace( /H/g, '29' )
2471							.replace( /i/g, '59' )
2472							.replace( /s/g, '59' );
2473					}
2474				}
2475
2476				if ($.type( options.mask ) === 'string') {
2477					if ( ! isValidValue( options.mask, input.val() )) {
2478						input.val( options.mask.replace( /[0-9]/g, '_' ) );
2479						setCaretPos( input[0], 0 );
2480					}
2481
2482					input.on(
2483						'paste.xdsoft',
2484						function (event) {
2485							// couple options here
2486							// 1. return false - tell them they can't paste
2487							// 2. insert over current characters - minimal validation
2488							// 3. full fledged parsing and validation
2489							// let's go option 2 for now
2490
2491							// fires multiple times for some reason
2492
2493							// https://stackoverflow.com/a/30496488/1366033
2494							var clipboardData = event.clipboardData || event.originalEvent.clipboardData || window.clipboardData,
2495							pastedData        = clipboardData.getData( 'text' ),
2496							val               = this.value,
2497							pos               = this.selectionStart
2498
2499							var valueBeforeCursor = val.substr( 0, pos );
2500							var valueAfterPaste   = val.substr( pos + pastedData.length );
2501
2502							val  = valueBeforeCursor + pastedData + valueAfterPaste;
2503							pos += pastedData.length;
2504
2505							if (isValidValue( options.mask, val )) {
2506								this.value = val;
2507								setCaretPos( this, pos );
2508							} else if ($.trim( val ) === '') {
2509								this.value = options.mask.replace( /[0-9]/g, '_' );
2510							} else {
2511								input.trigger( 'error_input.xdsoft' );
2512							}
2513
2514							event.preventDefault();
2515							return false;
2516						}
2517					);
2518
2519					input.on(
2520						'keydown.xdsoft',
2521						function (event) {
2522							var val = this.value,
2523							key     = event.which,
2524							pos     = this.selectionStart,
2525							selEnd  = this.selectionEnd,
2526							hasSel  = pos !== selEnd,
2527							digit;
2528
2529							// only alow these characters
2530							if (((key >= KEY0 && key <= KEY9) ||
2531							(key >= _KEY0 && key <= _KEY9)) ||
2532							(key === BACKSPACE || key === DEL)) {
2533
2534									// get char to insert which is new character or placeholder ('_')
2535									digit = (key === BACKSPACE || key === DEL) ? '_' :
2536								String.fromCharCode( (_KEY0 <= key && key <= _KEY9) ? key - KEY0 : key );
2537
2538									// we're deleting something, we're not at the start, and have normal cursor, move back one
2539									// if we have a selection length, cursor actually sits behind deletable char, not in front
2540								if (key === BACKSPACE && pos && ! hasSel) {
2541									pos -= 1;
2542								}
2543
2544								// don't stop on a separator, continue whatever direction you were going
2545								//   value char - keep incrementing position while on separator char and we still have room
2546								//   del char   - keep decrementing position while on separator char and we still have room
2547								while (true) {
2548									var maskValueAtCurPos        = options.mask.substr( pos, 1 );
2549									var posShorterThanMaskLength = pos < options.mask.length;
2550									var posGreaterThanZero       = pos > 0;
2551									var notNumberOrPlaceholder   = /[^0-9_]/;
2552									var curPosOnSep              = notNumberOrPlaceholder.test( maskValueAtCurPos );
2553									var continueMovingPosition   = curPosOnSep && posShorterThanMaskLength && posGreaterThanZero
2554
2555									// if we hit a real char, stay where we are
2556									if ( ! continueMovingPosition) {
2557										break;
2558									}
2559
2560									// hitting backspace in a selection, you can possibly go back any further - go forward
2561									pos += (key === BACKSPACE && ! hasSel) ? -1 : 1;
2562
2563								}
2564
2565								if (hasSel) {
2566									// pos might have moved so re-calc length
2567									var selLength = selEnd - pos
2568
2569									// if we have a selection length we will wipe out entire selection and replace with default template for that range
2570									var defaultBlank                     = options.mask.replace( /[0-9]/g, '_' );
2571									var defaultBlankSelectionReplacement = defaultBlank.substr( pos, selLength );
2572									var selReplacementRemainder          = defaultBlankSelectionReplacement.substr( 1 ) // might be empty
2573
2574									var valueBeforeSel      = val.substr( 0, pos );
2575									var insertChars         = digit + selReplacementRemainder;
2576									var charsAfterSelection = val.substr( pos + selLength );
2577
2578									val = valueBeforeSel + insertChars + charsAfterSelection
2579
2580								} else {
2581									var valueBeforeCursor  = val.substr( 0, pos );
2582									var insertChar         = digit;
2583									var valueAfterNextChar = val.substr( pos + 1 );
2584
2585									val = valueBeforeCursor + insertChar + valueAfterNextChar
2586								}
2587
2588								if ($.trim( val ) === '') {
2589									// if empty, set to default
2590									val = defaultBlank
2591								} else {
2592									// if at the last character don't need to do anything
2593									if (pos === options.mask.length) {
2594										event.preventDefault();
2595										return false;
2596									}
2597								}
2598
2599								// resume cursor location
2600								pos += (key === BACKSPACE) ? 0 : 1;
2601								// don't stop on a separator, continue whatever direction you were going
2602								while (/[^0-9_]/.test( options.mask.substr( pos, 1 ) ) && pos < options.mask.length && pos > 0) {
2603									pos += (key === BACKSPACE) ? 0 : 1;
2604								}
2605
2606								if (isValidValue( options.mask, val )) {
2607									this.value = val;
2608									setCaretPos( this, pos );
2609								} else if ($.trim( val ) === '') {
2610									this.value = options.mask.replace( /[0-9]/g, '_' );
2611								} else {
2612									input.trigger( 'error_input.xdsoft' );
2613								}
2614							} else {
2615								if (([AKEY, CKEY, VKEY, ZKEY, YKEY].indexOf( key ) !== -1 && ctrlDown) || [ESC, ARROWUP, ARROWDOWN, ARROWLEFT, ARROWRIGHT, F5, CTRLKEY, TAB, ENTER].indexOf( key ) !== -1) {
2616									return true;
2617								}
2618							}
2619
2620							event.preventDefault();
2621							return false;
2622						}
2623					);
2624				}
2625			}
2626
2627			_xdsoft_datetime.setCurrentTime( getCurrentValue() );
2628
2629			input
2630				.data( 'xdsoft_datetimepicker', datetimepicker )
2631				.on(
2632					'open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart',
2633					function () {
2634						if (input.is( ':disabled' ) || (input.data( 'xdsoft_datetimepicker' ).is( ':visible' ) && options.closeOnInputClick)) {
2635							return;
2636						}
2637						if ( ! options.openOnFocus) {
2638							return;
2639						}
2640						clearTimeout( timer );
2641						timer = setTimeout(
2642							function () {
2643								if (input.is( ':disabled' )) {
2644									return;
2645								}
2646
2647								triggerAfterOpen = true;
2648								_xdsoft_datetime.setCurrentTime( getCurrentValue(), true );
2649								if (options.mask) {
2650									setMask( options );
2651								}
2652								datetimepicker.trigger( 'open.xdsoft' );
2653							},
2654							100
2655						);
2656					}
2657				)
2658				.on(
2659					'keydown.xdsoft',
2660					function (event) {
2661						var elementSelector,
2662						key = event.which;
2663						if ([ENTER].indexOf( key ) !== -1 && options.enterLikeTab) {
2664							elementSelector = $( "input:visible,textarea:visible,button:visible,a:visible" );
2665							datetimepicker.trigger( 'close.xdsoft' );
2666							elementSelector.eq( elementSelector.index( this ) + 1 ).focus();
2667							return false;
2668						}
2669						if ([TAB].indexOf( key ) !== -1) {
2670							datetimepicker.trigger( 'close.xdsoft' );
2671							return true;
2672						}
2673					}
2674				)
2675				.on(
2676					'blur.xdsoft',
2677					function () {
2678						datetimepicker.trigger( 'close.xdsoft' );
2679					}
2680				);
2681		};
2682		destroyDateTimePicker = function (input) {
2683			var datetimepicker = input.data( 'xdsoft_datetimepicker' );
2684			if (datetimepicker) {
2685				datetimepicker.data( 'xdsoft_datetime', null );
2686				datetimepicker.remove();
2687				input
2688					.data( 'xdsoft_datetimepicker', null )
2689					.off( '.xdsoft' );
2690				$( options.contentWindow ).off( 'resize.xdsoft' );
2691				$( [options.contentWindow, options.ownerDocument.body] ).off( 'mousedown.xdsoft touchstart' );
2692				if (input.unmousewheel) {
2693					input.unmousewheel();
2694				}
2695			}
2696		};
2697		$( options.ownerDocument )
2698			.off( 'keydown.xdsoftctrl keyup.xdsoftctrl' )
2699			.on(
2700				'keydown.xdsoftctrl',
2701				function (e) {
2702					if (e.keyCode === CTRLKEY) {
2703						ctrlDown = true;
2704					}
2705				}
2706			)
2707			.on(
2708				'keyup.xdsoftctrl',
2709				function (e) {
2710					if (e.keyCode === CTRLKEY) {
2711						ctrlDown = false;
2712					}
2713				}
2714			);
2715
2716		this.each(
2717			function () {
2718				var datetimepicker = $( this ).data( 'xdsoft_datetimepicker' ), $input;
2719				if (datetimepicker) {
2720					if ($.type( opt ) === 'string') {
2721						switch (opt) {
2722							case 'show':
2723								$( this ).select().focus();
2724								datetimepicker.trigger( 'open.xdsoft' );
2725								break;
2726							case 'hide':
2727								datetimepicker.trigger( 'close.xdsoft' );
2728								break;
2729							case 'toggle':
2730								datetimepicker.trigger( 'toggle.xdsoft' );
2731								break;
2732							case 'destroy':
2733								destroyDateTimePicker( $( this ) );
2734								break;
2735							case 'reset':
2736								this.value = this.defaultValue;
2737								if ( ! this.value || ! datetimepicker.data( 'xdsoft_datetime' ).isValidDate( dateHelper.parseDate( this.value, options.format ) )) {
2738									datetimepicker.data( 'changed', false );
2739								}
2740								datetimepicker.data( 'xdsoft_datetime' ).setCurrentTime( this.value );
2741								break;
2742							case 'validate':
2743								$input = datetimepicker.data( 'input' );
2744								$input.trigger( 'blur.xdsoft' );
2745								break;
2746							default:
2747								if (datetimepicker[opt] && $.isFunction( datetimepicker[opt] )) {
2748									result = datetimepicker[opt]( opt2 );
2749								}
2750						}
2751					} else {
2752						datetimepicker
2753						.setOptions( opt );
2754					}
2755					return 0;
2756				}
2757				if ($.type( opt ) !== 'string') {
2758					if ( ! options.lazyInit || options.open || options.inline) {
2759						createDateTimePicker( $( this ) );
2760					} else {
2761						lazyInit( $( this ) );
2762					}
2763				}
2764			}
2765		);
2766
2767		return result;
2768	};
2769
2770	$.fn.datetimepicker.defaults = default_options;
2771
2772	function HighlightedDate(date, desc, style) {
2773		"use strict";
2774		this.date  = date;
2775		this.desc  = desc;
2776		this.style = style;
2777	}
2778};
2779;(function (factory) {
2780	if ( typeof define === 'function' && define.amd ) {
2781		// AMD. Register as an anonymous module.
2782		define( ['jquery', 'jquery-mousewheel'], factory );
2783	} else if (typeof exports === 'object') {
2784		// Node/CommonJS style for Browserify
2785		module.exports = factory( require( 'jquery' ) );;
2786	} else {
2787		// Browser globals
2788		factory( jQuery );
2789	}
2790}(datetimepickerFactory));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.