891 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
		
			
		
	
	
			891 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
|  | /** | ||
|  |  * | ||
|  |  * Date picker | ||
|  |  * Author: Stefan Petre www.eyecon.ro | ||
|  |  *  | ||
|  |  * Dual licensed under the MIT and GPL licenses | ||
|  |  *  | ||
|  |  */ | ||
|  | (function ($) { | ||
|  | 	var DatePicker = function () { | ||
|  | 		var	ids = {}, | ||
|  | 			views = { | ||
|  | 				years: 'datepickerViewYears', | ||
|  | 				moths: 'datepickerViewMonths', | ||
|  | 				days: 'datepickerViewDays' | ||
|  | 			}, | ||
|  | 			tpl = { | ||
|  | 				wrapper: '<div class="datepicker"><div class="datepickerContainer"><table cellspacing="0" cellpadding="0"><tbody><tr></tr></tbody></table></div></div>', | ||
|  | 				head: [ | ||
|  | 					'<td>', | ||
|  | 					'<table cellspacing="0" cellpadding="0">', | ||
|  | 						'<thead>', | ||
|  | 							'<tr>', | ||
|  | 								'<th class="datepickerGoPrev"><a href="#"><span><%=prev%></span></a></th>', | ||
|  | 								'<th colspan="6" class="datepickerMonth"><a href="#"><span></span></a></th>', | ||
|  | 								'<th class="datepickerGoNext"><a href="#"><span><%=next%></span></a></th>', | ||
|  | 							'</tr>', | ||
|  | 							'<tr class="datepickerDoW">', | ||
|  | 								'<th><span><%=week%></span></th>', | ||
|  | 								'<th><span><%=day1%></span></th>', | ||
|  | 								'<th><span><%=day2%></span></th>', | ||
|  | 								'<th><span><%=day3%></span></th>', | ||
|  | 								'<th><span><%=day4%></span></th>', | ||
|  | 								'<th><span><%=day5%></span></th>', | ||
|  | 								'<th><span><%=day6%></span></th>', | ||
|  | 								'<th><span><%=day7%></span></th>', | ||
|  | 							'</tr>', | ||
|  | 						'</thead>', | ||
|  | 					'</table></td>' | ||
|  | 				], | ||
|  | 				space : '<td class="datepickerSpace"><div></div></td>', | ||
|  | 				days: [ | ||
|  | 					'<tbody class="datepickerDays">', | ||
|  | 						'<tr>', | ||
|  | 							'<th class="datepickerWeek"><a href="#"><span><%=weeks[0].week%></span></a></th>', | ||
|  | 							'<td class="<%=weeks[0].days[0].classname%>"><a href="#"><span><%=weeks[0].days[0].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[0].days[1].classname%>"><a href="#"><span><%=weeks[0].days[1].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[0].days[2].classname%>"><a href="#"><span><%=weeks[0].days[2].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[0].days[3].classname%>"><a href="#"><span><%=weeks[0].days[3].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[0].days[4].classname%>"><a href="#"><span><%=weeks[0].days[4].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[0].days[5].classname%>"><a href="#"><span><%=weeks[0].days[5].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[0].days[6].classname%>"><a href="#"><span><%=weeks[0].days[6].text%></span></a></td>', | ||
|  | 						'</tr>', | ||
|  | 						'<tr>', | ||
|  | 							'<th class="datepickerWeek"><a href="#"><span><%=weeks[1].week%></span></a></th>', | ||
|  | 							'<td class="<%=weeks[1].days[0].classname%>"><a href="#"><span><%=weeks[1].days[0].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[1].days[1].classname%>"><a href="#"><span><%=weeks[1].days[1].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[1].days[2].classname%>"><a href="#"><span><%=weeks[1].days[2].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[1].days[3].classname%>"><a href="#"><span><%=weeks[1].days[3].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[1].days[4].classname%>"><a href="#"><span><%=weeks[1].days[4].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[1].days[5].classname%>"><a href="#"><span><%=weeks[1].days[5].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[1].days[6].classname%>"><a href="#"><span><%=weeks[1].days[6].text%></span></a></td>', | ||
|  | 						'</tr>', | ||
|  | 						'<tr>', | ||
|  | 							'<th class="datepickerWeek"><a href="#"><span><%=weeks[2].week%></span></a></th>', | ||
|  | 							'<td class="<%=weeks[2].days[0].classname%>"><a href="#"><span><%=weeks[2].days[0].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[2].days[1].classname%>"><a href="#"><span><%=weeks[2].days[1].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[2].days[2].classname%>"><a href="#"><span><%=weeks[2].days[2].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[2].days[3].classname%>"><a href="#"><span><%=weeks[2].days[3].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[2].days[4].classname%>"><a href="#"><span><%=weeks[2].days[4].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[2].days[5].classname%>"><a href="#"><span><%=weeks[2].days[5].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[2].days[6].classname%>"><a href="#"><span><%=weeks[2].days[6].text%></span></a></td>', | ||
|  | 						'</tr>', | ||
|  | 						'<tr>', | ||
|  | 							'<th class="datepickerWeek"><a href="#"><span><%=weeks[3].week%></span></a></th>', | ||
|  | 							'<td class="<%=weeks[3].days[0].classname%>"><a href="#"><span><%=weeks[3].days[0].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[3].days[1].classname%>"><a href="#"><span><%=weeks[3].days[1].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[3].days[2].classname%>"><a href="#"><span><%=weeks[3].days[2].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[3].days[3].classname%>"><a href="#"><span><%=weeks[3].days[3].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[3].days[4].classname%>"><a href="#"><span><%=weeks[3].days[4].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[3].days[5].classname%>"><a href="#"><span><%=weeks[3].days[5].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[3].days[6].classname%>"><a href="#"><span><%=weeks[3].days[6].text%></span></a></td>', | ||
|  | 						'</tr>', | ||
|  | 						'<tr>', | ||
|  | 							'<th class="datepickerWeek"><a href="#"><span><%=weeks[4].week%></span></a></th>', | ||
|  | 							'<td class="<%=weeks[4].days[0].classname%>"><a href="#"><span><%=weeks[4].days[0].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[4].days[1].classname%>"><a href="#"><span><%=weeks[4].days[1].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[4].days[2].classname%>"><a href="#"><span><%=weeks[4].days[2].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[4].days[3].classname%>"><a href="#"><span><%=weeks[4].days[3].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[4].days[4].classname%>"><a href="#"><span><%=weeks[4].days[4].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[4].days[5].classname%>"><a href="#"><span><%=weeks[4].days[5].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[4].days[6].classname%>"><a href="#"><span><%=weeks[4].days[6].text%></span></a></td>', | ||
|  | 						'</tr>', | ||
|  | 						'<tr>', | ||
|  | 							'<th class="datepickerWeek"><a href="#"><span><%=weeks[5].week%></span></a></th>', | ||
|  | 							'<td class="<%=weeks[5].days[0].classname%>"><a href="#"><span><%=weeks[5].days[0].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[5].days[1].classname%>"><a href="#"><span><%=weeks[5].days[1].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[5].days[2].classname%>"><a href="#"><span><%=weeks[5].days[2].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[5].days[3].classname%>"><a href="#"><span><%=weeks[5].days[3].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[5].days[4].classname%>"><a href="#"><span><%=weeks[5].days[4].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[5].days[5].classname%>"><a href="#"><span><%=weeks[5].days[5].text%></span></a></td>', | ||
|  | 							'<td class="<%=weeks[5].days[6].classname%>"><a href="#"><span><%=weeks[5].days[6].text%></span></a></td>', | ||
|  | 						'</tr>', | ||
|  | 					'</tbody>' | ||
|  | 				], | ||
|  | 				months: [ | ||
|  | 					'<tbody class="<%=className%>">', | ||
|  | 						'<tr>', | ||
|  | 							'<td colspan="2"><a href="#"><span><%=data[0]%></span></a></td>', | ||
|  | 							'<td colspan="2"><a href="#"><span><%=data[1]%></span></a></td>', | ||
|  | 							'<td colspan="2"><a href="#"><span><%=data[2]%></span></a></td>', | ||
|  | 							'<td colspan="2"><a href="#"><span><%=data[3]%></span></a></td>', | ||
|  | 						'</tr>', | ||
|  | 						'<tr>', | ||
|  | 							'<td colspan="2"><a href="#"><span><%=data[4]%></span></a></td>', | ||
|  | 							'<td colspan="2"><a href="#"><span><%=data[5]%></span></a></td>', | ||
|  | 							'<td colspan="2"><a href="#"><span><%=data[6]%></span></a></td>', | ||
|  | 							'<td colspan="2"><a href="#"><span><%=data[7]%></span></a></td>', | ||
|  | 						'</tr>', | ||
|  | 						'<tr>', | ||
|  | 							'<td colspan="2"><a href="#"><span><%=data[8]%></span></a></td>', | ||
|  | 							'<td colspan="2"><a href="#"><span><%=data[9]%></span></a></td>', | ||
|  | 							'<td colspan="2"><a href="#"><span><%=data[10]%></span></a></td>', | ||
|  | 							'<td colspan="2"><a href="#"><span><%=data[11]%></span></a></td>', | ||
|  | 						'</tr>', | ||
|  | 					'</tbody>' | ||
|  | 				] | ||
|  | 			}, | ||
|  | 			defaults = { | ||
|  | 				flat: false, | ||
|  | 				starts: 1, | ||
|  | 				prev: '◀', | ||
|  | 				next: '▶', | ||
|  | 				lastSel: false, | ||
|  | 				mode: 'single', | ||
|  | 				view: 'days', | ||
|  | 				calendars: 1, | ||
|  | 				format: 'Y-m-d', | ||
|  | 				position: 'bottom', | ||
|  | 				eventName: 'click', | ||
|  | 				onRender: function(){return {};}, | ||
|  | 				onChange: function(){return true;}, | ||
|  | 				onShow: function(){return true;}, | ||
|  | 				onBeforeShow: function(){return true;}, | ||
|  | 				onHide: function(){return true;}, | ||
|  | 				locale: { | ||
|  | 					days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], | ||
|  | 					daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], | ||
|  | 					daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"], | ||
|  | 					months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], | ||
|  | 					monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], | ||
|  | 					weekMin: 'wk' | ||
|  | 				} | ||
|  | 			}, | ||
|  | 			fill = function(el) { | ||
|  | 				var options = $(el).data('datepicker'); | ||
|  | 				var cal = $(el); | ||
|  | 				var currentCal = Math.floor(options.calendars/2), date, data, dow, month, cnt = 0, week, days, indic, indic2, html, tblCal; | ||
|  | 				cal.find('td>table tbody').remove(); | ||
|  | 				for (var i = 0; i < options.calendars; i++) { | ||
|  | 					date = new Date(options.current); | ||
|  | 					date.addMonths(-currentCal + i); | ||
|  | 					tblCal = cal.find('table').eq(i+1); | ||
|  | 					switch (tblCal[0].className) { | ||
|  | 						case 'datepickerViewDays': | ||
|  | 							dow = formatDate(date, 'B, Y'); | ||
|  | 							break; | ||
|  | 						case 'datepickerViewMonths': | ||
|  | 							dow = date.getFullYear(); | ||
|  | 							break; | ||
|  | 						case 'datepickerViewYears': | ||
|  | 							dow = (date.getFullYear()-6) + ' - ' + (date.getFullYear()+5); | ||
|  | 							break; | ||
|  | 					}  | ||
|  | 					tblCal.find('thead tr:first th:eq(1) span').text(dow); | ||
|  | 					dow = date.getFullYear()-6; | ||
|  | 					data = { | ||
|  | 						data: [], | ||
|  | 						className: 'datepickerYears' | ||
|  | 					} | ||
|  | 					for ( var j = 0; j < 12; j++) { | ||
|  | 						data.data.push(dow + j); | ||
|  | 					} | ||
|  | 					html = tmpl(tpl.months.join(''), data); | ||
|  | 					date.setDate(1); | ||
|  | 					data = {weeks:[], test: 10}; | ||
|  | 					month = date.getMonth(); | ||
|  | 					var dow = (date.getDay() - options.starts) % 7; | ||
|  | 					date.addDays(-(dow + (dow < 0 ? 7 : 0))); | ||
|  | 					week = -1; | ||
|  | 					cnt = 0; | ||
|  | 					while (cnt < 42) { | ||
|  | 						indic = parseInt(cnt/7,10); | ||
|  | 						indic2 = cnt%7; | ||
|  | 						if (!data.weeks[indic]) { | ||
|  | 							week = date.getWeekNumber(); | ||
|  | 							data.weeks[indic] = { | ||
|  | 								week: week, | ||
|  | 								days: [] | ||
|  | 							}; | ||
|  | 						} | ||
|  | 						data.weeks[indic].days[indic2] = { | ||
|  | 							text: date.getDate(), | ||
|  | 							classname: [] | ||
|  | 						}; | ||
|  | 						if (month != date.getMonth()) { | ||
|  | 							data.weeks[indic].days[indic2].classname.push('datepickerNotInMonth'); | ||
|  | 						} | ||
|  | 						if (date.getDay() == 0) { | ||
|  | 							data.weeks[indic].days[indic2].classname.push('datepickerSunday'); | ||
|  | 						} | ||
|  | 						if (date.getDay() == 6) { | ||
|  | 							data.weeks[indic].days[indic2].classname.push('datepickerSaturday'); | ||
|  | 						} | ||
|  | 						var fromUser = options.onRender(date); | ||
|  | 						var val = date.valueOf(); | ||
|  | 						if (fromUser.selected || options.date == val || $.inArray(val, options.date) > -1 || (options.mode == 'range' && val >= options.date[0] && val <= options.date[1])) { | ||
|  | 							data.weeks[indic].days[indic2].classname.push('datepickerSelected'); | ||
|  | 						} | ||
|  | 						if (fromUser.disabled) { | ||
|  | 							data.weeks[indic].days[indic2].classname.push('datepickerDisabled'); | ||
|  | 						} | ||
|  | 						if (fromUser.className) { | ||
|  | 							data.weeks[indic].days[indic2].classname.push(fromUser.className); | ||
|  | 						} | ||
|  | 						data.weeks[indic].days[indic2].classname = data.weeks[indic].days[indic2].classname.join(' '); | ||
|  | 						cnt++; | ||
|  | 						date.addDays(1); | ||
|  | 					} | ||
|  | 					html = tmpl(tpl.days.join(''), data) + html; | ||
|  | 					data = { | ||
|  | 						data: options.locale.monthsShort, | ||
|  | 						className: 'datepickerMonths' | ||
|  | 					}; | ||
|  | 					html = tmpl(tpl.months.join(''), data) + html; | ||
|  | 					tblCal.append(html); | ||
|  | 				} | ||
|  | 			}, | ||
|  | 			parseDate = function (date, format) { | ||
|  | 				if (date.constructor == Date) { | ||
|  | 					return new Date(date); | ||
|  | 				} | ||
|  | 				var parts = date.split(/\W+/); | ||
|  | 				var against = format.split(/\W+/), d, m, y, h, min, now = new Date(); | ||
|  | 				for (var i = 0; i < parts.length; i++) { | ||
|  | 					switch (against[i]) { | ||
|  | 						case 'd': | ||
|  | 						case 'e': | ||
|  | 							d = parseInt(parts[i],10); | ||
|  | 							break; | ||
|  | 						case 'm': | ||
|  | 							m = parseInt(parts[i], 10)-1; | ||
|  | 							break; | ||
|  | 						case 'Y': | ||
|  | 						case 'y': | ||
|  | 							y = parseInt(parts[i], 10); | ||
|  | 							y += y > 100 ? 0 : (y < 29 ? 2000 : 1900); | ||
|  | 							break; | ||
|  | 						case 'H': | ||
|  | 						case 'I': | ||
|  | 						case 'k': | ||
|  | 						case 'l': | ||
|  | 							h = parseInt(parts[i], 10); | ||
|  | 							break; | ||
|  | 						case 'P': | ||
|  | 						case 'p': | ||
|  | 							if (/pm/i.test(parts[i]) && h < 12) { | ||
|  | 								h += 12; | ||
|  | 							} else if (/am/i.test(parts[i]) && h >= 12) { | ||
|  | 								h -= 12; | ||
|  | 							} | ||
|  | 							break; | ||
|  | 						case 'M': | ||
|  | 							min = parseInt(parts[i], 10); | ||
|  | 							break; | ||
|  | 					} | ||
|  | 				} | ||
|  | 				return new Date( | ||
|  | 					y === undefined ? now.getFullYear() : y, | ||
|  | 					m === undefined ? now.getMonth() : m, | ||
|  | 					d === undefined ? now.getDate() : d, | ||
|  | 					h === undefined ? now.getHours() : h, | ||
|  | 					min === undefined ? now.getMinutes() : min, | ||
|  | 					0 | ||
|  | 				); | ||
|  | 			}, | ||
|  | 			formatDate = function(date, format) { | ||
|  | 				var m = date.getMonth(); | ||
|  | 				var d = date.getDate(); | ||
|  | 				var y = date.getFullYear(); | ||
|  | 				var wn = date.getWeekNumber(); | ||
|  | 				var w = date.getDay(); | ||
|  | 				var s = {}; | ||
|  | 				var hr = date.getHours(); | ||
|  | 				var pm = (hr >= 12); | ||
|  | 				var ir = (pm) ? (hr - 12) : hr; | ||
|  | 				var dy = date.getDayOfYear(); | ||
|  | 				if (ir == 0) { | ||
|  | 					ir = 12; | ||
|  | 				} | ||
|  | 				var min = date.getMinutes(); | ||
|  | 				var sec = date.getSeconds(); | ||
|  | 				var parts = format.split(''), part; | ||
|  | 				for ( var i = 0; i < parts.length; i++ ) { | ||
|  | 					part = parts[i]; | ||
|  | 					switch (parts[i]) { | ||
|  | 						case 'a': | ||
|  | 							part = date.getDayName(); | ||
|  | 							break; | ||
|  | 						case 'A': | ||
|  | 							part = date.getDayName(true); | ||
|  | 							break; | ||
|  | 						case 'b': | ||
|  | 							part = date.getMonthName(); | ||
|  | 							break; | ||
|  | 						case 'B': | ||
|  | 							part = date.getMonthName(true); | ||
|  | 							break; | ||
|  | 						case 'C': | ||
|  | 							part = 1 + Math.floor(y / 100); | ||
|  | 							break; | ||
|  | 						case 'd': | ||
|  | 							part = (d < 10) ? ("0" + d) : d; | ||
|  | 							break; | ||
|  | 						case 'e': | ||
|  | 							part = d; | ||
|  | 							break; | ||
|  | 						case 'H': | ||
|  | 							part = (hr < 10) ? ("0" + hr) : hr; | ||
|  | 							break; | ||
|  | 						case 'I': | ||
|  | 							part = (ir < 10) ? ("0" + ir) : ir; | ||
|  | 							break; | ||
|  | 						case 'j': | ||
|  | 							part = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; | ||
|  | 							break; | ||
|  | 						case 'k': | ||
|  | 							part = hr; | ||
|  | 							break; | ||
|  | 						case 'l': | ||
|  | 							part = ir; | ||
|  | 							break; | ||
|  | 						case 'm': | ||
|  | 							part = (m < 9) ? ("0" + (1+m)) : (1+m); | ||
|  | 							break; | ||
|  | 						case 'M': | ||
|  | 							part = (min < 10) ? ("0" + min) : min; | ||
|  | 							break; | ||
|  | 						case 'p': | ||
|  | 						case 'P': | ||
|  | 							part = pm ? "PM" : "AM"; | ||
|  | 							break; | ||
|  | 						case 's': | ||
|  | 							part = Math.floor(date.getTime() / 1000); | ||
|  | 							break; | ||
|  | 						case 'S': | ||
|  | 							part = (sec < 10) ? ("0" + sec) : sec; | ||
|  | 							break; | ||
|  | 						case 'u': | ||
|  | 							part = w + 1; | ||
|  | 							break; | ||
|  | 						case 'w': | ||
|  | 							part = w; | ||
|  | 							break; | ||
|  | 						case 'y': | ||
|  | 							part = ('' + y).substr(2, 2); | ||
|  | 							break; | ||
|  | 						case 'Y': | ||
|  | 							part = y; | ||
|  | 							break; | ||
|  | 					} | ||
|  | 					parts[i] = part; | ||
|  | 				} | ||
|  | 				return parts.join(''); | ||
|  | 			}, | ||
|  | 			extendDate = function(options) { | ||
|  | 				if (Date.prototype.tempDate) { | ||
|  | 					return; | ||
|  | 				} | ||
|  | 				Date.prototype.tempDate = null; | ||
|  | 				Date.prototype.months = options.months; | ||
|  | 				Date.prototype.monthsShort = options.monthsShort; | ||
|  | 				Date.prototype.days = options.days; | ||
|  | 				Date.prototype.daysShort = options.daysShort; | ||
|  | 				Date.prototype.getMonthName = function(fullName) { | ||
|  | 					return this[fullName ? 'months' : 'monthsShort'][this.getMonth()]; | ||
|  | 				}; | ||
|  | 				Date.prototype.getDayName = function(fullName) { | ||
|  | 					return this[fullName ? 'days' : 'daysShort'][this.getDay()]; | ||
|  | 				}; | ||
|  | 				Date.prototype.addDays = function (n) { | ||
|  | 					this.setDate(this.getDate() + n); | ||
|  | 					this.tempDate = this.getDate(); | ||
|  | 				}; | ||
|  | 				Date.prototype.addMonths = function (n) { | ||
|  | 					if (this.tempDate == null) { | ||
|  | 						this.tempDate = this.getDate(); | ||
|  | 					} | ||
|  | 					this.setDate(1); | ||
|  | 					this.setMonth(this.getMonth() + n); | ||
|  | 					this.setDate(Math.min(this.tempDate, this.getMaxDays())); | ||
|  | 				}; | ||
|  | 				Date.prototype.addYears = function (n) { | ||
|  | 					if (this.tempDate == null) { | ||
|  | 						this.tempDate = this.getDate(); | ||
|  | 					} | ||
|  | 					this.setDate(1); | ||
|  | 					this.setFullYear(this.getFullYear() + n); | ||
|  | 					this.setDate(Math.min(this.tempDate, this.getMaxDays())); | ||
|  | 				}; | ||
|  | 				Date.prototype.getMaxDays = function() { | ||
|  | 					var tmpDate = new Date(Date.parse(this)), | ||
|  | 						d = 28, m; | ||
|  | 					m = tmpDate.getMonth(); | ||
|  | 					d = 28; | ||
|  | 					while (tmpDate.getMonth() == m) { | ||
|  | 						d ++; | ||
|  | 						tmpDate.setDate(d); | ||
|  | 					} | ||
|  | 					return d - 1; | ||
|  | 				}; | ||
|  | 				Date.prototype.getFirstDay = function() { | ||
|  | 					var tmpDate = new Date(Date.parse(this)); | ||
|  | 					tmpDate.setDate(1); | ||
|  | 					return tmpDate.getDay(); | ||
|  | 				}; | ||
|  | 				Date.prototype.getWeekNumber = function() { | ||
|  | 					var tempDate = new Date(this); | ||
|  | 					tempDate.setDate(tempDate.getDate() - (tempDate.getDay() + 6) % 7 + 3); | ||
|  | 					var dms = tempDate.valueOf(); | ||
|  | 					tempDate.setMonth(0); | ||
|  | 					tempDate.setDate(4); | ||
|  | 					return Math.round((dms - tempDate.valueOf()) / (604800000)) + 1; | ||
|  | 				}; | ||
|  | 				Date.prototype.getDayOfYear = function() { | ||
|  | 					var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); | ||
|  | 					var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0); | ||
|  | 					var time = now - then; | ||
|  | 					return Math.floor(time / 24*60*60*1000); | ||
|  | 				}; | ||
|  | 			}, | ||
|  | 			layout = function (el) { | ||
|  | 				var options = $(el).data('datepicker'); | ||
|  | 				var cal = $('#' + options.id); | ||
|  | 				if (!options.extraHeight) { | ||
|  | 					var divs = $(el).find('div'); | ||
|  | 					//options.extraHeight = divs.get(0).offsetHeight + divs.get(1).offsetHeight;
 | ||
|  | 					//options.extraWidth = divs.get(2).offsetWidth + divs.get(3).offsetWidth;
 | ||
|  | 				} | ||
|  | 				var tbl = cal.find('table:first').get(0); | ||
|  | 				var width = tbl.offsetWidth; | ||
|  | 				var height = tbl.offsetHeight; | ||
|  | 				cal.css({ | ||
|  | 					width: width + options.extraWidth + 'px', | ||
|  | 					height: height + options.extraHeight + 'px' | ||
|  | 				}).find('div.datepickerContainer').css({ | ||
|  | 					width: width + 'px', | ||
|  | 					height: height + 'px' | ||
|  | 				}); | ||
|  | 			}, | ||
|  | 			click = function(ev) { | ||
|  | 				if ($(ev.target).is('span')) { | ||
|  | 					ev.target = ev.target.parentNode; | ||
|  | 				} | ||
|  | 				var el = $(ev.target); | ||
|  | 				if (el.is('a')) { | ||
|  | 					ev.target.blur(); | ||
|  | 					if (el.hasClass('datepickerDisabled')) { | ||
|  | 						return false; | ||
|  | 					} | ||
|  | 					var options = $(this).data('datepicker'); | ||
|  | 					var parentEl = el.parent(); | ||
|  | 					var tblEl = parentEl.parent().parent().parent(); | ||
|  | 					var tblIndex = $('table', this).index(tblEl.get(0)) - 1; | ||
|  | 					var tmp = new Date(options.current); | ||
|  | 					var changed = false; | ||
|  | 					var fillIt = false; | ||
|  | 					if (parentEl.is('th')) { | ||
|  | 						if (parentEl.hasClass('datepickerWeek') && options.mode == 'range' && !parentEl.next().hasClass('datepickerDisabled')) { | ||
|  | 							var val = parseInt(parentEl.next().text(), 10); | ||
|  | 							tmp.addMonths(tblIndex - Math.floor(options.calendars/2)); | ||
|  | 							if (parentEl.next().hasClass('datepickerNotInMonth')) { | ||
|  | 								tmp.addMonths(val > 15 ? -1 : 1); | ||
|  | 							} | ||
|  | 							tmp.setDate(val); | ||
|  | 							options.date[0] = (tmp.setHours(0,0,0,0)).valueOf(); | ||
|  | 							tmp.setHours(23,59,59,0); | ||
|  | 							tmp.addDays(6); | ||
|  | 							options.date[1] = tmp.valueOf(); | ||
|  | 							fillIt = true; | ||
|  | 							changed = true; | ||
|  | 							options.lastSel = false; | ||
|  | 						} else if (parentEl.hasClass('datepickerMonth')) { | ||
|  | 							tmp.addMonths(tblIndex - Math.floor(options.calendars/2)); | ||
|  | 							switch (tblEl.get(0).className) { | ||
|  | 								case 'datepickerViewDays': | ||
|  | 									tblEl.get(0).className = 'datepickerViewMonths'; | ||
|  | 									el.find('span').text(tmp.getFullYear()); | ||
|  | 									break; | ||
|  | 								case 'datepickerViewMonths': | ||
|  | 									tblEl.get(0).className = 'datepickerViewYears'; | ||
|  | 									el.find('span').text((tmp.getFullYear()-6) + ' - ' + (tmp.getFullYear()+5)); | ||
|  | 									break; | ||
|  | 								case 'datepickerViewYears': | ||
|  | 									tblEl.get(0).className = 'datepickerViewDays'; | ||
|  | 									el.find('span').text(formatDate(tmp, 'B, Y')); | ||
|  | 									break; | ||
|  | 							} | ||
|  | 						} else if (parentEl.parent().parent().is('thead')) { | ||
|  | 							switch (tblEl.get(0).className) { | ||
|  | 								case 'datepickerViewDays': | ||
|  | 									options.current.addMonths(parentEl.hasClass('datepickerGoPrev') ? -1 : 1); | ||
|  | 									break; | ||
|  | 								case 'datepickerViewMonths': | ||
|  | 									options.current.addYears(parentEl.hasClass('datepickerGoPrev') ? -1 : 1); | ||
|  | 									break; | ||
|  | 								case 'datepickerViewYears': | ||
|  | 									options.current.addYears(parentEl.hasClass('datepickerGoPrev') ? -12 : 12); | ||
|  | 									break; | ||
|  | 							} | ||
|  | 							fillIt = true; | ||
|  | 						} | ||
|  | 					} else if (parentEl.is('td') && !parentEl.hasClass('datepickerDisabled')) { | ||
|  | 						switch (tblEl.get(0).className) { | ||
|  | 							case 'datepickerViewMonths': | ||
|  | 								options.current.setMonth(tblEl.find('tbody.datepickerMonths td').index(parentEl)); | ||
|  | 								options.current.setFullYear(parseInt(tblEl.find('thead th.datepickerMonth span').text(), 10)); | ||
|  | 								options.current.addMonths(Math.floor(options.calendars/2) - tblIndex); | ||
|  | 								tblEl.get(0).className = 'datepickerViewDays'; | ||
|  | 								break; | ||
|  | 							case 'datepickerViewYears': | ||
|  | 								options.current.setFullYear(parseInt(el.text(), 10)); | ||
|  | 								tblEl.get(0).className = 'datepickerViewMonths'; | ||
|  | 								break; | ||
|  | 							default: | ||
|  | 								var val = parseInt(el.text(), 10); | ||
|  | 								tmp.addMonths(tblIndex - Math.floor(options.calendars/2)); | ||
|  | 								if (parentEl.hasClass('datepickerNotInMonth')) { | ||
|  | 									tmp.addMonths(val > 15 ? -1 : 1); | ||
|  | 								} | ||
|  | 								tmp.setDate(val); | ||
|  | 								switch (options.mode) { | ||
|  | 									case 'multiple': | ||
|  | 										val = (tmp.setHours(0,0,0,0)).valueOf(); | ||
|  | 										if ($.inArray(val, options.date) > -1) { | ||
|  | 											$.each(options.date, function(nr, dat){ | ||
|  | 												if (dat == val) { | ||
|  | 													options.date.splice(nr,1); | ||
|  | 													return false; | ||
|  | 												} | ||
|  | 											}); | ||
|  | 										} else { | ||
|  | 											options.date.push(val); | ||
|  | 										} | ||
|  | 										break; | ||
|  | 									case 'range': | ||
|  | 										if (!options.lastSel) { | ||
|  | 											options.date[0] = (tmp.setHours(0,0,0,0)).valueOf(); | ||
|  | 										} | ||
|  | 										val = (tmp.setHours(23,59,59,0)).valueOf(); | ||
|  | 										if (val < options.date[0]) { | ||
|  | 											options.date[1] = options.date[0] + 86399000; | ||
|  | 											options.date[0] = val - 86399000; | ||
|  | 										} else { | ||
|  | 											options.date[1] = val; | ||
|  | 										} | ||
|  | 										options.lastSel = !options.lastSel; | ||
|  | 										break; | ||
|  | 									default: | ||
|  | 										options.date = tmp.valueOf(); | ||
|  | 										break; | ||
|  | 								} | ||
|  | 								break; | ||
|  | 						} | ||
|  | 						fillIt = true; | ||
|  | 						changed = true; | ||
|  | 					} | ||
|  | 					if (fillIt) { | ||
|  | 						fill(this); | ||
|  | 					} | ||
|  | 					if (changed) { | ||
|  | 						options.onChange.apply(this, prepareDate(options)); | ||
|  | 					} | ||
|  | 				} | ||
|  | 				return false; | ||
|  | 			}, | ||
|  | 			prepareDate = function (options) { | ||
|  | 				var tmp; | ||
|  | 				if (options.mode == 'single') { | ||
|  | 					tmp = new Date(options.date); | ||
|  | 					return [formatDate(tmp, options.format), tmp, options.el]; | ||
|  | 				} else { | ||
|  | 					tmp = [[],[], options.el]; | ||
|  | 					$.each(options.date, function(nr, val){ | ||
|  | 						var date = new Date(val); | ||
|  | 						tmp[0].push(formatDate(date, options.format)); | ||
|  | 						tmp[1].push(date); | ||
|  | 					}); | ||
|  | 					return tmp; | ||
|  | 				} | ||
|  | 			}, | ||
|  | 			getViewport = function () { | ||
|  | 				var m = document.compatMode == 'CSS1Compat'; | ||
|  | 				return { | ||
|  | 					l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft), | ||
|  | 					t : window.pageYOffset || (m ? document.documentElement.scrollTop : document.body.scrollTop), | ||
|  | 					w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth), | ||
|  | 					h : window.innerHeight || (m ? document.documentElement.clientHeight : document.body.clientHeight) | ||
|  | 				}; | ||
|  | 			}, | ||
|  | 			isChildOf = function(parentEl, el, container) { | ||
|  | 				if (parentEl == el) { | ||
|  | 					return true; | ||
|  | 				} | ||
|  | 				if (parentEl.contains) { | ||
|  | 					return parentEl.contains(el); | ||
|  | 				} | ||
|  | 				if ( parentEl.compareDocumentPosition ) { | ||
|  | 					return !!(parentEl.compareDocumentPosition(el) & 16); | ||
|  | 				} | ||
|  | 				var prEl = el.parentNode; | ||
|  | 				while(prEl && prEl != container) { | ||
|  | 					if (prEl == parentEl) | ||
|  | 						return true; | ||
|  | 					prEl = prEl.parentNode; | ||
|  | 				} | ||
|  | 				return false; | ||
|  | 			}, | ||
|  | 			show = function (ev) { | ||
|  | 				var cal = $('#' + $(this).data('datepickerId')); | ||
|  | 				if (!cal.is(':visible')) { | ||
|  | 					var calEl = cal.get(0); | ||
|  | 					fill(calEl); | ||
|  | 					var options = cal.data('datepicker'); | ||
|  | 					options.onBeforeShow.apply(this, [cal.get(0)]); | ||
|  | 					var pos = $(this).offset(); | ||
|  | 					var viewPort = getViewport(); | ||
|  | 					var top = pos.top; | ||
|  | 					var left = pos.left; | ||
|  | 					var oldDisplay = $.curCSS(calEl, 'display'); | ||
|  | 					cal.css({ | ||
|  | 						visibility: 'hidden', | ||
|  | 						display: 'block' | ||
|  | 					}); | ||
|  | 					layout(calEl); | ||
|  | 					switch (options.position){ | ||
|  | 						case 'top': | ||
|  | 							top -= calEl.offsetHeight; | ||
|  | 							break; | ||
|  | 						case 'left': | ||
|  | 							left -= calEl.offsetWidth; | ||
|  | 							break; | ||
|  | 						case 'right': | ||
|  | 							left += this.offsetWidth; | ||
|  | 							break; | ||
|  | 						case 'bottom': | ||
|  | 							top += this.offsetHeight; | ||
|  | 							break; | ||
|  | 					} | ||
|  | 					if (top + calEl.offsetHeight > viewPort.t + viewPort.h) { | ||
|  | 						top = pos.top  - calEl.offsetHeight; | ||
|  | 					} | ||
|  | 					if (top < viewPort.t) { | ||
|  | 						top = pos.top + this.offsetHeight + calEl.offsetHeight; | ||
|  | 					} | ||
|  | 					if (left + calEl.offsetWidth > viewPort.l + viewPort.w) { | ||
|  | 						left = pos.left - calEl.offsetWidth; | ||
|  | 					} | ||
|  | 					if (left < viewPort.l) { | ||
|  | 						left = pos.left + this.offsetWidth | ||
|  | 					} | ||
|  | 					cal.css({ | ||
|  | 						visibility: 'visible', | ||
|  | 						display: 'block', | ||
|  | 						top: top + 'px', | ||
|  | 						left: left + 'px' | ||
|  | 					}); | ||
|  | 					if (options.onShow.apply(this, [cal.get(0)]) != false) { | ||
|  | 						cal.show(); | ||
|  | 					} | ||
|  | 					$(document).bind('mousedown', {cal: cal, trigger: this}, hide); | ||
|  | 				} | ||
|  | 				return false; | ||
|  | 			}, | ||
|  | 			hide = function (ev) { | ||
|  | 				if (ev.target != ev.data.trigger && !isChildOf(ev.data.cal.get(0), ev.target, ev.data.cal.get(0))) { | ||
|  | 					if (ev.data.cal.data('datepicker').onHide.apply(this, [ev.data.cal.get(0)]) != false) { | ||
|  | 						ev.data.cal.hide(); | ||
|  | 					} | ||
|  | 					$(document).unbind('mousedown', hide); | ||
|  | 				} | ||
|  | 			}; | ||
|  | 		return { | ||
|  | 			init: function(options){ | ||
|  | 				options = $.extend({}, defaults, options||{}); | ||
|  | 				extendDate(options.locale); | ||
|  | 				options.calendars = Math.max(1, parseInt(options.calendars,10)||1); | ||
|  | 				options.mode = /single|multiple|range/.test(options.mode) ? options.mode : 'single'; | ||
|  | 				return this.each(function(){ | ||
|  | 					if (!$(this).data('datepicker')) { | ||
|  | 						options.el = this; | ||
|  | 						if (options.date.constructor == String) { | ||
|  | 							options.date = parseDate(options.date, options.format); | ||
|  | 							options.date.setHours(0,0,0,0); | ||
|  | 						} | ||
|  | 						if (options.mode != 'single') { | ||
|  | 							if (options.date.constructor != Array) { | ||
|  | 								options.date = [options.date.valueOf()]; | ||
|  | 								if (options.mode == 'range') { | ||
|  | 									options.date.push(((new Date(options.date[0])).setHours(23,59,59,0)).valueOf()); | ||
|  | 								} | ||
|  | 							} else { | ||
|  | 								for (var i = 0; i < options.date.length; i++) { | ||
|  | 									options.date[i] = (parseDate(options.date[i], options.format).setHours(0,0,0,0)).valueOf(); | ||
|  | 								} | ||
|  | 								if (options.mode == 'range') { | ||
|  | 									options.date[1] = ((new Date(options.date[1])).setHours(23,59,59,0)).valueOf(); | ||
|  | 								} | ||
|  | 							} | ||
|  | 						} else { | ||
|  | 							options.date = options.date.valueOf(); | ||
|  | 						} | ||
|  | 						if (!options.current) { | ||
|  | 							options.current = new Date(); | ||
|  | 						} else { | ||
|  | 							options.current = parseDate(options.current, options.format); | ||
|  | 						}  | ||
|  | 						options.current.setDate(1); | ||
|  | 						options.current.setHours(0,0,0,0); | ||
|  | 						var id = 'datepicker_' + parseInt(Math.random() * 1000), cnt; | ||
|  | 						options.id = id; | ||
|  | 						$(this).data('datepickerId', options.id); | ||
|  | 						var cal = $(tpl.wrapper).attr('id', id).bind('click', click).data('datepicker', options); | ||
|  | 						if (options.className) { | ||
|  | 							cal.addClass(options.className); | ||
|  | 						} | ||
|  | 						var html = ''; | ||
|  | 						for (var i = 0; i < options.calendars; i++) { | ||
|  | 							cnt = options.starts; | ||
|  | 							if (i > 0) { | ||
|  | 								html += tpl.space; | ||
|  | 							} | ||
|  | 							html += tmpl(tpl.head.join(''), { | ||
|  | 									week: options.locale.weekMin, | ||
|  | 									prev: options.prev, | ||
|  | 									next: options.next, | ||
|  | 									day1: options.locale.daysMin[(cnt++)%7], | ||
|  | 									day2: options.locale.daysMin[(cnt++)%7], | ||
|  | 									day3: options.locale.daysMin[(cnt++)%7], | ||
|  | 									day4: options.locale.daysMin[(cnt++)%7], | ||
|  | 									day5: options.locale.daysMin[(cnt++)%7], | ||
|  | 									day6: options.locale.daysMin[(cnt++)%7], | ||
|  | 									day7: options.locale.daysMin[(cnt++)%7] | ||
|  | 								}); | ||
|  | 						} | ||
|  | 						cal | ||
|  | 							.find('tr:first').append(html) | ||
|  | 								.find('table').addClass(views[options.view]); | ||
|  | 						fill(cal.get(0)); | ||
|  | 						if (options.flat) { | ||
|  | 							cal.appendTo(this).show().css('position', 'relative'); | ||
|  | 							layout(cal.get(0)); | ||
|  | 						} else { | ||
|  | 							cal.appendTo(document.body); | ||
|  | 							$(this).bind(options.eventName, show); | ||
|  | 						} | ||
|  | 					} | ||
|  | 				}); | ||
|  | 			}, | ||
|  | 			showPicker: function() { | ||
|  | 				return this.each( function () { | ||
|  | 					if ($(this).data('datepickerId')) { | ||
|  | 						show.apply(this); | ||
|  | 					} | ||
|  | 				}); | ||
|  | 			}, | ||
|  | 			hidePicker: function() { | ||
|  | 				return this.each( function () { | ||
|  | 					if ($(this).data('datepickerId')) { | ||
|  | 						$('#' + $(this).data('datepickerId')).hide(); | ||
|  | 					} | ||
|  | 				}); | ||
|  | 			}, | ||
|  | 			setDate: function(date, shiftTo){ | ||
|  | 				return this.each(function(){ | ||
|  | 					if ($(this).data('datepickerId')) { | ||
|  | 						var cal = $('#' + $(this).data('datepickerId')); | ||
|  | 						var options = cal.data('datepicker'); | ||
|  | 						options.date = date; | ||
|  | 						if (options.date.constructor == String) { | ||
|  | 							options.date = parseDate(options.date, options.format); | ||
|  | 							options.date.setHours(0,0,0,0); | ||
|  | 						} | ||
|  | 						if (options.mode != 'single') { | ||
|  | 							if (options.date.constructor != Array) { | ||
|  | 								options.date = [options.date.valueOf()]; | ||
|  | 								if (options.mode == 'range') { | ||
|  | 									options.date.push(((new Date(options.date[0])).setHours(23,59,59,0)).valueOf()); | ||
|  | 								} | ||
|  | 							} else { | ||
|  | 								for (var i = 0; i < options.date.length; i++) { | ||
|  | 									options.date[i] = (parseDate(options.date[i], options.format).setHours(0,0,0,0)).valueOf(); | ||
|  | 								} | ||
|  | 								if (options.mode == 'range') { | ||
|  | 									options.date[1] = ((new Date(options.date[1])).setHours(23,59,59,0)).valueOf(); | ||
|  | 								} | ||
|  | 							} | ||
|  | 						} else { | ||
|  | 							options.date = options.date.valueOf(); | ||
|  | 						} | ||
|  | 						if (shiftTo) { | ||
|  | 							options.current = new Date (options.mode != 'single' ? options.date[0] : options.date); | ||
|  | 						} | ||
|  | 						fill(cal.get(0)); | ||
|  | 					} | ||
|  | 				}); | ||
|  | 			}, | ||
|  | 			getDate: function(formated) { | ||
|  | 				if (this.size() > 0) { | ||
|  | 					return prepareDate($('#' + $(this).data('datepickerId')).data('datepicker'))[formated ? 0 : 1]; | ||
|  | 				} | ||
|  | 			}, | ||
|  | 			clear: function(){ | ||
|  | 				return this.each(function(){ | ||
|  | 					if ($(this).data('datepickerId')) { | ||
|  | 						var cal = $('#' + $(this).data('datepickerId')); | ||
|  | 						var options = cal.data('datepicker'); | ||
|  | 						if (options.mode != 'single') { | ||
|  | 							options.date = []; | ||
|  | 							fill(cal.get(0)); | ||
|  | 						} | ||
|  | 					} | ||
|  | 				}); | ||
|  | 			}, | ||
|  | 			fixLayout: function(){ | ||
|  | 				return this.each(function(){ | ||
|  | 					if ($(this).data('datepickerId')) { | ||
|  | 						var cal = $('#' + $(this).data('datepickerId')); | ||
|  | 						var options = cal.data('datepicker'); | ||
|  | 						if (options.flat) { | ||
|  | 							layout(cal.get(0)); | ||
|  | 						} | ||
|  | 					} | ||
|  | 				}); | ||
|  | 			} | ||
|  | 		}; | ||
|  | 	}(); | ||
|  | 	$.fn.extend({ | ||
|  | 		DatePicker: DatePicker.init, | ||
|  | 		DatePickerHide: DatePicker.hidePicker, | ||
|  | 		DatePickerShow: DatePicker.showPicker, | ||
|  | 		DatePickerSetDate: DatePicker.setDate, | ||
|  | 		DatePickerGetDate: DatePicker.getDate, | ||
|  | 		DatePickerClear: DatePicker.clear, | ||
|  | 		DatePickerLayout: DatePicker.fixLayout | ||
|  | 	}); | ||
|  | })(jQuery); | ||
|  | 
 | ||
|  | (function(){ | ||
|  |   var cache = {}; | ||
|  |   | ||
|  |   this.tmpl = function tmpl(str, data){ | ||
|  |     // Figure out if we're getting a template, or if we need to
 | ||
|  |     // load the template - and be sure to cache the result.
 | ||
|  |     var fn = !/\W/.test(str) ? | ||
|  |       cache[str] = cache[str] || | ||
|  |         tmpl(document.getElementById(str).innerHTML) : | ||
|  |       | ||
|  |       // Generate a reusable function that will serve as a template
 | ||
|  |       // generator (and which will be cached).
 | ||
|  |       new Function("obj", | ||
|  |         "var p=[],print=function(){p.push.apply(p,arguments);};" + | ||
|  |         | ||
|  |         // Introduce the data as local variables using with(){}
 | ||
|  |         "with(obj){p.push('" + | ||
|  |         | ||
|  |         // Convert the template into pure JavaScript
 | ||
|  |         str | ||
|  |           .replace(/[\r\t\n]/g, " ") | ||
|  |           .split("<%").join("\t") | ||
|  |           .replace(/((^|%>)[^\t]*)'/g, "$1\r") | ||
|  |           .replace(/\t=(.*?)%>/g, "',$1,'") | ||
|  |           .split("\t").join("');") | ||
|  |           .split("%>").join("p.push('") | ||
|  |           .split("\r").join("\\'") | ||
|  |       + "');}return p.join('');"); | ||
|  |     | ||
|  |     // Provide some basic currying to the user
 | ||
|  |     return data ? fn( data ) : fn; | ||
|  |   }; | ||
|  | })(); |