PageSourceSearch

https://www.lomo.co.uk/wp-content/plugins/checkout-upsell-woocommerce/assets/js/template.js?ver=2.1.4

js lomo.co.uk collected 2026-10-10 01:18:18 UTC 36,536 bytes, 755 lines download raw bytes

1jQuery(function ($) {
2
3    let cuw_data = cuw_template.data;
4    let cuw_i18n = cuw_template.i18n;
5    let cuw_is_rtl = cuw_template.is_rtl;
6
7    /* Offer */
8    window.cuw_offer = {
9        // init
10        init: function () {
11            this.event_listeners();
12            if ($("#cuw-ppu-offer").length) {
13                cuw_offer.update_ppu_totals($("#cuw-ppu-offer"));
14            }
15        },
16
17        // update price when change variant
18        update_price: function (select, section) {
19            let variant = select.find('option:selected');
20            section.find('.cuw-product-price, .cuw-page-product-price, .cuw-ppu-product-price').html(variant.data('price_html'));
21            section.find('.cuw-ppu-order-totals').data('price', variant.data('price')).data('tax', variant.data('tax'));
22            section.find('.cuw-qty').prop('max', variant.data('stock_qty'));
23            if (variant.data('image')) {
24                section.find('.cuw-product-image, .cuw-page-product-image, .cuw-ppu-product-image').html(variant.data('image'));
25            }
26        },
27
28        // update the closest quantity input on click press plus or minus button
29        update_quantity: function (button) {
30            let wrapper = button.parent();
31            let input = wrapper.find('input'),
32                val = parseFloat(input.val()) || 0,
33                max = parseFloat(input.attr('max')) || '',
34                min = parseFloat(input.attr('min')) || 0,
35                step = parseFloat(input.attr('step')) || 1;
36
37            if (button.is('.cuw-plus')) {
38                if (max && (val >= max)) input.val(max);
39                else input.val(val + step);
40            } else {
41                if (min && (val <= min)) input.val(min);
42                else if (val > 0) input.val(val - step);
43            }
44
45            val = parseFloat(input.val()); // to get current value
46            wrapper.find('.cuw-minus').css('opacity', min === val ? 0.6 : 1);
47            wrapper.find('.cuw-plus').css('opacity', max === val ? 0.6 : 1);
48            input.trigger('change');
49        },
50
51        // to check inputting quantity
52        check_quantity: function (input) {
53            let product_quantity = parseInt(input.val());
54            let max_quantity = parseInt(input.prop('max'));
55            if (product_quantity > max_quantity) {
56                input.val(max_quantity);
57            }
58            input.closest('.quantity-input').find('.cuw-plus').css('opacity', product_quantity >= max_quantity ? 0.6 : 1);
59            input.closest('.cuw-offer, .cuw-page, .cuw-product, .cuw-product-row').find('.variant-select').trigger('change');
60        },
61
62        update_ppu_totals: function (section) {
63            let qty = section.find(".cuw-ppu-product-quantity .cuw-qty").val();
64            if (qty === undefined) {
65                qty = section.find(".cuw-ppu-order-totals").data('qty');
66            }
67            let product_price = section.find(".cuw-ppu-order-totals").data('price');
68            let tax = section.find(".cuw-ppu-order-totals").data('tax');
69            let order_total = section.find(".cuw-ppu-order-totals").data('order_total');
70
71            let subtotal = parseFloat(product_price) * parseFloat(qty);
72            let subtotal_tax = parseFloat(tax) * parseFloat(qty);
73            let updated_order_total = parseFloat(order_total) + subtotal + subtotal_tax;
74            section.find(".cuw-ppu-subtotal").html(cuw_helper.format_price(subtotal));
75            section.find(".cuw-ppu-tax").html(cuw_helper.format_price(subtotal_tax));
76            section.find(".cuw-ppu-total").html(cuw_helper.format_price(updated_order_total));
77        },
78
79        // to load event listeners
80        event_listeners: function () {
81            $(document).on("click", ".cuw-offer .quantity-input .cuw-plus, .cuw-offer .quantity-input .cuw-minus", function () {
82                cuw_offer.update_quantity($(this));
83            });
84
85            $(document).on("click", ".cuw-page .quantity-input .cuw-plus, .cuw-page .quantity-input .cuw-minus", function () {
86                cuw_offer.update_quantity($(this));
87            });
88
89            $(document).on("change", ".cuw-offer .variant-select", function () {
90                cuw_offer.update_price($(this), $(this).closest('.cuw-offer'));
91            });
92
93            $(document).on("input", '.cuw-offer .cuw-qty, #cuw-ppu-offer .cuw-qty', function () {
94                cuw_offer.check_quantity($(this));
95            });
96
97            $(document).on("change", '#cuw-ppu-offer .cuw-qty', function () {
98                cuw_offer.update_ppu_totals($("#cuw-ppu-offer"));
99            });
100
101            $(document).on("change", ".cuw-page .variant-select", function () {
102                cuw_offer.update_price($(this), $(this).closest('.cuw-page'));
103                cuw_offer.update_ppu_totals($("#cuw-ppu-offer"));
104            });
105        },
106    }
107
108    /* Products */
109    window.cuw_products = {
110        // init
111        init: function () {
112            this.event_listeners();
113            this.load_sections();
114        },
115
116        // load all available sections
117        load_sections: function () {
118            $(".cuw-products").each(function (index, section) {
119                cuw_products.load_section($(section));
120            });
121        },
122
123        // load specific section
124        load_section: function (section) {
125            section.find('.variant-select').trigger('change');
126            cuw_products.update_prices(section);
127        },
128
129        // get all products
130        get_all_products: function (section) {
131            let products = [];
132            section.find('.cuw-product').each(function (index, product) {
133                if ($(product).find(".cuw-product-checkbox").length || $(product).data('key')) {
134                    products.push($(product));
135                }
136            });
137            return products;
138        },
139
140        // get chosen products
141        get_chosen_products: function (section) {
142            let products = [];
143            section.find('.cuw-product').each(function (index, product) {
144                if ($(product).find(".cuw-product-checkbox").prop("checked") || $(product).data('key')) {
145                    products.push($(product));
146                }
147            });
148            return products;
149        },
150
151        // update modal product prices
152        update_product_row: function (section, product_row) {
153            let price_column = product_row.find('.cuw-product-price');
154            let product_id = product_row.data('product_id'), variant_id;
155            if (!product_id) {
156                product_id = product_row.data('id');
157            }
158
159            let product = section.find('.cuw-product[data-id="' + product_id + '"]').first();
160            let variant_select = product_row.find('.variant-select').first();
161            if (variant_select && variant_select.length) {
162                variant_id = variant_select.val();
163                let variant = variant_select.find('option[value="' + variant_id + '"]').first();
164                product.data('regular_price', variant.data('regular_price'));
165                product.data('price', variant.data('price'));
166                if (product_id) {
167                    product.closest('.cuw-products').find('.cuw-product[data-id="' + product_id + '"]').data('regular_price', variant.data('regular_price'));
168                    product.closest('.cuw-products').find('.cuw-product[data-id="' + product_id + '"]').data('price', variant.data('price'));
169                }
170                product.find('.cuw-product-variation-id').val(variant_id);
171                product.find('.cuw-product-variation-attributes-json').val(JSON.stringify(variant_select.data('chosen_attributes')));
172                product_row.find('.cuw-product-variation-id').val(variant_id);
173                product_row.find('.cuw-qty').prop('max', variant.data('stock_qty'));
174                if (variant.data('image')) {
175                    if (section.data('change_image') != 'only_row') {
176                        product.find('.cuw-product-image').html(variant.data('image'));
177                    }
178                    product_row.find('.cuw-product-image').html(variant.data('image'));
179                }
180                price_column.html(variant.data('price_html'));
181                //price_column.html(cuw_helper.get_price_html(variant.data('price'), variant.data('regular_price')));
182            } else if (price_column.html() === '') {
183                price_column.html(product.find('.cuw-product-price').html());
184                //price_column.html(cuw_helper.get_price_html(product.data('price'), product.data('regular_price')));
185            }
186        },
187
188        // update pricing section
189        update_prices: function (section, data = {}) {
190            if (section.closest('.cuw-modal').length > 0) {
191                section = section.closest('.cuw-modal');
192            }
193            let regular_price_total = 0, price_total = 0, items = 0, main_price = 0, main_item = 0, addons_price = 0,
194                addon_items = 0;
195            let total_items = this.get_all_products(section).length;
196            let main_product_id = parseInt(section.find('[name="main_product_id"]').val());
197            this.get_chosen_products(section).forEach(function (product) {
198                let quantity = 1;
199                if (product.find('.quantity-input .cuw-qty').length > 0) {
200                    quantity = parseFloat(product.find('.quantity-input .cuw-qty').first().val());
201                } else if (product.data('quantity')) {
202                    quantity = parseFloat(product.data('quantity'));
203                }
204                if (main_product_id === product.data('id')) {
205                    main_price = parseFloat(product.data('price')) * quantity;
206                    main_item = 1;
207                } else {
208                    addons_price += parseFloat(product.data('price')) * quantity;
209                    addon_items++;
210                }
211                regular_price_total += parseFloat(product.data('regular_price')) * quantity;
212                price_total += parseFloat(product.data('price')) * quantity;
213                items++;
214            });
215
216            let total_savings = regular_price_total - price_total;
217            let at_least_items = parseInt(section.find(".cuw-buy-section").find(".cuw-add-to-cart").data('at_least_items')) || 1;
218            if (items >= at_least_items) {
219                section.find(".cuw-buy-section .cuw-message").hide();
220                if (section.find(".cuw-buy-section .cuw-actions").first().data('inactive') === 'disable') {
221                    section.find(".cuw-buy-section .cuw-actions").show();
222                    section.find(".cuw-buy-section .cuw-actions").find(":input").prop('disabled', false);
223                } else {
224                    section.find(".cuw-buy-section .cuw-actions").show();
225                }
226                section.find(".cuw-buy-section .cuw-prices").show();
227
228                section.find(".cuw-main-item").html(main_item);
229                section.find(".cuw-addon-items").html(addon_items);
230                section.find(".cuw-total-items").html(items);
231                section.find(".cuw-main-price").html(cuw_helper.get_price_html(main_price));
232                section.find(".cuw-addons-price").html(cuw_helper.get_price_html(addons_price));
233
234                if (section.data('main_product_price')) {
235                    regular_price_total += parseFloat(section.data('main_product_regular_price'));
236                    price_total += parseFloat(section.data('main_product_price'));
237                }
238
239                section.find(".cuw-total-price").html(cuw_helper.get_price_html(price_total, regular_price_total));
240                if (price_total == 0) {
241                    section.find('.cuw-total-price-section').hide();
242                } else {
243                    section.find('.cuw-total-price-section').show();
244                }
245            } else {
246                if (section.find(".cuw-buy-section .cuw-actions").first().data('inactive') === 'disable') {
247                    section.find(".cuw-buy-section .cuw-actions").find(":input").prop('disabled', true);
248                } else {
249                    section.find(".cuw-buy-section .cuw-actions").hide();
250                }
251                section.find(".cuw-buy-section .cuw-prices").hide();
252                section.find(".cuw-buy-section .cuw-message").show();
253            }
254            if (total_savings > 0) {
255                section.find('.cuw-total-savings').not('[data-hidden="1"]').show();
256                section.find('.cuw-total-savings .cuw-saved-amount').html(cuw_helper.get_price_html(total_savings));
257            } else {
258                section.find('.cuw-total-savings').not('[data-hidden="1"]').hide();
259                section.find('.cuw-total-savings .cuw-saved-amount').html('');
260            }
261            if (data.cart_subtotal) {
262                section.find('.cuw-cart-subtotal').html(data.cart_subtotal);
263            }
264            this.update_add_to_cart_text(section, items, total_items);
265            this.update_cta_button(section);
266
267            jQuery(document.body).trigger('cuw_product_prices_updated', [{
268                regular_price_total: regular_price_total,
269                price_total: price_total,
270                items: items,
271                main_item: main_item,
272                main_price: main_price,
273                addon_items: addon_items,
274                addons_price: addons_price,
275                total_savings: total_savings,
276                available_items: total_items,
277                other_data: data,
278            }, section]);
279        },
280
281        update_cta_button: function (section) {
282            let disable = false;
283            this.get_chosen_products(section).forEach(function (product) {
284                if (product.hasClass('is_variable')) {
285                    if (product.find('.variant-select').val() === '' || product.find('.cuw-product-variation-id').val() === '') {
286                        disable = true;
287                        return false; // break
288                    }
289                }
290            });
291            section.find('.cuw-add-to-cart').not('[data-choose_variants="1"]').prop('disabled', disable);
292        },
293
294        // update inputs
295        update_inputs: function (product, show = true) {
296            let inputs = product.find(':input').not('input[type="checkbox"]');
297            let product_id = product.data('id');
298            if (show) {
299                inputs.prop("disabled", false);
300                product.css('opacity', '1');
301                if (product_id) {
302                    product.closest('.cuw-products').find('.cuw-product[data-id="' + product_id + '"]').css('opacity', '1');
303                }
304                product.find('.cuw-plus, .cuw-minus, .cuw-attributes-section').css('pointer-events', 'all');
305
306                product.find('.cuw-remove-item-from-cart, .cuw-added-text, .cuw-added-icon').hide();
307                product.find('.cuw-add-product-to-cart').show();
308            } else {
309                inputs.prop("disabled", true);
310                product.css('opacity', '0.8');
311                if (product_id) {
312                    product.closest('.cuw-products').find('.cuw-product[data-id="' + product_id + '"]').css('opacity', '0.8');
313                }
314                product.find('.cuw-plus, .cuw-minus, .cuw-attributes-section').css('pointer-events', 'none');
315
316                product.find('.cuw-add-product-to-cart').hide();
317                product.find('.cuw-remove-item-from-cart, .cuw-added-text, .cuw-added-icon').show();
318            }
319        },
320
321        // update add to cart text
322        update_add_to_cart_text: function (section, chosen_items_count, total_items_count) {
323            if (section.find(".cuw-buy-section").find(".cuw-add-to-cart").data('buy_now')) {
324                return;
325            }
326            let text = section.find(".cuw-buy-section").find(".cuw-add-to-cart").data('text');
327            if (text && !text.includes('{items_text}') && !text.includes('{items_count}')) {
328                text = text;
329            } else if (text && chosen_items_count > 1) {
330                let items_text = '';
331                let items_count = chosen_items_count + ' ' + cuw_i18n.add_to_cart.items;
332                if (cuw_i18n.add_to_cart.number_to_text[chosen_items_count]) {
333                    items_text = cuw_i18n.add_to_cart.number_to_text[chosen_items_count];
334                } else if (chosen_items_count === total_items_count) {
335                    items_text = cuw_i18n.add_to_cart.all_items;
336                } else {
337                    items_text = cuw_i18n.add_to_cart.selected_items;
338                }
339                text = text.replace('{items_text}', items_text).replace('{items_count}', items_count);
340            } else {
341                text = cuw_i18n.add_to_cart.text;
342            }
343            section.find(".cuw-add-to-cart").html(text);
344        },
345
346        // update badges
347        update_badges: function (product) {
348            if (product.find('.cuw-badge').data('hidden') == '1') return;
349
350            let save_text = product.find('.cuw-badge').data('save_text');
351            let regular_price = product.data('regular_price');
352            let price = product.data('price');
353
354            if (regular_price === '' || price === '' || !save_text) return;
355
356            if (regular_price === price) {
357                product.find('.cuw-badge').hide();
358            } else {
359                let amount = cuw_helper.format_price(regular_price - price);
360                let percentage = cuw_helper.format_percentage((regular_price - price) / regular_price * 100);
361                let text = save_text.replace('{price}', amount).replace('{percentage}', percentage);
362                product.find('.cuw-badge').html(text).show();
363            }
364        },
365
366        // update carousel actions
367        carousel_update_actions: function (section) {
368            let slider = section.find(".cuw-carousel-slider");
369            if (slider[0].scrollLeft === 0) {
370                section.find(".cuw-previous").css('opacity', 0.5);
371            } else if (Math.abs(slider[0].scrollLeft) + slider[0].clientWidth == slider[0].scrollWidth) {
372                section.find(".cuw-next").css('opacity', 0.5);
373            } else {
374                section.find(".cuw-previous, .cuw-next").css('opacity', 1);
375            }
376        },
377
378        // carousel scroll items
379        carousel_scroll_items: function (section, action) {
380            let slider = section.find(".cuw-carousel-slider");
381            let item_gap = parseInt(slider.data('gap')) || 18;
382            let item_width = parseInt(slider.find(':first-child').width());
383            if (action.hasClass('cuw-next')) {
384                slider.animate({
385                    scrollLeft: (cuw_is_rtl ? '-=' : '+=') + (item_width + item_gap),
386                    behaviour: 'smooth'
387                }, 10);
388            } else if (action.hasClass('cuw-previous')) {
389                slider.animate({
390                    scrollLeft: (cuw_is_rtl ? '+=' : '-=') + (item_width + item_gap),
391                    behaviour: 'smooth'
392                }, 10);
393            }
394        },
395
396        // to load event listeners
397        event_listeners: function () {
398            $(document).on("click", ".cuw-products .cuw-product-image", function () {
399                let checkbox = $(this).closest(".cuw-product").find(".cuw-product-checkbox").first();
400                checkbox.prop("checked", !checkbox.prop("checked")).trigger("change");
401            });
402
403            $(document).on('click', '.cuw-carousel .cuw-scroll-action', function () {
404                cuw_products.carousel_scroll_items($(this).closest(".cuw-carousel"), $(this));
405            });
406
407            $('.cuw-carousel .cuw-carousel-slider').on('scroll', function () {
408                cuw_products.carousel_update_actions($(this).closest(".cuw-carousel"));
409            });
410
411            $(".single_variation_wrap").on("show_variation", function (event, variation) {
412                $('.cuw-product-addons').each(function (index, section) {
413                    $(section).data('main_product_regular_price', variation.display_regular_price);
414                    $(section).data('main_product_price', variation.display_price);
415                    cuw_products.update_prices($(section));
416                });
417            });
418
419            $(document).on("change", ".cuw-products .cuw-product-checkbox", function () {
420                cuw_products.update_inputs($(this).closest(".cuw-product"), $(this).is(":checked"));
421                cuw_products.update_prices($(this).closest(".cuw-products"));
422            });
423
424            $(document).on("click", ".cuw-products .quantity-input .cuw-plus, .cuw-products .quantity-input .cuw-minus", function () {
425                cuw_offer.update_quantity($(this));
426            });
427
428            $(document).on("change", '.cuw-products .quantity-input .cuw-qty', function () {
429                cuw_products.update_prices($(this).closest(".cuw-products"));
430            });
431
432            $(document).on("input", '.cuw-products .quantity-input .cuw-qty', function () {
433                cuw_offer.check_quantity($(this));
434            });
435
436            $(document).on("change", ".cuw-products .variant-select", function () {
437                cuw_products.update_product_row($(this).closest(".cuw-products"), $(this).closest(".cuw-product-row"));
438                cuw_products.update_prices($(this).closest(".cuw-products"));
439                cuw_products.update_badges($(this).closest(".cuw-product-row"));
440            });
441
442            $(document).on("cuw_products_load_section", function (event, section) {
443                cuw_products.load_section(section);
444            });
445
446            $(document).on("click", '.cuw-cart-addon-products .cuw-toggle-ad
446dons', function () {
447                $(this).closest(".cuw-cart-addon-products").find(".cuw-products").slideToggle();
448                $(this).closest(".cuw-cart-addon-products").find(".cuw-addon-arrow-up").toggle();
449                $(this).closest(".cuw-cart-addon-products").find(".cuw-addon-arrow-down").toggle();
450            });
451
452            $(document).on("click", '.cuw-attributes-select .cuw-reset-attributes', function (event) {
453                event.preventDefault();
454                $(this).closest('.cuw-attributes-select').find('select').each(function (index, element) {
455                    $(element).html($(element).data('attribute_html'));
456                });
457
458                $(this).closest('.cuw-attributes-select').find('select').trigger('change');
459            });
460
461            $(document).on("change", '.cuw-attributes-select select', function () {
462                cuw_variations.update_attributes_fields($(this).closest('.cuw-attributes-select'));
463
464                var chosen_attributes = cuw_variations.get_chosen_attributes($(this).closest('.cuw-attributes-select'));
465                var chosen_attribute_data = cuw_variations.find_matching_variants(
466                    $(this).closest('.cuw-attributes-select').data('product_variations'),
467                    chosen_attributes.data
468                );
469
470                var section = $(this).closest('.cuw-attributes-section');
471                var variant_select = section.find('.variant-select');
472                if (chosen_attribute_data.length === 1 && chosen_attributes.count === chosen_attributes.chosenCount) {
473                    chosen_attribute_data = chosen_attribute_data.shift();
474                    variant_select.val(chosen_attribute_data.id).prop('selected', true);
475                    variant_select.data('chosen_attributes', chosen_attributes.data);
476                    variant_select.trigger('change');
477                    $(this).closest('.cuw-offer, .cuw-page').find('.cuw-button, .cuw-checkbox, .cuw-page-button, .cuw-ppu-accept-button')
478                        .prop('disabled', false)
479                        .css({'pointer-events': 'all', 'opacity': '1'});
480                    $(this).closest('#cuw-ppu-offer').find('.cuw-ppu-order-totals-table').css('display', 'table');
481                    $(this).closest('.cuw-product').find('.cuw-add-product-to-cart')
482                        .prop('disabled', false)
483                        .css({'pointer-events': 'all', 'opacity': '1'});
484                } else if (chosen_attribute_data.length === 0 && chosen_attributes.count === chosen_attributes.chosenCount) {
485                    // fail case, so we can ignore it
486                } else {
487                    variant_select.data('chosen_attributes', '[]');
488                    variant_select.val('').prop('selected', true);
489                    variant_select.trigger('change');
490                    $(this).closest('.cuw-offer, .cuw-page').find('.cuw-button, .cuw-checkbox, .cuw-page-button, .cuw-ppu-accept-button')
491                        .prop('disabled', true)
492                        .css({'pointer-events': 'none', 'opacity': '0.8'});
493                    $(this).closest('#cuw-ppu-offer').find('.cuw-ppu-order-totals-table').css('display', 'none');
494                    $(this).closest('.cuw-product').find('.cuw-add-product-to-cart')
495                        .prop('disabled', true)
496                        .css({'pointer-events': 'none', 'opacity': '0.8'});
497                }
498
499                section.find('.cuw-reset-attributes').css('display', chosen_attributes.chosenCount > 0 ? 'block' : 'none');
500            });
501        },
502    }
503
504    /* Variation */
505    window.cuw_variations = {
506
507        update_attributes_fields: function (variation_section) {
508            var product_variations = variation_section.data('product_variations');
509            var currently_chosen_attributes = cuw_variations.get_chosen_attributes(variation_section).data;
510
511            variation_section.find('select').each(function (index, element) {
512                var current_attribute_select = $(element),
513                    current_attribute_name = current_attribute_select.data('attribute_name'),
514                    attached_options_count = 0,
515                    new_attribute_select = $('<select/>'),
516                    option_gt_filter = ':gt(0)',
517                    selected_attribute_value = current_attribute_select.val() || '',
518                    selected_attribute_value_valid = true;
519
520                if (!current_attribute_select.data('attribute_html')) {
521                    var reference_select = current_attribute_select.clone();
522                    reference_select.find('option').removeAttr('attached').prop('disabled', false).prop('selected', false);
523                    current_attribute_select.data('attribute_options', reference_select.find('option' + option_gt_filter).get());
524                    current_attribute_select.data('attribute_html', reference_select.html());
525                }
526
527                new_attribute_select.html(current_attribute_select.data('attribute_html'));
528
529                var check_attributes = $.extend(true, {}, currently_chosen_attributes);
530                check_attributes[current_attribute_name] = '';
531                var variations_data = cuw_variations.find_matching_variants(product_variations, check_attributes);
532
533                for (var num in variations_data) {
534                    if (typeof (variations_data[num]) !== 'undefined') {
535                        var variation_attributes = variations_data[num].attributes;
536                        for (var attribute_name in variation_attributes) {
537                            if (variation_attributes.hasOwnProperty(attribute_name)) {
538                                var attribute_value = variation_attributes[attribute_name], variation_active = '';
539                                if (attribute_name === current_attribute_name) {
540                                    if (variations_data[num].is_active) {
541                                        variation_active = 'enabled';
542                                    }
543                                    if (attribute_value) {
544                                        attribute_value = $('<div/>').html(attribute_value).text();
545                                        var option_elements = new_attribute_select.find('option');
546                                        if (option_elements.length) {
547                                            for (var i = 0, length = option_elements.length; i < length; i++) {
548                                                var option_element = $(option_elements[i]),
549                                                    option_value = option_element.val();
550                                                if (attribute_value === option_value) {
551                                                    option_element.addClass('attached ' + variation_active);
552                                                    break;
553                                                }
554                                            }
555                                        }
556                                    } else {
557                                        new_attribute_select.find('option:gt(0)').addClass('attached ' + variation_active);
558                                    }
559                                }
560                            }
561                        }
562                    }
563                }
564
565                attached_options_count = new_attribute_select.find('option.attached').length;
566
567                if (selected_attribute_value) {
568                    selected_attribute_value_valid = false;
569                    if (0 !== attached_options_count) {
570                        new_attribute_select.find('option.attached.enabled').each(function () {
571                            var option_value = $(this).val();
572                            if (selected_attribute_value === option_value) {
573                                selected_attribute_value_valid = true;
574                                return false;
575                            }
576                        });
577                    }
578                }
579
580                if (attached_options_count > 0 && selected_attribute_value && selected_attribute_value_valid) {
581                    new_attribute_select.find('option:first').remove();
582                    option_gt_filter = '';
583                }
584
585                new_attribute_select.find('option' + option_gt_filter + ':not(.attached)').remove();
586
587                current_attribute_select.html(new_attribute_select.html());
588                current_attribute_select.find('option' + option_gt_filter + ':not(.enabled)').prop('disabled', true);
589
590                if (selected_attribute_value) {
591                    if (selected_attribute_value_valid) {
592                        current_attribute_select.val(selected_attribute_value);
593                    } else {
594                        current_attribute_select.val('').trigger('change');
595                    }
596                } else {
597                    current_attribute_select.val('');
598                }
599            });
600        },
601
602        find_matching_variants: function (variations_data, attributes) {
603            var matching = [];
604            for (var i = 0; i < variations_data.length; i++) {
605                var variation = variations_data[i];
606
607                if (cuw_variations.is_attributes_match(variation.attributes, attributes)) {
608                    matching.push(variation);
609                }
610            }
611            return matching;
612        },
613
614        is_attributes_match: function (variation_attributes, attributes) {
615            var match = true;
616            for (var attr_name in variation_attributes) {
617                if (variation_attributes.hasOwnProperty(attr_name)) {
618                    var value_1 = variation_attributes[attr_name];
619                    var value_2 = attributes[attr_name];
620                    if (value_1 !== undefined && value_2 !== undefined && value_1.length !== 0 && value_2.length !== 0 && value_1 !== value_2) {
621                        match = false;
622                    }
623                }
624            }
625            return match;
626        },
627
628        get_chosen_attributes: function (variation_section) {
629            var data = {}, count = 0, chosen = 0;
630            variation_section.find('select').each(function (index, element) {
631                var attribute_name = $(element).data('attribute_name');
632                var value = $(element).val() || '';
633                if (value.length > 0) {
634                    chosen++;
635                }
636                count++;
637                data[attribute_name] = value;
638            });
639            return {
640                'count': count,
641                'chosenCount': chosen,
642                'data': data,
643            };
644        },
645    }
646
647    /* Helper */
648    window.cuw_helper = {
649        // format price
650        format_price: function (price, tag = '') {
651            price = parseFloat(price).toFixed(cuw_data.woocommerce.price.decimals);
652            price = price.replace(".", cuw_data.woocommerce.price.decimal_separator);
653            let split = price.split(cuw_data.woocommerce.price.decimal_separator);
654            split[0] = split[0].replace(/\B(?=(\d{3})+(?!\d))/g, cuw_data.woocommerce.price.thousand_separator);
655            price = split.join(cuw_data.woocommerce.price.decimal_separator);
656            price = cuw_data.woocommerce.price.format.replace('%1$s', cuw_data.woocommerce.price.symbol).replace('%2$s', price);
657            return tag ? '<' + tag + '>' + price + '</' + tag + '>' : price;
658        },
659
660        // get price html
661        get_price_html: function (price, regular_price = null) {
662            if (regular_price && regular_price > price) {
663                return this.format_price(regular_price, 'del') + ' ' + this.format_price(price, 'ins');
664            }
665            return this.format_price(price, 'ins');
666        },
667
668        // get discount text
669        get_discount_text: function (discount_type, discount_value) {
670            let discount_text = '';
671            if (discount_type === 'percentage' && discount_value !== '') {
672                discount_text = cuw_helper.format_percentage(discount_value);
673            } else if (discount_type === 'fixed_price' && discount_value !== '') {
674                discount_text = cuw_helper.format_price(discount_value);
675            } else if (discount_type === 'free') {
676                discount_text = cuw_i18n.free;
677            }
678            return discount_text;
679        },
680
681        // to format discount percentage
682        format_percentage: function (price, round = true) {
683            if (price === '') return price;
684
685            if (round) {
686                price = Math.round(price * 100) / 100;
687                price = price.toFixed(2);
688                price = price.replace(/\.?0+$/, '');
689            }
690            return price += '%';
691        },
692    }
693
694    /* Spinner */
695    window.cuw_spinner = {
696        // show spinner
697        show: function (section) {
698            if (typeof section === 'string') {
699                section = $(section).first();
700            }
701            if (section.block) {
702                $(section).block({message: null, overlayCSS: {background: '#fff', opacity: 0.6}});
703            }
704        },
705
706        // hide spinner
707        hide: function (section) {
708            if (typeof section === 'string') {
709                section = $(section).first();
710            }
711            if (section.unblock) {
712                $(section).unblock();
713            }
714        }
715    }
716
717    /* Model */
718    window.cuw_modal = {
719        // show modal
720        show: function (modal, temp = false) {
721            if (typeof modal === 'string') {
722                modal = $(modal).first();
723            }
724            modal.show();
725            modal.find('.cuw-modal-close').click(function () {
726                temp ? modal.remove() : modal.hide()
727            });
728            $(window).click(function (event) {
729                if ($(event.target).hasClass('cuw-modal')) {
730                    temp ? modal.remove() : modal.hide()
731                }
732            });
733            $(document).keydown(function (event) {
734                if (event.keyCode === 27) {
735                    temp ? modal.remove() : modal.hide()
736                }
737            });
738        },
739
740        // hide modal
741        hide: function (modal) {
742            if (typeof modal === 'string') {
743                modal = $(modal).first();
744            }
745            modal.hide();
746        }
747    }
748
749    /* Init */
750    $(document).ready(function () {
751        cuw_offer.init();
752        cuw_products.init();
753    });
754
755});

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.