PageSourceSearch

https://www.yarnsandfibers.com/wp-content/uploads/hummingbird-assets/ee617d2963dfa12332cb6e293d017869.js

js yarnsandfibers.com collected 2026-09-24 23:11:54 UTC 51,302 bytes, 1,123 lines download raw bytes

1/**handles:events-manager**/
2jQuery(document).ready( function($){
3	var load_ui_css = false; //load jquery ui css?
4	/* Time Entry */
5	$('#start-time').each(function(i, el){
6		$(el).addClass('em-time-input em-time-start').next('#end-time').addClass('em-time-input em-time-end').parent().addClass('em-time-range');
7	});
8	if( $(".em-time-input").length > 0 ){
9		em_setup_timepicker('body');
10	}
11	/* Calendar AJAX */
12	$('.em-calendar-wrapper a').unbind("click");
13	$('.em-calendar-wrapper a').undelegate("click");
14	$('.em-calendar-wrapper').delegate('a.em-calnav, a.em-calnav', 'click', function(e){
15		e.preventDefault();
16		$(this).closest('.em-calendar-wrapper').prepend('<div class="loading" id="em-loading"></div>');
17		var url = em_ajaxify($(this).attr('href'));
18		$(this).closest('.em-calendar-wrapper').load(url, function(){$(this).trigger('em_calendar_load');});
19	} );
20
21	//Events Search
22	$(document).delegate('.em-toggle', 'click change', function(e){
23		e.preventDefault();
24		//show or hide advanced tickets, hidden by default
25		var el = $(this);
26		var rel = el.attr('rel').split(':');
27		if( el.hasClass('show-search') ){
28			if( rel.length > 1 ){ el.closest(rel[1]).find(rel[0]).slideUp(); }
29			else{ $(rel[0]).slideUp(); }
30			el.find('.show, .show-advanced').show();
31			el.find('.hide, .hide-advanced').hide();
32			el.removeClass('show-search');
33		}else{
34			if( rel.length > 1 ){ el.closest(rel[1]).find(rel[0]).slideDown(); }
35			else{ $(rel[0]).slideDown(); }
36			el.find('.show, .show-advanced').hide();
37			el.find('.hide, .hide-advanced').show();
38			el.addClass('show-search');
39		}
40		
41	});
42	if( EM.search_term_placeholder ){
43		if( 'placeholder' in document.createElement('input') ){
44			$('input.em-events-search-text, input.em-search-text').attr('placeholder', EM.search_term_placeholder);
45		}else{
46			$('input.em-events-search-text, input.em-search-text').blur(function(){
47				if( this.value=='' ) this.value = EM.search_term_placeholder;
48			}).focus(function(){
49				if( this.value == EM.search_term_placeholder ) this.value='';
50			}).trigger('blur');
51		}
52	}
53	$('.em-search-form select[name=country]').change( function(){
54		var el = $(this);
55		$('.em-search select[name=state]').html('<option value="">'+EM.txt_loading+'</option>');
56		$('.em-search select[name=region]').html('<option value="">'+EM.txt_loading+'</option>');
57		$('.em-search select[name=town]').html('<option value="">'+EM.txt_loading+'</option>');
58		if( el.val() != '' ){
59			el.closest('.em-search-location').find('.em-search-location-meta').slideDown();
60			var data = {
61				action : 'search_states',
62				country : el.val(),
63				return_html : true
64			};
65			$('.em-search select[name=state]').load( EM.ajaxurl, data );
66			data.action = 'search_regions';
67			$('.em-search select[name=region]').load( EM.ajaxurl, data );
68			data.action = 'search_towns';
69			$('.em-search select[name=town]').load( EM.ajaxurl, data );
70		}else{
71			el.closest('.em-search-location').find('.em-search-location-meta').slideUp();
72		}
73	});
74
75	$('.em-search-form select[name=region]').change( function(){
76		$('.em-search select[name=state]').html('<option value="">'+EM.txt_loading+'</option>');
77		$('.em-search select[name=town]').html('<option value="">'+EM.txt_loading+'</option>');
78		var data = {
79			action : 'search_states',
80			region : $(this).val(),
81			country : $('.em-search-form select[name=country]').val(),
82			return_html : true
83		};
84		$('.em-search select[name=state]').load( EM.ajaxurl, data );
85		data.action = 'search_towns';
86		$('.em-search select[name=town]').load( EM.ajaxurl, data );
87	});
88
89	$('.em-search-form select[name=state]').change( function(){
90		$('.em-search select[name=town]').html('<option value="">'+EM.txt_loading+'</option>');
91		var data = {
92			action : 'search_towns',
93			state : $(this).val(),
94			region : $('.em-search-form select[name=region]').val(),
95			country : $('.em-search-form select[name=country]').val(),
96			return_html : true
97		};
98		$('.em-search select[name=town]').load( EM.ajaxurl, data );
99	});
100	
101	//in order for this to work, you need the above classes to be present in your templates
102	$(document).delegate('.em-search-form, .em-events-search-form', 'submit', function(e){
103		var form = $(this);
104    	if( this.em_search && this.em_search.value == EM.txt_search){ this.em_search.value = ''; }
105    	var results_wrapper = form.closest('.em-search-wrapper').find('.em-search-ajax');
106    	if( results_wrapper.length == 0 ) results_wrapper = $('.em-search-ajax');
107    	if( results_wrapper.length > 0 ){
108    		results_wrapper.append('<div class="loading" id="em-loading"></div>');
109    		var submitButton = form.find('.em-search-submit');
110    		submitButton.data('buttonText', submitButton.val()).val(EM.txt_searching);
111    		var img = submitButton.children('img');
112    		if( img.length > 0 ) img.attr('src', img.attr('src').replace('search-mag.png', 'search-loading.gif'));
113    		var vars = form.serialize();
114    		$.ajax( EM.ajaxurl, {
115				type : 'POST',
116	    		dataType : 'html',
117	    		data : vars,
118			    success : function(responseText){
119			    	submitButton.val(submitButton.data('buttonText'));
120			    	if( img.length > 0 ) img.attr('src', img.attr('src').replace('search-loading.gif', 'search-mag.png'));
121		    		results_wrapper.replaceWith(responseText);
122		        	if( form.find('input[name=em_search]').val() == '' ){ form.find('input[name=em_search]').val(EM.txt_search); }
123		        	//reload results_wrapper
124		        	results_wrapper = form.closest('.em-search-wrapper').find('.em-search-ajax');
125		        	if( results_wrapper.length == 0 ) results_wrapper = $('.em-search-ajax');
126			    	jQuery(document).triggerHandler('em_search_ajax', [vars, results_wrapper, e]); //ajax has loaded new results
127			    }
128	    	});
129    		e.preventDefault();
130			return false;
131    	}
132	});
133	if( $('.em-search-ajax').length > 0 ){
134		$(document).delegate('.em-search-ajax a.page-numbers', 'click', function(e){
135			var a = $(this);
136			var data = a.closest('.em-pagination').attr('data-em-ajax');
137			var wrapper = a.closest('.em-search-ajax');
138			var wrapper_parent = wrapper.parent();
139		    var qvars = a.attr('href').split('?');
140		    var vars = qvars[1];
141		    //add data-em-ajax att if it exists
142		    if( data != '' ){
143		    	vars = vars != '' ? vars+'&'+data : data;
144		    }
145		    wrapper.append('<div class="loading" id="em-loading"></div>');
146		    $.ajax( EM.ajaxurl, {
147				type : 'POST',
148	    		dataType : 'html',
149	    		data : vars,
150			    success : function(responseText) {
151			    	wrapper.replaceWith(responseText);
152			    	wrapper = wrapper_parent.find('.em-search-ajax');
153			    	jQuery(document).triggerHandler('em_search_ajax', [vars, wrapper, e]); //ajax has loaded new results
154			    }
155	    	});
156			e.preventDefault();
157			return false;
158		});
159	}
160		
161	/*
162	 * ADMIN AREA AND PUBLIC FORMS (Still polishing this section up, note that form ids and classes may change accordingly)
163	 */
164	//Events List
165		//Approve/Reject Links
166		$('.events-table').on('click', '.em-event-delete', function(){
167			if( !confirm("Are you sure you want to delete?") ){ return false; }
168			window.location.href = this.href;
169		});
170	//Forms
171	$('#event-form #event-image-delete, #location-form #location-image-delete').on('click', function(){
172		var el = $(this);
173		if( el.is(':checked') ){
174			el.closest('.event-form-image, .location-form-image').find('#event-image-img, #location-image-img').hide();
175		}else{
176			el.closest('.event-form-image, .location-form-image').find('#event-image-img, #location-image-img').show();
177		}
178	});
179	//Event Editor 
180		//Recurrence Warnings
181		$('#event-form.em-event-admin-recurring').submit( function(event){
182			var form = $(this);
183			if( form.find('input[name="event_reschedule"]').first().val() == 1 ){
184				var warning_text = EM.event_reschedule_warning;
185			}else if( form.find('input[name="event_recreate_tickets"]').first().val() == 1 ){
186				var warning_text = EM.event_recurrence_bookings;
187			}else{
188				var warning_text = EM.event_recurrence_overwrite;
189			}
190			confirmation = confirm(warning_text);
191			if( confirmation == false ){
192				event.preventDefault();
193			}
194		});
195		//Buttons for recurrence warnings within event editor forms
196		$('.em-reschedule-trigger').click(function(e){
197			e.preventDefault();
198			var trigger = $(this);
199			trigger.closest('.em-recurrence-reschedule').find(trigger.data('target')).removeClass('reschedule-hidden');
200			trigger.siblings('.em-reschedule-value').val(1);
201			trigger.addClass('reschedule-hidden').siblings('a').removeClass('reschedule-hidden');
202		});
203		$('.em-reschedule-cancel').click(function(e){
204			e.preventDefault();
205			var trigger = $(this);
206			trigger.closest('.em-recurrence-reschedule').find(trigger.data('target')).addClass('reschedule-hidden');
207			trigger.siblings('.em-reschedule-value').val(0);
208			trigger.addClass('reschedule-hidden').siblings('a').removeClass('reschedule-hidden');
209		});
210	//Tickets & Bookings
211	if( $("#em-tickets-form").length > 0 ){
212		//Enable/Disable Bookings
213		$('#event-rsvp').click( function(event){
214			if( !this.checked ){
215				confirmation = confirm(EM.disable_bookings_warning);
216				if( confirmation == false ){
217					event.preventDefault();
218				}else{
219					$('#event-rsvp-options').hide();
220				}
221			}else{
222				$('#event-rsvp-options').fadeIn();
223			}
224		});
225		if($('input#event-rsvp').is(":checked")) {
226			$("div#rsvp-data").fadeIn();
227		} else {
228			$("div#rsvp-data").hide();
229		}
230		//Ticket(s) UI
231		var reset_ticket_forms = function(){
232			$('#em-tickets-form table tbody tr.em-tickets-row').show();
233			$('#em-tickets-form table tbody tr.em-tickets-row-form').hide();
234		};
235		//recurrences and cut-off logic for ticket availability
236		if( $('#em-recurrence-checkbox').length > 0 ){
237			$('#em-recurrence-checkbox').change(function(){
238				if( $('#em-recurrence-checkbox').is(':checked') ){
239					$('#em-tickets-form .ticket-dates-from-recurring, #em-tickets-form .ticket-dates-to-recurring, #event-rsvp-options .em-booking-date-recurring').show();
240					$('#em-tickets-form .ticket-dates-from-normal, #em-tickets-form .ticket-dates-to-normal, #event-rsvp-options .em-booking-date-normal, #em-tickets-form .hidden').hide();
241				}else{
242					$('#em-tickets-form .ticket-dates-from-normal, #em-tickets-form .ticket-dates-to-normal, #event-rsvp-options .em-booking-date-normal').show();
243					$('#em-tickets-form .ticket-dates-from-recurring, #em-tickets-form .ticket-dates-to-recurring, #event-rsvp-options .em-booking-date-recurring, #em-tickets-form .hidden').hide();
244				}
245			}).trigger('change');
246		}else if( $('#em-form-recurrence').length > 0 ){
247			$('#em-tickets-form .ticket-dates-from-recurring, #em-tickets-form .ticket-dates-to-recurring, #event-rsvp-options .em-booking-date-recurring').show();
248			$('#em-tickets-form .ticket-dates-from-normal, #em-tickets-form .ticket-dates-to-normal, #event-rsvp-options .em-booking-date-normal, #em-tickets-form .hidden').hide();
249		}else{
250			$('#em-tickets-form .ticket-dates-from-recurring, #em-tickets-form .ticket-dates-to-recurring, #event-rsvp-options .em-booking-date-recurring, #em-tickets-form .hidden').hide();
251		}
252		//Add a new ticket
253		$("#em-tickets-add").click(function(e){ 
254			e.preventDefault();
255			reset_ticket_forms();
256			//create copy of template slot, insert so ready for population
257			var tickets = $('#em-tickets-form table tbody');
258			var rowNo = tickets.length+1;
259			var slot = tickets.first().clone(true).attr('id','em-ticket-'+ rowNo).appendTo($('#em-tickets-form table'));
260			//change the index of the form element names
261			slot.find('*[name]').each( function(index,el){
262				el = $(el);
263				el.attr('name', el.attr('name').replace('em_tickets[0]','em_tickets['+rowNo+']'));
264			});
265			//show ticket and switch to editor
266			slot.show().find('.ticket-actions-edit').trigger('click');
267			//refresh datepicker and values
268			slot.find('.em-date-input-loc').datepicker('destroy').removeAttr('id'); //clear all datepickers
269			slot.find('.em-time-input').unbind().each(function(index, el){ this.timePicker = false; }); //clear all timepickers - consequently, also other click/blur/change events, recreate the further down
270			em_setup_datepicker(slot);
271			em_setup_timepicker(slot);
272		    $('html, body').animate({ scrollTop: slot.offset().top - 30 }); //sends user to form
273		});
274		//Edit a Ticket
275		$(document).delegate('.ticket-actions-edit', 'click', function(e){
276			e.preventDefault();
277			reset_ticket_forms();
278			var tbody = $(this).closest('tbody');
279			tbody.find('tr.em-tickets-row').hide();
280			tbody.find('tr.em-tickets-row-form').fadeIn();
281			return false;
282		});
283		$(document).delegate('.ticket-actions-edited', 'click', function(e){
284			e.preventDefault();
285			var tbody = $(this).closest('tbody');
286			var rowNo = tbody.attr('id').replace('em-ticket-','');
287			tbody.find('.em-tickets-row').fadeIn();
288			tbody.find('.em-tickets-row-form').hide();
289			tbody.find('*[name]').each(function(index,el){
290				el = $(el);
291				if( el.attr('name') == 'ticket_start_pub'){
292					tbody.find('span.ticket_start').text(el.attr('value'));
293				}else if( el.attr('name') == 'ticket_end_pub' ){
294					tbody.find('span.ticket_end').text(el.attr('value'));
295				}else if( el.attr('name') == 'em_tickets['+rowNo+'][ticket_type]' ){
296					if( el.find(':selected').val() == 'members' ){
297						tbody.find('span.ticket_name').prepend('* ');
298					}
299				}else if( el.attr('name') == 'em_tickets['+rowNo+'][ticket_start_recurring_days]' ){
300					var text = tbody.find('select.ticket-dates-from-recurring-when').val() == 'before' ? '-'+el.attr('value'):el.attr('value');
301					if( el.attr('value') != '' ){
302						tbody.find('span.ticket_start_recurring_days').text(text);
303						tbody.find('span.ticket_start_recurring_days_text, span.ticket_start_time').removeClass('hidden').show();
304					}else{
305						tbody.find('span.ticket_start_recurring_days').text(' - ');
306						tbody.find('span.ticket_start_recurring_days_text, span.ticket_start_time').removeClass('hidden').hide();
307					}
308				}else if( el.attr('name') == 'em_tickets['+rowNo+'][ticket_end_recurring_days]' ){
309					var text = tbody.find('select.ticket-dates-to-recurring-when').val() == 'before' ? '-'+el.attr('value'):el.attr('value');
310					if( el.attr('value') != '' ){
311						tbody.find('span.ticket_end_recurring_days').text(text);
312						tbody.find('span.ticket_end_recurring_days_text, span.ticket_end_time').removeClass('hidden').show();
313					}else{
314						tbody.find('span.ticket_end_recurring_days').text(' - ');
315						tbody.find('span.ticket_end_recurring_days_text, span.ticket_end_time').removeClass('hidden').hide();
316					}
317				}else{
318					tbody.find('.'+el.attr('name').replace('em_tickets['+rowNo+'][','').replace(']','').replace('[]','')).text(el.attr('value'));
319				}
320			});
321			//allow for others to hook into this
322			$(document).triggerHandler('em_maps_tickets_edit', [tbody, rowNo, true]);
323		    $('html, body').animate({ scrollTop: tbody.parent().offset().top - 30 }); //sends user back to top of form
324			return false;
325		});
326		$(document).delegate('.em-ticket-form select.ticket_type','change', function(e){
327			//check if ticket is for all users or members, if members, show roles to limit the ticket to
328			var el = $(this);
329			if( el.find('option:selected').val() == 'members' ){
330				el.closest('.em-ticket-form').find('.ticket-roles').fadeIn();
331			}else{
332				el.closest('.em-ticket-form').find('.ticket-roles').hide();
333			}
334		});
335		$(document).delegate('.em-ticket-form .ticket-options-advanced','click', function(e){
336			//show or hide advanced tickets, hidden by default
337			e.preventDefault();
338			var el = $(this);
339			if( el.hasClass('show') ){
340				el.closest('.em-ticket-form').find('.em-ticket-form-advanced').fadeIn();
341				el.find('.show,.show-advanced').hide();
342				el.find('.hide,.hide-advanced').show();
343			}else{
344				el.closest('.em-ticket-form').find('.em-ticket-form-advanced').hide();
345				el.find('.show,.show-advanced').show();
346				el.find('.hide,.hide-advanced').hide();
347			}
348			el.toggleClass('show');
349		});
350		$('.em-ticket-form').each( function(){
351			//check whether to show advanced options or not by default for each ticket
352			var show_advanced = false;
353			var el = $(this); 
354			el.find('.em-ticket-form-advanced input[type="text"]').each(function(){ if(this.value != '') show_advanced = true; });
355			if( el.find('.em-ticket-form-advanced input[type="checkbox"]:checked').length > 0 ){ show_advanced = true; }
356			el.find('.em-ticket-form-advanced option:selected').each(function(){ if(this.value != '') show_advanced = true; });
357			if( show_advanced ) el.find('.ticket-options-advanced').trigger('click');
358		});
359		//Delete a ticket
360		$(document).delegate('.ticket-actions-delete', 'click', function(e){
361			e.preventDefault();
362			var el = $(this);
363			var tbody = el.closest('tbody');
364			if( tbody.find('input.ticket_id').val() > 0 ){
365				//only will happen if no bookings made
366				el.text('Deleting...');	
367				$.getJSON( $(this).attr('href'), {'em_ajax_action':'delete_ticket', 'id':tbody.find('input.ticket_id').val()}, function(data){
368					if(data.result){
369						tbody.remove();
370					}else{
371						el.text('Delete');
372						alert(data.error);
373					}
374				});
375			}else{
376				//not saved to db yet, so just remove
377				tbody.remove();
378			}
379			return false;
380		});
381	}
382	//Manageing Bookings
383	if( $('#em-bookings-table').length > 0 ){
384		//Pagination link clicks
385		$(document).delegate('#em-bookings-table .tablenav-pages a', 'click', function(){
386			var el = $(this);
387			var form = el.parents('#em-bookings-table form.bookings-filter');
388			//get page no from url, change page, submit form
389			var match = el.attr('href').match(/#[0-9]+/);
390			if( match != null && match.length > 0){
391				var pno = match[0].replace('#','');
392				form.find('input[name=pno]').val(pno);
393			}else{
394				form.find('input[name=pno]').val(1);
395			}
396			form.trigger('submit');
397			return false;
398		});
399		//Overlay Options
400		var em_bookings_settings_dialog = {
401			modal : true,
402			autoOpen: false,
403			minWidth: 500,
404			height: 'auto',
405			buttons: [{
406				text: EM.bookings_settings_save,
407				click: function(e){
408					e.preventDefault();
409					//we know we'll deal with cols, so wipe hidden value from main
410					var match = $("#em-bookings-table form.bookings-filter [name=cols]").val('');
411					var booking_form_cols = $('form#em-bookings-table-settings-form input.em-bookings-col-item');
412					$.each( booking_form_cols, function(i,item_match){
413						//item_match = $(item_match);
414						if( item_match.value == 1 ){
415							if( match.val() != ''){
416								match.val(match.val()+','+item_match.name);
417							}else{
418								match.val(item_match.name);
419							}
420						}
421					});
422					//submit main form
423					$('#em-bookings-table-settings').trigger('submitted'); //hook into this with bind()
424					$('#em-bookings-table form.bookings-filter').trigger('submit');					
425					$(this).dialog('close');
426				}
427			}]
428		};
429		var em_bookings_export_dialog = {
430			modal : true,
431			autoOpen: false,
432			minWidth: 500,
433			height: 'auto',
434			buttons: [{
435				text: EM.bookings_export_save,
436				click: function(e){
437					$(this).children('form').submit();
438					$(this).dialog('close');
439				}
440			}]
441		};
442		if( $("#em-bookings-table-settings").length > 0 ){
443			//Settings Overlay
444			$("#em-bookings-table-settings").dialog(em_bookings_settings_dialog);
445			$(document).delegate('#em-bookings-table-settings-trigger','click', function(e){ e.preventDefault(); $("#em-bookings-table-settings").dialog('open'); });
446			//Export Overlay
447			$("#em-bookings-table-export").dialog(em_bookings_export_dialog);
448			$(document).delegate('#em-bookings-table-export-trigger','click', function(e){ e.preventDefault(); $("#em-bookings-table-export").dialog('open'); });
449			var export_overlay_show_tickets = function(){
450				if( $('#em-bookings-table-export-form input[name=show_tickets]').is(':checked') ){
451					$('#em-bookings-table-export-form .em-bookings-col-item-ticket').show();
452					$('#em-bookings-table-export-form #em-bookings-export-cols-active .em-bookings-col-item-ticket input').val(1);
453				}else{
454					$('#em-bookings-table-export-form .em-bookings-col-item-ticket').hide().find('input').val(0);					
455				}
456			};
457			//Sync export overlay with table search field changes
458			$('#em-bookings-table form select').each(function(i, el){
459				$(el).change(function(e){
460					var select_el = $(this);
461					var input_par = $('#em-bookings-table-export-form input[name='+select_el.attr('name')+']');
462					var input_par_selected = select_el.find('option:selected');
463					input_par.val(input_par_selected.val());
464				});
465			});
466			
467			export_overlay_show_tickets();
468			$('#em-bookings-table-export-form input[name=show_tickets]').click(export_overlay_show_tickets);
469			//Sortables
470			$( ".em-bookings-cols-sortable" ).sortable({
471				connectWith: ".em-bookings-cols-sortable",
472				update: function(event, ui) {
473					if( ui.item.parents('ul#em-bookings-cols-active, ul#em-bookings-export-cols-active').length > 0 ){							
474						ui.item.addClass('ui-state-highlight').removeClass('ui-state-default').children('input').val(1);
475					}else{
476						ui.item.addClass('ui-state-default').removeClass('ui-state-highlight').children('input').val(0);
477					}
478				}
479			}).disableSelection();
480			load_ui_css = true;
481		}
482		//Widgets and filter submissions
483		$(document).delegate('#em-bookings-table form.bookings-filter', 'submit', function(e){
484			var el = $(this);			
485			//append loading spinner
486			el.parents('#em-bookings-table').find('.table-wrap').first().append('<div id="em-loading" />');
487			//ajax call
488			$.post( EM.ajaxurl, el.serializeArray(), function(data){
489				var root = el.parents('#em-bookings-table').first();
490				root.replaceWith(data);
491				//recreate overlays
492				$('#em-bookings-table-export input[name=scope]').val(root.find('select[name=scope]').val());
493				$('#em-bookings-table-export input[name=status]').val(root.find('select[name=status]').val());
494				jQuery(document).triggerHandler('em_bookings_filtered', [data, root, el]);
495			});
496			return false;
497		});
498		//Approve/Reject Links
499		$(document).delegate('.em-bookings-approve,.em-bookings-reject,.em-bookings-unapprove,.em-bookings-delete', 'click', function(){
500			var el = $(this); 
501			if( el.hasClass('em-bookings-delete') ){
502				if( !confirm(EM.booking_delete) ){ return false; }
503			}
504			var url = em_ajaxify( el.attr('href'));		
505			var td = el.parents('td').first();
506			td.html(EM.txt_loading);
507			td.load( url );
508			return false;
509		});
510	}
511	//Old Bookings Table - depreciating soon
512	if( $('.em_bookings_events_table').length > 0 ){
513		//Widgets and filter submissions
514		$(document).delegate('.em_bookings_events_table form', 'submit', function(e){
515			var el = $(this);
516			var url = em_ajaxify( el.attr('action') );		
517			el.parents('.em_bookings_events_table').find('.table-wrap').first().append('<div id="em-loading" />');
518			$.get( url, el.serializeArray(), function(data){
519				el.parents('.em_bookings_events_table').first().replaceWith(data);
520			});
521			return false;
522		});
523		//Pagination link clicks
524		$(document).delegate('.em_bookings_events_table .tablenav-pages a', 'click', function(){		
525			var el = $(this);
526			var url = em_ajaxify( el.attr('href') );	
527			el.parents('.em_bookings_events_table').find('.table-wrap').first().append('<div id="em-loading" />');
528			$.get( url, function(data){
529				el.parents('.em_bookings_events_table').first().replaceWith(data);
530			});
531			return false;
532		});
533	}
534	
535	//Manual Booking
536	$(document).on('click', 'a.em-booking-button', function(e){
537		e.preventDefault();
538		var button = $(this);
539		if( button.text() != EM.bb_booked && $(this).text() != EM.bb_booking){
540			button.text(EM.bb_booking);
541			var button_data = button.attr('id').split('_'); 
542			$.ajax({
543				url: EM.ajaxurl,
544				dataType: 'jsonp',
545				data: {
546					event_id : button_data[1],
547					_wpnonce : button_data[2],
548					action : 'booking_add_one'
549				},
550				success : function(response, statusText, xhr, $form) {
551					if(response.result){
552						button.text(EM.bb_booked);
553					}else{
554						button.text(EM.bb_error);					
555					}
556					if(response.message != '') alert(response.message);
557				},
558				error : function(){ button.text(EM.bb_error); }
559			});
560		}
561		return false;
562	});	
563	$(document).on('click', 'a.em-cancel-button', function(e){
564		e.preventDefault();
565		var button = $(this);
566		if( button.text() != EM.bb_cancelled && button.text() != EM.bb_canceling){
567			button.text(EM.bb_canceling);
568			var button_data = button.attr('id').split('_'); 
569			$.ajax({
570				url: EM.ajaxurl,
571				dataType: 'jsonp',
572				data: {
573					booking_id : button_data[1],
574					_wpnonce : button_data[2],
575					action : 'booking_cancel'
576				},
577				success : function(response, statusText, xhr, $form) {
578					if(response.result){
579						button.text(EM.bb_cancelled);
580					}else{
581						button.text(EM.bb_cancel_error);
582					}
583				},
584				error : function(){ button.text(EM.bb_cancel_error); }
585			});
586		}
587		return false;
588	});  
589
590	//Datepicker
591	if( $('.em-date-single, .em-date-range, #em-date-start').length > 0 ){
592		load_ui_css = true;
593		em_setup_datepicker('body');
594	}
595	if( load_ui_css ) em_load_jquery_css();
596	
597	//previously in em-admin.php
598	function updateIntervalDescriptor () { 
599		$(".interval-desc").hide();
600		var number = "-plural";
601		if ($('input#recurrence-interval').val() == 1 || $('input#recurrence-interval').val() == "")
602		number = "-singular";
603		var descriptor = "span#interval-"+$("select#recurrence-frequency").val()+number;
604		$(descriptor).show();
605	}
606	function updateIntervalSelectors () {
607		$('p.alternate-selector').hide();   
608		$('p#'+ $('select#recurrence-frequency').val() + "-selector").show();
609	}
610	function updateShowHideRecurrence () {
611		if( $('input#event-recurrence').is(":checked")) {
612			$("#event_recurrence_pattern").fadeIn();
613			$("#event-date-explanation").hide();
614			$("#recurrence-dates-explanation").show();
615			$("h3#recurrence-dates-title").show();
616			$("h3#event-date-title").hide();     
617		} else {
618			$("#event_recurrence_pattern").hide();
619			$("#recurrence-dates-explanation").hide();
620			$("#event-date-explanation").show();
621			$("h3#recurrence-dates-title").hide();
622			$("h3#event-date-title").show();   
623		}
624	}		 
625	$("#recurrence-dates-explanation").hide();
626	$("#date-to-submit").hide();
627	$("#end-date-to-submit").hide();
628	
629	$("#localised-date").show();
630	$("#localised-end-date").show();
631	
632	$('#em-wrapper input.select-all').change(function(){
633	 	if($(this).is(':checked')){
634			$('input.row-selector').prop('checked', true);
635			$('input.select-all').prop('checked', true);
636	 	}else{
637			$('input.row-selector').prop('checked', false);
638			$('input.select-all').prop('checked', false);
639		}
640	}); 
641	
642	updateIntervalDescriptor(); 
643	updateIntervalSelectors();
644	updateShowHideRecurrence();
645	$('input#event-recurrence').change(updateShowHideRecurrence);
646	   
647	// recurrency elements   
648	$('input#recurrence-interval').keyup(updateIntervalDescriptor);
649	$('select#recurrence-frequency').change(updateIntervalDescriptor);
650	$('select#recurrence-frequency').change(updateIntervalSelectors);
651
652	/* Load any maps */	
653	if( $('.em-location-map').length > 0 || $('.em-locations-map').length > 0 || $('#em-map').length > 0 || $('.em-search-geo').length > 0 ){
654		em_maps_load();
655	}
656	
657	//Finally, add autocomplete here
658	//Autocomplete
659	if( jQuery( "div.em-location-data input#location-name" ).length > 0 ){
660		jQuery( "div.em-location-data input#location-name" ).autocomplete({
661			source: EM.locationajaxurl,
662			minLength: 2,
663			focus: function( event, ui ){
664				jQuery("input#location-id" ).val( ui.item.value );
665				return false;
666			},			 
667			select: function( event, ui ){
668				jQuery("input#location-id" ).val(ui.item.id).trigger('change');
669				jQuery("input#location-name" ).val(ui.item.value);
670				jQuery('input#location-address').val(ui.item.address);
671				jQuery('input#location-town').val(ui.item.town);
672				jQuery('input#location-state').val(ui.item.state);
673				jQuery('input#location-region').val(ui.item.region);
674				jQuery('input#location-postcode').val(ui.item.postcode);
675				if( ui.item.country == '' ){
676					jQuery('select#location-country option:selected').removeAttr('selected');
677				}else{
678					jQuery('select#location-country option[value="'+ui.item.country+'"]').attr('selected', 'selected');
679				}
680				jQuery('div.em-location-data input, div.em-location-data select').css('background-color','#ccc').attr('readonly','readonly');
681				jQuery('#em-location-reset').show();
682				jQuery('#em-location-search-tip').hide();
683				jQuery(document).triggerHandler('em_locations_autocomplete_selected', [event, ui]);
684				return false;
685			}
686		}).data( "ui-autocomplete" )._renderItem = function( ul, item ) {
687			html_val = "<a>" + em_esc_attr(item.label) + '<br><span style="font-size:11px"><em>'+ em_esc_attr(item.address) + ', ' + em_esc_attr(item.town)+"</em></span></a>";
688			return jQuery( "<li></li>" ).data( "item.autocomplete", item ).append(html_val).appendTo( ul );
689		};
690		jQuery('#em-location-reset a').click( function(){
691			jQuery('div.em-location-data input').css('background-color','#fff').val('').removeAttr('readonly');
692			jQuery('div.em-location-data select').css('background-color','#fff');
693			jQuery('div.em-location-data option:selected').removeAttr('selected');
694			jQuery('input#location-id').val('');
695			jQuery('#em-location-reset').hide();
696			jQuery('#em-location-search-tip').show();
697			jQuery('#em-map').hide();
698			jQuery('#em-map-404').show();
699			if(typeof(marker) !== 'undefined'){
700				marker.setPosition(new google.maps.LatLng(0, 0));
701				infoWindow.close();
702				marker.setDraggable(true);
703			}
704			return false;
705		});
706		if( jQuery('input#location-id').val() != '0' && jQuery('input#location-id').val() != '' ){
707			jQuery('div.em-location-data input, div.em-location-data select').css('background-color','#ccc').attr('readonly','readonly');
708			jQuery('#em-location-reset').show();
709			jQuery('#em-location-search-tip').hide();
710		}
711	}
712	
713});
714
715function em_load_jquery_css(){
716	if( EM.ui_css && jQuery('link#jquery-ui-css').length == 0 ){
717		var script = document.createElement("link");
718		script.id = 'jquery-ui-css';
719		script.rel = "stylesheet";
720		script.href = EM.ui_css;
721		document.body.appendChild(script);
722	}
723}
724
725function em_setup_datepicker(wrap){	
726	wrap = jQuery(wrap);
727	//default picker vals
728	var datepicker_vals = { altFormat: "yy-mm-dd", changeMonth: true, changeYear: true, firstDay : EM.firstDay, yearRange:'-100:+10' };
729	if( EM.dateFormat ) datepicker_vals.dateFormat = EM.dateFormat;
730	if( EM.yearRange ) datepicker_vals.yearRange = EM.yearRange;
731	jQuery(document).triggerHandler('em_datepicker', datepicker_vals);
732	
733	//apply datepickers
734	dateDivs = wrap.find('.em-date-single, .em-date-range');
735	if( dateDivs.length > 0 ){
736		//apply datepickers to elements
737		dateDivs.find('input.em-date-input-loc').each(function(i,dateInput){
738			//init the datepicker
739			var dateInput = jQuery(dateInput);
740			var dateValue = dateInput.nextAll('input.em-date-input').first();
741			var dateValue_value = dateValue.val();
742			dateInput.datepicker(datepicker_vals);
743			dateInput.datepicker('option', 'altField', dateValue);
744			//now set the value
745			if( dateValue_value ){
746				var this_date_formatted = jQuery.datepicker.formatDate( EM.dateFormat, jQuery.datepicker.parseDate('yy-mm-dd', dateValue_value) );
747				dateInput.val(this_date_formatted);
748				dateValue.val(dateValue_value);
749			}
750			//add logic for texts
751			dateInput.change(function(){
752				if( jQuery(this).val() == '' ){
753					jQuery(this).nextAll('.em-date-input').first().val('');
754				}
755			});
756		});
757		//deal with date ranges
758		dateDivs.filter('.em-date-range').find('input.em-date-input-loc').each(function(i,dateInput){
759			//finally, apply start/end logic to this field
760			dateInput = jQuery(dateInput);
761			if( dateInput.hasClass('em-date-start') ){
762				dateInput.datepicker('option','onSelect', function( selectedDate ) {
763					//get corresponding end date input, we expect ranges to be contained in .em-date-range with a start/end input element
764					var startDate = jQuery(this);
765					var endDate = startDate.parents('.em-date-range').find('.em-date-end').first();
766					var startValue = startDate.nextAll('input.em-date-input').first().val();
767					var endValue = endDate.nextAll('input.em-date-input').first().val();
768					if( startValue > endValue && endValue != '' ){
769						endDate.datepicker( "setDate" , selectedDate );
770						endDate.trigger('change');
771					}
772					endDate.datepicker( "option", 'minDate', selectedDate );
773				});
774			}else if( dateInput.hasClass('em-date-end') ){
775				var startInput = dateInput.parents('.em-date-range').find('.em-date-start').first();
776				if( startInput.val() != '' ){
777					dateInput.datepicker('option', 'minDate', startInput.val());
778				}
779			}
780		});
781	}
782}
783
784function em_setup_timepicker(wrap){
785	wrap = jQuery(wrap);
786	var timepicker_options = {
787		show24Hours: EM.show24hours == 1,
788		step:15
789	}
790	jQuery(document).triggerHandler('em_timepicker_options', timepicker_options);
791	wrap.find(".em-time-input").timePicker(timepicker_options);
792	
793	// Keep the duration between the two inputs.
794	wrap.find(".em-time-range input.em-time-start").each( function(i, el){
795		jQuery(el).data('oldTime', jQuery.timePicker(el).getTime());
796	}).change( function() {
797		var start = jQuery(this);
798		var end = start.nextAll('.em-time-end');
799		if (end.val()) { // Only update when second input has a value.
800		    // Calculate duration.
801			var oldTime = start.data('oldTime');
802		    var duration = (jQuery.timePicker(end).getTime() - oldTime);
803		    var time = jQuery.timePicker(start).getTime();
804		    if( jQuery.timePicker(end).getTime() >= oldTime ){
805			    // Calculate and update the time in the second input.
806			    jQuery.timePicker(end).setTime(new Date(new Date(time.getTime() + duration)));
807			}
808		    start.data('oldTime', time); 
809		}
810	});
811	// Validate.
812	wrap.find(".em-time-range input.em-time-end").change(function() {
813		var end = jQuery(this);
814		var start = end.prevAll('.em-time-start');
815		if( start.val() ){
816			if( jQuery.timePicker(start).getTime() > jQuery.timePicker(this).getTime() && ( jQuery('.em-date-end').val().length == 0 || jQuery('.em-date-start').val() == jQuery('.em-date-end').val() ) ) { end.addClass("error"); }
817			else { end.removeClass("error"); }
818		}
819	});
820	//Sort out all day checkbox
821	wrap.find('.em-time-range input.em-time-all-day').change(function(){
822		var allday = jQuery(this);
823		if( allday.is(':checked') ){
824			allday.siblings('.em-time-input').css('background-color','#ccc');
825		}else{
826			allday.siblings('.em-time-input').css('background-color','#fff');
827		}
828	}).trigger('change');
829}
830
831/* Useful function for adding the em_ajax flag to a url, regardless of querystring format */
832var em_ajaxify = function(url){
833	if ( url.search('em_ajax=0') != -1){
834		url = url.replace('em_ajax=0','em_ajax=1');
835	}else if( url.search(/\?/) != -1 ){
836		url = url + "&em_ajax=1";
837	}else{
838		url = url + "?em_ajax=1";
839	}
840	return url;
841};
842
843/*
844 * MAP FUNCTIONS
845 */
846var em_maps_loaded = false;
847var maps = {};
848var maps_markers = {};
849var infoWindow;
850//loads maps script if not already loaded and executes EM maps script
851function em_maps_load(){
852	if( !em_maps_loaded ){
853		if ( jQuery('script#google-maps').length == 0 && ( typeof google !== 'object' || typeof google.maps !== 'object' ) ){ 
854			var script = document.createElement("script");
855			script.type = "text/javascript";
856			script.id = "google-maps";
857			var proto = (EM.is_ssl) ? 'https:' : 'http:';
858			if( typeof EM.google_maps_api !== 'undefined' ){
859				script.src = proto + '//maps.google.com/maps/api/js?v=3&libraries=places&callback=em_maps&key='+EM.google_maps_api;
860			}else{
861				script.src = proto + '//maps.google.com/maps/api/js?v=3&libraries=places&callback=em_maps';
862			}
863			document.body.appendChild(script);
864		}else if( typeof google === 'object' && typeof google.maps === 'object' && !em_maps_loaded ){
865			em_maps();
866		}else if( jQuery('script#google-maps').length > 0 ){
867			jQuery(window).load(function(){ if( !em_maps_loaded ) em_maps(); }); //google isn't loaded so wait for page to load resources
868		}
869	}
870}
871//re-usable function to load global location maps
872function em_maps_load_locations(el){
873	var el = jQuery(el);
874	var map_id = el.attr('id').replace('em-locations-map-','');
875	var em_data = jQuery.parseJSON( el.nextAll('.em-locations-map-coords').first().text() );
876	if( em_data == null ){
877		var em_data = jQuery.parseJSON( jQuery('#em-locations-map-coords-'+map_id).text() );
878	}
879	jQuery.getJSON(document.URL, em_data , function(data){
880		if(data.length > 0){
881			//define default options and allow option for extension via event triggers
882			  var map_options = { mapTypeId: google.maps.MapTypeId.ROADMAP };
883			  if( typeof EM.google_map_id_styles == 'object' && typeof EM.google_map_id_styles[map_id] !== 'undefined' ){ console.log(EM.google_map_id_styles[map_id]); map_options.styles = EM.google_map_id_styles[map_id]; }
884			  else if( typeof EM.google_maps_styles !== 'undefined' ){ map_options.styles = EM.google_maps_styles; }
885			  jQuery(document).triggerHandler('em_maps_locations_map_options', map_options);
886			  var marker_options = {};
887			  jQuery(document).triggerHandler('em_maps_location_marker_options', marker_options);
888			  
889			  maps[map_id] = new google.maps.Map(el[0], map_options);
890			  maps_markers[map_id] = [];
891
892			  var bounds = new google.maps.LatLngBounds();
893			  
894			  jQuery.map( data, function( location, i ){
895				  if( !(location.location_latitude == 0 && location.location_longitude == 0) ){
896					var latitude = parseFloat( location.location_latitude );
897					var longitude = parseFloat( location.location_longitude );
898					var location_position = new google.maps.LatLng( latitude, longitude );
899					//extend the default marker options
900					jQuery.extend(marker_options, {
901					    position: location_position, 
902					    map: maps[map_id]
903					})
904					var marker = new google.maps.Marker(marker_options);
905					maps_markers[map_id].push(marker);
906					marker.setTitle(location.location_name);
907					var myContent = '<div class="em-map-balloon"><div id="em-map-balloon-'+map_id+'" class="em-map-balloon-content">'+ location.location_balloon +'</div></div>';
908					em_map_infobox(marker, myContent, maps[map_id]);
909					//extend bounds
910					bounds.extend(new google.maps.LatLng(latitude,longitude))
911				  }
912			  });
913			  // Zoom in to the bounds
914			  maps[map_id].fitBounds(bounds);
915			  
916			//Call a hook if exists
917			jQuery(document).triggerHandler('em_maps_locations_hook', [maps[map_id], data, map_id, maps_markers[map_id]]);
918		}else{
919			el.children().first().html('No locations found');
920			jQuery(document).triggerHandler('em_maps_locations_hook_not_found', [el]);
921		}
922	});
923}
924function em_maps_load_location(el){
925	el = jQuery(el);
926	var map_id = el.attr('id').replace('em-location-map-','');
927	em_LatLng = new google.maps.LatLng( jQuery('#em-location-map-coords-'+map_id+' .lat').text(), jQuery('#em-location-map-coords-'+map_id+' .lng').text());
928	//extend map and markers via event triggers
929	var map_options = {
930	    zoom: 14,
931	    center: em_LatLng,
932	    mapTypeId: google.maps.MapTypeId.ROADMAP,
933	    mapTypeControl: false,
934	    gestureHandling: 'cooperative'
935	};
936	if( typeof EM.google_map_id_styles == 'object' && typeof EM.google_map_id_styles[map_id] !== 'undefined' ){ console.log(EM.google_map_id_styles[map_id]); map_options.styles = EM.google_map_id_styles[map_id]; }
937	else if( typeof EM.google_maps_styles !== 'undefined' ){ map_options.styles = EM.google_maps_styles; }
938	jQuery(document).triggerHandler('em_maps_location_map_options', map_options);
939	maps[map_id] = new google.maps.Map( document.getElementById('em-location-map-'+map_id), map_options);
940	var marker_options = {
941	    position: em_LatLng,
942	    map: maps[map_id]
943	};
944	jQuery(document).triggerHandler('em_maps_location_marker_options', marker_options);
945	maps_markers[map_id] = new google.maps.Marker(marker_options);
946	infoWindow = new google.maps.InfoWindow({ content: jQuery('#em-location-map-info-'+map_id+' .em-map-balloon').get(0) });
947	infoWindow.open(maps[map_id],maps_markers[map_id]);
948	maps[map_id].panBy(40,-70);
949	
950	//JS Hook for handling map after instantiation
951	//Example hook, which you can add elsewhere in your theme's JS - jQuery(document).bind('em_maps_location_hook', function(){ alert('hi');} );
952	jQuery(document).triggerHandler('em_maps_location_hook', [maps[map_id], infoWindow, maps_markers[map_id], map_id]);
953	//map resize listener
954	jQuery(window).on('resize', function(e) {
955		google.maps.event.trigger(maps[map_id], "resize");
956		maps[map_id].setCenter(maps_markers[map_id].getPosition());
957		maps[map_id].panBy(40,-70);
958	});
959}
960jQuery(document).bind('em_search_ajax', function(e, vars, wrapper){
961	if( em_maps_loaded ){
962		wrapper.find('.em-location-map').each( function(index, el){ em_maps_load_location(el); } );
963		wrapper.find('.em-locations-map').each( function(index, el){ em_maps_load_locations(el); });
964	}
965});
966//Load single maps (each map is treated as a seperate map).
967function em_maps() {
968	//Find all the maps on this page and load them
969	jQuery('.em-location-map').each( function(index, el){ em_maps_load_location(el); } );	
970	jQuery('.em-locations-map').each( function(index, el){ em_maps_load_locations(el); } );
971	
972	//Location stuff - only needed if inputs for location exist
973	if( jQuery('select#location-select-id, input#location-address').length > 0 ){
974		var map, marker;
975		//load map info
976		var refresh_map_location = function(){
977			var location_latitude = jQuery('#location-latitude').val();
978			var location_longitude = jQuery('#location-longitude').val();
979			if( !(location_latitude == 0 && location_longitude == 0) ){
980				var position = new google.maps.LatLng(location_latitude, location_longitude); //the location coords
981				marker.setPosition(position);
982				var mapTitle = (jQuery('input#location-name').length > 0) ? jQuery('input#location-name').val():jQuery('input#title').val();
983				mapTitle = em_esc_attr(mapTitle);
984				marker.setTitle( mapTitle );
985				jQuery('#em-map').show();
986				jQuery('#em-map-404').hide();
987				google.maps.event.trigger(map, 'resize');
988				map.setCenter(position);
989				map.panBy(40,-55);
990				infoWindow.setContent( 
991					'<div id="location-balloon-content"><strong>' + mapTitle + '</strong><br>' + 
992					em_esc_attr(jQuery('#location-address').val()) + 
993					'<br>' + em_esc_attr(jQuery('#location-town').val()) + 
994					'</div>'
995				);
996				infoWindow.open(map, marker);
997				jQuery(document).triggerHandler('em_maps_location_hook', [map, infoWindow, marker, 0]);
998			} else {
999    			jQuery('#em-map').hide();
1000    			jQuery('#em-map-404').show();
1001			}
1002		};
1003		
1004		//Add listeners for changes to address
1005		var get_map_by_id = function(id){
1006			if(jQuery('#em-map').length > 0){
1007				jQuery.getJSON(document.URL,{ em_ajax_action:'get_location', id:id }, function(data){
1008					if( data.location_latitude!=0 && data.location_longitude!=0 ){
1009						loc_latlng = new google.maps.LatLng(data.location_latitude, data.location_longitude);
1010						marker.setPosition(loc_latlng);
1011						marker.setTitle( data.location_name );
1012						marker.setDraggable(false);
1013						jQuery('#em-map').show();
1014						jQuery('#em-map-404').hide();
1015						map.setCenter(loc_latlng);
1016						map.panBy(40,-55);
1017						infoWindow.setContent( '<div id="location-balloon-content">'+ data.location_balloon +'</div>');
1018						infoWindow.open(map, marker);
1019						google.maps.event.trigger(map, 'resize');
1020						jQuery(document).triggerHandler('em_maps_location_hook', [map, infoWindow, marker, 0]);
1021					}else{
1022						jQuery('#em-map').hide();
1023						jQuery('#em-map-404').show();
1024					}
1025				});
1026			}
1027		};
1028		jQuery('#location-select-id, input#location-id').change( function(){get_map_by_id(jQuery(this).val());} );
1029		jQuery('#location-name, #location-town, #location-address, #location-state, #location-postcode, #location-country').change( function(){
1030			//build address
1031			var addresses = [ jQuery('#location-address').val(), jQuery('#location-town').val(), jQuery('#location-state').val(), jQuery('#location-postcode').val() ];
1032			var address = '';
1033			jQuery.each( addresses, function(i, val){
1034				if( val != '' ){
1035					address = ( address == '' ) ? address+val:address+', '+val;
1036				}
1037			});
1038			if( address == '' ){ //in case only name is entered, no address
1039				jQuery('#em-map').hide();
1040				jQuery('#em-map-404').show();
1041				return false;
1042			}
1043			//do country last, as it's using the text version
1044			if( jQuery('#location-country option:selected').val() != 0 ){
1045				address = ( address == '' ) ? address+jQuery('#location-country option:selected').text():address+', '+jQuery('#location-country option:selected').text();
1046			}
1047			if( address != '' && jQuery('#em-map').length > 0 ){
1048				geocoder.geocode( { 'address': address }, function(results, status) {
1049				    if (status == google.maps.GeocoderStatus.OK) {
1050						jQuery('#location-latitude').val(results[0].geometry.location.lat());
1051						jQuery('#location-longitude').val(results[0].geometry.location.lng());
1052					}
1053				    refresh_map_location();
1054				});
1055			}
1056		});
1057		
1058		//Load map
1059		if(jQuery('#em-map').length > 0){
1060			var em_LatLng = new google.maps.LatLng(0, 0);
1061			var map_options = {
1062				    zoom: 14,
1063				    center: em_LatLng,
1064				    mapTypeId: google.maps.MapTypeId.ROADMAP,
1065				    mapTypeControl: false,
1066				    gestureHandling: 'cooperative'
1067			};
1068			if( typeof EM.google_maps_styles !== 'undefined' ){ map_options.styles = EM.google_maps_styles; }
1069			map = new google.maps.Map( document.getElementById('em-map'), map_options);
1070			var marker = new google.maps.Marker({
1071			    position: em_LatLng,
1072			    map: map,
1073			    draggable: true
1074			});
1075			infoWindow = new google.maps.InfoWindow({
1076			    content: ''
1077			});
1078			var geocoder = new google.maps.Geocoder();
1079			google.maps.event.addListener(infoWindow, 'domready', function() { 
1080				document.getElementById('location-balloon-content').parentNode.style.overflow=''; 
1081				document.getElementById('location-balloon-content').parentNode.parentNode.style.overflow=''; 
1082			});
1083			google.maps.event.addListener(marker, 'dragend', function() {
1084				var position = marker.getPosition();
1085				jQuery('#location-latitude').val(position.lat());
1086				jQuery('#location-longitude').val(position.lng());
1087				map.setCenter(position);
1088				map.panBy(40,-55);
1089			});
1090			if( jQuery('#location-select-id').length > 0 ){
1091				jQuery('#location-select-id').trigger('change');
1092			}else{
1093				refresh_map_location();
1094			}
1095			jQuery(document).triggerHandler('em_map_loaded', [map, infoWindow, marker]);
1096		}
1097		//map resize listener
1098		jQuery(window).on('resize', function(e) {
1099			google.maps.event.trigger(map, "resize");
1100			map.setCenter(marker.getPosition());
1101			map.panBy(40,-55);
1102		});
1103	}
1104	em_maps_loaded = true; //maps have been loaded
1105	jQuery(document).triggerHandler('em_maps_loaded');
1106}
1107  
1108function em_map_infobox(marker, message, map) {
1109  var iw = new google.maps.InfoWindow({ content: message });
1110  google.maps.event.addListener(marker, 'click', function() {
1111	if( infoWindow ) infoWindow.close();
1112	infoWindow = iw;
1113    iw.open(map,marker);
1114  });
1115}
1116
1117function em_esc_attr( str ){
1118	if( typeof str !== 'string' ) return '';
1119	return str.replace(/</gi,'&lt;').replace(/>/gi,'&gt;');
1120}
1121
1122/* jQuery timePicker - http://labs.perifer.se/timedatepicker/ @ http://github.com/perifer/timePicker commit 100644 */
1123(function(e){function t(t,n,r,i){t.value=e(n).text();e(t).change();if(!navigator.userAgent.match(/msie/i)){t.focus()}r.hide()}function n(e,t){var n=e.getHours();var i=t.show24Hours?n:(n+11)%12+1;var s=e.getMinutes();return r(i)+t.separator+r(s)+(t.show24Hours?"":n<12?" AM":" PM")}function r(e){return(e<10?"0":"")+e}function i(e,t){return typeof e=="object"?o(e):s(e,t)}function s(e,t){if(e){var n=e.split(t.separator);var r=parseFloat(n[0]);var i=parseFloat(n[1]);if(!t.show24Hours){if(r===12&&e.indexOf("AM")!==-1){r=0}else if(r!==12&&e.indexOf("PM")!==-1){r+=12}}var s=new Date(0,0,0,r,i,0);return o(s)}return null}function o(e){e.setFullYear(2001);e.setMonth(0);e.setDate(0);return e}e.fn.timePicker=function(t){var n=e.extend({},e.fn.timePicker.defaults,t);return this.each(function(){e.timePicker(this,n)})};e.timePicker=function(t,n){var r=e(t)[0];return r.timePicker||(r.timePicker=new jQuery._timePicker(r,n))};e.timePicker.version="0.3";e._timePicker=function(r,u){var a=false;var f=false;var l=i(u.startTime,u);var c=i(u.endTime,u);var h="selected";var p="li."+h;e(r).attr("autocomplete","OFF");var d=[];var v=new Date(l);while(v<=c){d[d.length]=n(v,u);v=new Date(v.setMinutes(v.getMinutes()+u.step))}var m=e('<div class="time-picker'+(u.show24Hours?"":" time-picker-12hours")+'"></div>');var g=e("<ul></ul>");for(var y=0;y<d.length;y++){g.append("<li>"+d[y]+"</li>")}m.append(g);m.appendTo("body").hide();m.mouseover(function(){a=true}).mouseout(function(){a=false});e("li",g).mouseover(function(){if(!f){e(p,m).removeClass(h);e(this).addClass(h)}}).mousedown(function(){a=true}).click(function(){t(r,this,m,u);a=false});var b=function(){if(m.is(":visible")){return false}e("li",m).removeClass(h);var t=e(r).offset();m.css({top:t.top+r.offsetHeight,left:t.left});m.show();var i=r.value?s(r.value,u):l;var a=l.getHours()*60+l.getMinutes();var f=i.getHours()*60+i.getMinutes()-a;var p=Math.round(f/u.step);var d=o(new Date(0,0,0,0,p*u.step+a,0));d=l<d&&d<=c?d:l;var v=e("li:contains("+n(d,u)+")",m);if(v.length){v.addClass(h);m[0].scrollTop=v[0].offsetTop}return true};e(r).focus(b).click(b);e(r).blur(function(){if(!a){m.hide()}});e(r)["keydown"](function(n){var i;f=true;var s=m[0].scrollTop;switch(n.keyCode){case 38:if(b()){return false}i=e(p,g);var o=i.prev().addClass(h)[0];if(o){i.removeClass(h);if(o.offsetTop<s){m[0].scrollTop=s-o.offsetHeight}}else{i.removeClass(h);o=e("li:last",g).addClass(h)[0];m[0].scrollTop=o.offsetTop-o.offsetHeight}return false;break;case 40:if(b()){return false}i=e(p,g);var a=i.next().addClass(h)[0];if(a){i.removeClass(h);if(a.offsetTop+a.offsetHeight>s+m[0].offsetHeight){m[0].scrollTop=s+a.offsetHeight}}else{i.removeClass(h);a=e("li:first",g).addClass(h)[0];m[0].scrollTop=0}return false;break;case 13:if(m.is(":visible")){var l=e(p,g)[0];t(r,l,m,u)}return false;break;case 27:m.hide();return false;break}return true});e(r).keyup(function(e){f=false});this.getTime=function(){return s(r.value,u)};this.setTime=function(t){r.value=n(i(t,u),u);e(r).change()}};e.fn.timePicker.defaults={step:30,startTime:new Date(0,0,0,0,0,0),endTime:new Date(0,0,0,23,30,0),separator:":",show24Hours:true}})(jQuery)

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.