PageSourceSearch

https://tunesrecordingstudio.com/_static/??-eJytUdtuwjAM/aGlYRNSy8…GOWtBHO2OmyT5VKzBTwXvknfH/Wh13d1F/N/gLL3Nqc

js tunesrecordingstudio.com collected 2026-10-04 06:02:43 UTC 39,581 bytes, 892 lines download raw bytes

1var mailchimp,mailchimp_cart,mailchimp_billing_email,mailchimp_username_email,mailchimp_registration_email,mailchimp_submitted_email=false,mailchimpReady=function(a){/in/.test(document.readyState)?setTimeout(()=>{mailchimpReady(a)},9):a()};function mailchimpHandleBillingEmail(selector){try{if(!mailchimp_public_data.allowed_to_set_cookies)return;if(mailchimp_public_data.disable_carts)return;var subscribed=document.querySelector("#mailchimp_woocommerce_newsletter");if(!subscribed)subscribed=document.querySelector("#subscribe-to-newsletter");if(!selector)selector="#billing_email";var a=document.querySelector(selector);var b=void 0!==a?a.value:"";if(!mailchimp_cart.valueEmail(b)||mailchimp_submitted_email===b){return false}mailchimp_cart.setEmail(b);var c=mailchimp_public_data.ajax_url+"?action=mailchimp_set_user_by_email";var d=new XMLHttpRequest;d.open("POST",c,!0);d.onload=function(){var successful=d.status>=200&&d.status<400;var msg=successful?"mailchimp.handle_billing_email.request.success":"mailchimp.handle_billing_email.request.error";if(successful){mailchimp_submitted_email=b}console.log(msg,d.responseText)};d.onerror=function(){console.log("mailchimp.handle_billing_email.request.error",d.responseText)};d.setRequestHeader("Content-Type","application/x-www-form-urlencoded");d.setRequestHeader("Accept","application/json");d.send("email="+b+"&mc_language="+mailchimp_public_data.language+"&subscribed="+(subscribed&&subscribed.checked?"1":"0"));return true}catch(a){console.log("mailchimp.handle_billing_email.error",a);mailchimp_submitted_email=!1}}!function(){"use strict";function mailchimpCart(){this.email_types="input[type=email]";this.regex_email=/^([A-Za-z0-9_+\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;this.current_email=null;this.previous_email=null;this.expireUser=function(){this.current_email=null;if(!mailchimp_public_data.allowed_to_set_cookies)return;mailchimp.storage.expire("mailchimp.cart.current_email")};this.expireSaved=function(){if(!mailchimp_public_data.allowed_to_set_cookies)return;mailchimp.storage.expire("mailchimp.cart.items")};this.setEmail=function(a){if(!mailchimp_public_data.allowed_to_set_cookies)return;if(!this.valueEmail(a))return false;this.setPreviousEmail(this.getEmail());mailchimp.storage.set("mailchimp.cart.current_email",this.current_email=a)};this.getEmail=function(){if(!mailchimp_public_data.allowed_to_set_cookies)return;if(this.current_email)return this.current_email;var a=mailchimp.storage.get("mailchimp.cart.current_email",!1);if(!a||!this.valueEmail(a))return false;return this.current_email=a};this.setPreviousEmail=function(a){if(!mailchimp_public_data.allowed_to_set_cookies)return;if(!this.valueEmail(a))return false;mailchimp.storage.set("mailchimp.cart.previous_email",this.previous_email=a)};this.valueEmail=function(a){return this.regex_email.test(a)};return this}var g={extend:function(a,b){for(var c in b||{})b.hasOwnProperty(c)&&(a[c]=b[c]);return a},getQueryStringVars:function(){var a=window.location.search||"",b=[],c={};if(a=a.substr(1),a.length){b=a.split("&");for(var d in b){var e=b[d];if("string"==typeof e){var f=e.split("="),g=f[0],h=f[1];g.length&&("undefined"==typeof c[g]&&(c[g]=[]),c[g].push(h))}}}return c},unEscape:function(a){return decodeURIComponent(a)},escape:function(a){return encodeURIComponent(a)},createDate:function(a,b){a||(a=0);var c=new Date,d=b?c.getDate()-a:c.getDate()+a;return c.setDate(d),c},arrayUnique:function(a){for(var b=a.concat(),c=0;c<b.length;++c)for(var d=c+1;d<b.length;++d)b[c]===b[d]&&b.splice(d,1);return b},objectCombineUnique:function(a){for(var b=a[0],c=1;c<a.length;c++){var d=a[c];for(var e in d)b[e]=d[e]}return b}},h=function(a,b){var c=function(a,b,d){return 1===arguments.length?c.get(a):c.set(a,b,d)};return c.get=function(b,d){return a.cookie!==c._cacheString&&c._populateCache(),void 0==c._cache[b]?d:c._cache[b]},c.defaults={path:"/",secure:true,samesite:"strict"},c.set=function(d,e,f){switch(f={path:f&&f.path||c.defaults.path,domain:f&&f.domain||c.defaults.domain,expires:f&&f.expires||c.defaults.expires,secure:f&&f.secure!==b?f.secure:c.defaults.secure,samesite:f&&f.samesite||c.defaults.samesite},e===b&&(f.expires=-1),typeof f.expires){case"number":f.expires=new Date((new Date).getTime()+1e3*f.expires);break;case"string":f.expires=new Date(f.expires)}return d=encodeURIComponent(d)+"="+(e+"").replace(/[^!#-+\--:<-\[\]-~]/g,encodeURIComponent),d+=f.path?";path="+f.path:"",d+=f.domain?";domain="+f.domain:"",d+=f.expires?";expires="+f.expires.toGMTString():"",d+=f.secure?";secure":"",d+=f.samesite?";samesite="+f.samesite:"",a.cookie=d,c},c.expire=function(a,d){return c.set(a,b,d)},c._populateCache=function(){c._cache={};try{c._cacheString=a.cookie;for(var d=c._cacheString.split("; "),e=0;e<d.length;e++){var f=d[e].indexOf("="),g=decodeURIComponent(d[e].substr(0,f)),f=decodeURIComponent(d[e].substr(f+1));c._cache[g]===b&&(c._cache[g]=f)}}catch(a){console.log(a)}},c.enabled=function(){var a="1"===c.set("cookies.js","1").get("cookies.js");return c.expire("cookies.js"),a}(),c}(document);mailchimp={storage:h,utils:g};mailchimp_cart=new mailchimpCart}();
1mailchimpReady(function(){if(!mailchimp_public_data.allowed_to_set_cookies)return;if(mailchimp_public_data.disable_carts)return;if(void 0===a){var a={site_url:document.location.origin,defaulted:!0,ajax_url:document.location.origin+"/wp-admin?admin-ajax.php"}}try{var b=mailchimp.utils.getQueryStringVars();var subscribed=document.querySelector("#mailchimp_woocommerce_newsletter");var blockSubscribed=document.querySelector("#subscribe-to-newsletter");if(subscribed){subscribed.onchange=function(){mailchimp_submitted_email=null;mailchimpHandleBillingEmail("#billing_email")}}else if(blockSubscribed){blockSubscribed.onchange=function(){mailchimp_submitted_email=null;mailchimpHandleBillingEmail('#contact-fields input[type="email"]')}}mailchimp_username_email=document.querySelector("#username");mailchimp_billing_email=document.querySelector("#billing_email");mailchimp_registration_email=document.querySelector("#reg_email");var mailchimp_username_email_block=document.querySelector('#contact-fields input[type="email"]');if(mailchimp_billing_email){mailchimp_billing_email.onblur=function(){mailchimpHandleBillingEmail("#billing_email")};mailchimp_billing_email.onfocus=function(){mailchimpHandleBillingEmail("#billing_email")}}if(mailchimp_username_email){mailchimp_username_email.onblur=function(){mailchimpHandleBillingEmail("#username")};mailchimp_username_email.onfocus=function(){mailchimpHandleBillingEmail("#username")}}if(mailchimp_registration_email){mailchimp_registration_email.onblur=function(){mailchimpHandleBillingEmail("#reg_email")};mailchimp_registration_email.onfocus=function(){mailchimpHandleBillingEmail("#reg_email")}}if(mailchimp_username_email_block){mailchimp_username_email_block.onblur=function(){mailchimpHandleBillingEmail('#contact-fields input[type="email"]')};mailchimp_username_email_block.onfocus=function(){mailchimpHandleBillingEmail('#contact-fields input[type="email"]')};var typingTimer;mailchimp_username_email_block.addEventListener("keyup",function(){typingTimer&&clearTimeout(typingTimer);typingTimer=setTimeout(function(){if(mailchimp_cart.valueEmail(mailchimp_username_email_block.value)){mailchimpHandleBillingEmail('#contact-fields input[type="email"]')}},2e3)});mailchimp_username_email_block.addEventListener("keydown",function(){typingTimer&&clearTimeout(typingTimer)})}}catch(e){console.log("mailchimp ready error",e)}});;
2/**
3 * Mailchimp Pixel Tracking for WooCommerce
4 *
5 * Listens for WooCommerce events and sends them to the Mailchimp Pixel SDK.
6 * Only tracks if window.$mcSite.pixel.api is available (MC.js loaded).
7 *
8 * @package MailChimp_WooCommerce
9 * @since 1.0.0
10 */
11
12(function ($) {
13	'use strict';
14
15	/**
16	 * Default config for waitForPixelSDK exponential backoff
17	 */
18	const PIXEL_SDK_WAIT_CONFIG = {
19		initialDelayMs: 100,
20		maxDelayMs: 5000,
21		maxAttempts: 20
22	};
23
24	/**
25	 * How long PRODUCT_VIEWED waits on a variable product for WooCommerce to resolve a
26	 * default or deep-linked variation before settling for the parent.
27	 */
28	const VARIATION_RESOLVE_WAIT_MS = 1200;
29
30	/**
31	 * Settle time after a form interaction before re-reading the variation id input.
32	 * The blocks form writes it through the Interactivity API on the next render.
33	 */
34	const VARIATION_INPUT_SETTLE_MS = 150;
35
36	/**
37	 * Mailchimp Pixel Tracking Handler
38	 */
39	const MailchimpPixelTracking = {
40		// Debounce timers for cart fetch calls
41		_atcTimer: null,
42		_rfcTimer: null,
43		_atcFetching: false,
44		_rfcFetching: false,
45		// PRODUCT_VIEWED state for a variable product being resolved to a variation
46		_viewTimer: null,
47		_viewedParent: null,
48		_viewedKeys: null,
49		_inputTimer: null,
50
51		/**
52		 * Initialize tracking.
53		 * Waits for Pixel SDK with exponential backoff, then sends page events and attaches handlers.
54		 */
55		init: function () {
56			const self = this;
57
58			// Registered before the SDK wait on purpose: that wait runs for seconds, and an
59			// integration that resolves its variation early must not race us.
60			window.mcPixel = window.mcPixel || {};
61			window.mcPixel.setVariation = function (variationId, product) {
62				self.setVariation(variationId, product);
63			};
64			document.addEventListener('mailchimp_woocommerce_set_variation', function (event) {
65				const detail = event.detail || {};
66				self.setVariation(detail.variationId, detail.product);
67			});
68
69			this.waitForPixelSDK(PIXEL_SDK_WAIT_CONFIG)
70				.then(function () {
71					self.sendPageEvents();
72					self.attachCartEventListeners();
73					self.interceptStoreApiRequests();
74					console.log('Mailchimp Pixel SDK loaded.');
75				})
76				.catch(function (e) {
77					console.log('Mailchimp Pixel SDK not loaded within timeout. Tracking disabled.', e);
78				});
79		},
80
81		/**
82		 * Wait for Pixel SDK to become available using exponential backoff.
83		 *
84		 * @param {Object} options Optional config
85		 * @param {number} options.initialDelayMs First delay in ms (default 100)
86		 * @param {number} options.maxDelayMs Cap on delay in ms (default 5000)
87		 * @param {number} options.maxAttempts Max number of attempts (default 20)
88		 * @return {Promise<void>}
88 Resolves when SDK is available, rejects after maxAttempts
89		 */
90		waitForPixelSDK: function (options) {
91			const config = options || {};
92			const initialDelayMs = config.initialDelayMs !== undefined ? config.initialDelayMs : PIXEL_SDK_WAIT_CONFIG.initialDelayMs;
93			const maxDelayMs = config.maxDelayMs !== undefined ? config.maxDelayMs : PIXEL_SDK_WAIT_CONFIG.maxDelayMs;
94			const maxAttempts = config.maxAttempts !== undefined ? config.maxAttempts : PIXEL_SDK_WAIT_CONFIG.maxAttempts;
95
96			function isSDKReady() {
97				return typeof window.$mcSite !== 'undefined' &&
98					window.$mcSite.pixel &&
99					typeof window.$mcSite.pixel.api !== 'undefined' &&
100					typeof window.$mcSite.pixel.api.track === 'function' &&
101					window.$mcSite.pixel.installed === true;
102			}
103
104			return new Promise(function (resolve, reject) {
105				let attempt = 0;
106
107				function scheduleCheck() {
108					if (isSDKReady()) {
109						// FIXME: temporary wait to accommodate for not being able to detect ready state
110						console.warn('Pixel SDK - remediation for pixel ready issue')
111						setTimeout(function () {
112							resolve();
113						}, 1000);
114						return;
115					}
116					if (attempt >= maxAttempts) {
117						reject(new Error('Pixel SDK not available'));
118						return;
119					}
120
121					const delay = Math.min(
122						initialDelayMs * Math.pow(2, attempt),
123						maxDelayMs
124					);
125					attempt += 1;
126
127					setTimeout(scheduleCheck, delay);
128				}
129
130				scheduleCheck();
131			});
132		},
133
134		/**
135		 * Synchronous check if Pixel SDK is available (e.g. before each track call).
136		 *
137		 * @return {boolean} True if SDK is available
138		 */
139		isPixelSDKReady: function () {
140			return typeof window.$mcSite !== 'undefined' &&
141				window.$mcSite.pixel &&
142				typeof window.$mcSite.pixel.api !== 'undefined' &&
143				typeof window.$mcSite.pixel.api.track === 'function';
144		},
145
146		/**
147		 * Get cart ID from window.mcPixel
148		 *
149		 * @return {string} Cart ID
150		 */
151		getCartId: function () {
152			return window.mcPixel && window.mcPixel.cartId ? window.mcPixel.cartId : '';
153		},
154
155		/**
156		 * Get the REST API base URL from the localized config.
157		 *
158		 * @return {string} REST base URL
159		 */
160		getRestBase: function () {
161			return (window.mcPixelConfig && window.mcPixelConfig.restBase) || '/wp-json/mailchimp-for-woocommerce/v1/';
162		},
163
164		/**
165		 * Send page-level events based on pre-populated data
166		 */
167		sendPageEvents: function () {
168			if (!window.mcPixel || !window.mcPixel.data) {
169				return;
170			}
171
172			const data = window.mcPixel.data;
173			const events = data.events || [];
174
175			// Send events based on what was set by PHP
176			events.forEach((eventType) => {
177				//console.log('Mailchimp Pixel: Sending event', eventType, data);
178				switch (eventType) {
179					case 'PRODUCT_ADDED_TO_CART':
180						if (data.added_to_cart) {
181							var atcItems = Array.isArray(data.added_to_cart) ? data.added_to_cart : [data.added_to_cart];
182							for (var ai = 0; ai < atcItems.length; ai++) {
183								this.sendProductAddedToCart(atcItems[ai]);
184							}
185						}
186						break;
187					case 'PRODUCT_REMOVED_FROM_CART':
188						if (data.removed_from_cart) {
189							var rfcItems = Array.isArray(data.removed_from_cart) ? data.removed_from_cart : [data.removed_from_cart];
190							for (var ri = 0; ri < rfcItems.length; ri++) {
191								this.sendProductRemovedFromCart(rfcItems[ri]);
192							}
193						}
194						break;
195					case 'IDENTITY':
196						if (data.identity && data.identity.email) {
197							this.sendIdentityEvent(data.identity.email);
198						}
199						break;
200					case 'PRODUCT_VIEWED':
201						// Skip if an add-to-cart or remove-from-cart already fired for the same product.
202						// The cart action implies the view, so firing both is redundant.
203						if (data.product) {
204							const viewedId = String(data.product.productId || data.product.id);
205							const atcArr = Array.isArray(data.added_to_cart) ? data.added_to_cart : (data.added_to_cart ? [data.added_to_cart] : []);
206							const rfcArr = Array.isArray(data.removed_from_cart) ? data.removed_from_cart : (data.removed_from_cart ? [data.removed_from_cart] : []);
207							const atcMatch = atcArr.some(function (p) { return String(p.productId || p.id
207) === viewedId; });
208							const rfcMatch = rfcArr.some(function (p) { return String(p.productId || p.id) === viewedId; });
209
210							if (
211								(events.includes('PRODUCT_ADDED_TO_CART') && atcMatch) ||
212								(events.includes('PRODUCT_REMOVED_FROM_CART') && rfcMatch)
213							) {
214								//console.log('Mailchimp Pixel: Skipping PRODUCT_VIEWED (superseded by cart event for same product)');
215								break;
216							}
217							this.trackProductViewed(data.product);
218						}
219						break;
220					case 'CART_VIEWED':
221						if (data.cart) {
222							this.sendCartViewed(data.cart);
223						}
224						break;
225					case 'CHECKOUT_STARTED':
226						if (data.checkout) {
227							this.sendCheckoutStarted(data.checkout);
228							window.mcPixel._handled.checkout = true;
229						}
230						break;
231					case 'PURCHASED':
232						if (data.order) {
233							this.sendPurchased(data.order);
234						}
235						break;
236					case 'PRODUCT_CATEGORY_VIEWED':
237						if (data.category) {
238							this.sendCategoryViewed(data.category);
239							window.mcPixel._handled.category = true;
240						}
241						break;
242					case 'SEARCH_SUBMITTED':
243						if (data.search) {
244							this.sendSearchSubmitted(data.search);
245							window.mcPixel._handled.search = true;
246						}
247						break;
248				}
249			});
250		},
251
252		/**
253		 * PRODUCT_VIEWED for the single product page.
254		 *
255		 * A variable product renders before the customer has picked anything, so the
256		 * server-side payload only knows the parent. WooCommerce announces the chosen
257		 * variation on the .variations_form with found_variation, so we hold the event
258		 * until that fires - or until it's clear nothing is going to resolve.
259		 *
260		 * @param {Object} product Parent product data from PHP
261		 */
262		trackProductViewed: function (product) {
263			const self = this;
264			this._viewedKeys = this._viewedKeys || {};
265
266			// not a variable product - the server already knew everything there is to know
267			if (!window.mcPixel.data.product_variations) {
268				this.sendProductViewedOnce(product, product.id);
269				return;
270			}
271
272			this._viewedParent = product;
273			this.attachVariationListeners();
274
275			const resolved = this.currentVariationId();
276			if (resolved) {
277				this.sendProductViewedOnce(this.resolveVariationPayload({ variation_id: resolved }), resolved);
278				return;
279			}
280
281			// nothing picked yet, but a default variation or ?attribute_* deep link still
282			// resolves a tick after the form initialises - give WooCommerce that tick
283			// before settling for the parent
284			this._viewTimer = setTimeout(function () {
285				self.sendProductViewedOnce(product, product.id);
286			}, VARIATION_RESOLVE_WAIT_MS);
287		},
288
289		/**
290		 * One PRODUCT_VIEWED per thing actually viewed: the parent, then each variation
291		 * the customer lands on. Switching back to an earlier pick sends nothing, so
292		 * clicking through a dropdown doesn't turn into a burst of events.
293		 *
294		 * @param {Object} product Product data to send
295		 * @param {string} key Dedup key - the variation id, or the parent id
296		 */
297		sendProductViewedOnce: function (product, key) {
298			clearTimeout(this._viewTimer);
299			if (this._viewedKeys[key]) {
300				return;
301			}
302			// only claim the key once it actually went out - an integration can call
303			// setVariation() before the SDK is up, and that must not count as sent
304			if (this.sendProductViewed(product)) {
305				this._viewedKeys[key] = true;
306			}
307		},
308
309		/**
310		 * Public API for themes, swatch plugins and custom templates.
311		 *
312		 * Detection covers what WooCommerce itself ships: the classic variations form,
313		 * and the hidden variation_id input the block form maintains. Anything else - a
314		 * custom swatch UI, a page builder widget, a headless front end - can announce
315		 * the selection itself, either directly:
316		 *
317		 *     window.mcPixel.setVariation( 123 );
318		 *
319		 * or, when it cannot reach our global, by dispatching an event:
320		 *
321		 *     document.dispatchEvent( new CustomEvent(
322		 *         'mailchimp_woocommerce_set_variation',
323		 *         { detail: { variationId: 123 } }
324		 *     ) );
325		 *
326		 * Pass a second argument to supply the whole product payload instead of letting
327		 * us resolve it. Sending the same variation twice is a no-op either way.
328		 *
329		 * @param {number|string} variationId Variation being viewed
330		 * @param {Object} [product] Optional product payload, sent as-is
331		 */
332		setVariation: function (variationId, product) {
333			const id = String(variationId || '');
334
335			if (!id || id === '0') {
336				return;
337			}
338			// an integration may beat PRODUCT_VIEWED to it - nothing to dedup against yet
339			this._viewedKeys = this._viewedKeys || {};
340			this.sendProductViewedOnce(
341				product || this.resolveVariationPayload({ variation_id: id }),
342				id
343			);
344		},
345
346		/**
347		 * found_variation is WooCommerce's own signal that every attribute is chosen and
348		 * a variation matched. Bound delegated off body so a form rendered late - blocks,
349		 * lazy themes, quick-view modals - is still covered.
350		 */
351		attachVariationListeners: function () {
352			const self = this;
353
354			$(document.body).on('found_variation', '.variations_form', function (event, variation) {
355				if (!variation || !variation.variation_id) {
356					return;
357				}
358				self.sendProductViewedOnce(
359					self.resolveVariationPayload(variation),
360					String(variation.variation_id)
361				);
362			});
363
364			// covers the block form, which fires no event at all
365			this.watchVariationInput();
366		},
367
368		/**
369		 * WooCommerce often resolves a variation before we boot - the SDK wait runs over a
370		 * second, and the form fires found_variation during its own init. The form parks
371		 * the answer in its variation_id input, so read that rather than assuming we were
372		 * listening at the right moment.
373		 *
374		 * @return {string} Resolved variation id, or '' when nothing is selected
375		 */
376		currentVariationId: function () {
377			// Classic puts this in .variations_form, blocks puts it in .single_variation_wrap
378			// inside its own form element - so key off the input, not either wrapper.
379			const inputs = document.querySelectorAll('form input[name="variation_id"], form input.variation_id');
380
381			for (let i = 0; i < inputs.length; i++) {
382				const id = parseInt(inputs[i].value, 10);
383				if (id > 0) {
384					return String(id);
385				}
386			}
387
388			return '';
389		},
390
391		/**
392		 * Catch variation changes on templates that announce nothing.
393		 *
394		 * The blocks "Add to Cart with Options" form runs on the Interactivity API and
395		 * fires no jQuery event and no CustomEvent, so found_variation never arrives.
396		 * What it does keep is the hidden variation_id input - WooCommerce renders it
397		 * specifically so "extensions or Express Payment methods" can read the form
398		 * state - so re-read that whenever the customer touches the form. Its value is
399		 * set as a property by the Interactivity API, which a MutationObserver would
400		 * never see, hence driving off the interaction instead.
401		 */
402		watchVariationInput: function () {
403			const self = this;
404
405			const recheck = function (event) {
406				// blocks renders its attribute options as buttons, so change alone misses them
407				if (!event.target || !event.target.closest || !event.target.closest('form')) {
408					return;
409				}
410				clearTimeout(self._inputTimer);
411				self._inputTimer = setTimeout(function () {
412					const id = self.currentVariationId();
413					if (id) {
414						self.sendProductViewedOnce(self.resolveVariationPayload({ variation_id: id }), id);
415					}
416				}, VARIATION_INPUT_SETTLE_MS);
417			};
418
419			document.addEventListener('change', recheck, true);
420			document.addEventListener('click', recheck, true);
421		},
422
423		/**
424		 * Turn a resolved variation into the product shape the pixel expects.
425		 *
426		 * Prefer the server-rendered variation: it carries the sku, categories and
427		 * parent-derived permalink that the event payload has no idea about, and it
428		 * matches what add-to-cart sends for the same variation. Past the pre-render cap
429		 * there is nothing to look up, so patch the parent with what the event does give
430		 * us - the id being right matters more than the rest.
431		 *
432		 * @param {Object} variation found_variation payload (or just {variation_id})
433		 * @return {Object} Product data for the pixel
434		 */
435		resolveVariationPayload: function (variation) {
436			const parent = this._viewedParent || {};
437			const id = String(variation.variation_id);
438			const rendered = window.mcPixel.data.product_variations[id];
439
440			if (rendered) {
441				return rendered;
442			}
443
444			const patched = $.extend({}, parent, {
445				id: id,
446				productId: parent.productId || parent.id || id
447			});
448			if (variation.sku) {
449				patched.sku = variation.sku;
450			}
451			if (variation.display_price !== undefined && variation.display_price !== null) {
452				patched.price = parseFloat(variation.display_price);
453			}
454			if (variation.image && variation.image.full_src) {
455				patched.imageUrl = variation.image.full_src;
456			}
457
458			return patched;
459		},
460
461		/**
462		 * Send PRODUCT_VIEWED event
463		 *
464		 * @param {Object} product Product data
465		 */
466		sendProductViewed: function (product) {
467			if (!this.isPixelSDKReady()) return false;
468
469			window.$mcSite.pixel.api.track('PRODUCT_VIEWED', {
470				product: product
471			}).catch((error) => {
472				console.error('Mailchimp Pixel: Error tracking PRODUCT_VIEWED', error);
473			});
474
475			return true;
476		},
477
478		/**
479		 * Send PRODUCT_ADDED_TO_CART event
480		 *
481		 * @param {Object} product Product data
482		 */
483		sendProductAddedToCart: function (product) {
484			if (!this.isPixelSDKReady()) return;
485
486			const cartId = this.getCartId();
487			const eventData = {
488				cartId: cartId,
489				product: {
490					item: {
491						id: product.id,
492						productId: product.productId,
493						title: product.title,
494						price: product.price,
495						currency: product.currency,
496						sku: product.sku || ''
497					},
498					quantity: product.quantity || 1,
499					price: product.price * (product.quantity || 1),
500					currency: product.currency
501				}
502			};
503
504			window.$mcSite.pixel.api.track('PRODUCT_ADDED_TO_CART', eventData).catch((error) => {
505				console.error('Mailchimp Pixel: Error tracking PRODUCT_ADDED_TO_CART', error);
506			});
507		},
508
509		/**
510		 * Send PRODUCT_REMOVED_FROM_CART event
511		 *
512		 * @param {Object} product Product data
513		 */
514		sendProductRemovedFromCart: function (product) {
515			if (!this.isPixelSDKReady()) return;
516
517			const cartId = this.getCartId();
518			const eventData = {
519				cartId: cartId,
520				product: {
521					item: {
522						id: product.id,
523						productId: product.productId,
524						title: product.title,
525						price: product.price,
526						currency: product.currency,
527						sku: product.sku || ''
528					},
529					quantity: product.quantity || 1,
530					price: product.price * (product.quantity || 1),
531					currency: product.currency
532				}
533			};
534
535			window.$mcSite.pixel.api.track('PRODUCT_REMOVED_FROM_CART', eventData).catch((error) => {
536				console.error('Mailchimp Pixel: Error tracking PRODUCT_REMOVED_FROM_CART', error);
537			});
538		},
539
540		/**
541		 * Send CART_VIEWED event
542		 *
543		 * @param {Object} cart Cart data
544		 */
545		sendCartViewed: function (cart) {
546			if (!this.isPixelSDKReady()) return;
547
548			window.$mcSite.pixel.api.track('CART_VIEWED', {
549				cart: cart
550			}).catch((error) => {
551				console.error('Mailchimp Pixel: Error tracking CART_VIEWED', error);
552			});
553		},
554
555		/**
556		 * Send CHECKOUT_STARTED event
557		 *
558		 * @param {Object} checkout Checkout data
559		 */
560		sendCheckoutStarted: function (checkout) {
561			if (!this.isPixelSDKReady()) return;
562
563			window.$mcSite.pixel.api.track('CHECKOUT_STARTED', {
564				checkout: checkout
565			}).catch((error) => {
566				console.error('Mailchimp Pixel: Error tracking CHECKOUT_STARTED', error);
567			});
568		},
569
570		sendIdentityEvent: function(email) {
571			if (!this.isPixelSDKReady()) return;
572			window.$mcSite.pixel.api.identify({
573				type: 'EMAIL',
574				value: email
575			});
576		},
577
578		/**
579		 * Send PURCHASED event
580		 *
581		 * @param {Object} order Order data
582		 */
583		sendPurchased: function (order) {
584			if (!this.isPixelSDKReady()) return;
585
586			window.$mcSite.pixel.api.track('PURCHASED', {
587				order: order
588			}).catch((error) => {
589				console.error('Mailchimp Pixel: Error tracking PURCHASED', error);
590			});
591		},
592
593		/**
594		 * Send PRODUCT_CATEGORY_VIEWED event
595		 *
596		 * @param {Object} category Category data
597		 */
598		sendCategoryViewed: function (category) {
599			if (!this.isPixelSDKReady()) return;
600
601			window.$mcSite.pixel.api.track('PRODUCT_CATEGORY_VIEWED', category).catch((error) => {
602				console.error('Mailchimp Pixel: Error tracking PRODUCT_CATEGORY_VIEWED', error);
603			});
604		},
605
606		/**
607		 * Send SEARCH_SUBMITTED event
608		 *
609		 * @param {Object} search Search data
610		 */
611		sendSearchSubmitted: function (search) {
612			if (!this.isPixelSDKReady()) return;
613
614			window.$mcSite.pixel.api.track('SEARCH_SUBMITTED', search).catch((error) => {
615				console.error('Mailchimp Pixel: Error tracking SEARCH_SUBMITTED', error);
616			});
617		},
618
619		/**
620		 * Find product by ID from pre-loaded products
621		 *
622		 * @param {number|string} productId Product ID
623		 * @return {Object|null} Product data or null
624		 */
625		findProductById: function (productId) {
626			if (!window.mcPixel || !window.mcPixel.data || !window.mcPixel.data.products) {
627				return null;
628			}
629
630			const products = window.mcPixel.data.products;
631			const id = String(productId);
632
633			for (let i = 0; i < products.length; i++) {
634				if (String(products[i].id) === id) {
635					return products[i];
636				}
637			}
638
639			return null;
640		},
641
642		/**
643		 * Debounced fetch for add-to-cart events.
644		 * Each call resets the timer so rapid-fire triggers coalesce into one
645		 * fetch that drains the entire PHP queue.
646		 * If a fetch is already in flight, schedule another drain after it completes.
647		 */
648		fetchAndTrackAddToCart: function () {
649			var self = this;
650			if (!this.isPixelSDKReady()) return;
651
652			clearTimeout(this._atcTimer);
653			this._atcTimer = setTimeout(function () {
654				self._drainAddToCartQueue();
655			}, 600);
656		},
657
658		_drainAddToCartQueue: async function () {
659			if (this._atcFetching) return;
660			this._atcFetching = true;
661
662			try {
663				var res = await fetch(this.getRestBase() + 'pixel/atc', {
664					method: 'GET',
665					credentials: 'same-origin',
666					headers: { 'Accept': 'application/json' },
667				});
668
669				if (!res.ok) return;
670
671				var data = await res.json();
672				if (!data) return;
673
674				var items = Array.isArray(data) ? data : [data];
675				for (var i = 0; i < items.length; i++) {
676					this.sendProductAddedToCart(items[i]);
677				}
678			} catch (e) {
679				// no-op
680			} finally {
681				this._atcFetching = false;
682			}
683		},
684
685		/**
686		 * Debounced fetch for remove-from-cart events.
687		 * Same debounce pattern as add-to-cart.
688		 */
689		fetchAndTrackRemoveFromCart: function () {
690			var self = this;
691			if (!this.isPixelSDKReady()) return;
692
693			clearTimeout(this._rfcTimer);
694			this._rfcTimer = setTimeout(function () {
695				self._drainRemoveFromCartQueue();
696			}, 600);
697		},
698
699		_drainRemoveFromCartQueue: async function () {
700			if (this._rfcFetching) return;
701			this._rfcFetching = true;
702
703			try {
704				var res = await fetch(this.getRestBase() + 'pixel/rfc', {
705					method: 'GET',
706					credentials: 'same-origin',
707					headers: { 'Accept': 'application/json' },
708				});
709
710				if (!res.ok) return;
711
712				var data = await res.json();
713				if (!data) return;
714
715				var items = Array.isArray(data) ? data : [data];
716				for (var i = 0; i < items.length; i++) {
717					this.sendProductRemovedFromCart(items[i]);
718				}
719			} catch (e) {
720				// no-op
721			} finally {
722				this._rfcFetching = false;
723			}
724		},
725
726		/**
727		 * Attach DOM and jQuery event listeners for cart add/remove.
728		 * These serve as fallback triggers alongside the fetch interceptor.
729		 */
730		attachCartEventListeners: function () {
731			const self = this;
732
733			// Classic themes (jQuery events fired by WooCommerce's add-to-cart.js)
734			$(document.body).on('added_to_cart', function () {
735				self.fetchAndTrackAddToCart();
736			});
737			$(document.body).on('removed_from_cart', function () {
738				self.fetchAndTrackRemoveFromCart();
739			});
740
741			// WC Blocks DOM CustomEvents
742			document.body.addEventListener('wc-blocks_added_to_cart', function () {
743				self.fetchAndTrackAddToCart();
744			});
745			document.body.addEventListener('wc-blocks_removed_from_cart', function () {
746				self.fetchAndTrackRemoveFromCart();
747			});
748		},
749
750		/**
751		 * Intercept window.fetch to detect WooCommerce Store API cart mutations.
752		 *
753		 * This is the most reliable method for catching add-to-cart and remove-from-cart
754		 * in block-based WooCommerce setups, where DOM events may not fire consistently.
755		 * Watches for successful POST requests to the Store API cart endpoints.
756		 */
757		interceptStoreApiRequests: function () {
758			const self = this;
759			const originalFetch = window.fetch;
760
761			window.fetch = function (input, init) {
762				var promise = originalFetch.apply(this, arguments);
763
764				promise.then(function (response) {
765					try {
766						if (!response.ok) return;
767
768						var method = (init && init.method) ? init.method.toUpperCase() :
769							(input instanceof Request ? input.method.toUpperCase() : 'GET');
770						if (method !== 'POST') return;
771
772						var url = typeof input === 'string' ? input :
773							(input instanceof Request ? input.url : String(input));
774
775						if (/wc\/store\/v1\/cart\/add-item/.test(url) || /wc\/store\/v1\/cart\/update-item/.test(url)) {
776							self.fetchAndTrackAddToCart();
777						} else if (/wc\/store\/v1\/cart\/remove-item/.test(url)) {
778							self.fetchAndTrackRemoveFromCart();
779						}
780					} catch (e) {
781						// Silently ignore interceptor errors
782					}
783				}).catch(function () {
784					// Ignore - the original caller handles fetch errors
785				});
786
787				return promise;
788			};
789		},
790	};
791
792	// Initialize when DOM is ready
793	$(document).ready(function () {
794		MailchimpPixelTracking.init();
795	});
796
797})(jQuery);
798;
799(()=>{"use strict";const e=window.wp.hooks,i="mailchimp-woocommerce";let t=!1;function c(){return void 0!==window.$mcSite&&window.$mcSite.pixel&&void 0!==window.$mcSite.pixel.api&&"function"==typeof window.$mcSite.pixel.api.track}function r(){return window.mcPixel&&window.mcPixel.cartId?window.mcPixel.cartId:""}function n(e,i){window.mcPixel&&i&&String(i)!==String(e)&&(window.mcPixel.parentMap||(window.mcPixel.parentMap={}),window.mcPixel.parentMap[String(e)]=String(i))}function o(e,i){t&&c()&&window.$mcSite.pixel.api.track(e,i).catch(function(i){console.error("Mailchimp Pixel Blocks: Error tracking "+e,i)})}function a(e){const i=e.prices||{},t=i.currency_minor_unit||2,c=Math.pow(10,t),r=i.price?parseInt(i.price,10)/c:0,o=String(e.id),a=(e.extensions||{})["mailchimp-pixel"]||{},d=a.product_id?String(a.product_id):function(e){return(window.mcPixel&&window.mcPixel.parentMap||{})[String(e)]||""}(o)||o;return n(o,d),{id:o,productId:d,title:e.name||"",price:r,currency:(i.currency_code||"").toUpperCase(),sku:e.sku||"",imageUrl:e.images&&e.images.length>0?e.images[0].src:"",productUrl:e.permalink||"",vendor:"",categories:[]}}function d(e){const i=e.prices||{},t=i.currency_minor_unit||2,c=Math.pow(10,t),r=i.line_total?parseInt(i.line_total,10)/c:0;return{item:a(e),quantity:e.quantity||1,price:r,currency:(i.currency_code||"").toUpperCase()}}(0,e.addAction)("experimental__woocommerce_blocks-cart-add-item",i,function(e){if(!t)return;if(window.mcPixel&&window.mcPixel._handled.addToCart)return;const i=e.product;if(!i)return;const c=function(e){const i=e.prices||{},t=i.currency_minor_unit||2,c=Math.pow(10,t),r=i.price?parseInt(i.price,10)/c:0,o=String(e.id),a=((e.extensions||{})["mailchimp-pixel"]||{}).product_id||e.parent,d=a?String(a):"";return n(o,d),{id:o,productId:d||o,title:e.name||"",price:r,currency:(i.currency_code||"").toUpperCase(),sku:e.sku||"",imageUrl:e.images&&e.images.length>0?e.images[0].src:"",productUrl:e.permalink||"",vendor:"",categories:(e.categories||[]).map(function(e){return e.name||""})}}(i),a=e.quantity||1;o("PRODUCT_ADDED_TO_CART",{cartId:r(),product:{item:{id:c.id,productId:c.productId,title:c.title,price:c.price,currency:c.currency,sku:c.sku},quantity:a,price:c.price*a,currency:c.currency}}),window.mcPixel&&(window.mcPixel._handled.addToCart=!0,setTimeout(function(){window.mcPixel._handled.addToCart=!1},1e3))}),(0,e.addAction)("experimental__woocommerce_blocks-cart-remove-item",i,function(e){if(!t)return;if(window.mcPixel&&window.mcPixel._handled.removeFromCart)return;const i=e.product;if(!i)return;const c=a(i),n=e.quantity||1;o("PRODUCT_REMOVED_FROM_CART",{cartId:r(),product:{item:{id:c.id,productId:c.productId,title:c.title,price:c.price,currency:c.currency,sku:c.sku},quantity:n,price:c.price*n,currency:c.currency}}),window.mcPixel&&(window.mcPixel._handled.removeFromCart=!0,setTimeout(function(){window.mcPixel._handled.removeFromCart=!1},1e3))}),(0,e.addAction)("experimental__woocommerce_blocks-checkout-render-checkout-form",i,function(e){if(!t)return;if(window.mcPixel&&window.mcPixel._handled.checkout)return;const i=e.storeCart;i&&i.cartItems&&0!==i.cartItems.length&&(o("CHECKOUT_STARTED",{checkout:function(e){const i=e.cartTotals||{},t=i.currency_minor_unit||2,c=Math.pow(10,t),n=(e.cartItems||[]).map(d),o=r();return{id:"checkout_"+o,cartId:o,lineItems:n,subtotalPrice:i.total_items?parseInt(i.total_items,10)/c:0,totalTax:i.total_tax?parseInt(i.total_tax,10)/c:0,totalShipping:i.total_shipping?parseInt(i.total_shipping,10)/c:0,totalPrice:i.total_price?parseInt(i.total_price,10)/c:0,currency:(i.currency_code||"").toUpperCase()}}(i)}),window.mcPixel&&(window.mcPixel._handled.checkout=!0))}),(0,e.addAction)("experimental__woocommerce_blocks-product-list-render",i,function(){t&&(window.mcPixel&&window.mcPixel._handled.category||window.mcPixel&&window.mcPixel.data&&window.mcPixel.data.category&&(o("PRODUCT_CATEGORY_VIEWED",window.mcPixel.data.category),window.mcPixel&&(window.mcPixel._handled.category=!0)))}),(0,e.addAction)("experimental__woocommerce_blocks-product-search",i,function(e){if(!t)return;if(window.mcPixel&&window.mcPixel._handled.search)return;const i=e.searchTerm||"";i&&(o("SEARCH_SUBMITTED",{query:i}),window.mcPixel&&(window.mcPixel._handled.search=!0))}),function(){let e=0;!function i(){if(c())return void setTimeout(function(){t=!0},1e3);if(e>=20)return;const r=Math.min(100*Math.pow(2,e),5e3);e+=1,setTimeout(i,r)}()}()})();;
800(function ($) {
801    'use strict';
802
803    function login_dropdown() {
804        $('.site-header-account').mouseenter(function () {
805            if ($('.account-dropdown .account-wrap').length == 0) {
806                $('.account-dropdown', this).append($('.account-wrap'));
807            }
808
809        });
810    }
811
812    function handleWindow() {
813        var body = document.querySelector('body');
814
815        if (window.innerWidth > body.clientWidth + 5) {
816            body.classList.add('has-scrollbar');
817            body.setAttribute('style', '--scroll-bar: ' + (window.innerWidth - body.clientWidth) + 'px');
818        } else {
819            body.classList.remove('has-scrollbar');
820        }
821    }
822
823    function minHeight() {
824        var bodyHeight = $(window).outerHeight(),
825            headerHeight = $('.site-header').outerHeight(true),
826            contentHeight = $('.site-content').height(),
827            contentouterHeight = $('.site-content').outerHeight(true),
828            footerHeight = $('.site-footer').outerHeight(true);
829        if ((bodyHeight - footerHeight - headerHeight - contentouterHeight) > 0) {
830
831            $('.site-content').css({
832                'min-height': bodyHeight - (headerHeight + footerHeight) - (contentouterHeight - contentHeight)
833            });
834        }
835    }
836
837    minHeight();
838    handleWindow();
839    login_dropdown();
840})(jQuery);
841;
842!function(){"use strict";var e=-1<navigator.userAgent.toLowerCase().indexOf("webkit"),t=-1<navigator.userAgent.toLowerCase().indexOf("opera"),n=-1<navigator.userAgent.toLowerCase().indexOf("msie");(e||t||n)&&document.getElementById&&window.addEventListener&&window.addEventListener("hashchange",function(){var e=document.getElementById(location.hash.substring(1));e&&(/^(?:a|select|input|button|textarea)$/i.test(e.tagName)||(e.tabIndex=-1),e.focus())},!1)}();;
843(function ($) {
844    'use strict';
845    $( document ).ready(function() {
846        $('.button-search-popup').on('click', function (e) {
847            e.preventDefault();
848            $('html').toggleClass('search-popup-active');
849        });
850
851        $('.site-search-popup-close').on('click', function (e) {
852            e.preventDefault();
853            $('html').toggleClass('search-popup-active');
854        });
855    });
856})(jQuery);;
857(function($){
858	'use strict';
859	$('body').on('click', '.supplero-login-form-ajax button[type="submit"]', (event) => {
860		var $this = $(event.currentTarget);
861		var $form = $this.closest('form');
862		$.ajax({
863			type: 'POST',
864			url: suppleroAjax.ajaxurl,
865			data: $form.serialize(),
866			beforeSend: () => {
867				$form.addClass('loading');
868				$form.find('input,button').prop('disabled', true);
869			},
870			success: (response) => {
871				if (response.status) {
872					$form.find('.result-error').remove();
873					location.reload();
874				} else {
875					if($form.find('.result-error').length <= 0){
876						$form.prepend(`<div class="result-error woocommerce-message woocommerce-error">${response.msg}</div>`);
877					}
878				}
879			},
880			complete: function () {
881				$form.find('input,button').prop('disabled', false);
882				$form.removeClass('loading');
883			}
884		});
885
886		return false;
887	});
888})(jQuery);
889
890;
891/* Elementor bundles are self-contained; this file exists for the elementor-webpack-runtime handle. */
892;

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