PageSourceSearch

https://baidenmitten.com/wp-content/plugins/caddy/public/js/caddy-public.js?ver=2.1.2

js baidenmitten.com collected 2026-10-07 23:22:43 UTC 23,552 bytes, 804 lines download raw bytes

1(function( $ ) {
2	'use strict';
3
4	//=============================================================================
5	// GLOBAL VARIABLES
6	//=============================================================================
7	var ccWindow = $( '.cc-window' );
8	var cc_quanity_update_send = true;
9	var expectingCartUpdate = false;
10
11
12	//=============================================================================
13	// UTILITY FUNCTIONS
14	//=============================================================================
15	
16	/**
17	 * Generate skeleton HTML for cart items loading state
18	 * 
19	 * @param {number|null} customCount - Optional custom number of skeleton items to display
20	 * @return {string} HTML string containing skeleton loaders
21	 */
22	function getSkeletonHTML(customCount) {
23		const cartCount = customCount || parseInt($('.cc-compass-count').text()) || 1;
24		
25		const skeletonItem = `
26		<div class="cc-skeleton-item">
27			<div class="cc-skeleton cc-skeleton-thumb"></div>
28			<div class="cc-skeleton-content">
29				<div class="cc-skeleton cc-skeleton-line medium"></div>
30				<div class="cc-skeleton cc-skeleton-line short"></div>
31			</div>
32		</div>
33		`;
34		
35		return skeletonItem.repeat(cartCount);
36	}
37
38	/**
39	 * Get WooCommerce AJAX URL for an endpoint
40	 * 
41	 * @param {string} endpoint - The endpoint to get URL for
42	 * @return {string} The complete AJAX URL
43	 */
44	function getWcAjaxUrl(endpoint) {
45		if (cc_ajax_script.wc_ajax_url) {
46			return cc_ajax_script.wc_ajax_url.replace('%%endpoint%%', endpoint);
47		}
48		return '/?wc-ajax=' + endpoint;
49	}
50
51	/**
52	 * Handle common AJAX response for cart operations
53	 * 
54	 * @param {Object} response - The AJAX response
55	 */
56	function handleCartResponse(response) {
57		if (response && response.fragments) {
58			$.each(response.fragments, function(key, value) {
59				$(key).replaceWith(value);
60			});
61			$(document.body).trigger('wc_fragments_refreshed');
62		}
63	}
64	
65	//=============================================================================
66	// CART MANAGEMENT FUNCTIONS
67	//=============================================================================
68	
69	/**
70	 * Load and display the cart screen with updated fragments
71	 *
72	 * @param {string} productAdded - Optional parameter indicating if a product was added ('yes' or 'move_to_cart')
73	 */
74	function cc_cart_screen(productAdded = '') {
75		if (window.cc_cart_ajax && window.cc_cart_ajax.readyState !== 4) {
76			window.cc_cart_ajax.abort();
77		}
78
79		window.cc_cart_ajax = $.ajax({
80			type: 'POST',
81			url: cc_ajax_script.ajaxurl,
82			data: {
83				action: 'caddy_get_cart_fragments',
84				_: new Date().getTime()
85			},
86			cache: false,
87			beforeSend: function() {
88				$('.cc-cart-items').html(getSkeletonHTML());
89			},
90			error: function(xhr, status, error) {
91				if (status !== 'abort') {
92					$('.cc-cart-items').html('<div class="cc-cart-error">Unable to load cart. <a href="' + cc_ajax_script.cart_url + '">View cart page</a>.</div>');
93				}
94			},
95			success: function(response) {
96				handleCartResponse(response);
97
98				var tabs = new Tabby('[data-tabs]');
99				tabs.toggle('#cc-cart');
100
101				if ('yes' == productAdded) {
102					$('.cc-window-wrapper').show();
103				} else if ('move_to_cart' === productAdded) {
104					$('.cc_cart_from_sfl').removeClass('cc_hide_btn');
105					$('.cc_cart_from_sfl').parent().find('.cc-loader').hide();
106					$('.cc-coupon .woocommerce-notices-wrapper').remove();
107					$('.cc-cart').removeAttr('hidden');
108				}
109			}
110		});
111	}
112
113	/**
114	 * Update cart item quantity
115	 * @param {string} cartKey - The cart item key
116	 * @param {number} newQty - The new quantity
117	 */
118	function cc_update_cart_quantity(cartKey, newQty) {
119		$('.cc-cart-items').html(getSkeletonHTML());
120
121		$.ajax({
122			type: 'POST',
123			url: getWcAjaxUrl('cc_update_item_quantity'),
124			data: {
125				cart_key: cartKey,
126				qty: newQty,
127				nonce: cc_ajax_script.nonce
128			},
129			success: handleCartResponse,
130			error: function() {
131				cc_refresh_cart();
132			},
133			complete: function() {
134				$('.cc-window-wrapper').show();
135			}
136		});
137	}
138
139	/**
140	 * Update item quantity in the cart
141	 * Handles quantity increment and decrement buttons
142	 * 
143	 * @param {Object} el - The button element that was clicked
144	 */
145	function cc_quantity_update_buttons(el) {
146		var wrap = $(el).parents('.cc-cart-product-list');
147		var input = $(wrap).find('.cc_item_quantity');
148		var key = $(input).data('key');
149		var number = parseInt($(input).val());
150		var type = $(el).data('type');
151		
152		if ('minus' == type) {
153			number--;
154		} else {
155			number++;
156		}
157		
158		if (number < 1) {
159			// If quantity would be less than 1, trigger remove item instead
160			var removeButton = $(el).closest('.cc-cart-product').find('a.remove_from_cart_button');
161			removeButton.trigger('click');
162			return;
163		}
164
165		cc_update_cart_quantity(key, number);
166	}
167
168	/**
169	 * Remove an item from the cart
170	 * 
171	 * @param {Object} button - The remove button that was clicked
172	 */
173	function cc_remove_item_from_cart(button) {
174		var cartItemKey = button.data('cart_item_key');
175
176		$('.cc-cart-items').html(getSkeletonHTML());
177		$('.cc-compass .ccicon-cart').hide();
178		$('.cc-compass .cc-loader').show();
179
180		$.ajax({
181			type: 'POST',
182			url: getWcAjaxUrl('cc_remove_item_from_cart'),
183			data: {
184				cart_item_key: cartItemKey,
185				nonce: cc_ajax_script.nonce
186			},
187			success: handleCartResponse,
188			error: function() {
189				cc_refresh_cart();
190			},
191			complete: function() {
192				$('.cc-compass .ccicon-cart').show();
193				$('.cc-compass .cc-loader').hide();
194				$('.cc-window-wrapper').show();
195			}
196		});
197	}
198
199	/**
200	 * Display the cart items list in the cart window
201	 */
202	function cc_cart_item_list() {
203		if ( !ccWindow.hasClass( 'visible' ) ) {
204			$( '.cc-compass' ).trigger( 'click' );
205		}
206	}
207
208	/**
209	 * Refresh the cart contents via AJAX
210	 * Gets updated fragments and refreshes the cart display
211	 */
212	function cc_refresh_cart() {
213		if (window.cc_refresh_ajax && window.cc_refresh_ajax.readyState !== 4) {
214			window.cc_refresh_ajax.abort();
215		}
216
217		window.cc_refresh_ajax = $.ajax({
218			type: 'POST',
219			url: cc_ajax_script.ajaxurl,
220			data: {
221				action: 'caddy_get_cart_fragments',
222				_: new Date().getTime()
223			},
224			cache: false,
225			success: handleCartResponse,
226			error: function(xhr, status, error) {
227				if (status !== 'abort') {
228					$('.cc-cart-items').html('<div class="cc-cart-error">Unable to refresh cart. <a href="javascript:void(0)" onclick="cc_refresh_cart()">Try again</a>.</div>');
229				}
230			}
231		});
232	}
233
234	//=============================================================================
235	// COUPON MANAGEMENT FUNCTIONS
236	//=============================================================================
237
238	/**
239	 * Apply a coupon code from the cart screen
240	 */
241	function cc_coupon_code_applied_from_cart_screen() {
242		var coupon_code = $('.cc-coupon-form #cc_coupon_code').val();
243
244		$('#cc-cart').css('opacity', '0.3');
245
246		$.ajax({
247			type: 'POST',
248			url: getWcAjaxUrl('cc_apply_coupon_to_cart'),
249			data: {
250				nonce: cc_ajax_script.nonce,
251				coupon_code: coupon_code
252			},
253			success: handleCartResponse,
254			complete: function() {
255				$('#cc-cart').css('opacity', '1');
256				var tabs = new Tabby('[data-tabs]');
257				tabs.toggle('#cc-cart');
258			}
259		});
260	}
261
262	/**
263	 * Remove a coupon code from the cart screen
264	 * 
265	 * @param {Object} $remove_code - The remove coupon button that was clicked
266	 */
267	function cc_coupon_code_removed_from_cart_screen($remove_code) {
268		var coupon_code_to_remove = $remove_code.parent('.cc-applied-coupon').find('.cc_applied_code').text();
269
270		$('#cc-cart').css('opacity', '0.3');
271
272		$.ajax({
273			type: 'POST',
274			url: getWcAjaxUrl('cc_remove_coupon_code'),
275			data: {
276				nonce: cc_ajax_script.nonce,
277				coupon_code_to_remove: coupon_code_to_remove
278			},
279			success: handleCartResponse,
280			complete: function() {
281				$('#cc-cart').css('opacity', '1');
282				var tabs = new Tabby('[data-tabs]');
283				tabs.toggle('#cc-cart');
284			}
285		});
286	}
287
288	//=============================================================================
289	// SAVE FOR LATER FUNCTIONALITY
290	//=============================================================================
291
292	/**
293	 * Save an item for later
294	 * Moves an item from the cart to the save-for-later list
295	 * 
296	 * @param {Object} $button - The save for later button that was clicked
297	 */
298	function cc_save_for_later($button) {
299		var product_id = $button.data('product_id');
300		var cart_item_key = $button.data('cart_item_key');
301
302		$('#cc-cart').css('opacity', '0.3');
303		$button.addClass('cc_hide_btn');
304		$button.parent().find('.cc-loader').show();
305
306		$.ajax({
307			type: 'POST',
308			url: getWcAjaxUrl('cc_save_for_later'),
309			data: {
310				nonce: cc_ajax_script.nonce,
311				product_id: product_id,
312				cart_item_key: cart_item_key
313			},
314			success: function(response) {
315				handleCartResponse(response);
316				var tabs = new Tabby('[data-tabs]');
317				tabs.toggle('#cc-saves');
318			},
319			complete: function() {
320				$button.removeClass('cc_hide_btn');
321				$button.parent().find('.cc-loader').hide();
322				$('#cc-cart').css('opacity', '1');
323			}
324		});
325	}
326
327	/**
328	 * Move an item from save-for-later to cart
329	 * 
330	 * @param {Object} $button - The move to cart button that was clicked
331	 */
332	function cc_move_to_cart($button) {
333		var product_id = $button.data('product_id');
334
335		$button.addClass('cc_hide_btn');
336		$button.parent().find('.cc-loader').show();
337
338		// First, add to cart using WooCommerce's standard method
339		$.ajax({
340			type: 'POST',
341			url: getWcAjaxUrl('add_to_cart'),
342			data: {
343				product_id: product_id,
344				quantity: 1
345			},
346			success: function(response) {
347				if (response.error) {
348					$button.removeClass('cc_hide_btn');
349					$button.parent().find('.cc-loader').hide();
350					// Handle error - don't remove from SFL
351				} else {
352					// Cart addition successful, now remove from SFL using existing method
353					$.ajax({
354						type: 'POST',
355						url: getWcAjaxUrl('cc_remove_item_from_sfl'),
356						data: {
357							nonce: cc_ajax_script.nonce,
358							product_id: product_id
359						},
360						success: function(sfl_response) {
361							cc_cart_screen('move_to_cart');
362						},
363						error: function() {
364							cc_cart_screen('move_to_cart');
365						}
366					});
367				}
368			},
369			error: function() {
370				$button.removeClass('cc_hide_btn');
371				$button.parent().find('.cc-loader').hide();
372				cc_refresh_cart();
373			}
374		});
375	}
376
377	/**
378	 * Remove an item from the save-for-later list
379	 * 
380	 * @param {Object} button - The remove button that was clicked
381	 */
382	function cc_remove_item_from_save_for_later(button) {
383		var productID = button.data('product_id');
384
385		$('#cc-saves').css('opacity', '0.3');
386
387		$.ajax({
388			type: 'POST',
389			url: getWcAjaxUrl('cc_remove_item_from_sfl'),
390			data: {
391				nonce: cc_ajax_script.nonce,
392				product_id: productID
393			},
394			success: function(response) {
395				handleCartResponse(response);
396				var tabs = new Tabby('[data-tabs]');
397				tabs.toggle('#cc-saves');
398			},
399			complete: function() {
400				$('#cc-saves').css('opacity', '1');
401			}
402		});
403	}
404
405	/**
406	 * Display the saved items list in the cart window
407	 */
408	function cc_saved_item_list() {
409		$( '.cc-compass' ).toggleClass( 'cc-compass-open' );
410		$( 'body' ).toggleClass( 'cc-window-open' );
411
412		$( '.cc-pl-info-container' ).hide();
413		$( '.cc-window-wrapper' ).show();
414
415		$( '.cc-overlay' ).show();
416
417		var tabs = new Tabby( '[data-tabs]' );
418		tabs.toggle( '#cc-saves' );
419
420		ccWindow.animate( { 'right': '0' }, 'slow' ).addClass( 'visible' );
421	}
422
423	/**
424	 * Navigate back to cart from product info view
425	 */
426	function cc_back_to_cart() {
427		$( '.cc-pl-info-container' ).hide();
428		$( '.cc-window-wrapper' ).show();
429	}
430
431	//=============================================================================
432	// DOCUMENT READY - EVENT HANDLERS & INITIALIZATION
433	//=============================================================================
434
435	jQuery( document ).ready( function( $ ) {
436
437		// Initialize cart screen on page load
438		setTimeout( function() {
439			cc_cart_screen();
440		}, 200 );
441
442		//-------------------------------------------------------------------------
443		// ACCESSIBILITY & NAVIGATION
444		//-------------------------------------------------------------------------
445		
446		// Tab usability
447		$( '.cc-nav ul li a' ).mousedown( function() {
448			$( this ).addClass( 'using-mouse' );
449		} );
450
451		$( 'body' ).keydown( function() {
452			$( '.cc-nav ul li a' ).removeClass( 'using-mouse' );
453		} );
454
455		// cc-window tabbing
456		var tabs = new Tabby( '[data-tabs]' );
457
458		// Tab navigation events
459		$( document ).on( 'click', '.cc-nav ul li a', function() {
460			var current_tab = $( this ).attr( 'data-id' );
461			if ( 'cc-cart' === current_tab ) {
462				$( '.cc-pl-upsells-slider' ).resize();
463			}
464		} );
465
466		//-------------------------------------------------------------------------
467		// CART WINDOW INTERACTIONS
468		//-------------------------------------------------------------------------
469		
470		// Clicking outside of mini cart
471		$( document ).mouseup( function( e ) {
472			var container = $( '.cc-window.visible, .cc-compass, #toast-container' );
473
474			if ( !container.is( e.target ) && container.has( e.target ).length === 0 ) {
475				if ( ccWindow.hasClass( 'visible' ) ) {
476
477					$( '.cc-compass' ).toggleClass( 'cc-compass-open' );
478					$( 'body' ).toggleClass( 'cc-window-open' );
479
480					$( '.cc-overlay' ).hide();
481					ccWindow.animate( { 'right': '-1000px' }, 'slow' ).removeClass( 'visible' );
482
483					if ( $( '#toast-container' ).length > 0 ) {
484						$( '#toast-container' ).animate( { 'right': '25px' }, 'fast' ).toggleClass( 'cc-toast-open' );
485					}
486				}
487			}
488		} );
489
490		// Compass click handler (toggle cart window)
491		$(document).on('click', '.cc-compass', function() {
492			$(this).toggleClass('cc-compass-open');
493			$('body').toggleClass('cc-window-open');
494
495			if (ccWindow.hasClass('visible')) {
496				$('.cc-overlay').hide();
497				$('.cc-window-wrapper').hide();
498				ccWindow.animate({'right': '-1000px'}, 'slow').removeClass('visible');
499			} else {
500				$('.cc-overlay').show();
501				$('.cc-window-wrapper').show();
502
503				$('.cc-cart-items').html(getSkeletonHTML());
504				
505				tabs.toggle('#cc-cart');
506				
507				ccWindow.animate({'right': '0'}, 'slow').addClass('visible');
508
509				cc_refresh_cart();
510			}
511		});
512
513		// Close button for cart window
514		$( document ).on( 'click', '.ccicon-x', function() {
515			$( '.cc-overlay' ).hide();
516			ccWindow.animate( { 'right': '-1000px' }, 'slow' ).removeClass( 'visible' );
517			$( '.cc-compass' ).toggleClass( 'cc-compass-open' );
518			$( 'body' ).toggleClass( 'cc-window-open' );
519		} );
520
521		//-------------------------------------------------------------------------
522		// CART ITEM MANAGEMENT
523		//-------------------------------------------------------------------------
524		
525		// Remove cart item
526		$( document ).on( 'click', '.cc-cart-product-list .cc-cart-product a.remove_from_cart_button', function() {
527			var button = $( this );
528			cc_remove_item_from_cart( button );
529		} );
530
531		// Item quantity update
532		$( document ).on( 'click', '.cc_item_quantity_update', function() {
533			var $this = $(this);
534			var quantityInput = $this.siblings('.cc_item_quantity');
535			var currentQuantity = parseInt(quantityInput.val(), 10);
536			
537			if ($this.hasClass('cc_item_quantity_minus') && currentQuantity === 1) {
538				// When quantity is 1 and user clicks minus, remove the item instead
539				var removeButton = $this.closest('.cc-cart-product').find('a.remove_from_cart_button');
540				removeButton.trigger('click');
541				return false; // Prevent any further processing
542			} else {
543				cc_quantity_update_buttons($this);
544			}
545		} );
546		
547		// Cart items list button clicked
548		$( document ).on( 'click', '.cc_cart_items_list', function() {
549			cc_cart_item_list();
550		} );
551
552		// View cart button clicked
553		$( document ).on( 'click', '.added_to_cart.wc-forward, .woocommerce-error .button.wc-forward', function( e ) {
554			e.preventDefault();
555			cc_cart_item_list();
556		} );
557
558		// Product added view cart button
559		$( document ).on( 'click', '.cc-pl-info .cc-pl-actions .cc-view-cart', function() {
560			tabs.toggle( '#cc-cart' );
561		} );
562
563		//-------------------------------------------------------------------------
564		// SAVE FOR LATER FUNCTIONALITY
565		//-------------------------------------------------------------------------
566		
567		// Remove from save for later
568		$( document ).on( 'click', 'a.remove_from_sfl_button', function() {
569			var button = $( this );
570			cc_remove_item_from_save_for_later( button );
571		} );
572
573		// Save for later button click from the Caddy cart screen
574		$( document ).on( 'click', '.save_for_later_btn', function() {
575			cc_save_for_later( $( this ) );
576		} );
577
578		// Move to cart button clicked
579		$( document ).on( 'click', '.cc_cart_from_sfl', function() {
580			cc_move_to_cart( $( this ) );
581		} );
582
583		// Move to cart button
584		$( document ).on( 'click', '.cc_back_to_cart', function() {
585			cc_back_to_cart();
586		} );
587
588		// Saved items list button clicked
589		$( document ).on( 'click', '.cc_saved_items_list', function() {
590			cc_saved_item_list();
591		} );
592
593		// Clicks on a view saved items
594		$( document ).on( 'click', '.cc-view-saved-items', function() {
595			var tabs = new Tabby( '[data-tabs]' );
596			tabs.toggle( '#cc-saves' );
597		} );
598
599		// Handle variations with save for later
600		if ( $( '.variations_form' ).length > 0 ) {
601			$( '.cc_add_product_to_sfl' ).addClass( 'disabled' );
602			$( this ).each( function() {
603				$( this ).on( 'found_variation', function( event, variation ) {
604					$( '.cc_add_product_to_sfl' ).removeClass( 'disabled' );
605				} );
606
607				$( this ).on( 'reset_data', function() {
608					$( '.cc_add_product_to_sfl' ).addClass( 'disabled' );
609				} );
610			} );
611		}
612
613		//-------------------------------------------------------------------------
614		// COUPON HANDLING
615		//-------------------------------------------------------------------------
616		
617		// Apply coupon form submission
618		$( document ).on( 'submit', '#apply_coupon_form', function( e ) {
619			e.preventDefault();
620			cc_coupon_code_applied_from_cart_screen();
621		} );
622
623		// Remove coupon
624		$( document ).on( 'click', '.cc-applied-coupon .cc-remove-coupon', function() {
625			cc_coupon_code_removed_from_cart_screen( $( this ) );
626		} );
627
628		// Coupon form toggle
629		$(document).on('click', '.cc-coupon-title', function() {
630			var $couponForm = $('.cc-coupon-form');
631			var $couponWrapper = $('.cc-coupon');
632			
633			if ($couponForm.is(':hidden')) {
634				$couponWrapper.addClass('cc-coupon-open');
635				$couponForm.slideDown(300);
636			} else {
637				$couponForm.slideUp(300, function() {
638					$couponWrapper.removeClass('cc-coupon-open');
639				});
640			}
641		});
642
643		// Update the error notice click handler
644		$(document).on('click', '.cc-coupon .woocommerce-error', function(e) {
645			var $error = $(this);
646			var clickX = e.pageX - $error.offset().left;
647			
648			if (clickX > $error.width() - 40) {
649				$(this).closest('.woocommerce-notices-wrapper').fadeOut(200);
650			}
651		});
652
653		//-------------------------------------------------------------------------
654		// ADD TO CART HANDLING
655		//-------------------------------------------------------------------------
656		
657		// Add a flag to track the source of the event
658		var handlingOurAjaxResponse = false;
659
660		// Add a flag to prevent double handling
661		var handlingCartUpdate = false;
662
663		// Handle add to cart button clicks for guest users
664		$(document).on('click', '.add_to_cart_button, .single_add_to_cart_button', function() {
665			expectingCartUpdate = true;
666		});
667
668		// Handle WooCommerce cart updates for guest users
669		$('body').on('added_to_cart wc_fragments_refreshed', function(event) {
670			// If this is a fragments refresh after add-to-cart, open cart
671			if (event.type === 'wc_fragments_refreshed' && expectingCartUpdate) {
672				expectingCartUpdate = false;
673				if (!ccWindow.hasClass('visible')) {
674					$('.cc-compass').trigger('click');
675				}
676			}
677		});
678
679		/**
680		 * Handle WooCommerce 'added_to_cart' event
681		 * 
682		 * Triggered when products are successfully added to the cart.
683		 * Manages cart window display based on:
684		 * - Device type (mobile/desktop)
685		 * - User preferences for notifications
686		 * - Whether the product was added from recommendations
687		 * 
688		 * Prevents duplicate event handling with the handlingCartUpdate flag.
689		 * 
690		 * @param {Event} e - The event object
691		 * @param {Object} fragments - Cart fragments returned from WooCommerce
692		 * @param {string} cart_hash - The cart hash
693		 * @param {Object} this_button - The button that triggered the add to cart action
694		 */
695		$('body').on('added_to_cart', function(e, fragments, cart_hash, this_button) {
696
697			if (handlingCartUpdate) {
698				return;
699			}
700
701			handlingCartUpdate = true;
702
703			var cpDeskNotice = $('.cc-compass-desk-notice').val(),
704				cpMobNotice = $('.cc-compass-mobile-notice').val();
705
706			var isRecommendationButton = $(this_button).closest('.cc-pl-recommendations').length > 0;
707
708			if (isRecommendationButton) {
709				cc_cart_screen('', {fragments: fragments, cart_hash: cart_hash});
710			}
711
712			if (cc_ajax_script.is_mobile && !ccWindow.hasClass('visible') && 'mob_disable_notices' === cpMobNotice) {
713				setTimeout(function() {
714					$('.cc-compass').trigger('click');
715					handlingCartUpdate = false;
716				}, 20);
717			} else if (!cc_ajax_script.is_mobile && !ccWindow.hasClass('visible')
718				&& ('desk_disable_notices' === cpDeskNotice || 'desk_notices_caddy_window' === cpDeskNotice || '' === cpDeskNotice)) {
719				setTimeout(function() {
720					$('.cc-compass').trigger('click');
721					handlingCartUpdate = false;
722				}, 20);
723			} else {
724				handlingCartUpdate = false;
725			}
726		});
727
728		// Listen for add to cart form submissions
729		$(document.body).on('submit', 'form.cart', function(e) {
730			e.preventDefault();
731
732			var $form = $(this);
733			var $button = e.originalEvent && e.originalEvent.submitter 
734				? $(e.originalEvent.submitter) 
735				: $form.find('button[type="submit"]');
736
737			// Create FormData object
738			var formData = new FormData($form[0]);
739			
740			// If product ID isn't in form, try to get it from URL
741			if(!formData.has('add-to-cart') && $form.attr('action')){
742				var matches = $form.attr('action').match(/add-to-cart=([0-9]+)/);
743				if(matches){
744					formData.append('add-to-cart', matches[1]);
745				}
746			}
747
748			// Add button data if it has name/value
749			if($button.attr('name') && $button.attr('value')){
750				formData.append($button.attr('name'), $button.attr('value'));
751			}
752
753			// Add caddy_ajax parameter
754			formData.append('caddy_ajax', true);
755
756			// Show loading state
757			$button.addClass('loading');
758			
759			// Add to cart via Ajax
760			$.ajax({
761				type: 'POST',
762				url: wc_add_to_cart_params.wc_ajax_url.replace('%%endpoint%%', 'add_to_cart'),
763				data: formData,
764				processData: false,
765				contentType: false,
766				success: function(response) {
767					if (response.error) {
768						// Let WooCommerce handle the error display
769						return true;
770					}
771					
772					// Update fragments
773					if (response.fragments) {
774						$.each(response.fragments, function(key, value) {
775							$(key).replaceWith(value);
776						});
777						$(document.body).trigger('wc_fragments_refreshed');
778					}
779
780					// Open the cart drawer
781					$('.cc-compass').addClass('cc-compass-open');
782					$('body').addClass('cc-window-open');
783					$('.cc-overlay').show();
784					$('.cc-window-wrapper').show();
785					$('.cc-cart-items').html(getSkeletonHTML());
786					ccWindow.animate({'right': '0'}, 'slow').addClass('visible');
787					
788					// Load cart screen with productAdded flag
789					cc_cart_screen('yes');
790
791					// Ensure wrapper stays visible after fragments refresh
792					$(document.body).one('wc_fragments_refreshed', function() {
793						$('.cc-window-wrapper').show();
794					});
795				},
796				complete: function() {
797					$button.removeClass('loading');
798				}
799			});
800		});
801		
802	});
803
804})( jQuery );

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