HEX
Server: nginx/1.24.0
System: Linux 0c1023d6c65e 6.8.0-137-generic #137-Ubuntu SMP PREEMPT_DYNAMIC Fri Jul 17 20:28:23 UTC 2026 x86_64
User: root (0)
PHP: 8.3.33
Disabled: NONE
Upload Files
File: /var/www/html/wp-content/themes/thegem-elementor/js/thegem-product-page.js
(function ($) {

	'use strict';

	let isTouch = window.gemSettings.isTouch,
		isMobile = $(window).width() < 768 && /Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ? true : false,
		isTabletPortrait = $(window).width() === 768 && isTouch && window.matchMedia("(orientation: portrait)") ? true : false,
		isSticky = $('.single-product-content').attr('data-sticky') === 'yes' ? true : false,
		isAjaxLoad = $('.single-product-content').attr('data-ajax-load') === 'yes' ? true : false,
		isOneByOne = $('.single-product-content-bottom').attr('data-review-layout') === 'one_by_one' ? true : false,
		isGridGallery = $('.product-gallery__grid').attr('data-gallery') === 'grid' ? true : false,
		isMenuVertical = $('.single-product-content').attr('data-menu-vertical') === 'yes' ? true : false,
		isComboboxInit = false,
		isExternalProduct = $('.product-page__wrapper.product-type-external').length > 0,
		isGroupedProduct = $('.product-page__wrapper.product-type-grouped').length > 0,
		isSubscriptionProduct = $('.product-page__wrapper.has-subscription-plans').length > 0,

		productPageScripts = {
			// Initialization the functions
			init: function () {
				productPageScripts.default();
				productPageScripts.tabs();
				productPageScripts.accordion();
				productPageScripts.stickyColumn();
				productPageScripts.rating();
				productPageScripts.productVariable();
				productPageScripts.productQuantity();
				if (isAjaxLoad) {
					productPageScripts.ajaxAddToCart();
				}
				productPageScripts.ajaxAddToWishlist();
				productPageScripts.ajaxRemoveFromWishlist();
				productPageScripts.scrollToReviews();
				productPageScripts.onResize();
			},

			default: function () {
				let $clearSelection = $('.product-page__reset-variations');
				let $popupNotification = $('.thegem-popup-notification-wrap');

				$popupNotification.closest('#main').addClass('over-header');

				setTimeout(() => {
					$clearSelection.removeClass('hidden');
				}, 400);
			},

			// Product page tabs
			tabs: function () {
				let $tabs = $('.thegem-tabs'),
					$tabNavItem = $('.thegem-tabs__nav-item'),
					$tabNavItemActive = $('.thegem-tabs__nav-item--active'),
					$line = $('.thegem-tabs__nav-slide'),
					isVertical = $tabs.attr("data-type") === 'vertical',
					activeClass = 'thegem-tabs__nav-item--active',
					$accItemTitle = $('.thegem-accordion__item-title'),
					$accItemBody = $('.thegem-accordion__item-body'),
					accActiveClass = 'thegem-accordion__item--active',

					getPosition = ($target) => {
						let $position = {
							top: $target.offsetTop,
							left: $target.offsetLeft
						};
						return $position;
					},

					animateLine = ($target, $ln) => {
						let currentWidth = $target.offsetWidth,
							currentHeight = $target.offsetHeight,
							currentPos = getPosition($target);

						if (isVertical) {
							$ln[0].style.top = currentPos.top + 'px';
							$ln[0].style.height = currentHeight + 'px';
						} else {
							$ln[0].style.left = currentPos.left + 'px';
							$ln[0].style.width = currentWidth + 'px';
						}
					},

					onLoadLine = () => {
						animateLine($tabNavItemActive[0], $line);
					};

				$tabNavItem.each(function (index, el) {
					onLoadLine();

					setTimeout(function () {
						$line[0].style.transition = '0.25s ease';
					}, 200);
				});

				$tabNavItem.on('click', function (e) {
					let currentAttrvalue = '[id="' + $(this).attr('data-id') + '"]';

					$tabNavItem.removeClass(activeClass);
					$(this).addClass(activeClass);
					$accItemTitle.removeClass(accActiveClass);
					$accItemBody.filter(currentAttrvalue).prev().addClass(accActiveClass);
					$accItemBody.hide().filter(currentAttrvalue).show();

					animateLine(e.currentTarget, $line);
					if (window.tgpLazyItems !== undefined) {
						window.tgpLazyItems.scrollHandle();
					}
				});
			},

			// Product page accordion
			accordion: function () {
				let $accItem = $('.thegem-accordion__item'),
					$accItemTitle = $('.thegem-accordion__item-title'),
					$accItemBody = $('.thegem-accordion__item-body'),
					$tabNavItem = $('.thegem-tabs__nav-item'),
					activeClass = 'thegem-accordion__item--active',
					tabActiveClass = 'thegem-tabs__nav-item--active';

				$accItemTitle.click(function(e){
					const current = $(this).attr('data-id');
					const currentAttrValue = '[id="' + $(this).attr('data-id') + '"]';

					if ($(window).width() < 768) {
						setTimeout(() => {
							const topPosition = $(e.target).offset().top;
							//window.scrollTo({top: topPosition});
							$('html, body').animate({scrollTop: topPosition - 100}, 400);
						}, 250);
					}

					if($(e.target).is('.thegem-accordion__item--active')){
						$(this).removeClass(activeClass);
						$('.thegem-accordion__item-body:visible').slideUp(300);
					} else {
						$accItemTitle.removeClass(activeClass).filter(this).addClass(activeClass);
						$accItemBody.slideUp(300).filter(currentAttrValue).slideDown(300);
					}

					$tabNavItem.removeClass(tabActiveClass);
					$('.thegem-tabs__nav-item[data-id=' + current + ']').addClass(tabActiveClass);
					if (window.tgpLazyItems !== undefined) {
						window.tgpLazyItems.scrollHandle();
					}
				});
			},

			// Product page sticky
			stickyColumn: function () {
				const $wrapper = $('.single-product-content'),
					$leftColumn = $('.product-page__left-column', $wrapper),
					$rightColumn = $('.product-page__right-column', $wrapper),
					$header = $('#site-header-wrapper'),
					headerH = $header.length > 0 && !isMenuVertical ? $header[0].clientHeight : 0;

				const stickyInit = (el) => {
					const offset = headerH - 1;
					const stickyOffset = $wrapper.data('sticky-offset');

					$(el).sticky({
						to: 'top',
						offset: stickyOffset ? stickyOffset : offset,
						effectsOffset: stickyOffset ? stickyOffset : offset,
						parent: $wrapper
					})
				}

				const stickyDestroy = (el) => {
					$(el).sticky('destroy');
				};

				setTimeout(function () {
					let $leftColumnHeight = $leftColumn.height(),
						$rightColumnHeight = $rightColumn.height();

					if (isSticky && !isMobile && !isTabletPortrait) {
						if (!isGridGallery) {
							$leftColumnHeight > $rightColumnHeight ? stickyInit($rightColumn) : stickyInit($leftColumn);
						} else {
							$leftColumnHeight > $rightColumnHeight ? stickyInit($rightColumn) : null;
						}
					}
				}, 200);
			},

			// Product page combobox
			combobox: function () {
				$(".thegem-select").each(function () {
					let template = '<div class="thegem-combobox">';
						template += '<div class="thegem-combobox__trigger">' + $('option:selected', this).text() + '</div>';
						template += '<div class="thegem-combobox__options">';
						$(this).find("option").each(function () {
							template += '<div class="thegem-combobox__options-item" data-value="' + $(this).attr("value") + '">' + $(this).html() + '</div>';
						});
						template += '</div></div>';

					if ($(this).parents(".thegem-combobox-wrap").length === 0){
						$(this).wrap('<div class="thegem-combobox-wrap"></div>');
					}
					//$(this).hide();
					$(this).after(template);
				});

				$(".thegem-combobox__options-item:first-of-type").hover(function () {
					$(this).parents(".thegem-combobox__options").addClass("hover");
				}, function () {
					$(this).parents(".thegem-combobox__options").removeClass("hover");
				});

				$(".thegem-combobox__trigger").on("click", function (e) {
					e.stopPropagation();

					let $count = $('table.variations tr').length,
						$table = $('table.variations'),
						hideIndex = () =>{
							setTimeout(function () {
								$('tr, td.value', $table).css('z-index', 0);
							}, 200);
						};

					$('tr, td.value', $table).css('z-index', 0);
					$(this).parents('tr, td.value').css('z-index', $count);

					if ($(this).parents(".thegem-combobox.opened").length != 0) {
						$(".thegem-combobox").removeClass("opened");
						hideIndex();
						return;
					}

					$('html').one('click', function () {
						$(".thegem-combobox").removeClass("opened");
						hideIndex();
						return;
					});

					$(".thegem-combobox").removeClass("opened");

					$(this).parents(".thegem-combobox").toggleClass("opened");
				});

				$(".thegem-combobox__options-item").on("click", function () {
					$(this).parents(".thegem-combobox-wrap").find("select").val($(this).data("value")).change();
					$(this).parents(".thegem-combobox__options").find(".thegem-combobox__options-item").removeClass("selection");
					$(this).addClass("selection");
					$(this).parents(".thegem-combobox").removeClass("opened");
					$(this).parents(".thegem-combobox").find(".thegem-combobox__trigger").text($(this).text());
				});
			},

			// Product page rating
			rating: function () {
				$(document).on('click mouseenter', '#reviews.woocommerce-Reviews .stars a', function(e) {
					$(this).prevAll().andSelf().addClass('rating-on');
					$(this).nextAll().removeClass('rating-on');
				})
				.on('mouseleave', '#reviews.woocommerce-Reviews .stars', function(e) {
					$( this ).find( 'a' ).removeClass('rating-on');
					if($( this ).hasClass('selected')) {
						$(this).find( 'a.active' ).prevAll().andSelf().addClass('rating-on');
					}
				});
			},

			// Product page variable
			productVariable: function () {
				let $variationForm = $(".variations_form"),
					$combobox = $(".thegem-combobox"),
					$reset = $('.reset_variations'),

					comboboxInit = () => {
						if(!isComboboxInit) {
							setTimeout(() => productPageScripts.combobox(), 250);
							isComboboxInit = true;
						}
					},
					comboboxRefresh = () => {
						productPageScripts.combobox();
						$(".thegem-combobox-wrap").find(".thegem-combobox:last-of-type").remove();
					};

				$variationForm.each(function () {
					comboboxInit();
				});

				$reset.on('click', function(){
					$variationForm.each(function () {
						$(this).on('change', '.variations select', function () {
							comboboxRefresh();

							let text = $('.thegem-combobox__options-item').eq(0).text();
							$combobox.find('.thegem-combobox__trigger').text(text);
						});
					});
				});

				$variationForm.on('woocommerce_update_variation_values', function() {
					comboboxRefresh();

					let text = $('.thegem-combobox__options-item').eq(0).text();
					$combobox.find('.thegem-combobox__trigger').text(text);
				});

				//huck for double submit form
				if ( window.history.replaceState ) {
					window.history.replaceState( null, null, window.location.href );
				}
			},

			// Product page quantity
			productQuantity: function () {
				let $form = $('form.cart');

				$('div.quantity:not(.buttons_added)', $form).addClass('buttons_added')
				.append('<button type="button" class="plus" >+</button>')
				.prepend('<button type="button" class="minus" >-</button>');
			},

			// Product page ajax add to cart
			ajaxAddToCart: function () {
				let $wrapper =  $('.single-product-content');

				$wrapper.on('click', '.single_add_to_cart_button', function (e, fragments, cart_hash) {
					e.preventDefault();

					const $thisButton = $(this);
					const $form = $thisButton.closest('form');
					const data = {};
					$form.serializeArray().forEach(el => {
						data[el.name] = el.value
					});
					data['action'] = 'thegem_ajax_add_to_cart';
					data['product_id'] = data.product_id ? data.product_id : $thisButton.val();
					data['add-to-cart'] = data['add-to-cart'] ? data['add-to-cart'] : data.product_id;

					// Check empty and out stock variation
					let variation_check = true
					const variationId = $form.find('input[name=variation_id]').val() || 0

					if ($form.find('input[name=variation_id]').length > 0 && $form.data('product_variations').length > 0) {
						$form.data('product_variations').forEach(variation => {
							if (variationId == 0 || (variation.variation_id == variationId && !variation.is_in_stock)) {
								variation_check = false
							}
						})
					}

					if (!variation_check) return false;

					$(document.body).trigger('adding_to_cart', [$thisButton, data]);

					$.ajax({
						type: 'post',
						url: wc_add_to_cart_params.ajax_url,
						data: data,
						success: function (response) {
							if (response.error && response.product_url) {
								window.location = response.product_url;
								return;
							} else {
								if(response.success) {
									let $addToCartTarget = $('.thegem-popup-notification-wrap');
	
									if ($addToCartTarget) {
										$('.thegem-popup-notification', $addToCartTarget).removeClass('show');
	
										let $cartPopupAdd = $addToCartTarget.find('.thegem-popup-notification.cart');
										$cartPopupAdd.addClass('show');
										setTimeout(function () {
											$cartPopupAdd.removeClass('show');
										}, $cartPopupAdd.data('timing'));
									}
	
									$(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $thisButton]);
									$('.added_to_cart').hide();
								} else {
									if(response.notices && $('.woocommerce-notices-wrapper').length) {
										$('.woocommerce-notices-wrapper').eq(0).html(response.notices);
										var noticesPosition = $('.woocommerce-notices-wrapper').eq(0).offset().top;
										$('html, body').stop().animate({scrollTop:noticesPosition - 100}, 500, 'swing');
									}
								}
							}
						},
					});

					return false;
				});
			},

			// Product page ajax add to wishlist
			ajaxAddToWishlist: function () {
				let $wrapper =  $('.single-product-content');

				$wrapper.on('click', '.add_to_wishlist', function () {
					let $wishlistTarget = $('.thegem-popup-notification-wrap');

					if ($wishlistTarget) {
						$('.thegem-popup-notification', $wishlistTarget).removeClass('show');

						let $wishlistPopupAdd = $wishlistTarget.find('.thegem-popup-notification.wishlist-add');
						$wishlistPopupAdd.addClass('show');
						setTimeout(function () {
							$wishlistPopupAdd.removeClass('show');
						}, $wishlistPopupAdd.data('timing'));
					}
				});
			},

			// Product page ajax remove from wishlist
			ajaxRemoveFromWishlist: function () {
				let $wrapper =  $('.single-product-content');

				$wrapper.on('click', '.remove_from_wishlist', function (e, fragments, cart_hash) {
					let $wishlistTarget = $('.thegem-popup-notification-wrap');

					if ($wishlistTarget) {
						$('.thegem-popup-notification', $wishlistTarget).removeClass('show');

						let $wishlistPopupRemove = $wishlistTarget.find('.thegem-popup-notification.wishlist-remove');
						$wishlistPopupRemove.addClass('show');
						setTimeout(function () {
							$wishlistPopupRemove.removeClass('show');
						}, $wishlistPopupRemove.data('timing'));
					}
				});
			},

			//Scroll to reviews
			scrollToReviews: function() {
				let $wrapper = $('.woocommerce-product-rating .product-reviews-link'),
					$header = $('#site-header')[0],
					$target = isOneByOne ? $('#thegem-reviews.thegem-one-by-one__item ') : $('.product-page__bottom-column'),
					fixedHeight = $('#site-header').height(),
					targetId = '#thegem-reviews',
					targetEl = $('[data-id="thegem-reviews"]')[0];

				$wrapper.on('click', '.woocommerce-review-link', function (e) {
					e.preventDefault();

					if (!$(targetId).is(":visible")) {
					   $(targetEl).trigger('click');
					}

					$(window).scroll(function () {
						if ($(this).scrollTop() > 0) {
							fixedHeight = $header.clientHeight;
						}
					});

					$("html, body").animate({scrollTop: $target.offset().top - fixedHeight}, 500);
				});
			},

			// Product page resize
			onResize: function () {
				let $accItem = $('.thegem-accordion__item'),
					tabView = 'thegem-accordion__item--tab-view',

					initMobileTabs = () => {
						$accItem.removeClass(tabView);
					},

					revertMobileTabs = () => {
						$accItem.addClass(tabView);
					};

				if (isMobile) {
					initMobileTabs();
				} else {
					productPageScripts.tabs();
					revertMobileTabs();
				}

				window.addEventListener("resize", function () {
					isMobile = window.outerWidth < 768 ? true : false;

					if (isMobile) {
						initMobileTabs();
					} else {
						productPageScripts.tabs();
						revertMobileTabs();
					}
				}, false);
			},
		};

	jQuery(window).on('elementor/frontend/init', function () {
		elementorFrontend.hooks.addAction('frontend/element_ready/woocommerce-product-data-tabs.default', function ($scope, $) {
			productPageScripts.tabs();
			productPageScripts.accordion();
			productPageScripts.rating();
		});
		elementorFrontend.hooks.addAction('frontend/element_ready/woocommerce-product-add-to-cart.default', function ($scope, $) {
			productPageScripts.productVariable();
			productPageScripts.productQuantity();
		});
	});

	// Run the function
	$(function () {
		productPageScripts.init();

		$.fn.initProductPageScripts = function () {
			productPageScripts.init();
		};
	});

})(jQuery);