PageSourceSearch

https://aroakdreamcup.com.tw/wp-content/plugins/product-extras-for-woocommerce/assets/js/pewc.js?ver=3.25.5

js aroakdreamcup.com.tw collected 2026-10-06 19:53:12 UTC 131,691 bytes, 3,003 lines download raw bytes

1(function($) {
2
3	var total_updated = false;
4
5	$( document ).ready( function() {
6
7		// $( 'body').find( '.dz-default.dz-message span' ).text( pewc_vars.drop_files_message );
8		// Init each select-box separately
9		$( '.pewc-select-box' ).each( function( index, element ) {
10			$( element ).ddslick({
11				onSelected: function( selectedData ) {
12					var original = selectedData.original[0];
13					var index = selectedData.selectedIndex;
14					var value = selectedData.selectedData.value;
15					var box_id = $( original ).attr( 'id' );
16					// Update field price
17					var hidden_option_id = box_id.replace( '_select_box', '' ) + '_' + index + '_hidden';
18					var price = $( '#' + hidden_option_id ).attr( 'data-option-cost' );
19					var wrapper = $( '#' + box_id ).closest( '.pewc-item' )
20						.attr( 'data-selected-option-price', price )
21						.attr( 'data-value', value )
22						.attr( 'data-field-value', value );
23					var hidden_select = $( '#' + box_id + '_' + index ).closest( '.pewc-item' ).find( '.pewc-select-box-hidden' ).attr( 'data-selected-option-price', price ).val( value );
24					//pewc_update_total_js(); // before 3.21.4
25
26					var select_box_wrapper = $( 'body' ).find( '.pewc-item-select-box .dd-container' );
27					$( 'body' ).find( '.dd-option label, .dd-selected label' ).each( function() {
28						$( this ).next( 'small' ).addBack().wrapAll( '<div class="dd-option-wrap"/>' );
29					});
30					// box_id = box_id.replace( '_select_box', '' );
31					box_id = $( '#' + box_id ).closest( '.pewc-item' ).attr( 'data-id' );
32					// Update the field attributes
33					$( 'body' ).find( '#' + box_id ).val( value ).trigger( 'change' );
34
35					var selected_option_price = $( '#' + box_id ).find( 'option:selected' ).attr( 'data-option-cost' );
36					$( wrapper ).attr( 'data-selected-option-price', selected_option_price );
37
38					$( 'body' ).find( '#' + box_id ).trigger( 'pewc_update_select_box' );
39					$( wrapper ).find( '.dd-selected-description' ).text( pewc_wc_price( selected_option_price, true ) );
40
41					pewc_update_total_js(); // since 3.21.4, moved here so that WCFAD can also update the price of the selected option
42
43				}
44			});
45		});
46
47		// Init each color-picker separately
48		$( '.pewc-color-picker-field' ).each( function ( index, element ) {
49			$(element).wpColorPicker({
50				defaultColor: $(element).data('color') ? $(element).data('color') : false,
51				change: function( event, ui ) {
52					// a callback to fire whenever the color changes to a valid color
53					$( 'body' ).trigger( 'pewc_trigger_calculations' );
54					$(element).trigger( 'pewc_trigger_color_picker_change' );
55					$(element).closest( '.pewc-item' ).attr( 'data-field-value', ui.color.toString() ); // 3.21.4
56				},
57				clear: function() {
58					// a callback to fire when the input is emptied or an invalid color
59					$( 'body' ).trigger( 'pewc_trigger_calculations' );
60					$(element).closest( '.pewc-item' ).attr( 'data-field-value', '' ); // 3.21.4
61				},
62				hide: !$(element).data('show'), // hide the color picker controls on load
63				palettes: !!$(element).data('palettes'), // show a group of common colors beneath the square
64				width: $(element).data('box-width') ? $(element).data('box-width') : 255,
65				mode: 'hsv',
66				type: 'full',
67				slider: 'horizontal'
68			});
69		});
70
71		$( 'body' ).find( '.dd-option label, .dd-selected label' ).each( function() {
72			$( this ).next( 'small' ).addBack().wrapAll( '<div class="dd-option-wrap"/>' );
73		});
74
75		// 3.24.5, for input type range, so that the slider will display the default value on page load
76		$( 'input.pewc-range-slider' ).each( function(){
77			if ( $(this).attr( 'value' ) > 0 ) {
78				$(this).trigger( 'change' );
79			}
80		});
81	});
82
83	$('.require-depends li:first input').on('change',function() {
84		// Display asterisk on dependent required fields
85		if( $(this).val() != '' ) {
86			$(this).closest('.pewc-group').addClass('show-required');
87		} else {
88			$(this).closest('.pewc-group').removeClass('show-required');
89		}
90	});
91	$('.pewc-file-upload').on('change',function(){
92		readURL( this, $(this).attr('id') );
93	});
94	$('.pewc-remove-image').on('click',function(e){
95		e.preventDefault();
96		id = $(this).attr('data-id');
97		$('#'+id).val("");
98		$('#'+id+'-placeholder').css('display','none');
99		$('#'+id+'-placeholder img').attr('src', '#');
100		$('#'+id+'-wrapper').removeClass('image-loaded');
101	});
102	function readURL(input,id) {
103		if( input.files && input.files[0] ) {
104			var i = input.files.length;
105			var reader = new FileReader();
106			reader.onload = function (e) {
107				$('#'+id+'-wrapper').addClass('image-loaded');
108				$('#'+id+'-placeholder').fadeIn();
109				$('#'+id+'-placeholder img').attr('src', e.target.result);
110			}
111			reader.readAsDataURL(input.files[0]);
112		}
113	}
114	$('body').on('change input keyup','.pewc-has-maxchars input, .pewc-has-maxchars textarea',function(){
115		var maxchars = parseInt( $(this).attr('data-maxchars') );
116		var str = $(this).val();
117		var str_ex_spaces = $(this).val();
118		// Don't cost spaces
119		// str_ex_spaces = str_ex_spaces.replace(/\s/g, "");
120		if( pewc_vars.remove_spaces != 'no' ) {
121			str_ex_spaces = str.replace(/\s/g, "");
122			var num_spaces = str.split( " " ).length - 1;
123			maxchars += parseInt( num_spaces );
124		} else {
125			str_ex_spaces = str;
126
127		}
128		var str_len = str_ex_spaces.length;
129		if(str_len>maxchars){
130			var new_str = str_ex_spaces.substring(0, maxchars);
131			$(this).val(new_str);
132		}
133	});
134	$('body').on( 'change input', '.pewc-form-field', function() {
135		$form = $(this).closest( 'form' );
136		add_on_images.update_add_on_image( $( this ), $form );
137		pewc_update_total_js();
138		if ( 'yes' == pewc_vars.enable_character_counter ) {
139			pewc_update_text_field_counter( $(this) );
140		}
141	});
142	$('body').on( 'change input', '.pewc-range-slider', function() {
143		$( this ).closest( '.pewc-item-field-wrapper' ).find( '.pewc-range-value' ).text( $( this ).val() );
144		$( this ).closest( '.pewc-item' ).attr( 'data-field-value', $( this ).val() ); // 3.24.5
145	});
146
147	// this updates all text field counters, called on first load
148	function pewc_update_text_field_counters() {
149		$( '.pewc-form-field' ).each( function(){
150			if ( $(this).closest( '.pewc-item' ).hasClass('pewc-item-text') || $(this).closest( '.pewc-item' ).hasClass('pewc-item-textarea') || $(this).closest( '.pewc-item' ).hasClass('pewc-item-advanced-preview') ) {
151				pewc_update_text_field_counter( $(this) );
152			}
153		});
154	}
155
156	function pewc_update_text_field_counter( field ) {
157		var wrapper = field.closest( '.pewc-item' );
158
159		if ( ! wrapper.hasClass('pewc-item-text') && ! wrapper.hasClass('pewc-item-textarea') && ! wrapper.hasClass('pewc-item-advanced-preview') ) {
160			return; // do nothing if not text fields
161		}
162
163		var val_length = field.val().length;
164		//var current_count = $( '.pewc-text-counter-container.'+field.attr('id')+' .pewc-current-count' );
165		var current_count = field.closest( '.pewc-item' ).find( '.pewc-text-counter-container.'+field.attr('id')+' .pewc-current-count' ); // 3.22.0, so that cloned text fields' counter works correctly
166		current_count.html( val_length );
167
168		current_count.removeClass( 'error' );
169		if ( parseInt( field.attr('data-minchars') ) > 0 && val_length < parseInt( field.attr('data-minchars') ) ) {
170			current_count.addClass( 'error' );
171		} else if ( parseInt( field.attr('data-maxchars') ) > 0 && val_length > parseInt( field.attr('data-maxchars') ) ) {
172			current_count.addClass( 'error' );
173		}
174	}
175
176	$('body').on('click','.pewc-remove-image',function(){
177		$form = $(this).closest('form');
178		// pewc_update_total( $form );
179		pewc_update_total_js();
180	});
181	// Bind to the show_variation event
182	// Update pewc-product-price field with variation price
183	// 3.20.1, changed .bind to .on, .bind is deprecated as of jQuery 3.0
184	$( document ).on( 'hide_variation', function( event, variation, purchasable ) {
185		$('#pewc-product-price').val( 0 );
186		$('#pewc-product-price-original').val( 0 ); // 3.21.7
187		pewc_update_total_js();
188		// hide all variation-dependent fields
189		$('.pewc-variation-dependent').each(function(){
190			if ($(this).hasClass( 'active' )) {
191				$(this).removeClass( 'active' );
192				// 3.20.1, run only if Optimised conditions is enabled
193				if ( pewc_vars.conditions_timer > 0 ) {
194					if( pewc_vars.reset_fields == 'yes' && ! $(this).hasClass( 'pewc-reset-me' ) ) {
195						$(this).addClass( 'pewc-reset-me' );
196					}
197					if ( $( this ).hasClass( 'pewc-field-triggers-condition' ) ) {
198						// 3.20.1, trigger the function trigger_field_condition_check() in pewc_conditions
199						if ( $( this ).find( 'input' ).length > 0 ) {
200							$( this ).find( 'input' ).trigger( 'change' );
201						} else if ( $( this ).find( 'select' ).length > 0 ) {
202							$( this ).find( 'select' ).trigger( 'change' );
203						}
204					}
205					if ( $( this ).hasClass( 'pewc-calculation-trigger' ) ) {
206						// sometimes the recalculate function is triggered too late, when the field is already hidden, so we trigger it manually
207						calculations.recalculate();
208					}
209				}
210				// 3.21.4
211				$( 'body' ).trigger( 'pewc_field_visibility_updated', [ $(this).attr('data-id'), 'hide' ] );
212			}
213		});
214		$( 'body' ).trigger( 'pewc_reset_fields' ); // 3.20.1
215	});
216	$( document ).on( 'show_variation', function( event, variation, purchasable ) {
217		$( '#pewc_calc_set_price' ).attr( 'data-calc-set', 0 );
218		pewc_update_total_js();
219		var var_price = variation.display_price;
220		$( '#pewc_variation_price' ).val( var_price );
221		$( '#pewc-product-price' ).val( var_price );
222		$( '#pewc-product-price-original' ).val( var_price ); // 3.21.7
223		// Update percentage prices
224		$( 'body' ).trigger( 'pewc_do_percentages' );
225		// Find any select options with percentage prices - these might not have a field price
226		$( this ).find( '.pewc-percentage.pewc-item-select select' ).each( function() {
227			pewc_update_select_percentage_field( $( this ), var_price );
228		});
229		$( this ).find( '.pewc-percentage.pewc-item-select-box' ).each( function() {
230			pewc_update_select_box_percentage_field( $( this ), var_price );
231		});
232		$( this ).find( '.pewc-percentage.pewc-item-image_swatch, .pewc-percentage.pewc-item-radio' ).each( function() {
233			pewc_update_radio_percentage_field( $( this ), var_price );
234		});
235		// Check for variation dependent fields
236		var variation_id = variation.variation_id;
237		$('.pewc-variation-dependent').each(function(){
238			var ids = $(this).attr('data-variations');
239			ids = ids.split( ',' );
240			ids = ids.map( function( x ) {
241				return parseInt( x, 10 );
242			});
243			if( ids.indexOf( variation_id ) != -1 ) {
244				$(this).addClass( 'active' );
245				// 3.20.1
246				if( pewc_vars.reset_fields == 'yes' && pewc_vars.conditions_timer > 0 ) {
247					$(this).removeClass( 'pewc-reset-me' );
248				}
249				// 3.21.4
250				$( 'body' ).trigger( 'pewc_field_visibility_updated', [ $(this).attr('data-id'), 'show' ] );
251			} else {
252				$(this).removeClass( 'active' );
253				// 3.20.1
254				if( pewc_vars.reset_fields == 'yes' && ! $(this).hasClass( 'pewc-reset-me' ) && pewc_vars.conditions_timer > 0 ) {
255					$(this).addClass( 'pewc-reset-me' );
256				}
257			}
258			// 3.20.1
259			if ( pewc_vars.conditions_timer > 0 ) {
260				if ( $( this ).hasClass( 'pewc-field-triggers-condition' ) ) {
261					// trigger trigger_field_condition_check() or trigger_condition_check() in pewc_conditions
262					if ( $( this ).find( 'input' ).length > 0 ) {
263						$( this ).find( 'input' ).trigger( 'change' );
264					} else if ( $( this ).find( 'select' ).length > 0 ) {
265						$( this ).find( 'select' ).trigger( 'change' );
266					}
267				}
268				if ( $( this ).hasClass( 'pewc-calculation-trigger' ) ) {
269					// sometimes the recalculate function is triggered too late, when the field is already hidden, so we trigger it manually
270					calculations.recalculate();
271				}
272			}
273		});
274		// Update product dimensions
275		$( '#pewc_product_length' ).val( variation.dimensions['length'] );
276		$( '#pewc_product_width' ).val( variation.dimensions['width'] );
277		$( '#pewc_product_height' ).val( variation.dimensions['height'] );
278		$( '#pewc_product_weight' ).val( variation.weight );
279		// Trigger recalculation
280		$( 'body' ).trigger( 'pewc_trigger_calculations' );
281		$( 'body' ).trigger( 'pewc_variations_updated' );
282		$( 'body' ).trigger( 'pewc_reset_fields' ); // 3.20.1
283		pewc_update_total_js();
284	});
285
286	$( 'body' ).on( 'pewc_do_percentages', function() {
287		$('.pewc-percentage').each(function() {
288			var var_price = $( '#pewc-product-price' ).val();
289			var new_price = ( var_price / 100 ) * parseFloat( $( this ).attr( 'data-percentage' ) );
290			if( isNaN( new_price ) ) {
291				new_price = 0;
292			}
293			$(this).attr( 'data-price', new_price );
294			var new_price_html = pewc_wc_price( new_price.toFixed(pewc_vars.decimals) );
295			$(this).find('.pewc-field-price').html(new_price_html);
296
297			// 3.21.4, for checkbox fields
298			if ( $(this).hasClass( 'pewc-item-checkbox' ) ) {
299				var new_price_currency_only = pewc_wc_price( new_price.toFixed( pewc_vars.decimals ), true );
300				$(this).find( '.pewc-checkbox-price' ).html( new_price_currency_only );
301				return;
302			}
303			// Find any options in this field - checkbox group
304			$(this).find( '.pewc-option-has-percentage' ).each(function() {
305				var option_price = ( var_price / 100 ) * $(this).attr('data-option-percentage');
306				$(this).attr('data-option-cost',option_price.toFixed(pewc_vars.decimals));
307				option_price = pewc_wc_price( option_price.toFixed(pewc_vars.decimals) );
308				$(this).closest('.pewc-checkbox-form-label').find('.pewc-option-cost-label').html(option_price);
309			});
310		});
311	});
312	$( 'body.pewc-variable-product' ).on( 'update change', '.pewc-percentage.pewc-item-select select', function( e ) {
313		// Only do this on variable products
314		pewc_update_select_percentage_field( $( this ), $( '#pewc_variation_price' ).val() );
315	});
316	// @param select is the select element itself
317	function pewc_update_select_percentage_field( select, var_price ) {
318		pewc_update_select_option_percentage( select, var_price );
319		// Trigger recalculation
320		$( 'body' ).trigger( 'pewc_trigger_calculations' );
321		pewc_update_total_js();
322	}
323	// @param selectbox is the wrapper element
324	// @param var_price the variation price
325	function pewc_update_select_box_percentage_field( selectbox, var_price ) {
326		var select = $( selectbox ).find( 'select' );
327		// Update the hidden select field
328		pewc_update_select_option_percentage( select, var_price );
329		// Now update the select box options
330		var box = $( selectbox ).find( '.dd-select' );
331		var box_options = $( selectbox ).find( '.dd-options' );
332		$( select ).find( 'option' ).each( function( i, v ) {
333			var new_price = ( var_price / 100 ) * $( this ).attr( 'data-option-percentage' );
334			var new_text = $( this ).val() + pewc_vars.separator + pewc_wc_price( new_price.toFixed( pewc_vars.decimals ), true );
335			var option = $( box_options ).find( 'li' ).eq( i );
336			$( option ).find( '.dd-option-description' ).text( new_text );
337		});
338		// Update the selected option price
339		var selected_price = $( select ).children( 'option:selected' ).attr( 'data-option-cost' );
340		selected_price = pewc_wc_price( selected_price, true );
341		$( selectbox ).find( '.dd-selected .dd-selected-description' ).text( selected_price );
342
343		// Trigger recalculation
344		$( 'body' ).trigger( 'pewc_trigger_calculations' );
345		pewc_update_total_js();
346	}
347	// Shared function for select and select box fields
348	function pewc_update_select_option_percentage( select, var_price ) {
349		var selected = $( select ).children( 'option:selected' );
350		var option_price = ( var_price / 100 ) * $( selected ).attr( 'data-option-percentage' );
351		var item = $( select ).closest( '.pewc-item' ).attr( 'data-selected-option-price', option_price );
352		$( selected ).attr( 'data-option-cost', option_price.toFixed( pewc_vars.decimals ) );
353		option_price = pewc_wc_price( option_price.toFixed( pewc_vars.decimals ) );
354		var data_price = $( select ).closest( '.pewc-item' ).attr( 'data-price' );
355		if( isNaN( data_price ) ) {
356			$( select ).closest( '.pewc-item' ).attr( 'data-price', 0 );
357		}
358		// Update all options prices
359		$( select ).find( 'option' ).each( function( i, v ) {
360			var new_price = ( var_price / 100 ) * $( this ).attr( 'data-option-percentage' );
361			$( this ).attr( 'data-option-cost', new_price.toFixed( pewc_vars.decimals ) );
362			if ( $( select ).closest( '.pewc-item' ).hasClass( 'pewc-hide-option-price' ) || $( this ).hasClass( 'pewc-first-option' ) ) {
363				return; // no need to proceed if option price is hidden for this field
364			}
365			var new_text = $( this ).val() + pewc_vars.separator + pewc_wc_price( new_price.toFixed( pewc_vars.decimals ), true );
366			$( this ).text( new_text );
367		});
368	}
369	// @param swatch is the swatch or radio group field wrapper
370	function pewc_update_radio_percentage_field( field, var_price ) {
371		// Iterate through each input element and update all options prices
372		$( field ).find( 'input' ).each( function( i, v ) {
373			var new_price = ( var_price / 100 ) * $( this ).attr( 'data-option-percentage' );
374			$( this ).attr( 'data-option-cost', new_price.toFixed( pewc_vars.decimals ) );
375			var new_text = $( this ).val() + pewc_vars.separator + pewc_wc_price( new_price.toFixed( pewc_vars.decimals ), true );
376			$( this ).closest( 'label' ).next().text( new_text );
377			if ( $( field ).hasClass( 'pewc-hide-option-price' ) ) {
378				return; // no need to proceed if option price is hidden for this field
379			}
380			// 3.21.4, added pewc-item-image-swatch-checkbox
381			if( ( $( field ).hasClass( 'pewc-item-radio' ) || $( field ).hasClass( 'pewc-item-image-swatch-checkbox' ) ) && $( field ).hasClass( 'pewc-item-image_swatch' ) ) {
382				// 3.21.4, added .pewc-radio-image-desc to avoid duplicates
383				$( this ).closest( 'label' ).find( '.pewc-radio-image-desc span' ).text( new_text );
384			} else if( $( field ).hasClass( 'pewc-item-radio' ) ) {
385				$( this ).closest( 'li' ).find( 'label span.pewc-radio-option-text' ).text( new_text );
386			}
387		});
388		// Trigger recalculation
389		$( 'body' ).trigger( 'pewc_trigger_calculations' );
390		pewc_update_total_js();
391	}
392	function pewc_update_total_js( $update=0 ) {
393
394		var flat_rate_total = 0;
395		var product_price = parseFloat( $('#pewc-product-price').val() );
396		var orig_product_price = parseFloat( $('#pewc-product-price-original').val() ); // 3.21.7
397		var total_price = 0; // Options running total
398		var orig_total_price = 0; // 3.21.7, stores add-on prices before getting adjusted by DPDR
399		var added_price = 0;
400		var field_value = [];
401		var field_label = [];
402
403		$('form.cart .pewc-form-field').each(function() {
404
405			added_price = 0;
406
407			var field_wrapper = $(this).closest('.pewc-group');
408			$( field_wrapper ).removeClass( 'pewc-active-field' );
409
410			// Ignore hidden variation dependent fields
411			if( ! $( field_wrapper ).hasClass( 'pewc-variation-dependent' ) || ( $( field_wrapper ).hasClass( 'pewc-variation-dependent' ) && $( field_wrapper ).hasClass( 'active' ) ) ) {
412
413				var group_wrap = $( field_wrapper ).closest( '.pewc-group-wrap' );
414				if ( group_wrap.hasClass( 'pewc-group-hidden' ) ) {
415					return; // this field is inside a hidden group, so ignore and return
416				}
417
418				// Check that the extra field is not flat rate
419				if( ! $(field_wrapper).hasClass('pewc-flatrate') ) {
420
421					if( $(field_wrapper).hasClass('pewc-group-checkbox') && ! $(field_wrapper).hasClass('pewc-hidden-field') ) {
422
423						if( $(field_wrapper).hasClass('pewc-per-unit-pricing') && $(this).prop('checked') ) {
424							// Bookings for WooCommerce
425							// Multiply option cost by number of booked units
426							// total_price += parseFloat( $('#num_units_int').val() ) * parseFloat( $(field_wrapper).attr('data-price') );
427							added_price = parseFloat( $('#num_units_int').val() ) * parseFloat( $(field_wrapper).attr('data-price') );
428							$( field_wrapper ).addClass( 'pewc-active-field' );
429						} else if( $(this).prop('checked') ) {
430							// total_price += parseFloat( $(field_wrapper).attr('data-price') );
431							added_price = parseFloat( $(field_wrapper).attr('data-price') );
432							$( field_wrapper ).addClass( 'pewc-active-field' );
433						} else {
434							$( field_wrapper ).removeClass( 'pewc-active-field' );
435						}
436
437					} else if( $(field_wrapper).hasClass('pewc-group-select' ) && ! $(field_wrapper).hasClass('pewc-hidden-field') ) {
438
439						// 'value' means use the price as value only, on calculation fields
440						if ( $(field_wrapper).attr( 'data-option-price-visibility' ) != 'value' ) {
441							// Add cost of selected option
442							added_price = parseFloat( $(this).find(':selected').attr('data-option-cost') );
443							// Add cost of select field
444							added_price += parseFloat( $(field_wrapper).attr('data-price') );
445						}
446						// 3.24.8, added check for pewc-first-field-empty
447						if ( ! $( field_wrapper ).hasClass( 'pewc-first-field-empty' ) || $(this).find(':selected').val() != '' ) {
448							$( field_wrapper ).addClass( 'pewc-active-field' );
449							$( field_wrapper ).attr( 'data-field-value', $(this).find(':selected').val() );
450						}
451
452					}	else if( $(field_wrapper).hasClass('pewc-group-select-box' ) && ! $(field_wrapper).hasClass('pewc-hidden-field') ) {
453
454						// 'value' means use the price as value only, on calculation fields
455						if ( $(field_wrapper).attr( 'data-option-price-visibility' ) != 'value' ) {
456							// Add cost of selected option
457							added_price = parseFloat( $( field_wrapper ).attr( 'data-selected-option-price') );
458							// Add cost of select field
459							added_price += parseFloat( $( field_wrapper ).attr( 'data-price' ) );
460						}
461						// 3.24.8, added check for pewc-first-field-empty
462						if ( ! $( field_wrapper ).hasClass( 'pewc-first-field-empty' ) || $(this).find(':selected').val() != '' ) {
463							$( field_wrapper ).addClass( 'pewc-active-field' );
464							//$( field_wrapper ).attr( 'data-field-value', $(this).find('.pewc-select-box-hidden' ).val() ); // doesn't work as of 3.21.6
465							$( field_wrapper ).attr( 'data-field-value', $(this).find( ':selected' ).val() ); // 3.21.7
466						}
467
468					} else if( $(this).val() && ! $(field_wrapper).hasClass('pewc-hidden-field') ) {
469
470						if( $(field_wrapper).hasClass('pewc-per-character-pricing') && ( $(field_wrapper).hasClass('pewc-item-text') || $(field_wrapper).hasClass('pewc-item-textarea') || $(field_wrapper).hasClass( 'pewc-item-advanced-preview' ) ) ) {
471							var str_len = pewc_get_text_str_len( $(this).val(), field_wrapper );
472							added_price = str_len * parseFloat( $(field_wrapper).attr('data-price') );
473						} else if( $(field_wrapper).hasClass('pewc-multiply-pricing') ) {
474							var num_value = $(this).val();
475							added_price = num_value * parseFloat( $(field_wrapper).attr('data-price') );
476						} else if( $(field_wrapper).hasClass('pewc-group-name_price') ) {
477							added_price = parseFloat( $(this).val() );
478						} else if( $(field_wrapper).hasClass('pewc-item-number' ) && $(field_wrapper).hasClass('pewc-per-unit-pricing') ) {
479								// Bookings for WooCommerce
480								// Multiply option cost by number of booked units
481								// total_price += parseFloat( $('#num_units_int').val() ) * parseFloat( $(field_wrapper).attr('data-price') );
482								added_price = parseFloat( $('#num_units_int').val() ) * parseFloat( $(field_wrapper).attr('data-price') ) * parseFloat( $( this ).val() );
483						} else {
484							added_price = parseFloat( $(field_wrapper).attr('data-price') );
485						}
486
487						if( $(this).val() ) {
488							$( field_wrapper ).addClass( 'pewc-active-field' );
489
490							if ( $(this).hasClass( 'pewc-range-slider' ) && $(this).attr( 'value' ) == '' ) {
491								// 3.24.5, input of type range always has a value, so if this is the first load, and we don't have a user-selected value, don't set data-field-value
492							} else {
493								$( field_wrapper ).attr( 'data-field-value', $(this).val() );
494							}
495						}
496
497					} else {
498
499						// blank text value falls here
500						$( field_wrapper ).attr( 'data-field-value', '' );
501
502					}
503
504
505					total_price += added_price;
506					if( ! isNaN( added_price ) ) {
507						$( field_wrapper ).attr( 'data-field-price', added_price );
508					}
509
510				} else {
511
512					// Flat rate item
513					if( $(field_wrapper).hasClass('pewc-group-checkbox') && ! $(field_wrapper).hasClass('pewc-hidden-field') ) {
514						if( $(field_wrapper).hasClass('pewc-per-unit-pricing') && $(this).prop('checked') ) {
515							// Bookings for WooCommerce
516							// Multiply option cost by number of booked units
517							added_price = parseFloat( $('#num_units_int').val() ) * parseFloat( $(field_wrapper).attr('data-price') );
518							$( field_wrapper ).addClass( 'pewc-active-field' );
519						} else if( $(this).prop('checked') ) {
520							added_price = parseFloat( $(field_wrapper).attr('data-price') );
521							$( field_wrapper ).addClass( 'pewc-active-field' );
522						}
523					} else if( ( $(field_wrapper).hasClass('pewc-group-select') || $(field_wrapper).hasClass('pewc-group-select-box') ) && ! $(field_wrapper).hasClass('pewc-hidden-field') ) {
524						// Add cost of selected option
525						added_price = parseFloat( $(this).find(':selected').attr('data-option-cost') );
526						// Add cost of select field
527						added_price += parseFloat( $(field_wrapper).attr('data-price') );
528						$( field_wrapper ).addClass( 'pewc-active-field' );
529					} else if( $(this).val() && ! $(field_wrapper).hasClass('pewc-hidden-field') ) {
530						if( $(field_wrapper).hasClass('pewc-per-character-pricing') ) {
531							var str_len = pewc_get_text_str_len( $(this).val(), field_wrapper );
532							added_price = str_len * parseFloat( $(field_wrapper).attr('data-price') );
533							$( field_wrapper ).addClass( 'pewc-active-field' );
534						} else if( $(field_wrapper).hasClass('pewc-multiply-pricing') ) {
535							var num_value = $(this).val();
536							added_price = num_value * parseFloat( $(field_wrapper).attr('data-price') );
537							$( field_wrapper ).addClass( 'pewc-active-field' );
538						} else if( $(field_wrapper).hasClass('pewc-group-name_price') ) {
539							added_price = parseFloat( $(this).val() );
540						} else {
541							added_price = parseFloat( $(field_wrapper).attr('data-price') );
542							$( field_wrapper ).addClass( 'pewc-active-field' );
543						}
544					}
545
546					flat_rate_total += added_price;
547					$( field_wrapper ).attr( 'data-field-price', added_price );
548					$( field_wrapper ).attr( 'data-field-value', $(this).val() ); // 3.24.1, for JS validation
549
550				}
551
552			}
553
554			if( $( field_wrapper ).val() ) {
555				set_summary_panel_data( $( field_wrapper ), $( field_wrapper ).val(), added_price );
556			}
557
558		});
559
560		$( 'form.cart .pewc-item-radio, form.cart .pewc-item-image_swatch' ).each(function() {
561
562			var field_value = [];
563
564			if( ! $( this ).hasClass( 'pewc-variation-dependent' ) || ( $( this ).hasClass( 'pewc-variation-dependent' ) && $( this ).hasClass( 'active' ) ) ) {
565
566				var radio_group_id = $(this).attr( 'data-id' );
567				var group_wrap = $( this ).closest( '.pewc-group-wrap' );
568
569				if( ! $(this).hasClass('pewc-hidden-field') && ! group_wrap.hasClass( 'pewc-group-hidden' ) ) {
570
571					if ( $(this).attr('data-option-price-visibility') == 'value' ) {
572
573						// this option is only used for calculations, so don't add the price to the total
574						if( $('.'+radio_group_id ).find( $('input[type=radio]:checked')).attr('data-option-cost') ) {
575							var selected_option_price = $('.'+radio_group_id).find( $('input[type=radio]:checked') ).attr('data-option-cost');
576							$( this ).attr( 'data-selected-option-price', selected_option_price );
577						}
578
579					} else if( ! $(this).hasClass('pewc-flatrate') ) {
580
581						if( $('.'+radio_group_id ).find( $('input[type=radio]:checked')).attr('data-option-cost') ) {
582							added_price = parseFloat( $(this).attr('data-price') );
583							var selected_option_price = $('.'+radio_group_id).find( $('input[type=radio]:checked') ).attr('data-option-cost');
584							$( this ).attr( 'data-selected-option-price', selected_option_price );
585							added_price += parseFloat( selected_option_price );
586							total_price += added_price;
587						}
588
589					} else {
590						if( $('.'+radio_group_id).find( $('input[type=radio]:checked')).attr('data-option-cost') ) {
591							flat_rate_total += parseFloat( $(this).attr('data-price') );
592							var selected_option_price = $('.'+radio_group_id).find( $('input[type=radio]:checked') ).attr('data-option-cost');
593							$( this ).attr( 'data-selected-option-price', selected_option_price );
594							flat_rate_total += parseFloat( selected_option_price );
595						}
596					}
597
598					if( $(this).find( $('input[type=radio]:checked')).val() ) {
599						set_summary_panel_data( $( this ), $(this).find( $('input[type=radio]:checked')).val(), added_price );
600					} else {
601						set_summary_panel_data( $( this ), '', 0 );
602						$( this ).removeClass( 'pewc-active-field' ); // 3.21.4, moved here because set_summary_panel_data adds the class pewc-active-field
603					}
604
605				}
606
607			}
608
609		});
610
611		$('form.cart .pewc-item-select').each(function() {
612			var selected_option_price = $( this ).find( 'option:selected' ).attr( 'data-option-cost' );
613			$( this ).attr( 'data-selected-option-price', selected_option_price );
614		});
615
616		$('form.cart .pewc-item-checkbox_group').each(function() {
617
618			var field_value = [];
619			var selected_counter = 0;
620
621			if( ! $( this ).hasClass( 'pewc-variation-dependent' ) || ( $( this ).hasClass( 'pewc-variation-dependent' ) && $( this ).hasClass( 'active' ) ) ) {
622
623				var checkbox_group_id = $(this).attr( 'data-id' );
624				var checkbox_group_price = 0;
625				var group_wrap = $( this ).closest( '.pewc-group-wrap' );
626
627				if( ! $(this).hasClass('pewc-hidden-field') && ! group_wrap.hasClass( 'pewc-group-hidden' ) ) {
628					var checkbox_value = [];
629					if( ! $(this).hasClass('pewc-flatrate') ) {
630						// Get the field price
631						if( $("input[name='" + checkbox_group_id + "[]']:checked" ).val() ) {
632							checkbox_group_price += parseFloat( $(this).attr('data-price') );
633						}
634						$('.'+checkbox_group_id).find( $('input[type=checkbox]:checked') ).each( function() {
635							checkbox_group_price += parseFloat( $(this).attr('data-option-cost') );
636							checkbox_value.push( $( this ).val() );
637							selected_counter++;
638						});
639						total_price += checkbox_group_price;
640
641						// Summary panel
642						if( $("input[name='" + checkbox_group_id + "[]']:checked" ).val() ) {
643							$( this ).attr( 'data-field-price', checkbox_group_price );
644							$( this ).addClass( 'pewc-active-field' );
645							$( this ).attr( 'data-field-value', checkbox_value.join( ', ' ) );
646						}
647						else {
648							// remove from summary panel
649							$( this ).attr( 'data-field-price', 0 );
650							$( this ).removeClass( 'pewc-active-field' );
651							$( this ).attr( 'data-field-value', '' );
652						}
653
654					} else {
655
656						// Flat rate
657						if( $("input[name='" + checkbox_group_id + "[]']:checked" ).val() ) {
658							flat_rate_total += parseFloat( $(this).attr('data-price') );
659						}
660						$('.'+checkbox_group_id).find( $('input[type=checkbox]:checked') ).each( function() {
661							flat_rate_total += parseFloat( $(this).attr('data-option-cost') );
662							checkbox_value.push( $( this ).val() );
663							selected_counter++;
664						});
665
666						if ( checkbox_value.length > 0 ) {
667							$( this ).attr( 'data-field-value', checkbox_value.join( ', ' ) );
668						} else {
669							$( this ).attr( 'data-field-value', '' );
670						}
671					}
672				}
673
674			}
675
676			pewc_update_checkbox_field_counter( $(this), selected_counter );
677
678		});
679		$('form.cart .pewc-item-image-swatch-checkbox').each(function() {
680
681			var field_value = [];
682			var selected_counter = 0;
683
684			if( ! $( this ).hasClass( 'pewc-variation-dependent' ) || ( $( this ).hasClass( 'pewc-variation-dependent' ) && $( this ).hasClass( 'active' ) ) ) {
685
686				var checkbox_group_id = $(this).attr( 'data-id' );
687				var checkbox_group_price = 0;
688				var group_wrap = $( this ).closest( '.pewc-group-wrap' );
689
690				if( ! $(this).hasClass('pewc-hidden-field') && ! group_wrap.hasClass( 'pewc-group-hidden' ) ) {
691					var field_value = [];
692					if( ! $(this).hasClass('pewc-flatrate') ) {
693						// Get the field price
694						if( $("input[name='" + checkbox_group_id + "[]']:checked" ).val() ) {
695							checkbox_group_price += parseFloat( $(this).attr('data-price') );
696						}
697						$('.'+checkbox_group_id).find( $('input[type=checkbox]:checked') ).each( function() {
698							field_value.push( $( this ).val() );
699							checkbox_group_price += parseFloat( $(this).attr('data-option-cost') );
700							selected_counter++;
701						});
702						total_price += checkbox_group_price;
703					} else {
704						// Flat rate
705						if( $("input[name='" + checkbox_group_id + "[]']:checked" ).val() ) {
706							flat_rate_total += parseFloat( $(this).attr('data-price') );
707						}
708						$('.'+checkbox_group_id).find( $('input[type=checkbox]:checked') ).each( function(){
709							field_value.push( $( this ).val() );
710							flat_rate_total += parseFloat( $(this).attr('data-option-cost') );
711							selected_counter++;
712						});
713					}
714				}
715
716				if( field_value.length > 0 ) {
717					set_summary_panel_data( $( this ), field_value.join( ', ' ), checkbox_group_price );
718				} else {
719					$( this ).removeClass( 'pewc-active-field' );
720					set_summary_panel_data( $( this ), '', 0 );
721				}
722
723			}
724
725			pewc_update_checkbox_field_counter( $(this), selected_counter );
726
727		});
728
729		// Check child products with select layout
730		var child_products_total = 0;
731		$('form.cart .pewc-child-select-field').each(function() {
732
733			var field_wrapper = $( this ).closest( '.pewc-item' );
734			var field_value = [];
735			var is_hidden = $( this ).closest( '.pewc-item' ).hasClass( 'pewc-hidden-field' );
736			var is_dependent = ( $( this ).closest( '.pewc-item' ).hasClass( 'pewc-variation-dependent' ) ) && ( ! $( this ).closest( '.pewc-item' ).hasClass( 'active' ) );
737			if( ! is_hidden && ! is_dependent ) {
738				// If the select field has a value
739				if( $(this).val() && $(this).val() != '' ) {
740					field_value.push( $(this).find(':selected').attr( 'data-field-value' ) );
741					var selected = $(this).find(':selected');
742					var child_product_price = selected.data( 'option-cost' );
743					// 3.21.4, compatibility with FD
744					if ( parseFloat( selected.attr('data-wcfad-price') ) > 0 ) {
745						child_product_price = parseFloat( selected.attr('data-wcfad-price') );
746					}
747					var qty = 0;
748					if( child_product_price > 0 ) {
749						var wrapper = $(this).closest('.child-product-wrapper');
750				
750		var quantities = $(wrapper).data('products-quantities');
751						// Get the quantity
752						if( quantities == 'linked' ) {
753							qty = $('form.cart .quantity .qty').val();
754						} else if( quantities == 'independent' ) {
755							// Find the child_quantity field
756							qty = $(wrapper).find('.pewc-child-quantity-field').val();
757							if ( pewc_vars.multiply_independent == 'yes' && $('form.cart .quantity .qty').val() !== undefined ) {
758								qty = qty * parseFloat( $('form.cart .quantity .qty').val() );
759							}
760						} else if( quantities == 'one-only' ) {
761							qty = 1;
762						}
763					}
764
765					child_products_total += parseFloat( child_product_price ) * parseFloat( qty );
766					if( field_value.length > 0 ) {
767						$( this ).closest( '.pewc-item' ).attr( 'data-field-price', child_products_total );
768						set_summary_panel_data( $( this ).closest( '.pewc-item' ), field_value.join( ', ' ), parseFloat( child_product_price ) * parseFloat( qty ) );
769					} else {
770						$( this ).closest( '.pewc-item' ).removeClass( 'pewc-active-field' );
771					}
772
773				}
774			}
775		});
776		$('form.cart .pewc-radio-images-wrapper.child-product-wrapper').each(function() {
777			var field_value = [];
778			var is_hidden = $( this ).closest( '.pewc-item' ).hasClass( 'pewc-hidden-field' );
779			var is_dependent = ( $( this ).closest( '.pewc-item' ).hasClass( 'pewc-variation-dependent' ) ) && ( ! $( this ).closest( '.pewc-item' ).hasClass( 'active' ) );
780			if( ! is_hidden && ! is_dependent ) {
781				var quantities = $(this).data('products-quantities');
782				var checked_radio = $(this).find('.pewc-radio-form-field:checked');
783				var radio_val = checked_radio.val();
784				if( radio_val && radio_val != undefined ) {
785					var child_product_price = checked_radio.data('option-cost');
786					// 3.21.4, compatibility with FD
787					if ( parseFloat( checked_radio.attr('data-wcfad-price') ) > 0 ) {
788						child_product_price = parseFloat( checked_radio.attr('data-wcfad-price') );
789					}
790					var qty = 0;
791					// sometimes child_product_price is zero if it's discounted
792					//if( child_product_price > 0 ) {
793						// Get the quantity
794						if( quantities == 'linked' ) {
795							qty = $('form.cart .quantity .qty').val();
796						} else if( quantities == 'independent' ) {
797							// Find the child_quantity field
798							qty = $(this).closest('.pewc-item-field-wrapper').find('.pewc-child-quantity-field').val();
799							if ( pewc_vars.multiply_independent == 'yes' && $('form.cart .quantity .qty').val() !== undefined ) {
800								qty = qty * parseFloat( $('form.cart .quantity .qty').val() );
801							}
802						} else if( quantities == 'one-only' ) {
803							qty = 1;
804						}
805					//}
806					child_products_total += parseFloat( child_product_price ) * parseFloat( qty );
807
808					if( child_products_total > 0 || qty > 0 ) {
809						$( this ).closest( '.pewc-item' ).attr( 'data-field-price', child_products_total );
810						set_summary_panel_data( $( this ).closest( '.pewc-item' ), checked_radio.attr( 'data-field-label' ), parseFloat( child_product_price ) * parseFloat( qty ) );
811					}
812
813				} else {
814					$( this ).closest( '.pewc-item' ).removeClass( 'pewc-active-field' );
815					$( this ).closest( '.pewc-item' )
816						.attr( 'data-field-price', 0 )
817						.attr( 'data-field-value', '' ); // 3.21.4, reset price and value
818				}
819
820			}
821		});
822
823		// 3.25.3, added form.cart .pewc-components-wrapper.child-product-wrapper
824		$( 'form.cart .pewc-checkboxes-images-wrapper.child-product-wrapper, form.cart .pewc-components-wrapper.child-product-wrapper' ).each(function() {
825
826			var this_child_total = 0;
827			var field_value = [];
828			var selected_counter = 0;
829			var is_hidden = $( this ).closest( '.pewc-item' ).hasClass( 'pewc-hidden-field' );
830			var is_dependent = ( $( this ).closest( '.pewc-item' ).hasClass( 'pewc-variation-dependent' ) ) && ( ! $( this ).closest( '.pewc-item' ).hasClass( 'active' ) );
831
832			if( ! is_hidden && ! is_dependent ) {
833				var quantities = $(this).data('products-quantities');
834				// Run through each selected checkbox
835
836				$( this ).closest( '.pewc-item' ).removeClass( 'pewc-active-field' );
837
838				$( this ).find('.pewc-checkbox-form-field:checkbox:checked').each(function() {
839					field_value.push( $( this ).attr( 'data-field-label' ) );
840					var child_product_price = $(this).data('option-cost');
841					// 3.21.4, compatibility with FD
842					if ( parseFloat( $(this).attr('data-wcfad-price') ) > 0 ) {
843						child_product_price = parseFloat( $(this).attr('data-wcfad-price') );
844					}
845					var qty = 0;
846
847					// Get the quantity
848					if( quantities == 'linked' ) {
849						qty = $('form.cart .quantity .qty').val();
850						selected_counter++;
851					} else if( quantities == 'independent' ) {
852						qty = $(this).closest('.pewc-checkbox-wrapper').find('.pewc-child-quantity-field').val();
853						selected_counter += parseInt( qty );
854						if ( pewc_vars.multiply_independent == 'yes' && $('form.cart .quantity .qty').val() !== undefined ) {
855							qty = qty * parseFloat( $('form.cart .quantity .qty').val() );
856						}
857					} else if( quantities == 'one-only' ) {
858						qty = 1;
859						selected_counter++;
860					}
861
862					if( child_product_price > 0 ) {
863						child_products_total += parseFloat( child_product_price ) * parseFloat( qty );
864						this_child_total += parseFloat( child_product_price ) * parseFloat( qty );
865					}
866
867				});
868
869				if( field_value.length > 0 ) {
870					$( this ).closest( '.pewc-item' ).attr( 'data-field-price', child_products_total );
871					set_summary_panel_data( $( this ).closest( '.pewc-item' ), field_value.join( ', ' ), this_child_total );
872				}
873
874			}
875
876			pewc_update_checkbox_field_counter( $( this ).closest( '.pewc-item' ), selected_counter );
877
878		});
879
880		// reset products column first
881		$('form.cart .pewc-item-products-column').each(function(){
882			$(this).removeClass('pewc-active-field');
883			$(this).attr('data-field-price', 0);
884			$(this).attr('data-field-value', '');
885			pewc_update_checkbox_field_counter( $(this), 0 );
886		});
887		$('form.cart .pewc-column-wrapper .pewc-variable-child-product-wrapper.checked').each(function() {
888			var field_value = [];
889			var field_wrapper = $( this ).closest( '.pewc-item' );
890			var parent_field_value = field_wrapper.attr('data-field-value');
891			if ( parent_field_value != 0 && parent_field_value != '') {
892				field_value = parent_field_value.split(', ');
893			}
894			var parent_field_price = parseFloat( field_wrapper.attr('data-field-price') );
895			var selected_counter = parseInt ( field_wrapper.attr( 'data-field-selected-counter' ) );
896			var is_hidden = field_wrapper.hasClass( 'pewc-hidden-field' );
897			var is_dependent = ( field_wrapper.hasClass( 'pewc-variation-dependent' ) ) && ( ! field_wrapper.hasClass( 'active' ) );
898
899			if( ! is_hidden && ! is_dependent ) {
900				var quantities = $(this).closest( '.pewc-column-wrapper' ).data('products-quantities');
901				// Run through each selected checkbox for variable child products
902
903				field_wrapper.removeClass( 'pewc-active-field' );
904
905				$(this).find('.pewc-variable-child-select').each(function() {
906					field_value.push( $( this ).find('option:selected').text() );
907					var child_product_price = $(this).find(':selected').data('option-cost');
908					// 3.21.4, compatibility with FD
909					if ( parseFloat( $(this).find(':selected').attr('data-wcfad-price') ) > 0 ) {
910						child_product_price = parseFloat( $(this).find(':selected').attr('data-wcfad-price') );
911					}
912					var qty = 0;
913
914					// Get the quantity
915					if( quantities == 'linked' ) {
916						qty = $('form.cart .quantity .qty').val();
917						selected_counter++;
918					} else if( quantities == 'independent' ) {
919						qty = $(this).closest('.pewc-checkbox-image-wrapper').find('.pewc-child-quantity-field').val();
920						selected_counter += parseInt( qty );
921						if ( pewc_vars.multiply_independent == 'yes' && $('form.cart .quantity .qty').val() !== undefined ) {
922							qty = qty * parseFloat( $('form.cart .quantity .qty').val() );
923						}
924					} else if( quantities == 'one-only' ) {
925						qty = 1;
926						selected_counter++;
927					}
928
929					if( child_product_price > 0 ) {
930						child_products_total += parseFloat( child_product_price ) * parseFloat( qty );
931						parent_field_price += parseFloat( child_product_price ) * parseFloat( qty );
932					}
933
934					if( field_value.length > 0 ) {
935						field_wrapper.attr( 'data-field-price', parent_field_price );
936						set_summary_panel_data( field_wrapper, field_value.join( ', ' ), parent_field_price );
937					}
938
939				});
940
941			}
942
943			pewc_update_checkbox_field_counter( field_wrapper, selected_counter );
944
945		});
946		$('form.cart .pewc-column-wrapper .pewc-simple-child-product-wrapper.checked').each(function() {
947			var field_value = [];
948			var field_wrapper = $( this ).closest( '.pewc-item' );
949			var parent_field_value = field_wrapper.attr('data-field-value');
950			if ( parent_field_value != 0 && parent_field_value != '') {
951				field_value = parent_field_value.split(', ');
952			}
953			var parent_field_price = parseFloat( field_wrapper.attr('data-field-price') );
954			var selected_counter = parseInt ( field_wrapper.attr( 'data-field-selected-counter' ) );
955			var is_hidden = field_wrapper.hasClass( 'pewc-hidden-field' );
956			var is_dependent = ( field_wrapper.hasClass( 'pewc-variation-dependent' ) ) && ( ! field_wrapper.hasClass( 'active' ) );
957
958			if( ! is_hidden && ! is_dependent ) {
959				var quantities = $(this).closest( '.pewc-column-wrapper' ).data('products-quantities');
960
961				field_wrapper.removeClass( 'pewc-active-field' );
962
963				// Run through each selected checkbox
964				$(this).find('.pewc-checkbox-form-field').each(function(){
965					field_value.push( $( this ).attr( 'data-field-label' ) );
966					var child_product_price = $(this).data('option-cost');
967					// 3.21.4, compatibility with FD
968					if ( parseFloat( $(this).attr('data-wcfad-price') ) > 0 ) {
969						child_product_price = parseFloat( $(this).attr('data-wcfad-price') );
970					}
971					var qty = 0;
972
973					// Get the quantity
974					if( quantities == 'linked' ) {
975						qty = $('form.cart .quantity .qty').val();
976						selected_counter++;
977					} else if( quantities == 'independent' ) {
978						qty = $(this).closest('.pewc-simple-child-product-wrapper').find('.pewc-child-quantity-field').val();
979						selected_counter += parseInt( qty );
980						if ( pewc_vars.multiply_independent == 'yes' && $('form.cart .quantity .qty').val() !== undefined ) {
981							qty = qty * parseFloat( $('form.cart .quantity .qty').val() );
982						}
983					} else if( quantities == 'one-only' ) {
984						qty = 1;
985						selected_counter++;
986					}
987
988					if( child_product_price > 0 ) {
989						child_products_total += parseFloat( child_product_price ) * parseFloat( qty );
990						parent_field_price += parseFloat( child_product_price ) * parseFloat( qty );
991					}
992
993					if( field_value.length > 0 ) {
994						field_wrapper.attr( 'data-field-price', parent_field_price );
995						set_summary_panel_data( field_wrapper, field_value.join( ', ' ), parent_field_price );
996					}
997
998				});
999
1000			}
1001
1002			pewc_update_checkbox_field_counter( field_wrapper, selected_counter );
1003
1004		});
1005
1006		// reset products swatches first
1007		$('form.cart .pewc-item-products-swatches').each(function(){
1008			$(this).removeClass('pewc-active-field');
1009			$(this).attr('data-field-price', 0);
1010			$(this).attr('data-field-value', '');
1011		});
1012		$('form.cart .pewc-swatches-wrapper .pewc-child-variation-main').each(function() {
1013			var field_value = [];
1014			var parent_field_value = $( this ).closest( '.pewc-item' ).attr('data-field-value');
1015			if ( parent_field_value != 0 && parent_field_value != '') {
1016				field_value = parent_field_value.split(', ');
1017			}
1018			var parent_field_price = parseFloat( $( this ).closest( '.pewc-item' ).attr('data-field-price') );
1019			var is_hidden = $( this ).closest( '.pewc-item' ).hasClass( 'pewc-hidden-field' );
1020			var is_dependent = ( $( this ).closest( '.pewc-item' ).hasClass( 'pewc-variation-dependent' ) ) && ( ! $( this ).closest( '.pewc-item' ).hasClass( 'active' ) );
1021			if( ! is_hidden && ! is_dependent ) {
1022
1023				var quantities = $(this).closest( '.pewc-swatches-wrapper' ).data('products-quantities');
1024
1025				// Run through each selected variation product
1026				$(this).find('.pewc-child-name input').each(function() {
1027					var child_product_price = parseFloat( $(this).attr( 'data-option-cost' ) );
1028					// 3.21.4, compatibility with FD
1029					if ( parseFloat( $(this).attr('data-wcfad-price') ) > 0 ) {
1030						child_product_price = parseFloat( $(this).attr('data-wcfad-price') );
1031					}
1032					var qty = 0;
1033					if( child_product_price > 0 && $(this).is( ':checked' ) ) {
1034						// Get the quantity
1035						// 3.21.4, added is :checked, only consider selected child product
1036						if( quantities == 'linked' ) {
1037							qty = $('form.cart .quantity .qty').val();
1038						} else if( quantities == 'independent' ) {
1039							qty = $(this).closest('.pewc-child-variation-main').find('.pewc-child-quantity-field').val();
1040							if ( pewc_vars.multiply_independent == 'yes' && $('form.cart .quantity .qty').val() !== undefined ) {
1041								qty = qty * parseFloat( $('form.cart .quantity .qty').val() );
1042							}
1043						} else if( quantities == 'one-only' ) {
1044							qty = 1;
1045						}
1046					}
1047					if ( qty < 1 ) {
1048						return; // quantity is zero, so ignore this field
1049					}
1050					field_value.push( $( this ).attr( 'data-field-label' ) );
1051					child_products_total += parseFloat( child_product_price ) * parseFloat( qty );
1052					parent_field_price += parseFloat( child_product_price ) * parseFloat( qty );
1053
1054					if( field_value.length > 0 ) {
1055						$( this ).closest( '.pewc-item' ).attr( 'data-field-price', parent_field_price );
1056						set_summary_panel_data( $( this ).closest( '.pewc-item' ), field_value.join( ', ' ), parent_field_price );
1057					}
1058				});
1059
1060			}
1061
1062		});
1063		$('form.cart .grid-layout').each( function() {
1064
1065			var is_hidden = $( this ).closest( '.pewc-item' ).hasClass( 'pewc-hidden-field' );
1066			var is_hidden_group = $( this ).closest( '.pewc-group-wrap' ).hasClass( 'pewc-group-hidden' );
1067			var is_dependent = ( $( this ).closest( '.pewc-item' ).hasClass( 'pewc-variation-dependent' ) ) && ( ! $( this ).closest( '.pewc-item' ).hasClass( 'active' ) );
1068			if( ! is_hidden && ! is_hidden_group && ! is_dependent ) {
1069				var child_product_price = parseFloat( $( this ).closest( '.pewc-item' ).attr( 'data-
1069price' ) );
1070				child_products_total += parseFloat( child_product_price );
1071			}
1072
1073		});
1074
1075		if( product_price < 0 ) product_price = 0;
1076
1077		// Summary panel rows
1078
1079		// Summary panel for add-on groups
1080		$( '.pewc-summary-panel-group-row' ).addClass( 'pewc-summary-panel-field-row-inactive' );
1081
1082		$( '.pewc-group-wrap' ).not( '.pewc-group-hidden' ).each( function() {
1083			var group_id = $( this ).attr( 'data-group-id' );
1084			$( '.pewc-summary-panel-group-'+group_id ).removeClass( 'pewc-summary-panel-field-row-inactive' );
1085		});
1086
1087		// Summary panel for add-on fields
1088		$( '.pewc-summary-panel-field-row' ).addClass( 'pewc-summary-panel-field-row-inactive' );
1089
1090		$( '.pewc-active-field' ).not( '.pewc-hidden-field' ).each( function() {
1091			var field_id = $( this ).attr( 'data-field-id' );
1092			var field_type = $( '.pewc-field-' + field_id ).attr( 'data-field-type' );
1093			$( '#pewc-summary-row-' + field_id ).removeClass( 'pewc-summary-panel-field-row-inactive' ).addClass( 'pewc-field-' + field_type );
1094			var field_price = parseFloat( $( this ).attr( 'data-field-price' ) );
1095			if( field_price ) {
1096				field_price = field_price.toFixed( pewc_vars.decimals );
1097			}
1098
1099			var field_label = $( this ).attr( 'data-field-label' );
1100			var field_value;
1101			if( $( this ).attr( 'data-field-type') != 'checkbox' ) {
1102				field_value = $( this ).attr( 'data-field-value' );
1103			}
1104			$( '#pewc-summary-row-' + field_id ).find( '.pewc-summary-panel-product-name' ).text( field_label );
1105			$( '#pewc-summary-row-' + field_id ).find( '.pewc-summary-panel-product-value' ).text( field_value );
1106			$( '#pewc-summary-row-' + field_id ).find( '.pewc-summary-panel-price' ).html( pewc_wc_price( field_price ) );
1107		});
1108
1109		var qty = 1;
1110		if( $('form.cart .qty').val() ) {
1111			qty = $('form.cart .qty').val();
1112		}
1113
1114		// See if we need to apply a discount to the add-ons care of Dynamic Pricing and Discount Rules
1115		// Updated on 3.21.4
1116		orig_total_price = total_price; // 3.21.7, for DPDR
1117		if ( pewc_wcfad_apply_discount() ) {
1118			total_price = pewc_wcfad.adjust_price( total_price );
1119		}
1120
1121		// Summary panel subtotal (3.9.8)
1122		var subtotal = parseFloat( child_products_total ) + parseFloat( total_price ) + parseFloat( qty * product_price );
1123		if( ! isNaN( subtotal ) ) {
1124			$( '#pewc-summary-panel-subtotal' ).html( pewc_wc_price( subtotal.toFixed(pewc_vars.decimals) ) );
1125		}
1126
1127		var total_grid_variations = $( '#pewc-grid-total-variations' ).val();
1128
1129		var product_price = qty * product_price;
1130		var grand_total = product_price;
1131		var orig_grand_total = qty * orig_product_price; // 3.21.7, for DPDR
1132		base_price = product_price;
1133		product_price = product_price.toFixed(pewc_vars.decimals);
1134		product_price = pewc_wc_price( product_price );
1135		product_price = add_price_suffix( product_price, base_price );
1136		$('#pewc-per-product-total').html( product_price );
1137
1138		total_price = qty * total_price;
1139		orig_total_price = qty * orig_total_price; // 3.21.7, for DPDR
1140		// Multiply add-ons by number of variations in bulk grid
1141		if( total_grid_variations ) {
1142			total_price = total_grid_variations * total_price;
1143		}
1144		total_price += child_products_total;
1145		grand_total += total_price;
1146		orig_grand_total += orig_total_price; // 3.21.7, for DPDR
1147
1148		if( ! isNaN( total_price ) ) {
1149			var base_total_price = total_price;
1150			total_price = total_price.toFixed(pewc_vars.decimals);
1151			total_price = pewc_wc_price( total_price );
1152			total_price = add_price_suffix( total_price, base_total_price );
1153			$('#pewc-options-total').html( total_price );
1154		}
1155
1156		if( flat_rate_total < 0 ) flat_rate_total = 0;
1157		base_flat_rate_total = flat_rate_total;
1158		grand_total += flat_rate_total;
1159		flat_rate_total = flat_rate_total.toFixed(pewc_vars.decimals);
1160		flat_rate_total = pewc_wc_price( flat_rate_total );
1161		flat_rate_total = add_price_suffix( flat_rate_total, base_flat_rate_total );
1162		$('#pewc-flat-rate-total').html( flat_rate_total );
1163
1164		// Set the product price using a calculation field
1165		// 3.13.3 added 2nd condition to apply only calculated price if at least 1 calculation field is not hidden
1166		if( ( $( '#pewc_calc_set_price').attr( 'data-calc-set' ) == 1 || $('input[name="pewc_calc_set_price"]').length > 1 ) && $( '.pewc-product-extra-groups-wrap .pewc-item-calculation' ).not( '.pewc-hidden-field' ).length > 0 ) {
1167			if ( $('input[name="pewc_calc_set_price"]').length > 1 ) {
1168				// 3.17.2, compatibility with Product Table Ultimate
1169				// find the first non-hidden total
1170				var new_grand_total = 0;
1171				$('input[name="pewc_calc_set_price"]').each(function(){
1172					if ( $(this).attr( 'data-calc-set' ) == 1 && $(this).closest( '.pewc-product-extra-groups-wrap' ).is( ':visible' ) ) {
1173						new_grand_total = parseFloat( $(this).closest( '.pewc-product-extra-groups-wrap' ).find('input[name="pewc_calc_set_price"][data-calc-set="1"]').val() );
1174					}
1175				});
1176				if ( new_grand_total > 0 ) {
1177					grand_total = new_grand_total;
1178				}
1179			} else {
1180				// single product page
1181				grand_total = parseFloat( $( '#pewc_calc_set_price').val() );
1182			}
1183
1184			if ( $('form.cart .quantity .qty').length > 0 ) {
1185
1186				// 3.12.0, apply dynamic pricing if it exists
1187				if ( pewc_wcfad_apply_discount() ) {
1188					grand_total = pewc_wcfad.adjust_price( grand_total );
1189				}
1190
1191				// 3.11.6 multiply product price by quantity
1192				grand_total = grand_total * parseFloat( $('form.cart .quantity .qty').val() );
1193
1194			}
1195		}
1196
1197		if( ! isNaN( grand_total ) ) {
1198			if ( isNaN( orig_grand_total ) || orig_grand_total == grand_total ) {
1199				orig_grand_total = ''; // 3.21.7, let's clear this so that we know we don't need it
1200			}
1201			var base_price = grand_total;
1202			grand_total = grand_total.toFixed( pewc_vars.decimals );
1203			grand_total = pewc_wc_price( grand_total );
1204			if( pewc_vars.update_price == 'yes' ) {
1205				update_product_price( grand_total, base_price, orig_grand_total );
1206			}
1207			grand_total = add_price_suffix( grand_total, base_price );
1208			$('#pewc-grand-total').html( grand_total );
1209		}
1210
1211		// Re-run this because some browsers are too quick
1212		// This won't run if we're using the optimised condition option
1213		if( $update == 0 && pewc_vars.conditions_timer < 1 ) {
1214			var interval = setTimeout( function() {
1215				pewc_update_total_js( 1 );
1216				if( ! total_updated ) {
1217					// Check any calculations before input fields are updated
1218					$( 'body' ).trigger( 'pewc_trigger_calculations' );
1219					total_updated = true;
1220				}
1221			},
1222			250 );
1223		}
1224
1225		// 3.15.0, let other plugins hook into this
1226		$( 'body' ).trigger( 'pewc_after_update_total_js', [ base_total_price, base_price, grand_total ] );
1227	}
1228
1229	/*
1230	 * Counts selected checkboxes, swatches, or products
1231	 */
1232	function pewc_update_checkbox_field_counter( field_wrapper, counter ) {
1233
1234		var current_count = field_wrapper.attr( 'data-field-selected-counter' );
1235
1236		// hopefully this prevents this process from being run multiple times
1237		if ( current_count != counter ) {
1238			field_wrapper.attr( 'data-field-selected-counter', counter );
1239			// Optimised validation will hook into the trigger below
1240			$( 'body' ).trigger( 'pewc_field_selected_counter_updated', [ field_wrapper, counter ] );
1241		}
1242	}
1243
1244	function add_price_suffix( price, base_price ) {
1245		if( pewc_vars.show_suffix == 'yes' ) {
1246			var price_suffix_setting = pewc_vars.price_suffix_setting;
1247			if( price_suffix_setting.indexOf( '{price_excluding_tax}' ) > -1 ) {
1248				var price_ex_tax = base_price * ( pewc_vars.percent_exc_tax / 100 );
1249				suffix = price_suffix_setting.replace( '{price_excluding_tax}', pewc_wc_price( price_ex_tax.toFixed( pewc_vars.decimals ), false, false ) );
1250			} else if( price_suffix_setting.indexOf( '{price_including_tax}' ) > -1 ) {
1251				var price_inc_tax = base_price * ( pewc_vars.percent_inc_tax / 100 );
1252				suffix = price_suffix_setting.replace( '{price_including_tax}', pewc_wc_price( price_inc_tax.toFixed( pewc_vars.decimals ), false, false ) );
1253			} else {
1254				suffix = pewc_vars.price_suffix;
1255			}
1256			price = price + ' <small class="woocommerce-price-suffix">' + suffix + '</small>';
1257		}
1258		return price;
1259	}
1260
1261	function update_product_price( grand_total, base_price, orig_grand_total ) {
1262		var price_suffix_setting = pewc_vars.price_suffix_setting;
1263		// We can rebuild him
1264		var suffix = $( '.pewc-main-price' ).find( '.woocommerce-price-suffix' ).html();
1265		var label = $( '.pewc-main-price' ).find( '.wcfad-rule-label' ).html();
1266		var before = $( '.pewc-main-price' ).find( '.pewc-label-before' ).html();
1267		var after = $( '.pewc-main-price' ).find( '.pewc-label-after' ).html();
1268		var hide = $( '.pewc-main-price' ).find( '.pewc-label-hidden' );
1269		var new_total = '';
1270
1271		if( hide.length > 0 ) {
1272			new_total = '<span class="pewc-label-hidden">' + hide.html() + '</span>';
1273		} else {
1274			if( before ) {
1275				new_total += '<span class="pewc-label-before">' + before + ' </span>';
1276			}
1277
1278			// 3.21.7
1279			if ( orig_grand_total != '' && pewc_vars.disable_wcfad_label != 'yes' ) {
1280				orig_grand_total.toFixed( pewc_vars.decimals );
1281				orig_grand_total = pewc_wc_price( orig_grand_total );
1282				new_total += ' <s>' + orig_grand_total + '</s> ';
1283			}
1284
1285			new_total += grand_total;
1286
1287			if( after ) {
1288				new_total += '<span class="pewc-label-after"> ' + after + '</span>';
1289			}
1290			if( suffix ) {
1291				if( price_suffix_setting.indexOf( '{price_excluding_tax}' ) > -1 ) {
1292					var price_ex_tax = base_price * ( pewc_vars.percent_exc_tax / 100 );
1293					suffix = price_suffix_setting.replace( '{price_excluding_tax}', pewc_wc_price( price_ex_tax.toFixed( pewc_vars.decimals ), false, false ) );
1294				} else if( price_suffix_setting.indexOf( '{price_including_tax}' ) > -1 ) {
1295					var price_inc_tax = base_price * ( pewc_vars.percent_inc_tax / 100 );
1296					suffix = price_suffix_setting.replace( '{price_including_tax}', pewc_wc_price( price_inc_tax.toFixed( pewc_vars.decimals ), false, false ) );
1297				}
1298				if( label && suffix.indexOf( 'wcfad-rule-label' ) < 0 ) {
1299					suffix += '<br><span class="wcfad-rule-label">' + label + '</span>';
1300				}
1301				new_total += '&nbsp;<small class="woocommerce-price-suffix">' + suffix + '</small>';
1302			}
1303		}
1304
1305		// 3.22.1, retain DPDR label even if Update pricing label is enabled
1306		var main_price = $( '.pewc-main-price').not( '.pewc-quickview-product-wrapper .pewc-main-price' );
1307		if ( main_price.find( '.wcfad-rule-label' ).length > 0 && new_total.indexOf( 'wcfad-rule-label' ) == -1 ) {
1308			// this has a DPDR discount label, add it to the new_total
1309			var dpdr_label = main_price.find( '.wcfad-rule-label' );
1310			new_total += '<br>' + dpdr_label[0].outerHTML;
1311		}
1312		main_price.html( new_total );
1313	}
1314
1315	function set_summary_panel_data( field, value, added_price ) {
1316		$( field ).attr( 'data-field-value', value );
1317		$( field ).attr( 'data-field-price', added_price );
1318		$( field ).addClass( 'pewc-active-field' );
1319	}
1320
1321	// old position of pewc_wc_price_without_currency and pewc_wc_price, moved outside of this container since 3.21.4
1322
1323	function format_separator( num ) {
1324	  return num.toString().replace( /(\d)(?=(\d{3})+(?!\d))/g, '$1,' );
1325	}
1326	// var interval = setInterval(function(){
1327	// 	pewc_update_total_js();
1328	// },
1329	// 500);
1330
1331	// 3.24.7, add a trigger event so that other plugins like PTU can re-trigger the form.cart input changes
1332	$( 'body' ).on( 'pewc_attach_form_cart_input_change', function() {
1333		$( 'form.cart' ).on('keyup input change paste', 'input:not(.pewc-grid-quantity-field), select, textarea.pewc-has-field-price', function(){
1334			pewc_update_total_js();
1335			$( 'body' ).trigger( 'pewc_updated_total_js' );
1336		});
1337	});
1338	$( 'body' ).trigger( 'pewc_attach_form_cart_input_change' );
1339
1340	var interval = setTimeout( function() {
1341		pewc_update_total_js();
1342		if ( 'yes' == pewc_vars.enable_character_counter ) {
1343			pewc_update_text_field_counters();
1344		}
1345	},
1346	250 );
1347	$( 'body' ).on( 'pewc_add_button_clicked', function() {
1348		pewc_update_total_js();
1349	});
1350	$( 'body' ).on( 'pewc_force_update_total_js', function() {
1351		pewc_update_total_js();
1352	});
1353	// Accordion and tabs
1354	$('.pewc-groups-accordion h3').on('click',function(e){
1355		// 3.13.7
1356		var is_open = $( this ).closest( '.pewc-group-wrap' ).hasClass( 'group-active' );
1357
1358		if ( $(this).closest( '.pewc-group-wrap' ).hasClass( 'pewc-disabled-group') ) {
1359			return;
1360		}
1361		if( pewc_vars.close_accordion == 'yes' ) {
1362			$( '.pewc-group-wrap' ).removeClass( 'group-active' );
1363		}
1364		// Don't reopen group if we've just closed it, only if close_accordion snippet is active
1365		if( ! is_open || pewc_vars.close_accordion != 'yes' ) {
1366			$(this).closest('.pewc-group-wrap').toggleClass('group-active');
1367		}
1368	});
1369	if( pewc_vars.accordion_toggle == 'open' ) {
1370		$('.pewc-group-wrap').addClass('group-active');
1371	} else if( pewc_vars.accordion_toggle == 'closed' ) {
1372		$('.pewc-group-wrap').removeClass('group-active');
1373	} else {
1374		$('.first-group').addClass('group-active');
1375	}
1376
1377	$('.pewc-tab').on('click',function(e) {
1378		// 3.13.7
1379		if ( $(this).hasClass( 'pewc-disabled-group') ) {
1380			return;
1381		}
1382
1383		e.preventDefault();
1384		var tab_id = $(this).attr('data-group-id');
1385		$('.pewc-tab').removeClass('active-tab tab-failed');
1386		$( '.pewc-group-js-validation-notice' ).hide();
1387		$(this).addClass('active-tab');
1388		$('.pewc-group-wrap').removeClass('group-active');
1389		$('.pewc-group-wrap-'+tab_id).addClass('group-active');
1390	});
1391	$('.pewc-next-step-button').on('click',function(e) {
1392		e.preventDefault();
1393		// 3.13.7
1394		if ( $(this).hasClass( 'pewc-disabled-group') ) {
1395			return;
1396		}
1397
1398		var tab_id = $( this ).attr( 'data-group-id' );
1399		var tab_index = $( this ).closest( '.pewc-group-wrap' ).attr( 'data-group-index' );
1400		var direction = $( this ).attr( 'data-direction' );
1401		$( '.pewc-tab' ).removeClass( 'active-tab tab-failed' );
1402		$( '.pewc-group-js-validation-notice' ).hide();
1403		// Check if the next group is visible
1404		if( $( '.pewc-group-wrap-' + tab_id ).hasClass( 'pewc-group-hidden' ) ) {
1405			// Count the total tabs
1406			var total_tabs = $( '.pewc-group-wrap' ).length;
1407			if( direction == 'next' ) {
1408				// Find the next group ID
1409				for( var i = parseInt( tab_index ) + 1; i < total_tabs; i++ ) {
1410					if( ! $( '.pewc-group-index-' + i ).hasClass( 'pewc-group-hidden' ) ) {
1411						tab_id = $( '.pewc-group-index-' + i ).attr( 'data-group-id' );
1412						break;
1413					}
1414				}
1415			} else {
1416				// Find the previous group ID
1417				for( var i = parseInt( tab_index ) - 1; i >= 0; i-- ) {
1418					if( ! $( '.pewc-group-index-' + i ).hasClass( 'pewc-group-hidden' ) ) {
1419						tab_id = $( '.pewc-group-index-' + i ).attr( 'data-group-id' );
1420						break;
1421					}
1422				}
1423			}
1424		}
1425		$( '#pewc-tab-' + tab_id ).addClass( 'active-tab' );
1426		$( '.pewc-group-wrap' ).removeClass( 'group-active' );
1427		$( '.pewc-group-wrap-' + tab_id ).addClass( 'group-active' );
1428
1429		// Scroll to top
1430		if ( pewc_vars.steps_group_disable_scroll_to_top != 'yes' ) {
1431			if( $( '.pewc-steps-wrapper' ).length > 0 ) {
1432				$([document.documentElement, document.body]).animate({
1433					scrollTop: $( '.pewc-steps-wrapper' ).offset().top
1434	    		}, 150);
1435			}
1436		}
1437	});
1438
1439	function pewc_get_text_str_len( str, wrapper ) {
1440		var new_str, str_ex_spaces ;
1441		var field = $(wrapper).find('.pewc-form-field');
1442		// Don't include spaces
1443		if( pewc_vars.remove_spaces != 'yes' ) {
1444			str_ex_spaces = str.replace(/\s/g, "");
1445		} else {
1446			str_ex_spaces = str;
1447		}
1448
1449		var str_len = str_ex_spaces.length;
1450		// Exclude alphanumerics if selected
1451		if( $(field).attr('data-alphanumeric') == 1 ) {
1452			str_ex_spaces = str_ex_spaces.replace(/\W/g, '');
1453			$(field).val(str_ex_spaces);
1454			str_len = str_ex_spaces.length;
1455		}
1456		// Allow alphanumerics but don't charge if selected
1457		if( $(field).attr('data-alphanumeric-charge') == 1 ) {
1458			str_ex_spaces = str_ex_spaces.replace(/\W/g, '');
1459			// $(field).val(str_ex_spaces);
1460			str_len = str_ex_spaces.length;
1461		}
1462		// If free characters are allowed
1463		var freechars = $(field).attr('data-freechars');
1464		str_len -= freechars;
1465		str_len = Math.max(0,str_len);
1466		return str_len;
1467	}
1468
1469	function pewc_disable_child_product_quantities() {
1470		$( '.woocommerce-cart-form__cart-item.pewc-child-product' ).each( function() {
1471			if( pewc_vars.disable_qty || pewc_vars.multiply_independent == 'yes' ) {
1472				$(this).find('.product-quantity input').attr('disabled',true);
1473			}
1474		});
1475	}
1476
1477	// Disable quantity fields in Barn2 Fast Cart
1478	$('body').on('click', 'a.wfc-open-cart-button', function( e ) {
1479		var timeout = setTimeout(
1480			function() {
1481				$( '.wfc-cart-form__cart-item.pewc-child-product' ).each( function() {
1482					if( pewc_vars.disable_qty || pewc_vars.multiply_independent == 'yes' ) {
1483						$(this).find('.product-quantity input').attr('disabled',true);
1484					}
1485				});
1486			},
1487			250
1488		);
1489	} );
1490
1491	// only do this if there are actually child products
1492	if ( $('.woocommerce-cart-form__cart-item.pewc-child-product').length > 0 ) {
1493		// call function on page load
1494		pewc_disable_child_product_quantities();
1495		// when cart is updated, disable quantities again
1496		$('body').on('updated_cart_totals', pewc_disable_child_product_quantities);
1497	}
1498
1499	// If child product is selected, manage allowable purchase quantity
1500	// Applies to radio and select
1501	$('body').on('change','.products-quantities-independent .pewc-child-select-field',function(){
1502		var number_field = $(this).closest('.child-product-wrapper').find('.pewc-child-quantity-field');
1503		if ( $( this ).val() != '') {
1504			// select field is not blank, update quantity
1505			if( $(number_field).val() == 0 ) {
1506				// Automatically enter a quantity when a product is selected
1507				$(number_field).val(1);
1508			};
1509		} else {
1510			// reset number field
1511			$( number_field ).val(0);
1512		}
1513		var available_stock = $(this).find(':selected').data('stock');
1514		if( available_stock ) {
1515			var number = $(number_field).attr('max',available_stock);
1516			if( $(number).val() > available_stock ) {
1517				$(number_field).val(available_stock);
1518			}
1519		} else {
1520			$(number_field).removeAttr('max');
1521		}
1522	});
1523	$('body').on('change input keyup paste click','.products-quantities-independent .pewc-child-quantity-field',function( e ) {
1524		e.stopPropagation(); // this prevents the click event from bubbling up to the event attached to the layer
1525		if ( $( this ).closest( '.pewc-item' ).hasClass( 'pewc-item-products-select' ) ) {
1526			// this is a Products select field
1527			var selIndex = 0;
1528			if( $(this).val() > 0 ) {
1529				var selField = $( this ).closest( '.pewc-item' ).find( 'select.pewc-child-select-field' );
1530				// find first select option with value if not already selected
1531				selIndex = selField.prop( 'selectedIndex' );
1532				if ( selIndex < 1 && selField.val() == '' ) {
1533					$( this ).closest( '.pewc-item' ).find( 'select.pewc-child-select-field option' ).each( function( index, element ) {
1534						if ( $(this).val() != '' && selIndex < 1 ) {
1535							selIndex = index;
1536							return;
1537						}
1538					});
1539				}
1540			}
1541			$( this ).closest( '.pewc-item' ).find( 'select.pewc-child-select-field' ).prop( 'selectedIndex', selIndex );
1542		} else {
1543			// Ensure this child product is selected
1544			// for checkbox images
1545			if( $(this).val() > 0 ) {
1546				var checkbox = $(this).closest('.pewc-checkbox-wrapper').find('input[type=checkbox]').prop('checked',true).change();
1547			} else {
1548				var checkbox = $(this).closest('.pewc-checkbox-wrapper').find('input[type=checkbox]').prop('checked',fal
1548se).change();
1549			}
1550		}
1551		var available_stock = $(this).find(':selected').data('stock');
1552		// $( 'body' ).trigger( 'pewc_update_child_quantity', [ $(this).closest('.pewc-checkbox-image-wrapper').find('input[type=checkbox]') ] );
1553		$( 'body' ).trigger( 'pewc_update_child_quantity', [ $(this).closest('.pewc-checkbox-wrapper').find('input[type=checkbox]') ] );
1554		pewc_update_total_js();
1555	});
1556
1557	// 3.24.8, Products and Product Categories fields, Radio Images/Radio List layout, independent quantity. Since the quantity input is now outside .products-quantities-independent, the script above doesn't get triggered.
1558	$( 'body' ).on( 'change input keyup paste click', '.pewc-item-products-radio.pewc-item-products-independent .pewc-child-quantity-field, .pewc-item-products-radio-list.pewc-item-products-independent .pewc-child-quantity-field', function( e ){
1559		var item_field_wrapper = $( this ).closest( '.pewc-item-field-wrapper' );
1560		var pewc_item_wrapper = item_field_wrapper.closest( '.pewc-item' );
1561		var radio_type = '';
1562		var number_checked = 0;
1563
1564		if ( pewc_item_wrapper.hasClass( 'pewc-item-products-radio' ) ) {
1565			radio_type = 'radio images';
1566			number_checked = item_field_wrapper.find( '.pewc-radio-images-wrapper .pewc-radio-image-wrapper.checked' ).length;
1567		} else {
1568			radio_type = 'radio list';
1569			number_checked = item_field_wrapper.find( '.pewc-radio-wrapper input.pewc-radio-form-field:checked' ).length;
1570		}
1571
1572		var number_value = $( this ).val();
1573		if ( number_value > 0 && number_checked < 1 ) {
1574			// we don't have a product selected, select the first one?
1575			if ( radio_type == 'radio images' ) {
1576				item_field_wrapper.find( '.pewc-radio-images-wrapper .pewc-radio-image-wrapper' ).each( function(){
1577					if ( ! $( this ).hasClass( 'checked' ) ) {
1578						$( this ).addClass( 'checked' );
1579					}
1580					$( this ).find( 'input.pewc-radio-form-field' ).prop( 'checked', true );
1581					return false; // break the loop since we only want to select the first one
1582				});
1583			} else {
1584				// radio list
1585				item_field_wrapper.find( '.pewc-radio-list-wrapper .pewc-radio-wrapper input.pewc-radio-form-field' ).each( function(){
1586					$( this ).prop( 'checked', true );
1587					return false; // break the loop since we only want to select the first one
1588				});
1589			}
1590		} else if ( number_value < 1 && number_checked > 0 ) {
1591			// de-select all products
1592			if ( radio_type == 'radio images' ) {
1593				item_field_wrapper.find( '.pewc-radio-images-wrapper .pewc-radio-image-wrapper.checked' ).each( function(){
1594					$( this ).removeClass( 'checked' );
1595					$( this ).find( 'input.pewc-radio-form-field' ).prop( 'checked', false );
1596				});
1597			} else {
1598				// radio list
1599				item_field_wrapper.find( '.pewc-radio-list-wrapper .pewc-radio-wrapper input.pewc-radio-form-field:checked' ).each( function(){
1600					$( this ).prop( 'checked', false );
1601				});
1602			}
1603		}
1604	});
1605
1606	$('body').on('change input keyup paste','.pewc-item-products-independent.pewc-child-qty-target .pewc-child-quantity-field',function() {
1607		// This runs when the user manually updates a child product quantity that has been set by a calculation field (independent quantities, radio items only)
1608		// If the calculation field has a reverse formula, use the result to set the source field value
1609		var wrapper = $( this ).closest( '.pewc-item' );
1610		// This is the ID of the calculation field that triggers this quantity update
1611		var triggered_by = $( wrapper ).attr( 'data-child-qty-triggered-by' );
1612		// Get the "reverse formula" - i.e. the method to calculate how to update the source input field
1613		var reverse_field_id = $( '.pewc-field-' + triggered_by ).attr( 'data-reverse-formula-field' );
1614		var reverse_formula = calculations.get_formula_by_id( reverse_field_id );
1615		// Do this calc "live" to avoid any race conditions with other fields getting updated
1616		calc_field = $( '.pewc-field-' + reverse_field_id );
1617		calc_field_id = $( calc_field ).attr( 'data-field-id' );
1618		price_wrapper = $( calc_field ).find( '.pewc-calculation-price-wrapper' );
1619		calc_field_id = $( calc_field ).attr( 'data-field-id' );
1620		formula = $( price_wrapper ).find( '.pewc-data-formula' ).val();
1621		fields = $( price_wrapper ).find( '.pewc-data-fields' ).val();
1622		round = $( price_wrapper ).find( '.pewc-formula-round' ).val();
1623		decimals = $( price_wrapper ).find( '.pewc-decimal-places' ).val();
1624		if( fields ) {
1625			fields = JSON.parse( fields );
1626		}
1627		var reverse_result = calculations.evaluate_formula( fields, reverse_formula, round, decimals, calc_field_id );
1628		// Update the "source" input field with the result of the reverse calculation
1629		// The source input is the number field used in the main calculation field
1630		var source_field_id = $( '.pewc-field-' + triggered_by ).attr( 'data-reverse-input-field' );
1631		$( '.pewc-field-' + source_field_id ).find( 'input' ).val( reverse_result );
1632
1633		// Check if the calculation can be overridden by manual quantity updates
1634		if( $( '.pewc-field-' + triggered_by ).hasClass( 'pewc-quantity-overrides' ) ) {
1635			// Only set the quantity of this field with the result of the calculation once - to allow users to override the calculation by updating the quantity manually
1636			$( wrapper ).addClass( 'pewc-quantity-updated' );
1637		}
1638		
1639	});
1640	$( 'body' ).on( 'pewc_update_child_quantity', function( e, el ) {
1641		// This is triggered when the quantity field for a child product is updated
1642		var child_qty = $( el ).closest('.pewc-checkbox-wrapper').find('input[type=number]').val();
1643		if( child_qty > 0 ) {
1644			$( el ).closest('.pewc-checkbox-image-wrapper').addClass('checked');
1645		} else {
1646			$( el ).closest('.pewc-checkbox-image-wrapper').removeClass('checked');
1647		}
1648	});
1649	$( 'body' ).on( 'click', '.products-quantities-independent .pewc-checkbox-form-field', function( e ) {
1650		if( $( this ).closest( '.pewc-checkbox-images-wrapper' ).hasClass( 'pewc-force-quantity' ) ) {
1651			e.stopPropagation();
1652			return;
1653		}
1654		// this is triggered when clicking the child product's image
1655		if( $(this).is(':checked') ){
1656			var number = $(this).closest('.pewc-checkbox-wrapper').find('input[type=number]').val();
1657			if( number==0 ) {
1658				var default_quantity = $(this).closest( '.pewc-checkbox-wrapper' ).find( 'input[type=number]' ).attr( 'data-default-quantity' );
1659				if( default_quantity == undefined || pewc_vars.set_child_quantity_default != 'yes' ) {
1660					default_quantity = 1;
1661				}
1662				$(this).closest('.pewc-checkbox-wrapper').find('input[type=number]').val( default_quantity );
1663				//$(this).closest('.pewc-checkbox-image-wrapper').addClass('checked'); // commented out in 3.13.2, this is handled when the wrapper itself is clicked
1664			}
1665		} else {
1666			var number = $(this).closest('.pewc-checkbox-wrapper').find('input[type=number]').val(0);
1667			//$(this).closest('.pewc-checkbox-image-wrapper').removeClass('checked'); // commented out in 3.13.2
1668		}
1669		e.stopPropagation(); // added in 3.13.2. this may be triggered when the wrapper is clicked. Prevents infinite loop
1670	});
1671	$( 'body' ).on( 'click', '.products-quantities-linked .pewc-checkbox-form-field, .products-quantities-one-only .pe
1671wc-checkbox-form-field', function( e ) {
1672		e.stopPropagation(); // 3.13.3, prevents infinite loop
1673		if( $(this).is(':checked') ){
1674			$(this).closest('.pewc-checkbox-image-wrapper').addClass('checked');
1675		} else {
1676			$(this).closest('.pewc-checkbox-image-wrapper').removeClass('checked');
1677		}
1678	});
1679
1680	// Toggle class on label when text swatch element is updated
1681	$( 'body' ).on( 'change', '.pewc-text-swatch input', function( e ) {
1682		var field_type = $( this ).closest( '.pewc-item' ).attr( 'data-field-type' );
1683		if( field_type == 'radio' ) {
1684			$( this ).closest( 'ul' ).find( 'label' ).removeClass( 'active-swatch' );
1685		}
1686
1687		if( $( this ).prop( 'checked' ) == true ) {
1688			$( this ).closest( 'label' ).addClass( 'active-swatch' );
1689		} else {
1690			$( this ).closest( 'label' ).removeClass( 'active-swatch' );
1691		}
1692	});
1693
1694	$( 'body' ).on( 'click', '.pewc-radio-image-wrapper, .pewc-checkbox-image-wrapper', function( e ) {
1695		var wrapper = $( this );
1696		if( $( wrapper ).hasClass( 'pewc-checkbox-disabled' ) ) {
1697			return;
1698		}
1699		if( $( wrapper ).closest( '.pewc-components-wrapper' ).hasClass( 'pewc-force-quantity' ) ) {
1700			return;
1701		}
1702		
1703		// 
1704		var radio;
1705		var is_image_swatch_checkbox = $( wrapper ).closest( '.pewc-item' ).hasClass( 'pewc-item-image-swatch-checkbox' );
1706		var is_checkbox = $( wrapper ).hasClass( 'pewc-checkbox-image-wrapper' );
1707		// Remove all checked for radio button
1708		if( ! is_image_swatch_checkbox && ! is_checkbox ) {
1709			var checked = $( wrapper ).find( '.pewc-radio-form-field' ).prop( 'checked' );
1710			var group = $( wrapper ).closest( '.pewc-radio-images-wrapper' ).find( '.pewc-radio-image-wrapper' ).removeClass( 'checked' );
1711			if( ! checked ) {
1712				$( wrapper ).addClass( 'checked' );
1713				//radio = $( wrapper ).find( '.pewc-radio-form-field' ).trigger( 'click' );
1714			}
1715			radio = $( wrapper ).find( '.pewc-radio-form-field' ).trigger( 'click' ); // moved here 3.9.5 for lightbox
1716		} else {
1717			// Checkbox
1718			if ( is_checkbox ) {
1719				// added in 3.13.2 for Products checkbox images
1720				e.preventDefault(); // this helps avoid the conflict with clicking the child product image
1721				radio = $( wrapper ).find( '.pewc-checkbox-form-field' );
1722				$( wrapper ).toggleClass( 'checked' );
1723				$( radio ).trigger( 'click' ); // this triggers the click event attached to .products-quantities-independent .pewc-checkbox-form-field
1724				e.stopPropagation();
1725			} else {
1726				radio = $( wrapper ).find( '.pewc-radio-form-field' );
1727				var checked = $( radio ).prop( 'checked' );
1728				$( wrapper ).toggleClass( 'checked' );
1729				$( radio ).prop( 'checked', ! checked ).trigger( 'click' ); // click added 3.9.5
1730			}
1731		}
1732
1733	}).on( 'click', '.pewc-radio-image-wrapper .pewc-radio-form-field', function( e ) {
1734		var is_image_swatch_checkbox = $( this ).closest( '.pewc-item' ).hasClass( 'pewc-item-image-swatch-checkbox' );
1735		if( ! is_image_swatch_checkbox ) {
1736			// Stop propagation for radio buttons
1737			e.stopPropagation();
1738			// Deselect the radio button
1739			var checked = $( this ).closest( '.pewc-radio-image-wrapper' ).hasClass( 'checked' );
1740			if( ! checked ) {
1741				$( this ).prop( 'checked', false ).trigger( 'change' ); // added on 3.9.5 for lightbox
1742				pewc_update_total_js();
1743			}
1744		} else {
1745			e.stopPropagation(); // added on 3.9.5, for checkbox in lightbox
1746			$( this ).closest( '.pewc-radio-image-wrapper' ).toggleClass( 'checked' ); // originally here before 3.9.5
1747		}
1748		$form = $( this ).closest( 'form' );
1749		add_on_images.update_add_on_image( $( this ), $form );
1750	});
1751
1752	$( 'body' ).on( 'click' , '.products-quantities-independent .pewc-radio-form-field', function() {
1753		if($(this).is(':checked')) {
1754			var number_field = $(this).closest('.pewc-item-field-wrapper').find('input[type=number]');
1755			var number = $(number_field).val();
1756			if( number == 0 ) {
1757				$( number_field ).val( 1 );
1758			}
1759			if( $(this).attr('data-stock') > 0 ) {
1760				// Ensure the quantity field doesn't display more than the available stock
1761				$(number_field).attr( 'max', $(this).attr('data-stock') );
1762				if( $(number_field).val() > $(this).attr('data-stock') ) {
1763					$(number_field).val( $(this).attr('data-stock') );
1764				}
1765			}
1766		} else {
1767			//var number = $(this).closest( '.pewc-radio-images-wrapper' ).find( 'input[type=number]' ).val( 0 );
1768			var number = $(this).closest( '.pewc-item-field-wrapper' ).find( 'input[type=number]' ).val( 0 ); // 3.24.8, change quantity to 0 for Products and Product Categories field, Radio Images layout, independent quantity
1769		}
1770	});
1771
1772	// 3.12.0, handler for enabling/disabling the add-to-cart button
1773	function pewc_toggle_add_to_cart_button( eventType, disabled, caller ) {
1774
1775		var button = $( 'body' ).find( 'form.cart .single_add_to_cart_button' );
1776		var disable_class = 'pewc-disabled-by-'+caller;
1777
1778		if ( button.length < 1 ) return; // do nothing
1779
1780		if ( disabled ) {
1781			// always disable button
1782			button.attr( 'disabled', true );
1783			if ( ! button.hasClass( disable_class ) ) {
1784				button.addClass( disable_class );
1785
1786				// 3.21.5
1787				var button_text = pewc_vars.calculating_text;
1788				if ( caller === 'upload' ) {
1789					button_text = pewc_vars.uploading_text;
1790				}
1791				pewc_update_add_to_cart_button_text( button, button_text );
1792			}
1793		} else {
1794			// remove the disable_class added by the caller when it enabled it previously
1795			button.removeClass( disable_class );
1796			// if we're trying to enable the add-to-cart button, check first if it hasn't been disabled by other plugins (example, by the calculation table)
1797			if ( button.attr( 'class' ).indexOf( 'pewc-disabled-by' ) == -1 ) {
1798				// our special class was not found, safe to enable again
1799				button.attr( 'disabled', false );
1800				pewc_update_add_to_cart_button_text( button, pewc_vars.default_add_to_cart_text );
1801			}
1802		}
1803
1804	}
1805	$( 'body' ).on( 'pewc_toggle_add_to_cart_button', pewc_toggle_add_to_cart_button );
1806
1807	function pewc_update_add_to_cart_button_text( button, button_text ) {
1808		if ( button.is( 'button' ) ) {
1809			button.text( button_text );
1810		} else {
1811			button.val( button_text ); // maybe an input type submit button
1812		}
1813	}
1814
1815	var calculations = {
1816
1817		init: function() {
1818
1819			if( pewc_vars.calculations_timer > 0 ) {
1820				var interval = setInterval(
1821					this.recalculate,
1822					pewc_vars.calculations_timer
1823				);
1824
1825				// since 3.12.0, disable add-to-cart button while recalculating
1826				if ( pewc_vars.disable_button_recalculate == 'yes' ) {
1827					$( 'body' ).on( 'keyup input change paste', 'form.cart .qty', this.disable_add_to_cart_button );
1828					$( 'body' ).on( 'keyup input change paste', 'form.cart .pewc-item.pewc-calculation-trigger, .pewc-form-field.pewc-calculation-trigger, .pewc-field-triggers-condition .pewc-form-field, .pewc-field-triggers-condition .pewc-radio-form-field', this.disable_add_to_cart_button );
1829					$( 'body' ).on( 'keyup input change paste', '.pewc-number-uploads', this.disable_add_to_cart_button );
1830					$( 'body' ).on( 'pewc_trigger_calculations', this.disable_add_to_cart_button );
1831					$( 'body' ).on( 'pewc_conditions_checked', this.disable_add_to_cart_button );
1832				}
1833			} else {
1834				// $( 'body' ).one( 'keyup input change paste', '.pewc-number-field.pewc-calculation-trigger, .pewc-field-triggers-condition .pewc-number-field', this.recalculate );
1835				$( 'body' ).on( 'keyup input change paste', 'form.cart .qty', this.recalculate );
1836				$( 'body' ).on( 'keyup input change paste', 'form.cart .pewc-item.pewc-calculation-trigger, .pewc-form-field.pewc-calculation-trigger, .pewc-field-triggers-condition .pewc-form-field, .pewc-field-triggers-condition .pewc-radio-form-field', this.recalculate );
1837				$( 'body' ).on( 'keyup input change paste', '.pewc-number-uploads', this.recalculate );
1838				$( 'body' ).on( 'pewc_trigger_calculations', this.recalculate );
1839				$( 'body' ).on( 'pewc_conditions_checked', this.recalculate );
1840			}
1841
1842		},
1843
1844		// 3.12.0
1845		disable_add_to_cart_button: function( e ) {
1846			// 3.12.2. Only disable if product has calculation fields
1847			var num_calcs = $( '.pewc-product-extra-groups-wrap .pewc-item-calculation' ).not( '.pewc-hidden-field' ).length;
1848
1849			if( parseFloat( num_calcs ) < 1 ) {
1850				return;
1851			}
1852			pewc_toggle_add_to_cart_button( e, true, 'calculation_recalculate' );
1853		},
1854
1855		recalculate: function( e ) {
1856
1857			// If we don't have any calculation fields, just bounce
1858			var num_calcs = $( '.pewc-product-extra-groups-wrap .pewc-item-calculation' ).not( '.pewc-hidden-field' ).length;
1859
1860			if( parseFloat( num_calcs ) < 1 ) {
1861				return;
1862			}
1863
1864			var calc_field, price_wrapper, dimensions_wrapper, formula, tags, calc_formula, replace, calc_field_id, calc_value, prev_calc_value;
1865
1866			var calc_fields = [];
1867
1868			var update = 0;
1869
1870			if ( pewc_vars.calculations_timer > 0 && pewc_vars.disable_button_recalculate == 'yes' ) {
1871				// 3.12.0, we use this to determine if we have to enable or disable the add-to-cart button
1872				var pewc_total_calc_price_start = $( '#pewc_total_calc_price' ).val();
1873			}
1874
1875			// Find any calculation fields
1876			$( 'body' ).find( 'form.cart .pewc-item-calculation' ).not( '.pewc-hidden-field' ).each( function() {
1877
1878				if( $( this ).hasClass( 'pewc-variation-dependent' ) && ! $( this ).hasClass( 'active' ) ) {
1879					return;
1880				}
1881
1882				var group = $( this ).closest( '.pewc-group-wrap' );
1883				if( $( group ).hasClass( 'pewc-group-hidden' ) ) {
1884					return;
1885				}
1886
1887				var group_id = $( group ).attr( 'data-group-id' );
1888
1889				calc_field = $( this );
1890				var field_id = $( calc_field ).attr( 'data-id' );
1891				calc_field_id = $( calc_field ).attr( 'data-field-id' );
1892				price_wrapper = $( calc_field ).find( '.pewc-calculation-price-wrapper' );
1893				formula = $( price_wrapper ).find( '.pewc-data-formula' ).val();
1894				fields = $( price_wrapper ).find( '.pewc-data-fields' ).val();
1895				tags = $( price_wrapper ).find( '.pewc-data-tag' ).val();
1896				action = $( price_wrapper ).find( '.pewc-action' ).val();
1897				round = $( price_wrapper ).find( '.pewc-formula-round' ).val();
1898				decimals = $( price_wrapper ).find( '.pewc-decimal-places' ).val();
1899				calc_value = $( price_wrapper ).find( '.pewc-calculation-value' );
1900				prev_calc_value = calc_value.val();
1901
1902				if( fields ) {
1903					fields = JSON.parse( fields );
1904				}
1905
1906				var result = calculations.evaluate_formula( fields, formula, round, decimals, calc_field_id );
1907
1908				if( result == '*' ) {
1909					$( calc_field ).closest( '.pewc-item-calculation' ).attr( 'data-price', 0 );
1910					$( price_wrapper ).find( 'span' ).html( pewc_vars.null_signifier );
1911					calc_value.val( 0 );
1912					if ( prev_calc_value != 0 ) {
1913						// 3.12.2. Trigger only if the value changed to avoid infinite loop
1914						calc_value.trigger( 'calculation_field_updated' )
1915					}
1916					if( pewc_vars.disable_button_calcs == 'yes' ) {
1917						calc_fields.push( calc_field_id );
1918						//$( 'body' ).find( 'form.cart .single_add_to_cart_button' ).attr( 'disabled', true );
1919						$( 'body' ).trigger( 'pewc_toggle_add_to_cart_button', [ true, 'calculation' ] ); // since 3.12.0
1920					}
1921				} else if( ! result || ! isNaN( result ) ) {
1922					if( pewc_vars.disable_button_calcs == 'yes' ) {
1923						calc_fields = calc_fields.filter( function( item ) {
1924							return item !== calc_field_id;
1925						});
1926						if( calc_fields.length < 1 ) {
1927							//$( 'body' ).find( 'form.cart .single_add_to_cart_button' ).attr( 'disabled', false );
1928							$( 'body' ).trigger( 'pewc_toggle_add_to_cart_button', [ false, 'calculation' ] ); // since 3.12.0
1929						}
1930					}
1931					$( price_wrapper ).find( 'span' ).html( result );
1932
1933					if( action == 'cost' || action == 'price' ) {
1934						$( calc_field ).closest( '.pewc-item-calculation' ).attr( 'data-price', result );
1935						$( price_wrapper ).find( 'span' ).html( pewc_wc_price( result ) );
1936					} else if( action == 'qty' ) {
1937						$( 'form.cart' ).find( '.quantity .qty' ).val( result ).trigger( 'pewc_qty_changed' );
1938					} else if( action == 'child-qty' ) {
1939						// When a calculation updates, check if it should update a child product quantity field (independent, radio buttons only)
1940						// If it does, we update the quantity field						
1941						// This is the product field that will have its quantity set
1942						var product_field_id = $( calc_field ).closest( '.pewc-item-calculation' ).find( '.pewc-calculation-price-wrapper' ).attr( 'data-product-field-id' );
1943						// This is the ID of the child product that will be selected
1944						var child_qty_product_id = $( calc_field ).closest( '.pewc-item-calculation' ).find( '.pewc-calculation-price-wrapper' ).attr( 'data-child-product-id' );
1945						// Only set the result of this calculation once - don't update quantity if the user has updated it manually themselves
1946						if( ! $( '.pewc-field-' + product_field_id ).hasClass( 'pewc-quantity-updated' ) ) {
1947							$( '.pewc-field-' + product_field_id ).find( '.pewc-child-quantity-field' ).val( result ).trigger( 'pewc_update_child_quantity' );
1948							var group_name = 'pewc_group_' + group_id + '_' + product_field_id;
1949							// Auto select item (provided an item is not already selected)
1950							if( $( "input[name='" + group_name + "_child_product[]']:checked" ).length < 1 ) {
1951								$( '#' + group_name + '_' + child_qty_product_id ).prop( 'checked', true );
1952								$( '#' + group_name + '_' + child_qty_product_id ).closest( '.pewc-radio-image-wrapper' ).addClass( 'checked' );
1953							}
1954						}						
1955					} else if ( ! $( calc_field ).hasClass( 'pewc-hidden-calculation' ) ) {
1956						// no-action falls here, don't bother if calc field is hidden
1957						// pewc-result-format is filterable
1958						var result_format = $( price_wrapper ).find( '.pewc-result-format' ).val();
1959						if ( result_format == 'price' ) {
1960							$( price_wrapper ).find( 'span' ).html( pewc_wc_price( result ) );
1961						} else if ( result_format == 'price without currency' ) {
1962							$( price_wrapper ).find( 'span' ).html( pewc_wc_price_without_currency( result ) );
1963						}
1964					}
1965
1966					if( action == 'price' ) {
1967						$( calc_field ).closest( '.pewc-product-extra-groups-wrap' ).find( '#pewc_calc_set_price' ).val( result ).attr( 'data-calc-set', 1 ); // 3.17.2, compatibility with Product Table Ultimate
1968						//$( '#pewc_calc_set_price' ).val( result ).attr( 'data-calc-set', 1 ); // before 3.17.2
1969					}
1970
1971					calc_value.val( result );
1972					if ( prev_calc_value != result ) {
1973						// 3.12.2. Trigger only if the value changed to avoid infinite loop
1974						calc_value.trigger( 'calculation_field_updated' );
1975						calc_value.trigger( 'change' ); // 3.17.2, makes this field more responsive to changes by typing
1976					}
1977				} else if( result && isNaN( result ) && result != 'error' ) {
1978					if( pewc_vars.allow_text_calcs ) {
1979						$( price_wrapper ).find( 'span' ).html( result );
1980						calc_value.val( result );
1981					}
1982				}
1983
1984				update++;
1985
1986			});
1987
1988			// Update the totals
1989			if( update > 0 ) {
1990				update = 0;
1991				pewc_update_total_js();
1992			}
1993
1994			if ( pewc_vars.calculations_timer > 0 && pewc_vars.disable_button_recalculate == 'yes' ) {
1995				// 3.12.0, we use this to determine if we have to enable or disable the add-to-cart button
1996				var pewc_total_calc_price_end = $( '#pewc_total_calc_price' ).val();
1997				var d = new Date();
1998				var time = d.getTime();
1999
2000				if ( pewc_total_calc_price_start != pewc_total_calc_price_end ) {
2001					// maybe we're not done calculating, disable the add-to-cart button
2002					$( 'body' ).trigger( 'pewc_toggle_add_to_cart_button', [ true, 'calculation_recalculate' ] );
2003					// record the last time there was a change
2004					$( '#pewc_total_calc_price' ).attr( 'data-last-calc-time', time );
2005				} else {
2006					// maybe we're done calculating, let's wait a second?
2007					if ( isNaN( $( '#pewc_total_calc_price' ).attr( 'data-last-calc-time') ) ) {
2008						// maybe this is not yet created, save a value
2009						$( '#pewc_total_calc_price' ).attr( 'data-last-calc-time', time );
2010					} else {
2011						var diff = parseFloat( time ) - parseFloat( $( '#pewc_total_calc_price' ).attr( 'data-last-calc-time') );
2012						if ( isNaN( diff ) || diff < pewc_vars.recalculate_waiting_time ) {
2013							// do nothing if not a number, or less than waiting time (default 0.7 seconds)
2014						} else {
2015							//enable the add-to-cart button
2016							$( 'body' ).trigger( 'pewc_toggle_add_to_cart_button', [ false, 'calculation_recalculate' ] );
2017						}
2018					}
2019				}
2020
2021			}
2022
2023		},
2024
2025		evaluate_look_up_table: function( calc_field_id ) {
2026
2027			var result = false;
2028
2029			if( pewc_look_up_fields == undefined ) return false;
2030
2031			var look_up_field = pewc_look_up_fields[calc_field_id];
2032
2033			var table = look_up_field[0];
2034			var x_field = look_up_field[1];
2035			var y_field = look_up_field[2];
2036
2037			var x_value = this.get_field_value( x_field );
2038			var y_value = this.get_field_value( y_field );
2039
2040			var tables = pewc_look_up_tables[table];
2041			if( tables == undefined ) {
2042				return false;
2043			}
2044
2045			var x_axis = tables[x_value];
2046
2047			// If there's not an element in the tables array for our x value, find the next one
2048			if( x_axis == undefined && x_value && x_value != undefined ) {
2049				if ( this.exact_match( calc_field_id, 'x' ) ) {
2050					return '*'; // 3.13.0, let's use the null signifier
2051				} else {
2052					x_value = calculations.find_nearest_index( x_value, tables );
2053					x_axis = tables[x_value];
2054				}
2055			} else if( x_axis == undefined && x_value==0 && x_value != undefined ) {
2056				x_axis = tables[Object.keys(tables)[0]];
2057			}
2058
2059			if( x_axis != undefined ) {
2060
2061				var y_axis = tables[y_value];
2062
2063				// if( y_axis == undefined && y_value && y_value != undefined ) {
2064				if( y_value && y_value != undefined ) {
2065					if ( ! this.exact_match( calc_field_id, 'y' ) ) {
2066						y_value = calculations.find_nearest_index( y_value, x_axis );
2067					}
2068				}
2069				if( y_value == 'max' ) {
2070					// Get last value in x_axis
2071					result = x_axis[Object.keys(x_axis)[Object.keys(x_axis).length - 1]];
2072				} else {
2073					result = x_axis[y_value];
2074				}
2075
2076				if ( this.exact_match( calc_field_id, 'y' ) && result == undefined ) {
2077					result = '*'; // 3.13.0
2078				}
2079			} else {
2080
2081				return false;
2082
2083			}
2084
2085			return result;
2086
2087		},
2088
2089		get_field_value: function( field_id ) {
2090
2091			var value = 0;
2092
2093			if( $( '.pewc-field-' + field_id ).find( 'input.pewc-number-field' ).length > 0 ) {
2094				return $( '.pewc-field-' + field_id ).find( 'input.pewc-number-field' ).val();
2095			} else if( $( '.pewc-field-' + field_id ).find( 'select' ).length > 0 ) {
2096				return $( '.pewc-field-' + field_id ).find( 'select option:selected' ).attr( 'value' );
2097			} else if( $( '.pewc-field-' + field_id ).find( 'input.pewc-radio-form-field[type="radio"]:checked' ).length > 0 ) {
2098				return $( '.pewc-field-' + field_id ).find( 'input.pewc-radio-form-field[type="radio"]:checked' ).attr( 'data-option-cost' );
2099			}
2100
2101			return value;
2102		},
2103
2104		find_nearest_index: function( value, axis ) {
2105
2106			var keys = Object.keys( axis ); // Just the keys
2107			keys.sort( (a,b) => a-b ); // sort the keys numerically. This is needed if keys have decimals
2108
2109			if( parseFloat( value ) <= parseFloat( keys[0] ) ) {
2110				return keys[0];
2111			}
2112
2113			// If first element is empty, replace with 0
2114			if( pewc_vars.set_initial_key == 'yes' ) {
2115				if( isNaN( keys[0] ) || keys[0] == '' ) {
2116					keys[0] = 0;
2117				}
2118			}
2119
2120			for( var i=0; i < keys.length; i++ ) {
2121				if( ( parseFloat( value ) > parseFloat( keys[i] ) ) && keys[i+1] !=undefined && ( parseFloat( value ) <= parseFloat( keys[i+1] ) ) ) { // Find the first key that is greater than the value passed in
2122					return keys[i+1];
2123				}
2124			}
2125
2126			if( keys[( keys.length ) - 1] == 'max' ) {
2127				return 'max';
2128			}
2129
2130			// Return this as a fallback in case we've gone over the last index
2131			return keys[i];
2132
2133		},
2134
2135		exact_match: function( calc_field_id, axis ) {
2136			// since 3.13.0
2137			if ( $( '.pewc-item-calculation.pewc-field-' + calc_field_id ).attr( 'data-exact-match-' + axis ) == 'yes' ) {
2138				return true;
2139			} else {
2140				return false;
2141			}
2142		},
2143
2144		evaluate_formula: function( fields, formula, round, decimals, calc_field_id ) {
2145
2146			var calc_formula = formula;
2147
2148			if( fields ) {
2149
2150				// Replace any field tags with values
2151				for( var i in fields ) {
2152
2153					// Look for any price values
2154					if( fields[i].indexOf( '_option_price' ) > -1 ) {
2155						var field_id = fields[i].replace( '_option_price', '' );
2156						// We want the price of the selected option in this field, not its value
2157						var o_price = parseFloat( $( 'form.cart .pewc-field-' + field_id ).attr( 'data-selected-option-price' ) );
2158						if( $( 'form.cart .pewc-field-' + field_id ).length == 0 && pewc_vars.zero_missing_field == 'yes' ) {
2159							o_price = 0;
2160						}
2161						replace = new RegExp( '{field_' + fields[i] + '}', 'g' );
2162						calc_formula = calc_formula.replace( replace, o_price );
2163					} else if ( fields[i].indexOf( '_option_value' ) > -1 ) {
2164						var field_id = fields[i].replace( '_option_value', '' );
2165						// We want the value of the selected option in this field
2166						var o_value = parseFloat( $( 'form.cart .pewc-field-' + field_id ).attr('data-field-value') );
2167						if( ( $( 'form.cart .pewc-field-' + field_id ).length == 0 && pewc_vars.zero_missing_field == 'yes' ) || isNaN( o_value ) ) {
2168							o_value = 0;
2169						}
2170						replace = new RegExp( '{field_' + fields[i] + '}', 'g' );
2171						calc_formula = calc_formula.replace( replace, o_value );
2172					} else if( fields[i].indexOf( '_field_price' ) > -1 ) {
2173						// We want the price of the field
2174						var field_id = fields[i].replace( '_field_price', '' );
2175						var f_price = parseFloat( $( 'form.cart .pewc-field-' + field_id ).attr( 'data-field-price' ) );
2176						if( $( 'form.cart .pewc-field-' + field_id ).length == 0 && pewc_vars.zero_missing_field == 'yes' ) {
2177							f_price = 0;
2178						}
2179						replace = new RegExp( '{field_' + fields[i] + '}', 'g' );
2180						calc_formula = calc_formula.replace( replace, f_price );
2181					} else if( fields[i].indexOf( '_number_uploads' ) > -1 ) {
2182						// We want the number of uploads
2183						var field_id = fields[i].replace( '_number_uploads', '' );
2184						var num_uploads = parseFloat( $( 'form.cart .pewc-field-' + field_id ).find( '.pewc-number-uploads' ).val() );
2185						if( $( 'form.cart .pewc-field-' + field_id ).length == 0 && pewc_vars.zero_missing_field == 'yes' ) {
2186							num_uploads = 0;
2187						}
2188						replace = new RegExp( '{field_' + fields[i] + '}', 'g' );
2189						calc_formula = calc_formula.replace( replace, num_uploads );
2190					} else if( fields[i].indexOf( '_pdf_count' ) > -1 ) {
2191						// Get the number of pages for this uploaded PDF
2192						var field_id = fields[i].replace( '_pdf_count', '' );
2193						var pdf_count = parseFloat( $( '#field_' + field_id + "_pdf_count" ).val() );
2194						replace = new RegExp( '{field_' + fields[i] + '}', 'g' );
2195						calc_formula = calc_formula.replace( replace, pdf_count );
2196					} else if( fields[i].indexOf( '_weight' ) > -1 ) {
2197						// Get the weight of child products selected in specified field
2198						var field_id = fields[i].replace( '_weight', '' );
2199						// Find the selected item in the field and get the weight
2200						var weight = $( 'form.cart .pewc-field-' + field_id ).find( 'input:checked').closest( '.pewc-radio-wrapper' ).attr( 'data-
2200product-weight' );
2201						replace = new RegExp( '{field_' + fields[i] + '}', 'g' );
2202						calc_formula = calc_formula.replace( replace, weight );
2203					} else if( fields[i].indexOf( '_length' ) > -1 ) {
2204						// Get the length of child products selected in specified field
2205						var field_id = fields[i].replace( '_length', '' );
2206						// Find the selected item in the field and get the length
2207						var length = $( 'form.cart .pewc-field-' + field_id ).find( 'input:checked').closest( '.pewc-radio-wrapper' ).attr( 'data-product-length' );
2208						replace = new RegExp( '{field_' + fields[i] + '}', 'g' );
2209						calc_formula = calc_formula.replace( replace, length );
2210					} else if( fields[i].indexOf( '_width' ) > -1 ) {
2211						// Get the width of child products selected in specified field
2212						var field_id = fields[i].replace( '_width', '' );
2213						// Find the selected item in the field and get the width
2214						var width = $( 'form.cart .pewc-field-' + field_id ).find( 'input:checked').closest( '.pewc-radio-wrapper' ).attr( 'data-product-width' );
2215						replace = new RegExp( '{field_' + fields[i] + '}', 'g' );
2216						calc_formula = calc_formula.replace( replace, width );
2217					} else if( fields[i].indexOf( '_height' ) > -1 ) {
2218						// Get the height of child products selected in specified field
2219						var field_id = fields[i].replace( '_height', '' );
2220						// Find the selected item in the field and get the height
2221						var height = $( 'form.cart .pewc-field-' + field_id ).find( 'input:checked').closest( '.pewc-radio-wrapper' ).attr( 'data-product-height' );
2222						replace = new RegExp( '{field_' + fields[i] + '}', 'g' );
2223						calc_formula = calc_formula.replace( replace, height );
2224					} else if( fields[i].indexOf( '_quantity' ) > -1 ) {
2225						// Get the quantity of child products in specified field - independent quantities, radio list / images only
2226						var field_id = fields[i].replace( '_quantity', '' );
2227						// Find the selected item in the field and get the quantity
2228						var quantity = $( 'form.cart .pewc-field-' + field_id ).find( '.pewc-independent-quantity-field').val();
2229						replace = new RegExp( '{field_' + fields[i] + '}', 'g' );
2230						calc_formula = calc_formula.replace( replace, quantity );
2231					} else {
2232						// Look for the value of number fields
2233						var f_val = parseFloat( $( 'form.cart .pewc-number-field-' + fields[i] ).val() );
2234						if( ! f_val && pewc_vars.zero_missing_field == 'yes' ) {
2235							f_val = 0;
2236						}
2237						if( ! isNaN( f_val ) ) {
2238							if( $( 'form.cart .pewc-field-' + fields[i] ).length == 0 && pewc_vars.zero_missing_field == 'yes' ) {
2239								f_val = 0;
2240							}
2241							replace = new RegExp( '{field_' + fields[i] + '}', 'g' );
2242							calc_formula = calc_formula.replace( replace, f_val );
2243						}
2244					}
2245
2246				}
2247
2248			}
2249
2250			if( formula === undefined ) {
2251				console.log( 'formula not defined: ' + calc_field_id );
2252				return false;
2253			}
2254
2255			var product_price = parseFloat( $('#pewc-product-price').val() );
2256			// 3.12.0, if action of calculation field is Set Product Price, and if product has an FD bulk discount, use the original product price in the calculation, so that we can then set the discounted price later
2257			if ( typeof pewc_wcfad !== 'undefined' && pewc_wcfad.reset_product_price( formula, calc_field_id ) ) {
2258				product_price = parseFloat( $('#pewc-product-price-original').val() );
2259			}
2260			var quantity = parseFloat( $( 'form.cart .quantity' ).find( '.qty' ).val() );
2261			if( formula.includes( "{look_up_table}" ) ) {
2262				calc_formula = calculations.evaluate_look_up_table( calc_field_id );
2263			}
2264			if( formula.includes( "{product_weight}" ) ) {
2265				var product_weight = parseFloat( $( '#pewc_product_weight' ).val() );
2266				calc_formula = calc_formula.replace( /{product_weight}/g, parseFloat( product_weight ) );
2267			}
2268			if( formula.includes( "{product_height}" ) ) {
2269				var product_height = parseFloat( $( '#pewc_product_height' ).val() );
2270				calc_formula = calc_formula.replace( /{product_height}/g, parseFloat( product_height ) );
2271			}
2272			if( formula.includes( "{product_length}" ) ) {
2273				var product_length = parseFloat( $( '#pewc_product_length' ).val() );
2274				calc_formula = calc_formula.replace( /{product_length}/g, parseFloat( product_length ) );
2275			}
2276			if( formula.includes( "{product_width}" ) ) {
2277				var product_width = parseFloat( $( '#pewc_product_width' ).val() );
2278				calc_formula = calc_formula.replace( /{product_width}/g, parseFloat( product_width ) );
2279			}
2280			if( formula.includes( "{product_price}" ) && product_price ) {
2281				calc_formula = calc_formula.replace( /{product_price}/g, parseFloat( product_price ) );
2282			}
2283			if( formula.includes( "{quantity}" ) && quantity ) {
2284				calc_formula = calc_formula.replace( /{quantity}/g, parseFloat( quantity ) );
2285			}
2286			if( formula.includes( "{variable_1}" ) && pewc_vars.variable_1 ) {
2287				calc_formula = calc_formula.replace( /{variable_1}/g, parseFloat( pewc_vars.variable_1 ) );
2288			}
2289			if( formula.includes( "{variable_2}" ) && pewc_vars.variable_2 ) {
2290				calc_formula = calc_formula.replace( /{variable_2}/g, parseFloat( pewc_vars.variable_2 ) );
2291			}
2292			if( formula.includes( "{variable_3}" ) && pewc_vars.variable_3 ) {
2293				calc_formula = calc_formula.replace( /{variable_3}/g, parseFloat( pewc_vars.variable_3 ) );
2294			}
2295			if( formula.includes( "{calculated_booking_cost}" ) ) {
2296				var calculated_booking_cost = parseFloat( $( '#calculated_booking_cost' ).val() );
2297				calc_formula = calc_formula.replace( /{calculated_booking_cost}/g, parseFloat( calculated_booking_cost ) );
2298			}
2299			if( formula.includes( "{num_units_int}" ) ) {
2300				var num_units_int = parseFloat( $( '#num_units_int' ).val() );
2301				calc_formula = calc_formula.replace( /{num_units_int}/g, parseFloat( num_units_int ) );
2302			}
2303			if( formula.includes( "{num_bookings}" ) ) {
2304				var num_units_int = parseFloat( $( '#num_bookings' ).val() );
2305				calc_formula = calc_formula.replace( /{num_bookings}/g, parseFloat( num_units_int ) );
2306			}
2307			if( formula.includes( "{total_variations}" ) ) {
2308				var total_variations = parseFloat( $( '#wcbvp_total_variations' ).val() );
2309				calc_formula = calc_formula.replace( /{total_variations}/g, parseFloat( total_variations ) );
2310			}
2311			if( formula.includes( "{pa_" ) ) {
2312				var attribute = formula.replace( "{", "" );
2313				var attribute = attribute.replace( "}", "" );
2314				var attribute_data = pewc_vars.attribute_data;
2315				calc_formula = parseFloat( attribute_data[attribute] );
2316			}
2317
2318			if( pewc_vars.global_calc_vars ) {
2319				var global_calc_vars = pewc_vars.global_calc_vars;
2320				// Iterate through our global vars
2321				for( var key in global_calc_vars ) {
2322					if( formula.includes( "{" + key + "}" ) ) {
2323						var global_var = "{" + key + "}";
2324						var global_var_regex = new RegExp( global_var, 'g' );
2325						calc_formula = calc_formula.replace( global_var_regex, global_calc_vars[key] );
2326					}
2327				}
2328			}
2329
2330			// Check for ACF fields
2331			if( typeof pewc_acf_fields != 'undefined' ) {
2332				for( var key in pewc_acf_fields ) {
2333					if( formula.includes( "{acf_" + key + "}" ) ) {
2334						var acf_field = "{acf_" + key + "}";
2335						// Find all instances
2336						var acf_field_regex = new RegExp( acf_field, 'g' );
2337						calc_formula = calc_formula.replace( acf_field_regex, pewc_acf_fields[key] );
2338					}
2339				}
2340			}
2341
2342			var result;
2343
2344			if( calc_formula == '*' ) return calc_formula;
2345
2346			if( pewc_vars.allow_text_calcs ) {
2347				return calc_formula;
2348			}
2349
2350			try {
2351				result = math.eval( calc_formula );
2352
2353				if( round == 'ceil' ) {
2354					result = math.ceil( result );
2355				} else if( round == 'floor' ) {
2356					result = math.floor( result );
2357				}
2358				if( pewc_vars.math_round == 'yes' ) {
2359					result = Math.round( result * 100 ) / 100;
2360				}
2361				return result.toFixed( parseFloat( decimals ) );
2362			} catch( err ) {
2363				// Check all tags have been replaced
2364				return 'error';
2365			}
2366
2367		},
2368
2369		get_formula_by_id: function( reverse_field_id ) {
2370
2371			var formula = $( '.pewc-field-' + reverse_field_id ).find( '.pewc-data-formula' ).val();
2372			return formula;
2373
2374		}
2375
2376	}
2377
2378	calculations.init();
2379
2380	var hidden_groups = {
2381
2382		init: function() {
2383			$( 'body' ).on( 'pewc_conditions_checked', this.check_group_visibility );
2384		},
2385
2386		/**
2387		 * Check whether to hide or display groups
2388		 */
2389		check_group_visibility: function() {
2390
2391			// Check each group
2392			$( 'body' ).find( '.pewc-group-wrap' ).each( function() {
2393				var all_hidden = true;
2394				var group = $( this );
2395				$( group ).find( '.pewc-item' ).each( function() {
2396					if( ! $( this ).hasClass( 'pewc-hidden-field' ) ) {
2397						all_hidden = false;
2398					}
2399				});
2400				if( all_hidden ) {
2401					$( group ).addClass( 'pewc-hidden-group' );
2402				} else {
2403					$( group ).removeClass( 'pewc-hidden-group' );
2404				}
2405			});
2406
2407		}
2408
2409	}
2410
2411	hidden_groups.init();
2412
2413	var summary_panel = {
2414
2415		init: function() {
2416			$( '.pewc-form-field' ).on( 'change update keyup', this.update_panel );
2417		},
2418
2419		update_panel: function( e ) {
2420			var field_id = $( this ).closest( '.pewc-item' ).attr( 'data-field-id' );
2421			var field_value = $( this ).val();
2422		},
2423
2424	}
2425
2426	summary_panel.init();
2427
2428	/**
2429	 * Sets product images for the chosen add-on
2430	 */
2431	var add_on_images = {
2432
2433		init: function() {
2434
2435			var $product        = $( 'form.cart' ).closest( '.product' ),
2436				$product_gallery  = $product.find( pewc_vars.product_gallery ),
2437				$gallery_nav      = $product.find( '.flex-control-nav' ),
2438				$gallery_img      = $gallery_nav.find( 'li:eq(0) img' ),
2439				$product_img_wrap = $product_gallery.find( pewc_vars.product_img_wrap ).eq( 0 ),
2440				$product_img      = $product_img_wrap.find( 'img' ).eq( 0 ),
2441				$product_link     = $product_img_wrap.find( 'a' ).eq( 0 );
2442
2443			if( add_on_images.replace_image() ) {
2444				// create an attribute where we can track where a replaced image came from
2445				$product_img.attr( 'data-pewc-from-field', '' );
2446
2447				// 3.17.2, find the first field that has a default value and not hidden, then auto replace main image with the selected swatch. if multiple are selected, pick the first one?
2448				$( document ).ready( function() {
2449					// we need to delay this so that the main image container takes the size of the original product image
2450					add_on_images.replace_main_with_default();
2451				});
2452
2453				// when Optimised conditions is enabled, update_add_on_image is run first before a group is hidden, so we do this to reset a main image if the field is inside a group that becomes hidden
2454				$( 'body' ).on( 'pewc_group_visibility_updated', function( e, id, action ) {
2455					add_on_images.check_if_src_hidden( $product_img );
2456				});
2457
2458				// 3.21.4, trigger replace main image if field is initially hidden by a condition
2459				$( 'body' ).on( 'pewc_field_visibility_updated', function( e, id, action ) {
2460					var pewc_item = $( '.pewc-item.' + id );
2461					if ( pewc_item.attr( 'data-default-value' ) != '' ) {
2462						// only do this if field has default value that needs to replace the main image
2463						if ( pewc_item.data( 'field-type' ) === 'image_swatch' ) {
2464							// 3.24.6, find the first checked/selected element
2465							var field = pewc_item.find( 'input[name="' + id + '[]"]:checked' )[0];
2466						} else {
2467							var field = pewc_item.find( 'input[name="' + id + '[]"]' )[0];
2468						}
2469						var $form = pewc_item.closest( 'form' );
2470						add_on_images.update_add_on_image( $( field ), $form );
2471					}
2472				});
2473
2474			}
2475
2476			// If we've got parent/child swatches, then hide/show the correct child swatch
2477			$( '.pewc-swatch-parent .pewc-radio-form-field' ).on( 'change', this.change_child );
2478
2479			// If we've got parent/child swatches, then ensure that all the child swatches are in sync
2480			$( '.pewc-swatch-child .pewc-radio-form-field' ).on( 'change', this.sync_children );
2481
2482		},
2483
2484		replace_image: function( field ) {
2485			// 3.17.2
2486			if( pewc_vars.replace_image ) {
2487				// global Replace main image, or the filter pewc_get_add_on_image_action, is used
2488				return pewc_vars.replace_image;
2489			} else if ( field ) {
2490				if ( field.hasClass( 'pewc-replace-main-image' ) ) {
2491					return true;
2492				}
2493			} else {
2494				// if we have just one field that has enabled Replace main image, activate
2495				if ( $( document ).find( '.pewc-replace-main-image' ).length > 0 ) {
2496					return true;
2497				}
2498			}
2499			return false;
2500		},
2501
2502		save_original_src: function( $product_img ) {
2503			if ( $product_img.attr( 'data-pewc-old-src' ) ) {
2504				return; // already set, do nothing
2505			}
2506			// Set original src values
2507			$product_img.attr( 'data-pewc-old-src', $product_img.attr( 'src' ) );
2508			// 3.13.3, data-src is used by WooCommerce zoom image
2509			if ( $product_img.attr( 'data-src' ) ) {
2510				$product_img.attr( 'data-pewc-old-data-src', $product_img.attr( 'data-src' ) );
2511			} else {
2512				$product_img.attr( 'data-pewc-old-data-src', '' );
2513			}
2514			if ( $product_img.attr( 'srcset' ) ) {
2515				$product_img.attr( 'data-pewc-old-srcset', $product_img.attr( 'srcset' ) );
2516			} else {
2517				$product_img.attr( 'data-pewc-old-srcset', '' );
2518			}
2519			// photoswipe gallery
2520			if ( $product_img.attr( 'data-large_image' ) ) {
2521				$product_img.attr( 'data-pewc-old-data-large_image', $product_img.attr( 'data-large_image' ) );
2522			} else {
2523				$product_img.attr( 'data-pewc-old-data-large_image', '' );
2524			}
2525			if ( $product_img.attr( 'data-large_image_width' ) ) {
2526				$product_img.attr( 'data-pewc-old-data-large_image_width', $product_img.attr( 'data-large_image_width' ) );
2527			} else {
2528				$product_img.attr( 'data-pewc-old-data-large_image_width', '' );
2529			}
2530			if ( $product_img.attr( 'data-large_image_height' ) ) {
2531				$product_img.attr( 'data-pewc-old-data-large_image_height', $product_img.attr( 'data-large_image_height' ) );
2532			} else {
2533				$product_img.attr( 'data-pewc-old-data-large_image_height', '' );
2534			}
2535
2536			// zoomImg
2537			var zoomImg = $product_img.closest( pewc_vars.product_img_wrap ).find( 'img.zoomImg' ).eq(0);
2538			if ( zoomImg ) {
2539				$product_img.attr( 'data-pewc-old-zoom', zoomImg.attr( 'src' ) );
2540			}
2541		},
2542
2543		update_add_on_image: function( field, $form ) {
2544			
2545			var field_wrapper = $( field ).closest( '.pewc-item' );
2546			var is_layered = $( field_wrapper ).attr( 'data-field-layered' );
2547
2548			if( ! add_on_images.replace_image( field_wrapper ) && is_layered != 'yes' ) {
2549				return;
2550			}
2551
2552			var field_type = $( field_wrapper ).attr( 'data-field-type' );
2553
2554			var $product        	= $form.closest( '.product' ),
2555				$product_gallery  	= $product.find( pewc_vars.product_gallery ),
2556				$layer_parent 		= pewc_vars.layer_parent,
2557				$gallery_nav      	= $product.find( '.flex-control-nav' ),
2558				$gallery_img      	= $gallery_nav.find( 'li:eq(0) img' ),
2559				$product_img_wrap 	= $product_gallery.find( pewc_vars.product_img_wrap ).eq( 0 ),
2560				$product_img      	= $product_img_wrap.find( 'img' ).eq( 0 ),
2561				$product_link     	= $product_img_wrap.find( 'a' ).eq( 0 );
2562
2563			if( ! $( field_wrapper ).hasClass( 'pewc-has-field-image' ) && field_type != 'image_swatch' && field_type != 'select-box' ) {
2564				// the clicked field is not an image swatch, select box, or does not have a field image, but let's check if we need to replace the main image with the original one
2565				add_on_images.check_if_src_hidden( $product_img );
2566				return;
2567			}
2568
2569			// 3.21.4, Ignore fields in hidden groups
2570			if ( $( field_wrapper ).closest( '.pewc-group-wrap' ).hasClass( 'pewc-group-hidden' ) ) {
2571				add_on_images.check_if_src_hidden( $product_img );
2572				return; 
2573			}
2574
2575			// 3.21.4, Ignore hidden variation-dependent fields and hidden fields
2576			if( ( $( field_wrapper ).hasClass( 'pewc-variation-dependent' ) && ! $( field_wrapper ).hasClass( 'active' ) ) || $( field_wrapper ).hasClass( 'pewc-hidden-field' ) ) {
2577				add_on_images.check_if_src_hidden( $product_img );
2578				return;
2579			}
2580
2581			var add_on_image_wrapper;
2582			var add_on_image_src;
2583			var add_on_image_large_image, add_on_image_large_image_width, add_on_image_large_image_height;
2584			var turn = 'off';
2585			if( field_type == 'checkbox' && $( field ).prop( 'checked' ) && add_on_images.replace_image( field_wrapper ) != 'replace_image_swatch_only' ) {
2586				turn = 'on';
2587				add_on_image_wrapper = $( field_wrapper ).find( '.pewc-item-field-image-wrapper' );
2588				add_on_image_src = $( add_on_image_wrapper ).attr( 'data-image-full-size' );
2589				add_on_image_srcset = add_on_image_src;
2590				// photoswipe gallery
2591				add_on_image_large_image = $( add_on_image_wrapper ).attr( 'data-image-full-size' );
2592				add_on_image_large_image_width = $( add_on_image_wrapper ).attr( 'data-large_image_width' );
2593				add_on_image_large_image_height = $( add_on_image_wrapper ).attr( 'data-large_image_height' );
2594			}
2595			if( field_type == 'image_swatch') {
2596				add_on_image_wrapper = field.closest( '.pewc-radio-image-wrapper' );
2597
2598				if ( add_on_image_wrapper.hasClass('checked') ) {
2599					add_on_image_src = add_on_image_wrapper.find( 'img' ).attr( 'data-src' );
2600					add_on_image_srcset = add_on_image_src;
2601					// photoswipe gallery
2602					add_on_image_large_image = add_on_image_wrapper.find( 'img' ).attr( 'data-large_image' );
2603					add_on_image_large_image_width = add_on_image_wrapper.find( 'img' ).attr( 'data-large_image_width' );
2604					add_on_image_large_image_height = add_on_image_wrapper.find( 'img' ).attr( 'data-large_image_height' );
2605
2606					if (add_on_image_src != undefined) {
2607						turn = 'on';
2608					}
2609				}
2610			} else if ( field_type == 'select-box' && add_on_images.replace_image( field_wrapper ) != 'replace_image_swatch_only' ) {
2611				// 3.13.7
2612				if ( field_wrapper.find( 'input.dd-selected-value' ).val() != '' ) {
2613					// check if the full image exists
2614					var src_image = field_wrapper.find( 'input.dd-selected-image-full' );
2615					if ( src_image.length > 0 ) {
2616						add_on_image_src = src_image.val();
2617					} else {
2618						src_image = field_wrapper.find( 'img.dd-selected-image' );
2619						add_on_image_src = src_image.attr( 'src' );
2620					}
2621					add_on_image_srcset = add_on_image_src;
2622					// photoswipe gallery
2623					add_on_image_large_image = add_on_image_src;
2624					add_on_image_large_image_width = src_image.attr( 'data-imgsrc-width' );
2625					add_on_image_large_image_height = src_image.attr( 'data-imgsrc-height' );
2626
2627					if ( add_on_image_src != undefined) {
2628						turn = 'on';
2629					}
2630				}
2631			}
2632
2633			if( is_layered == 'yes' ) {
2634				// This is a layered image so we are going to create/update layers
2635				var field_id = $( field_wrapper ).attr( 'data-field-id' );
2636				var layer_id = 'pewc-layer-' + field_id;
2637				var layer_index = $( field_wrapper ).attr( 'data-field-index' );
2638				// This is the wrapper, e.g. woocommerce-product-gallery__wrapper
2639				// Add our cloned image into a div within this wrapper
2640				// The wrapper can be absolutely positioned over the main image
2641				var swatch_src = $( add_on_image_wrapper ).find( 'img' ).attr( 'data-large_image' );
2642				// Check for an alternative image to replace the main image
2643				if( $( add_on_image_wrapper ).find( 'img' ).attr( 'data-alt_image' ).length > 0 ) {
2644					swatch_src = $( add_on_image_wrapper ).find( 'img' ).attr( 'data-alt_image' );
2645				}
2646				if( $( '.' + layer_id ).length === 0 && $( add_on_image_wrapper ).hasClass( 'checked' ) ) {
2647					// Get the selected swatch image src
2648					var layer_image = '<img class="pewc-layer-image" src="' + swatch_src + '">';
2649					// Make the layer
2650					// var layer = $product_img.clone().insertAfter( $product_img ).addClass( layer_id );
2651					$( $( '.' + $layer_parent ) ).append( '<div class="pewc-image-layer ' + layer_id + '" style="z-index:' + layer_index * 10 + '">' + layer_image + '</div>' );
2652				} else if( $( '.' + layer_id ).length !== 0 && $( add_on_image_wrapper ).hasClass( 'checked' ) ) {
2653					// Layer exists but need to update the image inside
2654					// swatch_src = $( add_on_image_wrapper ).find( 'img' ).attr( 'data-large_image' );
2655					$( '.' + layer_id ).find( 'img' ).attr( 'src', swatch_src );
2656				} else if( ! $( add_on_image_wrapper ).hasClass( 'checked' ) ) {
2657					$( '.' + layer_id ).remove();
2658				}
2659
2660			} else if ( add_on_image_src && turn == 'on' ) {
2661				// maybe save original
2662				add_on_images.save_original_src( $product_img );
2663				$product_img.attr( 'data-pewc-from-field', $( field_wrapper ).attr( 'data-id' ) );
2664				$product_img.attr( 'src', add_on_image_src );
2665				$product_img.attr( 'srcset', add_on_image_srcset );
2666				$product_img.attr( 'data-src', add_on_image_src ); // 3.13.3, used by WC zoomImg
2667				// replace photoswipe gallery
2668				$product_img.attr( 'data-large_image', add_on_image_large_image );
2669				$product_img.attr( 'data-large_image_width', add_on_image_large_image_width );
2670				$product_img.attr( 'data-large_image_height', add_on_image_large_image_height );
2671				// replace zoom image
2672				var zoomImg = $product_img.closest( pewc_vars.product_img_wrap ).find( 'img.zoomImg' ).eq(0);
2673				if ( zoomImg ) {
2674					zoomImg.attr( 'src', add_on_image_src );
2675				}
2676			} else {
2677				//add_on_images.reset_main_image( $product_img );
2678				add_on_images.replace_main_with_default( $product_img, false ); // 3.24.7, let's try to find an active swatch first before resetting the main image
2679			}
2680
2681			// 3.13.2 bring back the focus on the main image to see the selected image swatch
2682			if ( pewc_vars.replace_image_focus == 'yes' ) {
2683				var control_list_selector = '.' + pewc_vars.control_container + ' ' + pewc_vars.control_list;
2684				$( control_list_selector ).first().find( pewc_vars.control_element ).click();
2685				$( 'body' ).trigger( 'pewc_update_add_on_image_focus_on_main_image' ); // 3.23.1, for other sliders that have a different way of focusing on the first image e.g. Flickity
2686			}
2687		},
2688
2689		// If we are using secondary images, then hide/show the correct child swatch field
2690		change_child: function( e ) {
2691			
2692			var parent_swatch = e.target;
2693			var parent_index = $( parent_swatch ).closest( '.pewc-item' ).find( '.pewc-radio-image-wrapper.checked input' ).attr( 'data-option-index' );
2694			if( ! isNaN( parent_index ) ) {
2695				$( '.pewc-swatch-child' ).addClass( 'pewc-visibility-hidden' );
2696				$( '.pewc-swatch-child-' + parent_index ).removeClass( 'pewc-visibility-hidden' );
2697				var active_layer_id = $( '.pewc-swatch-child-' + parent_index ).attr( 'data-field-id' );
2698				// Get the selected child index
2699				var selected_input = $( '.pewc-swatch-child' ).not( '.pewc-visibility-hidden' ).closest( '.pewc-item' ).find( '.pewc-radio-image-wrapper.checked input' );
2700				var index = $( selected_input ).attr( 'data-option-index' );
2701				// console.log( 'Display parent index ' + parent_index + ' and child index ' + index );
2702				// Trigger the child swatch
2703				// var selected = $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).prop( 'checked' );
2704
2705				$( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper.pewc-radio-form-field' ).prop('checked', false);
2706
2707				// When we change the child, we need to hide unwanted image layers on the main image
2708				$( '.pewc-layer-' + active_layer_id ).show();
2709				// Hide the other child swatch layers
2710				var child_swatch_ids = JSON.parse( pewc_vars.child_swatch_ids );
2711				for( var i in child_swatch_ids ) {
2712					if( child_swatch_ids[i] != active_layer_id ) {
2713						$( '.pewc-layer-' + child_swatch_ids[i] ).fadeOut( 150 );
2714					} 
2715				}
2716				// Find any layers that we need to hide
2717				// $( '.pewc-show-for' ).each( function( layer_index, element ) {
2718				// 	// This layer only shows when a specific field is visible
2719				// 	var show_for = $( this ).attr( 'data-show-for' );
2720				// 	console.log( 'show for', show_for );
2721				// 	var layer_id = $( this ).attr( 'data-field-id' );
2722				// 	console.log( 'layer_id', layer_id );
2723				// 	if( show_for != active_layer_id ) {
2724				// 		$( '.pewc-layer-' + layer_id ).fadeOut( 150 );
2725				// 	} else {
2726				// 		$( '.pewc-layer-' + layer_id ).fadeIn( 150 );
2727				// 	}
2728				// });
2729				// $( '.pewc-image-layer' ).not( '.pewc-layer-' + active_layer_id ).fadeOut( 250 );
2730				
2731
2732				// if( ! selected ) {
2733					// console.log( 'selected 1', selected );
2734					$( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).addClass( 'here-' + parent_index + '-' + index ).trigger( 'click' );
2735					// selected = $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).prop( 'checked' );
2736					$( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).trigger( 'change' );
2737					// console.log( 'selected 2', selected );
2738					// if( selected ) {
2739						// $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).prop( 'checked', false ).trigger( 'change' );
2740						// selected = $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).prop( 'checked' );
2741						// $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).addClass( 'here-' + parent_index + '-' + index ).trigger( 'click' );
2742						// selected = $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).prop( 'checked' );
2743					// }
2744
2745				// }
2746				
2747			}
2748
2749		},
2750
2751		// If we've updated a child swatch, we need to ensure that other child swatches have the same value
2752		sync_children: function( e ) {
2753
2754			// Get the active parent index
2755			var parent_index = $( '.pewc-swatch-parent' ).find( '.pewc-radio-image-wrapper.checked input' ).attr( 'data-option-index' );
2756			var child_swatch = e.target;
2757			// Get the index of the selected child swatch
2758			var index = $( child_swatch ).closest( '.pewc-item' ).find( '.pewc-radio-image-wrapper.checked input' ).attr( 'data-option-index' );
2759			if( ! isNaN( index ) ) {
2760				// Ensure that all other child swatch fields have the same item selected
2761				$( '.pewc-swatch-child' ).find( '.pewc-radio-image-wrapper' ).removeClass( 'checked' );
2762				$( '.pewc-swatch-child' ).find( '.pewc-radio-image-wrapper-' + index ).addClass( 'checked' ).find( 'input' );
2763				// Need to ensure that the correct main image is displayed
2764				// Trigger a click on the currently visible selected swatch
2765				var input = $( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' );
2766				$( '.pewc-swatch-child-' + parent_index ).find( '.pewc-radio-image-wrapper-' + index + ' input' ).trigger( 'click' );
2767			}
2768
2769		},
2770
2771		check_if_src_hidden: function( $product_img ) {
2772			if ( $product_img.attr('data-pewc-from-field') != '' ) {
2773
2774				// main image is using an image from a field, check if the field where it came from is currently hidden. if so, put back the original main image
2775				var pewc_from_field = $( ".pewc-item."+$product_img.attr('data-pewc-from-field') );
2776
2777				if ( pewc_from_field.hasClass( 'pewc-hidden-field') || pewc_from_field.closest( '.pewc-group-wrap' ).hasClass( 'pewc-group-hidden') || ( pewc_from_field.hasClass( 'pewc-variation-dependent' ) && ! pewc_from_field.hasClass( 'active' ) ) ) {
2778					// field is hidden, reset image
2779					// 3.21.4, added variation-dependent fields
2780					//add_on_images.reset_main_image( $product_img );
2781					add_on_images.replace_main_with_default( $product_img ); // 3.24.7, let's try to find an active swatch first before resetting the main image
2782				}
2783			}
2784		},
2785
2786		reset_main_image: function ( $product_img ) {
2787			$product_img.attr( 'data-pewc-from-field', '' );
2788			$product_img.attr( 'src', $product_img.attr( 'data-pewc-old-src' ) );
2789			$product_img.attr( 'srcset', $product_img.attr( 'data-pewc-old-srcset' ) );
2790			$product_img.attr( 'data-src', $product_img.attr( 'data-pewc-old-data-src' ) ); // 3.13.3
2791			// photoswipe gallery
2792			$product_img.attr( 'data-large_image', $product_img.attr( 'data-pewc-old-data-large_image' ) );
2793			$product_img.attr( 'data-large_image_width', $product_img.attr( 'data-pewc-old-data-large_image_width' ) );
2794			$product_img.attr( 'data-large_image_height', $product_img.attr( 'data-pewc-old-data-large_image_height' ) );
2795			// zoom image
2796			var zoomImg = $product_img.closest( pewc_vars.product_img_wrap ).find( 'img.zoomImg' ).eq(0);
2797			if ( zoomImg ) {
2798				zoomImg.attr( 'src', $product_img.attr( 'data-pewc-old-zoom' ) );
2799			}
2800		},
2801
2802		replace_main_with_default: function( $product_img='', is_layered=true ) {
2803			// 3.17.2
2804			var replace_fields = [ 'image_swatch', 'select-box', 'checkbox' ];
2805			var replaced = false;
2806
2807			$( '.pewc-item' ).each( function( index, element ) {
2808				// 3.20.1
2809				var layered_image = $(this).hasClass( 'pewc-layered-image' );
2810
2811				// Replace main image is not active for this field, skip
2812				if ( ! add_on_images.replace_image( $(this) ) ) {
2813					return;
2814				}
2815
2816				// 3.25.4, skip layered images when resetting normal swatch fields?
2817				if ( layered_image && ! is_layered ) {
2818					return;
2819				}
2820
2821				// Main image has been replaced, we can skip
2822				// 3.20.1, don't skip if this is a layered image
2823				if ( replaced && ! layered_image ) {
2824					return;
2825				}
2826
2827				// Ignore fields in hidden groups
2828				if ( $( this ).closest( '.pewc-group-wrap' ).hasClass( 'pewc-group-hidden' ) ) {
2829					return; 
2830				}
2831
2832				// Ignore hidden variation-dependent fields and hidden fields
2833				if( ( $( this ).hasClass( 'pewc-variation-dependent' ) && ! $( this ).hasClass( 'active' ) ) || $( this ).hasClass( 'pewc-hidden-field' ) ) {
2834					return;
2835				}
2836
2837				if ( replace_fields.indexOf( $( this ).attr( 'data-field-type' ) ) > -1 && $( this ).attr( 'data-field-value' ) != '' ) {
2838					// 3.22.1, replaced data-default value with data-field-value in the condition so that the main image is also replaced when editing add-ons via Edit options on the cart
2839					var field_type = $( this ).attr( 'data-field-type' );
2840					if ( field_type  == 'image_swatch' ) {
2841						// find the first checked input, that must be the default
2842						$( this ).find( '.pewc-radio-form-field' ).each( function( index, element ){
2843							// 3.20.1, allow multiple layered images with default values
2844							if ( $( this ).is( ':checked' ) && ( ! replaced || layered_image ) ) {
2845								add_on_images.update_add_on_image( $( this ), $(this).closest( 'form' ) );
2846								replaced = true;
2847								return;
2848							}
2849						});
2850					} else if ( field_type == 'checkbox' ) {
2851						if ( $( this ).find( '.pewc-form-field' ).is( ':checked' ) ) {
2852							add_on_images.update_add_on_image( $( this ).find( '.pewc-form-field' ), $(this).closest( 'form' ) );
2853							replaced = true;
2854							return;
2855						}
2856					} else if ( field_type == 'select-box' ) {
2857						add_on_images.update_add_on_image( $( this ).find( 'select.pewc-form-field' ), $(this).closest( 'form' ) );
2858						replaced = true;
2859						return;
2860					}
2861				}
2862			});
2863
2864			// 3.24.7, if we didn't find a swatch, reset the main image
2865			if ( ! replaced && $product_img != '' ) {
2866				add_on_images.reset_main_image( $product_img );
2867			}
2868		},
2869
2870	}
2871
2872	add_on_images.init();
2873
2874	var tooltips = {
2875
2876		init: function() {
2877
2878			if( pewc_vars.enable_tooltips == 'yes' && ! pewc_vars.dequeue_tooltips ) {
2879				$( '.tooltip' ).tooltipster(
2880					{
2881						theme: 'tooltipster-shadow',
2882		        		side: 'right',
2883						contentAsHTML: pewc_vars.contentAsHTML,
2884						autoClose : pewc_vars.autoClose,
2885						interactive : pewc_vars.interactive,
2886						hideOnClick : pewc_vars.hideOnClick,
2887						trigger : pewc_vars.trigger,
2888						triggerOpen : pewc_vars.triggerOpen,
2889						triggerClose: pewc_vars.triggerClose
2890					}
2891				);
2892			}
2893
2894		}
2895
2896	}
2897
2898	tooltips.init();
2899
2900	var quickview = {
2901
2902		init: function() {
2903			$( 'body' ).on( 'click', '.pewc-show-quickview', this.show_quickview );
2904			$( 'body' ).on( 'click', '#pewc-quickview-background, .pewc-close-quickview', this.hide_quickview );
2905		},
2906
2907		show_quickview: function( e ) {
2908			e.stopPropagation();
2909			if( pewc_vars.quickview == 'yes' ) {
2910				// Open the link in a new tab
2911				e.preventDefault();
2912				$( 'body' ).addClass( 'pewc-quickview-active' );
2913			}
2914			
2915			// $( '.pewc-quickview-product-wrapper' ).hide();
2916			$( '#pewc-quickview-' + $(this).closest( 'li.pewc-item' ).attr( 'data-id' ) + '_' + $( this ).attr( 'data-child-product-id' ) ).css( 'left', '50%' );
2917		},
2918
2919		hide_quickview: function( e ) {
2920			 e.preventDefault();
2921			 $( 'body' ).removeClass( 'pewc-quickview-active' );
2922			 $( '.pewc-quickview-product-wrapper' ).css( 'left', '-5000px' );
2923		}
2924
2925	}
2926
2927	quickview.init();
2928
2929}
2929)(jQuery);
2930
2931// 3.21.4, moved outside so that other scripts can use this function
2932function pewc_wc_price_without_currency( price ) {
2933
2934	var price_settings = {
2935		decimal: pewc_vars.decimal_separator,
2936		thousand: pewc_vars.thousand_separator,
2937		precision: pewc_vars.decimals,
2938		format: '%v'
2939	};
2940
2941	if ( pewc_vars.price_trim_zeros == 'yes' && price == parseInt( price ) ) {
2942		// 3.21.3, trim zeros if filter is active
2943		price_settings.precision = 0;
2944	}
2945
2946	// since 3.12.0
2947	price = accounting.formatMoney( price, price_settings );
2948
2949	return price;
2950
2951}
2952
2953// 3.21.4, moved outside so that other scripts can use this function
2954function pewc_wc_price( price, price_only=false, update_pewc_total_calc_price=true ) {
2955
2956	if ( update_pewc_total_calc_price ) {
2957		jQuery( '#pewc_total_calc_price' ).val( price ); // Used in Bookings for WooCommerce
2958	}
2959
2960	// since 3.12.0
2961	var currency_html = '<span class="woocommerce-Price-currencySymbol">%s</span>';
2962	var currency_format = '';
2963	if ( price_only ) {
2964		currency_html = '%s';
2965	}
2966
2967	if( pewc_vars.currency_pos == 'left' ) {
2968		currency_format = currency_html+'%v';
2969	} else if( pewc_vars.currency_pos == 'right' ) {
2970		currency_format = '%v'+currency_html;
2971	} else if( pewc_vars.currency_pos == 'left_space' ) {
2972		currency_format = currency_html+' %v';
2973	} else if( pewc_vars.currency_pos == 'right_space' ) {
2974		currency_format = '%v '+currency_html;
2975	}
2976
2977	var price_settings = {
2978		symbol: pewc_vars.currency_symbol,
2979		decimal: pewc_vars.decimal_separator,
2980		thousand: pewc_vars.thousand_separator,
2981		precision: pewc_vars.decimals,
2982		format: currency_format
2983	};
2984
2985	if ( pewc_vars.price_trim_zeros == 'yes' && price == parseInt( price ) ) {
2986		// 3.21.3, trim zeros if filter is active
2987		price_settings.precision = 0;
2988	}
2989
2990	price = accounting.formatMoney( price, price_settings );
2991
2992	if ( ! price_only ) {
2993		return '<span class="woocommerce-Price-amount amount"><bdi>' + price + '</bdi></span>';
2994	}
2995
2996	return price;
2997
2998}
2999
3000// 3.21.7
3001function pewc_wcfad_apply_discount() {
3002	return typeof pewc_wcfad !== 'undefined' && pewc_wcfad.apply_discount();
3003}

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.