
var wordformOnloadgreCaptchaCallback = function() {
	console.log('grecaptcha is ready');	
  };	
var wordformreCaptchaErrorCallback = function(err) { console.err('reCAPTCHA Error:', err) }

jQuery(document).ready(function($) {	
	console.log('SC-WORDFORM-FRONTEND-OBJECT');
	console.log(sc_wordform_frontend_misc_script_obj);				

		function wordformParsePaymentValue(value) {
			const parsed = parseFloat(value);
			return Number.isFinite(parsed) ? parsed : 0;
		}

		function wordformFormatPaymentAmount(amount, currencySymbol, symbolPosition) {
			const normalizedAmount = wordformParsePaymentValue(amount);
			const formattedAmount = normalizedAmount.toFixed(2);

			if (symbolPosition === 'after') {
				return formattedAmount + ' ' + currencySymbol;
			}

			return currencySymbol + formattedAmount;
		}

		function wordformIsHttpsPage() {
			return window.location && window.location.protocol === 'https:';
		}

		function wordformGetCurrentPaymentTotal($form) {
			return wordformParsePaymentValue($form.find('.sc-wordform-payment-summary-total-input').first().val() || $form.attr('data-wordform-payment-total'));
		}

		function wordformGetAppliedCouponState($form) {
			return $form.data('wordform-applied-coupon') || null;
		}

		function wordformShowCouponMessage($form, message, state = 'info') {
			const $couponWrapper = $form.find('[data-wordform-payment-role="coupon"]').first();
			const $message = $couponWrapper.find('[data-wordform-payment-role="coupon-message"]').first();

			if (!$message.length) {
				return;
			}

			if (!String(message || '').trim().length) {
				$message.removeClass('is-error is-success is-info').hide().text('');
				return;
			}

			$message
				.removeClass('is-error is-success is-info')
				.addClass(state === 'error' ? 'is-error' : (state === 'success' ? 'is-success' : 'is-info'))
				.text(message)
				.show();
		}

		function wordformSetAppliedCouponState($form, couponState = null) {
			const $couponWrapper = $form.find('[data-wordform-payment-role="coupon"]').first();
			if (!$couponWrapper.length) {
				return;
			}

			const $input = $couponWrapper.find('[data-wordform-payment-role="coupon-input"]').first();
			const $applyButton = $couponWrapper.find('[data-wordform-payment-role="coupon-apply"]').first();
			const $removeButton = $couponWrapper.find('[data-wordform-payment-role="coupon-remove"]').first();
			const $codeField = $couponWrapper.find('.sc-wordform-payment-coupon-code').first();
			const $hiddenCodeField = $couponWrapper.find('.sc-wordform-payment-coupon-hidden-code').first();
			const $couponIdField = $couponWrapper.find('.sc-wordform-payment-coupon-id').first();
			const $discountField = $couponWrapper.find('.sc-wordform-payment-coupon-discount').first();

			if (!couponState || !couponState.coupon_code) {
				$form.removeData('wordform-applied-coupon');
				$codeField.val('');
				$hiddenCodeField.val('');
				$couponIdField.val('0');
				$discountField.val('0.00');
				$applyButton.prop('disabled', false).removeClass('wordform-payment-coupon-hidden').show();
				$removeButton.addClass('wordform-payment-coupon-hidden').hide();
				return;
			}

			$form.data('wordform-applied-coupon', couponState);
			$input.val(couponState.coupon_code || '');
			$codeField.val(couponState.coupon_code || '');
			$hiddenCodeField.val(couponState.coupon_code || '');
			$couponIdField.val((couponState.coupon && couponState.coupon.id) ? couponState.coupon.id : 0);
			$discountField.val(couponState.discount_amount || '0.00');
			$applyButton.prop('disabled', true).addClass('wordform-payment-coupon-hidden').hide();
			$removeButton.removeClass('wordform-payment-coupon-hidden').show();
		}

		function wordformClearAppliedCouponState($form, clearMessage = false) {
			const $couponWrapper = $form.find('[data-wordform-payment-role="coupon"]').first();
			const $input = $couponWrapper.find('[data-wordform-payment-role="coupon-input"]').first();
			const currentValue = $.trim($input.val() || '');

			wordformSetAppliedCouponState($form, null);
			$input.val(currentValue);

			if (clearMessage) {
				wordformShowCouponMessage($form, '');
			}
		}

		function wordformSyncHCaptchaToken($form) {
			const $hcaptchaTokenField = $form.find('.wordform-hcaptcha-token-value').first();
			if (!$hcaptchaTokenField.length) {
				return;
			}

			const responseToken = $.trim($form.find('textarea[name="h-captcha-response"]').val() || '');
			$hcaptchaTokenField.val(responseToken);
		}

		function wordformSetSubmissionValidationToken($form, validationToken = '') {
			const normalizedToken = $.trim(validationToken || '');
			if (!normalizedToken.length) {
				$form.removeData('wordform-submission-validation-token');
				return;
			}

			$form.data('wordform-submission-validation-token', normalizedToken);
		}

		function wordformGetSubmissionValidationToken($form) {
			return $.trim($form.data('wordform-submission-validation-token') || '');
		}

		function wordformClearSubmissionValidationToken($form) {
			$form.removeData('wordform-submission-validation-token');
		}

		function wordformInitializeSignatureCanvas($wrapper) {
			if (!$wrapper || !$wrapper.length) {
				return;
			}

			const $canvas = $wrapper.find('[data-wordform-signature-canvas]').first();
			const $shell = $wrapper.find('[data-wordform-signature-shell]').first();
			const $hidden = $wrapper.find('.sc-wordform-built-signature-data').first();
			const $placeholder = $wrapper.find('.sc-wordform-built-signature-placeholder').first();
			const $clearButton = $wrapper.find('[data-wordform-signature-clear]').first();
			const canvas = $canvas.get(0);

			if (!canvas || !$shell.length || !$hidden.length) {
				return;
			}

			const ctx = canvas.getContext('2d');
			let isDrawing = false;
			let lastPoint = null;
			let hasSignature = $.trim($hidden.val() || '') !== '';

			function togglePlaceholder() {
				$placeholder.toggle(!hasSignature);
			}

			function drawSavedSignature() {
				const existingValue = $.trim($hidden.val() || '');
				if (!existingValue.length) {
					hasSignature = false;
					togglePlaceholder();
					return;
				}

				const image = new Image();
				image.onload = function() {
					ctx.clearRect(0, 0, canvas.width, canvas.height);
					ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
					hasSignature = true;
					togglePlaceholder();
				};
				image.src = existingValue;
			}

			function resizeCanvas() {
				const shellWidth = $shell.outerWidth();
				const shellHeight = parseInt($canvas.attr('data-wordform-signature-height') || $shell.outerHeight() || 180, 10);
				if (!shellWidth || !shellHeight) {
					return;
				}

				const ratio = Math.max(window.devicePixelRatio || 1, 1);
				canvas.width = Math.floor(shellWidth * ratio);
				canvas.height = Math.floor(shellHeight * ratio);
				canvas.style.width = shellWidth + 'px';
				canvas.style.height = shellHeight + 'px';
				ctx.setTransform(1, 0, 0, 1, 0, 0);
				ctx.scale(ratio, ratio);
				ctx.lineCap = 'round';
				ctx.lineJoin = 'round';
				ctx.lineWidth = 2.2;
				ctx.strokeStyle = '#0f172a';
				drawSavedSignature();
			}

			function getPoint(event) {
				const rect = canvas.getBoundingClientRect();
				const sourceEvent = event.originalEvent || event;
				const pointer = sourceEvent.touches && sourceEvent.touches[0] ? sourceEvent.touches[0] : sourceEvent;
				return {
					x: pointer.clientX - rect.left,
					y: pointer.clientY - rect.top
				};
			}

			function writeSignatureValue() {
				$hidden.val(canvas.toDataURL('image/png'));
			}

			function beginStroke(event) {
				event.preventDefault();
				if (!$shell.is(':visible')) {
					return;
				}
				isDrawing = true;
				lastPoint = getPoint(event);
				ctx.beginPath();
				ctx.moveTo(lastPoint.x, lastPoint.y);
			}

			function drawStroke(event) {
				if (!isDrawing) {
					return;
				}

				event.preventDefault();
				const point = getPoint(event);
				ctx.lineTo(point.x, point.y);
				ctx.stroke();
				lastPoint = point;
				hasSignature = true;
				togglePlaceholder();
			}

			function endStroke(event) {
				if (!isDrawing) {
					return;
				}

				if (event) {
					event.preventDefault();
				}
				isDrawing = false;
				ctx.closePath();
				writeSignatureValue();
			}

			function clearSignature(event) {
				if (event) {
					event.preventDefault();
				}
				ctx.clearRect(0, 0, canvas.width, canvas.height);
				$hidden.val('');
				hasSignature = false;
				togglePlaceholder();
			}

			if (!$wrapper.data('wordform-signature-events-bound')) {
				if (window.PointerEvent) {
					canvas.addEventListener('pointerdown', beginStroke);
					canvas.addEventListener('pointermove', drawStroke);
					canvas.addEventListener('pointerup', endStroke);
					canvas.addEventListener('pointerleave', endStroke);
					canvas.addEventListener('pointercancel', endStroke);
				} else {
					$canvas.on('mousedown.wordformSignature touchstart.wordformSignature', beginStroke);
					$canvas.on('mousemove.wordformSignature touchmove.wordformSignature', drawStroke);
					$canvas.on('mouseup.wordformSignature mouseleave.wordformSignature touchend.wordformSignature touchcancel.wordformSignature', endStroke);
				}

				$clearButton.on('click.wordformSignature', clearSignature);
				$wrapper.data('wordform-signature-events-bound', true);
			}

			resizeCanvas();
			$wrapper.data('wordform-signature-resize', resizeCanvas);
		}

		function wordformInitializeSignatureFields(context) {
			const $context = context ? $(context) : $(document);
			$context.find('.sc-wordform-built-signature-wrapper').each(function() {
				wordformInitializeSignatureCanvas($(this));
			});
		}

		function wordformApplyRatingSelection($wrapper, ratingValue) {
			if (!$wrapper || !$wrapper.length) {
				return;
			}

			const maxRating = Math.min(Math.max(parseInt($wrapper.attr('data-wordform-rating-max'), 10) || 5, 3), 10);
			const normalizedValue = Math.min(Math.max(parseInt(ratingValue, 10) || 0, 0), maxRating);
			$wrapper.find('.sc-wordform-built-rating-value').val(normalizedValue > 0 ? normalizedValue : '');
			$wrapper.find('.sc-wordform-built-rating-star').each(function() {
				const starValue = parseInt($(this).attr('data-wordform-rating-value'), 10) || 0;
				const isActive = normalizedValue > 0 && starValue <= normalizedValue;
				$(this).toggleClass('is-active', isActive).attr('aria-pressed', isActive ? 'true' : 'false');
			});
		}

		function wordformInitializeRatingFields(context) {
			const $context = context ? $(context) : $(document);
			$context.find('.sc-wordform-built-rating-wrapper').each(function() {
				const $wrapper = $(this);
				if (!$wrapper.data('wordform-rating-events-bound')) {
					$wrapper.on('click.wordformRating', '.sc-wordform-built-rating-star', function(event) {
						event.preventDefault();
						wordformApplyRatingSelection($wrapper, $(this).attr('data-wordform-rating-value'));
					});
					$wrapper.data('wordform-rating-events-bound', true);
				}

				wordformApplyRatingSelection($wrapper, $wrapper.find('.sc-wordform-built-rating-value').val());
			});
		}

		function wordformRichEditorIsMeaningfullyEmpty(htmlValue) {
			const normalizedHtml = String(htmlValue || '')
				.replace(/<br\s*\/?>/gi, '')
				.replace(/&nbsp;/gi, ' ')
				.replace(/<p>\s*<\/p>/gi, '')
				.replace(/<div>\s*<\/div>/gi, '')
				.replace(/\s+/g, '')
				.trim();
			const plainText = $('<div>').html(String(htmlValue || '')).text().replace(/\u00a0/g, ' ').trim();
			return normalizedHtml.length === 0 || plainText.length === 0;
		}

		function wordformNormalizeRichEditorHtml($surface) {
			const htmlValue = ($surface.html() || '').trim();
			return wordformRichEditorIsMeaningfullyEmpty(htmlValue) ? '' : htmlValue;
		}

		function wordformSyncRichEditorValue($wrapper) {
			const $surface = $wrapper.find('[data-wordform-rich-surface]').first();
			const $hidden = $wrapper.find('[data-wordform-rich-hidden]').first();
			const normalizedHtml = wordformNormalizeRichEditorHtml($surface);
			$hidden.val(normalizedHtml);
			$surface.attr('data-wordform-is-empty', normalizedHtml.length ? 'no' : 'yes');
		}

		function wordformInitializeRichEditors(context) {
			const $context = context ? $(context) : $(document);
			$context.find('.sc-wordform-built-richeditor-wrapper').each(function() {
				const $wrapper = $(this);
				const $surface = $wrapper.find('[data-wordform-rich-surface]').first();
				const $hidden = $wrapper.find('[data-wordform-rich-hidden]').first();

				if (!$surface.length || !$hidden.length) {
					return;
				}

				if (!$wrapper.data('wordform-rich-editor-events-bound')) {
					$wrapper.on('click.wordformRichEditor', '[data-wordform-rich-command]', function(event) {
						event.preventDefault();
						$surface.trigger('focus');
						const command = $(this).attr('data-wordform-rich-command');
						if (command === 'createLink') {
							const urlValue = window.prompt('Enter link URL');
							if (!urlValue) {
								return;
							}
							document.execCommand('createLink', false, urlValue);
						} else {
							document.execCommand(command, false, null);
						}
						wordformSyncRichEditorValue($wrapper);
					});

					$surface.on('input.wordformRichEditor blur.wordformRichEditor paste.wordformRichEditor keyup.wordformRichEditor', function() {
						window.setTimeout(function() {
							wordformSyncRichEditorValue($wrapper);
						}, 0);
					});

					$wrapper.data('wordform-rich-editor-events-bound', true);
				}

				if ($.trim($hidden.val()).length && wordformRichEditorIsMeaningfullyEmpty($surface.html())) {
					$surface.html($hidden.val());
				}

				wordformSyncRichEditorValue($wrapper);
			});
		}

		function wordformGetGatewaySlugs($form) {
			const gatewaySlugs = [];
			['stripe', 'paypal', 'square', 'authorizenet'].forEach(function(gatewaySlug) {
				if ($form.find('[data-wordform-gateway="' + gatewaySlug + '"]').length) {
					gatewaySlugs.push(gatewaySlug);
				}
			});
			return gatewaySlugs;
		}

		function wordformHasInvalidGatewayConfiguration($form) {
			const hasPaymentMethodSelector = $form.find('[data-wordform-payment-role="method-selector"]').length > 0;
			return !hasPaymentMethodSelector && wordformGetGatewaySlugs($form).length > 1;
		}

		function wordformGetInvalidGatewayConfigurationMessage() {
			return 'This form has multiple payment gateways but no Payment Method element. Add Payment Method in the builder, or keep only one gateway in this form.';
		}

		function wordformShowInvalidGatewayConfigurationError($form) {
			const message = wordformGetInvalidGatewayConfigurationMessage();
			wordformShowGatewayError($form, message);
			wordformGetGatewaySlugs($form).forEach(function(gatewaySlug) {
				wordformShowGatewayError($form, message, gatewaySlug);
			});
		}

		function wordformGetSelectedPaymentGateway($form) {
			const requestedGateway = $form.data('wordform-requested-gateway') || '';
			if (requestedGateway && $form.find('[data-wordform-gateway="' + requestedGateway + '"]').length) {
				return requestedGateway;
			}

			const $selectedPaymentMethod = $form.find('.sc-wordform-built-payment-method-option-input:checked').first();

			if ($selectedPaymentMethod.length) {
				return $selectedPaymentMethod.val() || '';
			}

			if ($form.find('[data-wordform-gateway="stripe"]').length && !$form.find('[data-wordform-gateway="paypal"]').length) {
				return 'stripe';
			}

			if ($form.find('[data-wordform-gateway="paypal"]').length && !$form.find('[data-wordform-gateway="stripe"]').length) {
				return 'paypal';
			}

			if ($form.find('[data-wordform-gateway="square"]').length && !$form.find('[data-wordform-gateway="stripe"], [data-wordform-gateway="paypal"], [data-wordform-gateway="authorizenet"]').length) {
				return 'square';
			}

			if ($form.find('[data-wordform-gateway="authorizenet"]').length && !$form.find('[data-wordform-gateway="stripe"], [data-wordform-gateway="paypal"], [data-wordform-gateway="square"]').length) {
				return 'authorizenet';
			}

			if ($form.find('[data-wordform-gateway="stripe"]').length) {
				return 'stripe';
			}

			if ($form.find('[data-wordform-gateway="square"]').length) {
				return 'square';
			}

			if ($form.find('[data-wordform-gateway="authorizenet"]').length) {
				return 'authorizenet';
			}

			if ($form.find('[data-wordform-gateway="paypal"]').length) {
				return 'paypal';
			}

			return '';
		}

		function wordformSyncPaymentMethodSelector($form) {
			const $selector = $form.find('[data-wordform-payment-role="method-selector"]').first();
			if (!$selector.length) {
				return;
			}

			const availableGateways = [];
			const hasStripe = $form.find('[data-wordform-gateway="stripe"]').length > 0;
			const hasPaypal = $form.find('[data-wordform-gateway="paypal"]').length > 0;
			const hasSquare = $form.find('[data-wordform-gateway="square"]').length > 0;
			const hasAuthorizeNet = $form.find('[data-wordform-gateway="authorizenet"]').length > 0;

			if (hasStripe) {
				availableGateways.push('stripe');
			}
			if (hasPaypal) {
				availableGateways.push('paypal');
			}
			if (hasSquare) {
				availableGateways.push('square');
			}
			if (hasAuthorizeNet) {
				availableGateways.push('authorizenet');
			}

			$selector.find('.sc-wordform-built-payment-method-option').hide();
			availableGateways.forEach(function(gatewaySlug) {
				$selector.find('.sc-wordform-built-payment-method-option[data-wordform-payment-method-option="' + gatewaySlug + '"]').show();
			});

			let selectedGateway = wordformGetSelectedPaymentGateway($form);
			if (!selectedGateway || availableGateways.indexOf(selectedGateway) === -1) {
				selectedGateway = availableGateways[0] || '';
				if (selectedGateway) {
					$selector.find('.sc-wordform-built-payment-method-option-input[value="' + selectedGateway + '"]').prop('checked', true).attr('checked', true);
				}
			}

			$selector.find('.sc-wordform-built-payment-method-option').removeClass('is-active');
			if (selectedGateway) {
				$selector.find('.sc-wordform-built-payment-method-option[data-wordform-payment-method-option="' + selectedGateway + '"]').addClass('is-active');
			}

			$form.find('[data-wordform-payment-role="gateway"]').hide();
			if (selectedGateway) {
				$form.find('[data-wordform-gateway="' + selectedGateway + '"]').show();
			}

			if (!availableGateways.length) {
				$selector.find('.wordform-payment-gateway-error').remove();
				$selector.append('<small class="sc-wordform-error-msg wordform-payment-gateway-error">' + 'Add a Stripe, PayPal, Square, or Authorize.Net element to use Payment Method.' + '</small>');
			}
		}

		function wordformRefreshPaymentSummary($form) {
			if (!$form.length) {
				return;
			}

			const currencySymbol = $form.attr('data-wordform-payment-currency-symbol') || '$';
			const symbolPosition = $form.attr('data-wordform-payment-symbol-position') || 'before';
			let fixedItemsSubtotal = 0;
			let customAmountTotal = 0;
			let quantityMultiplier = 1;
			let discountAmount = 0;
			let total = 0;

			$form.find('[data-wordform-payment-role="item"]').each(function() {
				const itemAmount = $(this).attr('data-wordform-payment-amount') || $(this).find('.sc-wordform-payment-item-value').val();
				fixedItemsSubtotal += wordformParsePaymentValue(itemAmount);
			});

			const $quantityInput = $form.find('[data-wordform-payment-role="quantity-input"]').first();
			if ($quantityInput.length) {
				const minimumQuantity = Math.max(1, Math.round(wordformParsePaymentValue($quantityInput.attr('min')) || 1));
				let enteredQuantity = Math.round(wordformParsePaymentValue($quantityInput.val()));

				if (!Number.isFinite(enteredQuantity) || enteredQuantity < minimumQuantity) {
					enteredQuantity = minimumQuantity;
				}

				const maximumQuantity = Math.round(wordformParsePaymentValue($quantityInput.attr('max')));
				if (maximumQuantity > 0 && enteredQuantity > maximumQuantity) {
					enteredQuantity = maximumQuantity;
				}

				$quantityInput.val(enteredQuantity);
				quantityMultiplier = enteredQuantity;
			}

			$form.find('[data-wordform-payment-role="custom-amount-input"]').each(function() {
				const $input = $(this);
				const rawValue = ($input.val() === '') ? ($input.attr('data-default-amount') || '') : $input.val();
				const minimumAmount = wordformParsePaymentValue($input.attr('min'));
				let enteredAmount = wordformParsePaymentValue(rawValue);

				if (rawValue !== '' && enteredAmount < minimumAmount) {
					enteredAmount = minimumAmount;
					$input.val(minimumAmount.toFixed(2));
				}

				customAmountTotal += enteredAmount;
			});

			const subtotal = (fixedItemsSubtotal * quantityMultiplier) + customAmountTotal;
			const appliedCoupon = wordformGetAppliedCouponState($form);
			if (appliedCoupon && appliedCoupon.coupon_code) {
				let discountableSubtotal = fixedItemsSubtotal * quantityMultiplier;
				if (appliedCoupon.apply_to_custom_amount === 'yes') {
					discountableSubtotal += customAmountTotal;
				}

				if (discountableSubtotal > 0) {
					if (appliedCoupon.discount_type === 'percentage') {
						discountAmount = (discountableSubtotal * wordformParsePaymentValue(appliedCoupon.discount_value)) / 100;
					} else {
						discountAmount = wordformParsePaymentValue(appliedCoupon.discount_value);
					}
					discountAmount = Math.min(discountableSubtotal, Math.max(0, discountAmount));
				}
			}

			total = Math.max(0, subtotal - discountAmount);
			const formattedSubtotal = wordformFormatPaymentAmount(subtotal, currencySymbol, symbolPosition);
			const formattedDiscount = wordformFormatPaymentAmount(discountAmount, currencySymbol, symbolPosition);
			const formattedTotal = wordformFormatPaymentAmount(total, currencySymbol, symbolPosition);
			$form.attr('data-wordform-payment-total', total.toFixed(2));

			$form.find('[data-wordform-payment-role="summary"]').each(function() {
				const $summary = $(this);
				const emptyText = $summary.attr('data-empty-text') || 'Amounts will appear here';
				const hasAmount = subtotal > 0;
				const $discountRow = $summary.find('.sc-wordform-built-payment-summary-discount-row');

				$summary.find('.sc-wordform-payment-subtotal-text').text(formattedSubtotal);
				$summary.find('.sc-wordform-payment-discount-text').text('-' + formattedDiscount);
				$summary.find('.sc-wordform-payment-total-text').text(formattedTotal);
				$summary.find('.sc-wordform-payment-summary-total-input').val(total.toFixed(2));
				$summary.find('.sc-wordform-payment-summary-subtotal-input').val(subtotal.toFixed(2));
				$summary.find('.sc-wordform-payment-summary-discount-input').val(discountAmount.toFixed(2));
				$discountRow.toggle(discountAmount > 0);

				if (hasAmount) {
					$summary.find('.sc-wordform-built-payment-summary-empty-text').hide();
					$summary.find('.sc-wordform-built-payment-summary-totals').show();
				} else {
					$summary.find('.sc-wordform-built-payment-summary-empty-text').text(emptyText).show();
					$summary.find('.sc-wordform-built-payment-summary-totals').hide();
				}
			});

			$form.find('.sc-wordform-payment-gateway-total-text').text(formattedTotal);
			$form.find('.sc-wordform-payment-coupon-discount').val(discountAmount.toFixed(2));
		}

		function wordformInitializePaymentSummaries() {
			$('.sc-wordform-built-created-form-frontend-display-form').each(function() {
				wordformRefreshPaymentSummary($(this));
				wordformSyncPaymentMethodSelector($(this));
			});
		}

		const wordformStripeFormRegistry = {};
		const wordformStripeSettings = sc_wordform_frontend_misc_script_obj.payment_settings || {};
		const wordformStripePublishableKey = wordformStripeSettings.stripe_publishable_key || '';
		const wordformStripeEnabled = wordformStripeSettings.stripe_enabled === 'yes';
		const wordformStripeInstance = (wordformStripeEnabled && wordformStripePublishableKey && typeof window.Stripe === 'function') ? window.Stripe(wordformStripePublishableKey) : null;
		const wordformPaypalFormRegistry = {};
		const wordformPaypalEnabled = wordformStripeSettings.paypal_enabled === 'yes';
		const wordformSquareFormRegistry = {};
		const wordformSquareEnabled = wordformStripeSettings.square_enabled === 'yes';
		const wordformSquareApplicationId = wordformStripeSettings.square_application_id || '';
		const wordformSquareLocationId = wordformStripeSettings.square_location_id || '';
		const wordformAuthorizeNetEnabled = wordformStripeSettings.authorizenet_enabled === 'yes';
		const wordformAuthorizeNetLoginId = wordformStripeSettings.authorizenet_api_login_id || '';
		const wordformAuthorizeNetClientKey = wordformStripeSettings.authorizenet_client_key || '';

		function wordformShowGatewayError($form, message, gatewaySlug = '') {
			const $scope = gatewaySlug ? $form.find('[data-wordform-gateway="' + gatewaySlug + '"]').first() : $form;
			const $error = $scope.find('.wordform-payment-gateway-error').first();
			if ($error.length) {
				$error.text(message).show();
			}
		}

		function wordformClearGatewayError($form, gatewaySlug = '') {
			const $scope = gatewaySlug ? $form.find('[data-wordform-gateway="' + gatewaySlug + '"]').first() : $form;
			$scope.find('.wordform-payment-gateway-error').text('').hide();
		}

		function wordformIsGatewaySelectedOrVisible($form, gatewaySlug) {
			const selectedGateway = wordformGetSelectedPaymentGateway($form);
			const hasPaymentMethodSelector = $form.find('[data-wordform-payment-role="method-selector"]').length > 0;

			if (!hasPaymentMethodSelector) {
				return true;
			}

			return selectedGateway === gatewaySlug || $form.find('[data-wordform-gateway="' + gatewaySlug + '"]:visible').length > 0;
		}

		function wordformGetStripeConfigurationErrorMessage() {
			if (!wordformStripeEnabled || !wordformStripePublishableKey) {
				return 'Stripe is not configured correctly.';
			}

			if (typeof window.Stripe !== 'function') {
				return 'Stripe checkout could not be loaded.';
			}

			return 'Stripe is not configured correctly.';
		}

		function wordformDisplayValidationErrors(scWordformWrapper, scWordFormOuterMostDivWrapper, jsonData) {
			scWordformWrapper.find('.sc-wordform-error-msg').text('');
			scWordFormOuterMostDivWrapper.find('.wordform-validation-summary-error').remove();
			let hasValidationErrors = false;
			const validationMessages = wordformGetValidationMessages(scWordformWrapper);
			const showValidationSummary = String(validationMessages.validation_summary_show || 'yes').toLowerCase() !== 'no';
			const validationSummaryMsg = $.trim(validationMessages.validation_summary_msg || 'Please review the highlighted fields and try again.');
			if (jsonData.validationErrorData) {
				$.each(jsonData.validationErrorData, function(key, val) {
					if (typeof val.validationMsgClass !== 'undefined') {
						scWordformWrapper.find('.' + val.validationMsgClass).text(val.validationMsg);
						hasValidationErrors = true;
					} else {
						hasValidationErrors = true;
					}
				});

				if (hasValidationErrors && showValidationSummary && validationSummaryMsg.length) {
					scWordFormOuterMostDivWrapper.prepend('<div class="sc-wordform-submisson-fail-msg-div-wrapper wordform-validation-summary-error">' + validationSummaryMsg + '</div>');
				}
			} else if (jsonData.failMsg) {
				scWordFormOuterMostDivWrapper.prepend('<div class="wordform-validation-summary-error">' + jsonData.failMsg + '</div>');
			}

			const firstVisibleError = scWordformWrapper.find('.sc-wordform-error-msg').filter(function() {
				return $.trim($(this).text()).length > 0 && $(this).is(':visible');
			}).first();

			if (firstVisibleError.length) {
				firstVisibleError.get(0)?.scrollIntoView({ behavior: 'smooth', block: 'center' });
			} else {
				scWordFormOuterMostDivWrapper.get(0)?.scrollIntoView({ behavior: 'smooth', block: 'start' });
			}
		}

		function wordformSetSubmitProcessingState($form, isProcessing, options = {}) {
			const keepDisabled = !!options.keepDisabled;
			const showSpinner = String($form.attr('data-wordform-show-submit-spinner') || 'yes') === 'yes';
			const showOverlay = String($form.attr('data-wordform-show-submit-overlay') || 'no') === 'yes';
			const loadingText = $.trim($form.attr('data-wordform-submit-loading-text') || 'Submitting...');
			const $submitButton = $form.find('button[type="submit"]').first();
			const $spinner = $form.find('.wordform-users-form-submit-loading-icon').first();
			const $overlay = $form.closest('.sc-wordform-built-form-frontend-outermost-div-wrapper').find('.sc-wordform-submit-progress-overlay').first();

			$submitButton.prop('disabled', !!isProcessing || keepDisabled);

			if ($spinner.length) {
				if (isProcessing && showSpinner) {
					$spinner.css('display', 'inline-flex');
				} else {
					$spinner.hide();
				}
			}

			if ($overlay.length) {
				$overlay.find('.sc-wordform-submit-progress-overlay-text').text(loadingText);
				$overlay.toggleClass('is-active', !!isProcessing && showOverlay);
			}
		}

		function wordformRenderSubmissionSuccess($form, $outerWrapper, successHtml) {
			const hideOnSuccess = String($form.attr('data-wordform-hide-on-success') || 'yes') === 'yes';
			const successAsCard = String($form.attr('data-wordform-success-card') || 'yes') === 'yes';
			const redirectOnSuccess = String($form.attr('data-wordform-redirect-on-success') || 'no') === 'yes';
			const redirectUrl = $.trim($form.attr('data-wordform-redirect-url') || '');
			const $successWrapper = $('<div></div>').append($.parseHTML(successHtml, document, true));

			if (successAsCard) {
				$successWrapper.find('.sc-wordform-submission-success-msg-div-wrapper').addClass('is-card');
			} else {
				$successWrapper.find('.sc-wordform-submission-success-msg-div-wrapper').removeClass('is-card');
			}

			wordformResetAllPaymentStates($form);
			wordformClearSubmissionValidationToken($form);
			wordformSetSubmitProcessingState($form, false, { keepDisabled: true });

			if (hideOnSuccess) {
				$outerWrapper.html($successWrapper.html());
			} else {
				$outerWrapper.prepend($successWrapper.html());
			}

			$outerWrapper.get(0)?.scrollIntoView();

			if (redirectOnSuccess && redirectUrl) {
				window.setTimeout(function() {
					window.location.href = redirectUrl;
				}, 450);
			}
		}

		function wordformBuildRequestFormData(scWordformWrapper, actionName, includeFiles = true) {
			const scWordformWrapperID = scWordformWrapper.prop('id');
			const scWordFormName = scWordformWrapper.data('scwordform-form-name');
			const wordformFormElement = document.getElementById(scWordformWrapperID);
			wordformSyncHCaptchaToken(scWordformWrapper);
			wordformSyncDateRangeFields(scWordformWrapper);
			wordformSyncTimeFields(scWordformWrapper);
			const wordformFormdata = new FormData(wordformFormElement);
			let wordformTotalFilesUploading = 0;

			scWordformWrapper.find('.sc-wordform-built-upload-element').each(function() {
				const inputTypeFileElementName = $(this).prop('name');
				if (inputTypeFileElementName) {
					wordformFormdata.delete(inputTypeFileElementName);
				}
			});

			if (includeFiles) {
				$.each(wordform_selected_tmp_files, function(index, files) {
					let inputTypeFileElementName = scWordformWrapper.find('#' + index).prop('name');
					if (!inputTypeFileElementName) {
						return;
					}
					$.each(files, function(fileIndex, file) {
						wordformFormdata.append(inputTypeFileElementName, file);
						wordformTotalFilesUploading += 1;
					});
				});
			}

			wordformFormdata.append('action', actionName);
			wordformFormdata.append('security', sc_wordform_frontend_misc_script_obj.nonce);
			wordformFormdata.append('WordFormName', scWordFormName);
			wordformFormdata.append('WordFormID', scWordformWrapperID);

			const submissionValidationToken = wordformGetSubmissionValidationToken(scWordformWrapper);
			if (submissionValidationToken.length) {
				wordformFormdata.append('wordform_submission_validation_token', submissionValidationToken);
			}

			return {
				formData: wordformFormdata,
				totalFilesUploading: wordformTotalFilesUploading,
				formId: scWordformWrapperID,
				formName: scWordFormName
			};
		}

		function wordformBuildGatewayRequestFormData(scWordformWrapper, actionName, extraFields = {}) {
			const requestPayload = wordformBuildRequestFormData(scWordformWrapper, actionName, false);
			Object.keys(extraFields || {}).forEach(function(fieldName) {
				requestPayload.formData.append(fieldName, extraFields[fieldName]);
			});
			return requestPayload;
		}

		function wordformResetUploadProgress($form) {
			const $progressWrapper = $form.find('.progress');
			const $progressBar = $progressWrapper.find('.progress-bar');
			$progressWrapper.removeClass('is-active is-complete');
			$progressBar.width('0%').text('');
		}

		function wordformValidateUploadFieldsBeforeSubmit($form) {
			let isValid = true;
			const messages = wordformGetValidationMessages($form);

			$form.find('.sc-wordform-built-upload-wrapper').each(function() {
				const $wrapper = $(this);
				const isRequired = String($wrapper.find('input[type="hidden"][name$="[required]"]').first().val() || '').toLowerCase() === 'true';
				const $temporaryError = $wrapper.find('.wordform-temporary-file-selection-error').first();
				const $requiredError = $wrapper.find('.sc-wordform-built-upload-element-label-wrapper .sc-wordform-error-msg').first();
				const hasSelectedFiles = $wrapper.find('.wordform-selected-file-names-list li').length > 0 || (($wrapper.find('input[type="file"]').first().get(0)?.files?.length) || 0) > 0;

				if ($requiredError.length) {
					$requiredError.text('');
				}

				if ($temporaryError.length && $.trim($temporaryError.text()) !== '') {
					isValid = false;
					return;
				}

				if (isRequired && !hasSelectedFiles) {
					isValid = false;
					if ($requiredError.length) {
						$requiredError.text(messages.upload_required_msg || 'Select a file before submitting.');
					}
				}
			});

			return isValid;
		}

		function wordformSubmitCreatedFormAjax(scWordformWrapper, scWordFormOuterMostDivWrapper, requestPayload) {
			const wordformProgressBarEle = scWordformWrapper.find('.progress-bar');
			const wordformProgressWrapperEle = scWordformWrapper.find('.progress');

			$.ajax({
				xhr: function() {
					var xhr = new window.XMLHttpRequest();
					xhr.upload.addEventListener("progress", function(evt) {
						if (evt.lengthComputable) {
							var percentComplete = ((evt.loaded / evt.total) * 100);
							if (requestPayload.totalFilesUploading > 0 && sc_wordform_frontend_misc_script_obj.wordform_upload_config_data?.wordform_upload_show_hide_progress_bar == 'yes') {
								wordformProgressWrapperEle.addClass('is-active');
								wordformProgressBarEle.width(percentComplete + '%').css({'background-color': sc_wordform_frontend_misc_script_obj.wordform_upload_config_data?.wordform_upload_progress_bar_color}).html(Math.round(percentComplete) + '%');
							}
						}
					}, false);
					return xhr;
				},

				type: "POST",
				url: sc_wordform_frontend_misc_script_obj.ajax_url,
				processData: false,
				contentType: false,
				data: requestPayload.formData,

				beforeSend: function() {
					wordformResetUploadProgress(scWordformWrapper);
					if (requestPayload.totalFilesUploading > 0 && sc_wordform_frontend_misc_script_obj.wordform_upload_config_data?.wordform_upload_show_hide_progress_bar == 'yes') {
						wordformProgressWrapperEle.addClass('is-active');
					}
				},

				success: function(data) {
					let jsonData = JSON.parse(data);
					if (jsonData.status == 'fail') {
						wordformResetUploadProgress(scWordformWrapper);
						wordformSetSubmitProcessingState(scWordformWrapper, false);
						wordformDisplayValidationErrors(scWordformWrapper, scWordFormOuterMostDivWrapper, jsonData);
					}
					else {
						if (requestPayload.totalFilesUploading > 0 && sc_wordform_frontend_misc_script_obj.wordform_upload_config_data?.wordform_upload_show_hide_progress_bar == 'yes') {
							wordformProgressWrapperEle.addClass('is-complete');
							wordformProgressBarEle.width('100%').html('100%');
						} else {
							wordformResetUploadProgress(scWordformWrapper);
						}
						wordformRenderSubmissionSuccess(scWordformWrapper, scWordFormOuterMostDivWrapper, jsonData.successMsg);
					}
				},
				error: function(xhr, status, error) {
					wordformResetUploadProgress(scWordformWrapper);
					wordformSetSubmitProcessingState(scWordformWrapper, false);
					console.log(xhr);
					console.log(status);
					console.log(error);
				}
			});
		}

		function wordformGetStripeBillingDetails($form) {
			const billingDetails = {};
			const $emailField = $form.find('input[type="email"]').first();
			const $textFields = $form.find('input[type="text"]').not('.sc-wordform-authorizenet-card-number, .sc-wordform-authorizenet-expiry, .sc-wordform-authorizenet-cvv, .sc-wordform-authorizenet-postal');

			if ($emailField.length && $emailField.val()) {
				billingDetails.email = $emailField.val();
			}

			if ($textFields.length) {
				const firstValue = $textFields.eq(0).val() || '';
				const secondValue = $textFields.eq(1).val() || '';
				const fullName = $.trim((firstValue + ' ' + secondValue).trim());
				if (fullName) {
					billingDetails.name = fullName;
				}
			}

			return billingDetails;
		}

		function wordformResetStripePaymentState($form) {
			$form.data('wordform-stripe-payment-confirmed', false);
			if (($form.data('wordform-payment-approved-gateway') || '') === 'stripe') {
				$form.removeData('wordform-payment-approved-gateway');
			}
			$form.find('.sc-wordform-stripe-payment-status').val('');
			$form.find('.sc-wordform-stripe-payment-intent-id').val('');
			$form.find('.sc-wordform-stripe-payment-method-id').val('');
			$form.find('.sc-wordform-stripe-payment-amount').val('0.00');
		}

		function wordformResetPaypalPaymentState($form) {
			if (($form.data('wordform-payment-approved-gateway') || '') === 'paypal') {
				$form.removeData('wordform-payment-approved-gateway');
			}
			$form.find('.sc-wordform-paypal-payment-status').val('');
			$form.find('.sc-wordform-paypal-order-id').val('');
			$form.find('.sc-wordform-paypal-capture-id').val('');
			$form.find('.sc-wordform-paypal-payer-id').val('');
			$form.find('.sc-wordform-paypal-payment-amount').val('0.00');
		}

		function wordformResetSquarePaymentState($form) {
			if (($form.data('wordform-payment-approved-gateway') || '') === 'square') {
				$form.removeData('wordform-payment-approved-gateway');
			}
			$form.find('.sc-wordform-square-payment-status').val('');
			$form.find('.sc-wordform-square-payment-id').val('');
			$form.find('.sc-wordform-square-source-id').val('');
			$form.find('.sc-wordform-square-payment-amount').val('0.00');
			$form.find('.sc-wordform-square-card-brand').val('');
			$form.find('.sc-wordform-square-last4').val('');
			$form.find('.sc-wordform-square-receipt-url').val('');
		}

		function wordformResetAuthorizeNetPaymentState($form) {
			if (($form.data('wordform-payment-approved-gateway') || '') === 'authorizenet') {
				$form.removeData('wordform-payment-approved-gateway');
			}
			$form.find('.sc-wordform-authorizenet-payment-status').val('');
			$form.find('.sc-wordform-authorizenet-transaction-id').val('');
			$form.find('.sc-wordform-authorizenet-response-code').val('');
			$form.find('.sc-wordform-authorizenet-auth-code').val('');
			$form.find('.sc-wordform-authorizenet-payment-amount').val('0.00');
			$form.find('.sc-wordform-authorizenet-account-number').val('');
			$form.find('.sc-wordform-authorizenet-account-type').val('');
		}

		function wordformResetAllPaymentStates($form) {
			wordformResetStripePaymentState($form);
			wordformResetPaypalPaymentState($form);
			wordformResetSquarePaymentState($form);
			wordformResetAuthorizeNetPaymentState($form);
			$form.removeData('wordform-requested-gateway');
		}

		function wordformValidateFormBeforePayment(scWordformWrapper) {
			const deferred = $.Deferred();
			const scWordFormOuterMostDivWrapper = scWordformWrapper.parent();
			const validationRequest = wordformBuildRequestFormData(scWordformWrapper, 'sc_wordform_validate_created_form_submission', false);
			const gcaptchaTokenInputElementName = scWordformWrapper.find('.wordform-gcaptcha-token-value').prop('name');
			const gcaptchaActionInputElementName = scWordformWrapper.find('.wordform-gcaptcha-action-value').prop('name');
			const gcaptchaActionValue = String(scWordformWrapper.prop('id') || '').replace(/-/g, '_');

			if (!wordformValidateUploadFieldsBeforeSubmit(scWordformWrapper)) {
				wordformSetSubmitProcessingState(scWordformWrapper, false);
				scWordFormOuterMostDivWrapper[0].scrollIntoView();
				deferred.reject();
				return deferred.promise();
			}

			const performValidationRequest = function() {
				$.ajax({
					type: 'POST',
					url: sc_wordform_frontend_misc_script_obj.ajax_url,
					processData: false,
					contentType: false,
					data: validationRequest.formData,
					success: function(data) {
						let jsonData = JSON.parse(data);
						if (jsonData.status === 'fail') {
							wordformClearSubmissionValidationToken(scWordformWrapper);
							wordformDisplayValidationErrors(scWordformWrapper, scWordFormOuterMostDivWrapper, jsonData);
							wordformSetSubmitProcessingState(scWordformWrapper, false);
							deferred.reject(jsonData);
							return;
						}

						wordformSetSubmissionValidationToken(scWordformWrapper, jsonData?.submissionValidationToken || '');
						deferred.resolve(validationRequest);
					},
					error: function() {
						wordformShowGatewayError(scWordformWrapper, 'Form validation request failed.');
						wordformSetSubmitProcessingState(scWordformWrapper, false);
						deferred.reject();
					}
				});
			};

			if (
				sc_wordform_frontend_misc_script_obj.gcaptcha_site_key.length > 0 &&
				sc_wordform_frontend_misc_script_obj.gcaptcha_version === 'v3' &&
				parseInt(sc_wordform_frontend_misc_script_obj?.gcaptcha_form_element_exist, 10) === 1 &&
				typeof grecaptcha !== 'undefined' &&
				gcaptchaTokenInputElementName &&
				gcaptchaActionInputElementName
			) {
				grecaptcha.ready(function() {
					grecaptcha.execute(sc_wordform_frontend_misc_script_obj.gcaptcha_site_key, { action: gcaptchaActionValue }).then(function(token) {
						validationRequest.formData.append(gcaptchaTokenInputElementName, token);
						validationRequest.formData.append(gcaptchaActionInputElementName, gcaptchaActionValue);
						performValidationRequest();
					}).catch(function() {
						wordformClearSubmissionValidationToken(scWordformWrapper);
						wordformShowGatewayError(scWordformWrapper, 'Google reCaptcha could not verify this request. Please refresh and try again.');
						wordformSetSubmitProcessingState(scWordformWrapper, false);
						deferred.reject();
					});
				});
			} else {
				performValidationRequest();
			}

			return deferred.promise();
		}

		function wordformInitializeStripeElements() {
			if (!wordformStripeInstance) {
				$('.sc-wordform-built-created-form-frontend-display-form').each(function() {
					const $form = $(this);

					if ($form.find('[data-wordform-gateway="stripe"]').length && wordformIsGatewaySelectedOrVisible($form, 'stripe')) {
						wordformShowGatewayError($form, wordformGetStripeConfigurationErrorMessage(), 'stripe');
					}
				});
				return;
			}

			$('.sc-wordform-built-created-form-frontend-display-form').each(function() {
				const $form = $(this);
				const formId = $form.prop('id');
				const $stripeGateway = $form.find('[data-wordform-gateway="stripe"]');
				const $stepPanel = $stripeGateway.closest('.sc-wordform-step-panel');

				if (!$stripeGateway.length || wordformStripeFormRegistry[formId]) {
					return;
				}

				if ($stepPanel.length && !$stepPanel.hasClass('is-active')) {
					return;
				}

				const $cardElement = $stripeGateway.find('.sc-wordform-stripe-card-element');
				if (!$cardElement.length) {
					return;
				}

				const elements = wordformStripeInstance.elements();
				const card = elements.create('card', {
					hidePostalCode: true,
					style: {
						base: {
							fontSize: '16px',
							color: '#111827',
							fontFamily: 'inherit',
							'::placeholder': {
								color: '#6b7280'
							}
						},
						invalid: {
							color: '#d62d30'
						}
					}
				});
				card.mount('#' + $cardElement.attr('id'));
				card.on('change', function(event) {
					if (event.error) {
						wordformShowGatewayError($form, event.error.message, 'stripe');
					} else {
						wordformClearGatewayError($form, 'stripe');
					}
				});

				wordformStripeFormRegistry[formId] = {
					stripe: wordformStripeInstance,
					card: card
				};
			});
		}

		function wordformHandleStripePayment(scWordformWrapper) {
			const formId = scWordformWrapper.prop('id');
			const stripeContext = wordformStripeFormRegistry[formId];

			if (!stripeContext || !wordformStripeInstance || !wordformStripeEnabled || !wordformStripePublishableKey) {
				wordformShowGatewayError(scWordformWrapper, wordformGetStripeConfigurationErrorMessage(), 'stripe');
				wordformSetSubmitProcessingState(scWordformWrapper, false);
				return;
			}

			wordformClearGatewayError(scWordformWrapper, 'stripe');
			wordformRefreshPaymentSummary(scWordformWrapper);

			const totalAmount = wordformGetCurrentPaymentTotal(scWordformWrapper);
			if (totalAmount <= 0) {
				wordformShowGatewayError(scWordformWrapper, 'Payment total must be greater than zero.', 'stripe');
				wordformSetSubmitProcessingState(scWordformWrapper, false);
				return;
			}

			wordformValidateFormBeforePayment(scWordformWrapper).done(function(validationRequest) {
				const billingDetails = wordformGetStripeBillingDetails(scWordformWrapper);
				const paymentIntentRequest = wordformBuildGatewayRequestFormData(scWordformWrapper, 'sc_wordform_create_stripe_payment_intent', {
					wordform_id: validationRequest.formId,
					wordform_name: validationRequest.formName,
					currency: wordformStripeSettings.currency || 'USD',
					receipt_email: billingDetails.email || ''
				});
				$.ajax({
					type: 'POST',
					url: sc_wordform_frontend_misc_script_obj.ajax_url,
					dataType: 'json',
					processData: false,
					contentType: false,
					data: paymentIntentRequest.formData,
					success: function(intentResponse) {
						if (!intentResponse || intentResponse.status !== 'success') {
							wordformShowGatewayError(scWordformWrapper, intentResponse?.comment || 'Stripe payment could not be initialized.', 'stripe');
							wordformSetSubmitProcessingState(scWordformWrapper, false);
							return;
						}

						stripeContext.stripe.confirmCardPayment(intentResponse.clientSecret, {
							payment_method: {
								card: stripeContext.card,
								billing_details: billingDetails
							}
						}).then(function(result) {
							if (result.error) {
								wordformShowGatewayError(scWordformWrapper, result.error.message || 'Stripe payment failed.', 'stripe');
								wordformSetSubmitProcessingState(scWordformWrapper, false);
								return;
							}

							if (!result.paymentIntent || !['succeeded', 'processing', 'requires_capture'].includes(result.paymentIntent.status)) {
								wordformShowGatewayError(scWordformWrapper, 'Stripe payment is not in a payable state.', 'stripe');
								wordformSetSubmitProcessingState(scWordformWrapper, false);
								return;
							}

							scWordformWrapper.find('.sc-wordform-stripe-payment-status').val(result.paymentIntent.status);
							scWordformWrapper.find('.sc-wordform-stripe-payment-intent-id').val(result.paymentIntent.id || '');
							scWordformWrapper.find('.sc-wordform-stripe-payment-method-id').val(result.paymentIntent.payment_method || '');
							scWordformWrapper.find('.sc-wordform-stripe-payment-amount').val(totalAmount.toFixed(2));
							scWordformWrapper.data('wordform-stripe-payment-confirmed', true);
							scWordformWrapper.data('wordform-payment-approved-gateway', 'stripe');
							wordformClearGatewayError(scWordformWrapper, 'stripe');
							scWordformWrapper.trigger('submit');
						});
					},
					error: function() {
						wordformShowGatewayError(scWordformWrapper, 'Stripe payment request failed.', 'stripe');
						wordformSetSubmitProcessingState(scWordformWrapper, false);
					}
				});
			});
		}

		function wordformInitializeSquareElements() {
			if (!wordformSquareEnabled || !wordformSquareApplicationId || !wordformSquareLocationId || typeof window.Square === 'undefined' || typeof window.Square.payments !== 'function') {
				$('.sc-wordform-built-created-form-frontend-display-form').each(function() {
					const $form = $(this);
					if ($form.find('[data-wordform-gateway="square"]').length) {
						wordformShowGatewayError($form, 'Square is not configured correctly.', 'square');
					}
				});
				return;
			}

			$('.sc-wordform-built-created-form-frontend-display-form').each(async function() {
				const $form = $(this);
				const formId = $form.prop('id');
				const $squareGateway = $form.find('[data-wordform-gateway="square"]');
				const $stepPanel = $squareGateway.closest('.sc-wordform-step-panel');

				if (!$squareGateway.length) {
					return;
				}

				if ($stepPanel.length && !$stepPanel.hasClass('is-active')) {
					return;
				}

				// Square card attachment is unstable when initialized inside a hidden gateway panel.
				// Only initialize after the selected payment method makes the panel visible.
				if (!$squareGateway.is(':visible')) {
					return;
				}

				if (wordformSquareFormRegistry[formId]) {
					return;
				}

				const $cardElement = $squareGateway.find('.sc-wordform-square-card-element');
				if (!$cardElement.length) {
					return;
				}

				wordformSquareFormRegistry[formId] = { pending: true };

				try {
					const payments = window.Square.payments(wordformSquareApplicationId, wordformSquareLocationId);
					const card = await payments.card({
						style: {
							'.input-container': {
								borderColor: '#d0d6de',
								borderRadius: '16px'
							},
							'.input-container.is-focus': {
								borderColor: '#2563eb'
							},
							'.input-container.is-error': {
								borderColor: '#d62d30'
							},
							input: {
								fontSize: '16px',
								color: '#111827'
							},
							'.message-text': {
								color: '#d62d30'
							}
						}
					});

					await card.attach('#' + $cardElement.attr('id'));
					wordformSquareFormRegistry[formId] = {
						payments: payments,
						card: card
					};
					wordformClearGatewayError($form, 'square');
				} catch (error) {
					delete wordformSquareFormRegistry[formId];
					wordformShowGatewayError($form, (error && error.message) ? error.message : 'Square card field could not be initialized.', 'square');
				}
			});
		}

		function wordformHandleSquarePayment(scWordformWrapper) {
			const formId = scWordformWrapper.prop('id');
			const squareContext = wordformSquareFormRegistry[formId];

			if (!squareContext || !wordformSquareEnabled) {
				wordformShowGatewayError(scWordformWrapper, 'Square is not configured correctly.', 'square');
				wordformSetSubmitProcessingState(scWordformWrapper, false);
				return;
			}

			wordformClearGatewayError(scWordformWrapper, 'square');
			wordformRefreshPaymentSummary(scWordformWrapper);
			const totalAmount = wordformGetCurrentPaymentTotal(scWordformWrapper);

			if (totalAmount <= 0) {
				wordformShowGatewayError(scWordformWrapper, 'Payment total must be greater than zero.', 'square');
				wordformSetSubmitProcessingState(scWordformWrapper, false);
				return;
			}

			wordformValidateFormBeforePayment(scWordformWrapper).done(async function(validationRequest) {
				try {
					const billingDetails = wordformGetStripeBillingDetails(scWordformWrapper);
					const nameParts = $.trim(billingDetails.name || '').split(/\s+/).filter(Boolean);
					const verificationDetails = {
						intent: 'CHARGE',
						amount: totalAmount.toFixed(2),
						currencyCode: (wordformStripeSettings.currency || 'USD').toUpperCase(),
						customerInitiated: true,
						sellerKeyedIn: false,
						billingContact: {
							givenName: nameParts[0] || '',
							familyName: nameParts.length > 1 ? nameParts.slice(1).join(' ') : '',
							email: billingDetails.email || '',
							countryCode: 'US'
						}
					};

					const tokenizeResult = await squareContext.card.tokenize(verificationDetails);
					if (!tokenizeResult || tokenizeResult.status !== 'OK' || !tokenizeResult.token) {
						const squareError = (tokenizeResult && tokenizeResult.errors && tokenizeResult.errors.length) ? tokenizeResult.errors.map(error => error.message).join(', ') : 'Square card tokenization failed.';
						wordformShowGatewayError(scWordformWrapper, squareError, 'square');
						wordformSetSubmitProcessingState(scWordformWrapper, false);
						return;
					}
					$.ajax({
						type: 'POST',
						url: sc_wordform_frontend_misc_script_obj.ajax_url,
						dataType: 'json',
						processData: false,
						contentType: false,
						data: wordformBuildGatewayRequestFormData(scWordformWrapper, 'sc_wordform_create_square_payment', {
							wordform_id: validationRequest.formId,
							wordform_name: validationRequest.formName,
							currency: wordformStripeSettings.currency || 'USD',
							buyer_email: billingDetails.email || '',
							source_id: tokenizeResult.token
						}).formData,
						success: function(paymentResponse) {
							if (!paymentResponse || paymentResponse.status !== 'success') {
								wordformShowGatewayError(scWordformWrapper, paymentResponse?.comment || 'Square payment could not be completed.', 'square');
								wordformSetSubmitProcessingState(scWordformWrapper, false);
								return;
							}

							scWordformWrapper.find('.sc-wordform-square-payment-status').val(paymentResponse.paymentStatus || 'COMPLETED');
							scWordformWrapper.find('.sc-wordform-square-payment-id').val(paymentResponse.paymentId || '');
							scWordformWrapper.find('.sc-wordform-square-source-id').val(paymentResponse.sourceId || tokenizeResult.token || '');
							scWordformWrapper.find('.sc-wordform-square-payment-amount').val(paymentResponse.amount || totalAmount.toFixed(2));
							scWordformWrapper.find('.sc-wordform-square-payment-currency').val(paymentResponse.currency || wordformStripeSettings.currency || 'USD');
							scWordformWrapper.find('.sc-wordform-square-card-brand').val(paymentResponse.cardBrand || '');
							scWordformWrapper.find('.sc-wordform-square-last4').val(paymentResponse.last4 || '');
							scWordformWrapper.find('.sc-wordform-square-receipt-url').val(paymentResponse.receiptUrl || '');
							scWordformWrapper.data('wordform-payment-approved-gateway', 'square');
							wordformClearGatewayError(scWordformWrapper, 'square');
							scWordformWrapper.trigger('submit');
						},
						error: function() {
							wordformShowGatewayError(scWordformWrapper, 'Square payment request failed.', 'square');
							wordformSetSubmitProcessingState(scWordformWrapper, false);
						}
					});
				} catch (error) {
					wordformShowGatewayError(scWordformWrapper, (error && error.message) ? error.message : 'Square payment failed.', 'square');
					wordformSetSubmitProcessingState(scWordformWrapper, false);
				}
			});
		}

		function wordformHandleAuthorizeNetPayment(scWordformWrapper) {
			if (!wordformIsHttpsPage()) {
				wordformShowGatewayError(scWordformWrapper, 'Authorize.Net requires HTTPS. Open this form over https:// before testing this gateway.', 'authorizenet');
				wordformSetSubmitProcessingState(scWordformWrapper, false);
				return;
			}

			if (!wordformAuthorizeNetEnabled || !wordformAuthorizeNetLoginId || !wordformAuthorizeNetClientKey || typeof window.Accept === 'undefined' || typeof window.Accept.dispatchData !== 'function') {
				wordformShowGatewayError(scWordformWrapper, 'Authorize.Net is not configured correctly.', 'authorizenet');
				wordformSetSubmitProcessingState(scWordformWrapper, false);
				return;
			}

			wordformClearGatewayError(scWordformWrapper, 'authorizenet');
			wordformRefreshPaymentSummary(scWordformWrapper);
			const totalAmount = wordformGetCurrentPaymentTotal(scWordformWrapper);

			if (totalAmount <= 0) {
				wordformShowGatewayError(scWordformWrapper, 'Payment total must be greater than zero.', 'authorizenet');
				wordformSetSubmitProcessingState(scWordformWrapper, false);
				return;
			}

			const $gateway = scWordformWrapper.find('[data-wordform-gateway="authorizenet"]').first();
			const cardNumber = $.trim($gateway.find('.sc-wordform-authorizenet-card-number').val() || '');
			const expiryValue = $.trim($gateway.find('.sc-wordform-authorizenet-expiry').val() || '');
			const cardCode = $.trim($gateway.find('.sc-wordform-authorizenet-cvv').val() || '');
			const zip = $.trim($gateway.find('.sc-wordform-authorizenet-postal').val() || '');
			const expiryParts = expiryValue.split('/');
			const month = $.trim(expiryParts[0] || '');
			const year = $.trim(expiryParts[1] || '');

			if (!cardNumber || !month || !year || !cardCode) {
				wordformShowGatewayError(scWordformWrapper, 'Complete the card details first.', 'authorizenet');
				wordformSetSubmitProcessingState(scWordformWrapper, false);
				return;
			}

			wordformValidateFormBeforePayment(scWordformWrapper).done(function(validationRequest) {
				const secureData = {
					authData: {
						clientKey: wordformAuthorizeNetClientKey,
						apiLoginID: wordformAuthorizeNetLoginId
					},
					cardData: {
						cardNumber: cardNumber.replace(/\s+/g, ''),
						month: month,
						year: year.length === 2 ? ('20' + year) : year,
						cardCode: cardCode,
						zip: zip
					}
				};

				window.Accept.dispatchData(secureData, function(response) {
					if (!response || !response.messages || response.messages.resultCode !== 'Ok') {
						let errorMessage = 'Authorize.Net card tokenization failed.';
						if (response && response.messages && Array.isArray(response.messages.message)) {
							errorMessage = response.messages.message.map(message => message.text).join(', ');
						}
						wordformShowGatewayError(scWordformWrapper, errorMessage, 'authorizenet');
						wordformSetSubmitProcessingState(scWordformWrapper, false);
						return;
					}

					const opaqueData = response.opaqueData || {};
					const billingDetails = wordformGetStripeBillingDetails(scWordformWrapper);
					$.ajax({
						type: 'POST',
						url: sc_wordform_frontend_misc_script_obj.ajax_url,
						dataType: 'json',
						processData: false,
						contentType: false,
						data: wordformBuildGatewayRequestFormData(scWordformWrapper, 'sc_wordform_create_authorizenet_transaction', {
							wordform_id: validationRequest.formId,
							wordform_name: validationRequest.formName,
							buyer_email: billingDetails.email || '',
							data_descriptor: opaqueData.dataDescriptor || '',
							data_value: opaqueData.dataValue || ''
						}).formData,
						success: function(transactionResponse) {
							if (!transactionResponse || transactionResponse.status !== 'success') {
								wordformShowGatewayError(scWordformWrapper, transactionResponse?.comment || 'Authorize.Net payment could not be completed.', 'authorizenet');
								wordformSetSubmitProcessingState(scWordformWrapper, false);
								return;
							}

							scWordformWrapper.find('.sc-wordform-authorizenet-payment-status').val(transactionResponse.paymentStatus || 'APPROVED');
							scWordformWrapper.find('.sc-wordform-authorizenet-transaction-id').val(transactionResponse.transactionId || '');
							scWordformWrapper.find('.sc-wordform-authorizenet-response-code').val(transactionResponse.responseCode || '');
							scWordformWrapper.find('.sc-wordform-authorizenet-auth-code').val(transactionResponse.authCode || '');
							scWordformWrapper.find('.sc-wordform-authorizenet-payment-amount').val(transactionResponse.amount || totalAmount.toFixed(2));
							scWordformWrapper.find('.sc-wordform-authorizenet-payment-currency').val(transactionResponse.currency || wordformStripeSettings.currency || 'USD');
							scWordformWrapper.find('.sc-wordform-authorizenet-account-number').val(transactionResponse.accountNumber || '');
							scWordformWrapper.find('.sc-wordform-authorizenet-account-type').val(transactionResponse.accountType || '');
							scWordformWrapper.data('wordform-payment-approved-gateway', 'authorizenet');
							wordformClearGatewayError(scWordformWrapper, 'authorizenet');
							scWordformWrapper.trigger('submit');
						},
						error: function() {
							wordformShowGatewayError(scWordformWrapper, 'Authorize.Net transaction request failed.', 'authorizenet');
							wordformSetSubmitProcessingState(scWordformWrapper, false);
						}
					});
				});
			});
		}

		function wordformInitializeAuthorizeNetElements() {
			$('.sc-wordform-built-created-form-frontend-display-form').each(function() {
				const $form = $(this);
				const $gateway = $form.find('[data-wordform-gateway="authorizenet"]').first();
				const $stepPanel = $gateway.closest('.sc-wordform-step-panel');

				if (!$gateway.length) {
					return;
				}

				if ($stepPanel.length && !$stepPanel.hasClass('is-active')) {
					return;
				}

				if (!wordformIsHttpsPage()) {
					wordformShowGatewayError($form, 'Authorize.Net requires HTTPS. Open this form over https:// before testing this gateway.', 'authorizenet');
				} else if (!wordformAuthorizeNetEnabled || !wordformAuthorizeNetLoginId || !wordformAuthorizeNetClientKey || typeof window.Accept === 'undefined' || typeof window.Accept.dispatchData !== 'function') {
					wordformShowGatewayError($form, 'Authorize.Net is not configured correctly.', 'authorizenet');
				} else {
					wordformClearGatewayError($form, 'authorizenet');
				}
			});
		}

		function wordformGetValidationMessages($form) {
			const formId = $form.prop('id');
			const $validationField = $('#' + formId + '-validationMsg');
			if (!$validationField.length) {
				return {};
			}

			try {
				return JSON.parse($validationField.val() || '{}');
			} catch (error) {
				return {};
			}
		}

		function wordformGetStepValidationMessage(messages, fieldType) {
			const fieldMap = {
				text: messages.text_msg,
				firstlastname: messages.firstname_msg,
				number: messages.number_msg,
				textarea: messages.textarea_msg,
				richeditor: messages.richeditor_msg || messages.textarea_msg || messages.text_msg,
				range: messages.range_msg,
				url: messages.url_msg,
				tel: messages.tel_msg,
				date: messages.date_msg,
				time: messages.time_msg || messages.date_msg,
				datetime: messages.datetime_msg || messages.date_msg,
				address: messages.address_msg || messages.text_msg,
				maskinput: messages.maskinput_msg || messages.text_msg,
				rating: messages.rating_msg || messages.text_msg,
				likert: messages.likert_msg || messages.radio_msg || messages.text_msg,
				signature: messages.signature_msg || messages.text_msg,
				gdpr: messages.gdpr_msg || messages.checkbox_msg || messages.text_msg,
				radio: messages.radio_msg,
				checkbox: messages.checkbox_msg,
				select: messages.select_msg,
				email: messages.email_msg,
				upload: messages.upload_required_msg,
				terms: messages.checkbox_msg,
				payment_custom_amount: messages.payment_custom_amount_msg || messages.number_msg,
				payment_quantity: messages.payment_quantity_msg || messages.number_msg,
				payment_method: messages.payment_method_msg || messages.radio_msg
			};

			return fieldMap[fieldType] || 'Complete this field before moving to the next step.';
		}

		function wordformClearStepValidationErrors($panel) {
			$panel.find('.sc-wordform-error-msg').text('');
		}

		function wordformValidateCurrentStep($form, $panel) {
			let isValid = true;
			const messages = wordformGetValidationMessages($form);
			wordformClearStepValidationErrors($panel);

			$panel.find('.sc-wordform-step-field').each(function() {
				const $fieldWrapper = $(this);
				const fieldType = $fieldWrapper.data('wordform-step-field-type');
				const requiredFieldValue = String($fieldWrapper.find('input[type="hidden"][name$="[required]"]').first().val() || '').toLowerCase();
				const isRequired = requiredFieldValue === 'true';

				if (!isRequired) {
					return;
				}

				let fieldValid = true;

				switch (fieldType) {
					case 'text':
					case 'number':
					case 'textarea':
					case 'richeditor':
					case 'range':
					case 'url':
					case 'tel':
					case 'date':
					case 'time':
					case 'datetime':
					case 'email':
					case 'maskinput':
					case 'payment_custom_amount':
					case 'payment_quantity':
						if (fieldType === 'richeditor') {
							fieldValid = !wordformRichEditorIsMeaningfullyEmpty($fieldWrapper.find('[data-wordform-rich-hidden]').first().val() || '');
						} else {
							fieldValid = $.trim($fieldWrapper.find('input:not([type="hidden"]):not([type="radio"]):not([type="checkbox"]), textarea').first().val() || '') !== '';
						}
						if (fieldValid && fieldType === 'maskinput') {
							const patternValue = $.trim($fieldWrapper.find('input[type="hidden"][name$="[pattern]"]').first().val() || '');
							const currentValue = $.trim($fieldWrapper.find('input[type="text"]').first().val() || '');
							if (patternValue.length && currentValue.length) {
								try {
									fieldValid = new RegExp(patternValue).test(currentValue);
								} catch (error) {
									fieldValid = false;
								}
							}
						}
						break;
					case 'address':
						fieldValid = $fieldWrapper.find('.sc-wordform-built-address-element').filter(function() {
							return $.trim($(this).val() || '') === '';
						}).length === 0;
						break;
					case 'firstlastname':
						fieldValid = $fieldWrapper.find('input[type="text"]').filter(function() {
							return $.trim($(this).val() || '') === '';
						}).length === 0;
						break;
					case 'radio':
					case 'payment_method':
						fieldValid = $fieldWrapper.find('input[type="radio"]:checked').length > 0;
						break;
					case 'checkbox':
						fieldValid = $fieldWrapper.find('input[type="checkbox"]:checked').length > 0;
						break;
					case 'select':
						fieldValid = $.trim($fieldWrapper.find('select').first().val() || '') !== '';
						break;
					case 'terms':
					case 'gdpr':
						fieldValid = $fieldWrapper.find('input[type="checkbox"]').first().is(':checked');
						break;
					case 'upload':
						fieldValid = $fieldWrapper.find('.wordform-selected-file-names-list li').length > 0 || ($fieldWrapper.find('input[type="file"]').first().get(0)?.files?.length || 0) > 0;
						break;
					case 'rating':
						fieldValid = $.trim($fieldWrapper.find('.sc-wordform-built-rating-value').first().val() || '') !== '';
						break;
					case 'likert':
						fieldValid = true;
						$fieldWrapper.find('.sc-wordform-built-likert-row').each(function() {
							const hasSelection = $(this).find('.sc-wordform-built-likert-choice-input:checked').length > 0;
							if (!hasSelection) {
								fieldValid = false;
								return false;
							}
						});
						break;
					case 'signature':
						fieldValid = $.trim($fieldWrapper.find('.sc-wordform-built-signature-data').first().val() || '') !== '';
						break;
					default:
						fieldValid = true;
						break;
				}

				if (!fieldValid) {
					isValid = false;
					const validationMessage = wordformGetStepValidationMessage(messages, fieldType);
					const $messageTarget = $fieldWrapper.find('.sc-wordform-error-msg').first();
					if ($messageTarget.length) {
						$messageTarget.text(validationMessage);
					} else {
						$fieldWrapper.prepend('<div class="sc-wordform-error-msg">' + validationMessage + '</div>');
					}
				}
			});

			return isValid;
		}

		function wordformSetActiveStep($form, targetStep) {
			const $panels = $form.find('.sc-wordform-step-panel');
			const totalSteps = $panels.length;
			if (!totalSteps) {
				return;
			}

			const normalizedStep = Math.min(Math.max(parseInt(targetStep, 10) || 1, 1), totalSteps);
			$panels.removeClass('is-active').hide();
			$form.find('.sc-wordform-step-progress-item').removeClass('is-active is-complete');

			$panels.each(function(index) {
				const stepNumber = index + 1;
				if (stepNumber === normalizedStep) {
					$(this).addClass('is-active').show();
				}
				if (stepNumber < normalizedStep) {
					$form.find('.sc-wordform-step-progress-item[data-wordform-step-progress="' + stepNumber + '"]').addClass('is-complete');
				}
			});

			$form.find('.sc-wordform-step-progress-item[data-wordform-step-progress="' + normalizedStep + '"]').addClass('is-active');
			$form.attr('data-wordform-current-step', normalizedStep);

			wordformInitializeStripeElements();
			wordformInitializePaypalElements();
			wordformInitializeSquareElements();
			wordformInitializeAuthorizeNetElements();
			wordformInitializeRatingFields($form);
			wordformInitializeSignatureFields($form);
			wordformInitializeRichEditors($form);
		}

		function wordformInitializeStepPanels() {
			$('.sc-wordform-built-created-form-frontend-display-form').each(function() {
				const $form = $(this);
				if (!$form.find('.sc-wordform-step-panel').length) {
					return;
				}

				wordformSetActiveStep($form, 1);
			});
		}

		function wordformInitializePaypalElements() {
			if (!wordformPaypalEnabled || typeof window.paypal === 'undefined' || typeof window.paypal.Buttons !== 'function') {
				$('.sc-wordform-built-created-form-frontend-display-form').each(function() {
					const $form = $(this);
					if ($form.find('[data-wordform-gateway="paypal"]').length) {
						wordformShowGatewayError($form, 'PayPal is not configured correctly.', 'paypal');
					}
				});
				return;
			}

			$('.sc-wordform-built-created-form-frontend-display-form').each(function() {
				const $form = $(this);
				const formId = $form.prop('id');
				const $paypalGateway = $form.find('[data-wordform-gateway="paypal"]');
				const $stepPanel = $paypalGateway.closest('.sc-wordform-step-panel');
				const existingPaypalRegistry = wordformPaypalFormRegistry[formId];

				if (!$paypalGateway.length || (existingPaypalRegistry && (existingPaypalRegistry.initialized || existingPaypalRegistry.pending))) {
					return;
				}

				if ($stepPanel.length && !$stepPanel.hasClass('is-active')) {
					return;
				}

				const $buttonElement = $paypalGateway.find('.sc-wordform-paypal-button-element');
				if (!$buttonElement.length) {
					return;
				}

				wordformPaypalFormRegistry[formId] = { pending: true };

				const paypalButtons = window.paypal.Buttons({
					style: {
						layout: 'vertical',
						shape: 'pill',
						label: 'paypal',
						tagline: false
					},
					onClick: function(data, actions) {
						$form.data('wordform-requested-gateway', 'paypal');
						wordformClearGatewayError($form, 'paypal');
						if (wordformHasInvalidGatewayConfiguration($form)) {
							wordformShowInvalidGatewayConfigurationError($form);
							wordformSetSubmitProcessingState($form, false);
							return actions.reject();
						}
						wordformSetSubmitProcessingState($form, true);

						return wordformValidateFormBeforePayment($form).then(function() {
							return actions.resolve();
						}).catch(function() {
							return actions.reject();
						});
					},
					createOrder: function() {
						wordformRefreshPaymentSummary($form);
						const totalAmount = wordformGetCurrentPaymentTotal($form);

						if (totalAmount <= 0) {
							wordformShowGatewayError($form, 'Payment total must be greater than zero.', 'paypal');
							wordformSetSubmitProcessingState($form, false);
							return $.Deferred().reject().promise();
						}

						return $.ajax({
							type: 'POST',
							url: sc_wordform_frontend_misc_script_obj.ajax_url,
							dataType: 'json',
							processData: false,
							contentType: false,
							data: wordformBuildGatewayRequestFormData($form, 'sc_wordform_create_paypal_order', {
								wordform_id: formId,
								wordform_name: $form.data('scwordform-form-name'),
								currency: wordformStripeSettings.currency || 'USD'
							}).formData
						}).then(function(orderResponse) {
							if (!orderResponse || orderResponse.status !== 'success' || !orderResponse.orderId) {
								wordformShowGatewayError($form, orderResponse?.comment || 'PayPal order could not be created.', 'paypal');
								wordformSetSubmitProcessingState($form, false);
								return Promise.reject(new Error(orderResponse?.comment || 'PayPal order could not be created.'));
							}

							return orderResponse.orderId;
						}, function() {
							wordformShowGatewayError($form, 'PayPal order request failed.', 'paypal');
							wordformSetSubmitProcessingState($form, false);
							return Promise.reject(new Error('PayPal order request failed.'));
						});
					},
					onApprove: function(data) {
						wordformSetSubmitProcessingState($form, true);
						return $.ajax({
							type: 'POST',
							url: sc_wordform_frontend_misc_script_obj.ajax_url,
							dataType: 'json',
							data: {
								action: 'sc_wordform_capture_paypal_order',
								security: sc_wordform_frontend_misc_script_obj.nonce,
								order_id: data.orderID
							}
						}).then(function(captureResponse) {
							if (!captureResponse || captureResponse.status !== 'success') {
								wordformShowGatewayError($form, captureResponse?.comment || 'PayPal payment could not be captured.', 'paypal');
								wordformSetSubmitProcessingState($form, false);
								return Promise.reject(new Error(captureResponse?.comment || 'PayPal payment could not be captured.'));
							}

							const capturedAmount = captureResponse.amount || wordformGetCurrentPaymentTotal($form).toFixed(2);
							$form.find('.sc-wordform-paypal-payment-status').val(captureResponse.paypalStatus || 'COMPLETED');
							$form.find('.sc-wordform-paypal-order-id').val(captureResponse.orderId || data.orderID || '');
							$form.find('.sc-wordform-paypal-capture-id').val(captureResponse.captureId || '');
							$form.find('.sc-wordform-paypal-payer-id').val(data.payerID || '');
							$form.find('.sc-wordform-paypal-payment-amount').val(capturedAmount);
							$form.find('.sc-wordform-paypal-payment-currency').val(captureResponse.currency || wordformStripeSettings.currency || 'USD');
							$form.data('wordform-payment-approved-gateway', 'paypal');
							wordformClearGatewayError($form, 'paypal');
							$form.trigger('submit');
							return true;
						}, function() {
							wordformShowGatewayError($form, 'PayPal capture request failed.', 'paypal');
							wordformSetSubmitProcessingState($form, false);
							return Promise.reject(new Error('PayPal capture request failed.'));
						}).catch(function(error) {
							if (error && error.message) {
								wordformShowGatewayError($form, error.message, 'paypal');
							}
							wordformSetSubmitProcessingState($form, false);
							return false;
						});
					},
					onCancel: function() {
						wordformShowGatewayError($form, 'PayPal checkout was cancelled.', 'paypal');
						wordformSetSubmitProcessingState($form, false);
						wordformResetPaypalPaymentState($form);
						$form.removeData('wordform-requested-gateway');
					},
					onError: function(error) {
						let errorMessage = 'PayPal checkout failed.';
						if (error && error.message) {
							errorMessage = error.message;
						}
						wordformShowGatewayError($form, errorMessage, 'paypal');
						wordformSetSubmitProcessingState($form, false);
						wordformResetPaypalPaymentState($form);
						$form.removeData('wordform-requested-gateway');
					}
				});

				if (!paypalButtons || (typeof paypalButtons.isEligible === 'function' && !paypalButtons.isEligible())) {
					delete wordformPaypalFormRegistry[formId];
					wordformShowGatewayError($form, 'PayPal is not available for this browser or merchant configuration.', 'paypal');
					return;
				}

				Promise.resolve(paypalButtons.render('#' + $buttonElement.attr('id'))).then(function() {
					wordformPaypalFormRegistry[formId] = { initialized: true };
				}).catch(function(error) {
					delete wordformPaypalFormRegistry[formId];
					wordformShowGatewayError($form, (error && error.message) ? error.message : 'PayPal checkout could not be loaded.', 'paypal');
				});
			});
		}

		wordformInitializeStepPanels();
		wordformInitializePaymentSummaries();
		wordformInitializeStripeElements();
		wordformInitializePaypalElements();
		wordformInitializeSquareElements();
		wordformInitializeAuthorizeNetElements();
		$(window).on('load', function() {
			wordformInitializeStepPanels();
			wordformInitializePaymentSummaries();
			wordformInitializeStripeElements();
			wordformInitializePaypalElements();
			wordformInitializeSquareElements();
			wordformInitializeAuthorizeNetElements();
		});
		setTimeout(function() {
			wordformInitializeStepPanels();
			wordformInitializePaymentSummaries();
			wordformInitializeStripeElements();
			wordformInitializePaypalElements();
			wordformInitializeSquareElements();
			wordformInitializeAuthorizeNetElements();
		}, 300);

		$(document).on('input keyup change blur', '.sc-wordform-built-payment-custom-amount-element, .sc-wordform-built-payment-quantity-element', function() {
			const $form = $(this).closest('.sc-wordform-built-created-form-frontend-display-form');
			wordformResetAllPaymentStates($form);
			wordformRefreshPaymentSummary($form);
		});

		$(document).on('input keyup change blur', '[data-wordform-payment-role="coupon-input"]', function() {
			const $form = $(this).closest('.sc-wordform-built-created-form-frontend-display-form');
			const currentValue = $.trim($(this).val() || '').toUpperCase();
			const appliedCoupon = wordformGetAppliedCouponState($form);

			if (appliedCoupon && appliedCoupon.coupon_code && appliedCoupon.coupon_code !== currentValue) {
				wordformClearAppliedCouponState($form, true);
				wordformResetAllPaymentStates($form);
				wordformRefreshPaymentSummary($form);
			}
		});

		$(document).on('click', '[data-wordform-payment-role="coupon-apply"]', function() {
			const $button = $(this);
			const $form = $button.closest('.sc-wordform-built-created-form-frontend-display-form');
			const $couponWrapper = $button.closest('[data-wordform-payment-role="coupon"]');
			const $input = $couponWrapper.find('[data-wordform-payment-role="coupon-input"]').first();
			const couponCode = $.trim($input.val() || '').toUpperCase();
			const invalidMessage = $.trim($couponWrapper.attr('data-wordform-coupon-invalid-message') || '') || 'Coupon code is not valid.';
			const appliedMessage = $.trim($couponWrapper.attr('data-wordform-coupon-applied-message') || '') || 'Coupon applied successfully.';

			wordformClearGatewayError($form, 'stripe');
			wordformClearGatewayError($form, 'paypal');
			wordformClearGatewayError($form, 'square');
			wordformClearGatewayError($form, 'authorizenet');

			if (!couponCode.length) {
				wordformShowCouponMessage($form, 'Enter a coupon code.', 'error');
				return;
			}

			$input.val(couponCode);
			$button.prop('disabled', true);

			$.ajax({
				type: 'POST',
				url: sc_wordform_frontend_misc_script_obj.ajax_url,
				processData: false,
				contentType: false,
				dataType: 'json',
				data: wordformBuildGatewayRequestFormData($form, 'sc_wordform_validate_coupon', {
					coupon_code: couponCode
				}).formData,
				success: function(response) {
					if (!response || response.status !== 'success') {
						wordformClearAppliedCouponState($form);
						wordformResetAllPaymentStates($form);
						wordformRefreshPaymentSummary($form);
						wordformShowCouponMessage($form, response?.message || invalidMessage, 'error');
						return;
					}

					wordformSetAppliedCouponState($form, {
						coupon_code: response.coupon_code || couponCode,
						discount_amount: response.discount_amount || '0.00',
						discount_type: response.coupon?.discount_type || '',
						discount_value: response.coupon?.discount_value || '0.00',
						apply_to_custom_amount: response.coupon?.apply_to_custom_amount || 'no',
						coupon: response.coupon || {}
					});
					wordformResetAllPaymentStates($form);
					wordformRefreshPaymentSummary($form);
					wordformShowCouponMessage($form, appliedMessage || response?.message || 'Coupon applied successfully.', 'success');
				},
				error: function() {
					wordformClearAppliedCouponState($form);
					wordformResetAllPaymentStates($form);
					wordformRefreshPaymentSummary($form);
					wordformShowCouponMessage($form, 'Coupon request failed.', 'error');
				},
				complete: function() {
					if (!$form.data('wordform-applied-coupon')) {
						$button.prop('disabled', false);
					}
				}
			});
		});

		$(document).on('click', '[data-wordform-payment-role="coupon-remove"]', function() {
			const $form = $(this).closest('.sc-wordform-built-created-form-frontend-display-form');
			const $couponWrapper = $(this).closest('[data-wordform-payment-role="coupon"]');
			const $input = $couponWrapper.find('[data-wordform-payment-role="coupon-input"]').first();

			wordformClearAppliedCouponState($form, true);
			$input.val('');
			wordformResetAllPaymentStates($form);
			wordformRefreshPaymentSummary($form);
		});

		$(document).on('change', '.sc-wordform-built-payment-method-option-input', function() {
			const $form = $(this).closest('.sc-wordform-built-created-form-frontend-display-form');
			wordformResetAllPaymentStates($form);
			wordformClearGatewayError($form, 'stripe');
			wordformClearGatewayError($form, 'paypal');
			wordformClearGatewayError($form, 'square');
			wordformClearGatewayError($form, 'authorizenet');
			wordformSyncPaymentMethodSelector($form);
			wordformInitializeStripeElements();
			wordformInitializePaypalElements();
			wordformInitializeSquareElements();
			wordformInitializeAuthorizeNetElements();
		});

		$(document).on('click', '.sc-wordform-step-next-button', function() {
			const $form = $(this).closest('.sc-wordform-built-created-form-frontend-display-form');
			const $panel = $(this).closest('.sc-wordform-step-panel');
			const currentStep = parseInt($panel.attr('data-wordform-step') || '1', 10);

			if (!wordformValidateCurrentStep($form, $panel)) {
				$panel.get(0)?.scrollIntoView({ behavior: 'smooth', block: 'start' });
				return;
			}

			wordformSetActiveStep($form, currentStep + 1);
			$form.closest('.sc-wordform-built-form-frontend-outermost-div-wrapper').get(0)?.scrollIntoView({ behavior: 'smooth', block: 'start' });
		});

		$(document).on('click', '.sc-wordform-step-previous-button', function() {
			const $form = $(this).closest('.sc-wordform-built-created-form-frontend-display-form');
			const $panel = $(this).closest('.sc-wordform-step-panel');
			const currentStep = parseInt($panel.attr('data-wordform-step') || '1', 10);
			wordformClearStepValidationErrors($panel);
			wordformSetActiveStep($form, currentStep - 1);
			$form.closest('.sc-wordform-built-form-frontend-outermost-div-wrapper').get(0)?.scrollIntoView({ behavior: 'smooth', block: 'start' });
		});

		$(document).on('input', '.sc-wordform-authorizenet-expiry', function() {
			let value = ($(this).val() || '').replace(/[^\d]/g, '').slice(0, 4);
			if (value.length >= 3) {
				value = value.slice(0, 2) + '/' + value.slice(2);
			}
			$(this).val(value);
		});
	   		
		// Front-end Users Form Submission - Single Page Multiple Form Support
		$('.sc-wordform-built-created-form-frontend-display-form').on("submit", function(e) {
			e.preventDefault();		
			// console.log(e);		
			let scWordformWrapperID				= $(this).prop('id');		
			let scWordformWrapper				= $('#'+scWordformWrapperID);
			wordformSyncHCaptchaToken(scWordformWrapper);
			let gCapcthaTokenInputElementName   = scWordformWrapper.find('.wordform-gcaptcha-token-value').prop("name");
			let gCapcthaActionInputElementName  = scWordformWrapper.find('.wordform-gcaptcha-action-value').prop("name");
			let token                           = '';

			wordformSetSubmitProcessingState(scWordformWrapper, true);
			
			let scWordFormOuterMostDivWrapper	= scWordformWrapper.parent();
			let scWordFormID					= scWordformWrapperID;				
			let gCaptchaActionValue             = scWordFormID.replace(/-/g, '_');
			let scWordFormName					= scWordformWrapper.data('scwordform-form-name');

			// Remove form submission report messages if exist
			scWordformWrapper.find('.sc-wordform-submission-success-msg-div-wrapper,.sc-wordform-submisson-fail-msg-div-wrapper').remove();
			scWordformWrapper.prev('.sc-wordform-submission-success-msg-div-wrapper').remove();
			scWordformWrapper.find('.sc-wordform-error-msg').text('');
			const approvedGateway = scWordformWrapper.data('wordform-payment-approved-gateway') || '';
			const selectedGateway = wordformGetSelectedPaymentGateway(scWordformWrapper);
			const hasPaymentMethodSelector = scWordformWrapper.find('[data-wordform-payment-role="method-selector"]').length > 0;

			if (wordformHasInvalidGatewayConfiguration(scWordformWrapper)) {
				wordformShowInvalidGatewayConfigurationError(scWordformWrapper);
				wordformSetSubmitProcessingState(scWordformWrapper, false);
				return;
			}

			if (hasPaymentMethodSelector && !selectedGateway) {
				wordformShowGatewayError(scWordformWrapper, 'Select a payment method to continue.');
				wordformSetSubmitProcessingState(scWordformWrapper, false);
				return;
			}

			if (selectedGateway === 'stripe' && scWordformWrapper.find('[data-wordform-gateway="stripe"]').length > 0 && !scWordformWrapper.data('wordform-stripe-payment-confirmed')) {
				wordformHandleStripePayment(scWordformWrapper);
				return;
			}

			if (selectedGateway === 'paypal' && scWordformWrapper.find('[data-wordform-gateway="paypal"]').length > 0 && approvedGateway !== 'paypal') {
				wordformShowGatewayError(scWordformWrapper, 'Complete PayPal checkout first, then WordForm will submit the form automatically.', 'paypal');
				wordformSetSubmitProcessingState(scWordformWrapper, false);
				return;
			}

			if (selectedGateway === 'square' && scWordformWrapper.find('[data-wordform-gateway="square"]').length > 0 && approvedGateway !== 'square') {
				wordformHandleSquarePayment(scWordformWrapper);
				return;
			}

			if (selectedGateway === 'authorizenet' && scWordformWrapper.find('[data-wordform-gateway="authorizenet"]').length > 0 && approvedGateway !== 'authorizenet') {
				wordformHandleAuthorizeNetPayment(scWordformWrapper);
				return;
			}

			if (!hasPaymentMethodSelector && scWordformWrapper.find('[data-wordform-gateway="stripe"]').length > 0 && approvedGateway !== 'paypal' && !scWordformWrapper.data('wordform-stripe-payment-confirmed')) {
				wordformHandleStripePayment(scWordformWrapper);
				return;
			}

			if (!hasPaymentMethodSelector && scWordformWrapper.find('[data-wordform-gateway="square"]').length > 0 && scWordformWrapper.find('[data-wordform-gateway="stripe"]').length === 0 && approvedGateway !== 'square') {
				wordformHandleSquarePayment(scWordformWrapper);
				return;
			}

			if (!hasPaymentMethodSelector && scWordformWrapper.find('[data-wordform-gateway="authorizenet"]').length > 0 && scWordformWrapper.find('[data-wordform-gateway="stripe"], [data-wordform-gateway="square"]').length === 0 && approvedGateway !== 'authorizenet') {
				wordformHandleAuthorizeNetPayment(scWordformWrapper);
				return;
			}

			if (!hasPaymentMethodSelector && scWordformWrapper.find('[data-wordform-gateway="paypal"]').length > 0 && scWordformWrapper.find('[data-wordform-gateway="stripe"], [data-wordform-gateway="square"], [data-wordform-gateway="authorizenet"]').length === 0 && approvedGateway !== 'paypal') {
				wordformShowGatewayError(scWordformWrapper, 'Complete PayPal checkout first, then WordForm will submit the form automatically.', 'paypal');
				wordformSetSubmitProcessingState(scWordformWrapper, false);
				return;
			}

			wordformValidateFormBeforePayment(scWordformWrapper).done(function() {
				let wordform_formdata_payload = wordformBuildRequestFormData(scWordformWrapper, 'sc_wordform_created_form_submission', true);
				let wordform_formdata = wordform_formdata_payload.formData;
				const submissionValidationToken = wordformGetSubmissionValidationToken(scWordformWrapper);

				if ( submissionValidationToken.length ) {
					wordform_formdata.append( gCapcthaActionInputElementName, gCaptchaActionValue );
					wordformSubmitCreatedFormAjax(scWordformWrapper, scWordFormOuterMostDivWrapper, wordform_formdata_payload);
				}
				else if ( sc_wordform_frontend_misc_script_obj.gcaptcha_site_key.length > 0 
				        && sc_wordform_frontend_misc_script_obj.gcaptcha_version === 'v3' 
							&&  parseInt( sc_wordform_frontend_misc_script_obj?.gcaptcha_form_element_exist ) === 1 ) {
					grecaptcha.ready( function() {
				 		grecaptcha.execute( sc_wordform_frontend_misc_script_obj.gcaptcha_site_key, {action: gCaptchaActionValue } ).then(function(token) {
				 		 	wordform_formdata.append( gCapcthaTokenInputElementName, token );
				 		 	wordform_formdata.append( gCapcthaActionInputElementName, gCaptchaActionValue );
							wordformSubmitCreatedFormAjax(scWordformWrapper, scWordFormOuterMostDivWrapper, wordform_formdata_payload);
				 		 });
					});
				}
				else {
					console.log('NORMAL FORM SUBMISSION OR reCaptcha V2');
					if ( typeof grecaptcha !== 'undefined' ) {
						try {
							token = grecaptcha.getResponse();
							wordform_formdata.append( gCapcthaTokenInputElementName, token );
						}
						catch(error) {
							console.log( error.message );
						}
					}
					wordform_formdata.append( gCapcthaActionInputElementName, gCaptchaActionValue );
					wordformSubmitCreatedFormAjax(scWordformWrapper, scWordFormOuterMostDivWrapper, wordform_formdata_payload);
				}
			});
			
		}); // $('.sc-wordform-built-created-form-frontend-display-form').on("submit", function(e)	
	

	
	// When Selecting files - Supporting multiple input type file elements of same Form
	  var wordform_selected_tmp_files = {}; 	
	  var wordform_selected_total_file_numbers = 0;  

	  function wordformSetUploadError($wrapper, message) {
			$wrapper.text(message || '');
	  }

	  function wordformAppendUploadError($wrapper, message) {
			const currentMessage = $.trim($wrapper.text() || '');
			$wrapper.text(currentMessage ? currentMessage + '\n' + message : message);
	  }

	  $(".sc-wordform-built-upload-element").on("change", function(e) {
			let inputTypeElementkey   = $(this).data('input-typefile-element-key');
		    let UploadErrorMsgWrapper = $('#wordformUploadTempError-' + inputTypeElementkey );
			let uploadMultipleFiles   = $(this).prop('multiple');
			let scWordformWrapperID   = $(this).closest('form').prop('id');			
			let inputTypeFileId       = $(this).prop('id');
			let acceptFileExtensions  = $(this).prop('accept');
			let selectedFileListULId  = $(this).parent().next().prop('id');	
			let scWordFormID 		  = $(this).closest('.sc-wordform-built-created-form-frontend-display-form').prop('id');		
			let validationMessagesJsonStr = $('#'+scWordFormID+'-validationMsg').val().replace( '-', '_');	
			validationMessages        = JSON.parse( validationMessagesJsonStr );
			// console.log('Validation Messages:');
			// console.log(validationMessages);

			// console.log('Upload Multiple');
			// console.log(uploadMultipleFiles);
	
			UploadErrorMsgWrapper.text('');

			console.log('WordForm ID: '+ scWordformWrapperID );
			console.log(acceptFileExtensions);

			// console.log('Upload Config data');
			// console.log( sc_wordform_frontend_misc_script_obj.wordform_upload_config_data );
			// console.log('UPLOAD_MAX_SIZE: '+ sc_wordform_frontend_misc_script_obj.wordform_upload_config_data?.each_file_max_size_allowed );
			// console.log('POST_MAX_SIZE: '+ sc_wordform_frontend_misc_script_obj.wordform_upload_config_data?.all_files_max_size_allowed );
			// console.log('MAX_FILE_UPLOADS: '+ sc_wordform_frontend_misc_script_obj.wordform_upload_config_data?.max_num_files_allowed );				

			// Total Selected Files Number						
			if ( ( wordform_selected_total_file_numbers + e.target.files.length )  > sc_wordform_frontend_misc_script_obj.wordform_upload_config_data?.max_num_files_allowed ) {				
				console.log('Total Selected Files:'+ ( wordform_selected_total_file_numbers + e.target.files.length ) );
				wordformSetUploadError(UploadErrorMsgWrapper, validationMessages.upload_maxinput_msg);
			}
			else if ( wordformSelectedFilesSize( e.target.files ).singleFileSizeExceed === true ) {
				wordformSetUploadError(UploadErrorMsgWrapper, validationMessages.upload_size_msg);
			}
			else if ( wordformSelectedFilesSize( e.target.files ).multipleFileSizeExceed === true ) {
				wordformSetUploadError(UploadErrorMsgWrapper, validationMessages.upload_allsize_msg);
			}
			// Finally count selected file
			else {
				// Input Type File Element attribute Id as index
				wordform_selected_tmp_files[ inputTypeFileId ] ||= [];	
				// console.log( acceptFileExtensions.split(',') );
				for ( const file of e.target.files ) {		
					console.log(file);										
					if ( is_file_selected_once( file.name ) >= 0 ) {
						wordformAppendUploadError(UploadErrorMsgWrapper, file.name + ' - ' + validationMessages.upload_filealready_added_msg);
					}
					// If File Type Accepted | Consider File as uploadable | Multiple Upload - True
					else if ( acceptFileExtensions.split(',').includes( file.type ) && uploadMultipleFiles === true ) {			
						wordform_selected_total_file_numbers += 1;
						wordform_selected_tmp_files[ inputTypeFileId ].push( file );				
						$('#'+selectedFileListULId).append( '<li>' + file.name.trim() + sc_wordform_frontend_misc_script_obj.remove_file_icon + '</li>' );			
					}
					// If File Type Accepted | Consider File as uploadable | Multiple Upload - False															
					else if ( acceptFileExtensions.split(',').includes( file.type ) && uploadMultipleFiles === false ) {			
						// Adding first time for single file upload
						if ( typeof wordform_selected_tmp_files[ inputTypeFileId ][0] === 'undefined') {							
							wordform_selected_total_file_numbers += 1;						
							wordform_selected_tmp_files[ inputTypeFileId ].push( file );					
						}
						// Overwrite old one with new one
						else {							
							wordform_selected_tmp_files[ inputTypeFileId ][0] =  file;
						}
						$('#'+selectedFileListULId).html( '<li>' + file.name.trim() + sc_wordform_frontend_misc_script_obj.remove_file_icon + '</li>' );			
					}
					// If File Type Not Accepted
					else {
						wordformAppendUploadError(UploadErrorMsgWrapper, file.name + ' - ' + validationMessages.upload_allow_msg);
					}
				} // for							
				console.log('Total Selected Files:'+ wordform_selected_total_file_numbers );
		   }
		   console.log(wordform_selected_tmp_files );
	  });

	  // Remove selected file
	  $('body').on('click', '.wordform-remove-selected-file', function(e) {				
		let removeFileName = $(this).parent().text();
		// let inputTypeElementkey = $(this).closest('.wordform-selected-file-names-list').prop('id').split('-')[1];		
		// let UploadErrorMsgWrapper = $('#wordformUploadTempError-' + inputTypeElementkey );		
		console.log( 'Remove File Name:'+ removeFileName );				
		$.each( wordform_selected_tmp_files, function(index, files) {			
			let removeItemIndex = files.findIndex( function(file) { return file?.name?.trim() == removeFileName.trim(); });			
			// Remove or Delete
			if ( removeItemIndex !== -1 ) { files.splice( removeItemIndex, 1 );	}
		});	
		 console.log( wordform_selected_tmp_files );
		 $(this).closest('li').remove();
		 // Update Total File Numbers on Remove
		 wordform_selected_total_file_numbers--;
		 console.log('Total Selected Files:'+ wordform_selected_total_file_numbers );
	  });
	
	  // Check selected Individual | Multiple file | files size
	  function wordformSelectedFilesSize( selectedFiles ) {
		let fileSizeInfo = {};
		let total_size_in_bytes = 0;
		// Check each selected file size exceeded
		$.each( selectedFiles, function( index, file ) {
			total_size_in_bytes += file.size ||=0;
			console.log('Converted file.size into MB: '+ wordform_bytes_to_mb( file.size ) );
			console.log('Each File Size Allowed: '+ parseFloat( sc_wordform_frontend_misc_script_obj.wordform_upload_config_data?.each_file_max_size_allowed ) );
			if ( wordform_bytes_to_mb( file.size ) > parseFloat( sc_wordform_frontend_misc_script_obj.wordform_upload_config_data?.each_file_max_size_allowed ) ) {
				console.log( file.name + ' File Size '+ wordform_bytes_to_mb( file.size ) + ' Exceeded.' );
				fileSizeInfo.singleFileSizeExceed = true;
				return; // Break the loop
			}
		});
		// Merge Earlier file | files size if available with current selected file | files size		
		$.each( wordform_selected_tmp_files, function(index, files ) {
			$.each( files, function( index, file ) {
				total_size_in_bytes += file.size ||=0;
			});			
		});
		// Check all files total sizes exceeded
		if ( wordform_bytes_to_mb( total_size_in_bytes ) > parseFloat( sc_wordform_frontend_misc_script_obj.wordform_upload_config_data?.all_files_max_size_allowed ) ) {
			fileSizeInfo.multipleFileSizeExceed = true;
		}
		console.log('All selected files total size:'+ wordform_bytes_to_mb( total_size_in_bytes ) );
		return fileSizeInfo;
	  }

	  // Is same file selected once
	  function is_file_selected_once( filename ) {
		let addedFileIndex = -1;		
		$.each( wordform_selected_tmp_files, function( index, files ) {
			addedFileIndex = files.findIndex( function(file) { return file.name == filename; } );
			//  console.log('FileIndex: '+ addedFileIndex );
			// If Found - Break the Loop
			if ( addedFileIndex !== -1 ) return;			 
		});
		return addedFileIndex;
	  }

	  // Convert Bytes into MB
	//   function wordform_bytes_to_mb( bytes, decimals = 2) {
	// 	if (!+bytes) return 0;	
	// 	const k = 1024;
	// 	const dm = decimals < 0 ? 0 : decimals;
	// 	// const sizes = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
	// 	// Convert always into MB
	//     const sizes = ['MiB'];
	// 	const i = Math.floor(Math.log(bytes) / Math.log(k))	
	// 	// return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`
	// 	return parseFloat( (bytes / Math.pow(k, i) ).toFixed(dm) );
	// }	  
	  function wordform_bytes_to_mb( wordformBytes = 0 ) {
		if ( wordformBytes === 0 ) return 0;
		return parseFloat( ( wordformBytes / ( 1024 ** 2 ) ).toFixed(2) );
	  }


	  // Range Slider - Mousemove
	  $('body').on('mousemove click change', '.sc-wordform-built-range-element', function(e) {		
		let wordformRangeValueDisplayEle = $('.wordform-range-element-selected-value');
		let offset = $(this).offset();
		let selectedValue = $(this).val();
		console.log( selectedValue );
		console.log( e.pageY - offset.top );

		wordformRangeValueDisplayEle.text( selectedValue );		
		// wordformRangeValueDisplayEle.css({"left" : (e.pageX - offset.left), "top" : ( e.pageY - offset.top ) });
	  });

	  // Range Slider - Mouseout
	  $('body').on('mouseout', '.sc-wordform-built-range-element', function(e) {
		let wordformRangeValueDisplayEle = $('.wordform-range-element-selected-value');
		let selectedValue = $(this).val();
		// console.log( selectedValue );
		let rangeElementWidth = ($(this).width() + 5 ) + 'px';
		// wordformRangeValueDisplayEle.css({"left" : rangeElementWidth, "top" : '55%' });
	  });


	// Date: Date Picker //	
	function norm(value) {
		return String(value || '').replace(/\u00A0/g, ' ').replace(/\s+/g, ' ').trim();
	}

	function wordformApplyCalendarTheme($input) {
		const accentColor = $input.data('calendar-accent-color') || '#2563eb';
		const surfaceColor = $input.data('calendar-surface-color') || '#ffffff';
		const textColor = $input.data('calendar-text-color') || '#0f172a';
		const $picker = $('#ui-datepicker-div');
		if ($picker.length) {
			$picker.css({
				'--wf-calendar-accent': accentColor,
				'--wf-calendar-surface': surfaceColor,
				'--wf-calendar-text': textColor
			});
		}
		if ($input[0] && $input[0]._flatpickr && $input[0]._flatpickr.calendarContainer) {
			$($input[0]._flatpickr.calendarContainer).css({
				'--wf-calendar-accent': accentColor,
				'--wf-calendar-surface': surfaceColor,
				'--wf-calendar-text': textColor
			});
		}
	}

	function wordformEscapeRegexToken(token) {
		return String(token).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
	}

	function wordformReplaceFormatTokens(format, mapping) {
		const pattern = new RegExp(
			Object.keys(mapping)
				.sort((left, right) => right.length - left.length)
				.map(wordformEscapeRegexToken)
				.join('|'),
			'g'
		);
		return String(format || '').replace(pattern, function(match) {
			return mapping[match] || match;
		});
	}

	function wordformConvertDateFormatToFlatpickr(format) {
		const normalized = norm(format || 'yy-mm-dd');
		return wordformReplaceFormatTokens(normalized, {
			'DD': 'l',
			'D': 'D',
			'MM': 'F',
			'M': 'M',
			'yy': 'Y',
			'mm': 'm',
			'm': 'n',
			'dd': 'd',
			'd': 'j'
		});
	}

	function wordformConvertTimeFormatToFlatpickr(format) {
		const normalized = norm(format || 'HH:mm');
		return wordformReplaceFormatTokens(normalized, {
			'TT': 'K',
			'HH': 'H',
			'hh': 'h',
			'mm': 'i',
			'ss': 'S'
		});
	}

	function wordformConvertDateTimeFormatToFlatpickr(format) {
		const parts = splitCombinedFormat(format || 'yy-mm-dd HH:mm');
		return (wordformConvertDateFormatToFlatpickr(parts.dateFmt) + ' ' + wordformConvertTimeFormatToFlatpickr(parts.timeFmt)).trim();
	}

	function wordformParseDisplayDateValue(value, displayFormat) {
		if (typeof flatpickr === 'undefined') {
			return null;
		}
		return flatpickr.parseDate(String(value || '').trim(), wordformConvertDateFormatToFlatpickr(displayFormat || 'yy-mm-dd'), true);
	}

	function wordformParseDisplayDateTimeValue(value, combinedFormat) {
		if (typeof flatpickr === 'undefined') {
			return null;
		}
		return flatpickr.parseDate(String(value || '').trim(), wordformConvertDateTimeFormatToFlatpickr(combinedFormat || 'yy-mm-dd HH:mm'), false);
	}

	function wordformFormatDisplayDateValue(dateObj, displayFormat) {
		if (typeof flatpickr === 'undefined' || !dateObj || isNaN(dateObj.getTime())) {
			return '';
		}
		return flatpickr.formatDate(dateObj, wordformConvertDateFormatToFlatpickr(displayFormat || 'yy-mm-dd'));
	}

	function wordformFormatDisplayDateTimeValue(dateObj, combinedFormat) {
		if (typeof flatpickr === 'undefined' || !dateObj || isNaN(dateObj.getTime())) {
			return '';
		}
		return flatpickr.formatDate(dateObj, wordformConvertDateTimeFormatToFlatpickr(combinedFormat || 'yy-mm-dd HH:mm'));
	}

	function wordformParseIsoDate(value) {
		const normalized = String(value || '').trim();
		if (!/^\d{4}-\d{2}-\d{2}$/.test(normalized)) {
			return null;
		}
		const parts = normalized.split('-');
		return new Date(parseInt(parts[0], 10), parseInt(parts[1], 10) - 1, parseInt(parts[2], 10));
	}

	function wordformParseIsoDateTime(value) {
		const normalized = String(value || '').trim().replace('T', ' ');
		const match = normalized.match(/^(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2})$/);
		if (!match) {
			return null;
		}
		return new Date(
			parseInt(match[1], 10),
			parseInt(match[2], 10) - 1,
			parseInt(match[3], 10),
			parseInt(match[4], 10),
			parseInt(match[5], 10),
			0
		);
	}

	function wordformResolveDateBounds($input) {
		const minDate = wordformParseIsoDate($input.data('min-date'));
		const maxDate = wordformParseIsoDate($input.data('max-date'));
		const siteToday = wordformParseIsoDate($input.data('current-site-date')) || new Date();
		let effectiveMinDate = minDate;
		let effectiveMaxDate = maxDate;

		if (String($input.data('disable-past-dates')) === 'true') {
			effectiveMinDate = effectiveMinDate && effectiveMinDate > siteToday ? effectiveMinDate : siteToday;
		}

		if (String($input.data('disable-future-dates')) === 'true') {
			effectiveMaxDate = effectiveMaxDate && effectiveMaxDate < siteToday ? effectiveMaxDate : siteToday;
		}

		return {
			minDate: effectiveMinDate,
			maxDate: effectiveMaxDate
		};
	}

	function wordformIsDateWithinBounds(dateObj, bounds) {
		if (!dateObj || isNaN(dateObj.getTime())) {
			return false;
		}
		const candidate = new Date(dateObj.getFullYear(), dateObj.getMonth(), dateObj.getDate());
		if (bounds.minDate) {
			const min = new Date(bounds.minDate.getFullYear(), bounds.minDate.getMonth(), bounds.minDate.getDate());
			if (candidate < min) {
				return false;
			}
		}
		if (bounds.maxDate) {
			const max = new Date(bounds.maxDate.getFullYear(), bounds.maxDate.getMonth(), bounds.maxDate.getDate());
			if (candidate > max) {
				return false;
			}
		}
		return true;
	}

	function wordformResolveDateTimeBounds($input) {
		const minDateTime = wordformParseIsoDateTime($input.data('min-datetime'));
		const maxDateTime = wordformParseIsoDateTime($input.data('max-datetime'));
		const siteCurrentDateTime = wordformParseIsoDateTime($input.data('current-site-datetime')) || new Date();
		let effectiveMinDateTime = minDateTime;
		let effectiveMaxDateTime = maxDateTime;

		if (String($input.data('disable-past-dates')) === 'true') {
			effectiveMinDateTime = effectiveMinDateTime && effectiveMinDateTime > siteCurrentDateTime ? effectiveMinDateTime : siteCurrentDateTime;
		}

		if (String($input.data('disable-future-dates')) === 'true') {
			effectiveMaxDateTime = effectiveMaxDateTime && effectiveMaxDateTime < siteCurrentDateTime ? effectiveMaxDateTime : siteCurrentDateTime;
		}

		const minDate = effectiveMinDateTime
			? new Date(effectiveMinDateTime.getFullYear(), effectiveMinDateTime.getMonth(), effectiveMinDateTime.getDate())
			: null;
		const maxDate = effectiveMaxDateTime
			? new Date(effectiveMaxDateTime.getFullYear(), effectiveMaxDateTime.getMonth(), effectiveMaxDateTime.getDate())
			: null;

		return {
			minDate: minDate,
			maxDate: maxDate,
			minDateTime: effectiveMinDateTime,
			maxDateTime: effectiveMaxDateTime
		};
	}

	function wordformIsDateTimeWithinBounds(dateObj, bounds) {
		if (!dateObj || isNaN(dateObj.getTime())) {
			return false;
		}
		if (bounds.minDateTime && dateObj < bounds.minDateTime) {
			return false;
		}
		if (bounds.maxDateTime && dateObj > bounds.maxDateTime) {
			return false;
		}
		return true;
	}

	function wordformGetDateRangeErrorElement($display) {
		return $display.closest('.sc-wordform-built-date-wrapper').find('.sc-wordform-built-date-element-label-wrapper .sc-wordform-error-msg').first();
	}

	function wordformGetDateHiddenField($display) {
		return $display.closest('.sc-wordform-built-date-wrapper').find('.sc-wordform-built-date-element-hidden-rawdate').first();
	}

	function wordformGetDateTimeHiddenField($input) {
		return $input.closest('.sc-wordform-built-datetime-wrapper').find('.sc-wordform-built-datetime-element-hidden-rawdatetime').first();
	}

	function wordformGetDateTimeRangeErrorElement($input) {
		return $input.closest('.sc-wordform-built-datetime-wrapper').find('.sc-wordform-built-date-element-label-wrapper .sc-wordform-error-msg').first();
	}

	function wordformSetDateRangeError($display, message) {
		const $error = wordformGetDateRangeErrorElement($display);
		if ($error.length) {
			$error.text(String(message || '').trim());
		}
	}

	function wordformSetDateTimeRangeError($input, message) {
		const $error = wordformGetDateTimeRangeErrorElement($input);
		if ($error.length) {
			$error.text(String(message || '').trim());
		}
	}

	function wordformResetInvalidDateField($display, $hidden, message) {
		const normalizedMessage = String(message || '').trim();
		if ($hidden && $hidden.length) {
			$hidden.val('');
		}
		if ($display && $display.length) {
			$display.attr('data-wordform-date-invalid-message', normalizedMessage);
			$display.val('');
			if ($display[0] && $display[0]._flatpickr) {
				$display[0]._flatpickr.clear(false);
			}
		}
		wordformSetDateRangeError($display, normalizedMessage);
		return false;
	}

	function wordformResetInvalidDateTimeField($input, $hidden, message) {
		const normalizedMessage = String(message || '').trim();
		if ($hidden && $hidden.length) {
			$hidden.val('');
		}
		if ($input && $input.length) {
			$input.attr('data-wordform-datetime-invalid-message', normalizedMessage);
			$input.val('');
			if ($input[0] && $input[0]._flatpickr) {
				$input[0]._flatpickr.clear(false);
			}
		}
		wordformSetDateTimeRangeError($input, normalizedMessage);
		return false;
	}

	function wordformSyncSingleDateField($display) {
		if (!$display || !$display.length) {
			return true;
		}

		const displayFormat = $display.data("display-format") || "yy-mm-dd";
		const bounds = wordformResolveDateBounds($display);
		const $hidden = wordformGetDateHiddenField($display);
		const typedValue = String($display.val() || '').trim();
		const pendingInvalidMessage = String($display.attr('data-wordform-date-invalid-message') || '').trim();

		if (!typedValue.length) {
			$hidden.val('');
			if (pendingInvalidMessage.length) {
				wordformSetDateRangeError($display, pendingInvalidMessage);
				return false;
			}
			wordformSetDateRangeError($display, '');
			return true;
		}

		$display.removeAttr('data-wordform-date-invalid-message');

		try {
			const parsedDate = wordformParseDisplayDateValue(typedValue, displayFormat);
			if (!parsedDate || isNaN(parsedDate.getTime())) {
				throw new Error('Invalid date');
			}
			const normalizedValue = flatpickr.formatDate(parsedDate, 'Y-m-d');
			$hidden.val(normalizedValue);

			if (wordformIsDateWithinBounds(parsedDate, bounds)) {
				$display.val(wordformFormatDisplayDateValue(parsedDate, displayFormat));
				if ($display[0] && $display[0]._flatpickr) {
					$display[0]._flatpickr.setDate(normalizedValue, false, 'Y-m-d');
				}
				$display.removeAttr('data-wordform-date-invalid-message');
				wordformSetDateRangeError($display, '');
				return true;
			}

			return wordformResetInvalidDateField($display, $hidden, 'Please choose a date within the allowed range.');
		} catch (error) {
			return wordformResetInvalidDateField($display, $hidden, 'Please match the shown format.');
		}
	}

	function wordformSyncSingleDateTimeField($input) {
		if (!$input || !$input.length) {
			return true;
		}

		const combined = $input.data('datetime-format') || 'yy-mm-dd HH:mm';
		const bounds = wordformResolveDateTimeBounds($input);
		const $hidden = wordformGetDateTimeHiddenField($input);
		const pendingInvalidMessage = String($input.attr('data-wordform-datetime-invalid-message') || '').trim();

		const typedValue = norm($input.val());
		if (!typedValue.length) {
			$hidden.val('');
			if (pendingInvalidMessage.length) {
				wordformSetDateTimeRangeError($input, pendingInvalidMessage);
				return false;
			}
			wordformSetDateTimeRangeError($input, '');
			return true;
		}

		$input.removeAttr('data-wordform-datetime-invalid-message');

		const parsedDateTime = wordformParseDisplayDateTimeValue(typedValue, combined);
		if (!parsedDateTime) {
			return wordformResetInvalidDateTimeField($input, $hidden, 'Please match the shown format: ' + combined);
		}

		$hidden.val(toStandard(parsedDateTime));

		if (wordformIsDateTimeWithinBounds(parsedDateTime, bounds)) {
			const formatted = wordformFormatDisplayDateTimeValue(parsedDateTime, combined);
			$input.val(formatted).attr('data-datetime-value', formatted);
			if ($input[0] && $input[0]._flatpickr) {
				$input[0]._flatpickr.setDate(flatpickr.formatDate(parsedDateTime, 'Y-m-d H:i'), false, 'Y-m-d H:i');
			}
			$input.removeAttr('data-wordform-datetime-invalid-message');
			wordformSetDateTimeRangeError($input, '');
			return true;
		}

		return wordformResetInvalidDateTimeField($input, $hidden, 'Please choose a datetime within the allowed range.');
	}

	function wordformSyncDateRangeFields($form) {
		if (!$form || !$form.length) {
			return true;
		}

		let isValid = true;

		$form.find('.sc-wordform-built-date-element').each(function() {
			if (!wordformSyncSingleDateField($(this))) {
				isValid = false;
			}
		});

		$form.find('.sc-wordform-built-datetime-element').each(function() {
			if (!wordformSyncSingleDateTimeField($(this))) {
				isValid = false;
			}
		});

		return isValid;
	}

	$(".sc-wordform-built-date-element").each(function(){
		var $display = $(this);
		var displayFormat = $display.data("display-format") || "yy-mm-dd";
		var defaultDate = String($display.data("default-date") || '').trim();
		var bounds = wordformResolveDateBounds($display);
		var $hidden = wordformGetDateHiddenField($display);
		var flatpickrFormat = wordformConvertDateFormatToFlatpickr(displayFormat);

		if (typeof flatpickr === 'undefined') {
			return;
		}

		flatpickr(this, {
			dateFormat: flatpickrFormat,
			allowInput: true,
			clickOpens: true,
			disableMobile: true,
			defaultDate: defaultDate || null,
			minDate: bounds.minDate || null,
			maxDate: bounds.maxDate || null,
			onReady: function(selectedDates, dateStr, instance) {
				wordformApplyCalendarTheme($display);
				if (defaultDate) {
					$hidden.val(defaultDate);
					$display.val(wordformFormatDisplayDateValue(instance.selectedDates[0] || wordformParseIsoDate(defaultDate), displayFormat));
				}
			},
			onOpen: function() {
				wordformApplyCalendarTheme($display);
			},
			onChange: function(selectedDates) {
				if (selectedDates && selectedDates.length) {
					var normalized = flatpickr.formatDate(selectedDates[0], 'Y-m-d');
					$hidden.val(normalized);
					$display.val(wordformFormatDisplayDateValue(selectedDates[0], displayFormat));
					wordformSetDateRangeError($display, '');
				} else {
					$hidden.val('');
				}
			}
		});

		$display.on('change blur', function(){
			wordformSyncSingleDateField($(this));
		});
	});
	

	// DateTime: Date & Time Picker //


	// // ================================
	// // Frontend DateTime Picker
	// // ================================

	// // ---------- Helpers ----------
	// const norm = s => String(s || '').replace(/\u00A0/g, ' ').replace(/\s+/g, ' ').trim();

	// function splitCombinedFormat(fmt) {
	// 	fmt = norm(fmt);
	// 	const m = fmt.match(/([Hh]{1,2}:[m]{2}(?::[s]{2})?(?:\s?[Tt]{1,2})?)$/);
	// 	let dateFmt = fmt, timeFmt = 'HH:mm';
	// 	if (m) {
	// 	timeFmt = m[1].trim();
	// 	dateFmt = fmt.slice(0, m.index).trim().replace(/,$/, '');
	// 	}
	// 	return { dateFmt, timeFmt };
	// }

	// function is12h(timeFmt) {
	// 	return /t/i.test(timeFmt);
	// }

	// function parseDateTime(dateFmt, timeFmt, text) {
	// 	text = norm(text);
	// 	if (!text) return null;
	// 	const m = text.match(/([01]?\d|2[0-3]):[0-5]\d(?::[0-5]\d)?(?:\s?[APap][Mm])?$/);
	// 	let dateText = text, timeText = '';
	// 	if (m) {
	// 	timeText = m[0].trim();
	// 	dateText = text.slice(0, m.index).trim().replace(/,$/, '');
	// 	}
	// 	try {
	// 	const d = $.datepicker.parseDate(dateFmt, dateText);
	// 	let h = 0, mi = 0, s = 0;
	// 	if (timeText) {
	// 		const t = $.datepicker.parseTime(timeFmt, timeText);
	// 		h = t.hour ?? 0; mi = t.minute ?? 0; s = t.second ?? 0;
	// 	}
	// 	return new Date(d.getFullYear(), d.getMonth(), d.getDate(), h, mi, s);
	// 	} catch {
	// 	return null;
	// 	}
	// }

	// function toStandard(dateObj) {
	// 	return (
	// 	dateObj.getFullYear() +
	// 	'-' + ('0' + (dateObj.getMonth() + 1)).slice(-2) +
	// 	'-' + ('0' + dateObj.getDate()).slice(-2) +
	// 	' ' + ('0' + dateObj.getHours()).slice(-2) +
	// 	':' + ('0' + dateObj.getMinutes()).slice(-2)
	// 	);
	// }

	// // ---------- Main init ----------
	// function initWordformDateTimePicker($input) {
	// 	const combined = $input.data('datetime-format') || 'mm/dd/yy hh:mm TT';
	// 	const { dateFmt, timeFmt } = splitCombinedFormat(combined);
	// 	const ampm = is12h(timeFmt);

	// 	const $hidden = $input.closest('div,li,span,td')
	// 	.find('.sc-wordform-built-datetime-element-hidden-rawdatetime')
	// 	.first();

	// 	// Create hint & error once
	// 	let $hint = $input.siblings('.datetime-format-hint');
	// 	if (!$hint.length) $hint = $('<small class="datetime-format-hint"></small>').insertAfter($input);
	// 	// $hint.text('Display Format: ' + combined);		

	// 	let $err = $input.siblings('.datetime-error-msg');
	// 	if (!$err.length) $err = $('<small class="datetime-error-msg"></small>').insertAfter($hint);

	// 	// Avoid re-entrant recursion by blocking internal triggers
	// 	let insideBeforeShow = false;

	// 	$input.datetimepicker({
	// 	dateFormat: dateFmt,
	// 	timeFormat: timeFmt,
	// 	ampm: ampm,
	// 	controlType: 'select',
	// 	oneLine: true,
	// 	stepMinute: 1,
	// 	showButtonPanel: true,

	// 	beforeShow: function () {
	// 		if (insideBeforeShow) return; // guard against recursion
	// 		insideBeforeShow = true;
	// 		try {
	// 		$(this).datetimepicker('option', {
	// 			dateFormat: dateFmt, timeFormat: timeFmt, ampm: ampm
	// 		});
	// 		const raw = norm($input.data('datetime-value') || $input.val());
	// 		const dateObj = parseDateTime(dateFmt, timeFmt, raw) || new Date();
	// 		$(this).datetimepicker('setDate', dateObj);
	// 		if ($hidden.length) $hidden.val(toStandard(dateObj));
	// 		} catch { /* ignore */ }
	// 		insideBeforeShow = false;
	// 	},

	// 	onSelect: function () {
	// 		const d = $(this).datetimepicker('getDate');
	// 		if (d && $hidden.length) $hidden.val(toStandard(d));
	// 		$err.fadeOut(200);
	// 	}
	// 	});

	// 	// Initial seeding once
	// 	const initRaw = norm($input.data('datetime-value') || $input.val());
	// 	const initDate = parseDateTime(dateFmt, timeFmt, initRaw) || new Date();
	// 	$input.datetimepicker('setDate', initDate);
	// 	if ($hidden.length) $hidden.val(toStandard(initDate));

	// 	// -------------------------------
	// 	// Manual Typing (Live Validation)
	// 	// -------------------------------
	// 	let typingTimer;
	// 	$input.on('keyup', function () {
	// 	clearTimeout(typingTimer);
	// 	const txt = norm($(this).val());
	// 	if (!txt) {
	// 		$err.fadeOut(150);
	// 		return;
	// 	}

	// 	// Debounce: wait 400ms after last key press
	// 	typingTimer = setTimeout(() => {
	// 		const d = parseDateTime(dateFmt, timeFmt, txt);
	// 		if (d) {
	// 		// ✅ Valid input → normalize display & update hidden field
	// 		const formatted = $.datepicker.formatDate(dateFmt, d) + ' ' +
	// 			$.datepicker.formatTime(
	// 			timeFmt,
	// 			{ hour: d.getHours(), minute: d.getMinutes(), second: d.getSeconds() },
	// 			{ ampm: ampm }
	// 			);

	// 		// Update visible input & data attribute
	// 		$input.val(formatted).attr('data-datetime-value', formatted);

	// 		// Update hidden raw field as YYYY-MM-DD HH:mm (for backend storage)
	// 		if ($hidden.length) $hidden.val(toStandard(d));

	// 		$err.fadeOut(150);
	// 		} else {
	// 		// ⚠️ Invalid typing → show warning using expected format hint
	// 		$err.stop(true, true)
	// 			.text('Please match the shown format: ' + combined)
	// 			.fadeIn(200);
	// 		}
	// 	}, 400);
	// 	});



	// }

	// // ---------- Init all ----------
	// $('.sc-wordform-built-datetime-element').each(function () {
	// 	const $this = $(this);
	// 	if (!$this.data('datetimepicker-initialized')) {
	// 	initWordformDateTimePicker($this);
	// 	$this.data('datetimepicker-initialized', true);
	// 	}
	// });


	// ================================
	// Frontend DateTime Picker (Final)
	// ================================

	function splitCombinedFormat(fmt) {
	fmt = norm(fmt);
	const m = fmt.match(/([Hh]{1,2}:[m]{2}(?::[s]{2})?(?:\s?[Tt]{1,2})?)$/);
	let dateFmt = fmt, timeFmt = 'HH:mm';
	if (m) {
		timeFmt = m[1].trim();
		dateFmt = fmt.slice(0, m.index).trim().replace(/,$/, '');
	}
	return { dateFmt, timeFmt };
	}

	function is12h(timeFmt) {
	return /t/i.test(timeFmt);
	}

	function parseDateTime(dateFmt, timeFmt, text) {
	text = norm(text);
	if (!text) return null;
	const m = text.match(/([01]?\d|2[0-3]):[0-5]\d(?::[0-5]\d)?(?:\s?[APap][Mm])?$/);
	let dateText = text, timeText = '';
	if (m) {
		timeText = m[0].trim();
		dateText = text.slice(0, m.index).trim().replace(/,$/, '');
	}
	try {
		const d = $.datepicker.parseDate(dateFmt, dateText);
		let h = 0, mi = 0, s = 0;
		if (timeText) {
		const t = $.datepicker.parseTime(timeFmt, timeText);
		h = t.hour ?? 0; mi = t.minute ?? 0; s = t.second ?? 0;
		}
		return new Date(d.getFullYear(), d.getMonth(), d.getDate(), h, mi, s);
	} catch {
		return null;
	}
	}

	function toStandard(dateObj) {
	return (
		dateObj.getFullYear() +
		'-' + ('0' + (dateObj.getMonth() + 1)).slice(-2) +
		'-' + ('0' + dateObj.getDate()).slice(-2) +
		' ' + ('0' + dateObj.getHours()).slice(-2) +
		':' + ('0' + dateObj.getMinutes()).slice(-2)
	);
	}

	function initWordformDateTimePicker($input) {
	const combined = $input.data('datetime-format') || 'yy-mm-dd HH:mm';
	const bounds = wordformResolveDateTimeBounds($input);
	const flatpickrFormat = wordformConvertDateTimeFormatToFlatpickr(combined);
	const use24Hour = !/\bK\b/.test(flatpickrFormat);

	const $hidden = wordformGetDateTimeHiddenField($input);

	// Create hint only once
	let $hint = $input.siblings('.datetime-format-hint');
	if (!$hint.length) $hint = $('<small class="datetime-format-hint"></small>').insertAfter($input);

	if (typeof flatpickr === 'undefined') {
		return;
	}

	flatpickr($input[0], {
		enableTime: true,
		time_24hr: use24Hour,
		dateFormat: flatpickrFormat,
		allowInput: true,
		clickOpens: true,
		disableMobile: true,
		minDate: bounds.minDateTime || null,
		maxDate: bounds.maxDateTime || null,
		defaultDate: null,
		minuteIncrement: 1,
		onReady: function(selectedDates, dateStr, instance) {
			wordformApplyCalendarTheme($input);
			const raw = norm($input.data('datetime-value') || $hidden.val() || '');
			if (raw.length && raw.toLowerCase() !== 'none') {
				const parsed = wordformParseIsoDateTime(raw);
				if (parsed) {
					instance.setDate(flatpickr.formatDate(parsed, 'Y-m-d H:i'), false, 'Y-m-d H:i');
					$hidden.val(flatpickr.formatDate(parsed, 'Y-m-d H:i'));
					$input.val(wordformFormatDisplayDateTimeValue(parsed, combined)).attr('data-datetime-value', wordformFormatDisplayDateTimeValue(parsed, combined));
				}
			} else {
				$input.val('');
				$hidden.val('');
			}
		},
		onOpen: function() {
			wordformApplyCalendarTheme($input);
		},
		onChange: function(selectedDates) {
			if (selectedDates && selectedDates.length) {
				const normalized = flatpickr.formatDate(selectedDates[0], 'Y-m-d H:i');
				const formatted = wordformFormatDisplayDateTimeValue(selectedDates[0], combined);
				$hidden.val(normalized);
				$input.val(formatted).attr('data-datetime-value', formatted);
				$input.removeAttr('data-wordform-datetime-invalid-message');
				wordformSetDateTimeRangeError($input, '');
			} else {
				$hidden.val('');
			}
		}
	});

	// ----------- Initial Display Setup -----------
	const initRaw = norm($input.data('datetime-value') || $input.val());
	if (initRaw.length && initRaw.toLowerCase() !== 'none') {
		const initDate = wordformParseIsoDateTime(initRaw) || wordformParseDisplayDateTimeValue(initRaw, combined);
		if (initDate) {
			$input.val(wordformFormatDisplayDateTimeValue(initDate, combined)).attr('data-datetime-value', wordformFormatDisplayDateTimeValue(initDate, combined));
			if ($hidden.length) $hidden.val(flatpickr.formatDate(initDate, 'Y-m-d H:i'));
		}
	} else {
		$input.val('');
		if ($hidden.length) {
			$hidden.val('');
		}
	}

	// ----------- Manual Typing (Debounced Validation) -----------
	let typingTimer;
	$input.on('keyup', function () {
		clearTimeout(typingTimer);
		const txt = norm($(this).val());
		if (!txt) {
			if ($hidden.length) {
				$hidden.val('');
			}
			if (!String($input.attr('data-wordform-datetime-invalid-message') || '').trim()) {
				wordformSetDateTimeRangeError($input, '');
			}
			return;
		}

		typingTimer = setTimeout(() => {
			wordformSyncSingleDateTimeField($input);
		}, 400);
	});

	$input.on('blur change', function () {
		wordformSyncSingleDateTimeField($(this));
	});
	}

	// ---------- Init all ----------
	$('.sc-wordform-built-datetime-element').each(function () {
	const $this = $(this);
	if (!$this.data('datetimepicker-initialized')) {
		initWordformDateTimePicker($this);
		$this.data('datetimepicker-initialized', true);
	}
	});

	function wordformParseDisplayTimeValue(value, displayFormat) {
		if (typeof flatpickr === 'undefined') {
			return null;
		}
		return flatpickr.parseDate(
			String(value || '').trim(),
			wordformConvertTimeFormatToFlatpickr(displayFormat || 'HH:mm'),
			false
		);
	}

	function wordformFormatDisplayTimeValue(dateObj, displayFormat) {
		if (typeof flatpickr === 'undefined' || !dateObj || isNaN(dateObj.getTime())) {
			return '';
		}
		return flatpickr.formatDate(dateObj, wordformConvertTimeFormatToFlatpickr(displayFormat || 'HH:mm'));
	}

	function wordformGetTimeHiddenField($input) {
		return $input.closest('.sc-wordform-built-time-wrapper').find('.sc-wordform-built-time-element-hidden-rawtime').first();
	}

	function wordformGetTimeErrorElement($input) {
		return $input.closest('.sc-wordform-built-time-wrapper').find('.sc-wordform-built-time-element-label-wrapper .sc-wordform-error-msg').first();
	}

	function wordformSetTimeError($input, message) {
		const $error = wordformGetTimeErrorElement($input);
		if ($error.length) {
			$error.text(String(message || '').trim());
		}
	}

	function wordformResetInvalidTimeField($input, $hidden, message) {
		const normalizedMessage = String(message || '').trim();
		if ($hidden && $hidden.length) {
			$hidden.val('');
		}
		if ($input && $input.length) {
			$input.attr('data-wordform-time-invalid-message', normalizedMessage);
			$input.val('');
			if ($input[0] && $input[0]._flatpickr) {
				$input[0]._flatpickr.clear(false);
			}
		}
		wordformSetTimeError($input, normalizedMessage);
		return false;
	}

	function wordformSyncSingleTimeField($input) {
		if (!$input || !$input.length) {
			return true;
		}

		const displayFormat = $input.data('time-format') || 'HH:mm';
		const $hidden = wordformGetTimeHiddenField($input);
		const typedValue = norm($input.val());
		const pendingInvalidMessage = String($input.attr('data-wordform-time-invalid-message') || '').trim();

		if (!typedValue.length) {
			$hidden.val('');
			if (pendingInvalidMessage.length) {
				wordformSetTimeError($input, pendingInvalidMessage);
				return false;
			}
			wordformSetTimeError($input, '');
			return true;
		}

		$input.removeAttr('data-wordform-time-invalid-message');

		const parsedTime = wordformParseDisplayTimeValue(typedValue, displayFormat);
		if (!parsedTime || isNaN(parsedTime.getTime())) {
			return wordformResetInvalidTimeField($input, $hidden, 'Please match the shown time format.');
		}

		const normalized = flatpickr.formatDate(parsedTime, 'H:i');
		const formatted = wordformFormatDisplayTimeValue(parsedTime, displayFormat);
		$hidden.val(normalized);
		$input.val(formatted).attr('data-time-value', formatted);
		if ($input[0] && $input[0]._flatpickr) {
			$input[0]._flatpickr.setDate(normalized, false, 'H:i');
		}
		wordformSetTimeError($input, '');
		return true;
	}

	function wordformSyncTimeFields($form) {
		if (!$form || !$form.length) {
			return true;
		}

		let isValid = true;
		$form.find('.sc-wordform-built-time-element').each(function() {
			if (!wordformSyncSingleTimeField($(this))) {
				isValid = false;
			}
		});
		return isValid;
	}

	function initWordformTimePicker($input) {
		if (!$input || !$input.length || typeof flatpickr === 'undefined') {
			return;
		}

		const timeFormat = $input.data('time-format') || 'HH:mm';
		const defaultTime = norm($input.data('default-time') || '');
		const flatpickrFormat = wordformConvertTimeFormatToFlatpickr(timeFormat);
		const use24Hour = !/\bK\b/.test(flatpickrFormat);
		const $hidden = wordformGetTimeHiddenField($input);

		flatpickr($input[0], {
			enableTime: true,
			noCalendar: true,
			time_24hr: use24Hour,
			dateFormat: flatpickrFormat,
			allowInput: true,
			clickOpens: true,
			disableMobile: true,
			minuteIncrement: 1,
			defaultDate: null,
			onReady: function(selectedDates, dateStr, instance) {
				const raw = norm(defaultTime || $hidden.val() || '');
				if (raw.length) {
					const parsed = flatpickr.parseDate(raw, 'H:i', true);
					if (parsed) {
						const normalized = flatpickr.formatDate(parsed, 'H:i');
						const formatted = wordformFormatDisplayTimeValue(parsed, timeFormat);
						instance.setDate(normalized, false, 'H:i');
						$hidden.val(normalized);
						$input.val(formatted).attr('data-time-value', formatted);
						return;
					}
				}
				$input.val('');
				$hidden.val('');
			},
			onChange: function(selectedDates) {
				if (selectedDates && selectedDates.length) {
					const normalized = flatpickr.formatDate(selectedDates[0], 'H:i');
					const formatted = wordformFormatDisplayTimeValue(selectedDates[0], timeFormat);
					$hidden.val(normalized);
					$input.val(formatted).attr('data-time-value', formatted);
					$input.removeAttr('data-wordform-time-invalid-message');
					wordformSetTimeError($input, '');
				} else {
					$hidden.val('');
				}
			}
		});

		const initRaw = norm(defaultTime || $hidden.val() || '');
		if (initRaw.length) {
			const initTime = flatpickr.parseDate(initRaw, 'H:i', true) || wordformParseDisplayTimeValue(initRaw, timeFormat);
			if (initTime) {
				const normalized = flatpickr.formatDate(initTime, 'H:i');
				const formatted = wordformFormatDisplayTimeValue(initTime, timeFormat);
				$input.val(formatted).attr('data-time-value', formatted);
				$hidden.val(normalized);
			}
		} else {
			$input.val('');
			$hidden.val('');
		}

		let typingTimer;
		$input.on('keyup', function () {
			clearTimeout(typingTimer);
			const txt = norm($(this).val());
			if (!txt) {
				$hidden.val('');
				if (!String($input.attr('data-wordform-time-invalid-message') || '').trim()) {
					wordformSetTimeError($input, '');
				}
				return;
			}

			typingTimer = setTimeout(() => {
				wordformSyncSingleTimeField($input);
			}, 350);
		});

		$input.on('blur change', function () {
			wordformSyncSingleTimeField($(this));
		});
	}

	$('.sc-wordform-built-time-element').each(function() {
		const $this = $(this);
		if (!$this.data('timepicker-initialized')) {
			initWordformTimePicker($this);
			$this.data('timepicker-initialized', true);
		}
	});

	wordformInitializeRatingFields();
	wordformInitializeSignatureFields();
	wordformInitializeRichEditors();

	let wordformSignatureResizeTimer = null;
	$(window).on('resize.wordformSignature', function() {
		clearTimeout(wordformSignatureResizeTimer);
		wordformSignatureResizeTimer = setTimeout(function() {
			$('.sc-wordform-built-signature-wrapper').each(function() {
				const resizeHandler = $(this).data('wordform-signature-resize');
				if (typeof resizeHandler === 'function') {
					resizeHandler();
				}
			});
		}, 120);
	});




	// Start Preview & Test Page //

	jQuery(function($){
		const $formWrapper = $('.wordform-preview-n-test-form-wrapper');
		const $buttons = $('.wordform-responsive-toolbar .res-btn');
		const $body = $('body');

		function wordformSetPreviewBreakpointClass(width) {
			$body.removeClass('wordform-preview-width-laptop wordform-preview-width-tablet wordform-preview-width-mobile');

			if (width === '100%') {
				return;
			}

			const numericWidth = parseInt(width, 10);
			if (!Number.isFinite(numericWidth)) {
				return;
			}

			if (numericWidth <= 480) {
				$body.addClass('wordform-preview-width-mobile');
			} else if (numericWidth <= 768) {
				$body.addClass('wordform-preview-width-tablet');
			} else if (numericWidth <= 992) {
				$body.addClass('wordform-preview-width-laptop');
			}
		}

		$buttons.on('click', function(){
			const width = $(this).data('width');

			// Remove active class from all buttons
			$buttons.removeClass('active');

			// Add active class to clicked button (skip reset)
			if(width !== "100%") {
				$(this).addClass('active');
			}

			// Smooth resize with optional bounce
			$formWrapper.addClass('resizing');
			setTimeout(() => { $formWrapper.removeClass('resizing'); }, 300);

			// Apply width
			if(width === "100%") {
				$formWrapper.css({ width: '', margin: '' }); // reset
			} else {
				$formWrapper.css({
					width: width + 'px',
					margin: '0 auto'
				});
			}

			wordformSetPreviewBreakpointClass(width);
		});
	});

	// End Preview & Test Page //

			
}); // $(document)
