PageSourceSearch

https://www.mdsleiloes.com/web/media/com_rsform/js/script.js?d3c3d3abde1045d69002bbf5e043a951

js mdsleiloes.com collected 2026-09-27 04:12:08 UTC 79,470 bytes, 2,732 lines download raw bytes

1var RSFormProCalendars = {};
2var RSFormProPrices = {};
3var ajaxExtraValidationScript = {};
4var RSClickedSubmitElement = false;
5
6if (typeof RSFormPro != 'object') {
7	var RSFormPro = {};
8}
9
10RSFormPro.Forms = {};
11RSFormPro.Editors = {};
12RSFormPro.scrollToError = false;
13RSFormPro.usePositioning = false;
14
15/* Handle HTML5 form fields validation for the forms without AjaxValidation enabled */
16RSFormPro.setHTML5Validation = function (formId, isDisabledSubmit, errorClasses, totalPages) {
17	var parentErrorClass = errorClasses.parent;
18	var fieldErrorClass = errorClasses.field;
19	var submitElement = RSFormPro.getElementByType(formId, 'submit');
20	var i, j;
21	for (i = 0; i < submitElement.length; i++) {
22		if (RSFormProUtils.hasClass(submitElement[i],'rsform-submit-button')) {
23			RSFormProUtils.addEvent(submitElement[i], 'click', (function (event) {
24				var errorElements = RSFormPro.HTML5.validation(formId);
25				if (errorElements.length) {
26					var errorPagesFound = [];
27					for (j = 0; j < errorElements.length; j++) {
28						RSFormProUtils.addClass(errorElements[j], 'rsform-error');
29
30						if (document.getElementById('component' + errorElements[j].componentId)) {
31							document.getElementById('component' + errorElements[j].componentId).className = 'formError';
32						}
33						if (parentErrorClass) {
34							try {
35								var block = RSFormPro.getBlock(formId, RSFormProUtils.getAlias(errorElements[j].field.getAttribute('id')));
36
37								RSFormProUtils.addClass(block[0], parentErrorClass);
38							} catch (err) {}
39						}
40
41						if (totalPages > 0) {
42							errorPagesFound.push(errorElements[j].page);
43						}
44					}
45
46					if (totalPages > 0 && errorPagesFound.length) {
47						var firstErrorPage = Math.min.apply(null, errorPagesFound);
48						RSFormPro.Pages.change(formId, firstErrorPage, totalPages, false, errorClasses)
49					}
50
51					if (RSFormPro.scrollToError){
52						RSFormPro.gotoErrorElement(formId);
53					}
54
55					if (isDisabledSubmit) {
56						for (j = 0; j < submitElement.length; j++) {
57							submitElement[j].disabled = false;
58						}
59					}
60
61					event.preventDefault();
62				} else {
63					if (isDisabledSubmit) {
64						RSFormPro.submitForm(this.form);
65					}
66				}
67			}));
68		}
69	}
70};
71
72RSFormPro.formEvents = {};
73
74RSFormPro.addFormEvent = function(formId, func) {
75	if (typeof RSFormPro.formEvents[formId] !== 'object') {
76		RSFormPro.formEvents[formId] = [];
77	}
78
79	RSFormPro.formEvents[formId].push(func);
80};
81
82RSFormPro.submitForm = function(form) {
83	var formId = form.elements['form[formId]'].value;
84	var func;
85
86	if (typeof RSFormPro.formEvents[formId] === 'object' && RSFormPro.formEvents[formId].length > 0) {
87		func = RSFormPro.formEvents[formId].shift()
88		if (typeof func === 'function') {
89			func();
90
91			return false;
92		}
93	}
94
95	// if the submit button or any other element has the id submit the form.submit() function is overwritten
96	if (typeof form.submit === 'function') {
97		form.submit();
98	} else {
99		document.createElement('form').submit.call(form)
100	}
101};
102
103/* Disable the submit button when form is submitted functions */
104RSFormPro.setDisabledSubmit = function(formId, ajaxValidation){
105	if (!ajaxValidation) {
106		var i, j;
107		var submitElement = RSFormPro.getElementByType(formId, 'submit');
108		for (i = 0; i < submitElement.length; i++) {
109			if (RSFormProUtils.hasClass(submitElement[i],'rsform-submit-button')) {
110				RSFormProUtils.addEvent(submitElement[i],'click', (function(event) {
111					event.preventDefault();
112					for (j = 0; j < submitElement.length; j++) {
113						submitElement[j].disabled = true;
114					}
115				}));
116			}
117		}
118	}
119};
120/* Thank You Message in Popup Window functions */
121
122RSFormPro.showThankYouPopup = function (thankYouContainer){
123	var content = thankYouContainer.innerHTML;
124	var gotoUrl = thankYouContainer.querySelector('#rsfp-thankyou-popup-return-link').value;
125
126	// remove the html part from the layout
127	thankYouContainer.parentNode.removeChild(thankYouContainer);
128
129	RSFormProUtils.addClass(document.body, 'rsfp_popup_activated');
130
131	var outer = document.createElement('div');
132	outer.setAttribute('class', 'rsfp_thankyou_popup_outer');
133	outer.onclick = function() {
134		if (event && event.target && (RSFormProUtils.hasClass(event.target, 'rsfp_thankyou_popup_outer') || RSFormProUtils.hasClass(event.target, 'rsfp_thankou_popup_close_btn'))) {
135            destroyPopup();
136            redirectUrl();
137		}
138	};
139
140	var inner = document.createElement('div');
141	inner.setAttribute('class', 'rsfp_thankyou_popup_inner');
142	inner.setAttribute('id', 'rsfp_thankyou_popup_inner');
143	inner.innerHTML = content;
144
145	var close = document.createElement('div');
146	close.setAttribute('class', 'rsfp_thankou_popup_close_btn');
147	close.innerHTML = '&times;';
148
149	outer.appendChild(inner);
150	inner.appendChild(close);
151
152	document.body.appendChild(outer);
153
154	document.getElementById('rsfp_thankyou_popup_inner').style.marginTop = (window.innerHeight - document.getElementById('rsfp_thankyou_popup_inner').offsetHeight) / 2 + 'px';
155
156	var continueButton = outer.querySelector('[name=continue]');
157	if (continueButton) {
158		continueButton.removeAttribute('onclick');
159		continueButton.onclick = function() {
160			destroyPopup();
161			redirectUrl();
162		}
163	}
164
165	var redirectUrl = function() {
166        if (gotoUrl.length > 0) {
167            document.location = gotoUrl;
168        } else {
169            document.location.reload(true);
170        }
171	};
172
173	var destroyPopup = function() {
174        RSFormProUtils.removeClass(document.body, 'rsfp_popup_activated');
175
176        document.body.removeChild(outer);
177	};
178};
179
180/* Scroll to first error element */
181RSFormPro.gotoErrorElement = function(formId){
182	var form = RSFormPro.getForm(formId);
183	var errorElements = form.getElementsByClassName('formError');
184	if (errorElements.length) {
185		var block = RSFormPro.findAncestor(errorElements[0], 'rsform-block');
186		if (block) {
187			RSFormPro.scrollToElement(block);
188		} else {
189			RSFormPro.scrollToElement(errorElements[0]);
190		}
191	}
192};
193
194RSFormPro.findAncestor = function(el, cls){
195	while(el = el.parentElement) {
196		var elementClasses = el.className;
197		elementClasses = elementClasses.split(' ');
198		if (elementClasses.indexOf(cls) > -1) {
199			return el;
200		}
201	}
202
203	return false;
204};
205
206/* Reset all values, used with reset button for the submit */
207RSFormPro.resetElements = function(formId) {
208	var form 	= RSFormPro.getForm(formId);
209
210	if (form && form.elements.length) {
211		RSFormPro.resetValues(form.elements);
212	}
213};
214
215/* ScrollTo functions */
216RSFormPro.scrollToElement = function(element){
217	var to = element.offsetTop;
218	var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
219	var documentView = window.innerHeight + scrollTop;
220
221	// this is more specific for the modern browsers
222	if (typeof element.getBoundingClientRect === 'function') {
223		to = element.getBoundingClientRect().top + scrollTop;
224	}
225
226	if (to < scrollTop || to > documentView) {
227		RSFormPro.scrollTo(to, 300);
228	}
229};
230
231RSFormPro.scrollTo = function(to, duration) {
232	if (duration <= 0) return;
233	var elementScrollTop = window.pageYOffset ?  window.pageYOffset : document.documentElement.scrollTop;
234	var difference = to - elementScrollTop;
235	var perTick = difference / duration * 10;
236	
237	window.setTimeout(function() {
238		var limitControl;
239		limitControl = window.pageYOffset ?  window.pageYOffset : document.documentElement.scrollTop;
240		limitControl = limitControl + perTick;
241		window.scrollTo(0, limitControl);
242		// if the element has been reached or the scroll is at the bottom of the page no need to continue
243		if (limitControl == to) return;
244
245		RSFormPro.scrollTo(to, duration - 10);
246	}, 10);
247};
248
249/* Field specific functions */
250
251RSFormPro.refreshCaptcha = function(componentId, captchaPath) {
252	if (!captchaPath) {
253		captchaPath = 'index.php?option=com_rsform&task=captcha&format=image&componentId=' + componentId;
254	}
255	document.getElementById('captcha' + componentId).src = captchaPath + '&' + Math.random();
256	document.getElementById('captchaTxt' + componentId).value = '';
257	document.getElementById('captchaTxt' + componentId).focus();
258};
259
260RSFormPro.geoLocationTimeouts = {};
261
262RSFormPro.initGeoLocation = function(term, id, mapid, map, marker, geocoder, type) {
263	var content = document.getElementById('rsform_geolocation'+id);
264	var address	= document.getElementById(mapid).clientWidth;
265
266	document.getElementById('rsform_geolocation'+id).style.width = address+'px';
267	document.getElementById('rsform_geolocation'+id).style.display = 'none';
268	document.getElementById('rsform_geolocation'+id).innerHTML = '';
269
270	if (typeof RSFormPro.geoLocationTimeouts[id] !== 'undefined')
271	{
272		window.clearTimeout(RSFormPro.geoLocationTimeouts[id]);
273	}
274
275	if (term != '') {
276		RSFormPro.geoLocationTimeouts[id] = window.setTimeout(function(){
277			geocoder.geocode( {'address': term }, function(results, status) {
278				if (status == 'OK') {
279					for (var i=0; i<results.length; i++) {
280						var item	= results[i];
281						var theli	= document.createElement('li');
282						var thea	= document.createElement('a');
283
284						thea.setAttribute('href','javascript:void(0)');
285						thea.innerHTML = item.formatted_address;
286
287						RSFormProUtils.addEvent(thea,'click', (function() {
288							var mapValue = type ? item.formatted_address : item.geometry.location.lat().toFixed(5) + ',' + item.geometry.location.lng().toFixed(5);
289							var mapId	 = mapid;
290							var location = new google.maps.LatLng(item.geometry.location.lat().toFixed(5), item.geometry.location.lng().toFixed(5));
291
292							return function() {
293								document.getElementById(mapId).value = mapValue;
294								marker.setPosition(location);
295								map.setCenter(location);
296								document.getElementById('rsform_geolocation'+id).style.display = 'none';
297							}
298						})());
299
300						theli.appendChild(thea);
301						content.appendChild(theli);
302					}
303
304					document.getElementById('rsform_geolocation'+id).style.display = '';
305				}
306			});
307		}, 500);
308	}
309};
310
311RSFormPro.googleMap
311Ids = [];
312
313RSFormPro.requestLocation = function() {
314	if (navigator && navigator.geolocation && navigator.geolocation.getCurrentPosition) {
315		navigator.geolocation.getCurrentPosition(function(position){
316			var id, map, marker;
317
318			for (var i = 0; i < RSFormPro.googleMapIds.length; i++)
319			{
320				id = RSFormPro.googleMapIds[i];
321				map = window['rsformmap' + id];
322				marker = window['rsformmarker' + id];
323
324				map.setCenter({lat: position.coords.latitude, lng: position.coords.longitude});
325				marker.setPosition({lat: position.coords.latitude, lng: position.coords.longitude});
326				google.maps.event.trigger(marker, 'drag');
327			}
328		});
329	}
330};
331
332RSFormPro.disableInvalidDates = function(fieldName) {
333	var theDate = new Date(),
334		day,
335		index;
336
337	for (day = 1; day <= 31; day++) {
338		var year 	= parseInt(document.getElementById(fieldName + 'y').value);
339		var month 	= parseInt(document.getElementById(fieldName + 'm').value) - 1;
340
341		index = day - 1;
342		if (document.getElementById(fieldName + 'd').options[0].value == '') {
343			index++;
344		}
345		document.getElementById(fieldName + 'd').options[index].disabled = false;
346		if (!isNaN(year) && !isNaN(month)) {
347			if (typeof theDate.__msh_oldSetFullYear == 'function') {
348				theDate.__msh_oldSetFullYear(year, month, day);
349			} else {
350				theDate.setFullYear(year, month, day);
351			}
352
353			if (theDate.getDate() != day || theDate.getMonth() != month) {
354				document.getElementById(fieldName + 'd').options[index].disabled = true;
355			}
356		}
357	}
358	if (document.getElementById(fieldName + 'd').options[document.getElementById(fieldName + 'd').selectedIndex].disabled == true) {
359		for (day = 31; day >= 28; day--) {
360			index = day - 1;
361			if (document.getElementById(fieldName + 'd').options[0].value == '') {
362				index++;
363			}
364			if (document.getElementById(fieldName + 'd').options[index].disabled == false) {
365				document.getElementById(fieldName + 'd').value = day;
366				break;
367			}
368		}
369	}
370};
371
372RSFormPro.addMoreFiles = function(button) {
373	var clone = button.previousSibling.cloneNode(true);
374
375	var inputs = clone.getElementsByTagName('input');
376	if (inputs.length)
377	{
378		for (var i = 0; i < inputs.length; i++)
379		{
380			if (inputs[i].type && inputs[i].type.toUpperCase() === 'FILE')
381			{
382				var fieldName = inputs[i].getAttribute('id');
383				inputs[i].value = '';
384			}
385		}
386	}
387
388	var images = clone.getElementsByTagName('img');
389	if (images.length)
390	{
391		for (var j = 0; j < images.length; j++)
392		{
393			if (RSFormProUtils.hasClass(images[j], 'rsfp-image-polaroid'))
394			{
395				images[j].parentNode.parentNode.removeChild(images[j].parentNode);
396			}
397		}
398	}
399
400	button.parentNode.appendChild(clone);
401
402	var maxFiles = parseInt(button.getAttribute('data-rsfp-maxfiles'));
403	if (maxFiles > 0)
404	{
405		if (RSFormPro.getFieldsByName(button.getAttribute('data-rsfp-formid'), fieldName).length / 2 >= maxFiles)
406		{
407			button.disabled = true;
408		}
409	}
410};
411
412RSFormPro.openImageModal = function(element) {
413	var modal = document.createElement('div');
414	modal.setAttribute('class', 'rsfp-modal');
415
416	var close = document.createElement('span');
417	close.innerHTML = '&times;';
418	close.setAttribute('class', 'rsfp-modal-close-button');
419	modal.onclick = close.onclick = function() {
420		modal.parentNode.removeChild(modal);
421	};
422
423	var img = document.createElement('img');
424	img.setAttribute('class', 'rsfp-modal-image');
425	img.setAttribute('src', element.getAttribute('src'));
426
427	var caption = document.createElement('div');
428	caption.setAttribute('class', 'rsfp-modal-caption');
429	caption.innerHTML = element.getAttribute('alt');
430
431	modal.appendChild(close);
432	modal.appendChild(img);
433	modal.appendChild(caption);
434
435	document.getElementsByTagName('body')[0].appendChild(modal);
436
437	modal.style.display = 'block';
438}
439
440RSFormPro.loadImage = function(input) {
441	if ('files' in input && typeof FileReader === 'function')
442	{
443		var file, reader;
444
445		var images = input.parentNode.querySelectorAll('.rsfp-image-container');
446
447		for (var j = 0; j < images.length; j++)
448		{
449			images[j].parentNode.removeChild(images[j]);
450		}
451
452		for (var i = 0; i < input.files.length; i++)
453		{
454			file = input.files[i];
455
456			reader = new FileReader();
457			reader.onload = function(e) {
458				var div = document.createElement('div');
459				div.setAttribute('class', 'rsfp-image-container');
460
461				var img = document.createElement('img');
462				img.setAttribute('src', e.target.result);
463				img.setAttribute('alt', file.name);
464				img.setAttribute('title', file.name);
465				img.setAttribute('class', 'rsfp-image-polaroid');
466				img.onerror = function() {
467					img.src = "data:image/svg+xml,%3Csvg role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='currentColor' d='M256 8C119.034 8 8 119.033 8 256s111.034 248 248 248 248-111.034 248-248S392.967 8 256 8zm130.108 117.892c65.448 65.448 70 165.481 20.677 235.637L150.47 105.216c70.204-49.356 170.226-44.735 235.638 20.676zM125.892 386.108c-65.448-65.448-70-165.481-20.677-235.637L361.53 406.784c-70.203 49.356-170.226 44.736-235.638-20.676z'%3E%3C/path%3E%3C/svg%3E";
468					img.onclick = false;
469				};
470				img.onclick = function() {
471					RSFormPro.openImageModal(this);
472				};
473
474				div.appendChild(img);
475
476				input.parentNode.insertBefore(div, input.nextSibling);
477			};
478
479			reader.readAsDataURL(file);
480		}
481	}
482};
483
484/* Number functions */
485
486RSFormPro.formatNumber = function(number, decimals, dec_point, thousands_sep) {
487	var n = number, prec = decimals;
488	n = !isFinite(+n) ? 0 : +n;
489	prec = !isFinite(+prec) ? 0 : Math.abs(prec);
490	var sep = (typeof thousands_sep == "undefined") ? ',' : thousands_sep;
491	var dec = (typeof dec_point == "undefined") ? '.' : dec_point;
492
493	var s = (prec > 0) ? n.toFixed(prec) : Math.round(n).toFixed(prec); //fix for IE parseFloat(0.55).toFixed(0) = 0;
494
495	var abs = Math.abs(n).toFixed(prec);
496	var _, i;
497
498	if (abs >= 1000) {
499		_ = abs.split(/\D/);
500		i = _[0].length % 3 || 3;
501
502		_[0] = s.slice(0,i + (n < 0)) +
503			_[0].slice(i).replace(/(\d{3})/g, sep+'$1');
504
505		s = _.join(dec);
506	} else {
507		s = s.replace('.', dec);
508	}
509
510	return s;
511};
512
513RSFormPro.toNumber = function(number, decimal, thousands, decimals) {
514	// Remove decimals first
515	if (parseInt(decimals) > 0 && number.lastIndexOf(decimal) > -1) {
516		var index = number.lastIndexOf(decimal);
517		number = number.substring(0, index) + 'DECIMALS' + number.substring(index + 1);
518	}
519
520	// Remove thousands separator
521	if (number.indexOf(thousands) > -1) {
522		number = number.split(thousands).join('');
523	}
524
525	number = number.split('DECIMALS').join('.');
526	return parseFloat(number);
527};
528
529/* Form and element functions */
530
531RSFormPro.getForm = function(formId) {
532	if (typeof RSFormPro.Forms[formId] == 'undefined') {
533		var formIds = document.getElementsByName('form[formId]');
534		for (var i=0; i<formIds.length; i++)
535		{
536			if (parseInt(formIds[i].value) != parseInt(formId))
537				continue;
538
539			var form = formIds[i].parentNode;
540			if (form.tagName == 'FORM' || form.nodeName == 'FORM') {
541				RSFormPro.Forms[formId] = form;
542				return form;
543			}
544
545			while (form.parentNode)
546			{
547				form = form.parentNode;
548				if (form.tagName == 'FORM' || form.nodeName == 'FORM') {
549					RSFormPro.Forms[formId] = form;
550					return form;
551				}
552			}
553		}
554	}
555
556	return RSFormPro.Forms[formId];
557};
558
559RSFormPro.getValue = function(formId, name) {
560	var form	= RSFormPro.getForm(formId);
561	var values	= [];
562
563	if (typeof form != 'undefined')
564	{
565		for (var i = 0; i < form.elements.length; i++)
566		{
567			var element = form.elements[i];
568			var tagName = element.tagName || element.nodeName;
569
570			switch (tagName)
571			{
572				case 'INPUT':
573					if (element.type)
574						switch (element.type.toUpperCase())
575						{
576							case 'TEXT':
577							case 'NUMBER':
578							case 'HIDDEN':
579								if (!element.name || element.name != 'form[' + name + ']') continue;
580								
581								if (typeof RSFormPro.YUICalendar != 'undefined' &&
582									typeof RSFormPro.YUICalendar.calendars[formId] != 'undefined' &&
583									typeof RSFormPro.YUICalendar.calendars[formId][name] != 'undefined')
584									{
585										var selectedDate = new Date(RSFormPro.YUICalendar.calendars[formId][name].getSelectedDates()[0]);
586										return (selectedDate.getTime() / 1000).toString();
587									}
588								
589								if (typeof RSFormPro.jQueryCalendar != 'undefined' &&
590									typeof RSFormPro.jQueryCalendar.calendars[formId] != 'undefined' &&
591									typeof RSFormPro.jQueryCalendar.calendars[formId][name] != 'undefined')
592									{
593										var tmpDate = RSFormPro.jQueryCalendar.calendars[formId][name].calendarInstance.getValue();
594
595										if (RSFormPro.jQueryCalendar.calendars[formId][name].hiddenFormat.indexOf('HH:mm') === -1)
596										{
597											tmpDate.setHours(0, 0, 0, 0);
598										}
599
600										return parseInt(tmpDate.getTime() / 1000).toString();
601									}
602
603                                if (element.hasOwnProperty('rsfpGetValue'))
604                                {
605                                    return element.rsfpGetValue();
606                                }
607								
608								return element.value;
609								break;
610
611							case 'RADIO':
612								if (!element.name || element.name != 'form[' + name + ']') continue;
613
614								if (element.checked == true) {
615									values.push(element.value);
616								}
617								break;
618
619							case 'CHECKBOX':
620								if (!element.name || element.name != 'form[' + name + '][]') continue;
621								if (element.checked == true) {
622									values.push(element.value);
623								}
624								break;
625						}
626					break;
627
628				case 'SELECT':
629					if (!element.name || element.name != 'form[' + name + '][]') continue;
630
631					if (element.options)
632						for (var o=0; o<element.options.length; o++)
633							if (element.options[o].selected)
634							{
635								values.push(element.options[o].value);
636							}
637					break;
638			}
639		}
640	}
641
642	return values;
643};
644
645RSFormPro.getElementByType = function(formId, type) {
646	var form	= RSFormPro.getForm(formId);
647	type = type.toUpperCase();
648	var elements	= [];
649
650	if (typeof form != 'undefined')
651	{
652		for (var i = 0; i < form.elements.length; i++)
653		{
654			var element = form.elements[i];
655			var tagName = element.tagName || element.nodeName;
656			switch (tagName)
657			{
658				case 'INPUT':
659				case 'BUTTON':
660					if (element.type.toUpperCase() == type) {
661						elements.push(element);
662					}
663					break;
664
665				case 'SELECT':
666				case 'TEXTAREA':
667					if (type == 'SELECT' || type == 'TEXTAREA') {
668						elements.push(element);
669					}
670					break;
671			}
672		}
673	}
674
675	return elements;
676};
677
678RSFormPro.resettingValues = false;
679
680RSFormPro.resetValues = function(items) {
681	if (RSFormPro.resettingValues)
682	{
683		return;
684	}
685
686	RSFormPro.resettingValues = true;
687
688	var element, tagName;
689	try
690	{
691		for (var i = 0; i < items.length; i++)
692		{
693			element = items[i];
694			tagName = element.tagName || element.nodeName;
695
696			switch (tagName)
697			{
698				case 'INPUT':
699					if (element.type)
700					{
701						switch (element.type.toUpperCase())
702						{
703							case 'CHECKBOX':
704							case 'RADIO':
705								element.checked = element.defaultChecked;
706								RSFormPro.triggerEvent(element, 'change');
707							break;
708							
709							case 'NUMBER':
710							case 'TEXT':
711								element.value = element.defaultValue;
712
713								if (element.id)
714								{
715									// Range Slider
716									if (element.id.indexOf('rs-range-slider') === 0 && typeof jQuery !== 'undefined')
717									{
718										jQuery(element).data('ionRangeSlider').reset();
719									}
720
721									// Date and Time Picker
722									if (element.id.indexOf('txtjQcal') === 0 && typeof jQuery !== 'undefined' && typeof RSFormPro.jQueryCalendar !== 'undefined')
723									{
724										jQuery(element).datetimepicker('reset');
725									}
726
727									// Calendar
728									if (element.id.indexOf('txtcal') === 0 && typeof RSFormPro.YUICalendar !== 'undefined')
729									{
730										var match = element.id.match(/^txtcal([0-9]+)_[0-9]+$/);
731										if (match.length === 2)
732										{
733											var formId = match[1];
734											var calendarName = element.name.match(/^form\[(.*)\]$/)[1];
735
736											if (typeof RSFormPro.YUICalendar.calendars[formId][calendarName] !== 'undefined')
737											{
738												RSFormPro.YUICalendar.calendars[formId][calendarName].reset();
739											}
740										}
741									}
742								}
743
744								RSFormPro.triggerEvent(element, 'change');
745								RSFormPro.triggerEvent(element, 'input');
746							break;
747						}
748					}
749				break;
750				
751				case 'TEXTAREA':
752					element.value = element.defaultValue;
753					
754					RSFormPro.triggerEvent(element, 'change');
755					RSFormPro.triggerEvent(element, 'input');
756				break;
757
758				case 'SELECT':
759					if (element.options)
760					{
761						var unselected = [];
762						for (var o = 0; o < element.options.length; o++) {
763							element.options[o].selected = element.options[o].defaultSelected;
764
765							if (!element.options[o].defaultSelected) {
766								unselected.push(o);
767							}
768						}
769						
770						// in safari something must be selected
771						if (element.options.length == unselected.length) {
772							element.selectedIndex = 0;
773						}
774					}
775					
776					RSFormPro.triggerEvent(element, 'change');
777				break;
778			}
779		}
780	}
781	catch (err) {}
782
783	RSFormPro.resettingValues = false;
784};
785
786RSFormPro.triggerEvent = function(element, type) {
787	try {
788		var event;
789		if (document.createEvent) {
790			event = document.createEvent("HTMLEvents");
791			event.initEvent(type, true, true);
792		} else {
793			event = document.createEventObject();
794			event.eventType = type;
795		}
796
797		event.eventName = type;
798
799		if (document.createEvent) {
800			element.dispatchEvent(event);
801		} else {
802			element.fireEvent("on" + event.eventType, event);
803		}
804	} catch (e) {}
805};
806
807RSFormPro.isChecked = function(formId, name, value) {
808	var isChecked 	= false;
809	var form 		= RSFormPro.getForm(formId);
810
811	if (typeof form != 'undefined')
812	{
813		primary_loop:
814			for (var i=0; i<form.elements.length; i++)
815			{
816				var element = form.elements[i];
817				var tagName = element.tagName || element.nodeName;
818
819				switch (tagName)
820				{
821					case 'INPUT':
822						if (element.type)
823							switch (element.type.toUpperCase())
824							{
825								default:
826									if (!element.name || element.name != 'form[' + name + ']') continue;
827									if (!element.value) continue;
828
829									if (element.value == value)
830									{
831										isChecked = true;
832										break primary_loop;
833									}
834
835									break;
836								case 'RADIO':
837									if (!element.name || element.name != 'form[' + name + ']') continue;
838									if (element.checked == true && element.value == value)
839									{
840										isChecked = true;
841										break primary_loop;
842									}
843									break;
844
845								case 'CHECKBOX':
846									if (!element.name || element.name != 'form[' + name + '][]') continue;
847									if (element.checked == true && element.value == value)
848									{
849										isChecked = true;
850										break primary_loop;
851									}
852									break;
853							}
854						break;
855
856					case 'SELECT':
857						if (!element.name || element.name != 'form[' + name + '][]') continue;
858
859						if (element.options)
860							for (var o=0; o<element.options.length; o++)
861								if (element.options[o].selected && element.options[o].value == value)
862								{
863									isChecked = true;
864									break primary_loop;
865								}
866						break;
867				}
868			}
869	}
870
871	return isChecked;
872};
873
874RSFormPro.getBlock = function(formId, block) {
875	var form 	 = RSFormPro.getForm(formId);
876	var possible = false;
877	var blocks, current_block;
878
879	if (typeof form != 'undefined') {
880		if (blocks = getElementsByClassName('rsform-block')) {
881			for (i=0; i<blocks.length; i++) {
882				var classes = blocks[i].className.split(' ');
883				for (c=0; c<classes.length; c++) {
884					if (classes[c] == 'rsform-block-' + block) {
885						if (blocks[i].parentNode) {
886							current_block = blocks[i];
887							if (current_block == form)
888								return [ blocks[i] ];
889
890							while (current_block.parentNode) {
891								current_block = current_block.parentNode;
892								if (current_block == form)
893									return [ blocks[i] ];
894							}
895						}
896
897						possible = [ blocks[i] ];
898					}
899				}
900			}
901		}
902	}
903
904	return possible;
905};
906
907RSFormPro.getFieldsByName = function(formId, name) {
908	var form 	= RSFormPro.getForm(formId);
909	var results = [];
910	var pushed  = false;
911
912	if (typeof form != 'undefined') {
913		for (var i=0; i<form.elements.length; i++) {
914			var element = form.elements[i];
915			pushed = false;
916			if (element.name && (
917					// single fields
918					element.name == 'form[' + name + ']' ||
919					// multiple fields
920					element.name == 'form[' + name + '][]' ||
921					// new field - Birthday field
922					element.name == 'form[' + name + '][d]' ||
923					element.name == 'form[' + name + '][m]' ||
924					element.name == 'form[' + name + '][y]'
925				)) {
926				results.push(element);
927				pushed = true;
928			}
929
930			if (pushed) {
931				// for calendar
932				if (element.id && element.id.indexOf('txtcal') > -1) {
933					var suffix = element.id.replace('txtcal', '');
934					if (document.getElementById('btn' + suffix))
935					{
936						results.push(document.getElementById('btn' + suffix));
937					}
938				}
939				// for labels (radio, checkbox)
940				var labels = form.getElementsByTagName('label');
941				for (var l=0; l<labels.length; l++) {
942					if (labels[l].htmlFor && labels[l].htmlFor == element.id)
943						results.push(labels[l]);
944				}
945			}
946		}
947	}
948
949	return results;
950};
951
952RSFormPro.showCounter = function(element, id) {
953	var current = element.value.length;
954	var result;
955	if (element.maxLength > 0)
956	{
957		result = current + '/' + element.maxLength;
958	}
959	else
960	{
961		result = current;
962	}
963	
964	document.getElementById('rsfp-counter-' + id).innerText = result;
965};
966
967RSFormPro.limitSelections = function(formId, field, max) {
968    RSFormProUtils.addEvent(window, 'load', function() {
969        var fields = RSFormPro.getFieldsByName(formId, field);
970        var objects = [];
971        var i;
972        var tagName;
973
974        if (!fields || !fields.length) {
975            return;
976        }
977
978        for (i = 0; i < fields.length; i++) {
979            tagName = fields[i].tagName || fields[i].nodeName;
980            tagName = tagName.toUpperCase();
981
982            if (tagName === 'INPUT' && fields[i].type && fields[i].type.toUpperCase() === 'CHECKBOX' && !fields[i].disabled) {
983                objects.push(fields[i]);
984            }
985        }
986
987        if (!objects.length) {
988            return;
989        }
990
991        function limitSelections() {
992            var values = RSFormProUtils.getChecked(objects);
993            RSFormProUtils.remAttr(objects, 'disabled');
994            if (values && values.length > 0 && values.length >= max) {
995                RSFormProUtils.setAttr(RSFormProUtils.getUnchecked(objects), 'disabled', true);
996            }
997		}
998
999        for (i = 0; i < objects.length; i++) {
1000            RSFormProUtils.addEvent(objects[i], 'change', limitSelections);
1001        }
1002
1003        limitSelections();
1004    });
1005};
1006
1007/*HTML5 simulators*/
1008
1009RSFormPro.HTML5 = {
1010	validation: function(formId){
1011		var form = RSFormPro.getForm(formId);
1012		var errorElements = [];
1013		var html5types = ['number', 'email', 'range', 'url', 'tel'];
1014		var multipleTypes = ['radio'];
1015
1016		var checkValidityExists = true;
1017		var page = 0;
1018		var componentId;
1019		var elementId;
1020		var match;
1021
1022		if (form.elements.length) {
1023			for (var i = 0; i < form.elements.length; i++) {
1024				if (!checkValidityExists) {
1025					break;
1026				}
1027
1028				// if the multiple form is present and also validation we will need to find in which page the element is located
1029				if (form.elements[i].type == 'button') {
1030					var onclick = form.elements[i].getAttribute('onclick');
1031					if (typeof onclick == 'string' && (onclick.indexOf('rsfp_changePage') > -1 || onclick.indexOf('RSFormPro.Pages.change') > -1)) {
1032						var countCommas = 0;
1033						var pos = onclick.indexOf(',');
1034						while (pos > -1) {
1035							++countCommas;
1036							pos = onclick.indexOf(',', ++pos);
1037						}
1038
1039						if (countCommas > 2) {
1040							page++;
1041						}
1042					}
1043				}
1044				if (html5types.indexOf(form.elements[i].type) > -1) {
1045					if ( typeof(form.elements[i].checkValidity) === 'function' && checkValidityExists) {
1046						if (!form.elements[i].checkValidity()) {
1047							var elementObj = {
1048								field: form.elements[i],
1049								page: page
1050							};
1051							// try to get the componentId
1052							elementId = form.elements[i].getAttribute('id');
1053							if (multipleTypes.indexOf(form.elements[i].type) > -1)
1054							{
1055								if (match = form.elements[i].getAttribute('name').match(/form\[(.*)\]/))
1056								{
1057									elementId = match[1];
1058								}
1059							}
1060							componentId = RSFormPro.HTML5.getComponentId(formId, elementId);
1061
1062							if (componentId) {
1063								elementObj.componentId = componentId;
1064							}
1065
1066							errorElements.push(elementObj);
1067						}
1068					} else {
1069						checkValidityExists = false;
1070					}
1071				}
1072			}
1073		}
1074		return errorElements;
1075	},
1076
1077	componentIds: {},
1078
1079	getComponentId: function(formId, elementAlias) {
1080		if (typeof RSFormPro.HTML5.componentIds[formId] == 'undefined') {
1081			RSFormPro.HTML5.componentIds[formId] = {};
1082		}
1083
1084		if (typeof RSFormPro.HTML5.componentIds[formId][elementAlias] == 'undefined') {
1085			RSFormPro.HTML5.componentIds[formId][elementAlias] = false;
1086			var block = RSFormPro.getBlock(formId, RSFormProUtils.getAlias(elementAlias));
1087
1088			if (typeof block[0] !== 'undefined') {
1089				var componentIdBlock;
1090
1091				componentIdBlock = RSFormProUtils.getElementsByClassName('formNoError', 'span', block[0]);
1092				if (componentIdBlock.length === 0) {
1093					componentIdBlock = RSFormProUtils.getElementsByClassName('formError', 'span', block[0]);
1094				}
1095
1096				if (componentIdBlock.length > 0) {
1097					var componentId = componentIdBlock[0].getAttribute('id');
1098					RSFormPro.HTML5.componentIds[formId][elementAlias] = componentId.replace('component', '');
1099				}
1100			}
1101		}
1102
1103		return RSFormPro.HTML5.componentIds[formId][elementAlias];
1104	}
1105};
1106
1107/* Pagination functions */
1108
1109RSFormPro.Pages = {
1110	change: function(formId, page, totalPages, validate, errorClasses) {
1111		// callback functions if next page is clicked
1112		var direction = RSFormPro.Pages.checkDirection(formId, page);
1113		if (direction == 'next') {
1114			RSFormPro.callbacks.runCallback(formId, 'nextPage');
1115		}
1116		RSFormPro.callbacks.runCallback(formId, 'changePage');
1117		
1118		var thePage;
1119
1120		if (validate) {
1121			var form = RSFormPro.getForm(formId);
1122			if (!RSFormPro.Ajax.validate(form, page, errorClasses, totalPages)) {
1123				return false;
1124			}
1125		}
1126
1127		for (var i = 0; i <= totalPages; i++) {
1128			thePage = document.getElementById('rsform_' + formId + '_page_' + i);
1129			if (thePage) {
1130				RSFormPro.Pages.hide(thePage);
1131			}
1132		}
1133
1134		thePage = document.getElementById('rsform_' + formId + '_page_' + page);
1135		if (thePage) {
1136			RSFormPro.Pages.show(thePage);
1137			try {
1138				var func = window["rsfp_showProgress_" + formId];
1139				if (typeof func == "function") {
1140					func(page);
1141				}
1142			}
1143			catch (err) {}
1144		}
1145	},
1146	hide: function(thePage) {
1147		RSFormProUtils.addClass(thePage, 'formHidden');
1148	},
1149	show: function(thePage) {
1150		RSFormProUtils.removeClass(thePage, 'formHidden');
1151	},
1152	
1153	checkDirection : function(formId, page) {
1154		var base = RSFormPro.Pages;
1155		if (typeof base.history[formId] == 'undefined') {
1156			base.history[formId] = page;
1157			return 'next';
1158		} else {
1159			var direction;
1160			if (base.history[formId] <= page ) { 
1161				direction = 'next';
1162			} else {
1163				direction = 'prev';
1164			}
1165			base.history[formId] = page;
1166			
1167			return direction;
1168		}
1169	},	
1170	history: {}
1171};
1172
1173/* Condition functions */
1174RSFormPro.Conditions = {
1175	add: function(formId, name, fnCondition) {
1176		var form = RSFormPro.getForm(formId);
1177
1178		if (typeof form != 'undefined') {
1179			for (var i = 0; i < form.elements.length; i++) {
1180				var element = form.elements[i];
1181				if (element.name && (element.name == 'form[' + name + ']' || element.name == 'form[' + name + '][]')) {
1182					RSFormProUtils.addEvent(element, 'change', function() {
1183						fnCondition();
1184					});
1185				}
1186			}
1187		}
1188	},
1189	run: function(condition) {
1190		var formId = condition.form_id,
1191            conditions = [],
1192            items = [],
1193			detail, isChecked, displayValue, match;
1194
1195		var i, c;
1196
1197		if (typeof condition.details === 'object')
1198		{
1199			for (i = 0; i < condition.details.length; i++)
1200			{
1201				detail = condition.details[i];
1202                isChecked = RSFormPro.isChecked(formId, detail.ComponentName, detail.value);
1203                conditions.push(isChecked === (detail.operator === 'is'));
1204			}
1205
1206			items = [];
1207
1208			if (condition.ComponentNames)
1209			{
1210				for (c = 0; c < condition.ComponentNames.length; c++)
1211				{
1212					if (parseInt(condition.block) === 1)
1213					{
1214						items = items.concat(RSFormPro.getBlock(formId, RSFormProUtils.getAlias(condition.ComponentNames[c])));
1215					}
1216					else
1217					{
1218						items = items.concat(RSFormPro.getFieldsByName(formId, condition.ComponentNames[c]));
1219					}
1220				}
1221			}
1222
1223			if (items.length > 0)
1224			{
1225				if (condition.condition === 'all')
1226				{
1227                    // && conditions need all elements of the Array to be true -> no false in Array
1228                    match = conditions.indexOf(false) === -1;
1229				}
1230				else
1231				{
1232                    // || conditions need only one element to be true -> one true in array
1233					match = conditions.indexOf(true) > -1;
1234				}
1235
1236                if (match)
1237                {
1238                    displayValue = condition.action === 'show' ? '' : 'none';
1239                }
1240                else
1241                {
1242                    displayValue = condition.action === 'show' ? 'none' : '';
1243                }
1244
1245				RSFormProUtils.setDisplay(items, displayValue);
1246                if (displayValue === 'none')
1247				{
1248					if (condition.ComponentNames)
1249					{
1250						for (c = 0; c < condition.ComponentNames.length; c++)
1251						{
1252							RSFormPro.resetValues(RSFormPro.getFieldsByName(formId, condition.ComponentNames[c]));
1253						}
1254					}
1255				}
1256			}
1257		}
1258	},
1259	runAll: function(formId) {
1260		var func = window['rsfp_runAllConditions' + formId];
1261		if (typeof func === 'function') {
1262			func();
1263		}
1264	},
1265	addReset: function(formId) {
1266		var resetElements = RSFormPro.getElementByType(formId, 'reset');
1267		if (resetElements.length > 0)
1268		{
1269			for (var i = 0; i < resetElements.length; i++)
1270			{
1271				RSFormProUtils.addEvent(resetElements[i], 'click', function() {
1272					window.setTimeout(function() {
1273						RSFormPro.Conditions.runAll(formId);
1274					}, 1);
1275				});
1276			}
1277		}
1278	},
1279	delayRun: function(formId) {
1280		var func = window['rsfp_runAllConditions' + formId];
1281		if (typeof func === 'function') {
1282			RSFormProUtils.addEvent(window, 'load', func);
1283		}
1284	}
1285};
1286
1287/* Calculation functions */
1288
1289RSFormPro.Calculations = {
1290	toDays: function(seconds) {
1291		return Math.round(parseFloat(seconds) / 86400);
1292	},
1293	toHours: function(seconds) {
1294		return Math.round(parseFloat(seconds) / 86400 * 24);
1295	},
1296	toMinutes: function(seconds) {
1297        return Math.round(parseFloat(seconds) / 86400 * 24 * 60);
1298    },
1299	addEvents: function(formId, fields) {
1300		RSFormProUtils.addEvent(window, 'load', function(){
1301			RSFormPro.Calculations._addEvents(formId, fields);
1302		});
1303	},
1304	_addEvents: function(formId, fields) {
1305		var func 		= window['rsfp_Calculations' + formId];
1306		var thefields	= fields ? fields : RSFormProPrices;
1307		var event 		= 'change';
1308		var objects, tagName;
1309		
1310		var resetElements = RSFormPro.getElementByType(formId, 'reset');
1311		if (resetElements.length > 0)
1312		{
1313			for (var i = 0; i < resetElements.length; i++)
1314			{
1315				RSFormProUtils.addEvent(resetElements[i], 'click', function() {
1316					if (typeof func === 'function') {
1317						window.setTimeout(func, 1);
1318					}
1319				});
1320			}
1321		}
1322
1323		for (var field in thefields) {
1324			if (!thefields.hasOwnProperty(field)) {
1325				continue;
1326			}
1327			field = field.replace(formId+'_','');
1328			objects = RSFormPro.getFieldsByName(formId,field);
1329			for(i = 0; i < objects.length;i++) {
1330				tagName = objects[i].tagName || objects[i].nodeName;
1331
1332				if (tagName === 'INPUT' || tagName === 'SELECT') {
1333					event = 'change';
1334					if (tagName === 'INPUT' && typeof objects[i].type == 'string') {
1335						switch (objects[i].type.toUpperCase())
1336						{
1337							default:
1338								event = 'change';
1339							break;
1340							
1341							case 'NUMBER':
1342							case 'TEXT':
1343								event = 'input';
1344								
1345								if (typeof RSFormPro.jQueryCalendar !== 'undefined' &&
1346									typeof RSFormPro.jQueryCalendar.calendars[formId] !== 'undefined' &&
1347									typeof RSFormPro.jQueryCalendar.calendars[formId][field] !== 'undefined')
1348									{
1349										RSFormPro.jQueryCalendar.calendars[formId][field].calendarInstance.setOptions({onChangeDateTime: function() {
1350											if (typeof func === 'function') {
1351												func();
1352											}
1353										}});
1354									}
1355								
1356								if (typeof RSFormPro.YUICalendar !== 'undefined' &&
1357									typeof RSFormPro.YUICalendar.calendars[formId] !== 'undefined' &&
1358									typeof RSFormPro.YUICalendar.calendars[formId][field] !== 'undefined')
1359									{
1360										RSFormPro.YUICalendar.calendars[formId][field].selectEvent.subscribe(function() {
1361											if (typeof func === 'function') {
1362												func();
1363											}
1364										}, RSFormPro.YUICalendar.calendars[formId][field], true);
1365									}
1366
1367								if (objects[i].hasOwnProperty('rsfpOnChange'))
1368								{
1369									objects[i].rsfpOnChange(func);
1370								}
1371							break;
1372						}
1373					}
1374
1375					RSFormProUtils.addEvent(objects[i], event, function() {
1376						if (typeof func === 'function') {
1377							func();
1378						}
1379					});
1380				}
1381			}
1382		}
1383	}
1384};
1385
1386/* AJAX functions */
1387RSFormPro.Ajax = {
1388	Wait: false,
1389	URL: false,
1390	Params: {},
1391	getParamsObject: function() {
1392		return {
1393			vars: [],
1394			push: function(str) {
1395				return this.vars.push(str);
1396			},
1397			
1398			indexOf: function(str) {
1399				return this.vars.join('&').indexOf(str);
1400			},
1401			
1402			replace: function(r, w) {
1403				this.vars = this.vars.join('&').replace(r, w).split('&');
1404				
1405				return this.vars.join('&');
1406			},
1407			
1408			toString: function() {
1409				return this.vars.join('&');
1410			}
1411		};
1412	},
1413	getXHR: function() {
1414		try {
1415			return new window.XMLHttpRequest();
1416		} catch ( e ) {}
1417	},
1418	getXHRLegacy: function() {
1419		return {
1420			send: function(data)
1421			{
1422				if (data === RSFormPro.Ajax.Params)
1423				{
1424					data = data.toString();
1425				}
1426				
1427				return RSFormPro.Ajax.xhr.send(data);
1428			}
1429		}
1430	},
1431	displayValidationErrors: function(formComponents, task, formId, data) {
1432		if (task == 'afterSend') {
1433			var ids, i, j, id, formComponent, elementBlock;
1434			var parentErrorClass = typeof data.parentErrorClass !== 'undefined' && data.parentErrorClass.length > 0 ? data.parentErrorClass : false;
1435			var fieldErrorClass = typeof data.fieldErrorClass !== 'undefined' && data.fieldErrorClass.length > 0 ? data.fieldErrorClass : false;
1436
1437			ids = data.response[0].split(',');
1438			for (i = 0; i < ids.length; i++)
1439			{
1440				id = parseInt(ids[i]);
1441
1442				if (isNaN(id))
1443				{
1444					continue;
1445				}
1446
1447				if (typeof formComponents[id] === 'undefined')
1448				{
1449					continue;
1450				}
1451
1452				formComponent = RSFormPro.getFieldsByName(formId, formComponents[id]);
1453
1454				if (!formComponent || formComponent.length < 1)
1455				{
1456					continue;
1457				}
1458
1459				for (j = 0; j < formComponent.length; j++)
1460				{
1461					if (formComponent[j])
1462					{
1463						RSFormProUtils.removeClass(formComponent[j], 'rsform-error');
1464						formComponent[j].removeAttribute('aria-invalid');
1465						if (formComponent[j].getAttribute('aria-describedby') === 'component' + id) {
1466							formComponent[j].removeAttribute('aria-describedby');
1467						}
1468
1469						if (parentErrorClass)
1470						{
1471							try
1472							{
1473								if (elementBlock = RSFormPro.getBlock(formId, RSFormProUtils.getAlias(formComponents[id])))
1474								{
1475									RSFormProUtils.removeClass(elementBlock[0], parentErrorClass);
1476								}
1477							}
1478							catch (err) {}
1479						}
1480
1481						if (fieldErrorClass)
1482						{
1483							RSFormProUtils.removeClass(formComponent[j], fieldErrorClass);
1484						}
1485					}
1486				}
1487			}
1488
1489			ids = data.response[1].split(',');
1490			var doScroll = false;
1491			var doFocus = false;
1492			for (i = 0; i < ids.length; i++)
1493			{
1494				id = parseInt(ids[i]);
1495				
1496				if (isNaN(id))
1497				{
1498					continue;
1499				}
1500				
1501				if (typeof formComponents[id] === 'undefined')
1502				{
1503					continue;
1504				}
1505				
1506				formComponent = RSFormPro.getFieldsByName(formId, formComponents[id]);
1507
1508				if (!formComponent || formComponent.length < 1)
1509				{
1510					continue;
1511				}
1512				
1513				for (j = 0; j < formComponent.length; j++)
1514				{
1515					if (formComponent[j])
1516					{
1517						RSFormProUtils.addClass(formComponent[j], 'rsform-error');
1518
1519						if (!doScroll)
1520						{
1521							doScroll = true;
1522						}
1523						
1524						if (parentErrorClass)
1525						{
1526							try
1527							{
1528								if (elementBlock = RSFormPro.getBlock(formId, RSFormProUtils.getAlias(formComponents[id])))
1529								{
1530									RSFormProUtils.addClass(elementBlock[0], parentErrorClass);
1531								}
1532							}
1533							catch (err) {}
1534						}
1535
1536						if (fieldErrorClass)
1537						{
1538							RSFormProUtils.addClass(formComponent[j], fieldErrorClass);
1539						}
1540
1541						if (['INPUT', 'SELECT', 'TEXTAREA'].indexOf(formComponent[j].nodeName) > -1)
1542						{
1543							if (formComponent[j].getAttribute('type') !== 'button') {
1544								formComponent[j].setAttribute('aria-invalid', 'true');
1545								formComponent[j].setAttribute('aria-describedby', 'component' + id);
1546
1547								if (!doFocus && typeof formComponent[j].focus === 'function') {
1548									formComponent[j].focus();
1549									doFocus = true;
1550								}
1551							}
1552						}
1553					}
1554				}
1555			}
1556			
1557			// scroll to first error elment
1558			if (RSFormPro.scrollToError && doScroll){
1559				RSFormPro.gotoErrorElement(formId);
1560			}
1561		}
1562	},
1563	validate: function(form, page, errorClasses, totalPages) {
1564		try {
1565			var el = form.elements.length;
1566		} catch (err) {
1567			form = this;
1568		}
1569
1570		RSFormPro.Ajax.xhr = RSFormPro.Ajax.getXHR();
1571		RSFormPro.Ajax.xmlHttp = RSFormPro.Ajax.getXHRLegacy();
1572		var url = 'index.php?option=com_rsform&task=ajaxValidate';
1573		if (typeof RSFormPro.Ajax.URL == 'string') {
1574			url = RSFormPro.Ajax.URL;
1575		}
1576		
1577		RSFormPro.Ajax.Params = RSFormPro.Ajax.getParamsObject();
1578
1579		var submits = [],
1580			errorFields = [],
1581			success = false,
1582			formId = form.elements['form[formId]'].value,
1583			totalJSDetectedPages = 0,
1584			i,
1585			j;
1586
1587		// File uploads AJAX validation variabiles
1588		var ajaxSkippedFileUploads = [],
1589			filesLength = 0,
1590			filesCollection = [],
1591			identicalFiles = [];
1592		
1593		if (typeof errorClasses != 'object')
1594		{
1595			errorClasses = {'parent': '', 'field': ''}
1596		}
1597
1598		for (i=0; i<form.elements.length; i++)
1599		{
1600			// try and detect total pages of the form
1601			if (form.elements[i].type == 'button') {
1602				var onclick = form.elements[i].getAttribute('onclick');
1603				if (typeof onclick === 'string' && (onclick.indexOf('rsfp_changePage') > -1 || onclick.indexOf('RSFormPro.Pages.change') > -1)) {
1604					var countCommas = 0;
1605					var pos = onclick.indexOf(',');
1606					while (pos > -1) {
1607						++countCommas;
1608						pos = onclick.indexOf(',', ++pos);
1609					}
1610
1611					if (countCommas > 2) {
1612						totalJSDetectedPages++;
1613					}
1614				}
1615			}
1616
1617			// don't send an empty value
1618			if (!form.elements[i].name) continue;
1619			if (form.elements[i].name.length == 0) continue;
1620			// check if the checkbox is checked
1621			if (form.elements[i].type == 'checkbox' && form.elements[i].checked == false) continue;
1622			// check if the radio is selected
1623			if (form.elements[i].type == 'radio' && form.elements[i].checked == false) continue;
1624
1625			if (form.elements[i].type == 'submit' && form.elements[i].getAttribute('data-disableonsubmit') == '1') {
1626				submits.push(form.elements[i]);
1627				form.elements[i].disabled = true;
1628			}
1629
1630			// check if form is a dropdown with multiple selections
1631			if (form.elements[i].type == 'select-multiple')
1632			{
1633				for (j = 0; j < form.elements[i].options.length; j++) {
1634					if (form.elements[i].options[j].selected) {
1635						RSFormPro.Ajax.Params.push(form.elements[i].name + '=' + encodeURIComponent(form.elements[i].options[j].value));
1636					}
1637				}
1638
1639				continue;
1640			}
1641
1642			if (form.elements[i].type == 'file')
1643			{
1644				if ('files' in form.elements[i])
1645				{
1646					try
1647					{
1648						if (RSFormPro.usePositioning)
1649						{
1650							if (form.elements[i].offsetParent !== document.getElementsByTagName('body')[0])
1651							{
1652								throw 'CONDITIONAL_HIDDEN';
1653							}
1654						}
1655						else
1656						{
1657							if (form.elements[i].offsetParent === null)
1658							{
1659								throw 'CONDITIONAL_HIDDEN';
1660							}
1661						}
1662
1663						if (form.elements[i].getAttribute('data-rsfp-skip-ajax') === 'true')
1664						{
1665							// Not already processed
1666							if (ajaxSkippedFileUploads.indexOf(form.elements[i].name) === -1)
1667							{
1668								// All fields are identical, make sure this code is only run once.
1669								ajaxSkippedFileUploads.push(form.elements[i].name);
1670
1671								// Get all identical fields
1672								identicalFiles = form.elements[form.elements[i].name];
1673
1674								filesLength = 0;
1675								filesCollection = [];
1676
1677								if (typeof identicalFiles === 'object')
1678								{
1679									// NodeList (multiple inputs)
1680									if (typeof identicalFiles.length !== 'undefined' && identicalFiles.length > 0)
1681									{
1682										for (var tmp = 0; tmp < identicalFiles.length; tmp++)
1683										{
1684											if (identicalFiles[tmp].files.length > 0)
1685											{
1686												filesLength += identicalFiles[tmp].files.length;
1687												filesCollection = filesCollection.concat(identicalFiles[tmp].files[0]);
1688											}
1689										}
1690									}
1691									else if (typeof identicalFiles.files !== 'undefined')
1692									{
1693										// Just one input
1694										filesLength += identicalFiles.files.length;
1695										filesCollection = filesCollection.concat(identicalFiles.files[0]);
1696									}
1697								}
1698							}
1699							else
1700							{
1701								throw 'AJAX_SKIPPED_FILE_UPLOAD';
1702							}
1703						}
1704						else
1705						{
1706							filesLength = form.elements[i].files.length;
1707							filesCollection = form.elements[i].files;
1708						}
1709
1710						if (filesLength === 0 && form.elements[i].getAttribute('data-rsfp-required') === 'true')
1711						{
1712							throw new RSFormPro.validationError('VALIDATION_ERROR', RSFormPro.Translations.translate(formId, form.elements[i].getAttribute('id'), 'VALIDATIONMESSAGE'));
1713						}
1714
1715						if (form.elements[i].getAttribute('data-rsfp-required') === 'true' || filesLength > 0)
1716						{
1717							if (form.elements[i].getAttribute('data-rsfp-minfiles'))
1718							{
1719								var minFiles = parseInt(form.elements[i].getAttribute('data-rsfp-minfiles'));
1720
1721								if (filesLength < minFiles)
1722								{
1723									throw new RSFormPro.validationError('VALIDATION_ERROR', RSFormProUtils.sprintf(RSFormPro.Translations.commonTranslate('COM_RSFORM_MIN
1723FILES_REQUIRED'), minFiles));
1724								}
1725							}
1726
1727							if (form.elements[i].getAttribute('data-rsfp-maxfiles'))
1728							{
1729								var maxFiles = parseInt(form.elements[i].getAttribute('data-rsfp-maxfiles'));
1730
1731								if (filesLength > maxFiles)
1732								{
1733									throw new RSFormPro.validationError('VALIDATION_ERROR', RSFormProUtils.sprintf(RSFormPro.Translations.commonTranslate('COM_RSFORM_MAXFILES_REQUIRED'), maxFiles));
1734								}
1735							}
1736						}
1737
1738						for (var f = 0; f < filesLength; f++)
1739						{
1740							var file = filesCollection[f];
1741							var maxSize = parseInt(form.elements[i].getAttribute('data-rsfp-size'));
1742							if ('size' in file && maxSize > 0)
1743							{
1744								if (file.size > maxSize)
1745								{
1746									throw new RSFormPro.validationError('VALIDATION_ERROR', RSFormProUtils.sprintf(RSFormPro.Translations.commonTranslate('COM_RSFORM_FILE_EXCEEDS_LIMIT'), file.name, maxSize / 1024));
1747								}
1748							}
1749							if ('name' in file)
1750							{
1751								var exts = form.elements[i].getAttribute('data-rsfp-exts');
1752								if (exts)
1753								{
1754									exts = JSON.parse(exts);
1755
1756									var ext = file.name.slice((file.name.lastIndexOf(".") - 1 >>> 0) + 2);
1757									if (exts.indexOf(ext.toLowerCase()) === -1)
1758									{
1759										throw new RSFormPro.validationError('VALIDATION_ERROR', RSFormProUtils.sprintf(RSFormPro.Translations.commonTranslate('COM_RSFORM_FILE_EXTENSION_NOT_ALLOWED'), file.name));
1760									}
1761								}
1762							}
1763						}
1764					}
1765					catch (error)
1766					{
1767						if (typeof error === 'object')
1768						{
1769							if (error.toString() === 'VALIDATION_ERROR')
1770							{
1771								var parents = RSFormProUtils.getParents(form.elements[i]),
1772									page_number,
1773									parent;
1774								if (parents.length > 0)
1775								{
1776									for (var p = 0; p < parents.length; p++)
1777									{
1778										parent = parents[p];
1779
1780										if ('getAttribute' in parent)
1781										{
1782											var hasId = parents[p].getAttribute('id');
1783											var pageId = 'rsform_' + formId + '_page_';
1784											if (hasId && hasId.indexOf(pageId) === 0)
1785											{
1786												page_number = hasId.slice(pageId.length);
1787												break;
1788											}
1789										}
1790									}
1791								}
1792
1793								var elementObj = {
1794									field: form.elements[i],
1795									page: page_number
1796								};
1797
1798								// try to get the componentId
1799								var componentId = RSFormPro.HTML5.getComponentId(formId, form.elements[i].getAttribute('id'));
1800								if (componentId)
1801								{
1802									elementObj.componentId = componentId;
1803
1804									if (document.getElementById('component' + componentId) && error.message.length > 0)
1805									{
1806										document.getElementById('component' + componentId).innerText = error.message;
1807									}
1808								}
1809
1810								errorFields.push(elementObj);
1811							}
1812						}
1813					}
1814				}
1815			}
1816
1817			if (form.elements[i].type !== 'file')
1818			{
1819				if (typeof RSFormPro.Editors[form.elements[i].name] === 'function' && RSFormPro.Editors[form.elements[i].name]() !== null)
1820				{
1821					RSFormPro.Ajax.Params.push(form.elements[i].name + '=' + encodeURIComponent(RSFormPro.Editors[form.elements[i].name]()));
1822				}
1823				else
1824				{
1825					RSFormPro.Ajax.Params.push(form.elements[i].name + '=' + encodeURIComponent(form.elements[i].value));
1826				}
1827			}
1828		}
1829
1830		errorFields = errorFields.concat(RSFormPro.HTML5.validation(formId));
1831
1832		if (page) {
1833			RSFormPro.Ajax.Params.push('page=' + page);
1834		}
1835
1836		RSFormPro.Ajax.xhr.open("POST", url, true);
1837
1838		//Send the proper header information along with the request
1839		RSFormPro.Ajax.xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
1840		
1841		if (typeof ajaxExtraValidationScript[formId] == 'function') {
1842			ajaxExtraValidationScript[formId]('beforeSend', formId, {'url': url, 'params': RSFormPro.Ajax.Params});
1843		}
1844
1845		if (!RSFormPro.Ajax.Wait)
1846		{
1847			// B/C layer
1848			RSFormPro.Ajax.xmlHttp.send(RSFormPro.Ajax.Params);
1849		}
1850		success = true;
1851		
1852		RSFormPro.Ajax.xhr.onreadystatechange = function() {
1853			if (RSFormPro.Ajax.xhr.readyState === 4 && RSFormPro.Ajax.xhr.status === 200) {
1854				try
1855				{
1856					var RSFormProResponse = JSON.parse(RSFormPro.Ajax.xhr.responseText);
1857				}
1858				catch (error)
1859				{
1860					// Parse invalid data
1861					if (typeof RSFormProResponse !== 'object')
1862					{
1863						var match = RSFormPro.Ajax.xhr.responseText.match(/{.*}/);
1864
1865						if (match.length > 0)
1866						{
1867							RSFormProResponse = JSON.parse(match[0]);
1868						}
1869					}
1870				}
1871
1872				var response = [];
1873				var ids;
1874				var i;
1875
1876				if (typeof RSFormProResponse.formComponents !== 'undefined')
1877				{
1878					// All spans set to no error
1879					ids = RSFormProResponse.formComponents;
1880
1881					for (i = 0; i < ids.length; i++)
1882					{
1883						if (!isNaN(parseInt(ids[i])) && document.getElementById('component'+ids[i]))
1884						{
1885							document.getElementById('component'+ids[i]).className = 'formNoError';
1886						}
1887					}
1888
1889					// Legacy
1890					response.push(RSFormProResponse.formComponents.join(','));
1891				}
1892
1893				if (typeof RSFormProResponse.invalidComponents === 'undefined')
1894				{
1895					RSFormProResponse.invalidComponents = [];
1896				}
1897
1898				// add the HTML5 elements with errors
1899				var errorOnPage;
1900				if (errorFields.length)
1901				{
1902					for (i = 0; i < errorFields.length; i++)
1903					{
1904						if (typeof errorFields[i].componentId !== 'undefined')
1905						{
1906							if (typeof page === 'undefined' || (page - 1) == errorFields[i].page)
1907							{
1908								RSFormProResponse.invalidComponents.push(errorFields[i].componentId);
1909								if (typeof errorOnPage !== 'undefined')
1910								{
1911									errorOnPage = errorFields[i].page < errorOnPage ? errorFields[i].page : errorOnPage;
1912								}
1913								else 
1914								{
1915									errorOnPage = errorFields[i].page;
1916								}
1917							}
1918						}
1919					}
1920				}
1921
1922				// Show errors
1923				var errorComponents = [];
1924
1925				var errorMessageContainer;
1926
1927				for (i = 0; i < RSFormProResponse.invalidComponents.length; i++)
1928				{
1929					if (!isNaN(parseInt(RSFormProResponse.invalidComponents[i])))
1930					{
1931						errorMessageContainer = document.getElementById('component' + RSFormProResponse.invalidComponents[i]);
1932
1933						if (errorMessageContainer)
1934						{
1935							errorMessageContainer.className = 'formError';
1936
1937							if (RSFormProResponse.validationMessages && typeof RSFormProResponse.validationMessages[RSFormProResponse.invalidComponents[i]] !== 'undefined')
1938							{
1939								errorMessageContainer.innerHTML = RSFormProResponse.validationMessages[RSFormProResponse.invalidComponents[i]];
1940							}
1941						}
1942
1943						errorComponents.push(RSFormProResponse.invalidComponents[i]);
1944						success = false;
1945					}
1946				}
1947
1948				// lets detect if the multiple page form is submitted
1949				var changePageHTML5Errors = false;
1950				if (totalJSDetectedPages > 0 && RSClickedSubmitElement && submits.indexOf(RSClickedSubmitElement) >= 0 && typeof errorOnPage !== 'undefined') {
1951					changePageHTML5Errors = true;
1952				}
1953
1954				// Legacy
1955				response.push(RSFormProResponse.invalidComponents.join(','));
1956
1957				if (typeof RSFormProResponse.allPages !== 'undefined' || changePageHTML5Errors)
1958				{
1959					// Legacy
1960					response.push(RSFormProResponse.currentPage);
1961					response.push(RSFormProResponse.allPages);
1962
1963					if (typeof RSFormProResponse.allPages !== 'undefined')
1964					{
1965						page = parseInt(RSFormProResponse.currentPage) - 1;
1966						totalPages = parseInt(RSFormProResponse.allPages);
1967						if (changePageHTML5Errors)
1968						{
1969							page = page > errorOnPage ? errorOnPage : page;
1970						}
1971					}
1972					else
1973					{
1974						if (changePageHTML5Errors)
1975						{
1976							page = errorOnPage;
1977							totalPages = totalJSDetectedPages;
1978						}
1979					}
1980
1981					RSFormPro.Pages.change(formId, page, totalPages, false);
1982				}
1983
1984				if (typeof ajaxExtraValidationScript[formId] === 'function')
1985				{
1986					// rewrite the response so that all the error components are added (that includes HTML5 fields)
1987					if (errorComponents.length)
1988					{
1989						response[1] = errorComponents.join();
1990					}
1991
1992					ajaxExtraValidationScript[formId]('afterSend', formId, {'url': url, 'params': RSFormPro.Ajax.Params, 'response': response, 'parentErrorClass': errorClasses.parent, 'fieldErrorClass': errorClasses.field, 'json': RSFormProResponse});
1993				}
1994				
1995				if (success === false)
1996				{
1997					// The submits must be clickable again
1998					for (i = 0; i < submits.length; i++)
1999					{
2000						submits[i].disabled = false;
2001					}
2002
2003					try
2004					{
2005						if (typeof page === 'undefined' || page == 0)
2006						{
2007							RSFormPro.callbacks.runCallback(formId, 'afterValidationFailed'); // callback functions if validation fails when form is submitted
2008						}
2009						else
2010						{
2011							RSFormPro.callbacks.runCallback(formId, 'nextPageFailed'); // callback functions if validation fails when a specific page of the form is checked
2012						}
2013
2014						if (document.getElementById('rsform_error_' + formId))
2015						{
2016							document.getElementById('rsform_error_' + formId).style.display = 'block';
2017						}
2018					}
2019					catch (err) { }
2020				}
2021				else
2022				{
2023					// Change the page if the validation passes
2024					if (page)
2025					{
2026						RSFormPro.Pages.change(formId, page, totalPages, false);
2027						// The submits must be clickable again
2028						for (i = 0; i < submits.length; i++)
2029						{
2030							submits[i].disabled = false;
2031						}
2032					}
2033					else
2034					{
2035						// the submit button has been pressed so we need to submit the form
2036						// if the submit button or any other element has the id submit the form.submit() function is overwritten
2037						RSFormPro.submitForm(form);
2038					}
2039
2040					try
2041					{
2042						if (typeof page === 'undefined' || page == 0)
2043						{
2044							RSFormPro.callbacks.runCallback(formId, 'afterValidationSuccess'); // callback functions if validation succeeds
2045						}
2046						else
2047						{
2048							RSFormPro.callbacks.runCallback(formId, 'nextPageSuccess'); // callback functions if validation succeeds when a specific page of the form is checked
2049						}
2050
2051						if (document.getElementById('rsform_error_' + formId))
2052						{
2053							document.getElementById('rsform_error_' + formId).style.display = 'none';
2054						}
2055					}
2056					catch (err) { }
2057				}
2058
2059				return success;
2060			}
2061		};
2062
2063		return false;
2064	},
2065	overrideSubmit: function(formId, validationParams, disableSubmitButton) {
2066        var form = RSFormPro.getForm(formId);
2067        var submitElement = RSFormPro.getElementByType(formId, 'submit');
2068		var i, j;
2069        for (i = 0; i < submitElement.length; i++) {
2070			if (RSFormProUtils.hasClass(submitElement[i],'rsform-submit-button')) {
2071				RSFormProUtils.addEvent(submitElement[i],'click', (function(event) {
2072					event.preventDefault();
2073					RSClickedSubmitElement = this;
2074					if (disableSubmitButton) {
2075						for (j = 0; j < submitElement.length; j++) {
2076							submitElement[j].setAttribute('data-disableonsubmit','1');
2077						}
2078					}
2079
2080					RSFormPro.Ajax.validate(form, undefined, validationParams);
2081				}));
2082			}
2083		}
2084	}
2085};
2086
2087RSFormPro.validationError = function(type, message) {
2088	this.type = type;
2089	this.message = message;
2090};
2091
2092RSFormPro.validationError.prototype.toString = function() {
2093	return this.type;
2094};
2095
2096RSFormPro.callbacks = {
2097	allCallbacks: {},
2098	
2099	addCallback: function(formId, callbackName, args) {
2100		var base = RSFormPro.callbacks;
2101		
2102		if (typeof base.allCallbacks[formId] == 'undefined') {
2103			base.allCallbacks[formId] = {}
2104		}
2105		
2106		if (typeof base.allCallbacks[formId][callbackName] == 'undefined') {
2107			base.allCallbacks[formId][callbackName] = [];
2108		}
2109		
2110		base.allCallbacks[formId][callbackName].push(args);
2111	},
2112	
2113	runCallback: function(formId, callbackName) {
2114		var base = RSFormPro.callbacks;
2115		if (typeof base.allCallbacks[formId] != 'undefined' && typeof base.allCallbacks[formId][callbackName] != 'undefined' && base.allCallbacks[formId][callbackName].length > 0) {
2116			for (var i = 0; i < base.allCallbacks[formId][callbackName].length; i++) {
2117				var args = base.allCallbacks[formId][callbackName][i];
2118				var functionName = args[0];
2119				
2120				var functionArgs =  [];
2121				for (var j = 1; j < args.length; j++) {
2122					functionArgs.push(args[j]);
2123				}
2124				
2125				// execute the callback function set for this trigger
2126				functionName.apply(self, functionArgs);
2127			}
2128		}
2129	}
2130};
2131
2132/* Translations */
2133
2134RSFormPro.Translations = {
2135	translations: {},
2136	commonTranslations: {},
2137
2138	add: function(formId, name, key, translation) {
2139		if (typeof this.translations[formId + '-' + name] !== 'object')
2140		{
2141			this.translations[formId + '-' + name] = {};
2142		}
2143
2144		this.translations[formId + '-' + name][key] = translation;
2145	},
2146
2147	translate: function(formId, name, key) {
2148		if (typeof this.translations[formId + '-' + name][key] == 'string')
2149		{
2150			return this.translations[formId + '-' + name][key];
2151		}
2152
2153		return key;
2154	},
2155
2156	addCommonTranslation: function(key, translation) {
2157		this.commonTranslations[key] = translation;
2158	},
2159
2160	commonTranslate: function(key) {
2161		if (typeof this.commonTranslations[key] == 'string')
2162		{
2163			return this.commonTranslations[key];
2164		}
2165
2166		return key;
2167	}
2168};
2169
2170/* Helper functions */
2171
2172var RSFormProUtils = {
2173	addEvent: function(obj, evType, fn) {
2174		if (obj.addEventListener)
2175		{
2176			obj.addEventListener(evType, fn, false);
2177			return true;
2178		}
2179		else if (obj.attachEvent)
2180		{
2181			var r = obj.attachEvent("on"+evType, fn);
2182			return r;
2183		}
2184		else
2185		{
2186			return false;
2187		}
2188	},
2189	hasClass: function (el, name) {
2190		return new RegExp('(\\s|^)' + name + '(\\s|$)').test(el.className);
2191	},
2192	addClass: function(el, name) {
2193		if (!RSFormProUtils.hasClass(el, name)) {
2194			el.className += (el.className ? ' ' : '') + name;
2195		}
2196	},
2197	removeClass: function(el, name) {
2198		if (RSFormProUtils.hasClass(el, name)) {
2199			el.className = el.className.replace(new RegExp('(\\s|^)' + name + '(\\s|$)'),' ').replace(/^\s+|\s+$/g, '');
2200		}
2201	},
2202	setDisplay: function (items, value) {
2203		if (!items || !items.length) {
2204			return false;
2205		}
2206
2207		for (var i = 0; i < items.length; i++) {
2208			if (!items[i]) {
2209				continue;
2210			}
2211
2212			if (!RSFormPro.usePositioning) {
2213				items[i].style.display = value;
2214			} else {
2215				value === 'none' ? RSFormProUtils.addClass(items[i], 'formHidden') : RSFormProUtils.removeClass(items[i], 'formHidden');
2216			}
2217		}
2218	},
2219	setAttr: function (items, attr, value) {
2220        for (var i = 0; i < items.length; i++) {
2221            items[i].setAttribute(attr, value);
2222        }
2223	},
2224    remAttr: function (items, attr) {
2225        for (var i = 0; i < items.length; i++) {
2226            items[i].removeAttribute(attr);
2227        }
2228    },
2229	getChecked: function (items) {
2230		var elements = [];
2231		var element, tagName;
2232        for (var i = 0; i < items.length; i++) {
2233        	element = items[i];
2234            tagName = element.tagName || element.nodeName;
2235
2236            if (tagName == 'INPUT' && element.type && element.type.toUpperCase() == 'CHECKBOX' && element.checked == true) {
2237				elements.push(element);
2238			}
2239        }
2240
2241        return elements;
2242	},
2243    getUnchecked: function (items) {
2244        var elements = [];
2245        var element, tagName;
2246        for (var i = 0; i < items.length; i++) {
2247            element = items[i];
2248            tagName = element.tagName || element.nodeName;
2249
2250            if (tagName == 'INPUT' && element.type && element.type.toUpperCase() == 'CHECKBOX' && !element.checked) {
2251                elements.push(element);
2252            }
2253        }
2254
2255        return elements;
2256    },
2257	getAlias: function(str) {
2258		str = str.replace(/\-/g, ' ');
2259
2260		if (!String.prototype.trim) {
2261			str = str.replace(/^\s+|\s+$/g, '');
2262		} else {
2263			str = str.trim();
2264		}
2265
2266		str = str.toLowerCase();
2267		str = str.replace(/(\s|[^A-Za-z0-9\-])+/g, '-');
2268		str = str.replace(/^\-+|\-+$/g, '');
2269
2270		return str;
2271	},
2272	getParents: function(a) {
2273		var els = [];
2274		while (a) {
2275			els.push(a);
2276			a = a.parentNode;
2277		}
2278		// Remove our own element
2279		if (els.length > 0)
2280		{
2281			els.shift()
2282		}
2283
2284		return els;
2285	},
2286	getElementsByClassName: function (className, tag, elm) {
2287		if (document.getElementsByClassName) {
2288			getElementsByClassName = function (className, tag, elm) {
2289				elm = elm || document;
2290				var elements = elm.getElementsByClassName(className),
2291					nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
2292					returnElements = [],
2293					current;
2294				for(var i=0, il=elements.length; i<il; i+=1){
2295					current = elements[i];
2296					if(!nodeName || nodeName.test(current.nodeName)) {
2297						returnElements.push(current);
2298					}
2299				}
2300				return returnElements;
2301			};
2302		} else if (document.evaluate) {
2303			getElementsByClassName = function (className, tag, elm) {
2304				tag = tag || "*";
2305				elm = elm || document;
2306				var classes = className.split(" "),
2307					classesToCheck = "",
2308					xhtmlNamespace = "http://www.w3.org/1999/xhtml",
2309					namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
2310					returnElements = [],
2311					elements,
2312					node;
2313				for(var j=0, jl=classes.length; j<jl; j+=1){
2314					classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
2315				}
2316				try	{
2317					elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
2318				}
2319				catch (e) {
2320					elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
2321				}
2322				while ((node = elements.iterateNext())) {
2323					returnElements.push(node);
2324				}
2325				return returnElements;
2326			};
2327		} else {
2328			getElementsByClassName = function (className, tag, elm) {
2329				tag = tag || "*";
2330				elm = elm || document;
2331				var classes = className.split(" "),
2332					classesToCheck = [],
2333					elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
2334					current,
2335					returnElements = [],
2336					match;
2337				for(var k=0, kl=classes.length; k<kl; k+=1){
2338					classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
2339				}
2340				for(var l=0, ll=elements.length; l<ll; l+=1){
2341					current = elements[l];
2342					match = false;
2343					for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
2344						match = classesToCheck[m].test(current.className);
2345						if (!match) {
2346							break;
2347						}
2348					}
2349					if (match) {
2350						returnElements.push(current);
2351					}
2352				}
2353				return returnElements;
2354			};
2355		}
2356
2357		return getElementsByClassName(className, tag, elm);
2358	},
2359
2360	/*!
2361	**  sprintf.js -- POSIX sprintf(3)-style String Formatting for JavaScript
2362	**  Copyright (c) 2006-2019 Dr. Ralf S. Engelschall <[email protected]>
2363	**  Partly based on Public Domain code by Jan Moesen <http://jan.moesen.nu/>
2364	**
2365	**  Permission is hereby granted, free of charge, to any person obtaining
2366	**  a copy of this software and associated documentation files (the
2367	**  "Software"), to deal in the Software without restriction, including
2368	**  without limitation the rights to use, copy, modify, merge, publish,
2369	**  distribute, sublicense, and/or sell copies of the Software, and to
2370	**  permit persons to whom the Software is furnished to do so, subject to
2371	**  the following conditions:
2372	**
2373	**  The above copyright notice and this permission notice shall be included
2374	**  in all copies or substantial portions of the Software.
2375	**
2376	**  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2377	**  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2378	**  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2379	**  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
2380	**  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2381	**  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2382	**  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2383	*/
2384	sprintf: function () {
2385		/*  argument sanity checking  */
2386		if (!arguments || arguments.length < 1)
2387			throw new Error("sprintf: ERROR: not enough arguments");
2388
2389		/*  initialize processing queue  */
2390		var argumentnum = 0;
2391		var done = "", todo = arguments[argumentnum++];
2392
2393		/*  parse still to be done format string  */
2394		var m;
2395		while ((m = /^([^%]*)%(?:(\d+)\$|\((.*?)\))?([#0 +'-]+)?(\*|\d+)?(\.\*|\.\d+)?([%diouxXfFeEcs])((?:.|[\r\n])*)$/.exec(todo))) {
2396			var pProlog    = m[1],
2397				pAccessD   = m[2],
2398				pAccessN   = m[3],
2399				pFlags     = m[4],
2400				pMinLength = m[5],
2401				pPrecision = m[6],
2402				pType      = m[7],
2403				pEpilog    = m[8];
2404
2405			/*  determine substitution  */
2406			var subst;
2407			if (pType === "%")
2408			/*  special case: escaped percent character  */
2409				subst = "%";
2410			else {
2411				/*  parse padding and justify aspects of flags  */
2412				var padWith = " ";
2413				var justifyRight = true;
2414				if (pFlags) {
2415					if (pFlags.indexOf("0") >= 0)
2416						padWith = "0";
2417					if (pFlags.indexOf("-") >= 0) {
2418						padWith = " ";
2419						justifyRight = false;
2420					}
2421				}
2422				else
2423					pFlags = "";
2424
2425				/*  determine minimum length  */
2426				var access;
2427				var minLength = -1;
2428				if (pMinLength) {
2429					if (pMinLength === "*") {
2430						access = argumentnum++;
2431						if (access >= arguments.length)
2432							throw new Error("sprintf: ERROR: not enough arguments");
2433						minLength = arguments[access];
2434					}
2435					else
2436						minLength = parseInt(pMinLength, 10);
2437				}
2438
2439				/*  determine precision  */
2440				var precision = -1;
2441				if (pPrecision) {
2442					if (pPrecision === ".*") {
2443						access = argumentnum++;
2444						if (access >= arguments.length)
2445							throw new Error("sprintf: ERROR: not enough arguments");
2446						precision = arguments[access];
2447					}
2448					else
2449						precision = parseInt(pPrecision.substring(1), 10);
2450				}
2451
2452				/*  determine how to fetch argument  */
2453				access = argumentnum++;
2454				if (pAccessD) {
2455					access = parseInt(pAccessD, 10);
2456					if (access >= arguments.length)
2457						throw new Error("sprintf: ERROR: not enough arguments");
2458					subst = arguments[access];
2459				}
2460				else if (pAccessN) {
2461					if (typeof arguments[1] !== "object")
2462						throw new Error("sprintf: ERROR: invalid non-object arguments for named argument");
2463					subst = arguments[1][pAccessN];
2464					if (typeof subst === "undefined")
2465						throw new Error("sprintf: ERROR: invalid undefined value for named argument");
2466				}
2467				else {
2468					if (access >= arguments.length)
2469						throw new Error("sprintf: ERROR: not enough arguments");
2470					subst = arguments[access];
2471				}
2472
2473				/*  dispatch into expansions according to type  */
2474				var prefix = "";
2475				switch (pType) {
2476					/*  decimal number  */
2477					case "d":
2478					case "i":
2479						if (typeof subst !== "number")
2480							subst = 0;
2481						subst = subst.toString(10);
2482						if (pFlags.indexOf("#") >= 0 && subst >= 0)
2483							subst = "+" + subst;
2484						if (pFlags.indexOf(" ") >= 0 && subst >= 0)
2485							subst = " " + subst;
2486						break;
2487
2488					/*  binary number  */
2489					case "b":
2490						if (typeof subst !== "number")
2491							subst = 0;
2492						subst = subst.toString(2);
2493						break;
2494
2495					/*  octal number  */
2496					case "o":
2497						if (typeof subst !== "number")
2498							subst = 0;
2499						subst = subst.toString(8);
2500						break;
2501
2502					/*  unsigned decimal number  */
2503					case "u":
2504						if (typeof subst !== "number")
2505							subst = 0;
2506						subst = Math.abs(subst);
2507						subst = subst.toString(10);
2508						break;
2509
2510					/*  (lower-case) hexadecimal number  */
2511					case "x":
2512						if (typeof subst !== "number")
2513							subst = 0;
2514						subst = subst.toString(16).toLowerCase();
2515						if (pFlags.indexOf("#") >= 0)
2516							prefix = "0x";
2517						break;
2518
2519					/*  (upper-case) hexadecimal number  */
2520					case "X":
2521						if (typeof subst !== "number")
2522							subst = 0;
2523						subst = subst.toString(16).toUpperCase();
2524						if (pFlags.indexOf("#") >= 0)
2525							prefix = "0X";
2526						break;
2527
2528					/*  (lower/upper-case) floating point number (fixed precision)  */
2529					case "f":
2530					case "F":
2531						if (typeof subst !== "number")
2532							subst = 0.0;
2533						subst = 0.0 + subst;
2534						if (precision > -1) {
2535							if (subst.toFixed)
2536								subst = subst.toFixed(precision);
2537							else {
2538								subst = (Math.round(subst * Math.pow(10, precision)) / Math.pow(10, precision));
2539								subst += "0000000000";
2540								subst = subst.substr(0, subst.indexOf(".") + precision + 1);
2541							}
2542						}
2543						subst = "" + subst;
2544						if (pFlags.indexOf("'") >= 0) {
2545							var k = 0;
2546							for (var i = (subst.length - 1) - 3; i >= 0; i -= 3) {
2547								subst = subst.substring(0, i) + (k === 0 ? "." : ",") + subst.substring(i);
2548								k = (k + 1) % 2;
2549							}
2550						}
2551						break;
2552
2553					/*  (lower/upper-case) floating point number (exponential-based precision)  */
2554					case "e":
2555					case "E":
2556						if (typeof subst !== "number")
2557							subst = 0.0;
2558						subst = 0.0 + subst;
2559						if (precision > -1) {
2560							if (subst.toExponential)
2561								subst = subst.toExponential(precision);
2562							else
2563								throw new Error("sprintf: ERROR: toExponential() method not supported");
2564						}
2565						subst = "" + subst;
2566						if (pType === "E")
2567							subst = subst.replace(/e\+/, "E+");
2568						break;
2569
2570					/*  single character  */
2571					case "c":
2572						if (typeof subst !== "number")
2573							subst = 0;
2574						subst = String.fromCharCode(subst);
2575						break;
2576
2577					/*  string  */
2578					case "s":
2579						if (typeof subst !== "string")
2580							subst = String(subst);
2581						if (precision > -1)
2582							subst = subst.substr(0, precision);
2583						break;
2584					default:
2585						throw new Error("sprintf: ERROR: invalid conversion character \"" + pType + "\"");
2586				}
2587
2588				/*  apply optional padding  */
2589				var padding = minLength - subst.toString().length - prefix.toString().length;
2590				if (padding > 0) {
2591					var arrTmp = new Array(padding + 1);
2592					if (justifyRight)
2593						subst = arrTmp.join(padWith) + subst;
2594					else
2595						subst = subst + arrTmp.join(padWith);
2596				}
2597
2598				/*  add optional prefix  */
2599				subst = prefix + subst;
2600			}
2601
2602			/*  update the processing queue  */
2603			done = done + pProlog + subst;
2604			todo = pEpilog;
2605		}
2606
2607		/*  return finally formatted string  */
2608		return (done + todo);
2609	}
2610};
2611
2612function isset() {
2613  // http://kevin.vanzonneveld.net
2614  // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
2615  // +   improved by: FremyCompany
2616  // +   improved by: Onno Marsman
2617  // +   improved by: Rafał Kukawski
2618  // *     example 1: isset( undefined, true);
2619  // *     returns 1: false
2620  // *     example 2: isset( 'Kevin van Zonneveld' );
2621  // *     returns 2: true
2622  var a = arguments,
2623    l = a.length,
2624    i = 0,
2625    undef;
2626
2627  if (l === 0) {
2628    throw new Error('Empty isset');
2629  }
2630
2631  while (i !== l) {
2632    if (a[i] === undef || a[i] === null) {
2633      return false;
2634    }
2635    i++;
2636  }
2637  return true;
2638}
2639
2640/* Legacy functions */
2641
2642function rsfp_geolocation(term, id, mapid,  map, marker, geocoder, type) {
2643	return RSFormPro.initGeoLocation(term, id, mapid, map, marker, geocoder, type);
2644}
2645
2646function refreshCaptcha(componentId, captchaPath) {
2647	return RSFormPro.refreshCaptcha(componentId, captchaPath);
2648}
2649
2650function number_format(number, decimals, dec_point, thousands_sep) {
2651	return RSFormPro.formatNumber(number, decimals, dec_point, thousands_sep);
2652}
2653
2654function rsfp_toNumber(number, decimal, thousands, decimals) {
2655	return RSFormPro.toNumber(number, decimal, thousands, decimals);
2656}
2657
2658function rsfp_getForm(formId) {
2659	return RSFormPro.getForm(formId);
2660}
2661
2662function rsfp_getValue(formId, name) {
2663	return RSFormPro.getValue(formId, name);
2664}
2665
2666function rsfp_verifyChecked(formId, name, value) {
2667	return RSFormPro.isChecked(formId, name, value);
2668}
2669
2670function rsfp_getBlock(formId, block) {
2671	return RSFormPro.getBlock(formId, block);
2672}
2673
2674function rsfp_getFieldsByName(formId, name) {
2675	return RSFormPro.getFieldsByName(formId, name);
2676}
2677
2678function rsfp_addEvent(obj, evType, fn) {
2679	return RSFormProUtils.addEvent(obj, evType, fn);
2680}
2681
2682function rsfp_setDisplay(items, value) {
2683	return RSFormProUtils.setDisplay(items, value);
2684}
2685
2686function stringURLSafe(str) {
2687	return RSFormProUtils.getAlias(str);
2688}
2689
2690function rsfp_changePage(formId, page, totalPages, validate, errorClasses) {
2691	return RSFormPro.Pages.change(formId, page, totalPages, validate, errorClasses);
2692}
2693
2694function rsfp_hidePage(thePage) {
2695	return RSFormPro.Pages.hide(thePage);
2696}
2697
2698function rsfp_showPage(thePage) {
2699	return RSFormPro.Pages.show(thePage);
2700}
2701
2702function rsfp_checkValidDate(fieldName) {
2703	return RSFormPro.disableInvalidDates(fieldName);
2704}
2705
2706function rsfp_addCondition(formId, name, fnCondition) {
2707	return RSFormPro.Conditions.add(formId, name, fnCondition);
2708}
2709
2710function rsfp_runAllConditions(formId) {
2711	return RSFormPro.Conditions.runAll(formId);
2712}
2713
2714function rsfp_setCalculationsEvents(formId, fields) {
2715	return RSFormPro.Calculations.addEvents(formId, fields);
2716}
2717
2718function getElementsByClassName(className, tag, elm) {
2719	return RSFormProUtils.getElementsByClassName(className, tag, elm);
2720}
2721
2722function buildXmlHttp() {
2723	return RSFormPro.Ajax.getXHR();
2724}
2725
2726function ajaxDisplayValidationErrors(formComponents, task, formId, data) {
2727	return RSFormPro.Ajax.displayValidationErrors(formComponents, task, formId, data);
2728}
2729
2730function ajaxValidation(form, page, errorClasses) {
2731	return RSFormPro.Ajax.validate(form, page, errorClasses);
2732}

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