PageSourceSearch

https://economymiddleeast.com/wp-content/plugins/ws-form-pro/public/js/ws-form-public-captcha.js?ver=1.12.11

js economymiddleeast.com collected 2026-09-24 09:05:33 UTC 52,973 bytes, 1,639 lines download raw bytes

1(function($) {
2
3	'use strict';
4
5	// Adds recaptcha elements
6	$.WS_Form.prototype.form_recaptcha = function() {
7
8		var ws_this = this;
9
10		// Get reCAPTCHA objects
11		var recaptcha_objects = $('[data-recaptcha]', this.form_canvas_obj);
12		var recaptcha_objects_count = recaptcha_objects.length;
13		if(!recaptcha_objects_count) { return false;}
14
15		// Should header script be loaded
16		if(!$('#wsf-recaptcha-script-head').length) {
17
18			var recaptcha_script_head = '<script id="wsf-recaptcha-script-head">';
19			recaptcha_script_head += 'var wsf_recaptcha_loaded = false;';
20			recaptcha_script_head += 'function wsf_recaptcha_onload() {';
21			recaptcha_script_head += 'wsf_recaptcha_loaded = true;';
22			recaptcha_script_head += '}';
23			recaptcha_script_head += '</script>';
24
25			$('head').append(recaptcha_script_head);
26		}
27
28		// Work out what type of reCAPTCHA should load
29		var recaptcha_version = ($('[data-recaptcha-type="v3_default"]', this.form_canvas_obj).length) ? 3 : 2;
30
31		// Should reCAPTCHA script be called?
32		if(!window['grecaptcha'] && !$('#wsf-recaptcha-script-body').length) {
33
34			switch(recaptcha_version) {
35
36				case 2 :
37
38					var recaptcha_script_body = '
vendor: 150 bytes, line 38
38<script id="wsf-recaptcha-script-body" src="https://www.google.com/recaptcha/api.js?onload=wsf_recaptcha_onload&render=explicit" async defer></script>
38';
39					break;
40
41				case 3 :
42
43					var recaptcha_site_key = $('[data-recaptcha-type="v3_default"]', this.form_canvas_obj).eq(0).attr('data-site-key');
44					var recaptcha_script_body = '
vendor: 156 bytes, line 44
44<script id="wsf-recaptcha-script-body" src="https://www.google.com/recaptcha/api.js?onload=wsf_recaptcha_onload&render=' + recaptcha_site_key + '"></script>
44';
45					break;
46			}
47			$('body').append(recaptcha_script_body);
48
49		} else if(window['grecaptcha']) {
50
51			window.wsf_recaptcha_loaded = true;
52		}
53
54		// Reset reCAPTCHA arrays
55		this.recaptchas = [];
56		this.recaptchas_v2_default = [];
57		this.recaptchas_v2_invisible = [];
58		this.recaptchas_v3_default = [];
59
60		recaptcha_objects.each(function() {
61
62			// Name
63			var name = $(this).attr('name');
64
65			// ID
66			var recaptcha_id = $(this).attr('id');
67			if((recaptcha_id === undefined) || (recaptcha_id == '')) { return false; }
68
69			// Site key
70			var recaptcha_site_key = $(this).attr('data-site-key');
71			if((recaptcha_site_key === undefined) || (recaptcha_site_key == '')) { return false; }
72
73			// Recaptcha type
74			var recaptcha_recaptcha_type = $(this).attr('data-recaptcha-type');
75			if((recaptcha_recaptcha_type === undefined) || (['v2_default', 'v2_invisible', 'v3_default'].indexOf(recaptcha_recaptcha_type) == -1)) { recaptcha_recaptcha_type = 'default'; }
76
77			// Type
78			var recaptcha_type = $(this).attr('data-type');
79			if((recaptcha_type === undefined) || (['image', 'audio'].indexOf(recaptcha_type) == -1)) { recaptcha_type = 'image'; }
80
81			// Language (Optional)
82			var recaptcha_language = $(this).attr('data-language');
83			if(recaptcha_language === undefined) { recaptcha_language = ''; }
84
85			// Action
86			var recaptcha_action = $(this).attr('data-recaptcha-action');
87			if((recaptcha_action === undefined) || (recaptcha_action == '')) { recaptcha_action = 'ws_form_loaded_#form_id'; }
88
89			switch(recaptcha_recaptcha_type) {
90
91				case 'v2_default' :
92
93					// Size
94					var recaptcha_size = $(this).attr('data-size');
95					if((recaptcha_size === undefined) || (['normal', 'compact', 'invisible'].indexOf(recaptcha_size) == -1)) { recaptcha_size = 'normal'; }
96
97					// Theme (Default only)
98					var recaptcha_theme = $(this).attr('data-theme');
99					if((recaptcha_theme === undefined) || (['light', 'dark'].indexOf(recaptcha_theme) == -1)) { recaptcha_theme = 'light'; }
100
101					// Classes
102					var class_recaptcha_invalid_label_array = ws_this.get_field_value_fallback('recaptcha', false, 'class_invalid_label', []);
103					var class_recaptcha_invalid_field_array = ws_this.get_field_value_fallback('recaptcha', false, 'class_invalid_field', []);
104					var class_recaptcha_invalid_invalid_feedback_array = ws_this.get_field_value_fallback('recaptcha', false, 'class_invalid_invalid_feedback', []);
105					var class_recaptcha_valid_label_array = ws_this.get_field_value_fallback('recaptcha', false, 'class_valid_label', []);
106					var class_recaptcha_valid_field_array = ws_this.get_field_value_fallback('recaptcha', false, 'class_valid_field', []);
107					var class_recaptcha_valid_invalid_feedback_array = ws_this.get_field_value_fallback('recaptcha', false, 'class_valid_invalid_feedback', []);
108
109					// Process recaptcha
110					var recaptcha_obj_field = $(this);
111					var recaptcha_obj_wrapper = recaptcha_obj_field.closest('[data-id]');
112					var recaptcha_obj_label = $('label', recaptcha_obj_wrapper);
113					var recaptcha_obj_invalid_feedback = $('#' + ws_this.form_id_prefix + 'invalid-feedback-' + recaptcha_id, recaptcha_obj_wrapper, ws_this.form_canvas_obj);
114
115					var config = {
116
117						'sitekey': recaptcha_site_key,
118						'type': recaptcha_type,
119						'theme': recaptcha_theme,
120						'size': recaptcha_size,
121
122						'callback': function(token) {
123
124							// Completed - Label
125							recaptcha_obj_label.addClass(class_recaptcha_valid_label_array.join(' '));
126							recaptcha_obj_label.removeClass(class_recaptcha_invalid_label_array.join(' '));
127
128							// Completed - Field
129							recaptcha_obj_field.addClass(class_recaptcha_valid_field_array.join(' '));
130							recaptcha_obj_field.removeClass(class_recaptcha_invalid_field_array.join(' '));
131							recaptcha_obj_field.removeAttr('data-captcha-invalid');
132
133							// Completed - Feedback
134							recaptcha_obj_invalid_feedback.addClass(class_recaptcha_valid_invalid_feedback_array.join(' '));
135							recaptcha_obj_invalid_feedback.removeClass(class_recaptcha_invalid_invalid_feedback_array.join(' '));
136
137							// Run conditions
138							ws_this.recaptcha_conditions_run();
139
140							// Fire real time form validation
141							ws_this.form_validate_real_time_process(false, false);
142						},
143
144						'expired-callback': function() {
145
146							// Empty - Label
147							recaptcha_obj_label.addClass(class_recaptcha_invalid_label_array.join(' '));
148							recaptcha_obj_label.removeClass(class_recaptcha_valid_label_array.join(' '));
149
150							// Empty - Field
151							recaptcha_obj_field.addClass(class_recaptcha_invalid_field_array.join(' '));
152							recaptcha_obj_field.removeClass(class_recaptcha_valid_field_array.join(' '));
153							recaptcha_obj_field.attr('data-captcha-invalid', '');
154
155							// Empty - Feedback
156							recaptcha_obj_invalid_feedback.addClass(class_recaptcha_invalid_invalid_feedback_array.join(' '));
157							recaptcha_obj_invalid_feedback.removeClass(class_recaptcha_valid_invalid_feedback_array.join(' '));
158
159							// Run conditions
160							ws_this.recaptcha_conditions_run();
161
162							// Fire real time form validation
163							ws_this.form_validate_real_time_process(false, false);
164
165						},
166
167						'error-callback': function() {
168
169							// Empty - Label
170							recaptcha_obj_label.addClass(class_recaptcha_invalid_label_array.join(' '));
171							recaptcha_obj_label.removeClass(class_recaptcha_valid_label_array.join(' '));
172
173							// Empty - Field
174							recaptcha_obj_field.addClass(class_recaptcha_invalid_field_array.join(' '));
175							recaptcha_obj_field.removeClass(class_recaptcha_valid_field_array.join(' '));
176							recaptcha_obj_field.attr('data-captcha-invalid', '');
177
178							// Empty - Feedback
179							recaptcha_obj_invalid_feedback.addClass(class_recaptcha_invalid_invalid_feedback_array.join(' '));
180							recaptcha_obj_invalid_feedback.removeClass(class_recaptcha_valid_invalid_feedback_array.join(' '));
181
182							// Run conditions
183							ws_this.recaptcha_conditions_run();
184
185							// Fire real time form validation
186							ws_this.form_validate_real_time_process(false, false);
187						}
188					};
189
190					if(recaptcha_language != '') { config.hl = recaptcha_language; }
191
192					// Build recaptcha object
193					var recaptcha = {
194
195						'id': false,
196						'recaptcha_site_key': recaptcha_site_key,
197						'name': name,
198						'recaptcha_id': recaptcha_id,
199						'config': config,
200						'recaptcha_recaptcha_type': recaptcha_recaptcha_type,
201						'type': 'v2_default'
202					};
203
204					// Add to recaptcha arrays
205					ws_this.recaptchas_v2_default.push(recaptcha);
206
207					ws_this.recaptcha_process(recaptcha);
208
209					break;
210
211				case 'v2_invisible' :
212
213					// Badge (Invisible only)
214					var recaptcha_badge = $(this).attr('data-badge');
215					if((recaptcha_badge === undefined) || (['bottomright', 'bottomleft', 'inline'].indexOf(recaptcha_badge) == -1)) { recaptcha_badge = 'bottomright'; }
216
217					// Process recaptcha
218					var config = {
219
220						'sitekey': recaptcha_site_key,
221						'badge': recaptcha_badge,
222						'size': 'invisible',
223
224						'callback': function() {
225
226							// Run conditions
227							ws_this.recaptcha_conditions_run();
228
229							// Fire real time form validation
230							ws_this.form_validate_real_time_process(false, false);
231
232							// Form validated
233							ws_this.form_post('submit');
234						},
235
236						'expired-callback': function() {
237
238							// Run conditions
239							ws_this.recaptcha_conditions_run();
240
241							// Fire real time form validation
242							ws_this.form_validate_real_time_process(false, false);
243
244						},
245
246						'error-callback': function() {
247
248							// Throw error
249							ws_this.error('error_recaptcha_v2_invisible');
250
251							// Run conditions
252							ws_this.recaptcha_conditions_run();
253
254							// Fire real time form validation
255							ws_this.form_validate_real_time_process(false, false);
256						}
257					};
258
259					if(recaptcha_language != '') { config.hl = recaptcha_language; }
260
261					// Build recaptcha object
262					var recaptcha = {
263
264						'id': false,
265						'recaptcha_site_key': recaptcha_site_key,
266						'name': name,
267						'recaptcha_id': recaptcha_id,
268						'config': config,
269						'recaptcha_recaptcha_type': recaptcha_recaptcha_type,
270						'type': 'v2_invisible'
271					};
272
273					// Add to recaptcha arrays
274					ws_this.recaptchas_v2_invisible.push(recaptcha);
275
276					// Process recaptcha
277					ws_this.recaptcha_process(recaptcha);
278
279					break;				
280
281				case 'v3_default' :
282
283					// Parse recaptcha_action
284					recaptcha_action = ws_this.parse_variables_process(recaptcha_action).output;
285
286					// Config
287					var config = {'action': recaptcha_action};
288
289					// Build recaptcha object
290					var recaptcha = {
291
292						'id': false,
293						'recaptcha_site_key': recaptcha_site_key,
294						'name': name,
295						'recaptcha_id': recaptcha_id,
296						'config': config,
297						'recaptcha_recaptcha_type': recaptcha_recaptcha_type,
298						'type': 'v3_default'
299					};
300
301					// Add to recaptcha arrays
302					ws_this.recaptchas_v3_default.push(recaptcha)
303
304					// Process recaptcha
305					ws_this.recaptcha_process(recaptcha);
306
307					break;
308			}
309		});
310	}
311
312	// reCAPTCHA run conditions
313	$.WS_Form.prototype.recaptcha_conditions_run = function() {
314
315		// Run conditions
316		for(var recaptcha_conditions_index in this.recaptchas_conditions) {
317
318			if(!this.recaptchas_conditions.hasOwnProperty(recaptcha_conditions_index)) { continue; }
319
320			this.recaptchas_conditions[recaptcha_conditions_index]();
321		}
322	}
323
324	// Wait until reCAPTCHA loaded, then process
325	$.WS_Form.prototype.recaptcha_process = function(recaptcha, total_ms_start) {
326
327		var ws_this = this;
328
329		// Timeout check
330		if(typeof total_ms_start === 'undefined') { total_ms_start = new Date().getTime(); }
331		if((new Date().getTime() - total_ms_start) > this.timeout_recaptcha) {
332
333			this.error('error_timeout_recaptcha');
334			return false;
335		}
336
337		// Check to see if reCAPTCHA loaded
338		if(
339			wsf_recaptcha_loaded &&
340			$('#' + recaptcha.recaptcha_id).length
341		) {
342			switch(recaptcha.type) {
343
344				case 'v2_default' :
345
346					var id = grecaptcha.render(recaptcha.recaptcha_id, recaptcha.config);
347					recaptcha.id = id;
348					this.form_validate_real_time_process(false, false);
349					break;
350
351				case 'v2_invisible' :
352
353					var id = grecaptcha.render(recaptcha.recaptcha_id, recaptcha.config);
354					recaptcha.id = id;
355					this.form_validate_real_time_process(false, false);
356					break;
357
358				case 'v3_default' :
359
360					// Add hidden field
361					if(!$('[name="g-recaptcha-response"]', ws_this.form_canvas_obj).length) {
362
363						ws_this.form_add_hidden_input('g-recaptcha-response');
364					}
365
366					break;
367			}
368
369			// Add to reCaptcha array
370			this.recaptchas.push(recaptcha);
371
372			// Run conditions
373			this.recaptcha_conditions_run();
374
375		} else {
376
377			var ws_this = this;
378			setTimeout(function() { ws_this.recaptcha_process(recaptcha, total_ms_start); }, this.timeout_interval);
379		}
380	}
381
382	// reCAPTCHA V2 invisible execute
383	$.WS_Form.prototype.recaptcha_v2_invisible_execute = function() {
384
385		var ws_this = this;		
386
387		// Run through each hidden captcha for this form
388		for(var recaptchas_v2_invisible_index in this.recaptchas_v2_invisible) {
389
390			if(!this.recaptchas_v2_invisible.hasOwnProperty(recaptchas_v2_invisible_index)) { continue; }
391
392			// Get ID
393			var recaptcha = this.recaptchas_v2_invisible[recaptchas_v2_invisible_index];
394			var recaptcha_id = recaptcha.id;
395
396			// Execute
397			grecaptcha.execute(recaptcha_id);
398
399			// Fire real time form validation
400			ws_this.form_validate_real_time_process(false, false);
401		}
402	}
403
404	// reCAPTCHA - Reset
405	$.WS_Form.prototype.recaptcha_reset = function() {
406
407		// Run through each reCAPTCHA for this form and reset it
408		for(var recaptchas_index in this.recaptchas) {
409
410			if(!this.recaptchas.hasOwnProperty(recaptchas_index)) { continue; }
411
412			// Get reCAPTCHA
413			var recaptcha = this.recaptchas[recaptchas_index];
414
415			// Reset
416			switch(recaptcha.recaptcha_recaptcha_type) {
417
418				case 'v3_default' :
419
420					// Reset V3 - Nothing to do
421					break;
422
423				default :
424
425					// Get ID
426					var recaptcha_id = recaptcha.id;
427
428					// Reset V2
429					if(recaptcha_id !== false) {
430
431						grecaptcha.reset(recaptcha_id);
432					}
433			}
434		}
435	}
436
437	// reCAPTCHA V2 invisible execute
438	$.WS_Form.prototype.recaptcha_v3_default_execute = function() {
439
440		var ws_this = this;		
441
442		// Run through each hidden captcha for this form
443		for(var recaptchas_v3_default_index in this.recaptchas_v3_default) {
444
445			if(!this.recaptchas_v3_default.hasOwnProperty(recaptchas_v3_default_index)) { continue; }
446
447			// Get recaptcha
448			var recaptcha = this.recaptchas_v3_default[recaptchas_v3_default_index];
449
450			// Execute
451			ws_this.recaptcha_v3_default_execute_single(recaptcha);
452		}
453	}
454
455	// reCAPTCHA - V3 - Execute - Single
456	$.WS_Form.prototype.recaptcha_v3_default_execute_single = function(recaptcha) {
457
458		var ws_this = this;
459
460		grecaptcha.execute(recaptcha.recaptcha_site_key, recaptcha.config).then(function(token){
461
462			// Update V3 token
463			$('[name="g-recaptcha-response"]', ws_this.form_canvas_obj).val(token);
464
465			// Fire real time form validation
466			ws_this.form_validate_real_time_process(false, false);
467
468			// Log
469			ws_this.log('log_recaptcha_v3_action_fired', recaptcha.config.action);
470			// Form validated
471			ws_this.form_post('submit');
472		});
473	}
474
475	// reCAPTCHA - Get response by name
476	$.WS_Form.prototype.recaptcha_get_response_by_name = function(name) {
477
478		// Run through each reCAPTCHA and look for name
479		for(var recaptchas_index in this.recaptchas) {
480
481			if(!this.recaptchas.hasOwnProperty(recaptchas_index)) { continue; }
482
483			var recaptcha = this.recaptchas[recaptchas_index];
484			var recaptcha_id = recaptcha.id;
485
486			// If name found, return response
487			if(
488				(recaptcha.name == name) &&
489				(recaptcha_id !== false)
490			) {
491				return grecaptcha.getResponse(recaptcha_id);
492			}
493		}
494
495		return '';
496	}
497
498	// Adds hcaptcha elements
499	$.WS_Form.prototype.form_hcaptcha = function() {
500
501		var ws_this = this;
502
503		// Get hCaptcha objects
504		var hcaptcha_objects = $('[data-hcaptcha]', this.form_canvas_obj);
505		var hcaptcha_objects_count = hcaptcha_objects.length;
506		if(!hcaptcha_objects_count) { return false;}
507
508		// Should header script be loaded
509		if(!$('#wsf-hcaptcha-script-head').length) {
510
511			var hcaptcha_script_head = '<script id="wsf-hcaptcha-script-head">';
512			hcaptcha_script_head += 'var wsf_hcaptcha_loaded = false;';
513			hcaptcha_script_head += 'function wsf_hcaptcha_onload() {';
514			hcaptcha_script_head += 'wsf_hcaptcha_loaded = true;';
515			hcaptcha_script_head += '}';
516			hcaptcha_script_head += '</script>';
517
518			$('head').append(hcaptcha_script_head);
519		}
520
521		// Should hCaptcha script be called?
522		if(!window['hcaptcha'] && !$('#wsf-hcaptcha-script-body').length) {
523
524			var hcaptcha_script_body = '<script id="wsf-hcaptcha-script-body" src="https://js.hcaptcha.com/1/api.js?onload=wsf_hcaptcha_onload&render=explicit&recaptchacompat=off" async defer></script>';
525			$('body').append(hcaptcha_script_body);
526		}
527
528		// Reset hCaptcha arrays
529		this.hcaptchas = [];
530		this.hcaptchas_default = [];
531		this.hcaptchas_invisible = [];
532
533		hcaptcha_objects.each(function() {
534
535			// Name
536			var name = $(this).attr('name');
537
538			// ID
539			var hcaptcha_id = $(this).attr('id');
540			if((hcaptcha_id === undefined) || (hcaptcha_id == '')) { return false; }
541
542			// Site key
543			var hcaptcha_site_key = $(this).attr('data-site-key');
544			if((hcaptcha_site_key === undefined) || (hcaptcha_site_key == '')) { return false; }
545
546			// Type
547			var hcaptcha_type = $(this).attr('data-hcaptcha-type');
548			if((hcaptcha_type === undefined) || (['default', 'invisible'].indexOf(hcaptcha_type) == -1)) { hcaptcha_type = 'default'; }
549
550			// Language (Optional)
551			var hcaptcha_language = $(this).attr('data-language');
552			if(hcaptcha_language === undefined) { hcaptcha_language = ''; }
553
554			switch(hcaptcha_type) {
555
556				case 'default' :
557
558					// Size
559					var hcaptcha_size = $(this).attr('data-size');
560					if((hcaptcha_size === undefined) || (['normal', 'compact'].indexOf(hcaptcha_size) == -1)) { hcaptcha_size = 'normal'; }
561
562					// Theme (Default only)
563					var hcaptcha_theme = $(this).attr('data-theme');
564					if((hcaptcha_theme === undefined) || (['light', 'dark'].indexOf(hcaptcha_theme) == -1)) { hcaptcha_theme = 'light'; }
565
566					// Classes
567					var class_hcaptcha_invalid_label_array = ws_this.get_field_value_fallback('hcaptcha', false, 'class_invali
567d_label', []);
568					var class_hcaptcha_invalid_field_array = ws_this.get_field_value_fallback('hcaptcha', false, 'class_invalid_field', []);
569					var class_hcaptcha_invalid_invalid_feedback_array = ws_this.get_field_value_fallback('hcaptcha', false, 'class_invalid_invalid_feedback', []);
570					var class_hcaptcha_valid_label_array = ws_this.get_field_value_fallback('hcaptcha', false, 'class_valid_label', []);
571					var class_hcaptcha_valid_field_array = ws_this.get_field_value_fallback('hcaptcha', false, 'class_valid_field', []);
572					var class_hcaptcha_valid_invalid_feedback_array = ws_this.get_field_value_fallback('hcaptcha', false, 'class_valid_invalid_feedback', []);
573
574					// Process hcaptcha
575					var hcaptcha_obj_field = $(this);
576					var hcaptcha_obj_wrapper = hcaptcha_obj_field.closest('[data-id]');
577					var hcaptcha_obj_label = $('label', hcaptcha_obj_wrapper);
578					var hcaptcha_obj_invalid_feedback = $('#' + ws_this.form_id_prefix + 'invalid-feedback-' + hcaptcha_id, hcaptcha_obj_wrapper, ws_this.form_canvas_obj);
579
580					var config = {
581
582						'sitekey': hcaptcha_site_key,
583						'type': hcaptcha_type,
584						'theme': hcaptcha_theme,
585						'size': hcaptcha_size,
586
587						'callback': function(token) {
588
589							// Completed - Label
590							hcaptcha_obj_label.addClass(class_hcaptcha_valid_label_array.join(' '));
591							hcaptcha_obj_label.removeClass(class_hcaptcha_invalid_label_array.join(' '));
592
593							// Completed - Field
594							hcaptcha_obj_field.addClass(class_hcaptcha_valid_field_array.join(' '));
595							hcaptcha_obj_field.removeClass(class_hcaptcha_invalid_field_array.join(' '));
596							hcaptcha_obj_field.removeAttr('data-captcha-invalid');
597
598							// Completed - Feedback
599							hcaptcha_obj_invalid_feedback.addClass(class_hcaptcha_valid_invalid_feedback_array.join(' '));
600							hcaptcha_obj_invalid_feedback.removeClass(class_hcaptcha_invalid_invalid_feedback_array.join(' '));
601
602							// Run conditions
603							ws_this.hcaptcha_conditions_run();
604
605							// Fire real time form validation
606							ws_this.form_validate_real_time_process(false, false);
607						},
608
609						'expired-callback': function() {
610
611							// Empty - Label
612							hcaptcha_obj_label.addClass(class_hcaptcha_invalid_label_array.join(' '));
613							hcaptcha_obj_label.removeClass(class_hcaptcha_valid_label_array.join(' '));
614
615							// Empty - Field
616							hcaptcha_obj_field.addClass(class_hcaptcha_invalid_field_array.join(' '));
617							hcaptcha_obj_field.removeClass(class_hcaptcha_valid_field_array.join(' '));
618							hcaptcha_obj_field.attr('data-captcha-invalid', '');
619
620							// Empty - Feedback
621							hcaptcha_obj_invalid_feedback.addClass(class_hcaptcha_invalid_invalid_feedback_array.join(' '));
622							hcaptcha_obj_invalid_feedback.removeClass(class_hcaptcha_valid_invalid_feedback_array.join(' '));
623
624							// Run conditions
625							ws_this.hcaptcha_conditions_run();
626
627							// Fire real time form validation
628							ws_this.form_validate_real_time_process(false, false);
629						},
630
631						'error-callback': function() {
632
633							// Empty - Label
634							hcaptcha_obj_label.addClass(class_hcaptcha_invalid_label_array.join(' '));
635							hcaptcha_obj_label.removeClass(class_hcaptcha_valid_label_array.join(' '));
636
637							// Empty - Field
638							hcaptcha_obj_field.addClass(class_hcaptcha_invalid_field_array.join(' '));
639							hcaptcha_obj_field.removeClass(class_hcaptcha_valid_field_array.join(' '));
640							hcaptcha_obj_field.attr('data-captcha-invalid', '');
641
642							// Empty - Feedback
643							hcaptcha_obj_invalid_feedback.addClass(class_hcaptcha_invalid_invalid_feedback_array.join(' '));
644							hcaptcha_obj_invalid_feedback.removeClass(class_hcaptcha_valid_invalid_feedback_array.join(' '));
645
646							// Run conditions
647							ws_this.hcaptcha_conditions_run();
648
649							// Fire real time form validation
650							ws_this.form_validate_real_time_process(false, false);
651						}
652					};
653
654					if(hcaptcha_language != '') { config.hl = hcaptcha_language; }
655
656					// Build hcaptcha object
657					var hcaptcha = {'id': false, 'hcaptcha_site_key': hcaptcha_site_key, 'name': name, 'hcaptcha_id': hcaptcha_id, 'config': config, 'type': 'default'}
658
659					// Add to hcaptcha arrays
660					ws_this.hcaptchas_default.push(hcaptcha);
661
662					ws_this.hcaptcha_process(hcaptcha);
663
664					break;
665
666				case 'invisible' :
667
668					// Badge (Invisible only)
669					var hcaptcha_badge = $(this).attr('data-badge');
670					if((hcaptcha_badge === undefined) || (['bottomright', 'bottomleft', 'inline'].indexOf(hcaptcha_badge) == -1)) { hcaptcha_badge = 'bottomright'; }
671
672					// Process hcaptcha
673					var config = {
674
675						'sitekey': hcaptcha_site_key,
676						'badge': hcaptcha_badge,
677						'size': 'invisible',
678
679						'callback': function() {
680
681							// Run conditions
682							ws_this.hcaptcha_conditions_run();
683
684							// Fire real time form validation
685							ws_this.form_validate_real_time_process(false, false);
686
687							// Form validated
688							ws_this.form_post('submit');
689						},
690
691						'expired-callback': function() {
692
693							// Run conditions
694							ws_this.hcaptcha_conditions_run();
695
696							// Fire real time form validation
697							ws_this.form_validate_real_time_process(false, false);
698
699						},
700
701						'error-callback': function() {
702
703							// Throw error
704							ws_this.error('error_hcaptcha_invisible');
705
706							// Run conditions
707							ws_this.hcaptcha_conditions_run();
708
709							// Fire real time form validation
710							ws_this.form_validate_real_time_process(false, false);
711						}
712					};
713
714					if(hcaptcha_language != '') { config.hl = hcaptcha_language; }
715
716					// Build hcaptcha object
717					var hcaptcha = {
718
719						'id': false,
720						'hcaptcha_site_key': hcaptcha_site_key,
721						'name': name,
722						'hcaptcha_id': hcaptcha_id,
723						'config': config,
724						'type': 'invisible'
725					};
726
727					// Add to hcaptcha array
728					ws_this.hcaptchas_invisible.push(hcaptcha)
729
730					// Process hcaptcha
731					ws_this.hcaptcha_process(hcaptcha);
732
733					break;
734			}
735		});
736	}
737
738	// hCaptcha run conditions
739	$.WS_Form.prototype.hcaptcha_conditions_run = function() {
740
741		// Run conditions
742		for(var hcaptcha_conditions_index in this.hcaptchas_conditions) {
743
744			if(!this.hcaptchas_conditions.hasOwnProperty(hcaptcha_conditions_index)) { continue; }
745
746			this.hcaptchas_conditions[hcaptcha_conditions_index]();
747		}
748	}
749
750	// Wait until hCaptcha loaded, then process
751	$.WS_Form.prototype.hcaptcha_process = function(hcaptcha_config, total_ms_start) {
752
753		var ws_this = this;
754
755		// Timeout check
756		if(typeof total_ms_start === 'undefined') { total_ms_start = new Date().getTime(); }
757		if((new Date().getTime() - total_ms_start) > this.timeout_hcaptcha) {
758
759			this.error('error_timeout_hcaptcha');
760			return false;
761		}
762
763		// Check to see if hCaptcha loaded
764		if(
765			wsf_hcaptcha_loaded &&
766			$('#' + hcaptcha_config.hcaptcha_id).length
767		) {
768
769			switch(hcaptcha_config.type) {
770
771				case 'default' :
772
773					var id = hcaptcha.render(hcaptcha_config.hcaptcha_id, hcaptcha_config.config);
774					hcaptcha_config.id = id;
775					this.form_validate_real_time_process(false, false);
776					break;
777
778				case 'invisible' :
779
780					var id = hcaptcha.render(hcaptcha_config.hcaptcha_id, hcaptcha_config.config);
781					hcaptcha_config.id = id;
782					this.form_validate_real_time_process(false, false);
783					break;
784			}
785
786			// Add to hcaptcha array
787			this.hcaptchas.push(hcaptcha_config);
788
789			// Run conditions
790			this.hcaptcha_conditions_run();
791
792		} else {
793
794			var ws_this = this;
795			setTimeout(function() { ws_this.hcaptcha_process(hcaptcha_config, total_ms_start); }, this.timeout_interval);
796		}
797	}
798
799	// hCaptcha V2 invisible execute
800	$.WS_Form.prototype.hcaptcha_invisible_execute = function() {
801
802		var ws_this = this;		
803
804		// Run through each hidden captcha for this form
805		for(var hcaptchas_invisible_index in this.hcaptchas_invisible) {
806
807			if(!this.hcaptchas_invisible.hasOwnProperty(hcaptchas_invisible_index)) { continue; }
808
809			// Get ID
810			var hcaptcha_config = this.hcaptchas_invisible[hcaptchas_invisible_index];
811			var hcaptcha_id = hcaptcha_config.id;
812
813			// Execute
814			hcaptcha.execute(hcaptcha_id);
815
816			// Fire real time form validation
817			ws_this.form_validate_real_time_process(false, false);
818		}
819	}
820
821	// hCaptcha - Reset
822	$.WS_Form.prototype.hcaptcha_reset = function() {
823
824		// Run through each hCaptcha for this form and reset it
825		for(var hcaptchas_index in this.hcaptchas) {
826
827			if(!this.hcaptchas.hasOwnProperty(hcaptchas_index)) { continue; }
828
829			// Get ID
830			var hcaptcha_config = this.hcaptchas[hcaptchas_index];
831			var hcaptcha_id = hcaptcha_config.id;
832
833			// Reset
834			hcaptcha.reset(hcaptcha_id);
835		}
836	}
837
838	// hCaptcha - Get response by name
839	$.WS_Form.prototype.hcaptcha_get_response_by_name = function(name) {
840
841		// Run through each hCaptcha and look for name
842		for(var hcaptchas_index in this.hcaptchas) {
843
844			if(!this.hcaptchas.hasOwnProperty(hcaptchas_index)) { continue; }
845
846			// Get ID
847			var hcaptcha_config = this.hcaptchas[hcaptchas_index];
848			var hcaptcha_id = hcaptcha_config.id;
849
850			// If name found, return response
851			if(hcaptcha_config.name == name) {
852
853				return hcaptcha.getResponse(hcaptcha_id);
854			}
855		}
856
857		return '';
858	}
859
860	// Adds Turnstile elements
861	$.WS_Form.prototype.form_turnstile = function() {
862
863		var ws_this = this;
864
865		// Get Turnstile objects
866		var turnstile_objects = $('[data-turnstile]', this.form_canvas_obj);
867		var turnstile_objects_count = turnstile_objects.length;
868		if(!turnstile_objects_count) { return false;}
869
870		// Should header script be loaded
871		if(!$('#wsf-turnstile-script-head').length) {
872
873			var turnstile_script_head = '<script id="wsf-turnstile-script-head">';
874			turnstile_script_head += 'var wsf_turnstile_loaded = false;';
875			turnstile_script_head += 'function wsf_turnstile_onload() {';
876			turnstile_script_head += 'wsf_turnstile_loaded = true;';
877			turnstile_script_head += '}';
878			turnstile_script_head += '</script>';
879
880			$('head').append(turnstile_script_head);
881		}
882
883		// Should Turnstile script be called?
884		if(!window['turnstile'] && !$('#wsf-turnstile-script-body').length) {
885
886			var turnstile_script_body = '<script id="wsf-turnstile-script-body" src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=wsf_turnstile_onload&render=explicit" async defer></script>';
887			$('body').append(turnstile_script_body);
888		}
889
890		// Reset Turnstile arrays
891		this.turnstiles = [];
892		this.turnstiles_default = [];
893
894		turnstile_objects.each(function() {
895
896			// Name
897			var name = $(this).attr('name');
898
899			// ID
900			var turnstile_id = $(this).attr('id');
901			if((turnstile_id === undefined) || (turnstile_id == '')) { return false; }
902
903			// Site key
904			var turnstile_site_key = $(this).attr('data-site-key');
905			if((turnstile_site_key === undefined) || (turnstile_site_key == '')) { return false; }
906
907			// Theme
908			var turnstile_theme = $(this).attr('data-theme');
909			if((turnstile_theme === undefined) || (['light', 'dark', 'auto'].indexOf(turnstile_theme) == -1)) { turnstile_theme = 'auto'; }
910
911			// Size
912			var turnstile_size = $(this).attr('data-size');
913			if((turnstile_size === undefined) || (['normal', 'compact'].indexOf(turnstile_size) == -1)) { turnstile_size = 'normal'; }
914
915			// Appearance
916			var turnstile_appearance = $(this).attr('data-appearance');
917			if((turnstile_appearance === undefined) || (['always', 'execute', 'interaction-only'].indexOf(turnstile_appearance) == -1)) { turnstile_appearance = 'always'; }
918
919			// Classes
920			var class_turnstile_invalid_label_array = ws_this.get_field_value_fallback('turnstile', false, 'class_invali
920d_label', []);
921			var class_turnstile_invalid_field_array = ws_this.get_field_value_fallback('turnstile', false, 'class_invalid_field', []);
922			var class_turnstile_invalid_invalid_feedback_array = ws_this.get_field_value_fallback('turnstile', false, 'class_invalid_invalid_feedback', []);
923			var class_turnstile_valid_label_array = ws_this.get_field_value_fallback('turnstile', false, 'class_valid_label', []);
924			var class_turnstile_valid_field_array = ws_this.get_field_value_fallback('turnstile', false, 'class_valid_field', []);
925			var class_turnstile_valid_invalid_feedback_array = ws_this.get_field_value_fallback('turnstile', false, 'class_valid_invalid_feedback', []);
926
927			// Process turnstile
928			var turnstile_obj_field = $(this);
929			var turnstile_obj_wrapper = turnstile_obj_field.closest('[data-id]');
930			var turnstile_obj_label = $('label', turnstile_obj_wrapper);
931			var turnstile_obj_invalid_feedback = $('#' + ws_this.form_id_prefix + 'invalid-feedback-' + turnstile_id, turnstile_obj_wrapper, ws_this.form_canvas_obj);
932
933			// Interaction only - Cloudflare renders the silent widget out of flow (0 height), so collapse field spacing until an interactive challenge is shown
934			if((turnstile_appearance === 'interaction-only') && (typeof ResizeObserver !== 'undefined')) {
935
936				new ResizeObserver(function() {
937
938					turnstile_obj_wrapper.toggleClass('wsf-turnstile-interactive', (turnstile_obj_field[0].offsetHeight > 1));
939
940				}).observe(turnstile_obj_field[0]);
941			}
942
943			var config = {
944
945				'sitekey': turnstile_site_key,
946				'theme': turnstile_theme,
947				'size': turnstile_size,
948				'appearance': turnstile_appearance,
949
950				'callback': function(token) {
951
952					// Completed - Label
953					turnstile_obj_label.addClass(class_turnstile_valid_label_array.join(' '));
954					turnstile_obj_label.removeClass(class_turnstile_invalid_label_array.join(' '));
955
956					// Completed - Field
957					turnstile_obj_field.addClass(class_turnstile_valid_field_array.join(' '));
958					turnstile_obj_field.removeClass(class_turnstile_invalid_field_array.join(' '));
959					turnstile_obj_field.removeAttr('data-captcha-invalid');
960
961					// Completed - Feedback
962					turnstile_obj_invalid_feedback.addClass(class_turnstile_valid_invalid_feedback_array.join(' '));
963					turnstile_obj_invalid_feedback.removeClass(class_turnstile_invalid_invalid_feedback_array.join(' '));
964
965					// Run conditions
966					ws_this.turnstile_conditions_run();
967
968					// Fire real time form validation
969					ws_this.form_validate_real_time_process(false, false);
970
971				},
972
973				'expired-callback': function() {
974
975					// Empty - Label
976					turnstile_obj_label.addClass(class_turnstile_invalid_label_array.join(' '));
977					turnstile_obj_label.removeClass(class_turnstile_valid_label_array.join(' '));
978
979					// Empty - Field
980					turnstile_obj_field.addClass(class_turnstile_invalid_field_array.join(' '));
981					turnstile_obj_field.removeClass(class_turnstile_valid_field_array.join(' '));
982					turnstile_obj_field.attr('data-captcha-invalid', '');
983
984					// Empty - Feedback
985					turnstile_obj_invalid_feedback.addClass(class_turnstile_invalid_invalid_feedback_array.join(' '));
986					turnstile_obj_invalid_feedback.removeClass(class_turnstile_valid_invalid_feedback_array.join(' '));
987
988					// Run conditions
989					ws_this.turnstile_conditions_run();
990
991					// Fire real time form validation
992					ws_this.form_validate_real_time_process(false, false);
993
994				},
995
996				'error-callback': function() {
997
998					// Empty - Label
999					turnstile_obj_label.addClass(class_turnstile_invalid_label_array.join(' '));
1000					turnstile_obj_label.removeClass(class_turnstile_valid_label_array.join(' '));
1001
1002					// Empty - Field
1003					turnstile_obj_field.addClass(class_turnstile_invalid_field_array.join(' '));
1004					turnstile_obj_field.removeClass(class_turnstile_valid_field_array.join(' '));
1005
1006					// Empty - Feedback
1007					turnstile_obj_invalid_feedback.addClass(class_turnstile_invalid_invalid_feedback_array.join(' '));
1008					turnstile_obj_invalid_feedback.removeClass(class_turnstile_valid_invalid_feedback_array.join(' '));
1009					turnstile_obj_field.attr('data-captcha-invalid', '');
1010
1011					// Run conditions
1012					ws_this.turnstile_conditions_run();
1013
1014					// Fire real time form validation
1015					ws_this.form_validate_real_time_process(false, false);
1016				}
1017			};
1018
1019			// Build turnstile object
1020			var turnstile = {
1021
1022				'id': false,
1023				'turnstile_site_key': turnstile_site_key,
1024				'name': name,
1025				'turnstile_id': turnstile_id,
1026				'config': config,
1027				'type': 'default'
1028			};
1029
1030			// Add to turnstile arrays
1031			ws_this.turnstiles_default.push(turnstile);
1032
1033			ws_this.turnstile_process(turnstile);
1034		});
1035	}
1036
1037	// Turnstile run conditions
1038	$.WS_Form.prototype.turnstile_conditions_run = function() {
1039
1040		// Run conditions
1041		for(var turnstile_conditions_index in this.turnstiles_conditions) {
1042
1043			if(!this.turnstiles_conditions.hasOwnProperty(turnstile_conditions_index)) { continue; }
1044
1045			this.turnstiles_conditions[turnstile_conditions_index]();
1046		}
1047	}
1048
1049	// Wait until Turnstile loaded, then process
1050	$.WS_Form.prototype.turnstile_process = function(turnstile_config, total_ms_start) {
1051
1052		var ws_this = this;
1053
1054		// Timeout check
1055		if(typeof total_ms_start === 'undefined') { total_ms_start = new Date().getTime(); }
1056		if((new Date().getTime() - total_ms_start) > this.timeout_turnstile) {
1057
1058			this.error('error_timeout_turnstile');
1059			return false;
1060		}
1061
1062		// Check to see if Turnstile loaded
1063		if(
1064			wsf_turnstile_loaded &&
1065			$('#' + turnstile_config.turnstile_id).length
1066		) {
1067			var id = turnstile.render('#' + turnstile_config.turnstile_id, turnstile_config.config);
1068
1069			turnstile_config.id = id;
1070
1071			this.form_validate_real_time_process(false, false);
1072
1073			// Add to turnstile array
1074			this.turnstiles.push(turnstile_config);
1075
1076			// Run conditions
1077			this.turnstile_conditions_run();
1078
1079		} else {
1080
1081			var ws_this = this;
1082			setTimeout(function() { ws_this.turnstile_process(turnstile_config, total_ms_start); }, this.timeout_interval);
1083		}
1084	}
1085
1086	// Turnstile - Reset
1087	$.WS_Form.prototype.turnstile_reset = function() {
1088
1089		// Run through each Turnstile for this form and reset it
1090		for(var turnstiles_index in this.turnstiles) {
1091
1092			if(!this.turnstiles.hasOwnProperty(turnstiles_index)) { continue; }
1093
1094			// Get ID
1095			var turnstile_config = this.turnstiles[turnstiles_index];
1096			var turnstile_id = turnstile_config.id;
1097
1098			// Reset
1099			turnstile.reset(turnstile_id);
1100		}
1101	}
1102
1103	// Turnstile - Get response by name
1104	$.WS_Form.prototype.turnstile_get_response_by_name = function(name) {
1105
1106		// Run through each Turnstile and look for name
1107		for(var turnstiles_index in this.turnstiles) {
1108
1109			if(!this.turnstiles.hasOwnProperty(turnstiles_index)) { continue; }
1110
1111			// Get ID
1112			var turnstile_config = this.turnstiles[turnstiles_index];
1113			var turnstile_id = turnstile_config.id;
1114
1115			// If name found, return response
1116			if(turnstile_config.name == name) {
1117
1118				return turnstile.getResponse(turnstile_id);
1119			}
1120		}
1121
1122		return '';
1123	}
1124
1125	// Adds CaptchaFox elements
1126	$.WS_Form.prototype.form_captchafox = function() {
1127
1128		var ws_this = this;
1129
1130		// Get CaptchaFox objects
1131		var captchafox_objects = $('[data-captchafox]', this.form_canvas_obj);
1132		var captchafox_objects_count = captchafox_objects.length;
1133		if(!captchafox_objects_count) { return false;}
1134
1135		// Should header script be loaded
1136		if(!$('#wsf-captchafox-script-head').length) {
1137
1138			var captchafox_script_head = '<script id="wsf-captchafox-script-head">';
1139			captchafox_script_head += 'var wsf_captchafox_loaded = false;';
1140			captchafox_script_head += 'function wsf_captchafox_onload() {';
1141			captchafox_script_head += 'wsf_captchafox_loaded = true;';
1142			captchafox_script_head += '}';
1143			captchafox_script_head += '</script>';
1144
1145			$('head').append(captchafox_script_head);
1146		}
1147
1148		// Should CaptchaFox script be called?
1149		if(!window['captchafox'] && !$('#wsf-captchafox-script-body').length) {
1150
1151			var captchafox_script_body = '<script id="wsf-captchafox-script-body" src="https://cdn.captchafox.com/api.js?onload=wsf_captchafox_onload&render=explicit" async defer></script>';
1152			$('body').append(captchafox_script_body);
1153		}
1154
1155		// Reset CaptchaFox arrays
1156		this.captchafoxes = [];
1157		this.captchafoxes_default = [];
1158
1159		captchafox_objects.each(function() {
1160
1161			// Name
1162			var name = $(this).attr('name');
1163
1164			// ID
1165			var captchafox_id = $(this).attr('id');
1166			if((captchafox_id === undefined) || (captchafox_id == '')) { return false; }
1167
1168			// Site key
1169			var captchafox_site_key = $(this).attr('data-site-key');
1170			if((captchafox_site_key === undefined) || (captchafox_site_key == '')) { return false; }
1171
1172			// Theme
1173			var captchafox_theme = $(this).attr('data-theme');
1174			if((captchafox_theme === undefined) || (['light', 'dark'].indexOf(captchafox_theme) == -1)) { captchafox_theme = 'auto'; }
1175
1176			// Mode
1177			var captchafox_mode = $(this).attr('data-mode');
1178			if((captchafox_mode === undefined) || (['inline', 'popup', 'hidden'].indexOf(captchafox_mode) == -1)) { captchafox_mode = 'inline'; }
1179
1180			// Classes
1181			var class_captchafox_invalid_label_array = ws_this.get_field_value_fallback('captchafox', false, 'class_invalid_label', []);
1182			var class_captchafox_invalid_field_array = ws_this.get_field_value_fallback('captchafox', false, 'class_invalid_field', []);
1183			var class_captchafox_invalid_invalid_feedback_array = ws_this.get_field_value_fallback('captchafox', false, 'class_invalid_invalid_feedback', []);
1184			var class_captchafox_valid_label_array = ws_this.get_field_value_fallback('c
1184aptchafox', false, 'class_valid_label', []);
1185			var class_captchafox_valid_field_array = ws_this.get_field_value_fallback('captchafox', false, 'class_valid_field', []);
1186			var class_captchafox_valid_invalid_feedback_array = ws_this.get_field_value_fallback('captchafox', false, 'class_valid_invalid_feedback', []);
1187
1188			// Process captchafox
1189			var captchafox_obj_field = $(this);
1190			var captchafox_obj_wrapper = captchafox_obj_field.closest('[data-id]');
1191			var captchafox_obj_label = $('label', captchafox_obj_wrapper);
1192			var captchafox_obj_invalid_feedback = $('#' + ws_this.form_id_prefix + 'invalid-feedback-' + captchafox_id, captchafox_obj_wrapper, ws_this.form_canvas_obj);
1193
1194			switch(captchafox_mode) {
1195
1196				// Inline and pop-up
1197				case 'inline' :
1198				case 'popup' :
1199
1200					var config = {
1201
1202						'sitekey': captchafox_site_key,
1203						'mode': captchafox_mode,
1204						'theme': captchafox_theme,
1205
1206						'onVerify': function(token) {
1207
1208							// Completed - Label
1209							captchafox_obj_label.addClass(class_captchafox_valid_label_array.join(' '));
1210							captchafox_obj_label.removeClass(class_captchafox_invalid_label_array.join(' '));
1211
1212							// Completed - Field
1213							captchafox_obj_field.addClass(class_captchafox_valid_field_array.join(' '));
1214							captchafox_obj_field.removeClass(class_captchafox_invalid_field_array.join(' '));
1215							captchafox_obj_field.removeAttr('data-captcha-invalid');
1216
1217							// Completed - Feedback
1218							captchafox_obj_invalid_feedback.addClass(class_captchafox_valid_invalid_feedback_array.join(' '));
1219							captchafox_obj_invalid_feedback.removeClass(class_captchafox_invalid_invalid_feedback_array.join(' '));
1220
1221							// Run conditions
1222							ws_this.captchafox_conditions_run();
1223
1224							// Fire real time form validation
1225							ws_this.form_validate_real_time_process(false, false);
1226						},
1227
1228						'onExpire': function() {
1229
1230							// Empty - Label
1231							captchafox_obj_label.addClass(class_captchafox_invalid_label_array.join(' '));
1232							captchafox_obj_label.removeClass(class_captchafox_valid_label_array.join(' '));
1233
1234							// Empty - Field
1235							captchafox_obj_field.addClass(class_captchafox_invalid_field_array.join(' '));
1236							captchafox_obj_field.removeClass(class_captchafox_valid_field_array.join(' '));
1237							captchafox_obj_field.attr('data-captcha-invalid', '');
1238
1239							// Empty - Feedback
1240							captchafox_obj_invalid_feedback.addClass(class_captchafox_invalid_invalid_feedback_array.join(' '));
1241							captchafox_obj_invalid_feedback.removeClass(class_captchafox_valid_invalid_feedback_array.join(' '));
1242
1243							// Run conditions
1244							ws_this.captchafox_conditions_run();
1245
1246							// Fire real time form validation
1247							ws_this.form_validate_real_time_process(false, false);
1248						},
1249
1250						'onError': function() {
1251
1252							// Empty - Label
1253							captchafox_obj_label.addClass(class_captchafox_invalid_label_array.join(' '));
1254							captchafox_obj_label.removeClass(class_captchafox_valid_label_array.join(' '));
1255
1256							// Empty - Field
1257							captchafox_obj_field.addClass(class_captchafox_invalid_field_array.join(' '));
1258							captchafox_obj_field.removeClass(class_captchafox_valid_field_array.join(' '));
1259							captchafox_obj_field.attr('data-captcha-invalid', '');
1260
1261							// Empty - Feedback
1262							captchafox_obj_invalid_feedback.addClass(class_captchafox_invalid_invalid_feedback_array.join(' '));
1263							captchafox_obj_invalid_feedback.removeClass(class_captchafox_valid_invalid_feedback_array.join(' '));
1264
1265							// Run conditions
1266							ws_this.captchafox_conditions_run();
1267
1268							// Fire real time form validation
1269							ws_this.form_validate_real_time_process(false, false);
1270						}
1271					};
1272
1273					// Build captchafox object
1274					var captchafox = {
1275
1276						'id': false,
1277						'captchafox_site_key': captchafox_site_key,
1278						'name': name,
1279						'captchafox_id': captchafox_id,
1280						'config': config,
1281						'type': 'default'
1282					};
1283
1284					// Add to captchafox arrays
1285					ws_this.captchafoxes_default.push(captchafox);
1286
1287					ws_this.captchafox_process(captchafox);
1288
1289					break;
1290
1291				// Hidden
1292				case 'hidden' :
1293
1294					var config = {
1295
1296						'sitekey': captchafox_site_key,
1297						'mode': captchafox_mode,
1298
1299						'onVerify': function(token) {
1300
1301							// Completed - Field
1302							captchafox_obj_field.removeAttr('data-captcha-invalid');
1303
1304							// Run conditions
1305							ws_this.captchafox_conditions_run();
1306
1307							// Fire real time form validation
1308							ws_this.form_validate_real_time_process(false, false);
1309
1310							// Form validated
1311							setTimeout(function() {
1312
1313								ws_this.form_post('submit');
1314
1315							}, 0);
1316						},
1317
1318						'onExpire': function() {
1319
1320							// Empty - Field
1321							captchafox_obj_field.attr('data-captcha-invalid', '');
1322
1323							// Run conditions
1324							ws_this.captchafox_conditions_run();
1325
1326							// Fire real time form validation
1327							ws_this.form_validate_real_time_process(false, false);
1328						},
1329
1330						'onError': function() {
1331
1332							// Empty - Field
1333							captchafox_obj_field.attr('data-captcha-invalid', '');
1334
1335							// Throw error
1336							ws_this.error('error_captchafox_invisible');
1337
1338							// Run conditions
1339							ws_this.captchafox_conditions_run();
1340
1341							// Fire real time form validation
1342							ws_this.form_validate_real_time_process(false, false);
1343						}
1344					};
1345
1346					// Build captchafox object
1347					var captchafox = {
1348
1349						'id': false,
1350						'captchafox_site_key': captchafox_site_key,
1351						'name': name,
1352						'captchafox_id': captchafox_id,
1353						'config': config,
1354						'type': 'default'
1355					};
1356
1357					// Add to captchafox arrays
1358					ws_this.captchafoxes_invisible.push(captchafox);
1359
1360					ws_this.captchafox_process(captchafox);
1361
1362					break;
1363			}
1364		});
1365	}
1366
1367	// CaptchaFox run conditions
1368	$.WS_Form.prototype.captchafox_conditions_run = function() {
1369
1370		// Run conditions
1371		for(var captchafox_conditions_index in this.captchafoxes_conditions) {
1372
1373			if(!this.captchafoxes_conditions.hasOwnProperty(captchafox_conditions_index)) { continue; }
1374
1375			this.captchafoxes_conditions[captchafox_conditions_index]();
1376		}
1377	}
1378
1379	// Wait until CaptchaFox loaded, then process
1380	$.WS_Form.prototype.captchafox_process = async function(captchafox_config, total_ms_start) {
1381
1382		var ws_this = this;
1383
1384		// Timeout check
1385		if(typeof total_ms_start === 'undefined') { total_ms_start = new Date().getTime(); }
1386		if((new Date().getTime() - total_ms_start) > this.timeout_captchafox) {
1387
1388			this.error('error_timeout_captchafox');
1389			return false;
1390		}
1391
1392		// Check to see if CaptchaFox loaded
1393		if(
1394			wsf_captchafox_loaded &&
1395			$('#' + captchafox_config.captchafox_id).length
1396		) {
1397			var id = await captchafox.render('#' + captchafox_config.captchafox_id, captchafox_config.config);
1398
1399			captchafox_config.id = id;
1400
1401			this.form_validate_real_time_process(false, false);
1402
1403			// Add to captchafox array
1404			this.captchafoxes.push(captchafox_config);
1405
1406			// Run conditions
1407			this.captchafox_conditions_run();
1408
1409		} else {
1410
1411			var ws_this = this;
1412			setTimeout(function() { ws_this.captchafox_process(captchafox_config, total_ms_start); }, this.timeout_interval);
1413		}
1414	}
1415
1416	// CaptchaFox invisible execute
1417	$.WS_Form.prototype.captchafox_invisible_execute = async function() {
1418
1419		var ws_this = this;		
1420
1421		// Run through each hidden captcha for this form
1422		for(var captchafoxes_invisible_index in this.captchafoxes_invisible) {
1423
1424			if(!this.captchafoxes_invisible.hasOwnProperty(captchafoxes_invisible_index)) { continue; }
1425
1426			// Get ID
1427			var captchafox_config = this.captchafoxes_invisible[captchafoxes_invisible_index];
1428			var captchafox_id = captchafox_config.id;
1429
1430			// Execute
1431			var token = await captchafox.execute(captchafox_id);
1432
1433			// Fire real time form validation
1434			ws_this.form_validate_real_time_process(false, false);
1435		}
1436	}
1437
1438	// CaptchaFox - Reset
1439	$.WS_Form.prototype.captchafox_reset = function() {
1440
1441		// Run through each CaptchaFox for this form and reset it
1442		for(var captchafoxes_index in this.captchafoxes) {
1443
1444			if(!this.captchafoxes.hasOwnProperty(captchafoxes_index)) { continue; }
1445
1446			// Get ID
1447			var captchafox_config = this.captchafoxes[captchafoxes_index];
1448			var captchafox_id = captchafox_config.id;
1449
1450			// Reset
1451			captchafox.reset(captchafox_id);
1452		}
1453	}
1454
1455	// CaptchaFox - Get response by name
1456	$.WS_Form.prototype.captchafox_get_response_by_name = function(name) {
1457
1458		// Run through each CaptchaFox and look for name
1459		for(var captchafoxes_index in this.captchafoxes) {
1460
1461			if(!this.captchafoxes.hasOwnProperty(captchafoxes_index)) { continue; }
1462
1463			// Get ID
1464			var captchafox_config = this.captchafoxes[captchafoxes_index];
1465			var captchafox_id = captchafox_config.id;
1466
1467			// If name found, return response
1468			if(captchafox_config.name == name) {
1469
1470				return captchafox.getResponse(captchafox_id);
1471			}
1472		}
1473
1474		return '';
1475	}
1476
1477	// Captcha validation
1478	$.WS_Form.prototype.form_validate_captcha = function(captchas_array, field_type, form) {
1479
1480		if(captchas_array.length == 0) { return true; }
1481
1482		// hCaptcha
1483		var class_captcha_invalid_label_array = this.get_field_value_fallback(field_type, false, 'class_invalid_label', []);
1484		var class_captcha_invalid_field_array = this.get_field_value_fallback(field_type, false, 'class_invalid_field', []);
1485		var class_captcha_invalid_invalid_feedback_array = this.get_field_value_fallback(field_type, false, 'class_invalid_invalid_feedback', []);
1486		var class_captcha_valid_label_array = this.get_field_value_fallback(field_type, false, 'class_valid_label', []);
1487		var class_captcha_valid_field_array = this.get_field_value_fallback(field_type, false, 'class_valid_field', []);
1488		var class_captcha_valid_invalid_feedback_array = this.get_field_value_fallback(field_type, false, 'class_valid_invalid_feedback', []);
1489
1490		// Run through each hCaptcha for this form
1491		for(var captchas_index in captchas_array) {
1492
1493			if(!captchas_array.hasOwnProperty(captchas_index)) { continue; }
1494
1495			// Get data
1496			var captcha_config = captchas_array[captchas_index];
1497			var captcha_id = captcha_config.id;
1498			var captcha_name = captcha_config.name;
1499
1500			// If reCAPTCHA is hidden, bypass this reCAPTCHA
1501			var captcha_obj = $('#' + captcha_config.captcha_id, this.form_canvas_obj);
1502			if(
1503				(captcha_obj.attr('data-required-bypass') !== undefined) ||
1504				(captcha_obj.attr('data-required-bypass-section') !== undefined) ||
1505				(captcha_obj.attr('data-required-bypass-group') !== undefined)
1506
1507			) { continue; };
1508
1509			var captcha_obj_field = $('[name="' + this.esc_selector(captcha_name) + '"]', form);
1510			var captcha_obj_wrapper = captcha_obj_field.closest('[data-id]');
1511			var captcha_obj_label = $('label', captcha_obj_wrapper);
1512			var captcha_obj_invalid_feedback = $('#' + this.form_id_prefix + 'invali
1512d-feedback-' + captcha_id, form);
1513
1514			var captcha_response = '';
1515
1516			switch(field_type) {
1517
1518				case 'recaptcha' :
1519
1520					captcha_response = grecaptcha.getResponse(captcha_id);
1521					break;
1522
1523				case 'hcaptcha' :
1524
1525					captcha_response = hcaptcha.getResponse(captcha_id);
1526					break;
1527
1528				case 'turnstile' :
1529
1530					captcha_response = turnstile.getResponse(captcha_id);
1531					break;
1532
1533				case 'captchafox' :
1534
1535					captcha_response = captchafox.getResponse(captcha_id);
1536					break;
1537			}
1538
1539			// Execute
1540			if(!captcha_response) {
1541
1542				// Empty - Label
1543				captcha_obj_label.addClass(class_captcha_invalid_label_array.join(' '));
1544				captcha_obj_label.removeClass(class_captcha_valid_label_array.join(' '));
1545
1546				// Empty - Field
1547				captcha_obj_field.addClass(class_captcha_invalid_field_array.join(' '));
1548				captcha_obj_field.removeClass(class_captcha_valid_field_array.join(' '));
1549				captcha_obj_field.attr('data-captcha-invalid', '');
1550
1551				// Empty - Feedback
1552				captcha_obj_invalid_feedback.addClass(class_captcha_invalid_invalid_feedback_array.join(' '));
1553				captcha_obj_invalid_feedback.removeClass(class_captcha_valid_invalid_feedback_array.join(' '));
1554
1555				// Determine which tab and object to focus
1556				return {
1557
1558					object_focus : captcha_obj_field,
1559					group_index_focus : this.get_group_index(captcha_obj_wrapper)
1560				};
1561
1562			} else {
1563
1564				// Completed - Label
1565				captcha_obj_label.addClass(class_captcha_valid_label_array.join(' '));
1566				captcha_obj_label.removeClass(class_captcha_invalid_label_array.join(' '));
1567
1568				// Completed - Field
1569				captcha_obj_field.addClass(class_captcha_valid_field_array.join(' '));
1570				captcha_obj_field.removeClass(class_captcha_invalid_field_array.join(' '));
1571				captcha_obj_field.removeAttr('data-captcha-invalid');
1572
1573				// Completed - Feedback
1574				captcha_obj_invalid_feedback.addClass(class_captcha_valid_invalid_feedback_array.join(' '));
1575				captcha_obj_invalid_feedback.removeClass(class_captcha_invalid_invalid_feedback_array.join(' '));
1576			}
1577		}
1578
1579		return true;
1580	}
1581
1582	// Form - Validate - Silent - Captchas
1583	$.WS_Form.prototype.form_validate_silent_captchas = function(captchas_array, field_type, form) {
1584
1585		if(captchas_array.length == 0) { return true; }
1586
1587		// Run through each captcha for this form
1588		for(var captchas_index in captchas_array) {
1589
1590			if(!captchas_array.hasOwnProperty(captchas_index)) { continue; }
1591
1592			var captcha_config = captchas_array[captchas_index];
1593
1594			if(captcha_config.id === false) { return false; }
1595
1596			// If hCaptcha is hidden, bypass this hCaptcha
1597			var captcha_id = captcha_config.captcha_id;
1598			var captcha_obj = $('#' + captcha_id, form);
1599			if(
1600				(captcha_obj.attr('data-required-bypass') !== undefined) ||
1601				(captcha_obj.attr('data-required-bypass-section') !== undefined) ||
1602				(captcha_obj.attr('data-required-bypass-group') !== undefined)
1603
1604			) { continue; };
1605
1606			var captcha_response = '';
1607
1608			switch(field_type) {
1609
1610				case 'recaptcha' :
1611
1612					captcha_response = grecaptcha.getResponse(captcha_config.id);
1613					break;
1614
1615				case 'hcaptcha' :
1616
1617					captcha_response = hcaptcha.getResponse(captcha_config.id);
1618					break;
1619
1620				case 'turnstile' :
1621
1622					captcha_response = turnstile.getResponse(captcha_config.id);
1623					break;
1624
1625				case 'captchafox' :
1626
1627					captcha_response = captchafox.getResponse(captcha_config.id);
1628					break;
1629			}
1630
1631			// Execute
1632			if(!captcha_response) { return false; }
1633		}
1634
1635		// Validated
1636		return true;
1637	}
1638
1639})(jQuery);

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