// source --> https://polskipsychologwuk.com/wp-content/plugins/booking-ultra-pro/js/bup-front.js 
if(typeof $ == 'undefined'){
	var $ = jQuery;
}
(function($) {
    jQuery(document).ready(function () { 
	
	   "use strict";
	   
	 //  alert(bup_pro_front.country_detection);
	 // Disable Staff Dropdown
	 jQuery('#bup-staff').prop('disabled',true);

	//  jQuery('#bup-provider-tooltip[title]').tipsy({
	//       arrowWidth: 0, //arrow css border-width + margin-(left|right), default is 5 + 5
	//       attr: 'data-tipsy', //default attributes for tipsy - data-tipsy-position | data-tipsy-offset | data-tipsy-disabled
	//       cls: 'bup-provider-tooltip-holder', //tipsy custom class
	//       duration: 150, //tipsy fadeIn, fadeOut duration
	//       offset: 0, //tipsy offset from element
	//       position: 'bottom-right', //tipsy position - top-left | top-center | top-right | bottom-left | bottom-center | bottom-right | left | right
	//       trigger: 'hover', // how tooltip is triggered - hover | focus | click | manual
	//       onShow: null, //onShow event
	//       onHide: null //onHide event
	// })
	  
	   if(bup_pro_front.country_detection != 'no'  ){
		   
	   
		  jQuery("#reg_telephone").intlTelInput({
			  // allowDropdown: false,
			  // autoHideDialCode: false,
			  // autoPlaceholder: "off",
			  // dropdownContainer: "body",
			  // excludeCountries: ["us"],
			  // formatOnDisplay: false,
			  geoIpLookup: function(callback) {
				 jQuery.get("http://ipinfo.io", function() {}, "jsonp").always(function(resp) {
				   var countryCode = (resp && resp.country) ? resp.country : "";
				  callback(countryCode);
				});
			   },
			  // hiddenInput: "full_number",
				initialCountry: "auto",
			  // nationalMode: false,
			  // onlyCountries: ['us', 'gb', 'ch', 'ca', 'do'],
			  // placeholderNumberType: "MOBILE",
			  // preferredCountries: ['cn', 'jp'],
			  // separateDialCode: true,
			  utilsScript: "../js/int-phone-code/js/utils.js"
			});
		
	   }else{
		   
		   // alert('NO Active');
		   
		   }
	   
	   // Adding jQuery Datepicker
		jQuery(function() {
			
			if(BUPdayslimitarray.version == 1 && BUPdayslimitarray.dayslimit_key != ''){
				jQuery( ".bupro-datepicker" ).datepicker({ 
					showOtherMonths: true, 
					dateFormat: bup_pro_front.bb_date_picker_format, 
					closeText: BUPDatePicker.closeText,
					currentText: BUPDatePicker.currentText,
					monthNames: BUPDatePicker.monthNames,
					monthNamesShort: BUPDatePicker.monthNamesShort,
					dayNames: BUPDatePicker.dayNames,
					dayNamesShort: BUPDatePicker.dayNamesShort,
					dayNamesMin: BUPDatePicker.dayNamesMin,
					firstDay: BUPDatePicker.firstDay,
					isRTL: BUPDatePicker.isRTL,
					minDate: 0,
					maxDate: (BUPdayslimitarray.dayslimit_key)-1
				});
			}
			else{
				jQuery( ".bupro-datepicker" ).datepicker({ 
					showOtherMonths: true, 
					dateFormat: bup_pro_front.bb_date_picker_format, 
					closeText: BUPDatePicker.closeText,
					currentText: BUPDatePicker.currentText,
					monthNames: BUPDatePicker.monthNames,
					monthNamesShort: BUPDatePicker.monthNamesShort,
					dayNames: BUPDatePicker.dayNames,
					dayNamesShort: BUPDatePicker.dayNamesShort,
					dayNamesMin: BUPDatePicker.dayNamesMin,
					firstDay: BUPDatePicker.firstDay,
					isRTL: BUPDatePicker.isRTL,
					 minDate: 0
				 });
			}
		
			jQuery("#ui-datepicker-div").wrap('<div class="ui-datepicker-wrapper" />');
		});
		
		
	
	jQuery(document).on("click", ".bup_payment_options", function(e) {
		
		
		var payment_method =  jQuery(this).attr("data-method");
		
		if(payment_method=='stripe')
		{
			$(".bup-profile-field-cc").slideDown();
			
			
		}else{
			
			$(".bup-profile-field-cc").slideUp();
						
		}			
			
		
				
       });
	   
	 
	//this loads step 2	
	jQuery(document).on("click", ".bup-btn-delete-cart-item", function(e) {
			
			var cart_item=   jQuery(this).attr("item-cart-id");	
								
    		jQuery.ajax({
					type: 'POST',
					url: ajaxurl,
					data: {"action": "bup_delete_cart_item", "cart_item": cart_item},
					
					success: function(data){					
																	
					
						bup_reload_cart();	
										    
						

						}
				});			
			
			 
    		e.preventDefault();		 
				
        });
		
	jQuery(document).on("click", "#bup-btn-clean-cart", function(e) {
			
						
			var cart_item=   jQuery(this).attr("item-cart-id");	
								
    		jQuery.ajax({
					type: 'POST',
					url: ajaxurl,
					data: {"action": "bup_clear_cart", "cart_item": cart_item},
					
					success: function(data){					
																	
						bup_reload_cart();	
										    
						}
				});			
			
			 
    		e.preventDefault();		 
				
    });
		
	//checkout page with form
	jQuery(document).on("click", "#bup-btn-checkout-cart", function(e) {
			
			var template_id=   jQuery("#template_id").val();
	 		jQuery.ajax({
					type: 'POST',
					url: ajaxurl,
					data: {"action": "bup_display_cart_checkout", "template_id": template_id},
					
					success: function(data){					
																	
					
						var res =jQuery.parseJSON(data);						
						if(res.response=='OK')
						{
							bup_update_booking_steps(3);						
						}
											
						jQuery("#bup-steps-cont-res").html(res.content);
										    
						bup_phone_format();

						}
				});			
			
			 
    		e.preventDefault();		 
				
        });
		
		
		
	//this loads step 2	
	jQuery(document).on("click", "#bup-btn-next-step1", function(e) {
			
						
			var b_category=   jQuery("#bup-category").val();
			var b_date=   jQuery("#bup-start-date").val();
			var b_staff=   jQuery("#bup-staff").val();
			var b_location=   jQuery("#bup-filter-id").val();
			var template_id=   jQuery("#template_id").val();
			var booking_form_type=   jQuery("#bup_booking_form_type").val();	
			jQuery("#bup-err-message" ).html( '' );			
			jQuery("#bup-steps-cont-res").html(bup_pro_front.message_wait_availability);				
						
    		jQuery.ajax({
					type: 'POST',
					url: ajaxurl,
					data: {"action": "ubp_book_step_2", "b_category": b_category, "b_date": b_date , "b_staff": b_staff, "b_location": b_location, "template_id": template_id },
					
					success: function(data){		
						var res =jQuery.parseJSON(data);						
						if(res.response=='OK')
						{
							bup_update_booking_steps(2);						
						}
										
						jQuery("#bup-steps-cont-res").html(res.content);											
						}
				});				
			 
    		e.preventDefault();		 
				
        });
		
		
		//load cart
		
		jQuery(document).on("click", "#bup-btn-show-cart", function(e) {
			
			bup_reload_cart(); 	 
    		e.preventDefault();		 
				
        });
		
		jQuery(document).on("change", "#bup-category, #bup-filter-id", function(e) {
			
			var b_category=   jQuery("#bup-category").val();
			var filter_id=   jQuery("#bup-filter-id").val();
			var template_id=   jQuery("#template_id").val();	
			
			
			if(b_category.length == 0) {				

				jQuery("#bup-staff-booking-list").html(`
					 <label>With <a id="bup-provider-tooltip" title="Please Select Service First"><i class="fa fa-question-circle" aria-hidden="true"></i></a> </label> 
						<select name="bup-staff" id="bup-staff">
							<option value="" selected="selected" >Please select provider</option>							
					</select>`);
				$('#bup-staff').prop('disabled', true);	
				
				return;
			}
			
			$('#bup-staff option:first-child').attr("selected", "selected");
			$('#bup-staff option:first-child').text(bup_pro_front.message_wait_staff_box);		
									

    		jQuery.ajax({
					type: 'POST',
					url: ajaxurl,
					data: {"action": "bup_load_dw_of_staff", "b_category": b_category, "filter_id": filter_id , "template_id": template_id},
					
					success: function(data){						
						var res = data;	
						jQuery("#bup-staff-booking-list").html(res);
						$('#bup-staff').prop('disabled', false);					    
						

						}
				});			
			
			
    		e.preventDefault();		 
				
        });
		

		
	
	jQuery(document).on("change", "#bup-purchased-qty", function(e) {
			
						
			var b_qty=   jQuery("#bup-purchased-qty").val();
			var service_id=   jQuery("#service_id").val();
			var staff_id=   jQuery("#staff_id").val();
			
    		jQuery.ajax({
					type: 'POST',
					url: ajaxurl,
					data: {"action": "bup_update_purchase_total", 
					"b_qty": b_qty, "service_id": service_id , "staff_id": staff_id},
					
					success: function(data){						
						
						var res = data;
						var res =jQuery.parseJSON(data);						
						if(res.response=='OK')
						{
							jQuery("#bup-total-booking-amount").html(res.amount_with_symbol);
							jQuery("#bup_service_cost").val(res.amount);
						
						}

						

						}
				});			
			
			
    		e.preventDefault();		 
				
        });
		
		
	
			
	//this loads step 3	
	/*jQuery(document).on("click", ".bup-btn-book-app", function(e) {
			
			e.preventDefault();			
			
			var date_to_book =  jQuery(this).attr("bup-data-date");
			var service_and_staff_id =  jQuery(this).attr("bup-data-service-staff");
			var time_slot =  jQuery(this).attr("bup-data-timeslot");
			var form_id =  jQuery("#bup-custom-form-id").val();
			var location_id =  jQuery("#bup-filter-id").val();
			
			var field_legends =  jQuery("#field_legends").val();
			var placeholders =  jQuery("#placeholders").val();
			var template_id =  jQuery("#template_id").val();
			
			var max_capacity =   jQuery(this).attr("bup-max-capacity"); 
			var max_available =   jQuery(this).attr("bup-max-available"); 
			
			jQuery("#bup-err-message" ).html( '' );		
			
			
			jQuery.ajax({
						type: 'POST',
						url: ajaxurl,
						data: {"action": "ubp_book_step_3", "date_to_book": date_to_book, "service_and_staff_id": service_and_staff_id  , "time_slot": time_slot , "form_id": form_id , "location_id": location_id  , "field_legends": field_legends  , 
						"placeholders": placeholders,
						"template_id": template_id ,
						"max_capacity": max_capacity,
						"max_available": max_available },
						
						success: function(data){
							
							//alert('ok');
							
							var res = data;
							var res =jQuery.parseJSON(data);
													
							if(res.response=='OK')
							{
								bup_update_booking_steps(3);						
							}
												
							jQuery("#bup-steps-cont-res").html(res.content);
							$("#bup-registration-form").validationEngine({promptPosition: 'inline'});				    
							
	
						}
						
			
				});
						
    		e.preventDefault();		 
				
        });*/
		
	/*	jQuery(document).on("click", ".bup-btn-book-app", function(e) {
			
			e.preventDefault();			
			
			var date_to_book =  jQuery(this).attr("bup-data-date");
			var service_and_staff_id =  jQuery(this).attr("bup-data-service-staff");
			var time_slot =  jQuery(this).attr("bup-data-timeslot");
			var form_id =  jQuery("#bup-custom-form-id").val();
			var location_id =  jQuery("#bup-filter-id").val();
			
			var field_legends =  jQuery("#field_legends").val();
			var placeholders =  jQuery("#placeholders").val();
			var template_id =  jQuery("#template_id").val();
			var show_cart =  jQuery("#bup_cart_id").val();
			
			var max_capacity =   jQuery(this).attr("bup-max-capacity"); 
			var max_available =   jQuery(this).attr("bup-max-available"); 
			
			jQuery("#bup-err-message" ).html( '' );		
			
			var completeCalled = false;
			
			jQuery('body, html').animate({scrollTop: jQuery("#bup-steps-cont-res").offset().top   }, 1500,
			
				function() {
					
					if(!completeCalled){
						
						completeCalled = true;
					
						jQuery.ajax({
							type: 'POST',
							url: ajaxurl,
							data: {"action": "ubp_book_step_3", "date_to_book": date_to_book, "service_and_staff_id": service_and_staff_id  , "time_slot": time_slot , "form_id": form_id , "location_id": location_id  , "field_legends": field_legends  , 
							"placeholders": placeholders,
							"template_id": template_id ,
							"max_capacity": max_capacity,
							"max_available": max_available },
							
							success: function(data){
								
								var res = data;
								var res =jQuery.parseJSON(data);
														
								if(res.response=='OK')
								{
									bup_update_booking_steps(3);						
								}
								
								
								if(show_cart==1){
									
									bup_reload_cart();											
								
								
								}else{
									
									jQuery("#bup-steps-cont-res").html(res.content);
									$("#bup-registration-form").validationEngine({promptPosition: 'inline'});
									
								}
								
		
							}
						});	
					
					
					}	
					
			
				}
			
			);
						
    		e.preventDefault();		 
				
        });*/
		
		//this is for the li element on reduced layout
		jQuery(document).on("click", ".bup-btn-book-app-li", function(e) {
			
			e.preventDefault();			
			
			var date_to_book =  jQuery(this).attr("bup-data-date");
			var service_and_staff_id =  jQuery(this).attr("bup-data-service-staff");
			var time_slot =  jQuery(this).attr("bup-data-timeslot");
			var form_id =  jQuery("#bup-custom-form-id").val();
			var location_id =  jQuery("#bup-filter-id").val();
			
			var field_legends =  jQuery("#field_legends").val();
			var placeholders =  jQuery("#placeholders").val();
			var template_id =  jQuery("#template_id").val();
			var show_cart =  jQuery("#bup_cart_id").val();
			
			var max_capacity =   jQuery(this).attr("bup-max-capacity"); 
			var max_available =   jQuery(this).attr("bup-max-available"); 
			
			jQuery("#bup-err-message" ).html( '' );		
			
			var completeCalled = false;
			
			jQuery('body, html').animate({scrollTop: jQuery("#bup-steps-cont-res").offset().top   }, 1500,
			
				function() {
					
					if(!completeCalled){
						
						completeCalled = true;
					
						jQuery.ajax({
							type: 'POST',
							url: ajaxurl,
							data: {"action": "ubp_book_step_3", 
							"date_to_book": date_to_book, 
							"service_and_staff_id": service_and_staff_id  , 
							"time_slot": time_slot , 
							"form_id": form_id , 
							"location_id": location_id  , 
							"field_legends": field_legends  , 
							"placeholders": placeholders,
							"template_id": template_id ,
							"max_capacity": max_capacity,
							"max_available": max_available },
							
							success: function(data){
								
								var res = data;
								var res =jQuery.parseJSON(data);
														
								if(res.response=='OK')
								{
									bup_update_booking_steps(3);						
								}
								
								
								if(show_cart==1){
									
									bup_reload_cart();	
                                    bup_update_booking_steps(33);
								
								
								}else{
									
									jQuery("#bup-steps-cont-res").html(res.content);
									$("#bup-registration-form").validationEngine({promptPosition: 'inline'});
									
								}
								
								//reoload phone format
								
								bup_phone_format();
								
								
		
							}
						});	
					
					
					}	
					
			
				}
			
			);
						
    		e.preventDefault();		 
				
        });
		
		jQuery(document).on("click", "#bup-btn-book-app-confirm", function(e) {
			
			e.preventDefault();
			
			$("#bup-registration-form").validationEngine({promptPosition: 'inline'});				
			var frm_validation  = $("#bup-registration-form").validationEngine('validate');	
			
		
			//check if user is a staff member trying to purchase an own service
			
			 if(bup_pro_front.country_detection != 'no'  ){
				 
				 var intlNumber = $("#reg_telephone").intlTelInput("getNumber");					
				jQuery("#full_number").val(intlNumber);
				
				var countryData = $("#reg_telephone").intlTelInput("getSelectedCountryData");
				
				jQuery("#full_number_prefix").val(countryData.dialCode);
				jQuery("#full_number_iso").val(countryData.iso2);
				 
				 				 
			}
			
			if(frm_validation)
			{
							
				var myRadioPayment = $('input[name=bup_payment_method]');
				var payment_method_selected = myRadioPayment.filter(':checked').val();				
				var payment_method =  jQuery("#bup_payment_method_stripe_hidden").val();
				
				if(payment_method=='stripe' && payment_method_selected=='stripe')
				{
					var wait_message = '<div class="bup_wait">' + bup_pro_front.wait_submit + '</div>';				
					jQuery('#bup-stripe-payment-errors').html(wait_message);					
					bup_stripe_process_card();
				
				} else if (payment_method=='stripe' && payment_method_selected=='authorize') {
					
					
				
				}else{
					
					
					jQuery("#bup-message-submit-booking-conf").html(bup_pro_front.message_wait_availability);					
					$('#bup-btn-book-app-confirm').prop('disabled', 'disabled');					
					$("#bup-registration-form").submit();
				
				}
				
				
			}else{
				
			}
			
									
    		e.preventDefault();		 
				
        });
		
 
       
    }); //END READY
})(jQuery);

function bup_update_booking_steps(current_step){
	
	var show_cart =  jQuery("#bup_cart_id").val();
	
	bup_update_booking_steps_remove_all();				
	jQuery( "#bup-step-rounded-" + current_step).removeClass( "bup-cart-step-inactive" ).addClass( "bup-cart-step-active" );
	
	if(current_step==3)	
	{	
		if(show_cart==1)
		{
			jQuery("#bup-btn-next-step1").text( bup_pro_front.button_legend_step3_cart);
		
		}else{
			
			jQuery("#bup-btn-next-step1").text( bup_pro_front.button_legend_step3);
		}
	
	}
	
	if(current_step==2)	
	{		
		jQuery("#bup-btn-next-step1").text( bup_pro_front.button_legend_step2);
	
	}		

}

function bup_update_booking_steps_remove_all()
{				
	
	jQuery( "#bup-step-rounded-1, #bup-step-rounded-2, #bup-step-rounded-3, #bup-step-rounded-33, #bup-step-rounded-4" ).removeClass( "bup-cart-step-active" ).addClass( "bup-cart-step-inactive" );				


}


function bup_load_step_4(order_key){
		
		
		jQuery("#bup-steps-cont-res").html(bup_pro_front.message_wait_availability);			
			
			jQuery.ajax({
					type: 'POST',
					url: ajaxurl,
					data: {"action": "ubp_book_step_4", "order_key": order_key},
					
					success: function(data){					
						
						var res = data;								
						jQuery("#bup-steps-cont-res").html(res);
						bup_update_booking_steps(4);					    
						

						}
				});	
	
}

function bup_load_staff_by_service(b_category){
	
	
			var filter_id=   jQuery("#bup-filter-id").val();
			var template_id=   jQuery("#template_id").val();	
			
			$('#bup-staff').prop('disabled', 'disabled');
			
			$('#bup-staff option:first-child').attr("selected", "selected");
			$('#bup-staff option:first-child').text(bup_pro_front.message_wait_staff_box);									
						
    		jQuery.ajax({
					type: 'POST',
					url: ajaxurl,
					data: {"action": "bup_load_dw_of_staff", "b_category": b_category, "filter_id": filter_id , "template_id": template_id},
					
					success: function(data){					
						
						var res = data;								
						jQuery("#bup-staff-booking-list").html(res);
						$('#bup-staff').prop('disabled', false);					    
						

						}
				});			
			
}

function bup_phone_format(){
	

if(bup_pro_front.country_detection != 'no'  ){
	
	 jQuery("#reg_telephone").intlTelInput({
			  // allowDropdown: false,
			  // autoHideDialCode: false,
			  // autoPlaceholder: "off",
			  // dropdownContainer: "body",
			  // excludeCountries: ["us"],
			  // formatOnDisplay: false,
			  geoIpLookup: function(callback) {
				 jQuery.get("https://ipinfo.io", function() {}, "jsonp").always(function(resp) {
				   var countryCode = (resp && resp.country) ? resp.country : "";
				  callback(countryCode);
				});
			   },
			   hiddenInput: "full_number",
				initialCountry: "auto",
			  // nationalMode: false,
			  // onlyCountries: ['us', 'gb', 'ch', 'ca', 'do'],
			   placeholderNumberType: "MOBILE",
			  // preferredCountries: ['cn', 'jp'],
			  // separateDialCode: true,
			//  utilsScript: "../js/int-phone-code/js/utils.js"
			   utilsScript: bup_pro_front.country_util_url
			  
			  
			});
	}

}


function bup_auto_display_slots(b_category, b_staff){	

			var b_date=   jQuery("#bup-start-date").val();
			var b_location=   jQuery("#bup-filter-id").val();
			var template_id=   jQuery("#template_id").val();
			var booking_form_type=   jQuery("#bup_booking_form_type").val();	
			
			jQuery("#bup-err-message" ).html( '' );			
			jQuery("#bup-steps-cont-res").html(bup_pro_front.message_wait_availability);				
						
    		jQuery.ajax({
					type: 'POST',
					url: ajaxurl,
					data: {"action": "ubp_book_step_2", "b_category": b_category, "b_date": b_date , "b_staff": b_staff, "b_location": b_location, "template_id": template_id },
					
					success: function(data){						
						
						var res =jQuery.parseJSON(data);						
						if(res.response=='OK')
						{
							bup_update_booking_steps(2);						
						}
											
						jQuery("#bup-steps-cont-res").html(res.content);											
										    
						

						}
				});				
			 
}

function bup_reload_cart(){	
	
	var template_id=   jQuery("#template_id").val();
		
			jQuery.ajax({
					type: 'POST',
					url: ajaxurl,
					data: {"action": "bup_get_shopping_cart","reload_cart": "reload_cart","template_id": template_id},
					
					success: function(data){					
						
						var res = data;								
						jQuery("#bup-steps-cont-res").html(res);
                        bup_update_booking_steps(33);
									    
						

						}
						
						,
				  error: function(errorThrown){
					  alert(errorThrown);
				  } 
				});	
	
};
// source --> https://polskipsychologwuk.com/wp-includes/js/plupload/moxie.min.js?ver=1.3.5.1 
var MXI_DEBUG=!1;!function(o,x){"use strict";var s={};function n(e,t){for(var i,n=[],r=0;r<e.length;++r){if(!(i=s[e[r]]||function(e){for(var t=o,i=e.split(/[.\/]/),n=0;n<i.length;++n){if(!t[i[n]])return;t=t[i[n]]}return t}(e[r])))throw"module definition dependecy not found: "+e[r];n.push(i)}t.apply(null,n)}function e(e,t,i){if("string"!=typeof e)throw"invalid module definition, module id must be defined and be a string";if(t===x)throw"invalid module definition, dependencies must be specified";if(i===x)throw"invalid module definition, definition function must be specified";n(t,function(){s[e]=i.apply(null,arguments)})}e("moxie/core/utils/Basic",[],function(){function n(i){return s(arguments,function(e,t){0<t&&s(e,function(e,t){void 0!==e&&(o(i[t])===o(e)&&~r(o(e),["array","object"])?n(i[t],e):i[t]=e)})}),i}function s(e,t){var i,n,r;if(e)if("number"===o(e.length)){for(r=0,i=e.length;r<i;r++)if(!1===t(e[r],r))return}else if("object"===o(e))for(n in e)if(e.hasOwnProperty(n)&&!1===t(e[n],n))return}function r(e,t){if(t){if(Array.prototype.indexOf)return Array.prototype.indexOf.call(t,e);for(var i=0,n=t.length;i<n;i++)if(t[i]===e)return i}return-1}var o=function(e){return void 0===e?"undefined":null===e?"null":e.nodeType?"node":{}.toString.call(e).match(/\s([a-z|A-Z]+)/)[1].toLowerCase()};a=0;var a;return{guid:function(e){for(var t=(new Date).getTime().toString(32),i=0;i<5;i++)t+=Math.floor(65535*Math.random()).toString(32);return(e||"o_")+t+(a++).toString(32)},typeOf:o,extend:n,each:s,isEmptyObj:function(e){if(e&&"object"===o(e))for(var t in e)return!1;return!0},inSeries:function(e,n){var r=e.length;"function"!==o(n)&&(n=function(){}),e&&e.length||n(),function t(i){"function"===o(e[i])&&e[i](function(e){++i<r&&!e?t(i):n(e)})}(0)},inParallel:function(e,i){var n=0,r=e.length,o=new Array(r);s(e,function(e,t){e(function(e){if(e)return i(e);e=[].slice.call(arguments);e.shift(),o[t]=e,++n===r&&(o.unshift(null),i.apply(this,o))})})},inArray:r,arrayDiff:function(e,t){var i,n=[];for(i in"array"!==o(e)&&(e=[e]),"array"!==o(t)&&(t=[t]),e)-1===r(e[i],t)&&n.push(e[i]);return!!n.length&&n},arrayIntersect:function(e,t){var i=[];return s(e,function(e){-1!==r(e,t)&&i.push(e)}),i.length?i:null},toArray:function(e){for(var t=[],i=0;i<e.length;i++)t[i]=e[i];return t},trim:function(e){return e&&(String.prototype.trim?String.prototype.trim.call(e):e.toString().replace(/^\s*/,"").replace(/\s*$/,""))},sprintf:function(e){var t=[].slice.call(arguments,1);return e.replace(/%[a-z]/g,function(){var e=t.shift();return"undefined"!==o(e)?e:""})},parseSizeStr:function(e){var t,i;return"string"!=typeof e?e:(t={t:1099511627776,g:1073741824,m:1048576,k:1024},i=(e=/^([0-9\.]+)([tmgk]?)$/.exec(e.toLowerCase().replace(/[^0-9\.tmkg]/g,"")))[2],e=+e[1],t.hasOwnProperty(i)&&(e*=t[i]),Math.floor(e))}}}),e("moxie/core/utils/Env",["moxie/core/utils/Basic"],function(n){m="function",h="object",r=function(e,t){return-1!==t.toLowerCase().indexOf(e.toLowerCase())},o={browser:[[/(opera\smini)\/([\w\.-]+)/i,/(opera\s[mobiletab]+).+version\/([\w\.-]+)/i,/(opera).+version\/([\w\.]+)/i,/(opera)[\/\s]+([\w\.]+)/i],[a="name",c="version"],[/\s(opr)\/([\w\.]+)/i],[[a,"Opera"],c],[/(kindle)\/([\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]+)*/i,/(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?([\w\.]*)/i,/(?:ms|\()(ie)\s([\w\.]+)/i,/(rekonq)\/([\w\.]+)*/i,/(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi)\/([\w\.-]+)/i],[a,c],[/(trident).+rv[:\s]([\w\.]+).+like\sgecko/i],[[a,"IE"],c],[/(edge)\/((\d+)?[\w\.]+)/i],[a,c],[/(yabrowser)\/([\w\.]+)/i],[[a,"Yandex"],c],[/(comodo_dragon)\/([\w\.]+)/i],[[a,/_/g," "],c],[/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i,/(uc\s?browser|qqbrowser)[\/\s]?([\w\.]+)/i],[a,c],[/(dolfin)\/([\w\.]+)/i],[[a,"Dolphin"],c],[/((?:android.+)crmo|crios)\/([\w\.]+)/i],[[a,"Chrome"],c],[/XiaoMi\/MiuiBrowser\/([\w\.]+)/i],[c,[a,"MIUI Browser"]],[/android.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)/i],[c,[a,"Android Browser"]],[/FBAV\/([\w\.]+);/i],[c,[a,"Facebook"]],[/version\/([\w\.]+).+?mobile\/\w+\s(safari)/i],[c,[a,"Mobile Safari"]],[/version\/([\w\.]+).+?(mobile\s?safari|safari)/i],[c,a],[/webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i],[a,[c,(i={rgx:function(){for(var e,t,i,n,r,o,s,a=0,u=arguments;a<u.length;a+=2){var c=u[a],l=u[a+1];if(void 0===e)for(n in e={},l)typeof(r=l[n])==h?e[r[0]]=d:e[r]=d;for(t=i=0;t<c.length;t++)if(o=c[t].exec(this.getUA())){for(n=0;n<l.length;n++)s=o[++i],typeof(r=l[n])==h&&0<r.length?2==r.length?typeof r[1]==m?e[r[0]]=r[1].call(this,s):e[r[0]]=r[1]:3==r.length?typeof r[1]!=m||r[1].exec&&r[1].test?e[r[0]]=s?s.replace(r[1],r[2]):d:e[r[0]]=s?r[1].call(this,s,r[2]):d:4==r.length&&(e[r[0]]=s?r[3].call(this,s.replace(r[1],r[2])):d):e[r]=s||d;break}if(o)break}return e},str:function(e,t){for(var i in t)if(typeof t[i]==h&&0<t[i].length){for(var n=0;n<t[i].length;n++)if(r(t[i][n],e))return"?"===i?d:i}else if(r(t[i],e))return"?"===i?d:i;return e}}).str,(e={browser:{oldsafari:{major:{1:["/8","/1","/3"],2:"/4","?":"/"},version:{"1.0":"/8",1.2:"/1",1.3:"/3","2.0":"/412","2.0.2":"/416","2.0.3":"/417","2.0.4":"/419","?":"/"}}},device:{sprint:{model:{"Evo Shift 4G":"7373KT"},vendor:{HTC:"APA",Sprint:"Sprint"}}},os:{windows:{version:{ME:"4.90","NT 3.11":"NT3.51","NT 4.0":"NT4.0",2e3:"NT 5.0",XP:["NT 5.1","NT 5.2"],Vista:"NT 6.0",7:"NT 6.1",8:"NT 6.2",8.1:"NT 6.3",RT:"ARM"}}}}).browser.oldsafari.version]],[/(konqueror)\/([\w\.]+)/i,/(webkit|khtml)\/([\w\.]+)/i],[a,c],[/(navigator|netscape)\/([\w\.-]+)/i],[[a,"Netscape"],c],[/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i,/(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/([\w\.-]+)/i,/(mozilla)\/([\w\.]+).+rv\:.+gecko\/\d+/i,/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf)[\/\s]?([\w\.]+)/i,/(links)\s\(([\w\.]+)/i,/(gobrowser)\/?([\w\.]+)*/i,/(ice\s?browser)\/v?([\w\._]+)/i,/(mosaic)[\/\s]([\w\.]+)/i],[a,c]],engine:[[/windows.+\sedge\/([\w\.]+)/i],[c,[a,"EdgeHTML"]],[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i,/(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i,/(icab)[\/\s]([23]\.[\d\.]+)/i],[a,c],[/rv\:([\w\.]+).*(gecko)/i],[c,a]],os:[[/microsoft\s(windows)\s(vista|xp)/i],[a,c],[/(windows)\snt\s6\.2;\s(arm)/i,/(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i],[a,[c,i.str,e.os.windows.version]],[/(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i],[[a,"Windows"],[c,i.str,e.os.windows.version]],[/\((bb)(10);/i],[[a,"BlackBerry"],c],[/(blackberry)\w*\/?([\w\.]+)*/i,/(tizen)[\/\s]([\w\.]+)/i,/(android|webos|palm\os|qnx|bada|rim\stablet\sos|meego|contiki)[\/\s-]?([\w\.]+)*/i,/linux;.+(sailfish);/i],[a,c],[/(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i],[[a,"Symbian"],c],[/\((series40);/i],[a],[/mozilla.+\(mobile;.+gecko.+firefox/i],[[a,"Firefox OS"],c],[/(nintendo|playstation)\s([wids3portablevu]+)/i,/(mint)[\/\s\(]?(\w+)*/i,/(mageia|vectorlinux)[;\s]/i,/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\/\s-]?([\w\.-]+)*/i,/(hurd|linux)\s?([\w\.]+)*/i,/(gnu)\s?([\w\.]+)*/i],[a,c],[/(cros)\s[\w]+\s([\w\.]+\w)/i],[[a,"Chromium OS"],c],[/(sunos)\s?([\w\.]+\d)*/i],[[a,"Solaris"],c],[/\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i],[a,c],[/(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i],[[a,"iOS"],[c,/_/g,"."]],[/(mac\sos\sx)\s?([\w\s\.]+\w)*/i,/(macintosh|mac(?=_powerpc)\s)/i],[[a,"Mac OS"],[c,/_/g,"."]],[/((?:open)?solaris)[\/\s-]?([\w\.]+)*/i,/(haiku)\s(\w+)/i,/(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i,/(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms)/i,/(unix)\s?([\w\.]+)*/i],[a,c]]};var d,m,h,r,i,o,e=function(e){var t=e||(window&&window.navigator&&window.navigator.userAgent?window.navigator.userAgent:"");this.getBrowser=function(){return i.rgx.apply(this,o.browser)},this.getEngine=function(){return i.rgx.apply(this,o.engine)},this.getOS=function(){return i.rgx.apply(this,o.os)},this.getResult=function(){return{ua:this.getUA(),browser:this.getBrowser(),engine:this.getEngine(),os:this.getOS()}},this.getUA=function(){return t},this.setUA=function(e){return t=e,this},this.setUA(t)};function t(e){var t=[].slice.call(arguments);return t.shift(),"function"===n.typeOf(u[e])?u[e].apply(this,t):!!u[e]}u={define_property:!1,create_canvas:!(!(a=document.createElement("canvas")).getContext||!a.getContext("2d")),return_response_type:function(e){try{if(-1!==n.inArray(e,["","text","document"]))return!0;if(window.XMLHttpRequest){var t=new XMLHttpRequest;if(t.open("get","/"),"responseType"in t)return t.responseType=e,t.responseType===e}}catch(e){}return!1},use_data_uri:((s=new Image).onload=function(){u.use_data_uri=1===s.width&&1===s.height},setTimeout(function(){s.src="data:image/gif;base64,R0lGODlhAQABAIAAAP8AAAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="},1),!1),use_data_uri_over32kb:function(){return u.use_data_uri&&("IE"!==l.browser||9<=l.version)},use_data_uri_of:function(e){return u.use_data_uri&&e<33e3||u.use_data_uri_over32kb()},use_fileinput:function(){var e;return!navigator.userAgent.match(/(Android (1.0|1.1|1.5|1.6|2.0|2.1))|(Windows Phone (OS 7|8.0))|(XBLWP)|(ZuneWP)|(w(eb)?OSBrowser)|(webOS)|(Kindle\/(1.0|2.0|2.5|3.0))/)&&((e=document.createElement("input")).setAttribute("type","file"),!e.disabled)}};var s,a,u,c=(new e).getResult(),l={can:t,uaParser:e,browser:c.browser.name,version:c.browser.version,os:c.os.name,osVersion:c.os.version,verComp:function(e,t,i){function n(e){return(e=(e=(""+e).replace(/[_\-+]/g,".")).replace(/([^.\d]+)/g,".$1.").replace(/\.{2,}/g,".")).length?e.split("."):[-8]}function r(e){return e?isNaN(e)?u[e]||-7:parseInt(e,10):0}var o,s=0,a=0,u={dev:-6,alpha:-5,a:-5,beta:-4,b:-4,RC:-3,rc:-3,"#":-2,p:1,pl:1};for(e=n(e),t=n(t),o=Math.max(e.length,t.length),s=0;s<o;s++)if(e[s]!=t[s]){if(e[s]=r(e[s]),t[s]=r(t[s]),e[s]<t[s]){a=-1;break}if(e[s]>t[s]){a=1;break}}if(!i)return a;switch(i){case">":case"gt":return 0<a;case">=":case"ge":return 0<=a;case"<=":case"le":return a<=0;case"==":case"=":case"eq":return 0===a;case"<>":case"!=":case"ne":return 0!==a;case"":case"<":case"lt":return a<0;default:return null}},global_event_dispatcher:"moxie.core.EventTarget.instance.dispatchEvent"};return l.OS=l.os,MXI_DEBUG&&(l.debug={runtime:!0,events:!1},l.log=function(){var e,t,i=arguments[0];"string"===n.typeOf(i)&&(i=n.sprintf.apply(this,arguments)),window&&window.console&&window.console.log?window.console.log(i):document&&((e=document.getElementById("moxie-console"))||((e=document.createElement("pre")).id="moxie-console",document.body.appendChild(e)),-1!==n.inArray(n.typeOf(i),["object","array"])?(t=i,e.appendChild(document.createTextNode(t+"\n"))):e.appendChild(document.createTextNode(i+"\n")))}),l}),e("moxie/core/I18n",["moxie/core/utils/Basic"],function(i){var t={};return{addI18n:function(e){return i.extend(t,e)},translate:function(e){return t[e]||e},_:function(e){return this.translate(e)},sprintf:function(e){var t=[].slice.call(arguments,1);return e.replace(/%[a-z]/g,function(){var e=t.shift();return"undefined"!==i.typeOf(e)?e:""})}}}),e("moxie/core/utils/Mime",["moxie/core/utils/Basic","moxie/core/I18n"],function(a,n){var e={mimes:{},extensions:{},addMimeType:function(e){for(var t,i,n=e.split(/,/),r=0;r<n.length;r+=2){for(i=n[r+1].split(/ /),t=0;t<i.length;t++)this.mimes[i[t]]=n[r];this.extensions[n[r]]=i}},extList2mimes:function(e,t){for(var i,n,r,o=[],s=0;s<e.length;s++)for(i=e[s].extensions.split(/\s*,\s*/),n=0;n<i.length;n++){if("*"===i[n])return[];if((r=this.mimes[i[n]])&&-1===a.inArray(r,o)&&o.push(r),t&&/^\w+$/.test(i[n]))o.push("."+i[n]);else if(!r)return[]}return o},mimes2exts:function(e){var n=this,r=[];return a.each(e,function(e){if("*"===e)return!(r=[]);var i=e.match(/^(\w+)\/(\*|\w+)$/);i&&("*"===i[2]?a.each(n.extensions,function(e,t){new RegExp("^"+i[1]+"/").test(t)&&[].push.apply(r,n.extensions[t])}):n.extensions[e]&&[].push.apply(r,n.extensions[e]))}),r},mimes2extList:function(e){var t=[],i=[];return"string"===a.typeOf(e)&&(e=a.trim(e).split(/\s*,\s*/)),i=this.mimes2exts(e),t.push({title:n.translate("Files"),extensions:i.length?i.join(","):"*"}),t.mimes=e,t},getFileExtension:function(e){e=e&&e.match(/\.([^.]+)$/);return e?e[1].toLowerCase():""},getFileMime:function(e){return this.mimes[this.getFileExtension(e)]||""}};return e.addMimeType("application/msword,doc dot,application/pdf,pdf,application/pgp-signature,pgp,application/postscript,ps ai eps,application/rtf,rtf,application/vnd.ms-excel,xls xlb,application/vnd.ms-powerpoint,ppt pps pot,application/zip,zip,application/x-shockwave-flash,swf swfl,application/vnd.openxmlformats-officedocument.wordprocessingml.document,docx,application/vnd.openxmlformats-officedocument.wordprocessingml.template,dotx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xlsx,application/vnd.openxmlformats-officedocument.presentationml.presentation,pptx,application/vnd.openxmlformats-officedocument.presentationml.template,potx,application/vnd.openxmlformats-officedocument.presentationml.slideshow,ppsx,application/x-javascript,js,application/json,json,audio/mpeg,mp3 mpga mpega mp2,audio/x-wav,wav,audio/x-m4a,m4a,audio/ogg,oga ogg,audio/aiff,aiff aif,audio/flac,flac,audio/aac,aac,audio/ac3,ac3,audio/x-ms-wma,wma,image/bmp,bmp,image/gif,gif,image/jpeg,jpg jpeg jpe,image/photoshop,psd,image/png,png,image/svg+xml,svg svgz,image/tiff,tiff tif,text/plain,asc txt text diff log,text/html,htm html xhtml,text/css,css,text/csv,csv,text/rtf,rtf,video/mpeg,mpeg mpg mpe m2v,video/quicktime,qt mov,video/mp4,mp4,video/x-m4v,m4v,video/x-flv,flv,video/x-ms-wmv,wmv,video/avi,avi,video/webm,webm,video/3gpp,3gpp 3gp,video/3gpp2,3g2,video/vnd.rn-realvideo,rv,video/ogg,ogv,video/x-matroska,mkv,application/vnd.oasis.opendocument.formula-template,otf,application/octet-stream,exe"),e}),e("moxie/core/utils/Dom",["moxie/core/utils/Env"],function(c){function i(e,t){return!!e.className&&new RegExp("(^|\\s+)"+t+"(\\s+|$)").test(e.className)}return{get:function(e){return"string"!=typeof e?e:document.getElementById(e)},hasClass:i,addClass:function(e,t){i(e,t)||(e.className=e.className?e.className.replace(/\s+$/,"")+" "+t:t)},removeClass:function(e,t){e.className&&(t=new RegExp("(^|\\s+)"+t+"(\\s+|$)"),e.className=e.className.replace(t,function(e,t,i){return" "===t&&" "===i?" ":""}))},getStyle:function(e,t){return e.currentStyle?e.currentStyle[t]:window.getComputedStyle?window.getComputedStyle(e,null)[t]:void 0},getPos:function(e,t){var i,n,r,o=0,s=0,a=document;function u(e){var t,i=0,n=0;return e&&(e=e.getBoundingClientRect(),t="CSS1Compat"===a.compatMode?a.documentElement:a.body,i=e.left+t.scrollLeft,n=e.top+t.scrollTop),{x:i,y:n}}if(t=t||a.body,e&&e.getBoundingClientRect&&"IE"===c.browser&&(!a.documentMode||a.documentMode<8))return n=u(e),r=u(t),{x:n.x-r.x,y:n.y-r.y};for(i=e;i&&i!=t&&i.nodeType;)o+=i.offsetLeft||0,s+=i.offsetTop||0,i=i.offsetParent;for(i=e.parentNode;i&&i!=t&&i.nodeType;)o-=i.scrollLeft||0,s-=i.scrollTop||0,i=i.parentNode;return{x:o,y:s}},getSize:function(e){return{w:e.offsetWidth||e.clientWidth,h:e.offsetHeight||e.clientHeight}}}}),e("moxie/core/Exceptions",["moxie/core/utils/Basic"],function(e){function t(e,t){for(var i in e)if(e[i]===t)return i;return null}return{RuntimeError:(a={NOT_INIT_ERR:1,NOT_SUPPORTED_ERR:9,JS_ERR:4},e.extend(d,a),d.prototype=Error.prototype,d),OperationNotAllowedException:(e.extend(l,{NOT_ALLOWED_ERR:1}),l.prototype=Error.prototype,l),ImageError:(s={WRONG_FORMAT:1,MAX_RESOLUTION_ERR:2,INVALID_META_ERR:3},e.extend(c,s),c.prototype=Error.prototype,c),FileException:(o={NOT_FOUND_ERR:1,SECURITY_ERR:2,ABORT_ERR:3,NOT_READABLE_ERR:4,ENCODING_ERR:5,NO_MODIFICATION_ALLOWED_ERR:6,INVALID_STATE_ERR:7,SYNTAX_ERR:8},e.extend(u,o),u.prototype=Error.prototype,u),DOMException:(r={INDEX_SIZE_ERR:1,DOMSTRING_SIZE_ERR:2,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,INVALID_CHARACTER_ERR:5,NO_DATA_ALLOWED_ERR:6,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INUSE_ATTRIBUTE_ERR:10,INVALID_STATE_ERR:11,SYNTAX_ERR:12,INVALID_MODIFICATION_ERR:13,NAMESPACE_ERR:14,INVALID_ACCESS_ERR:15,VALIDATION_ERR:16,TYPE_MISMATCH_ERR:17,SECURITY_ERR:18,NETWORK_ERR:19,ABORT_ERR:20,URL_MISMATCH_ERR:21,QUOTA_EXCEEDED_ERR:22,TIMEOUT_ERR:23,INVALID_NODE_TYPE_ERR:24,DATA_CLONE_ERR:25},e.extend(n,r),n.prototype=Error.prototype,n),EventException:(e.extend(i,{UNSPECIFIED_EVENT_TYPE_ERR:0}),i.prototype=Error.prototype,i)};function i(e){this.code=e,this.name="EventException"}function n(e){this.code=e,this.name=t(r,e),this.message=this.name+": DOMException "+this.code}var r,o,s,a;function u(e){this.code=e,this.name=t(o,e),this.message=this.name+": FileException "+this.code}function c(e){this.code=e,this.name=t(s,e),this.message=this.name+": ImageError "+this.code}function l(e){this.code=e,this.name="OperationNotAllowedException"}function d(e){this.code=e,this.name=t(a,e),this.message=this.name+": RuntimeError "+this.code}}),e("moxie/core/EventTarget",["moxie/core/utils/Env","moxie/core/Exceptions","moxie/core/utils/Basic"],function(c,l,d){function e(){var u={};d.extend(this,{uid:null,init:function(){this.uid||(this.uid=d.guid("uid_"))},addEventListener:function(e,t,i,n){var r,o=this;this.hasOwnProperty("uid")||(this.uid=d.guid("uid_")),e=d.trim(e),/\s/.test(e)?d.each(e.split(/\s+/),function(e){o.addEventListener(e,t,i,n)}):(e=e.toLowerCase(),i=parseInt(i,10)||0,(r=u[this.uid]&&u[this.uid][e]||[]).push({fn:t,priority:i,scope:n||this}),u[this.uid]||(u[this.uid]={}),u[this.uid][e]=r)},hasEventListener:function(e){e=e?u[this.uid]&&u[this.uid][e]:u[this.uid];return e||!1},removeEventListener:function(e,t){e=e.toLowerCase();var i,n=u[this.uid]&&u[this.uid][e];if(n){if(t){for(i=n.length-1;0<=i;i--)if(n[i].fn===t){n.splice(i,1);break}}else n=[];n.length||(delete u[this.uid][e],d.isEmptyObj(u[this.uid])&&delete u[this.uid])}},removeAllEventListeners:function(){u[this.uid]&&delete u[this.uid]},dispatchEvent:function(e){var t,i,n,r,o,s={},a=!0;if("string"!==d.typeOf(e)){if(r=e,"string"!==d.typeOf(r.type))throw new l.EventException(l.EventException.UNSPECIFIED_EVENT_TYPE_ERR);e=r.type,void 0!==r.total&&void 0!==r.loaded&&(s.total=r.total,s.loaded=r.loaded),s.async=r.async||!1}return-1!==e.indexOf("::")?(r=e.split("::"),t=r[0],e=r[1]):t=this.uid,e=e.toLowerCase(),(i=u[t]&&u[t][e])&&(i.sort(function(e,t){return t.priority-e.priority}),(n=[].slice.call(arguments)).shift(),s.type=e,n.unshift(s),MXI_DEBUG&&c.debug.events&&c.log("Event '%s' fired on %u",s.type,t),o=[],d.each(i,function(t){n[0].target=t.scope,o.push(s.async?function(e){setTimeout(function(){e(!1===t.fn.apply(t.scope,n))},1)}:function(e){e(!1===t.fn.apply(t.scope,n))})}),o.length)&&d.inSeries(o,function(e){a=!e}),a},bind:function(){this.addEventListener.apply(this,arguments)},unbind:function(){this.removeEventListener.apply(this,arguments)},unbindAll:function(){this.removeAllEventListeners.apply(this,arguments)},trigger:function(){return this.dispatchEvent.apply(this,arguments)},handleEventProps:function(e){var t=this;this.bind(e.join(" "),function(e){e="on"+e.type.toLowerCase();"function"===d.typeOf(this[e])&&this[e].apply(this,arguments)}),d.each(e,function(e){e="on"+e.toLowerCase(e),"undefined"===d.typeOf(t[e])&&(t[e]=null)})}})}return e.instance=new e,e}),e("moxie/runtime/Runtime",["moxie/core/utils/Env","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/EventTarget"],function(c,l,d,i){var n={},m={};function h(e,t,r,i,n){var o,s,a=this,u=l.guid(t+"_"),n=n||"browser";e=e||{},m[u]=this,r=l.extend({access_binary:!1,access_image_binary:!1,display_media:!1,do_cors:!1,drag_and_drop:!1,filter_by_extension:!0,resize_image:!1,report_upload_progress:!1,return_response_headers:!1,return_response_type:!1,return_status_code:!0,send_custom_headers:!1,select_file:!1,select_folder:!1,select_multiple:!0,send_binary_string:!1,send_browser_cookies:!0,send_multipart:!0,slice_blob:!1,stream_upload:!1,summon_file_dialog:!1,upload_filesize:!0,use_http_method:!0},r),e.preferred_caps&&(n=h.getMode(i,e.preferred_caps,n)),MXI_DEBUG&&c.debug.runtime&&c.log("\tdefault mode: %s",n),s={},o={exec:function(e,t,i,n){if(o[t]&&(s[e]||(s[e]={context:this,instance:new o[t]}),s[e].instance[i]))return s[e].instance[i].apply(this,n)},removeInstance:function(e){delete s[e]},removeAllInstances:function(){var i=this;l.each(s,function(e,t){"function"===l.typeOf(e.instance.destroy)&&e.instance.destroy.call(e.context),i.removeInstance(t)})}},l.extend(this,{initialized:!1,uid:u,type:t,mode:h.getMode(i,e.required_caps,n),shimid:u+"_container",clients:0,options:e,can:function(e,t){var i,n=arguments[2]||r;if("string"===l.typeOf(e)&&"undefined"===l.typeOf(t)&&(e=h.parseCaps(e)),"object"!==l.typeOf(e))return"function"===l.typeOf(n[e])?n[e].call(this,t):t===n[e];for(i in e)if(!this.can(i,e[i],n))return!1;return!0},getShimContainer:function(){var e,t=d.get(this.shimid);return t||(e=this.options.container?d.get(this.options.container):document.body,(t=document.createElement("div")).id=this.shimid,t.className="moxie-shim moxie-shim-"+this.type,l.extend(t.style,{position:"absolute",top:"0px",left:"0px",width:"1px",height:"1px",overflow:"hidden"}),e.appendChild(t),e=null),t},getShim:function(){return o},shimExec:function(e,t){var i=[].slice.call(arguments,2);return a.getShim().exec.call(this,this.uid,e,t,i)},exec:function(e,t){var i=[].slice.call(arguments,2);return a[e]&&a[e][t]?a[e][t].apply(this,i):a.shimExec.apply(this,arguments)},destroy:function(){var e;a&&((e=d.get(this.shimid))&&e.parentNode.removeChild(e),o&&o.removeAllInstances(),this.unbindAll(),delete m[this.uid],this.uid=null,a=o=null)}}),this.mode&&e.required_caps&&!this.can(e.required_caps)&&(this.mode=!1)}return h.order="html5,html4",h.getRuntime=function(e){return m[e]||!1},h.addConstructor=function(e,t){t.prototype=i.instance,n[e]=t},h.getConstructor=function(e){return n[e]||null},h.getInfo=function(e){var t=h.getRuntime(e);return t?{uid:t.uid,type:t.type,mode:t.mode,can:function(){return t.can.apply(t,arguments)}}:null},h.parseCaps=function(e){var t={};return"string"!==l.typeOf(e)?e||{}:(l.each(e.split(","),function(e){t[e]=!0}),t)},h.can=function(e,t){var e=h.getConstructor(e);return!!e&&(t=(e=new e({required_caps:t})).mode,e.destroy(),!!t)},h.thatCan=function(e,t){var i,n=(t||h.order).split(/\s*,\s*/);for(i in n)if(h.can(n[i],e))return n[i];return null},h.getMode=function(n,e,t){var r=null;if("undefined"===l.typeOf(t)&&(t="browser"),e&&!l.isEmptyObj(n)){if(l.each(e,function(e,t){if(n.hasOwnProperty(t)){var i=n[t](e);if("string"==typeof i&&(i=[i]),r){if(!(r=l.arrayIntersect(r,i)))return MXI_DEBUG&&c.debug.runtime&&c.log("\t\t%c: %v (conflicting mode requested: %s)",t,e,i),r=!1}else r=i}MXI_DEBUG&&c.debug.runtime&&c.log("\t\t%c: %v (compatible modes: %s)",t,e,r)}),r)return-1!==l.inArray(t,r)?t:r[0];if(!1===r)return!1}return t},h.capTrue=function(){return!0},h.capFalse=function(){return!1},h.capTest=function(e){return function(){return!!e}},h}),e("moxie/runtime/RuntimeClient",["moxie/core/utils/Env","moxie/core/Exceptions","moxie/core/utils/Basic","moxie/runtime/Runtime"],function(a,u,t,c){return function(){var s;t.extend(this,{connectRuntime:function(r){var e,o=this;if("string"===t.typeOf(r)?e=r:"string"===t.typeOf(r.ruid)&&(e=r.ruid),e){if(s=c.getRuntime(e))return s.clients++,s;throw new u.RuntimeError(u.RuntimeError.NOT_INIT_ERR)}!function e(t){var i,n;t.length?(i=t.shift().toLowerCase(),(n=c.getConstructor(i))?(MXI_DEBUG&&a.debug.runtime&&(a.log("Trying runtime: %s",i),a.log(r)),(s=new n(r)).bind("Init",function(){s.initialized=!0,MXI_DEBUG&&a.debug.runtime&&a.log("Runtime '%s' initialized",s.type),setTimeout(function(){s.clients++,o.trigger("RuntimeInit",s)},1)}),s.bind("Error",function(){MXI_DEBUG&&a.debug.runtime&&a.log("Runtime '%s' failed to initialize",s.type),s.destroy(),e(t)}),MXI_DEBUG&&a.debug.runtime&&a.log("\tselected mode: %s",s.mode),s.mode?s.init():s.trigger("Error")):e(t)):(o.trigger("RuntimeError",new u.RuntimeError(u.RuntimeError.NOT_INIT_ERR)),s=null)}((r.runtime_order||c.order).split(/\s*,\s*/))},disconnectRuntime:function(){s&&--s.clients<=0&&s.destroy(),s=null},getRuntime:function(){return s&&s.uid?s:s=null},exec:function(){return s?s.exec.apply(this,arguments):null}})}}),e("moxie/file/FileInput",["moxie/core/utils/Basic","moxie/core/utils/Env","moxie/core/utils/Mime","moxie/core/utils/Dom","moxie/core/Exceptions","moxie/core/EventTarget","moxie/core/I18n","moxie/runtime/Runtime","moxie/runtime/RuntimeClient"],function(o,i,n,s,a,e,u,c,l){var d=["ready","change","cancel","mouseenter","mouseleave","mousedown","mouseup"];function t(r){MXI_DEBUG&&i.log("Instantiating FileInput...");var e,t=this;if(-1!==o.inArray(o.typeOf(r),["string","node"])&&(r={browse_button:r}),!(e=s.get(r.browse_button)))throw new a.DOMException(a.DOMException.NOT_FOUND_ERR);e={accept:[{title:u.translate("All Files"),extensions:"*"}],name:"file",multiple:!1,required_caps:!1,container:e.parentNode||document.body},"string"==typeof(r=o.extend({},e,r)).required_caps&&(r.required_caps=c.parseCaps(r.required_caps)),"string"==typeof r.accept&&(r.accept=n.mimes2extList(r.accept)),e=(e=s.get(r.container))||document.body,"static"===s.getStyle(e,"position")&&(e.style.position="relative"),e=null,l.call(t),o.extend(t,{uid:o.guid("uid_"),ruid:null,shimid:null,files:null,init:function(){t.bind("RuntimeInit",function(e,n){t.ruid=n.uid,t.shimid=n.shimid,t.bind("Ready",function(){t.trigger("Refresh")},999),t.bind("Refresh",function(){var e,t=s.get(r.browse_button),i=s.get(n.shimid);t&&(e=s.getPos(t,s.get(r.container)),t=s.getSize(t),i)&&o.extend(i.style,{top:e.y+"px",left:e.x+"px",width:t.w+"px",height:t.h+"px"})}),n.exec.call(t,"FileInput","init",r)}),t.connectRuntime(o.extend({},r,{required_caps:{select_file:!0}}))},disable:function(e){var t=this.getRuntime();t&&t.exec.call(this,"FileInput","disable","undefined"===o.typeOf(e)||e)},refresh:function(){t.trigger("Refresh")},destroy:function(){var e=this.getRuntime();e&&(e.exec.call(this,"FileInput","destroy"),this.disconnectRuntime()),"array"===o.typeOf(this.files)&&o.each(this.files,function(e){e.destroy()}),this.files=null,this.unbindAll()}}),this.handleEventProps(d)}return t.prototype=e.instance,t}),e("moxie/core/utils/Encode",[],function(){function d(e){return unescape(encodeURIComponent(e))}function m(e){return decodeURIComponent(escape(e))}return{utf8_encode:d,utf8_decode:m,atob:function(e,t){if("function"==typeof window.atob)return t?m(window.atob(e)):window.atob(e);var i,n,r,o,s,a,u="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",c=0,l=0,d=[];if(!e)return e;for(e+="";i=(s=u.indexOf(e.charAt(c++))<<18|u.indexOf(e.charAt(c++))<<12|(r=u.indexOf(e.charAt(c++)))<<6|(o=u.indexOf(e.charAt(c++))))>>16&255,n=s>>8&255,s=255&s,d[l++]=64==r?String.fromCharCode(i):64==o?String.fromCharCode(i,n):String.fromCharCode(i,n,s),c<e.length;);return a=d.join(""),t?m(a):a},btoa:function(e,t){if(t&&(e=d(e)),"function"==typeof window.btoa)return window.btoa(e);var i,n,r,o,s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",a=0,u=0,t="",c=[];if(!e)return e;for(;i=(o=e.charCodeAt(a++)<<16|e.charCodeAt(a++)<<8|e.charCodeAt(a++))>>12&63,n=o>>6&63,r=63&o,c[u++]=s.charAt(o>>18&63)+s.charAt(i)+s.charAt(n)+s.charAt(r),a<e.length;);var t=c.join(""),l=e.length%3;return(l?t.slice(0,l-3):t)+"===".slice(l||3)}}}),e("moxie/file/Blob",["moxie/core/utils/Basic","moxie/core/utils/Encode","moxie/runtime/RuntimeClient"],function(o,i,n){var s={};return function r(e,t){n.call(this),e&&this.connectRuntime(e),t?"string"===o.typeOf(t)&&(t={data:t}):t={},o.extend(this,{uid:t.uid||o.guid("uid_"),ruid:e,size:t.size||0,type:t.type||"",slice:function(e,t,i){return this.isDetached()?function(e,t,i){var n=s[this.uid];return"string"===o.typeOf(n)&&n.length?((i=new r(null,{type:i,size:t-e})).detach(n.substr(e,i.size)),i):null}.apply(this,arguments):this.getRuntime().exec.call(this,"Blob","slice",this.getSource(),e,t,i)},getSource:function(){return s[this.uid]||null},detach:function(e){var t;this.ruid&&(this.getRuntime().exec.call(this,"Blob","destroy"),this.disconnectRuntime(),this.ruid=null),"data:"==(e=e||"").substr(0,5)&&(t=e.indexOf(";base64,"),this.type=e.substring(5,t),e=i.atob(e.substring(t+8))),this.size=e.length,s[this.uid]=e},isDetached:function(){return!this.ruid&&"string"===o.typeOf(s[this.uid])},destroy:function(){this.detach(),delete s[this.uid]}}),t.data?this.detach(t.data):s[this.uid]=t}}),e("moxie/file/File",["moxie/core/utils/Basic","moxie/core/utils/Mime","moxie/file/Blob"],function(r,o,s){function e(e,t){var i,n;t=t||{},s.apply(this,arguments),this.type||(this.type=o.getFileMime(t.name)),t.name?n=(n=t.name.replace(/\\/g,"/")).substr(n.lastIndexOf("/")+1):this.type&&(i=this.type.split("/")[0],n=r.guid((""!==i?i:"file")+"_"),o.extensions[this.type])&&(n+="."+o.extensions[this.type][0]),r.extend(this,{name:n||r.guid("file_"),relativePath:"",lastModifiedDate:t.lastModifiedDate||(new Date).toLocaleString()})}return e.prototype=s.prototype,e}),e("moxie/file/FileDrop",["moxie/core/I18n","moxie/core/utils/Dom","moxie/core/Exceptions","moxie/core/utils/Basic","moxie/core/utils/Env","moxie/file/File","moxie/runtime/RuntimeClient","moxie/core/EventTarget","moxie/core/utils/Mime"],function(t,r,e,o,s,i,a,n,u){var c=["ready","dragenter","dragleave","drop","error"];function l(i){MXI_DEBUG&&s.log("Instantiating FileDrop...");var e,n=this;"string"==typeof i&&(i={drop_zone:i}),e={accept:[{title:t.translate("All Files"),extensions:"*"}],required_caps:{drag_and_drop:!0}},(i="object"==typeof i?o.extend({},e,i):e).container=r.get(i.drop_zone)||document.body,"static"===r.getStyle(i.container,"position")&&(i.container.style.position="relative"),"string"==typeof i.accept&&(i.accept=u.mimes2extList(i.accept)),a.call(n),o.extend(n,{uid:o.guid("uid_"),ruid:null,files:null,init:function(){n.bind("RuntimeInit",function(e,t){n.ruid=t.uid,t.exec.call(n,"FileDrop","init",i),n.dispatchEvent("ready")}),n.connectRuntime(i)},destroy:function(){var e=this.getRuntime();e&&(e.exec.call(this,"FileDrop","destroy"),this.disconnectRuntime()),this.files=null,this.unbindAll()}}),this.handleEventProps(c)}return l.prototype=n.instance,l}),e("moxie/file/FileReader",["moxie/core/utils/Basic","moxie/core/utils/Encode","moxie/core/Exceptions","moxie/core/EventTarget","moxie/file/Blob","moxie/runtime/RuntimeClient"],function(e,n,r,t,o,i){var s=["loadstart","progress","load","abort","error","loadend"];function a(){function t(e,t){if(this.trigger("loadstart"),this.readyState===a.LOADING)this.trigger("error",new r.DOMException(r.DOMException.INVALID_STATE_ERR)),this.trigger("loadend");else if(t instanceof o)if(this.result=null,this.readyState=a.LOADING,t.isDetached()){var i=t.getSource();switch(e){case"readAsText":case"readAsBinaryString":this.result=i;break;case"readAsDataURL":this.result="data:"+t.type+";base64,"+n.btoa(i)}this.readyState=a.DONE,this.trigger("load"),this.trigger("loadend")}else this.connectRuntime(t.ruid),this.exec("FileReader","read",e,t);else this.trigger("error",new r.DOMException(r.DOMException.NOT_FOUND_ERR)),this.trigger("loadend")}i.call(this),e.extend(this,{uid:e.guid("uid_"),readyState:a.EMPTY,result:null,error:null,readAsBinaryString:function(e){t.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){t.call(this,"readAsDataURL",e)},readAsText:function(e){t.call(this,"readAsText",e)},abort:function(){this.result=null,-1===e.inArray(this.readyState,[a.EMPTY,a.DONE])&&(this.readyState===a.LOADING&&(this.readyState=a.DONE),this.exec("FileReader","abort"),this.trigger("abort"),this.trigger("loadend"))},destroy:function(){this.abort(),this.exec("FileReader","destroy"),this.disconnectRuntime(),this.unbindAll()}}),this.handleEventProps(s),this.bind("Error",function(e,t){this.readyState=a.DONE,this.error=t},999),this.bind("Load",function(e){this.readyState=a.DONE},999)}return a.EMPTY=0,a.LOADING=1,a.DONE=2,a.prototype=t.instance,a}),e("moxie/core/utils/Url",[],function(){function s(e,t){for(var i=["source","scheme","authority","userInfo","user","pass","host","port","relative","path","directory","file","query","fragment"],n=i.length,r={},o=/^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/.exec(e||"");n--;)o[n]&&(r[i[n]]=o[n]);return r.scheme||(t&&"string"!=typeof t||(t=s(t||document.location.href)),r.scheme=t.scheme,r.host=t.host,r.port=t.port,e="",/^[^\/]/.test(r.path)&&(e=t.path,e=/\/[^\/]*\.[^\/]*$/.test(e)?e.replace(/\/[^\/]+$/,"/"):e.replace(/\/?$/,"/")),r.path=e+(r.path||"")),r.port||(r.port={http:80,https:443}[r.scheme]||80),r.port=parseInt(r.port,10),r.path||(r.path="/"),delete r.source,r}return{parseUrl:s,resolveUrl:function(e){e="object"==typeof e?e:s(e);return e.scheme+"://"+e.host+(e.port!=={http:80,https:443}[e.scheme]?":"+e.port:"")+e.path+(e.query||"")},hasSameOrigin:function(e){function t(e){return[e.scheme,e.host,e.port].join("/")}return"string"==typeof e&&(e=s(e)),t(s())===t(e)}}}),e("moxie/runtime/RuntimeTarget",["moxie/core/utils/Basic","moxie/runtime/RuntimeClient","moxie/core/EventTarget"],function(e,t,i){function n(){this.uid=e.guid("uid_"),t.call(this),this.destroy=function(){this.disconnectRuntime(),this.unbindAll()}}return n.prototype=i.instance,n}),e("moxie/file/FileReaderSync",["moxie/core/utils/Basic","moxie/runtime/RuntimeClient","moxie/core/utils/Encode"],function(e,i,a){return function(){function t(e,t){var i;if(!t.isDetached())return i=this.connectRuntime(t.ruid).exec.call(this,"FileReaderSync","read",e,t),this.disconnectRuntime(),i;var n=t.getSource();switch(e){case"readAsBinaryString":return n;case"readAsDataURL":return"data:"+t.type+";base64,"+a.btoa(n);case"readAsText":for(var r="",o=0,s=n.length;o<s;o++)r+=String.fromCharCode(n[o]);return r}}i.call(this),e.extend(this,{uid:e.guid("uid_"),readAsBinaryString:function(e){return t.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){return t.call(this,"readAsDataURL",e)},readAsText:function(e){return t.call(this,"readAsText",e)}})}}),e("moxie/xhr/FormData",["moxie/core/Exceptions","moxie/core/utils/Basic","moxie/file/Blob"],function(e,s,a){return function(){var r,o=[];s.extend(this,{append:function(i,e){var n=this,t=s.typeOf(e);e instanceof a?r={name:i,value:e}:"array"===t?(i+="[]",s.each(e,function(e){n.append(i,e)})):"object"===t?s.each(e,function(e,t){n.append(i+"["+t+"]",e)}):"null"===t||"undefined"===t||"number"===t&&isNaN(e)?n.append(i,"false"):o.push({name:i,value:e.toString()})},hasBlob:function(){return!!this.getBlob()},getBlob:function(){return r&&r.value||null},getBlobName:function(){return r&&r.name||null},each:function(t){s.each(o,function(e){t(e.value,e.name)}),r&&t(r.value,r.name)},destroy:function(){r=null,o=[]}})}}),e("moxie/xhr/XMLHttpRequest",["moxie/core/utils/Basic","moxie/core/Exceptions","moxie/core/EventTarget","moxie/core/utils/Encode","moxie/core/utils/Url","moxie/runtime/Runtime","moxie/runtime/RuntimeTarget","moxie/file/Blob","moxie/file/FileReaderSync","moxie/xhr/FormData","moxie/core/utils/Env","moxie/core/utils/Mime"],function(_,b,e,A,I,T,S,r,t,O,D,N){var C={100:"Continue",101:"Switching Protocols",102:"Processing",200:"OK",201:"Created",202:"Accepted",203:"Non-Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",207:"Multi-Status",226:"IM Used",300:"Multiple Choices",301:"Moved Permanently",302:"Found",303:"See Other",304:"Not Modified",305:"Use Proxy",306:"Reserved",307:"Temporary Redirect",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Request Entity Too Large",414:"Request-URI Too Long",415:"Unsupported Media Type",416:"Requested Range Not Satisfiable",417:"Expectation Failed",422:"Unprocessable Entity",423:"Locked",424:"Failed Dependency",426:"Upgrade Required",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",510:"Not Extended"};function M(){this.uid=_.guid("uid_")}M.prototype=e.instance;var L=["loadstart","progress","abort","error","load","timeout","loadend"];function F(){var o,s,a,u,c,t,i=this,n={timeout:0,readyState:F.UNSENT,withCredentials:!1,status:0,statusText:"",responseType:"",responseXML:null,responseText:null,response:null},l=!0,d={},m=null,h=null,f=!1,p=!1,g=!1,x=!1,E=!1,y=!1,w={},v="";function R(e,t){if(n.hasOwnProperty(e))return 1===arguments.length?(D.can("define_property")?n:i)[e]:void(D.can("define_property")?n[e]=t:i[e]=t)}_.extend(this,n,{uid:_.guid("uid_"),upload:new M,open:function(e,t,i,n,r){if(!e||!t)throw new b.DOMException(b.DOMException.SYNTAX_ERR);if(/[\u0100-\uffff]/.test(e)||A.utf8_encode(e)!==e)throw new b.DOMException(b.DOMException.SYNTAX_ERR);if(~_.inArray(e.toUpperCase(),["CONNECT","DELETE","GET","HEAD","OPTIONS","POST","PUT","TRACE","TRACK"])&&(s=e.toUpperCase()),~_.inArray(s,["CONNECT","TRACE","TRACK"]))throw new b.DOMException(b.DOMException.SECURITY_ERR);if(t=A.utf8_encode(t),e=I.parseUrl(t),y=I.hasSameOrigin(e),o=I.resolveUrl(t),(n||r)&&!y)throw new b.DOMException(b.DOMException.INVALID_ACCESS_ERR);if(a=n||e.user,u=r||e.pass,!1===(l=i||!0)&&(R("timeout")||R("withCredentials")||""!==R("responseType")))throw new b.DOMException(b.DOMException.INVALID_ACCESS_ERR);f=!l,p=!1,d={},function(){R("responseText",""),R("responseXML",null),R("response",null),R("status",0),R("statusText",""),0}.call(this),R("readyState",F.OPENED),this.dispatchEvent("readystatechange")},setRequestHeader:function(e,t){if(R("readyState")!==F.OPENED||p)throw new b.DOMException(b.DOMException.INVALID_STATE_ERR);if(/[\u0100-\uffff]/.test(e)||A.utf8_encode(e)!==e)throw new b.DOMException(b.DOMException.SYNTAX_ERR);return e=_.trim(e).toLowerCase(),!~_.inArray(e,["accept-charset","accept-encoding","access-control-request-headers","access-control-request-method","connection","content-length","cookie","cookie2","content-transfer-encoding","date","expect","host","keep-alive","origin","referer","te","trailer","transfer-encoding","upgrade","user-agent","via"])&&!/^(proxy\-|sec\-)/.test(e)&&(d[e]?d[e]+=", "+t:d[e]=t,!0)},getAllResponseHeaders:function(){return v||""},getResponseHeader:function(e){return e=e.toLowerCase(),!E&&!~_.inArray(e,["set-cookie","set-cookie2"])&&v&&""!==v&&(t||(t={},_.each(v.split(/\r\n/),function(e){e=e.split(/:\s+/);2===e.length&&(e[0]=_.trim(e[0]),t[e[0].toLowerCase()]={header:e[0],value:_.trim(e[1])})})),t.hasOwnProperty(e))?t[e].header+": "+t[e].value:null},overrideMimeType:function(e){var t,i;if(~_.inArray(R("readyState"),[F.LOADING,F.DONE]))throw new b.DOMException(b.DOMException.INVALID_STATE_ERR);if(e=_.trim(e.toLowerCase()),/;/.test(e)&&(t=e.match(/^([^;]+)(?:;\scharset\=)?(.*)$/))&&(e=t[1],t[2])&&(i=t[2]),!N.mimes[e])throw new b.DOMException(b.DOMException.SYNTAX_ERR);0},send:function(e,t){if(w="string"===_.typeOf(t)?{ruid:t}:t||{},this.readyState!==F.OPENED||p)throw new b.DOMException(b.DOMException.INVALID_STATE_ERR);e instanceof r?(w.ruid=e.ruid,h=e.type||"application/octet-stream"):e instanceof O?e.hasBlob()&&(t=e.getBlob(),w.ruid=t.ruid,h=t.type||"application/octet-stream"):"string"==typeof e&&(m="UTF-8",h="text/plain;charset=UTF-8",e=A.utf8_encode(e)),this.withCredentials||(this.withCredentials=w.required_caps&&w.required_caps.send_browser_cookies&&!y),g=!f&&this.upload.hasEventListener(),E=!1,x=!e,f||(p=!0),function(e){var i=this;function n(){c&&(c.destroy(),c=null),i.dispatchEvent("loadend"),i=null}function r(t){c.bind("LoadStart",function(e){R("readyState",F.LOADING),i.dispatchEvent("readystatechange"),i.dispatchEvent(e),g&&i.upload.dispatchEvent(e)}),c.bind("Progress",function(e){R("readyState")!==F.LOADING&&(R("readyState",F.LOADING),i.dispatchEvent("readystatechange")),i.dispatchEvent(e)}),c.bind("UploadProgress",function(e){g&&i.upload.dispatchEvent({type:"progress",lengthComputable:!1,total:e.total,loaded:e.loaded})}),c.bind("Load",function(e){R("readyState",F.DONE),R("status",Number(t.exec.call(c,"XMLHttpRequest","getStatus")||0)),R("statusText",C[R("status")]||""),R("response",t.exec.call(c,"XMLHttpRequest","getResponse",R("responseType"))),~_.inArray(R("responseType"),["text",""])?R("responseText",R("response")):"document"===R("responseType")&&R("responseXML",R("response")),v=t.exec.call(c,"XMLHttpRequest","getAllResponseHeaders"),i.dispatchEvent("readystatechange"),0<R("status")?(g&&i.upload.dispatchEvent(e),i.dispatchEvent(e)):(E=!0,i.dispatchEvent("error")),n()}),c.bind("Abort",function(e){i.dispatchEvent(e),n()}),c.bind("Error",function(e){E=!0,R("readyState",F.DONE),i.dispatchEvent("readystatechange"),x=!0,i.dispatchEvent(e),n()}),t.exec.call(c,"XMLHttpRequest","send",{url:o,method:s,async:l,user:a,password:u,headers:d,mimeType:h,encoding:m,responseType:i.responseType,withCredentials:i.withCredentials,options:w},e)}(new Date).getTime(),c=new S,"string"==typeof w.required_caps&&(w.required_caps=T.parseCaps(w.required_caps));w.required_caps=_.extend({},w.required_caps,{return_response_type:i.responseType}),e instanceof O&&(w.required_caps.send_multipart=!0);_.isEmptyObj(d)||(w.required_caps.send_custom_headers=!0);y||(w.required_caps.do_cors=!0);w.ruid?r(c.connectRuntime(w)):(c.bind("RuntimeInit",function(e,t){r(t)}),c.bind("RuntimeError",function(e,t){i.dispatchEvent("RuntimeError",t)}),c.connectRuntime(w))}.call(this,e)},abort:function(){if(f=!(E=!0),~_.inArray(R("readyState"),[F.UNSENT,F.OPENED,F.DONE]))R("readyState",F.UNSENT);else{if(R("readyState",F.DONE),p=!1,!c)throw new b.DOMException(b.DOMException.INVALID_STATE_ERR);c.getRuntime().exec.call(c,"XMLHttpRequest","abort",x),x=!0}},destroy:function(){c&&("function"===_.typeOf(c.destroy)&&c.destroy(),c=null),this.unbindAll(),this.upload&&(this.upload.unbindAll(),this.upload=null)}}),this.handleEventProps(L.concat(["readystatechange"])),this.upload.handleEventProps(L)}return F.UNSENT=0,F.OPENED=1,F.HEADERS_RECEIVED=2,F.LOADING=3,F.DONE=4,F.prototype=e.instance,F}),e("moxie/runtime/Transporter",["moxie/core/utils/Basic","moxie/core/utils/Encode","moxie/runtime/RuntimeClient","moxie/core/EventTarget"],function(m,t,e,i){function h(){var o,n,s,a,r,u;function c(){a=r=0,s=this.result=null}function l(e,t){var i=this;n=t,i.bind("TransportingProgress",function(e){(r=e.loaded)<a&&-1===m.inArray(i.state,[h.IDLE,h.DONE])&&d.call(i)},999),i.bind("TransportingComplete",function(){r=a,i.state=h.DONE,s=null,i.result=n.exec.call(i,"Transporter","getAsBlob",e||"")},999),i.state=h.BUSY,i.trigger("TransportingStarted"),d.call(i)}function d(){var e=a-r;e<u&&(u=e),e=t.btoa(s.substr(r,u)),n.exec.call(this,"Transporter","receive",e,a)}e.call(this),m.extend(this,{uid:m.guid("uid_"),state:h.IDLE,result:null,transport:function(e,i,t){var n,r=this;t=m.extend({chunk_size:204798},t),(o=t.chunk_size%3)&&(t.chunk_size+=3-o),u=t.chunk_size,c.call(this),a=(s=e).length,"string"===m.typeOf(t)||t.ruid?l.call(r,i,this.connectRuntime(t)):(n=function(e,t){r.unbind("RuntimeInit",n),l.call(r,i,t)},this.bind("RuntimeInit",n),this.connectRuntime(t))},abort:function(){this.state=h.IDLE,n&&(n.exec.call(this,"Transporter","clear"),this.trigger("TransportingAborted")),c.call(this)},destroy:function(){this.unbindAll(),n=null,this.disconnectRuntime(),c.call(this)}})}return h.IDLE=0,h.BUSY=1,h.DONE=2,h.prototype=i.instance,h}),e("moxie/image/Image",["moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/Exceptions","moxie/file/FileReaderSync","moxie/xhr/XMLHttpRequest","moxie/runtime/Runtime","moxie/runtime/RuntimeClient","moxie/runtime/Transporter","moxie/core/utils/Env","moxie/core/EventTarget","moxie/file/Blob","moxie/file/File","moxie/core/utils/Encode"],function(a,n,u,e,o,s,t,c,l,i,d,m,h){var f=["progress","load","error","resize","embedded"];function p(){function i(e){var t=a.typeOf(e);try{if(e instanceof p){if(!e.size)throw new u.DOMException(u.DOMException.INVALID_STATE_ERR);!function(e,t){var i=this.connectRuntime(e.ruid);this.ruid=i.uid,i.exec.call(this,"Image","loadFromImage",e,"undefined"===a.typeOf(t)||t)}.apply(this,arguments)}else if(e instanceof d){if(!~a.inArray(e.type,["image/jpeg","image/png"]))throw new u.ImageError(u.ImageError.WRONG_FORMAT);r.apply(this,arguments)}else if(-1!==a.inArray(t,["blob","file"]))i.call(this,new m(null,e),arguments[1]);else if("string"===t)"data:"===e.substr(0,5)?i.call(this,new d(null,{data:e}),arguments[1]):function(e,t){var i,n=this;(i=new o).open("get",e),i.responseType="blob",i.onprogress=function(e){n.trigger(e)},i.onload=function(){r.call(n,i.response,!0)},i.onerror=function(e){n.trigger(e)},i.onloadend=function(){i.destroy()},i.bind("RuntimeError",function(e,t){n.trigger("RuntimeError",t)}),i.send(null,t)}.apply(this,arguments);else{if("node"!==t||"img"!==e.nodeName.toLowerCase())throw new u.DOMException(u.DOMException.TYPE_MISMATCH_ERR);i.call(this,e.src,arguments[1])}}catch(e){this.trigger("error",e.code)}}function r(t,e){var i=this;function n(e){i.ruid=e.uid,e.exec.call(i,"Image","loadFromBlob",t)}i.name=t.name||"",t.isDetached()?(this.bind("RuntimeInit",function(e,t){n(t)}),e&&"string"==typeof e.required_caps&&(e.required_caps=s.parseCaps(e.required_caps)),this.connectRuntime(a.extend({required_caps:{access_image_binary:!0,resize_image:!0}},e))):n(this.connectRuntime(t.ruid))}t.call(this),a.extend(this,{uid:a.guid("uid_"),ruid:null,name:"",size:0,width:0,height:0,type:"",meta:{},clone:function(){this.load.apply(this,arguments)},load:function(){i.apply(this,arguments)},downsize:function(e){var t={width:this.width,height:this.height,type:this.type||"image/jpeg",quality:90,crop:!1,preserveHeaders:!0,resample:!1};e="object"==typeof e?a.extend(t,e):a.extend(t,{width:arguments[0],height:arguments[1],crop:arguments[2],preserveHeaders:arguments[3]});try{if(!this.size)throw new u.DOMException(u.DOMException.INVALID_STATE_ERR);if(this.width>p.MAX_RESIZE_WIDTH||this.height>p.MAX_RESIZE_HEIGHT)throw new u.ImageError(u.ImageError.MAX_RESOLUTION_ERR);this.exec("Image","downsize",e.width,e.height,e.crop,e.preserveHeaders)}catch(e){this.trigger("error",e.code)}},crop:function(e,t,i){this.downsize(e,t,!0,i)},getAsCanvas:function(){if(l.can("create_canvas"))return this.connectRuntime(this.ruid).exec.call(this,"Image","getAsCanvas");throw new u.RuntimeError(u.RuntimeError.NOT_SUPPORTED_ERR)},getAsBlob:function(e,t){if(this.size)return this.exec("Image","getAsBlob",e||"image/jpeg",t||90);throw new u.DOMException(u.DOMException.INVALID_STATE_ERR)},getAsDataURL:function(e,t){if(this.size)return this.exec("Image","getAsDataURL",e||"image/jpeg",t||90);throw new u.DOMException(u.DOMException.INVALID_STATE_ERR)},getAsBinaryString:function(e,t){e=this.getAsDataURL(e,t);return h.atob(e.substring(e.indexOf("base64,")+7))},embed:function(r,e){var o,s=this;e=a.extend({width:this.width,height:this.height,type:this.type||"image/jpeg",quality:90},e||{});try{if(!(r=n.get(r)))throw new u.DOMException(u.DOMException.INVALID_NODE_TYPE_ERR);if(!this.size)throw new u.DOMException(u.DOMException.INVALID_STATE_ERR);this.width>p.MAX_RESIZE_WIDTH||this.height;var t=new p;return t.bind("Resize",function(){!function(e,t){var i=this;if(l.can("create_canvas")){var n=i.getAsCanvas();if(n)return r.appendChild(n),i.destroy(),void s.trigger("embedded")}if(!(n=i.getAsDataURL(e,t)))throw new u.ImageError(u.ImageError.WRONG_FORMAT);l.can("use_data_uri_of",n.length)?(r.innerHTML='<img src="'+n+'" width="'+i.width+'" height="'+i.height+'" />',i.destroy(),s.trigger("embedded")):((t=new c).bind("TransportingComplete",function(){o=s.connectRuntime(this.result.ruid),s.bind("Embedded",function(){a.extend(o.getShimContainer().style,{top:"0px",left:"0px",width:i.width+"px",height:i.height+"px"}),o=null},999),o.exec.call(s,"ImageView","display",this.result.uid,width,height),i.destroy()}),t.transport(h.atob(n.substring(n.indexOf("base64,")+7)),e,{required_caps:{display_media:!0},runtime_order:"flash,silverlight",container:r}))}.call(this,e.type,e.quality)}),t.bind("Load",function(){t.downsize(e)}),this.meta.thumb&&this.meta.thumb.width>=e.width&&this.meta.thumb.height>=e.height?t.load(this.meta.thumb.data):t.clone(this,!1),t}catch(e){this.trigger("error",e.code)}},destroy:function(){this.ruid&&(this.getRuntime().exec.call(this,"Image","destroy"),this.disconnectRuntime()),this.unbindAll()}}),this.handleEventProps(f),this.bind("Load Resize",function(){!function(e){e=e||this.exec("Image","getInfo");this.size=e.size,this.width=e.width,this.height=e.height,this.type=e.type,this.meta=e.meta,""===this.name&&(this.name=e.name)}.call(this)},999)}return p.MAX_RESIZE_WIDTH=8192,p.MAX_RESIZE_HEIGHT=8192,p.prototype=i.instance,p}),e("moxie/runtime/html5/Runtime",["moxie/core/utils/Basic","moxie/core/Exceptions","moxie/runtime/Runtime","moxie/core/utils/Env"],function(s,e,a,u){var c={};return a.addConstructor("html5",function(e){var t,i=this,n=a.capTest,r=a.capTrue,o=s.extend({access_binary:n(window.FileReader||window.File&&window.File.getAsDataURL),access_image_binary:function(){return i.can("access_binary")&&!!c.Image},display_media:n(u.can("create_canvas")||u.can("use_data_uri_over32kb")),do_cors:n(window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest),drag_and_drop:n(("draggable"in(o=document.createElement("div"))||"ondragstart"in o&&"ondrop"in o)&&("IE"!==u.browser||u.verComp(u.version,9,">"))),filter_by_extension:n("Chrome"===u.browser&&u.verComp(u.version,28,">=")||"IE"===u.browser&&u.verComp(u.version,10,">=")||"Safari"===u.browser&&u.verComp(u.version,7,">=")),return_response_headers:r,return_response_type:function(e){return!("json"!==e||!window.JSON)||u.can("return_response_type",e)},return_status_code:r,report_upload_progress:n(window.XMLHttpRequest&&(new XMLHttpRequest).upload),resize_image:function(){return i.can("access_binary")&&u.can("create_canvas")},select_file:function(){return u.can("use_fileinput")&&window.File},select_folder:function(){return i.can("select_file")&&"Chrome"===u.browser&&u.verComp(u.version,21,">=")},select_multiple:function(){return i.can("select_file")&&!("Safari"===u.browser&&"Windows"===u.os)&&!("iOS"===u.os&&u.verComp(u.osVersion,"7.0.0",">")&&u.verComp(u.osVersion,"8.0.0","<"))},send_binary_string:n(window.XMLHttpRequest&&((new XMLHttpRequest).sendAsBinary||window.Uint8Array&&window.ArrayBuffer)),send_custom_headers:n(window.XMLHttpRequest),send_multipart:function(){return!!(window.XMLHttpRequest&&(new XMLHttpRequest).upload&&window.FormData)||i.can("send_binary_string")},slice_blob:n(window.File&&(File.prototype.mozSlice||File.prototype.webkitSlice||File.prototype.slice)),stream_upload:function(){return i.can("slice_blob")&&i.can("send_multipart")},summon_file_dialog:function(){return i.can("select_file")&&("Firefox"===u.browser&&u.verComp(u.version,4,">=")||"Opera"===u.browser&&u.verComp(u.version,12,">=")||"IE"===u.browser&&u.verComp(u.version,10,">=")||!!~s.inArray(u.browser,["Chrome","Safari"]))},upload_filesize:r},arguments[2]);a.call(this,e,arguments[1]||"html5",o),s.extend(this,{init:function(){this.trigger("Init")},destroy:(t=this.destroy,function(){t.call(i),t=i=null})}),s.extend(this.getShim(),c)}),c}),e("moxie/core/utils/Events",["moxie/core/utils/Basic"],function(o){var s={},a="moxie_"+o.guid();function u(){this.returnValue=!1}function c(){this.cancelBubble=!0}function r(t,e,i){if(e=e.toLowerCase(),t[a]&&s[t[a]]&&s[t[a]][e]){for(var n,r=(n=s[t[a]][e]).length-1;0<=r&&(n[r].orig!==i&&n[r].key!==i||(t.removeEventListener?t.removeEventListener(e,n[r].func,!1):t.detachEvent&&t.detachEvent("on"+e,n[r].func),n[r].orig=null,n[r].func=null,n.splice(r,1),void 0===i));r--);if(n.length||delete s[t[a]][e],o.isEmptyObj(s[t[a]])){delete s[t[a]];try{delete t[a]}catch(e){t[a]=void 0}}}}return{addEvent:function(e,t,i,n){var r;t=t.toLowerCase(),e.addEventListener?e.addEventListener(t,r=i,!1):e.attachEvent&&e.attachEvent("on"+t,r=function(){var e=window.event;e.target||(e.target=e.srcElement),e.preventDefault=u,e.stopPropagation=c,i(e)}),e[a]||(e[a]=o.guid()),s.hasOwnProperty(e[a])||(s[e[a]]={}),(e=s[e[a]]).hasOwnProperty(t)||(e[t]=[]),e[t].push({func:r,orig:i,key:n})},removeEvent:r,removeAllEvents:function(i,n){i&&i[a]&&o.each(s[i[a]],function(e,t){r(i,t,n)})}}}),e("moxie/runtime/html5/file/FileInput",["moxie/runtime/html5/Runtime","moxie/file/File","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/utils/Events","moxie/core/utils/Mime","moxie/core/utils/Env"],function(e,a,u,c,l,d,m){return e.FileInput=function(){var s;u.extend(this,{init:function(e){var t,i,n,r=this,o=r.getRuntime(),e=(s=e).accept.mimes||d.extList2mimes(s.accept,o.can("filter_by_extension"));(t=o.getShimContainer()).innerHTML='<input id="'+o.uid+'" type="file" style="font-size:999px;opacity:0;"'+(s.multiple&&o.can("select_multiple")?"multiple":"")+(s.directory&&o.can("select_folder")?"webkitdirectory directory":"")+(e?' accept="'+e.join(",")+'"':"")+" />",e=c.get(o.uid),u.extend(e.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),i=c.get(s.browse_button),o.can("summon_file_dialog")&&("static"===c.getStyle(i,"position")&&(i.style.position="relative"),n=parseInt(c.getStyle(i,"z-index"),10)||1,i.style.zIndex=n,t.style.zIndex=n-1,l.addEvent(i,"click",function(e){var t=c.get(o.uid);t&&!t.disabled&&t.click(),e.preventDefault()},r.uid)),n=o.can("summon_file_dialog")?i:t,l.addEvent(n,"mouseover",function(){r.trigger("mouseenter")},r.uid),l.addEvent(n,"mouseout",function(){r.trigger("mouseleave")},r.uid),l.addEvent(n,"mousedown",function(){r.trigger("mousedown")},r.uid),l.addEvent(c.get(s.container),"mouseup",function(){r.trigger("mouseup")},r.uid),e.onchange=function e(t){var i;r.files=[],u.each(this.files,function(e){var t="";if(s.directory&&"."==e.name)return!0;e.webkitRelativePath&&(t="/"+e.webkitRelativePath.replace(/^\//,"")),(e=new a(o.uid,e)).relativePath=t,r.files.push(e)}),"IE"!==m.browser&&"IEMobile"!==m.browser?this.value="":(i=this.cloneNode(!0),this.parentNode.replaceChild(i,this),i.onchange=e),r.files.length&&r.trigger("change")},r.trigger({type:"ready",async:!0})},disable:function(e){var t=this.getRuntime();(t=c.get(t.uid))&&(t.disabled=!!e)},destroy:function(){var e=this.getRuntime(),t=e.getShim(),e=e.getShimContainer();l.removeAllEvents(e,this.uid),l.removeAllEvents(s&&c.get(s.container),this.uid),l.removeAllEvents(s&&c.get(s.browse_button),this.uid),e&&(e.innerHTML=""),t.removeInstance(this.uid),s=null}})}}),e("moxie/runtime/html5/file/Blob",["moxie/runtime/html5/Runtime","moxie/file/Blob"],function(e,t){return e.Blob=function(){this.slice=function(){return new t(this.getRuntime().uid,function(t,i,n){var e;if(!window.File.prototype.slice)return(e=window.File.prototype.webkitSlice||window.File.prototype.mozSlice)?e.call(t,i,n):null;try{return t.slice(),t.slice(i,n)}catch(e){return t.slice(i,n-i)}}.apply(this,arguments))}}}),e("moxie/runtime/html5/file/FileDrop",["moxie/runtime/html5/Runtime","moxie/file/File","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/utils/Events","moxie/core/utils/Mime"],function(e,r,l,i,d,m){return e.FileDrop=function(){var t,n,o=[],s=[];function a(e){if(e.dataTransfer&&e.dataTransfer.types)return e=l.toArray(e.dataTransfer.types||[]),-1!==l.inArray("Files",e)||-1!==l.inArray("public.file-url",e)||-1!==l.inArray("application/x-moz-file",e)}function u(e,t){var i;i=e,s.length&&(i=m.getFileExtension(i.name))&&-1===l.inArray(i,s)||((i=new r(n,e)).relativePath=t||"",o.push(i))}function c(e,t){var i=[];l.each(e,function(s){i.push(function(e){{var t,n,r;(o=e,(i=s).isFile)?i.file(function(e){u(e,i.fullPath),o()},function(){o()}):i.isDirectory?(t=o,n=[],r=(e=i).createReader(),function t(i){r.readEntries(function(e){e.length?([].push.apply(n,e),t(i)):i()},i)}(function(){c(n,t)})):o()}var i,o})}),l.inSeries(i,function(){t()})}l.extend(this,{init:function(e){var r=this;t=e,n=r.ruid,s=function(e){for(var t=[],i=0;i<e.length;i++)[].push.apply(t,e[i].extensions.split(/\s*,\s*/));return-1===l.inArray("*",t)?t:[]}(t.accept),e=t.container,d.addEvent(e,"dragover",function(e){a(e)&&(e.preventDefault(),e.dataTransfer.dropEffect="copy")},r.uid),d.addEvent(e,"drop",function(e){var t,i,n;a(e)&&(e.preventDefault(),o=[],e.dataTransfer.items&&e.dataTransfer.items[0].webkitGetAsEntry?(t=e.dataTransfer.items,i=function(){r.files=o,r.trigger("drop")},n=[],l.each(t,function(e){var t=e.webkitGetAsEntry();t&&(t.isFile?u(e.getAsFile(),t.fullPath):n.push(t))}),n.length?c(n,i):i()):(l.each(e.dataTransfer.files,function(e){u(e)}),r.files=o,r.trigger("drop")))},r.uid),d.addEvent(e,"dragenter",function(e){r.trigger("dragenter")},r.uid),d.addEvent(e,"dragleave",function(e){r.trigger("dragleave")},r.uid)},destroy:function(){d.removeAllEvents(t&&i.get(t.container),this.uid),n=o=s=t=null}})}}),e("moxie/runtime/html5/file/FileReader",["moxie/runtime/html5/Runtime","moxie/core/utils/Encode","moxie/core/utils/Basic"],function(e,o,s){return e.FileReader=function(){var n,r=!1;s.extend(this,{read:function(e,t){var i=this;i.result="",(n=new window.FileReader).addEventListener("progress",function(e){i.trigger(e)}),n.addEventListener("load",function(e){var t;i.result=r?(t=n.result,o.atob(t.substring(t.indexOf("base64,")+7))):n.result,i.trigger(e)}),n.addEventListener("error",function(e){i.trigger(e,n.error)}),n.addEventListener("loadend",function(e){n=null,i.trigger(e)}),"function"===s.typeOf(n[e])?(r=!1,n[e](t.getSource())):"readAsBinaryString"===e&&(r=!0,n.readAsDataURL(t.getSource()))},abort:function(){n&&n.abort()},destroy:function(){n=null}})}}),e("moxie/runtime/html5/xhr/XMLHttpRequest",["moxie/runtime/html5/Runtime","moxie/core/utils/Basic","moxie/core/utils/Mime","moxie/core/utils/Url","moxie/file/File","moxie/file/Blob","moxie/xhr/FormData","moxie/core/Exceptions","moxie/core/utils/Env"],function(e,m,u,h,f,p,g,x,E){return e.XMLHttpRequest=function(){var c,l,d=this;m.extend(this,{send:function(e,t){var i,n=this,r="Mozilla"===E.browser&&E.verComp(E.version,4,">=")&&E.verComp(E.version,7,"<"),o="Android Browser"===E.browser,s=!1;if(l=e.url.replace(/^.+?\/([\w\-\.]+)$/,"$1").toLowerCase(),(c=!window.XMLHttpRequest||"IE"===E.browser&&E.verComp(E.version,8,"<")?function(){for(var e=["Msxml2.XMLHTTP.6.0","Microsoft.XMLHTTP"],t=0;t<e.length;t++)try{return new ActiveXObject(e[t])}catch(e){}}():new window.XMLHttpRequest).open(e.method,e.url,e.async,e.user,e.password),t instanceof p)t.isDetached()&&(s=!0),t=t.getSource();else if(t instanceof g){if(t.hasBlob())if(t.getBlob().isDetached())t=function(e){var i="----moxieboundary"+(new Date).getTime(),n="\r\n",r="";if(this.getRuntime().can("send_binary_string"))return c.setRequestHeader("Content-Type","multipart/form-data; boundary="+i),e.each(function(e,t){e instanceof p?r+="--"+i+n+'Content-Disposition: form-data; name="'+t+'"; filename="'+unescape(encodeURIComponent(e.name||"blob"))+'"'+n+"Content-Type: "+(e.type||"application/octet-stream")+n+n+e.getSource()+n:r+="--"+i+n+'Content-Disposition: form-data; name="'+t+'"'+n+n+unescape(encodeURIComponent(e))+n}),r+="--"+i+"--"+n;throw new x.RuntimeError(x.RuntimeError.NOT_SUPPORTED_ERR)}.call(n,t),s=!0;else if((r||o)&&"blob"===m.typeOf(t.getBlob().getSource())&&window.FileReader)return void function(e,t){var i,n,r=this;i=t.getBlob().getSource(),(n=new window.FileReader).onload=function(){t.append(t.getBlobName(),new p(null,{type:i.type,data:n.result})),d.send.call(r,e,t)},n.readAsBinaryString(i)}.call(n,e,t);t instanceof g&&(i=new window.FormData,t.each(function(e,t){e instanceof p?i.append(t,e.getSource()):i.append(t,e)}),t=i)}if(c.upload?(e.withCredentials&&(c.withCredentials=!0),c.addEventListener("load",function(e){n.trigger(e)}),c.addEventListener("error",function(e){n.trigger(e)}),c.addEventListener("progress",function(e){n.trigger(e)}),c.upload.addEventListener("progress",function(e){n.trigger({type:"UploadProgress",loaded:e.loaded,total:e.total})})):c.onreadystatechange=function(){switch(c.readyState){case 1:case 2:break;case 3:var t,i;try{h.hasSameOrigin(e.url)&&(t=c.getResponseHeader("Content-Length")||0),c.responseText&&(i=c.responseText.length)}catch(e){t=i=0}n.trigger({type:"progress",lengthComputable:!!t,total:parseInt(t,10),loaded:i});break;case 4:c.onreadystatechange=function(){},0===c.status?n.trigger("error"):n.trigger("load")}},m.isEmptyObj(e.headers)||m.each(e.headers,function(e,t){c.setRequestHeader(t,e)}),""!==e.responseType&&"responseType"in c&&("json"!==e.responseType||E.can("return_response_type","json")?c.responseType=e.responseType:c.responseType="text"),s)if(c.sendAsBinary)c.sendAsBinary(t);else{for(var a=new Uint8Array(t.length),u=0;u<t.length;u++)a[u]=255&t.charCodeAt(u);c.send(a.buffer)}else c.send(t);n.trigger("loadstart")},getStatus:function(){try{if(c)return c.status}catch(e){}return 0},getResponse:function(e){var t=this.getRuntime();try{switch(e){case"blob":var i,n=new f(t.uid,c.response),r=c.getResponseHeader("Content-Disposition");return r&&(i=r.match(/filename=([\'\"'])([^\1]+)\1/))&&(l=i[2]),n.name=l,n.type||(n.type=u.getFileMime(l)),n;case"json":return E.can("return_response_type","json")?c.response:200===c.status&&window.JSON?JSON.parse(c.responseText):null;case"document":var o=c,s=o.responseXML,a=o.responseText;return"IE"===E.browser&&a&&s&&!s.documentElement&&/[^\/]+\/[^\+]+\+xml/.test(o.getResponseHeader("Content-Type"))&&((s=new window.ActiveXObject("Microsoft.XMLDOM")).async=!1,s.validateOnParse=!1,s.loadXML(a)),s&&("IE"===E.browser&&0!==s.parseError||!s.documentElement||"parsererror"===s.documentElement.tagName)?null:s;default:return""!==c.responseText?c.responseText:null}}catch(e){return null}},getAllResponseHeaders:function(){try{return c.getAllResponseHeaders()}catch(e){}return""},abort:function(){c&&c.abort()},destroy:function(){d=l=null}})}}),e("moxie/runtime/html5/utils/BinaryReader",["moxie/core/utils/Basic"],function(t){function e(e){(e instanceof ArrayBuffer?function(r){var o=new DataView(r);t.extend(this,{readByteAt:function(e){return o.getUint8(e)},writeByteAt:function(e,t){o.setUint8(e,t)},SEGMENT:function(e,t,i){switch(arguments.length){case 2:return r.slice(e,e+t);case 1:return r.slice(e);case 3:if((i=null===i?new ArrayBuffer:i)instanceof ArrayBuffer){var n=new Uint8Array(this.length()-t+i.byteLength);0<e&&n.set(new Uint8Array(r.slice(0,e)),0),n.set(new Uint8Array(i),e),n.set(new Uint8Array(r.slice(e+t)),e+i.byteLength),this.clear(),r=n.buffer,o=new DataView(r);break}default:return r}},length:function(){return r?r.byteLength:0},clear:function(){o=r=null}})}:function(n){function r(e,t,i){i=3===arguments.length?i:n.length-t-1,n=n.substr(0,t)+e+n.substr(i+t)}t.extend(this,{readByteAt:function(e){return n.charCodeAt(e)},writeByteAt:function(e,t){r(String.fromCharCode(t),e,1)},SEGMENT:function(e,t,i){switch(arguments.length){case 1:return n.substr(e);case 2:return n.substr(e,t);case 3:r(null!==i?i:"",e,t);break;default:return n}},length:function(){return n?n.length:0},clear:function(){n=null}})}).apply(this,arguments)}return t.extend(e.prototype,{littleEndian:!1,read:function(e,t){var i,n,r;if(e+t>this.length())throw new Error("You are trying to read outside the source boundaries.");for(n=this.littleEndian?0:-8*(t-1),i=r=0;r<t;r++)i|=this.readByteAt(e+r)<<Math.abs(n+8*r);return i},write:function(e,t,i){var n,r;if(e>this.length())throw new Error("You are trying to write outside the source boundaries.");for(n=this.littleEndian?0:-8*(i-1),r=0;r<i;r++)this.writeByteAt(e+r,t>>Math.abs(n+8*r)&255)},BYTE:function(e){return this.read(e,1)},SHORT:function(e){return this.read(e,2)},LONG:function(e){return this.read(e,4)},SLONG:function(e){e=this.read(e,4);return 2147483647<e?e-4294967296:e},CHAR:function(e){return String.fromCharCode(this.read(e,1))},STRING:function(e,t){return this.asArray("CHAR",e,t).join("")},asArray:function(e,t,i){for(var n=[],r=0;r<i;r++)n[r]=this[e](t+r);return n}}),e}),e("moxie/runtime/html5/image/JPEGHeaders",["moxie/runtime/html5/utils/BinaryReader","moxie/core/Exceptions"],function(a,u){return function o(e){var r,t,i,s=[],n=new a(e);if(65496!==n.SHORT(0))throw n.clear(),new u.ImageError(u.ImageError.WRONG_FORMAT);for(r=2;r<=n.length();)if(65488<=(t=n.SHORT(r))&&t<=65495)r+=2;else{if(65498===t||65497===t)break;i=n.SHORT(r+2)+2,65505<=t&&t<=65519&&s.push({hex:t,name:"APP"+(15&t),start:r,length:i,segment:n.SEGMENT(r,i)}),r+=i}return n.clear(),{headers:s,restore:function(e){var t,i,n=new a(e);for(r=65504==n.SHORT(2)?4+n.SHORT(4):2,i=0,t=s.length;i<t;i++)n.SEGMENT(r,0,s[i].segment),r+=s[i].length;return e=n.SEGMENT(),n.clear(),e},strip:function(e){var t,i,n=new o(e),r=n.headers;for(n.purge(),t=new a(e),i=r.length;i--;)t.SEGMENT(r[i].start,r[i].length,"");return e=t.SEGMENT(),t.clear(),e},get:function(e){for(var t=[],i=0,n=s.length;i<n;i++)s[i].name===e.toUpperCase()&&t.push(s[i].segment);return t},set:function(e,t){var i,n,r,o=[];for("string"==typeof t?o.push(t):o=t,i=n=0,r=s.length;i<r&&(s[i].name===e.toUpperCase()&&(s[i].segment=o[n],s[i].length=o[n].length,n++),!(n>=o.length));i++);},purge:function(){this.headers=s=[]}}}}),e("moxie/runtime/html5/image/ExifParser",["moxie/core/utils/Basic","moxie/runtime/html5/utils/BinaryReader","moxie/core/Exceptions"],function(p,o,g){function s(e){var t,l,h,f,i;if(o.call(this,e),l={tiff:{274:"Orientation",270:"ImageDescription",271:"Make",272:"Model",305:"Software",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer"},exif:{36864:"ExifVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",36867:"DateTimeOriginal",33434:"ExposureTime",33437:"FNumber",34855:"ISOSpeedRatings",37377:"ShutterSpeedValue",37378:"ApertureValue",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37386:"FocalLength",41986:"ExposureMode",41987:"WhiteBalance",41990:"SceneCaptureType",41988:"DigitalZoomRatio",41992:"Contrast",41993:"Saturation",41994:"Sharpness"},gps:{0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude"},thumb:{513:"JPEGInterchangeFormat",514:"JPEGInterchangeFormatLength"}},h={ColorSpace:{1:"sRGB",0:"Uncalibrated"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{1:"Daylight",2:"Fliorescent",3:"Tungsten",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 -5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire",1:"Flash fired",5:"Strobe return light not detected",7:"Strobe return light detected",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},ExposureMode:{0:"Auto exposure",1:"Manual exposure",2:"Auto bracket"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},GPSLatitudeRef:{N:"North latitude",S:"South latitude"},GPSLongitudeRef:{E:"East longitude",W:"West longitude"}},n=(f={tiffHeader:10}).tiffHeader,t={clear:this.clear},p.extend(this,{read:function(){try{return s.prototype.read.apply(this,arguments)}catch(e){throw new g.ImageError(g.ImageError.INVALID_META_ERR)}},write:function(){try{return s.prototype.write.apply(this,arguments)}catch(e){throw new g.ImageError(g.ImageError.INVALID_META_ERR)}},UNDEFINED:function(){return this.BYTE.apply(this,arguments)},RATIONAL:function(e){return this.LONG(e)/this.LONG(e+4)},SRATIONAL:function(e){return this.SLONG(e)/this.SLONG(e+4)},ASCII:function(e){return this.CHAR(e)},TIFF:function(){return i||null},EXIF:function(){var e=null;if(f.exifIFD){try{e=r.call(this,f.exifIFD,l.exif)}catch(e){return null}if(e.ExifVersion&&"array"===p.typeOf(e.ExifVersion)){for(var t=0,i="";t<e.ExifVersion.length;t++)i+=String.fromCharCode(e.ExifVersion[t]);e.ExifVersion=i}}return e},GPS:function(){var e=null;if(f.gpsIFD){try{e=r.call(this,f.gpsIFD,l.gps)}catch(e){return null}e.GPSVersionID&&"array"===p.typeOf(e.GPSVersionID)&&(e.GPSVersionID=e.GPSVersionID.join("."))}return e},thumb:function(){if(f.IFD1)try{var e=r.call(this,f.IFD1,l.thumb);if("JPEGInterchangeFormat"in e)return this.SEGMENT(f.tiffHeader+e.JPEGInterchangeFormat,e.JPEGInterchangeFormatLength)}catch(e){}return null},setExif:function(e,t){return("PixelXDimension"===e||"PixelYDimension"===e)&&function(e,t,i){var n,r,o,s=0;if("string"==typeof t){var a,u=l[e.toLowerCase()];for(a in u)if(u[a]===t){t=a;break}}n=f[e.toLowerCase()+"IFD"],r=this.SHORT(n);for(var c=0;c<r;c++)if(o=n+12*c+2,this.SHORT(o)==t){s=o+8;break}if(!s)return!1;try{this.write(s,i,4)}catch(e){return!1}return!0}.call(this,"exif",e,t)},clear:function(){t.clear(),e=l=h=i=f=t=null}}),65505!==this.SHORT(0)||"EXIF\0"!==this.STRING(4,5).toUpperCase())throw new g.ImageError(g.ImageError.INVALID_META_ERR);if(this.littleEndian=18761==this.SHORT(n),42!==this.SHORT(n+=2))throw new g.ImageError(g.ImageError.INVALID_META_ERR);f.IFD0=f.tiffHeader+this.LONG(n+=2),"ExifIFDPointer"in(i=r.call(this,f.IFD0,l.tiff))&&(f.exifIFD=f.tiffHeader+i.ExifIFDPointer,delete i.ExifIFDPointer),"GPSInfoIFDPointer"in i&&(f.gpsIFD=f.tiffHeader+i.GPSInfoIFDPointer,delete i.GPSInfoIFDPointer),p.isEmptyObj(i)&&(i=null);var n=this.LONG(f.IFD0+12*this.SHORT(f.IFD0)+2);function r(e,t){for(var i,n,r,o,s,a=this,u={},c={1:"BYTE",7:"UNDEFINED",2:"ASCII",3:"SHORT",4:"LONG",5:"RATIONAL",9:"SLONG",10:"SRATIONAL"},l={BYTE:1,UNDEFINED:1,ASCII:1,SHORT:2,LONG:4,RATIONAL:8,SLONG:4,SRATIONAL:8},d=a.SHORT(e),m=0;m<d;m++)if((i=t[a.SHORT(r=e+2+12*m)])!==x){if(o=c[a.SHORT(r+=2)],n=a.LONG(r+=2),!(s=l[o]))throw new g.ImageError(g.ImageError.INVALID_META_ERR);if(r+=4,(r=4<s*n?a.LONG(r)+f.tiffHeader:r)+s*n>=this.length())throw new g.ImageError(g.ImageError.INVALID_META_ERR);"ASCII"===o?u[i]=p.trim(a.STRING(r,n).replace(/\0$/,"")):(s=a.asArray(o,r,n),o=1==n?s[0]:s,h.hasOwnProperty(i)&&"object"!=typeof o?u[i]=h[i][o]:u[i]=o)}return u}n&&(f.IFD1=f.tiffHeader+n)}return s.prototype=o.prototype,s}),e("moxie/runtime/html5/image/JPEG",["moxie/core/utils/Basic","moxie/core/Exceptions","moxie/runtime/html5/image/JPEGHeaders","moxie/runtime/html5/utils/BinaryReader","moxie/runtime/html5/image/ExifParser"],function(s,a,u,c,l){return function(e){var i,n,t,r=new c(e);if(65496!==r.SHORT(0))throw new a.ImageError(a.ImageError.WRONG_FORMAT);i=new u(e);try{n=new l(i.get("app1")[0])}catch(e){}function o(e){var t,i=0;for(e=e||r;i<=e.length();){if(65472<=(t=e.SHORT(i+=2))&&t<=65475)return i+=5,{height:e.SHORT(i),width:e.SHORT(i+=2)};t=e.SHORT(i+=2),i+=t-2}return null}t=o.call(this),s.extend(this,{type:"image/jpeg",size:r.length(),width:t&&t.width||0,height:t&&t.height||0,setExif:function(e,t){if(!n)return!1;"object"===s.typeOf(e)?s.each(e,function(e,t){n.setExif(t,e)}):n.setExif(e,t),i.set("app1",n.SEGMENT())},writeHeaders:function(){return arguments.length?i.restore(arguments[0]):i.restore(e)},stripHeaders:function(e){return i.strip(e)},purge:function(){!function(){n&&i&&r&&(n.clear(),i.purge(),r.clear(),t=i=n=r=null)}.call(this)}}),n&&(this.meta={tiff:n.TIFF(),exif:n.EXIF(),gps:n.GPS(),thumb:function(){var e,t,i=n.thumb();if(i&&(e=new c(i),t=o(e),e.clear(),t))return t.data=i,t;return null}()})}}),e("moxie/runtime/html5/image/PNG",["moxie/core/Exceptions","moxie/core/utils/Basic","moxie/runtime/html5/utils/BinaryReader"],function(a,u,c){return function(e){for(var t,r=new c(e),i=0,n=0,o=[35152,20039,3338,6666],n=0;n<o.length;n++,i+=2)if(o[n]!=r.SHORT(i))throw new a.ImageError(a.ImageError.WRONG_FORMAT);function s(){r&&(r.clear(),e=t=r=null)}t=function(){var e=function(e){var t,i,n;return t=r.LONG(e),i=r.STRING(e+=4,4),n=e+=4,e=r.LONG(e+t),{length:t,type:i,start:n,CRC:e}}.call(this,8);return"IHDR"==e.type?(e=e.start,{width:r.LONG(e),height:r.LONG(e+=4)}):null}.call(this),u.extend(this,{type:"image/png",size:r.length(),width:t.width,height:t.height,purge:function(){s.call(this)}}),s.call(this)}}),e("moxie/runtime/html5/image/ImageInfo",["moxie/core/utils/Basic","moxie/core/Exceptions","moxie/runtime/html5/image/JPEG","moxie/runtime/html5/image/PNG"],function(n,r,o,s){return function(t){var i=[o,s],e=function(){for(var e=0;e<i.length;e++)try{return new i[e](t)}catch(e){}throw new r.ImageError(r.ImageError.WRONG_FORMAT)}();n.extend(this,{type:"",size:0,width:0,height:0,setExif:function(){},writeHeaders:function(e){return e},stripHeaders:function(e){return e},purge:function(){t=null}}),n.extend(this,e),this.purge=function(){e.purge(),e=null}}}),e("moxie/runtime/html5/image/MegaPixel",[],function(){function R(e){var t,i=e.naturalWidth;return 1048576<i*e.naturalHeight&&((t=document.createElement("canvas")).width=t.height=1,(t=t.getContext("2d")).drawImage(e,1-i,0),0===t.getImageData(0,0,1,1).data[3])}return{isSubsampled:R,renderTo:function(e,t,i){for(var n=e.naturalWidth,r=e.naturalHeight,o=i.width,s=i.height,a=i.x||0,u=i.y||0,c=t.getContext("2d"),l=(R(e)&&(n/=2,r/=2),1024),d=document.createElement("canvas"),m=(d.width=d.height=l,d.getContext("2d")),h=function(e,t){var i=document.createElement("canvas"),n=(i.width=1,i.height=t,i.getContext("2d")),r=(n.drawImage(e,0,0),n.getImageData(0,0,1,t).data),o=0,s=t,a=t;for(;o<a;)0===r[4*(a-1)+3]?s=a:o=a,a=s+o>>1;i=null;e=a/t;return 0==e?1:e}(e,r),f=0;f<r;){for(var p=r<f+l?r-f:l,g=0;g<n;){var x=n<g+l?n-g:l,E=(m.clearRect(0,0,l,l),m.drawImage(e,-g,-f),g*o/n+a<<0),y=Math.ceil(x*o/n),w=f*s/r/h+u<<0,v=Math.ceil(p*s/r/h);c.drawImage(d,0,0,x,p,E,w,y,v),g+=l}f+=l}}}}),e("moxie/runtime/html5/image/Image",["moxie/runtime/html5/Runtime","moxie/core/utils/Basic","moxie/core/Exceptions","moxie/core/utils/Encode","moxie/file/Blob","moxie/file/File","moxie/runtime/html5/image/ImageInfo","moxie/runtime/html5/image/MegaPixel","moxie/core/utils/Mime","moxie/core/utils/Env"],function(e,g,d,x,t,E,y,w,v,R){return e.Image=function(){var i,n,m,r,o,s=this,h=!1,f=!0;function p(){if(m||i)return m||i;throw new d.ImageError(d.DOMException.INVALID_STATE_ERR)}function a(e){return x.atob(e.substring(e.indexOf("base64,")+7))}function u(e){var t=this;(i=new Image).onerror=function(){l.call(this),t.trigger("error",d.ImageError.WRONG_FORMAT)},i.onload=function(){t.trigger("load")},i.src="data:"==e.substr(0,5)?e:"data:"+(o.type||"")+";base64,"+x.btoa(e)}function c(e,t,i,n){var r,o,s,a=0,u=0;if(f=n,o=this.meta&&this.meta.tiff&&this.meta.tiff.Orientation||1,-1!==g.inArray(o,[5,6,7,8])&&(s=e,e=t,t=s),s=p(),!(1<(r=i?(e=Math.min(e,s.width),t=Math.min(t,s.height),Math.max(e/s.width,t/s.height)):Math.min(e/s.width,t/s.height))&&!i&&n)){if(m=m||document.createElement("canvas"),n=Math.round(s.width*r),r=Math.round(s.height*r),i?(m.width=e,m.height=t,e<n&&(a=Math.round((n-e)/2)),t<r&&(u=Math.round((r-t)/2))):(m.width=n,m.height=r),!f){var c=m.width,l=m.height,i=o;switch(i){case 5:case 6:case 7:case 8:m.width=l,m.height=c;break;default:m.width=c,m.height=l}var d=m.getContext("2d");switch(i){case 2:d.translate(c,0),d.scale(-1,1);break;case 3:d.translate(c,l),d.rotate(Math.PI);break;case 4:d.translate(0,l),d.scale(1,-1);break;case 5:d.rotate(.5*Math.PI),d.scale(1,-1);break;case 6:d.rotate(.5*Math.PI),d.translate(0,-l);break;case 7:d.rotate(.5*Math.PI),d.translate(c,-l),d.scale(-1,1);break;case 8:d.rotate(-.5*Math.PI),d.translate(-c,0)}}!function(e,t,i,n,r,o){"iOS"===R.OS?w.renderTo(e,t,{width:r,height:o,x:i,y:n}):t.getContext("2d").drawImage(e,i,n,r,o)}.call(this,s,m,-a,-u,n,r),this.width=m.width,this.height=m.height,h=!0}this.trigger("Resize")}function l(){n&&(n.purge(),n=null),r=i=m=o=null,h=!1}g.extend(this,{loadFromBlob:function(e){var t=this,i=t.getRuntime(),n=!(1<arguments.length)||arguments[1];if(!i.can("access_binary"))throw new d.RuntimeError(d.RuntimeError.NOT_SUPPORTED_ERR);(o=e).isDetached()?(r=e.getSource(),u.call(this,r)):function(e,t){var i,n=this;{if(!window.FileReader)return t(e.getAsDataURL());(i=new FileReader).onload=function(){t(this.result)},i.onerror=function(){n.trigger("error",d.ImageError.WRONG_FORMAT)},i.readAsDataURL(e)}}.call(this,e.getSource(),function(e){n&&(r=a(e)),u.call(t,e)})},loadFromImage:function(e,t){this.meta=e.meta,o=new E(null,{name:e.name,size:e.size,type:e.type}),u.call(this,t?r=e.getAsBinaryString():e.getAsDataURL())},getInfo:function(){var e=this.getRuntime();return!n&&r&&e.can("access_image_binary")&&(n=new y(r)),!(e={width:p().width||0,height:p().height||0,type:o.type||v.getFileMime(o.name),size:r&&r.length||o.size||0,name:o.name||"",meta:n&&n.meta||this.meta||{}}).meta||!e.meta.thumb||e.meta.thumb.data instanceof t||(e.meta.thumb.data=new t(null,{type:"image/jpeg",data:e.meta.thumb.data})),e},downsize:function(){c.apply(this,arguments)},getAsCanvas:function(){return m&&(m.id=this.uid+"_canvas"),m},getAsBlob:function(e,t){return e!==this.type&&c.call(this,this.width,this.height,!1),new E(null,{name:o.name||"",type:e,data:s.getAsBinaryString.call(this,e,t)})},getAsDataURL:function(e){var t=arguments[1]||90;if(!h)return i.src;if("image/jpeg"!==e)return m.toDataURL("image/png");try{return m.toDataURL("image/jpeg",t/100)}catch(e){return m.toDataURL("image/jpeg")}},getAsBinaryString:function(e,t){if(!h)return r=r||a(s.getAsDataURL(e,t));if("image/jpeg"!==e)r=a(s.getAsDataURL(e,t));else{var i;t=t||90;try{i=m.toDataURL("image/jpeg",t/100)}catch(e){i=m.toDataURL("image/jpeg")}r=a(i),n&&(r=n.stripHeaders(r),f&&(n.meta&&n.meta.exif&&n.setExif({PixelXDimension:this.width,PixelYDimension:this.height}),r=n.writeHeaders(r)),n.purge(),n=null)}return h=!1,r},destroy:function(){s=null,l.call(this),this.getRuntime().getShim().removeInstance(this.uid)}})}}),e("moxie/runtime/flash/Runtime",[],function(){return{}}),e("moxie/runtime/silverlight/Runtime",[],function(){return{}}),e("moxie/runtime/html4/Runtime",["moxie/core/utils/Basic","moxie/core/Exceptions","moxie/runtime/Runtime","moxie/core/utils/Env"],function(o,e,s,a){var u={};return s.addConstructor("html4",function(e){var t,i=this,n=s.capTest,r=s.capTrue;s.call(this,e,"html4",{access_binary:n(window.FileReader||window.File&&File.getAsDataURL),access_image_binary:!1,display_media:n(u.Image&&(a.can("create_canvas")||a.can("use_data_uri_over32kb"))),do_cors:!1,drag_and_drop:!1,filter_by_extension:n("Chrome"===a.browser&&a.verComp(a.version,28,">=")||"IE"===a.browser&&a.verComp(a.version,10,">=")||"Safari"===a.browser&&a.verComp(a.version,7,">=")),resize_image:function(){return u.Image&&i.can("access_binary")&&a.can("create_canvas")},report_upload_progress:!1,return_response_headers:!1,return_response_type:function(e){return!("json"!==e||!window.JSON)||!!~o.inArray(e,["text","document",""])},return_status_code:function(e){return!o.arrayDiff(e,[200,404])},select_file:function(){return a.can("use_fileinput")},select_multiple:!1,send_binary_string:!1,send_custom_headers:!1,send_multipart:!0,slice_blob:!1,stream_upload:function(){return i.can("select_file")},summon_file_dialog:function(){return i.can("select_file")&&("Firefox"===a.browser&&a.verComp(a.version,4,">=")||"Opera"===a.browser&&a.verComp(a.version,12,">=")||"IE"===a.browser&&a.verComp(a.version,10,">=")||!!~o.inArray(a.browser,["Chrome","Safari"]))},upload_filesize:r,use_http_method:function(e){return!o.arrayDiff(e,["GET","POST"])}}),o.extend(this,{init:function(){this.trigger("Init")},destroy:(t=this.destroy,function(){t.call(i),t=i=null})}),o.extend(this.getShim(),u)}),u}),e("moxie/runtime/html4/file/FileInput",["moxie/runtime/html4/Runtime","moxie/file/File","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/utils/Events","moxie/core/utils/Mime","moxie/core/utils/Env"],function(e,d,m,h,f,s,p){return e.FileInput=function(){var a,u,c=[];function l(){var e,t,i,n=this,r=n.getRuntime(),o=m.guid("uid_"),s=r.getShimContainer();a&&(e=h.get(a+"_form"))&&m.extend(e.style,{top:"100%"}),(t=document.createElement("form")).setAttribute("id",o+"_form"),t.setAttribute("method","post"),t.setAttribute("enctype","multipart/form-data"),t.setAttribute("encoding","multipart/form-data"),m.extend(t.style,{overflow:"hidden",position:"absolute",top:0,left:0,width:"100%",height:"100%"}),(i=document.createElement("input")).setAttribute("id",o),i.setAttribute("type","file"),i.setAttribute("name",u.name||"Filedata"),i.setAttribute("accept",c.join(",")),m.extend(i.style,{fontSize:"999px",opacity:0}),t.appendChild(i),s.appendChild(t),m.extend(i.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),"IE"===p.browser&&p.verComp(p.version,10,"<")&&m.extend(i.style,{filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"}),i.onchange=function(){var e;if(this.value){if(this.files){if(0===(e=this.files[0]).size)return void t.parentNode.removeChild(t)}else e={name:this.value};e=new d(r.uid,e),this.onchange=function(){},l.call(n),n.files=[e],i.setAttribute("id",e.uid),t.setAttribute("id",e.uid+"_form"),n.trigger("change"),i=t=null}},r.can("summon_file_dialog")&&(e=h.get(u.browse_button),f.removeEvent(e,"click",n.uid),f.addEvent(e,"click",function(e){i&&!i.disabled&&i.click(),e.preventDefault()},n.uid)),a=o}m.extend(this,{init:function(e){var t,i,n,r=this,o=r.getRuntime();c=(u=e).accept.mimes||s.extList2mimes(e.accept,o.can("filter_by_extension")),t=o.getShimContainer(),n=h.get(e.browse_button),o.can("summon_file_dialog")&&("static"===h.getStyle(n,"position")&&(n.style.position="relative"),i=parseInt(h.getStyle(n,"z-index"),10)||1,n.style.zIndex=i,t.style.zIndex=i-1),i=o.can("summon_file_dialog")?n:t,f.addEvent(i,"mouseover",function(){r.trigger("mouseenter")},r.uid),f.addEvent(i,"mouseout",function(){r.trigger("mouseleave")},r.uid),f.addEvent(i,"mousedown",function(){r.trigger("mousedown")},r.uid),f.addEvent(h.get(e.container),"mouseup",function(){r.trigger("mouseup")},r.uid),l.call(this),t=null,r.trigger({type:"ready",async:!0})},disable:function(e){var t;(t=h.get(a))&&(t.disabled=!!e)},destroy:function(){var e=this.getRuntime(),t=e.getShim(),e=e.getShimContainer();f.removeAllEvents(e,this.uid),f.removeAllEvents(u&&h.get(u.container),this.uid),f.removeAllEvents(u&&h.get(u.browse_button),this.uid),e&&(e.innerHTML=""),t.removeInstance(this.uid),a=c=u=null}})}}),e("moxie/runtime/html4/file/FileReader",["moxie/runtime/html4/Runtime","moxie/runtime/html5/file/FileReader"],function(e,t){return e.FileReader=t}),e("moxie/runtime/html4/xhr/XMLHttpRequest",["moxie/runtime/html4/Runtime","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/utils/Url","moxie/core/Exceptions","moxie/core/utils/Events","moxie/file/Blob","moxie/xhr/FormData"],function(e,m,h,f,p,g,x,E){return e.XMLHttpRequest=function(){var u,c,l;function d(t){var e,i,n,r=this,o=!1;if(l){if(e=l.id.replace(/_iframe$/,""),e=h.get(e+"_form")){for(n=(i=e.getElementsByTagName("input")).length;n--;)switch(i[n].getAttribute("type")){case"hidden":i[n].parentNode.removeChild(i[n]);break;case"file":o=!0}i=[],o||e.parentNode.removeChild(e),e=null}setTimeout(function(){g.removeEvent(l,"load",r.uid),l.parentNode&&l.parentNode.removeChild(l);var e=r.getRuntime().getShimContainer();e.children.length||e.parentNode.removeChild(e),e=l=null,t()},1)}}m.extend(this,{send:function(t,e){var i,n,r,o,s=this,a=s.getRuntime();if(u=c=null,e instanceof E&&e.hasBlob()){if(o=e.getBlob(),i=o.uid,r=h.get(i),!(n=h.get(i+"_form")))throw new p.DOMException(p.DOMException.NOT_FOUND_ERR)}else i=m.guid("uid_"),(n=document.createElement("form")).setAttribute("id",i+"_form"),n.setAttribute("method",t.method),n.setAttribute("enctype","multipart/form-data"),n.setAttribute("encoding","multipart/form-data"),a.getShimContainer().appendChild(n);n.setAttribute("target",i+"_iframe"),e instanceof E&&e.each(function(e,t){var i;e instanceof x?r&&r.setAttribute("name",t):(i=document.createElement("input"),m.extend(i,{type:"hidden",name:t,value:e}),r?n.insertBefore(i,r):n.appendChild(i))}),n.setAttribute("action",t.url),e=a.getShimContainer()||document.body,(a=document.createElement("div")).innerHTML='<iframe id="'+i+'_iframe" name="'+i+'_iframe" src="javascript:&quot;&quot;" style="display:none"></iframe>',l=a.firstChild,e.appendChild(l),g.addEvent(l,"load",function(){var e;try{e=l.contentWindow.document||l.contentDocument||window.frames[l.id].document,/^4(0[0-9]|1[0-7]|2[2346])\s/.test(e.title)?u=e.title.replace(/^(\d+).*$/,"$1"):(u=200,c=m.trim(e.body.innerHTML),s.trigger({type:"progress",loaded:c.length,total:c.length}),o&&s.trigger({type:"uploadprogress",loaded:o.size||1025,total:o.size||1025}))}catch(e){if(!f.hasSameOrigin(t.url))return void d.call(s,function(){s.trigger("error")});u=404}d.call(s,function(){s.trigger("load")})},s.uid),n.submit(),s.trigger("loadstart")},getStatus:function(){return u},getResponse:function(e){if("json"===e&&"string"===m.typeOf(c)&&window.JSON)try{return JSON.parse(c.replace(/^\s*<pre[^>]*>/,"").replace(/<\/pre>\s*$/,""))}catch(e){return null}return c},abort:function(){var e=this;l&&l.contentWindow&&(l.contentWindow.stop?l.contentWindow.stop():l.contentWindow.document.execCommand?l.contentWindow.document.execCommand("Stop"):l.src="about:blank"),d.call(this,function(){e.dispatchEvent("abort")})}})}}),e("moxie/runtime/html4/image/Image",["moxie/runtime/html4/Runtime","moxie/runtime/html5/image/Image"],function(e,t){return e.Image=t});for(var t=["moxie/core/utils/Basic","moxie/core/utils/Env","moxie/core/I18n","moxie/core/utils/Mime","moxie/core/utils/Dom","moxie/core/Exceptions","moxie/core/EventTarget","moxie/runtime/Runtime","moxie/runtime/RuntimeClient","moxie/file/FileInput","moxie/core/utils/Encode","moxie/file/Blob","moxie/file/File","moxie/file/FileDrop","moxie/file/FileReader","moxie/core/utils/Url","moxie/runtime/RuntimeTarget","moxie/file/FileReaderSync","moxie/xhr/FormData","moxie/xhr/XMLHttpRequest","moxie/runtime/Transporter","moxie/image/Image","moxie/core/utils/Events"],i=0;i<t.length;i++){for(var r=o,a=t[i],u=a.split(/[.\/]/),c=0;c<u.length-1;++c)r[u[c]]===x&&(r[u[c]]={}),r=r[u[c]];r[u[u.length-1]]=s[a]}}(this),function(e){"use strict";var r={},o=e.moxie.core.utils.Basic.inArray;!function e(t){var i,n;for(i in t)"object"!=(n=typeof t[i])||~o(i,["Exceptions","Env","Mime"])?"function"==n&&(r[i]=t[i]):e(t[i])}(e.moxie),r.Env=e.moxie.core.utils.Env,r.Mime=e.moxie.core.utils.Mime,r.Exceptions=e.moxie.core.Exceptions,e.mOxie=r,e.o||(e.o=r)}(this);
// source --> https://polskipsychologwuk.com/wp-includes/js/plupload/plupload.min.js?ver=2.1.9 
!function(e,I,S){var T=e.setTimeout,D={};function w(e){var t=e.required_features,r={};function i(e,t,i){var n={chunks:"slice_blob",jpgresize:"send_binary_string",pngresize:"send_binary_string",progress:"report_upload_progress",multi_selection:"select_multiple",dragdrop:"drag_and_drop",drop_element:"drag_and_drop",headers:"send_custom_headers",urlstream_upload:"send_binary_string",canSendBinary:"send_binary",triggerDialog:"summon_file_dialog"};n[e]?r[n[e]]=t:i||(r[e]=t)}return"string"==typeof t?F.each(t.split(/\s*,\s*/),function(e){i(e,!0)}):"object"==typeof t?F.each(t,function(e,t){i(t,e)}):!0===t&&(0<e.chunk_size&&(r.slice_blob=!0),!e.resize.enabled&&e.multipart||(r.send_binary_string=!0),F.each(e,function(e,t){i(t,!!e,!0)})),e.runtimes="html5,html4",r}var t,F={VERSION:"2.1.9",STOPPED:1,STARTED:2,QUEUED:1,UPLOADING:2,FAILED:4,DONE:5,GENERIC_ERROR:-100,HTTP_ERROR:-200,IO_ERROR:-300,SECURITY_ERROR:-400,INIT_ERROR:-500,FILE_SIZE_ERROR:-600,FILE_EXTENSION_ERROR:-601,FILE_DUPLICATE_ERROR:-602,IMAGE_FORMAT_ERROR:-700,MEMORY_ERROR:-701,IMAGE_DIMENSIONS_ERROR:-702,mimeTypes:I.mimes,ua:I.ua,typeOf:I.typeOf,extend:I.extend,guid:I.guid,getAll:function(e){for(var t,i=[],n=(e="array"!==F.typeOf(e)?[e]:e).length;n--;)(t=F.get(e[n]))&&i.push(t);return i.length?i:null},get:I.get,each:I.each,getPos:I.getPos,getSize:I.getSize,xmlEncode:function(e){var t={"<":"lt",">":"gt","&":"amp",'"':"quot","'":"#39"};return e&&(""+e).replace(/[<>&\"\']/g,function(e){return t[e]?"&"+t[e]+";":e})},toArray:I.toArray,inArray:I.inArray,addI18n:I.addI18n,translate:I.translate,isEmptyObj:I.isEmptyObj,hasClass:I.hasClass,addClass:I.addClass,removeClass:I.removeClass,getStyle:I.getStyle,addEvent:I.addEvent,removeEvent:I.removeEvent,removeAllEvents:I.removeAllEvents,cleanName:function(e){for(var t=[/[\300-\306]/g,"A",/[\340-\346]/g,"a",/\307/g,"C",/\347/g,"c",/[\310-\313]/g,"E",/[\350-\353]/g,"e",/[\314-\317]/g,"I",/[\354-\357]/g,"i",/\321/g,"N",/\361/g,"n",/[\322-\330]/g,"O",/[\362-\370]/g,"o",/[\331-\334]/g,"U",/[\371-\374]/g,"u"],i=0;i<t.length;i+=2)e=e.replace(t[i],t[i+1]);return e=(e=e.replace(/\s+/g,"_")).replace(/[^a-z0-9_\-\.]+/gi,"")},buildUrl:function(e,t){var i="";return F.each(t,function(e,t){i+=(i?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(e)}),i&&(e+=(0<e.indexOf("?")?"&":"?")+i),e},formatSize:function(e){var t;return e===S||/\D/.test(e)?F.translate("N/A"):(t=Math.pow(1024,4))<e?i(e/t,1)+" "+F.translate("tb"):e>(t/=1024)?i(e/t,1)+" "+F.translate("gb"):e>(t/=1024)?i(e/t,1)+" "+F.translate("mb"):1024<e?Math.round(e/1024)+" "+F.translate("kb"):e+" "+F.translate("b");function i(e,t){return Math.round(e*Math.pow(10,t))/Math.pow(10,t)}},parseSize:I.parseSizeStr,predictRuntime:function(e,t){var i=new F.Uploader(e),t=I.Runtime.thatCan(i.getOption().required_features,t||e.runtimes);return i.destroy(),t},addFileFilter:function(e,t){D[e]=t}};F.addFileFilter("mime_types",function(e,t,i){e.length&&!e.regexp.test(t.name)?(this.trigger("Error",{code:F.FILE_EXTENSION_ERROR,message:F.translate("File extension error."),file:t}),i(!1)):i(!0)}),F.addFileFilter("max_file_size",function(e,t,i){e=F.parseSize(e),void 0!==t.size&&e&&t.size>e?(this.trigger("Error",{code:F.FILE_SIZE_ERROR,message:F.translate("File size error."),file:t}),i(!1)):i(!0)}),F.addFileFilter("prevent_duplicates",function(e,t,i){if(e)for(var n=this.files.length;n--;)if(t.name===this.files[n].name&&t.size===this.files[n].size)return this.trigger("Error",{code:F.FILE_DUPLICATE_ERROR,message:F.translate("Duplicate file error."),file:t}),void i(!1);i(!0)}),F.Uploader=function(e){var u,i,n,p,t=F.guid(),l=[],h={},o=[],d=[],c=!1;function r(){var e,t,i=0;if(this.state==F.STARTED){for(t=0;t<l.length;t++)e||l[t].status!=F.QUEUED?i++:(e=l[t],this.trigger("BeforeUpload",e)&&(e.status=F.UPLOADING,this.trigger("UploadFile",e)));i==l.length&&(this.state!==F.STOPPED&&(this.state=F.STOPPED,this.trigger("StateChanged")),this.trigger("UploadComplete",l))}}function s(e){e.percent=0<e.size?Math.ceil(e.loaded/e.size*100):100,a()}function a(){var e,t;for(n.reset(),e=0;e<l.length;e++)(t=l[e]).size!==S?(n.size+=t.origSize,n.loaded+=t.loaded*t.origSize/t.size):n.size=S,t.status==F.DONE?n.uploaded++:t.status==F.FAILED?n.failed++:n.queued++;n.size===S?n.percent=0<l.length?Math.ceil(n.uploaded/l.length*100):0:(n.bytesPerSec=Math.ceil(n.loaded/((+new Date-i||1)/1e3)),n.percent=0<n.size?Math.ceil(n.loaded/n.size*100):0)}function f(){var e=o[0]||d[0];return!!e&&e.getRuntime().uid}function g(n,e){var r=this,s=0,t=[],a={runtime_order:n.runtimes,required_caps:n.required_features,preferred_caps:h};F.each(n.runtimes.split(/\s*,\s*/),function(e){n[e]&&(a[e]=n[e])}),n.browse_button&&F.each(n.browse_button,function(i){t.push(function(t){var e=new I.FileInput(F.extend({},a,{accept:n.filters.mime_types,name:n.file_data_name,multiple:n.multi_selection,container:n.container,browse_button:i}));e.onready=function(){var e=I.Runtime.getInfo(this.ruid);I.extend(r.features,{chunks:e.can("slice_blob"),multipart:e.can("send_multipart"),multi_selection:e.can("select_multiple")}),s++,o.push(this),t()},e.onchange=function(){r.addFile(this.files)},e.bind("mouseenter mouseleave mousedown mouseup",function(e){c||(n.browse_button_hover&&("mouseenter"===e.type?I.addClass(i,n.browse_button_hover):"mouseleave"===e.type&&I.removeClass(i,n.browse_button_hover)),n.browse_button_active&&("mousedown"===e.type?I.addClass(i,n.browse_button_active):"mouseup"===e.type&&I.removeClass(i,n.browse_button_active)))}),e.bind("mousedown",function(){r.trigger("Browse")}),e.bind("error runtimeerror",function(){e=null,t()}),e.init()})}),n.drop_element&&F.each(n.drop_element,function(i){t.push(function(t){var e=new I.FileDrop(F.extend({},a,{drop_zone:i}));e.onready=function(){var e=I.Runtime.getInfo(this.ruid);I.extend(r.features,{chunks:e.can("slice_blob"),multipart:e.can("send_multipart"),dragdrop:e.can("drag_and_drop")}),s++,d.push(this),t()},e.ondrop=function(){r.addFile(this.files)},e.bind("error runtimeerror",function(){e=null,t()}),e.init()})}),I.inSeries(t,function(){"function"==typeof e&&e(s)})}function _(e,t,i){var a=this,o=!1;function n(e,t,i){var n,r,s=u[e];switch(e){case"max_file_size":"max_file_size"===e&&(u.max_file_size=u.filters.max_file_size=t);break;case"chunk_size":(t=F.parseSize(t))&&(u[e]=t,u.send_file_name=!0);break;case"multipart":(u[e]=t)||(u.send_file_name=!0);break;case"unique_names":(u[e]=t)&&(u.send_file_name=!0);break;case"filters":"array"===F.typeOf(t)&&(t={mime_types:t}),i?F.extend(u.filters,t):u.filters=t,t.mime_types&&(u.filters.mime_types.regexp=(n=u.filters.mime_types,r=[],F.each(n,function(e){F.each(e.extensions.split(/,/),function(e){/^\s*\*\s*$/.test(e)?r.push("\\.*"):r.push("\\."+e.replace(new RegExp("["+"/^$.*+?|()[]{}\\".replace(/./g,"\\$&")+"]","g"),"\\$&"))})}),new RegExp("("+r.join("|")+")$","i")));break;case"resize":i?F.extend(u.resize,t,{enabled:!0}):u.resize=t;break;case"prevent_duplicates":u.prevent_duplicates=u.filters.prevent_duplicates=!!t;break;case"container":case"browse_button":case"drop_element":t="container"===e?F.get(t):F.getAll(t);case"runtimes":case"multi_selection":u[e]=t,i||(o=!0);break;default:u[e]=t}i||a.trigger("OptionChanged",e,t,s)}"object"==typeof e?F.each(e,function(e,t){n(t,e,i)}):n(e,t,i),i?(u.required_features=w(F.extend({},u)),h=w(F.extend({},u,{required_features:!0}))):o&&(a.trigger("Destroy"),g.call(a,u,function(e){e?(a.runtime=I.Runtime.getInfo(f()).type,a.trigger("Init",{runtime:a.runtime}),a.trigger("PostInit")):a.trigger("Error",{code:F.INIT_ERROR,message:F.translate("Init error.")})}))}function m(e,t){var i;e.settings.unique_names&&(e="part",(i=t.name.match(/\.([^.]+)$/))&&(e=i[1]),t.target_name=t.id+"."+e)}function b(r,s){var a,o=r.settings.url,u=r.settings.chunk_size,l=r.settings.max_retries,d=r.features,c=0;function f(){0<l--?T(g,1e3):(s.loaded=c,r.trigger("Error",{code:F.HTTP_ERROR,message:F.translate("HTTP Error."),file:s,response:p.responseText,status:p.status,responseHeaders:p.getAllResponseHeaders()}))}function g(){var e,i,t,n={};s.status===F.UPLOADING&&r.state!==F.STOPPED&&(r.settings.send_file_name&&(n.name=s.target_name||s.name),e=u&&d.chunks&&a.size>u?(t=Math.min(u,a.size-c),a.slice(c,c+t)):(t=a.size,a),u&&d.chunks&&(r.settings.send_chunk_number?(n.chunk=Math.ceil(c/u),n.chunks=Math.ceil(a.size/u)):(n.offset=c,n.total=a.size)),(p=new I.XMLHttpRequest).upload&&(p.upload.onprogress=function(e){s.loaded=Math.min(s.size,c+e.loaded),r.trigger("UploadProgress",s)}),p.onload=function(){400<=p.status?f():(l=r.settings.max_retries,t<a.size?(e.destroy(),c+=t,s.loaded=Math.min(c,a.size),r.trigger("ChunkUploaded",s,{offset:s.loaded,total:a.size,response:p.responseText,status:p.status,responseHeaders:p.getAllResponseHeaders()}),"Android Browser"===I.Env.browser&&r.trigger("UploadProgress",s)):s.loaded=s.size,e=i=null,!c||c>=a.size?(s.size!=s.origSize&&(a.destroy(),a=null),r.trigger("UploadProgress",s),s.status=F.DONE,r.trigger("FileUploaded",s,{response:p.responseText,status:p.status,responseHeaders:p.getAllResponseHeaders()})):T(g,1))},p.onerror=function(){f()},p.onloadend=function(){this.destroy(),p=null},r.settings.multipart&&d.multipart?(p.open("post",o,!0),F.each(r.settings.headers,function(e,t){p.setRequestHeader(t,e)}),i=new I.FormData,F.each(F.extend(n,r.settings.multipart_params),function(e,t){i.append(t,e)}),i.append(r.settings.file_data_name,e),p.send(i,{runtime_order:r.settings.runtimes,required_caps:r.settings.required_features,preferred_caps:h})):(o=F.buildUrl(r.settings.url,F.extend(n,r.settings.multipart_params)),p.open("post",o,!0),p.setRequestHeader("Content-Type","application/octet-stream"),F.each(r.settings.headers,function(e,t){p.setRequestHeader(t,e)}),p.send(e,{runtime_order:r.settings.runtimes,required_caps:r.settings.required_features,preferred_caps:h})))}s.loaded&&(c=s.loaded=u?u*Math.floor(s.loaded/u):0),a=s.getSource(),r.settings.resize.enabled&&function(e,t){if(e.ruid){e=I.Runtime.getInfo(e.ruid);if(e)return e.can(t)}}(a,"send_binary_string")&&~I.inArray(a.type,["image/jpeg","image/png"])?function(t,e,i){var n=new I.Image;try{n.onload=function(){if(e.width>this.width&&e.height>this.height&&e.quality===S&&e.preserve_headers&&!e.crop)return this.destroy(),i(t);n.downsize(e.width,e.height,e.crop,e.preserve_headers)},n.onresize=function(){i(this.getAsBlob(t.type,e.quality)),this.destroy()},n.onerror=function(){i(t)},n.load(t)}catch(e){i(t)}}.call(this,a,r.settings.resize,function(e){a=e,s.size=e.size,g()}):g()}function R(e,t){s(t)}function E(e){if(e.state==F.STARTED)i=+new Date;else if(e.state==F.STOPPED)for(var t=e.files.length-1;0<=t;t--)e.files[t].status==F.UPLOADING&&(e.files[t].status=F.QUEUED,a())}function y(){p&&p.abort()}function v(e){a(),T(function(){r.call(e)},1)}function z(e,t){t.code===F.INIT_ERROR?e.destroy():t.code===F.HTTP_ERROR&&(t.file.status=F.FAILED,s(t.file),e.state==F.STARTED)&&(e.trigger("CancelUpload"),T(function(){r.call(e)},1))}function O(e){e.stop(),F.each(l,function(e){e.destroy()}),l=[],o.length&&(F.each(o,function(e){e.destroy()}),o=[]),d.length&&(F.each(d,function(e){e.destroy()}),d=[]),c=!(h={}),i=p=null,n.reset()}u={runtimes:I.Runtime.order,max_retries:0,chunk_size:0,multipart:!0,multi_selection:!0,file_data_name:"file",filters:{mime_types:[],prevent_duplicates:!1,max_file_size:0},resize:{enabled:!1,preserve_headers:!0,crop:!1},send_file_name:!0,send_chunk_number:!0},_.call(this,e,null,!0),n=new F.QueueProgress,F.extend(this,{id:t,uid:t,state:F.STOPPED,features:{},runtime:null,files:l,settings:u,total:n,init:function(){var t,i=this,e=i.getOption("preinit");return"function"==typeof e?e(i):F.each(e,function(e,t){i.bind(t,e)}),function(){this.bind("FilesAdded FilesRemoved",function(e){e.trigger("QueueChanged"),e.refresh()}),this.bind("CancelUpload",y),this.bind("BeforeUpload",m),this.bind("UploadFile",b),this.bind("UploadProgress",R),this.bind("StateChanged",E),this.bind("QueueChanged",a),this.bind("Error",z),this.bind("FileUploaded",v),this.bind("Destroy",O)}.call(i),F.each(["container","browse_button","drop_element"],function(e){if(null===i.getOption(e))return!(t={code:F.INIT_ERROR,message:F.translate("'%' specified, but cannot be found.")})}),t?i.trigger("Error",t):u.browse_button||u.drop_element?void g.call(i,u,function(e){var t=i.getOption("init");"function"==typeof t?t(i):F.each(t,function(e,t){i.bind(t,e)}),e?(i.runtime=I.Runtime.getInfo(f()).type,i.trigger("Init",{runtime:i.runtime}),i.trigger("PostInit")):i.trigger("Error",{code:F.INIT_ERROR,message:F.translate("Init error.")})}):i.trigger("Error",{code:F.INIT_ERROR,message:F.translate("You must specify either 'browse_button' or 'drop_element'.")})},setOption:function(e,t){_.call(this,e,t,!this.runtime)},getOption:function(e){return e?u[e]:u},refresh:function(){o.length&&F.each(o,function(e){e.trigger("Refresh")}),this.trigger("Refresh")},start:function(){this.state!=F.STARTED&&(this.state=F.STARTED,this.trigger("StateChanged"),r.call(this))},stop:function(){this.state!=F.STOPPED&&(this.state=F.STOPPED,this.trigger("StateChanged"),this.trigger("CancelUpload"))},disableBrowse:function(){c=arguments[0]===S||arguments[0],o.length&&F.each(o,function(e){e.disable(c)}),this.trigger("DisableBrowse",c)},getFile:function(e){for(var t=l.length-1;0<=t;t--)if(l[t].id===e)return l[t]},addFile:function(e,n){var r,s=this,a=[],o=[];r=f(),function e(i){var t=I.typeOf(i);if(i instanceof I.File){if(!i.ruid&&!i.isDetached()){if(!r)return!1;i.ruid=r,i.connectRuntime(r)}e(new F.File(i))}else i instanceof I.Blob?(e(i.getSource()),i.destroy()):i instanceof F.File?(n&&(i.name=n),a.push(function(t){var n,e,r;n=i,e=function(e){e||(l.push(i),o.push(i),s.trigger("FileFiltered",i)),T(t,1)},r=[],I.each(s.settings.filters,function(e,i){D[i]&&r.push(function(t){D[i].call(s,e,n,function(e){t(!e)})})}),I.inSeries(r,e)})):-1!==I.inArray(t,["file","blob"])?e(new I.File(null,i)):"node"===t&&"filelist"===I.typeOf(i.files)?I.each(i.files,e):"array"===t&&(n=null,I.each(i,e))}(e),a.length&&I.inSeries(a,function(){o.length&&s.trigger("FilesAdded",o)})},removeFile:function(e){for(var t="string"==typeof e?e:e.id,i=l.length-1;0<=i;i--)if(l[i].id===t)return this.splice(i,1)[0]},splice:function(e,t){var e=l.splice(e===S?0:e,t===S?l.length:t),i=!1;return this.state==F.STARTED&&(F.each(e,function(e){if(e.status===F.UPLOADING)return!(i=!0)}),i)&&this.stop(),this.trigger("FilesRemoved",e),F.each(e,function(e){e.destroy()}),i&&this.start(),e},dispatchEvent:function(e){var t,i;if(e=e.toLowerCase(),t=this.hasEventListener(e)){t.sort(function(e,t){return t.priority-e.priority}),(i=[].slice.call(arguments)).shift(),i.unshift(this);for(var n=0;n<t.length;n++)if(!1===t[n].fn.apply(t[n].scope,i))return!1}return!0},bind:function(e,t,i,n){F.Uploader.prototype.bind.call(this,e,t,n,i)},destroy:function(){this.trigger("Destroy"),u=n=null,this.unbindAll()}})},F.Uploader.prototype=I.EventTarget.instance,F.File=(t={},function(e){F.extend(this,{id:F.guid(),name:e.name||e.fileName,type:e.type||"",size:e.size||e.fileSize,origSize:e.size||e.fileSize,loaded:0,percent:0,status:F.QUEUED,lastModifiedDate:e.lastModifiedDate||(new Date).toLocaleString(),getNative:function(){var e=this.getSource().getSource();return-1!==I.inArray(I.typeOf(e),["blob","file"])?e:null},getSource:function(){return t[this.id]||null},destroy:function(){var e=this.getSource();e&&(e.destroy(),delete t[this.id])}}),t[this.id]=e}),F.QueueProgress=function(){var e=this;e.size=0,e.loaded=0,e.uploaded=0,e.failed=0,e.queued=0,e.percent=0,e.bytesPerSec=0,e.reset=function(){e.size=e.loaded=e.uploaded=e.failed=e.queued=e.percent=e.bytesPerSec=0}},e.plupload=F}(window,mOxie);
// source --> https://polskipsychologwuk.com/wp-content/plugins/booking-ultra-pro/js/languages/jquery.validationEngine-en.js?ver=6.9.4 
(function($){
    $.fn.validationEngineLanguage = function(){
    };
    $.validationEngineLanguage = {
        newLang: function(){
            $.validationEngineLanguage.allRules = {
                "required": { // Add your regex rules here, you can take telephone as an example
                    "regex": "none",
                    "alertText": "* This field is required",
                    "alertTextCheckboxMultiple": "* Please select an option",
                    "alertTextCheckboxe": "* This checkbox is required",
                    "alertTextDateRange": "* Both date range fields are required"
                },
                "requiredInFunction": { 
                    "func": function(field, rules, i, options){
                        return (field.val() == "test") ? true : false;
                    },
                    "alertText": "* Field must equal test"
                },
                "dateRange": {
                    "regex": "none",
                    "alertText": "* Invalid ",
                    "alertText2": "Date Range"
                },
                "dateTimeRange": {
                    "regex": "none",
                    "alertText": "* Invalid ",
                    "alertText2": "Date Time Range"
                },
                "minSize": {
                    "regex": "none",
                    "alertText": "* Minimum ",
                    "alertText2": " characters required"
                },
                "maxSize": {
                    "regex": "none",
                    "alertText": "* Maximum ",
                    "alertText2": " characters allowed"
                },
		"groupRequired": {
                    "regex": "none",
                    "alertText": "* You must fill one of the following fields",
                    "alertTextCheckboxMultiple": "* Please select an option",
                    "alertTextCheckboxe": "* This checkbox is required"
                },
                "min": {
                    "regex": "none",
                    "alertText": "* Minimum value is "
                },
                "max": {
                    "regex": "none",
                    "alertText": "* Maximum value is "
                },
                "past": {
                    "regex": "none",
                    "alertText": "* Date prior to "
                },
                "future": {
                    "regex": "none",
                    "alertText": "* Date past "
                },	
                "maxCheckbox": {
                    "regex": "none",
                    "alertText": "* Maximum ",
                    "alertText2": " options allowed"
                },
                "minCheckbox": {
                    "regex": "none",
                    "alertText": "* Please select ",
                    "alertText2": " options"
                },
                "equals": {
                    "regex": "none",
                    "alertText": "* Fields do not match"
                },
                "creditCard": {
                    "regex": "none",
                    "alertText": "* Invalid credit card number"
                },
                "phone": {
                    // credit: jquery.h5validate.js / orefalo
                    "regex": /^([\+][0-9]{1,3}([ \.\-])?)?([\(][0-9]{1,6}[\)])?([0-9 \.\-]{1,32})(([A-Za-z \:]{1,11})?[0-9]{1,4}?)$/,
                    "alertText": "* Invalid phone number"
                },
                "email": {
                    // HTML5 compatible email regex ( http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#    e-mail-state-%28type=email%29 )
                    "regex": /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
                    "alertText": "* Invalid email address"
                },
                "fullname": {
                    "regex":/^([a-zA-Z]+[\'\,\.\-]?[a-zA-Z ]*)+[ ]([a-zA-Z]+[\'\,\.\-]?[a-zA-Z ]+)+$/,
                    "alertText":"* Must be first and last name"
                },
                "zip": {
                    "regex":/^\d{5}$|^\d{5}-\d{4}$/,
                    "alertText":"* Invalid zip format"
                },
                "integer": {
                    "regex": /^[\-\+]?\d+$/,
                    "alertText": "* Not a valid integer"
                },
                "number": {
                    // Number, including positive, negative, and floating decimal. credit: orefalo
                    "regex": /^[\-\+]?((([0-9]{1,3})([,][0-9]{3})*)|([0-9]+))?([\.]([0-9]+))?$/,
                    "alertText": "* Invalid floating decimal number"
                },
                "date": {                    
                    //	Check if date is valid by leap year
			"func": function (field) {
					var pattern = new RegExp(/^(\d{4})[\/\-\.](0?[1-9]|1[012])[\/\-\.](0?[1-9]|[12][0-9]|3[01])$/);
					var match = pattern.exec(field.val());
					if (match == null)
					   return false;
	
					var year = match[1];
					var month = match[2]*1;
					var day = match[3]*1;					
					var date = new Date(year, month - 1, day); // because months starts from 0.
	
					return (date.getFullYear() == year && date.getMonth() == (month - 1) && date.getDate() == day);
				},                		
			 "alertText": "* Invalid date, must be in YYYY-MM-DD format"
                },
                "ipv4": {
                    "regex": /^((([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))[.]){3}(([0-1]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))$/,
                    "alertText": "* Invalid IP address"
                },
                "url": {
                    "regex": /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,
                    "alertText": "* Invalid URL"
                },
                "onlyNumberSp": {
                    "regex": /^[0-9\ ]+$/,
                    "alertText": "* Numbers only"
                },
                "onlyLetterSp": {
                    "regex": /^[a-zA-Z\ \']+$/,
                    "alertText": "* Letters only"
                },
                "onlyLetterNumber": {
                    "regex": /^[0-9a-zA-Z]+$/,
                    "alertText": "* No special characters allowed"
                },
                // --- CUSTOM RULES -- Those are specific to the demos, they can be removed or changed to your likings
                "ajaxUserCall": {
                    "url": "ajaxValidateFieldUser",
                    // you may want to pass extra data on the ajax call
                    "extraData": "name=eric",
                    "alertText": "* This user is already taken",
                    "alertTextLoad": "* Validating, please wait"
                },
				"ajaxUserCallPhp": {
                    "url": "phpajax/ajaxValidateFieldUser.php",
                    // you may want to pass extra data on the ajax call
                    "extraData": "name=eric",
                    // if you provide an "alertTextOk", it will show as a green prompt when the field validates
                    "alertTextOk": "* This username is available",
                    "alertText": "* This user is already taken",
                    "alertTextLoad": "* Validating, please wait"
                },
                "ajaxNameCall": {
                    // remote json service location
                    "url": "ajaxValidateFieldName",
                    // error
                    "alertText": "* This name is already taken",
                    // if you provide an "alertTextOk", it will show as a green prompt when the field validates
                    "alertTextOk": "* This name is available",
                    // speaks by itself
                    "alertTextLoad": "* Validating, please wait"
                },
				 "ajaxNameCallPhp": {
	                    // remote json service location
	                    "url": "phpajax/ajaxValidateFieldName.php",
	                    // error
	                    "alertText": "* This name is already taken",
	                    // speaks by itself
	                    "alertTextLoad": "* Validating, please wait"
	                },
                "validate2fields": {
                    "alertText": "* Please input HELLO"
                },
	            //tls warning:homegrown not fielded 
                "dateFormat":{
                    "regex": /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$|^(?:(?:(?:0?[13578]|1[02])(\/|-)31)|(?:(?:0?[1,3-9]|1[0-2])(\/|-)(?:29|30)))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^(?:(?:0?[1-9]|1[0-2])(\/|-)(?:0?[1-9]|1\d|2[0-8]))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^(0?2(\/|-)29)(\/|-)(?:(?:0[48]00|[13579][26]00|[2468][048]00)|(?:\d\d)?(?:0[48]|[2468][048]|[13579][26]))$/,
                    "alertText": "* Invalid Date"
                },
                //tls warning:homegrown not fielded 
				"dateTimeFormat": {
	                "regex": /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])\s+(1[012]|0?[1-9]){1}:(0?[1-5]|[0-6][0-9]){1}:(0?[0-6]|[0-6][0-9]){1}\s+(am|pm|AM|PM){1}$|^(?:(?:(?:0?[13578]|1[02])(\/|-)31)|(?:(?:0?[1,3-9]|1[0-2])(\/|-)(?:29|30)))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^((1[012]|0?[1-9]){1}\/(0?[1-9]|[12][0-9]|3[01]){1}\/\d{2,4}\s+(1[012]|0?[1-9]){1}:(0?[1-5]|[0-6][0-9]){1}:(0?[0-6]|[0-6][0-9]){1}\s+(am|pm|AM|PM){1})$/,
                    "alertText": "* Invalid Date or Date Format",
                    "alertText2": "Expected Format: ",
                    "alertText3": "mm/dd/yyyy hh:mm:ss AM|PM or ", 
                    "alertText4": "yyyy-mm-dd hh:mm:ss AM|PM"
	            }
            };
            
        }
    };

    $.validationEngineLanguage.newLang();
    
})(jQuery);
// source --> https://polskipsychologwuk.com/wp-content/plugins/booking-ultra-pro/js/jquery.validationEngine.js?ver=6.9.4 
/*
 * Inline Form Validation Engine 2.6.2, jQuery plugin
 *
 * Copyright(c) 2010, Cedric Dugas
 * http://www.position-absolute.com
 *
 * 2.0 Rewrite by Olivier Refalo
 * http://www.crionics.com
 *
 * Form validation engine allowing custom regex rules to be added.
 * Licensed under the MIT License
 */
 (function($) {

	"use strict";

	var methods = {

		/**
		* Kind of the constructor, called before any action
		* @param {Map} user options
		*/
		init: function(options) {
			var form = this;
			if (!form.data('jqv') || form.data('jqv') == null ) {
				options = methods._saveOptions(form, options);
				// bind all formError elements to close on click
				$(document).on("click", ".formError", function() {
					$(this).fadeOut(150, function() {
						// remove prompt once invisible
						$(this).parent('.formErrorOuter').remove();
						$(this).remove();
					});
				});
			}
			return this;
		 },
		/**
		* Attachs jQuery.validationEngine to form.submit and field.blur events
		* Takes an optional params: a list of options
		* ie. jQuery("#formID1").validationEngine('attach', {promptPosition : "centerRight"});
		*/
		attach: function(userOptions) {

			var form = this;
			var options;

			if(userOptions)
				options = methods._saveOptions(form, userOptions);
			else
				options = form.data('jqv');

			options.validateAttribute = (form.find("[data-validation-engine*=validate]").length) ? "data-validation-engine" : "class";
			if (options.binded) {

				// delegate fields
				form.on(options.validationEventTrigger, "["+options.validateAttribute+"*=validate]:not([type=checkbox]):not([type=radio]):not(.datepicker)", methods._onFieldEvent);
				form.on("click", "["+options.validateAttribute+"*=validate][type=checkbox],["+options.validateAttribute+"*=validate][type=radio]", methods._onFieldEvent);
				form.on(options.validationEventTrigger,"["+options.validateAttribute+"*=validate][class*=datepicker]", {"delay": 300}, methods._onFieldEvent);
			}
			if (options.autoPositionUpdate) {
				$(window).bind("resize", {
					"noAnimation": true,
					"formElem": form
				}, methods.updatePromptsPosition);
			}
			form.on("click","a[data-validation-engine-skip], a[class*='validate-skip'], button[data-validation-engine-skip], button[class*='validate-skip'], input[data-validation-engine-skip], input[class*='validate-skip']", methods._submitButtonClick);
			form.removeData('jqv_submitButton');

			// bind form.submit
			form.on("submit", methods._onSubmitEvent);
			return this;
		},
		/**
		* Unregisters any bindings that may point to jQuery.validaitonEngine
		*/
		detach: function() {

			var form = this;
			var options = form.data('jqv');

			// unbind fields
			form.off(options.validationEventTrigger, "["+options.validateAttribute+"*=validate]:not([type=checkbox]):not([type=radio]):not(.datepicker)", methods._onFieldEvent);
			form.off("click", "["+options.validateAttribute+"*=validate][type=checkbox],["+options.validateAttribute+"*=validate][type=radio]", methods._onFieldEvent);
			form.off(options.validationEventTrigger,"["+options.validateAttribute+"*=validate][class*=datepicker]", methods._onFieldEvent);

			// unbind form.submit
			form.off("submit", methods._onSubmitEvent);
			form.removeData('jqv');

			form.off("click", "a[data-validation-engine-skip], a[class*='validate-skip'], button[data-validation-engine-skip], button[class*='validate-skip'], input[data-validation-engine-skip], input[class*='validate-skip']", methods._submitButtonClick);
			form.removeData('jqv_submitButton');

			if (options.autoPositionUpdate)
				$(window).off("resize", methods.updatePromptsPosition);

			return this;
		},
		/**
		* Validates either a form or a list of fields, shows prompts accordingly.
		* Note: There is no ajax form validation with this method, only field ajax validation are evaluated
		*
		* @return true if the form validates, false if it fails
		*/
		validate: function() {
			var element = $(this);
			var valid = null;

			if (element.is("form") || element.hasClass("validationEngineContainer")) {
				if (element.hasClass('validating')) {
					// form is already validating.
					// Should abort old validation and start new one. I don't know how to implement it.
					return false;
				} else {
					element.addClass('validating');
					var options = element.data('jqv');
					var valid = methods._validateFields(this);

					// If the form doesn't validate, clear the 'validating' class before the user has a chance to submit again
					setTimeout(function(){
						element.removeClass('validating');
					}, 100);
					if (valid && options.onSuccess) {
						options.onSuccess();
					} else if (!valid && options.onFailure) {
						options.onFailure();
					}
				}
			} else if (element.is('form') || element.hasClass('validationEngineContainer')) {
				element.removeClass('validating');
			} else {
				// field validation
				var form = element.closest('form, .validationEngineContainer'),
					options = (form.data('jqv')) ? form.data('jqv') : $.validationEngine.defaults,
					valid = methods._validateField(element, options);
			}
			if(options.onValidationComplete) {
				// !! ensures that an undefined return is interpreted as return false but allows a onValidationComplete() to possibly return true and have form continue processing
				return !!options.onValidationComplete(form, valid);
			}
			return valid;
		},
		/**
		*  Redraw prompts position, useful when you change the DOM state when validating
		*/
		updatePromptsPosition: function(event) {

			if (event && this == window) {
				var form = event.data.formElem;
				var noAnimation = event.data.noAnimation;
			}
			else
				var form = $(this.closest('form, .validationEngineContainer'));

			var options = form.data('jqv');
			// No option, take default one
			if (!options)
				options = methods._saveOptions(form, options);
			form.find('['+options.validateAttribute+'*=validate]').not(":disabled").each(function(){
				var field = $(this);
				if (options.prettySelect && field.is(":hidden"))
				  field = form.find("#" + options.usePrefix + field.attr('id') + options.useSuffix);
				var prompt = methods._getPrompt(field);
				var promptText = $(prompt).find(".formErrorContent").html();

				if(prompt)
					methods._updatePrompt(field, $(prompt), promptText, undefined, false, options, noAnimation);
			});
			return this;
		},
		/**
		* Displays a prompt on a element.
		* Note that the element needs an id!
		*
		* @param {String} promptText html text to display type
		* @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
		* @param {String} possible values topLeft, topRight, bottomLeft, centerRight, bottomRight
		*/
		showPrompt: function(promptText, type, promptPosition, showArrow) {
			var form = this.closest('form, .validationEngineContainer');
			var options = form.data('jqv');
			// No option, take default one
			if(!options)
				options = methods._saveOptions(this, options);
			if(promptPosition)
				options.promptPosition=promptPosition;
			options.showArrow = showArrow==true;

			methods._showPrompt(this, promptText, type, false, options);
			return this;
		},
		/**
		* Closes form error prompts, CAN be invidual
		*/
		hide: function() {
			 var form = $(this).closest('form, .validationEngineContainer');
			 var options = form.data('jqv');
			 // No option, take default one
			 if (!options)
				options = methods._saveOptions(form, options);
			 var fadeDuration = (options && options.fadeDuration) ? options.fadeDuration : 0.3;
			 var closingtag;

			 if($(this).is("form") || $(this).hasClass("validationEngineContainer")) {
				 closingtag = "parentForm"+methods._getClassName($(this).attr("id"));
			 } else {
				 closingtag = methods._getClassName($(this).attr("id")) +"formError";
			 }
			 $('.'+closingtag).fadeTo(fadeDuration, 0.3, function() {
				 $(this).parent('.formErrorOuter').remove();
				 $(this).remove();
			 });
			 return this;
		 },
		 /**
		 * Closes all error prompts on the page
		 */
		 hideAll: function() {

			 var form = this;
			 var options = form.data('jqv');
			 var duration = options ? options.fadeDuration:300;
			 $('.formError').fadeTo(duration, 300, function() {
				 $(this).parent('.formErrorOuter').remove();
				 $(this).remove();
			 });
			 return this;
		 },
		/**
		* Typically called when user exists a field using tab or a mouse click, triggers a field
		* validation
		*/
		_onFieldEvent: function(event) {
			var field = $(this);
			var form = field.closest('form, .validationEngineContainer');
			var options = form.data('jqv');
			// No option, take default one
			if (!options)
				options = methods._saveOptions(form, options);
			options.eventTrigger = "field";
			// validate the current field
			window.setTimeout(function() {
				methods._validateField(field, options);
			}, (event.data) ? event.data.delay : 0);

		},
		/**
		* Called when the form is submited, shows prompts accordingly
		*
		* @param {jqObject}
		*            form
		* @return false if form submission needs to be cancelled
		*/
		_onSubmitEvent: function() {
			var form = $(this);
			var options = form.data('jqv');

			//check if it is trigger from skipped button
			if (form.data("jqv_submitButton")){
				var submitButton = $("#" + form.data("jqv_submitButton"));
				if (submitButton){
					if (submitButton.length > 0){
						if (submitButton.hasClass("validate-skip") || submitButton.attr("data-validation-engine-skip") == "true")
							return true;
					}
				}
			}

			options.eventTrigger = "submit";

			// validate each field
			// (- skip field ajax validation, not necessary IF we will perform an ajax form validation)
			var r=methods._validateFields(form);

			if (r && options.ajaxFormValidation) {
				methods._validateFormWithAjax(form, options);
				// cancel form auto-submission - process with async call onAjaxFormComplete
				return false;
			}

			if(options.onValidationComplete) {
				// !! ensures that an undefined return is interpreted as return false but allows a onValidationComplete() to possibly return true and have form continue processing
				return !!options.onValidationComplete(form, r);
			}
			return r;
		},
		/**
		* Return true if the ajax field validations passed so far
		* @param {Object} options
		* @return true, is all ajax validation passed so far (remember ajax is async)
		*/
		_checkAjaxStatus: function(options) {
			var status = true;
			$.each(options.ajaxValidCache, function(key, value) {
				if (!value) {
					status = false;
					// break the each
					return false;
				}
			});
			return status;
		},

		/**
		* Return true if the ajax field is validated
		* @param {String} fieldid
		* @param {Object} options
		* @return true, if validation passed, false if false or doesn't exist
		*/
		_checkAjaxFieldStatus: function(fieldid, options) {
			return options.ajaxValidCache[fieldid] == true;
		},
		/**
		* Validates form fields, shows prompts accordingly
		*
		* @param {jqObject}
		*            form
		* @param {skipAjaxFieldValidation}
		*            boolean - when set to true, ajax field validation is skipped, typically used when the submit button is clicked
		*
		* @return true if form is valid, false if not, undefined if ajax form validation is done
		*/
		_validateFields: function(form) {
			var options = form.data('jqv');

			// this variable is set to true if an error is found
			var errorFound = false;

			// Trigger hook, start validation
			form.trigger("jqv.form.validating");
			// first, evaluate status of non ajax fields
			var first_err=null;
			form.find('['+options.validateAttribute+'*=validate]').not(":disabled").each( function() {
				var field = $(this);
				var names = [];
				if ($.inArray(field.attr('name'), names) < 0) {
					errorFound |= methods._validateField(field, options);
					if (errorFound && first_err==null)
						if (field.is(":hidden") && options.prettySelect)
							first_err = field = form.find("#" + options.usePrefix + methods._jqSelector(field.attr('id')) + options.useSuffix);
						else {

							//Check if we need to adjust what element to show the prompt on
							//and and such scroll to instead
							if(field.data('jqv-prompt-at') instanceof jQuery ){
								field = field.data('jqv-prompt-at');
							} else if(field.data('jqv-prompt-at')) {
								field = $(field.data('jqv-prompt-at'));
							}
							first_err=field;
						}
					if (options.doNotShowAllErrosOnSubmit)
						return false;
					names.push(field.attr('name'));

					//if option set, stop checking validation rules after one error is found
					if(options.showOneMessage == true && errorFound){
						return false;
					}
				}
			});

			// second, check to see if all ajax calls completed ok
			// errorFound |= !methods._checkAjaxStatus(options);

			// third, check status and scroll the container accordingly
			form.trigger("jqv.form.result", [errorFound]);

			if (errorFound) {
				if (options.scroll) {
					var destination=first_err.offset().top;
					var fixleft = first_err.offset().left;

					//prompt positioning adjustment support. Usage: positionType:Xshift,Yshift (for ex.: bottomLeft:+20 or bottomLeft:-20,+10)
					var positionType=options.promptPosition;
					if (typeof(positionType)=='string' && positionType.indexOf(":")!=-1)
						positionType=positionType.substring(0,positionType.indexOf(":"));

					if (positionType!="bottomRight" && positionType!="bottomLeft") {
						var prompt_err= methods._getPrompt(first_err);
						if (prompt_err) {
							destination=prompt_err.offset().top;
						}
					}

					// Offset the amount the page scrolls by an amount in px to accomodate fixed elements at top of page
					if (options.scrollOffset) {
						destination -= options.scrollOffset;
					}

					// get the position of the first error, there should be at least one, no need to check this
					//var destination = form.find(".formError:not('.greenPopup'):first").offset().top;
					if (options.isOverflown) {
						var overflowDIV = $(options.overflownDIV);
						if(!overflowDIV.length) return false;
						var scrollContainerScroll = overflowDIV.scrollTop();
						var scrollContainerPos = -parseInt(overflowDIV.offset().top);

						destination += scrollContainerScroll + scrollContainerPos - 5;
						var scrollContainer = $(options.overflownDIV + ":not(:animated)");

						scrollContainer.animate({ scrollTop: destination }, 1100, function(){
							if(options.focusFirstField) first_err.focus();
						});

					} else {
						$("html, body").animate({
							scrollTop: destination
						}, 1100, function(){
							if(options.focusFirstField) first_err.focus();
						});
						$("html, body").animate({scrollLeft: fixleft},1100)
					}

				} else if(options.focusFirstField)
					first_err.focus();
				return false;
			}
			return true;
		},
		/**
		* This method is called to perform an ajax form validation.
		* During this process all the (field, value) pairs are sent to the server which returns a list of invalid fields or true
		*
		* @param {jqObject} form
		* @param {Map} options
		*/
		_validateFormWithAjax: function(form, options) {

			var data = form.serialize();
									var type = (options.ajaxFormValidationMethod) ? options.ajaxFormValidationMethod : "GET";
			var url = (options.ajaxFormValidationURL) ? options.ajaxFormValidationURL : form.attr("action");
									var dataType = (options.dataType) ? options.dataType : "json";
			$.ajax({
				type: type,
				url: url,
				cache: false,
				dataType: dataType,
				data: data,
				form: form,
				methods: methods,
				options: options,
				beforeSend: function() {
					return options.onBeforeAjaxFormValidation(form, options);
				},
				error: function(data, transport) {
					if (options.onFailure) {
						options.onFailure(data, transport);
					} else {
						methods._ajaxError(data, transport);
					}
				},
				success: function(json) {
					if ((dataType == "json") && (json !== true)) {
						// getting to this case doesn't necessary means that the form is invalid
						// the server may return green or closing prompt actions
						// this flag helps figuring it out
						var errorInForm=false;
						for (var i = 0; i < json.length; i++) {
							var value = json[i];

							var errorFieldId = value[0];
							var errorField = $($("#" + errorFieldId)[0]);

							// make sure we found the element
							if (errorField.length == 1) {

								// promptText or selector
								var msg = value[2];
								// if the field is valid
								if (value[1] == true) {

									if (msg == ""  || !msg){
										// if for some reason, status==true and error="", just close the prompt
										methods._closePrompt(errorField);
									} else {
										// the field is valid, but we are displaying a green prompt
										if (options.allrules[msg]) {
											var txt = options.allrules[msg].alertTextOk;
											if (txt)
												msg = txt;
										}
										if (options.showPrompts) methods._showPrompt(errorField, msg, "pass", false, options, true);
									}
								} else {
									// the field is invalid, show the red error prompt
									errorInForm|=true;
									if (options.allrules[msg]) {
										var txt = options.allrules[msg].alertText;
										if (txt)
											msg = txt;
									}
									if(options.showPrompts) methods._showPrompt(errorField, msg, "", false, options, true);
								}
							}
						}
						options.onAjaxFormComplete(!errorInForm, form, json, options);
					} else
						options.onAjaxFormComplete(true, form, json, options);

				}
			});

		},
		/**
		* Validates field, shows prompts accordingly
		*
		* @param {jqObject}
		*            field
		* @param {Array[String]}
		*            field's validation rules
		* @param {Map}
		*            user options
		* @return false if field is valid (It is inversed for *fields*, it return false on validate and true on errors.)
		*/
		_validateField: function(field, options, skipAjaxValidation) {
			if (!field.attr("id")) {
				field.attr("id", "form-validation-field-" + $.validationEngine.fieldIdCounter);
				++$.validationEngine.fieldIdCounter;
			}

           if (!options.validateNonVisibleFields && (field.is(":hidden") && !options.prettySelect || field.parent().is(":hidden")))
				return false;

			var rulesParsing = field.attr(options.validateAttribute);
			var getRules = /validate\[(.*)\]/.exec(rulesParsing);

			if (!getRules)
				return false;
			var str = getRules[1];
			var rules = str.split(/\[|,|\]/);

			// true if we ran the ajax validation, tells the logic to stop messing with prompts
			var isAjaxValidator = false;
			var fieldName = field.attr("name");
			var promptText = "";
			var promptType = "";
			var required = false;
			var limitErrors = false;
			options.isError = false;
			options.showArrow = true;

			// If the programmer wants to limit the amount of error messages per field,
			if (options.maxErrorsPerField > 0) {
				limitErrors = true;
			}

			var form = $(field.closest("form, .validationEngineContainer"));
			// Fix for adding spaces in the rules
			for (var i = 0; i < rules.length; i++) {
				rules[i] = rules[i].replace(" ", "");
				// Remove any parsing errors
				if (rules[i] === '') {
					delete rules[i];
				}
			}

			for (var i = 0, field_errors = 0; i < rules.length; i++) {

				// If we are limiting errors, and have hit the max, break
				if (limitErrors && field_errors >= options.maxErrorsPerField) {
					// If we haven't hit a required yet, check to see if there is one in the validation rules for this
					// field and that it's index is greater or equal to our current index
					if (!required) {
						var have_required = $.inArray('required', rules);
						required = (have_required != -1 &&  have_required >= i);
					}
					break;
				}


				var errorMsg = undefined;
				switch (rules[i]) {

					case "required":
						required = true;
						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._required);
						break;
					case "custom":
						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._custom);
						break;
					case "groupRequired":
						// Check is its the first of group, if not, reload validation with first field
						// AND continue normal validation on present field
						var classGroup = "["+options.validateAttribute+"*=" +rules[i + 1] +"]";
						var firstOfGroup = form.find(classGroup).eq(0);
						if(firstOfGroup[0] != field[0]){

							methods._validateField(firstOfGroup, options, skipAjaxValidation);
							options.showArrow = true;

						}
						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._groupRequired);
						if(errorMsg)  required = true;
						options.showArrow = false;
						break;
					case "ajax":
						// AJAX defaults to returning it's loading message
						errorMsg = methods._ajax(field, rules, i, options);
						if (errorMsg) {
							promptType = "load";
						}
						break;
					case "minSize":
						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._minSize);
						break;
					case "maxSize":
						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._maxSize);
						break;
					case "min":
						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._min);
						break;
					case "max":
						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._max);
						break;
					case "past":
						errorMsg = methods._getErrorMessage(form, field,rules[i], rules, i, options, methods._past);
						break;
					case "future":
						errorMsg = methods._getErrorMessage(form, field,rules[i], rules, i, options, methods._future);
						break;
					case "dateRange":
						var classGroup = "["+options.validateAttribute+"*=" + rules[i + 1] + "]";
						options.firstOfGroup = form.find(classGroup).eq(0);
						options.secondOfGroup = form.find(classGroup).eq(1);

						//if one entry out of the pair has value then proceed to run through validation
						if (options.firstOfGroup[0].value || options.secondOfGroup[0].value) {
							errorMsg = methods._getErrorMessage(form, field,rules[i], rules, i, options, methods._dateRange);
						}
						if (errorMsg) required = true;
						options.showArrow = false;
						break;

					case "dateTimeRange":
						var classGroup = "["+options.validateAttribute+"*=" + rules[i + 1] + "]";
						options.firstOfGroup = form.find(classGroup).eq(0);
						options.secondOfGroup = form.find(classGroup).eq(1);

						//if one entry out of the pair has value then proceed to run through validation
						if (options.firstOfGroup[0].value || options.secondOfGroup[0].value) {
							errorMsg = methods._getErrorMessage(form, field,rules[i], rules, i, options, methods._dateTimeRange);
						}
						if (errorMsg) required = true;
						options.showArrow = false;
						break;
					case "maxCheckbox":
						field = $(form.find("input[name='" + fieldName + "']"));
						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._maxCheckbox);
						break;
					case "minCheckbox":
						field = $(form.find("input[name='" + fieldName + "']"));
						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._minCheckbox);
						break;
					case "equals":
						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._equals);
						break;
					case "funcCall":
						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._funcCall);
						break;
					case "creditCard":
						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._creditCard);
						break;
					case "condRequired":
						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._condRequired);
						if (errorMsg !== undefined) {
							required = true;
						}
						break;
					case "funcCallRequired":
						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._funcCallRequired);
						if (errorMsg !== undefined) {
							required = true;
						}
						break;

					default:
				}

				var end_validation = false;

				// If we were passed back an message object, check what the status was to determine what to do
				if (typeof errorMsg == "object") {
					switch (errorMsg.status) {
						case "_break":
							end_validation = true;
							break;
						// If we have an error message, set errorMsg to the error message
						case "_error":
							errorMsg = errorMsg.message;
							break;
						// If we want to throw an error, but not show a prompt, return early with true
						case "_error_no_prompt":
							return true;
							break;
						// Anything else we continue on
						default:
							break;
					}
				}
				
				//funcCallRequired, first in rules, and has error, skip anything else
				if( i==0 && str.indexOf('funcCallRequired')==0 && errorMsg !== undefined ){
					promptText += errorMsg + "<br/>";
					options.isError=true;
					field_errors++;
					end_validation=true;
				}

				// If it has been specified that validation should end now, break
				if (end_validation) {
					break;
				}

				// If we have a string, that means that we have an error, so add it to the error message.
				if (typeof errorMsg == 'string') {
					promptText += errorMsg + "<br/>";
					options.isError = true;
					field_errors++;
				}
			}
			// If the rules required is not added, an empty field is not validated
			//the 3rd condition is added so that even empty password fields should be equal
			//otherwise if one is filled and another left empty, the "equal" condition would fail
			//which does not make any sense
			if(!required && !(field.val()) && field.val().length < 1 && $.inArray('equals', rules) < 0) options.isError = false;

			// Hack for radio/checkbox group button, the validation go into the
			// first radio/checkbox of the group
			var fieldType = field.prop("type");
			var positionType=field.data("promptPosition") || options.promptPosition;

			if ((fieldType == "radio" || fieldType == "checkbox") && form.find("input[name='" + fieldName + "']").size() > 1) {
				if(positionType === 'inline') {
					field = $(form.find("input[name='" + fieldName + "'][type!=hidden]:last"));
				} else {
				field = $(form.find("input[name='" + fieldName + "'][type!=hidden]:first"));
				}
				options.showArrow = options.showArrowOnRadioAndCheckbox;
			}

			if(field.is(":hidden") && options.prettySelect) {
				field = form.find("#" + options.usePrefix + methods._jqSelector(field.attr('id')) + options.useSuffix);
			}

			if (options.isError && options.showPrompts){
				methods._showPrompt(field, promptText, promptType, false, options);
			}else{
				if (!isAjaxValidator) methods._closePrompt(field);
			}

			if (!isAjaxValidator) {
				field.trigger("jqv.field.result", [field, options.isError, promptText]);
			}

			/* Record error */
			var errindex = $.inArray(field[0], options.InvalidFields);
			if (errindex == -1) {
				if (options.isError)
				options.InvalidFields.push(field[0]);
			} else if (!options.isError) {
				options.InvalidFields.splice(errindex, 1);
			}

			methods._handleStatusCssClasses(field, options);

			/* run callback function for each field */
			if (options.isError && options.onFieldFailure)
				options.onFieldFailure(field);

			if (!options.isError && options.onFieldSuccess)
				options.onFieldSuccess(field);

			return options.isError;
		},
		/**
		* Handling css classes of fields indicating result of validation
		*
		* @param {jqObject}
		*            field
		* @param {Array[String]}
		*            field's validation rules
		* @private
		*/
		_handleStatusCssClasses: function(field, options) {
			/* remove all classes */
			if(options.addSuccessCssClassToField)
				field.removeClass(options.addSuccessCssClassToField);

			if(options.addFailureCssClassToField)
				field.removeClass(options.addFailureCssClassToField);

			/* Add classes */
			if (options.addSuccessCssClassToField && !options.isError)
				field.addClass(options.addSuccessCssClassToField);

			if (options.addFailureCssClassToField && options.isError)
				field.addClass(options.addFailureCssClassToField);
		},

		 /********************
		  * _getErrorMessage
		  *
		  * @param form
		  * @param field
		  * @param rule
		  * @param rules
		  * @param i
		  * @param options
		  * @param originalValidationMethod
		  * @return {*}
		  * @private
		  */
		 _getErrorMessage:function (form, field, rule, rules, i, options, originalValidationMethod) {
			 // If we are using the custon validation type, build the index for the rule.
			 // Otherwise if we are doing a function call, make the call and return the object
			 // that is passed back.
	 		 var rule_index = jQuery.inArray(rule, rules);
			 if (rule === "custom" || rule === "funcCall" || rule === "funcCallRequired") {
				 var custom_validation_type = rules[rule_index + 1];
				 rule = rule + "[" + custom_validation_type + "]";
				 // Delete the rule from the rules array so that it doesn't try to call the
			    // same rule over again
			    delete(rules[rule_index]);
			 }
			 // Change the rule to the composite rule, if it was different from the original
			 var alteredRule = rule;


			 var element_classes = (field.attr("data-validation-engine")) ? field.attr("data-validation-engine") : field.attr("class");
			 var element_classes_array = element_classes.split(" ");

			 // Call the original validation method. If we are dealing with dates or checkboxes, also pass the form
			 var errorMsg;
			 if (rule == "future" || rule == "past"  || rule == "maxCheckbox" || rule == "minCheckbox") {
				 errorMsg = originalValidationMethod(form, field, rules, i, options);
			 } else {
				 errorMsg = originalValidationMethod(field, rules, i, options);
			 }

			 // If the original validation method returned an error and we have a custom error message,
			 // return the custom message instead. Otherwise return the original error message.
			 if (errorMsg != undefined) {
				 var custom_message = methods._getCustomErrorMessage($(field), element_classes_array, alteredRule, options);
				 if (custom_message) errorMsg = custom_message;
			 }
			 return errorMsg;

		 },
		 _getCustomErrorMessage:function (field, classes, rule, options) {
			var custom_message = false;
			var validityProp = /^custom\[.*\]$/.test(rule) ? methods._validityProp["custom"] : methods._validityProp[rule];
			 // If there is a validityProp for this rule, check to see if the field has an attribute for it
			if (validityProp != undefined) {
				custom_message = field.attr("data-errormessage-"+validityProp);
				// If there was an error message for it, return the message
				if (custom_message != undefined)
					return custom_message;
			}
			custom_message = field.attr("data-errormessage");
			 // If there is an inline custom error message, return it
			if (custom_message != undefined)
				return custom_message;
			var id = '#' + field.attr("id");
			// If we have custom messages for the element's id, get the message for the rule from the id.
			// Otherwise, if we have custom messages for the element's classes, use the first class message we find instead.
			if (typeof options.custom_error_messages[id] != "undefined" &&
				typeof options.custom_error_messages[id][rule] != "undefined" ) {
						  custom_message = options.custom_error_messages[id][rule]['message'];
			} else if (classes.length > 0) {
				for (var i = 0; i < classes.length && classes.length > 0; i++) {
					 var element_class = "." + classes[i];
					if (typeof options.custom_error_messages[element_class] != "undefined" &&
						typeof options.custom_error_messages[element_class][rule] != "undefined") {
							custom_message = options.custom_error_messages[element_class][rule]['message'];
							break;
					}
				}
			}
			if (!custom_message &&
				typeof options.custom_error_messages[rule] != "undefined" &&
				typeof options.custom_error_messages[rule]['message'] != "undefined"){
					 custom_message = options.custom_error_messages[rule]['message'];
			 }
			 return custom_message;
		 },
		 _validityProp: {
			 "required": "value-missing",
			 "custom": "custom-error",
			 "groupRequired": "value-missing",
			 "ajax": "custom-error",
			 "minSize": "range-underflow",
			 "maxSize": "range-overflow",
			 "min": "range-underflow",
			 "max": "range-overflow",
			 "past": "type-mismatch",
			 "future": "type-mismatch",
			 "dateRange": "type-mismatch",
			 "dateTimeRange": "type-mismatch",
			 "maxCheckbox": "range-overflow",
			 "minCheckbox": "range-underflow",
			 "equals": "pattern-mismatch",
			 "funcCall": "custom-error",
			 "funcCallRequired": "custom-error",
			 "creditCard": "pattern-mismatch",
			 "condRequired": "value-missing"
		 },
		/**
		* Required validation
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		*            user options
		* @param {bool} condRequired flag when method is used for internal purpose in condRequired check
		* @return an error string if validation failed
		*/
		_required: function(field, rules, i, options, condRequired) {
			switch (field.prop("type")) {
				case "radio":
				case "checkbox":
					// new validation style to only check dependent field
					if (condRequired) {
						if (!field.prop('checked')) {
							return options.allrules[rules[i]].alertTextCheckboxMultiple;
						}
						break;
					}
					// old validation style
					var form = field.closest("form, .validationEngineContainer");
					var name = field.attr("name");
					if (form.find("input[name='" + name + "']:checked").size() == 0) {
						if (form.find("input[name='" + name + "']:visible").size() == 1)
							return options.allrules[rules[i]].alertTextCheckboxe;
						else
							return options.allrules[rules[i]].alertTextCheckboxMultiple;
					}
					break;
				case "text":
				case "password":
				case "textarea":
				case "file":
				case "select-one":
				case "select-multiple":
				default:
					var field_val      = $.trim( field.val()                               );
					var dv_placeholder = $.trim( field.attr("data-validation-placeholder") );
					var placeholder    = $.trim( field.attr("placeholder")                 );
					if (
						   ( !field_val                                    )
						|| ( dv_placeholder && field_val == dv_placeholder )
						|| ( placeholder    && field_val == placeholder    )
					) {
						return options.allrules[rules[i]].alertText;
					}
					break;
			}
		},
		/**
		* Validate that 1 from the group field is required
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		*            user options
		* @return an error string if validation failed
		*/
		_groupRequired: function(field, rules, i, options) {
			var classGroup = "["+options.validateAttribute+"*=" +rules[i + 1] +"]";
			var isValid = false;
			// Check all fields from the group
			field.closest("form, .validationEngineContainer").find(classGroup).each(function(){
				if(!methods._required($(this), rules, i, options)){
					isValid = true;
					return false;
				}
			});

			if(!isValid) {
		  return options.allrules[rules[i]].alertText;
		}
		},
		/**
		* Validate rules
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		*            user options
		* @return an error string if validation failed
		*/
		_custom: function(field, rules, i, options) {
			var customRule = rules[i + 1];
			var rule = options.allrules[customRule];
			var fn;
			if(!rule) {
				alert("jqv:custom rule not found - "+customRule);
				return;
			}

			if(rule["regex"]) {
				 var ex=rule.regex;
					if(!ex) {
						alert("jqv:custom regex not found - "+customRule);
						return;
					}
					var pattern = new RegExp(ex);

					if (!pattern.test(field.val())) return options.allrules[customRule].alertText;

			} else if(rule["func"]) {
				fn = rule["func"];

				if (typeof(fn) !== "function") {
					alert("jqv:custom parameter 'function' is no function - "+customRule);
						return;
				}

				if (!fn(field, rules, i, options))
					return options.allrules[customRule].alertText;
			} else {
				alert("jqv:custom type not allowed "+customRule);
					return;
			}
		},
		/**
		* Validate custom function outside of the engine scope
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		*            user options
		* @return an error string if validation failed
		*/
		_funcCall: function(field, rules, i, options) {
			var functionName = rules[i + 1];
			var fn;
			if(functionName.indexOf('.') >-1)
			{
				var namespaces = functionName.split('.');
				var scope = window;
				while(namespaces.length)
				{
					scope = scope[namespaces.shift()];
				}
				fn = scope;
			}
			else
				fn = window[functionName] || options.customFunctions[functionName];
			if (typeof(fn) == 'function')
				return fn(field, rules, i, options);

		},
		_funcCallRequired: function(field, rules, i, options) {
			return methods._funcCall(field,rules,i,options);
		},
		/**
		* Field match
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		*            user options
		* @return an error string if validation failed
		*/
		_equals: function(field, rules, i, options) {
			var equalsField = rules[i + 1];

			if (field.val() != $("#" + equalsField).val())
				return options.allrules.equals.alertText;
		},
		/**
		* Check the maximum size (in characters)
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		*            user options
		* @return an error string if validation failed
		*/
		_maxSize: function(field, rules, i, options) {
			var max = rules[i + 1];
			var len = field.val().length;

			if (len > max) {
				var rule = options.allrules.maxSize;
				return rule.alertText + max + rule.alertText2;
			}
		},
		/**
		* Check the minimum size (in characters)
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		*            user options
		* @return an error string if validation failed
		*/
		_minSize: function(field, rules, i, options) {
			var min = rules[i + 1];
			var len = field.val().length;

			if (len < min) {
				var rule = options.allrules.minSize;
				return rule.alertText + min + rule.alertText2;
			}
		},
		/**
		* Check number minimum value
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		*            user options
		* @return an error string if validation failed
		*/
		_min: function(field, rules, i, options) {
			var min = parseFloat(rules[i + 1]);
			var len = parseFloat(field.val());

			if (len < min) {
				var rule = options.allrules.min;
				if (rule.alertText2) return rule.alertText + min + rule.alertText2;
				return rule.alertText + min;
			}
		},
		/**
		* Check number maximum value
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		*            user options
		* @return an error string if validation failed
		*/
		_max: function(field, rules, i, options) {
			var max = parseFloat(rules[i + 1]);
			var len = parseFloat(field.val());

			if (len >max ) {
				var rule = options.allrules.max;
				if (rule.alertText2) return rule.alertText + max + rule.alertText2;
				//orefalo: to review, also do the translations
				return rule.alertText + max;
			}
		},
		/**
		* Checks date is in the past
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		*            user options
		* @return an error string if validation failed
		*/
		_past: function(form, field, rules, i, options) {

			var p=rules[i + 1];
			var fieldAlt = $(form.find("*[name='" + p.replace(/^#+/, '') + "']"));
			var pdate;

			if (p.toLowerCase() == "now") {
				pdate = new Date();
			} else if (undefined != fieldAlt.val()) {
				if (fieldAlt.is(":disabled"))
					return;
				pdate = methods._parseDate(fieldAlt.val());
			} else {
				pdate = methods._parseDate(p);
			}
			var vdate = methods._parseDate(field.val());

			if (vdate > pdate ) {
				var rule = options.allrules.past;
				if (rule.alertText2) return rule.alertText + methods._dateToString(pdate) + rule.alertText2;
				return rule.alertText + methods._dateToString(pdate);
			}
		},
		/**
		* Checks date is in the future
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		*            user options
		* @return an error string if validation failed
		*/
		_future: function(form, field, rules, i, options) {

			var p=rules[i + 1];
			var fieldAlt = $(form.find("*[name='" + p.replace(/^#+/, '') + "']"));
			var pdate;

			if (p.toLowerCase() == "now") {
				pdate = new Date();
			} else if (undefined != fieldAlt.val()) {
				if (fieldAlt.is(":disabled"))
					return;
				pdate = methods._parseDate(fieldAlt.val());
			} else {
				pdate = methods._parseDate(p);
			}
			var vdate = methods._parseDate(field.val());

			if (vdate < pdate ) {
				var rule = options.allrules.future;
				if (rule.alertText2)
					return rule.alertText + methods._dateToString(pdate) + rule.alertText2;
				return rule.alertText + methods._dateToString(pdate);
			}
		},
		/**
		* Checks if valid date
		*
		* @param {string} date string
		* @return a bool based on determination of valid date
		*/
		_isDate: function (value) {
			var dateRegEx = new RegExp(/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$|^(?:(?:(?:0?[13578]|1[02])(\/|-)31)|(?:(?:0?[1,3-9]|1[0-2])(\/|-)(?:29|30)))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^(?:(?:0?[1-9]|1[0-2])(\/|-)(?:0?[1-9]|1\d|2[0-8]))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^(0?2(\/|-)29)(\/|-)(?:(?:0[48]00|[13579][26]00|[2468][048]00)|(?:\d\d)?(?:0[48]|[2468][048]|[13579][26]))$/);
			return dateRegEx.test(value);
		},
		/**
		* Checks if valid date time
		*
		* @param {string} date string
		* @return a bool based on determination of valid date time
		*/
		_isDateTime: function (value){
			var dateTimeRegEx = new RegExp(/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])\s+(1[012]|0?[1-9]){1}:(0?[1-5]|[0-6][0-9]){1}:(0?[0-6]|[0-6][0-9]){1}\s+(am|pm|AM|PM){1}$|^(?:(?:(?:0?[13578]|1[02])(\/|-)31)|(?:(?:0?[1,3-9]|1[0-2])(\/|-)(?:29|30)))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^((1[012]|0?[1-9]){1}\/(0?[1-9]|[12][0-9]|3[01]){1}\/\d{2,4}\s+(1[012]|0?[1-9]){1}:(0?[1-5]|[0-6][0-9]){1}:(0?[0-6]|[0-6][0-9]){1}\s+(am|pm|AM|PM){1})$/);
			return dateTimeRegEx.test(value);
		},
		//Checks if the start date is before the end date
		//returns true if end is later than start
		_dateCompare: function (start, end) {
			return (new Date(start.toString()) < new Date(end.toString()));
		},
		/**
		* Checks date range
		*
		* @param {jqObject} first field name
		* @param {jqObject} second field name
		* @return an error string if validation failed
		*/
		_dateRange: function (field, rules, i, options) {
			//are not both populated
			if ((!options.firstOfGroup[0].value && options.secondOfGroup[0].value) || (options.firstOfGroup[0].value && !options.secondOfGroup[0].value)) {
				return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
			}

			//are not both dates
			if (!methods._isDate(options.firstOfGroup[0].value) || !methods._isDate(options.secondOfGroup[0].value)) {
				return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
			}

			//are both dates but range is off
			if (!methods._dateCompare(options.firstOfGroup[0].value, options.secondOfGroup[0].value)) {
				return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
			}
		},
		/**
		* Checks date time range
		*
		* @param {jqObject} first field name
		* @param {jqObject} second field name
		* @return an error string if validation failed
		*/
		_dateTimeRange: function (field, rules, i, options) {
			//are not both populated
			if ((!options.firstOfGroup[0].value && options.secondOfGroup[0].value) || (options.firstOfGroup[0].value && !options.secondOfGroup[0].value)) {
				return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
			}
			//are not both dates
			if (!methods._isDateTime(options.firstOfGroup[0].value) || !methods._isDateTime(options.secondOfGroup[0].value)) {
				return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
			}
			//are both dates but range is off
			if (!methods._dateCompare(options.firstOfGroup[0].value, options.secondOfGroup[0].value)) {
				return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
			}
		},
		/**
		* Max number of checkbox selected
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		*            user options
		* @return an error string if validation failed
		*/
		_maxCheckbox: function(form, field, rules, i, options) {

			var nbCheck = rules[i + 1];
			var groupname = field.attr("name");
			var groupSize = form.find("input[name='" + groupname + "']:checked").size();
			if (groupSize > nbCheck) {
				options.showArrow = false;
				if (options.allrules.maxCheckbox.alertText2)
					 return options.allrules.maxCheckbox.alertText + " " + nbCheck + " " + options.allrules.maxCheckbox.alertText2;
				return options.allrules.maxCheckbox.alertText;
			}
		},
		/**
		* Min number of checkbox selected
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		*            user options
		* @return an error string if validation failed
		*/
		_minCheckbox: function(form, field, rules, i, options) {

			var nbCheck = rules[i + 1];
			var groupname = field.attr("name");
			var groupSize = form.find("input[name='" + groupname + "']:checked").size();
			if (groupSize < nbCheck) {
				options.showArrow = false;
				return options.allrules.minCheckbox.alertText + " " + nbCheck + " " + options.allrules.minCheckbox.alertText2;
			}
		},
		/**
		* Checks that it is a valid credit card number according to the
		* Luhn checksum algorithm.
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		*            user options
		* @return an error string if validation failed
		*/
		_creditCard: function(field, rules, i, options) {
			//spaces and dashes may be valid characters, but must be stripped to calculate the checksum.
			var valid = false, cardNumber = field.val().replace(/ +/g, '').replace(/-+/g, '');

			var numDigits = cardNumber.length;
			if (numDigits >= 14 && numDigits <= 16 && parseInt(cardNumber) > 0) {

				var sum = 0, i = numDigits - 1, pos = 1, digit, luhn = new String();
				do {
					digit = parseInt(cardNumber.charAt(i));
					luhn += (pos++ % 2 == 0) ? digit * 2 : digit;
				} while (--i >= 0)

				for (i = 0; i < luhn.length; i++) {
					sum += parseInt(luhn.charAt(i));
				}
				valid = sum % 10 == 0;
			}
			if (!valid) return options.allrules.creditCard.alertText;
		},
		/**
		* Ajax field validation
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		*            user options
		* @return nothing! the ajax validator handles the prompts itself
		*/
		 _ajax: function(field, rules, i, options) {

			 var errorSelector = rules[i + 1];
			 var rule = options.allrules[errorSelector];
			 var extraData = rule.extraData;
			 var extraDataDynamic = rule.extraDataDynamic;
			 var data = {
				"fieldId" : field.attr("id"),
				"fieldValue" : field.val()
			 };

			 if (typeof extraData === "object") {
				$.extend(data, extraData);
			 } else if (typeof extraData === "string") {
				var tempData = extraData.split("&");
				for(var i = 0; i < tempData.length; i++) {
					var values = tempData[i].split("=");
					if (values[0] && values[0]) {
						data[values[0]] = values[1];
					}
				}
			 }

			 if (extraDataDynamic) {
				 var tmpData = [];
				 var domIds = String(extraDataDynamic).split(",");
				 for (var i = 0; i < domIds.length; i++) {
					 var id = domIds[i];
					 if ($(id).length) {
						 var inputValue = field.closest("form, .validationEngineContainer").find(id).val();
						 var keyValue = id.replace('#', '') + '=' + escape(inputValue);
						 data[id.replace('#', '')] = inputValue;
					 }
				 }
			 }

			 // If a field change event triggered this we want to clear the cache for this ID
			 if (options.eventTrigger == "field") {
				delete(options.ajaxValidCache[field.attr("id")]);
			 }

			 // If there is an error or if the the field is already validated, do not re-execute AJAX
			 if (!options.isError && !methods._checkAjaxFieldStatus(field.attr("id"), options)) {
				 $.ajax({
					 type: options.ajaxFormValidationMethod,
					 url: rule.url,
					 cache: false,
					 dataType: "json",
					 data: data,
					 field: field,
					 rule: rule,
					 methods: methods,
					 options: options,
					 beforeSend: function() {},
					 error: function(data, transport) {
						if (options.onFailure) {
							options.onFailure(data, transport);
						} else {
							methods._ajaxError(data, transport);
						}
					 },
					 success: function(json) {

						 // asynchronously called on success, data is the json answer from the server
						 var errorFieldId = json[0];
						 //var errorField = $($("#" + errorFieldId)[0]);
						 var errorField = $("#"+ errorFieldId).eq(0);

						 // make sure we found the element
						 if (errorField.length == 1) {
							 var status = json[1];
							 // read the optional msg from the server
							 var msg = json[2];
							 if (!status) {
								 // Houston we got a problem - display an red prompt
								 options.ajaxValidCache[errorFieldId] = false;
								 options.isError = true;

								 // resolve the msg prompt
								 if(msg) {
									 if (options.allrules[msg]) {
										 var txt = options.allrules[msg].alertText;
										 if (txt) {
											msg = txt;
							}
									 }
								 }
								 else
									msg = rule.alertText;

								 if (options.showPrompts) methods._showPrompt(errorField, msg, "", true, options);
							 } else {
								 options.ajaxValidCache[errorFieldId] = true;

								 // resolves the msg prompt
								 if(msg) {
									 if (options.allrules[msg]) {
										 var txt = options.allrules[msg].alertTextOk;
										 if (txt) {
											msg = txt;
							}
									 }
								 }
								 else
								 msg = rule.alertTextOk;

								 if (options.showPrompts) {
									 // see if we should display a green prompt
									 if (msg)
										methods._showPrompt(errorField, msg, "pass", true, options);
									 else
										methods._closePrompt(errorField);
								}

								 // If a submit form triggered this, we want to re-submit the form
								 if (options.eventTrigger == "submit")
									field.closest("form").submit();
							 }
						 }
						 errorField.trigger("jqv.field.result", [errorField, options.isError, msg]);
					 }
				 });

				 return rule.alertTextLoad;
			 }
		 },
		/**
		* Common method to handle ajax errors
		*
		* @param {Object} data
		* @param {Object} transport
		*/
		_ajaxError: function(data, transport) {
			if(data.status == 0 && transport == null)
				alert("The page is not served from a server! ajax call failed");
			else if(typeof console != "undefined")
				console.log("Ajax error: " + data.status + " " + transport);
		},
		/**
		* date -> string
		*
		* @param {Object} date
		*/
		_dateToString: function(date) {
			return date.getFullYear()+"-"+(date.getMonth()+1)+"-"+date.getDate();
		},
		/**
		* Parses an ISO date
		* @param {String} d
		*/
		_parseDate: function(d) {

			var dateParts = d.split("-");
			if(dateParts==d)
				dateParts = d.split("/");
			if(dateParts==d) {
				dateParts = d.split(".");
				return new Date(dateParts[2], (dateParts[1] - 1), dateParts[0]);
			}
			return new Date(dateParts[0], (dateParts[1] - 1) ,dateParts[2]);
		},
		/**
		* Builds or updates a prompt with the given information
		*
		* @param {jqObject} field
		* @param {String} promptText html text to display type
		* @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
		* @param {boolean} ajaxed - use to mark fields than being validated with ajax
		* @param {Map} options user options
		*/
		 _showPrompt: function(field, promptText, type, ajaxed, options, ajaxform) {
		 	//Check if we need to adjust what element to show the prompt on
			if(field.data('jqv-prompt-at') instanceof jQuery ){
				field = field.data('jqv-prompt-at');
			} else if(field.data('jqv-prompt-at')) {
				field = $(field.data('jqv-prompt-at'));
			}

			 var prompt = methods._getPrompt(field);
			 // The ajax submit errors are not see has an error in the form,
			 // When the form errors are returned, the engine see 2 bubbles, but those are ebing closed by the engine at the same time
			 // Because no error was found befor submitting
			 if(ajaxform) prompt = false;
			 // Check that there is indded text
			 if($.trim(promptText)){
				 if (prompt)
					methods._updatePrompt(field, prompt, promptText, type, ajaxed, options);
				 else
					methods._buildPrompt(field, promptText, type, ajaxed, options);
			}
		 },
		/**
		* Builds and shades a prompt for the given field.
		*
		* @param {jqObject} field
		* @param {String} promptText html text to display type
		* @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
		* @param {boolean} ajaxed - use to mark fields than being validated with ajax
		* @param {Map} options user options
		*/
		_buildPrompt: function(field, promptText, type, ajaxed, options) {

			// create the prompt
			var prompt = $('<div>');
			prompt.addClass(methods._getClassName(field.attr("id")) + "formError");
			// add a class name to identify the parent form of the prompt
			prompt.addClass("parentForm"+methods._getClassName(field.closest('form, .validationEngineContainer').attr("id")));
			prompt.addClass("formError");

			switch (type) {
				case "pass":
					prompt.addClass("greenPopup");
					break;
				case "load":
					prompt.addClass("blackPopup");
					break;
				default:
					/* it has error  */
					//alert("unknown popup type:"+type);
			}
			if (ajaxed)
				prompt.addClass("ajaxed");

			// create the prompt content
			var promptContent = $('<div>').addClass("formErrorContent").html(promptText).appendTo(prompt);

			// determine position type
			var positionType=field.data("promptPosition") || options.promptPosition;

			// create the css arrow pointing at the field
			// note that there is no triangle on max-checkbox and radio
			if (options.showArrow) {
				var arrow = $('<div>').addClass("formErrorArrow");

				//prompt positioning adjustment support. Usage: positionType:Xshift,Yshift (for ex.: bottomLeft:+20 or bottomLeft:-20,+10)
				if (typeof(positionType)=='string')
				{
					var pos=positionType.indexOf(":");
					if(pos!=-1)
						positionType=positionType.substring(0,pos);
				}

				switch (positionType) {
					case "bottomLeft":
					case "bottomRight":
						prompt.find(".formErrorContent").before(arrow);
						arrow.addClass("formErrorArrowBottom").html('<div class="line1"><!-- --></div><div class="line2"><!-- --></div><div class="line3"><!-- --></div><div class="line4"><!-- --></div><div class="line5"><!-- --></div><div class="line6"><!-- --></div><div class="line7"><!-- --></div><div class="line8"><!-- --></div><div class="line9"><!-- --></div><div class="line10"><!-- --></div>');
						break;
					case "topLeft":
					case "topRight":
						arrow.html('<div class="line10"><!-- --></div><div class="line9"><!-- --></div><div class="line8"><!-- --></div><div class="line7"><!-- --></div><div class="line6"><!-- --></div><div class="line5"><!-- --></div><div class="line4"><!-- --></div><div class="line3"><!-- --></div><div class="line2"><!-- --></div><div class="line1"><!-- --></div>');
						prompt.append(arrow);
						break;
				}
			}
			// Add custom prompt class
			if (options.addPromptClass)
				prompt.addClass(options.addPromptClass);

            // Add custom prompt class defined in element
            var requiredOverride = field.attr('data-required-class');
            if(requiredOverride !== undefined) {
                prompt.addClass(requiredOverride);
            } else {
                if(options.prettySelect) {
                    if($('#' + field.attr('id')).next().is('select')) {
                        var prettyOverrideClass = $('#' + field.attr('id').substr(options.usePrefix.length).substring(options.useSuffix.length)).attr('data-required-class');
                        if(prettyOverrideClass !== undefined) {
                            prompt.addClass(prettyOverrideClass);
                        }
                    }
                }
            }

			prompt.css({
				"opacity": 0
			});
			if(positionType === 'inline') {
				prompt.addClass("inline");
				if(typeof field.attr('data-prompt-target') !== 'undefined' && $('#'+field.attr('data-prompt-target')).length > 0) {
					prompt.appendTo($('#'+field.attr('data-prompt-target')));
				} else {
					field.after(prompt);
				}
			} else {
				field.before(prompt);
			}

			var pos = methods._calculatePosition(field, prompt, options);
			prompt.css({
				'position': positionType === 'inline' ? 'relative' : 'absolute',
				"top": pos.callerTopPosition,
				"left": pos.callerleftPosition,
				"marginTop": pos.marginTopSize,
				"opacity": 0
			}).data("callerField", field);


			if (options.autoHidePrompt) {
				setTimeout(function(){
					prompt.animate({
						"opacity": 0
					},function(){
						prompt.closest('.formErrorOuter').remove();
						prompt.remove();
					});
				}, options.autoHideDelay);
			}
			return prompt.animate({
				"opacity": 0.87
			});
		},
		/**
		* Updates the prompt text field - the field for which the prompt
		* @param {jqObject} field
		* @param {String} promptText html text to display type
		* @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
		* @param {boolean} ajaxed - use to mark fields than being validated with ajax
		* @param {Map} options user options
		*/
		_updatePrompt: function(field, prompt, promptText, type, ajaxed, options, noAnimation) {

			if (prompt) {
				if (typeof type !== "undefined") {
					if (type == "pass")
						prompt.addClass("greenPopup");
					else
						prompt.removeClass("greenPopup");

					if (type == "load")
						prompt.addClass("blackPopup");
					else
						prompt.removeClass("blackPopup");
				}
				if (ajaxed)
					prompt.addClass("ajaxed");
				else
					prompt.removeClass("ajaxed");

				prompt.find(".formErrorContent").html(promptText);

				var pos = methods._calculatePosition(field, prompt, options);
				var css = {"top": pos.callerTopPosition,
				"left": pos.callerleftPosition,
				"marginTop": pos.marginTopSize};

				if (noAnimation)
					prompt.css(css);
				else
					prompt.animate(css);
			}
		},
		/**
		* Closes the prompt associated with the given field
		*
		* @param {jqObject}
		*            field
		*/
		 _closePrompt: function(field) {
			 var prompt = methods._getPrompt(field);
			 if (prompt)
				 prompt.fadeTo("fast", 0, function() {
					 prompt.parent('.formErrorOuter').remove();
					 prompt.remove();
				 });
		 },
		 closePrompt: function(field) {
			 return methods._closePrompt(field);
		 },
		/**
		* Returns the error prompt matching the field if any
		*
		* @param {jqObject}
		*            field
		* @return undefined or the error prompt (jqObject)
		*/
		_getPrompt: function(field) {
				var formId = $(field).closest('form, .validationEngineContainer').attr('id');
			var className = methods._getClassName(field.attr("id")) + "formError";
				var match = $("." + methods._escapeExpression(className) + '.parentForm' + methods._getClassName(formId))[0];
			if (match)
			return $(match);
		},
		/**
		  * Returns the escapade classname
		  *
		  * @param {selector}
		  *            className
		  */
		  _escapeExpression: function (selector) {
			  return selector.replace(/([#;&,\.\+\*\~':"\!\^$\[\]\(\)=>\|])/g, "\\$1");
		  },
		/**
		 * returns true if we are in a RTLed document
		 *
		 * @param {jqObject} field
		 */
		isRTL: function(field)
		{
			var $document = $(document);
			var $body = $('body');
			var rtl =
				(field && field.hasClass('rtl')) ||
				(field && (field.attr('dir') || '').toLowerCase()==='rtl') ||
				$document.hasClass('rtl') ||
				($document.attr('dir') || '').toLowerCase()==='rtl' ||
				$body.hasClass('rtl') ||
				($body.attr('dir') || '').toLowerCase()==='rtl';
			return Boolean(rtl);
		},
		/**
		* Calculates prompt position
		*
		* @param {jqObject}
		*            field
		* @param {jqObject}
		*            the prompt
		* @param {Map}
		*            options
		* @return positions
		*/
		_calculatePosition: function (field, promptElmt, options) {

			var promptTopPosition, promptleftPosition, marginTopSize;
			var fieldWidth 	= field.width();
			var fieldLeft 	= field.position().left;
			var fieldTop 	=  field.position().top;
			var fieldHeight 	=  field.height();
			var promptHeight = promptElmt.height();


			// is the form contained in an overflown container?
			promptTopPosition = promptleftPosition = 0;
			// compensation for the arrow
			marginTopSize = -promptHeight;


			//prompt positioning adjustment support
			//now you can adjust prompt position
			//usage: positionType:Xshift,Yshift
			//for example:
			//   bottomLeft:+20 means bottomLeft position shifted by 20 pixels right horizontally
			//   topRight:20, -15 means topRight position shifted by 20 pixels to right and 15 pixels to top
			//You can use +pixels, - pixels. If no sign is provided than + is default.
			var positionType=field.data("promptPosition") || options.promptPosition;
			var shift1="";
			var shift2="";
			var shiftX=0;
			var shiftY=0;
			if (typeof(positionType)=='string') {
				//do we have any position adjustments ?
				if (positionType.indexOf(":")!=-1) {
					shift1=positionType.substring(positionType.indexOf(":")+1);
					positionType=positionType.substring(0,positionType.indexOf(":"));

					//if any advanced positioning will be needed (percents or something else) - parser should be added here
					//for now we use simple parseInt()

					//do we have second parameter?
					if (shift1.indexOf(",") !=-1) {
						shift2=shift1.substring(shift1.indexOf(",") +1);
						shift1=shift1.substring(0,shift1.indexOf(","));
						shiftY=parseInt(shift2);
						if (isNaN(shiftY)) shiftY=0;
					};

					shiftX=parseInt(shift1);
					if (isNaN(shift1)) shift1=0;

				};
			};


			switch (positionType) {
				default:
				case "topRight":
					promptleftPosition +=  fieldLeft + fieldWidth - 27;
					promptTopPosition +=  fieldTop;
					break;

				case "topLeft":
					promptTopPosition +=  fieldTop;
					promptleftPosition += fieldLeft;
					break;

				case "centerRight":
					promptTopPosition = fieldTop+4;
					marginTopSize = 0;
					promptleftPosition= fieldLeft + field.outerWidth(true)+5;
					break;
				case "centerLeft":
					promptleftPosition = fieldLeft - (promptElmt.width() + 2);
					promptTopPosition = fieldTop+4;
					marginTopSize = 0;

					break;

				case "bottomLeft":
					promptTopPosition = fieldTop + field.height() + 5;
					marginTopSize = 0;
					promptleftPosition = fieldLeft;
					break;
				case "bottomRight":
					promptleftPosition = fieldLeft + fieldWidth - 27;
					promptTopPosition =  fieldTop +  field.height() + 5;
					marginTopSize = 0;
					break;
				case "inline":
					promptleftPosition = 0;
					promptTopPosition = 0;
					marginTopSize = 0;
			};



			//apply adjusments if any
			promptleftPosition += shiftX;
			promptTopPosition  += shiftY;

			return {
				"callerTopPosition": promptTopPosition + "px",
				"callerleftPosition": promptleftPosition + "px",
				"marginTopSize": marginTopSize + "px"
			};
		},
		/**
		* Saves the user options and variables in the form.data
		*
		* @param {jqObject}
		*            form - the form where the user option should be saved
		* @param {Map}
		*            options - the user options
		* @return the user options (extended from the defaults)
		*/
		 _saveOptions: function(form, options) {

			 // is there a language localisation ?
			 if ($.validationEngineLanguage)
			 var allRules = $.validationEngineLanguage.allRules;
			 else
			 $.error("jQuery.validationEngine rules are not loaded, plz add localization files to the page");
			 // --- Internals DO NOT TOUCH or OVERLOAD ---
			 // validation rules and i18
			 $.validationEngine.defaults.allrules = allRules;

			 var userOptions = $.extend(true,{},$.validationEngine.defaults,options);

			 form.data('jqv', userOptions);
			 return userOptions;
		 },

		 /**
		 * Removes forbidden characters from class name
		 * @param {String} className
		 */
		 _getClassName: function(className) {
			 if(className)
				 return className.replace(/:/g, "_").replace(/\./g, "_");
					  },
		/**
		 * Escape special character for jQuery selector
		 * http://totaldev.com/content/escaping-characters-get-valid-jquery-id
		 * @param {String} selector
		 */
		 _jqSelector: function(str){
			return str.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1');
		},
		/**
		* Conditionally required field
		*
		* @param {jqObject} field
		* @param {Array[String]} rules
		* @param {int} i rules index
		* @param {Map}
		* user options
		* @return an error string if validation failed
		*/
		_condRequired: function(field, rules, i, options) {
			var idx, dependingField;

			for(idx = (i + 1); idx < rules.length; idx++) {
				dependingField = jQuery("#" + rules[idx]).first();

				/* Use _required for determining wether dependingField has a value.
				 * There is logic there for handling all field types, and default value; so we won't replicate that here
				 * Indicate this special use by setting the last parameter to true so we only validate the dependingField on chackboxes and radio buttons (#462)
				 */
				if (dependingField.length && methods._required(dependingField, ["required"], 0, options, true) == undefined) {
					/* We now know any of the depending fields has a value,
					 * so we can validate this field as per normal required code
					 */
					return methods._required(field, ["required"], 0, options);
				}
			}
		},

	    _submitButtonClick: function(event) {
	        var button = $(this);
	        var form = button.closest('form, .validationEngineContainer');
	        form.data("jqv_submitButton", button.attr("id"));
	    }
		  };

	 /**
	 * Plugin entry point.
	 * You may pass an action as a parameter or a list of options.
	 * if none, the init and attach methods are being called.
	 * Remember: if you pass options, the attached method is NOT called automatically
	 *
	 * @param {String}
	 *            method (optional) action
	 */
	 $.fn.validationEngine = function(method) {

		 var form = $(this);
		 if(!form[0]) return form;  // stop here if the form does not exist

		 if (typeof(method) == 'string' && method.charAt(0) != '_' && methods[method]) {

			 // make sure init is called once
			 if(method != "showPrompt" && method != "hide" && method != "hideAll")
			 methods.init.apply(form);

			 return methods[method].apply(form, Array.prototype.slice.call(arguments, 1));
		 } else if (typeof method == 'object' || !method) {

			 // default constructor with or without arguments
			 methods.init.apply(form, arguments);
			 return methods.attach.apply(form);
		 } else {
			 $.error('Method ' + method + ' does not exist in jQuery.validationEngine');
		 }
	};



	// LEAK GLOBAL OPTIONS
	$.validationEngine= {fieldIdCounter: 0,defaults:{

		// Name of the event triggering field validation
		validationEventTrigger: "blur",
		// Automatically scroll viewport to the first error
		scroll: true,
		// Focus on the first input
		focusFirstField:true,
		// Show prompts, set to false to disable prompts
		showPrompts: true,
       // Should we attempt to validate non-visible input fields contained in the form? (Useful in cases of tabbed containers, e.g. jQuery-UI tabs)
       validateNonVisibleFields: false,
		// Opening box position, possible locations are: topLeft,
		// topRight, bottomLeft, centerRight, bottomRight, inline
		// inline gets inserted after the validated field or into an element specified in data-prompt-target
		promptPosition: "topRight",
		bindMethod:"bind",
		// internal, automatically set to true when it parse a _ajax rule
		inlineAjax: false,
		// if set to true, the form data is sent asynchronously via ajax to the form.action url (get)
		ajaxFormValidation: false,
		// The url to send the submit ajax validation (default to action)
		ajaxFormValidationURL: false,
		// HTTP method used for ajax validation
		ajaxFormValidationMethod: 'get',
		// Ajax form validation callback method: boolean onComplete(form, status, errors, options)
		// retuns false if the form.submit event needs to be canceled.
		onAjaxFormComplete: $.noop,
		// called right before the ajax call, may return false to cancel
		onBeforeAjaxFormValidation: $.noop,
		// Stops form from submitting and execute function assiciated with it
		onValidationComplete: false,

		// Used when you have a form fields too close and the errors messages are on top of other disturbing viewing messages
		doNotShowAllErrosOnSubmit: false,
		// Object where you store custom messages to override the default error messages
		custom_error_messages:{},
		// true if you want to validate the input fields on blur event
		binded: true,
		// set to true, when the prompt arrow needs to be displayed
		showArrow: true,
		// set to false, determines if the prompt arrow should be displayed when validating
		// checkboxes and radio buttons
		showArrowOnRadioAndCheckbox: false,
		// did one of the validation fail ? kept global to stop further ajax validations
		isError: false,
		// Limit how many displayed errors a field can have
		maxErrorsPerField: false,

		// Caches field validation status, typically only bad status are created.
		// the array is used during ajax form validation to detect issues early and prevent an expensive submit
		ajaxValidCache: {},
		// Auto update prompt position after window resize
		autoPositionUpdate: false,

		InvalidFields: [],
		onFieldSuccess: false,
		onFieldFailure: false,
		onSuccess: false,
		onFailure: false,
		validateAttribute: "class",
		addSuccessCssClassToField: "",
		addFailureCssClassToField: "",

		// Auto-hide prompt
		autoHidePrompt: false,
		// Delay before auto-hide
		autoHideDelay: 10000,
		// Fade out duration while hiding the validations
		fadeDuration: 0.3,
	 // Use Prettify select library
	 prettySelect: false,
	 // Add css class on prompt
	 addPromptClass : "",
	 // Custom ID uses prefix
	 usePrefix: "",
	 // Custom ID uses suffix
	 useSuffix: "",
	 // Only show one message per error prompt
	 showOneMessage: false
	}};
	$(function(){$.validationEngine.defaults.promptPosition = methods.isRTL()?'topLeft':"topRight"});
})(jQuery);