PageSourceSearch

https://szifon.com/wp-content/plugins/woo-product-filter/modules/w…/js/frontend.woofilters.js?ver=3.4.5

js szifon.com collected 2026-09-25 00:22:26 UTC 160,157 bytes, 4,384 lines download raw bytes

1/**
2 * Product Filter by WBW - Frontend Woofilters JS
3 *
4 * @version 3.3.0
5 *
6 * @author woobewoo
7 */
8
9/**
10 * Detect Thrive editor context.
11 *
12 * @version 3.1.8
13 * @since   3.1.8
14 */
15function wpfIsThriveEditor() {
16	var href = window.location.href;
17	return (
18		href.includes('tve=') ||
19		href.includes('tvet=') ||
20		href.includes('_preview') ||
21		href.includes('tcbf=') ||
22		href.includes('thrive')
23	);
24}
25
26/**
27 * Main function.
28 *
29 * @version 3.3.0
30 */
31(function ($, app) {
32	"use strict";
33
34	/**
35	 * wpfIsAjaxPaginationEnabled.
36	 *
37	 * @version 3.1.7
38	 */
39	function wpfIsAjaxPaginationEnabled() {
40		var wrapper = jQuery('.wpfMainWrapper').first();
41		if (!wrapper.length) return false;
42
43		var raw = wrapper.attr('data-filter-settings');
44		try {
45			var settings = JSON.parse(raw);
46		} catch (e) {
47			return false;
48		}
49
50		return !!(settings.settings &&
51			(parseInt(settings.settings.ajax_pagination, 10) === 1 ||
52			parseInt(settings.settings.slug_format, 10) === 1));
53	}
54
55	/**
56	 * WpfFrontendPage.
57	 *
58	 * @version 3.3.0
59	 */
60	function WpfFrontendPage() {
61		this.$obj = this;
62		this.noWoo = this.$obj.checkNoWooPage();
63		var slugFormatEnable;
64		if ( ! window.wpfAdminPage ) {
65			var $fgeneralSettings = this.getFilterMainSettings( jQuery( '.wpfMainWrapper' ) );
66			if ( ! $fgeneralSettings ) {
67				return false;
68			}
69			if ( typeof $fgeneralSettings.settings.slug_format !== 'undefined' ) {
70				slugFormatEnable = $fgeneralSettings.settings.slug_format;
71			} else {
72				// Set default value if not found
73				slugFormatEnable = '';  // Set your default value here
74			}
75		}
76		this.slugFormat = slugFormatEnable;
77		this.readyFuncs = ['.berocket_load_more_preload', 'woocommerce-product-bundle-hide', 'show_variation', 'woo_variation_swatches_pro_init', '.variations_form', 'yith_infs_start', 'flatsome_infinite_scroll','.dipl_woo_products_pagination_wrapper', 'divi_filter_loadmore_ajax_handler'];
78		this.isSafari = navigator.vendor && navigator.vendor.indexOf('Apple') > -1 && ((navigator.userAgent && navigator.userAgent.indexOf('CriOS') == -1 && navigator.userAgent.indexOf('FxiOS') == -1) || (navigator.platform && /iPhone|iPad|iPod/.test(navigator.platform)));
79		this.disableScrollJs = true;
80		this.lastFids = [];
81		return this.$obj;
82	}
83
84	/**
85	 * WpfFrontendPage.prototype.init.
86	 *
87	 * @version 3.1.8
88	 */
89	WpfFrontendPage.prototype.init = (function () {
90		var _thisObj = this.$obj;
91		app.wpfNewUrl = '';
92		window.wpfDoNotLoadMore = false;
93		_thisObj.filterClick = true;
94		_thisObj.filteringId = 0;
95
96		_thisObj.setCurrentLocation();
97		_thisObj.filterLoadTypes = [];
98		_thisObj.defaultProductSelector = 'ul.products';
99		_thisObj.isAdminPreview = jQuery('#wpfFiltersEditForm').length > 0 || (typeof isElementorPreview != 'undefined' && isElementorPreview == 1) || wpfIsThriveEditor();
100		_thisObj.moveFloatingElements();
101		_thisObj.checkForceFilters();
102		_thisObj.eventsPriceFilter();
103		_thisObj.disableLeerOptions();
104		_thisObj.eventsFrontend();
105		_thisObj.changeSlugByUrl();
106		_thisObj.chageRangeFieldWidth();
107		_thisObj.addSpecificPluginActions();
108		_thisObj.resizeWindow();
109		_thisObj.changeOrderBy();
110		_thisObj.copySelectsForSafari();
111
112		jQuery('.wpfMainWrapper').each(function() {
113			_thisObj.markCheckboxSelected(jQuery(this), true);
114		});
115
116		setTimeout(function () {
117			jQuery('.wpfFilterContent.wpfHide, .wpfFilterContent.wpfBlockAnimated').each(function () {
118				jQuery(this).find('input, select, a, button, [tabindex]').attr('tabindex', '-1');
119			});
120		}, 600);
121
122		if (_thisObj.isAdminPreview) {
123			_thisObj.hideFiltersLoader();
124		} else {
125			setTimeout(function () {
126				_thisObj.hideFiltersLoader();
127			}, 100);
128		}
129		var slugFormat=_thisObj.slugFormat;
130		if(slugFormat !== "" && slugFormat !== 0 && slugFormat && slugFormat !== "0") {
131			if($('.wpfFilterButton').length >0 && !window.wpfAdminPage){
132				applyFilter(_thisObj,$('.wpfFilterButton'));
133			}
134		}
135	});
136
137	WpfFrontendPage.prototype.moveFloatingElements = (function () {
138		var _thisObj = this.$obj;
139		if (!_thisObj.isAdminPreview && jQuery('.wpfFloatingBlock').length == 0 && jQuery('.wpfFloatingWrapper').length == 1) {
140			jQuery('body').append('<div class="wpfFloatingBlock"></div>');
141			if (jQuery('.wpfFloatingSwitcher').length == 1) {
142				var button = $('.wpfFloatingSwitcher');
143				if (button.hasClass('wpfSwitcherRealFloat')) {
144					button.detach();
145					$('.wpfFloatingBlock').append(button);
146				}
147			}
148			if (jQuery('.wpfFloatingOverlay').length == 1) {
149				var overlay = $('.wpfFloatingOverlay').detach();
150				$('.wpfFloatingBlock').append(overlay);
151			}
152			if ($('.wpfFloatingWrapper').closest('.wpfFilterForWtbp').length) $('.wpfFloatingBlock').addClass('wpfFilterForWtbpFloating');
153			var block = $('.wpfFloatingWrapper').detach();
154			$('.wpfFloatingBlock').append(block);
155
156		}
157	});
158
159	WpfFrontendPage.prototype.changeOrderBy = (function () {
160		jQuery('.woocommerce-ordering select').on('change', function (e) {
161			e.preventDefault();
162			var orderBy = jQuery(this).val(),
163				curUrl = window.location.href;
164
165			if ((curUrl.indexOf('?') === -1)) {
166				curUrl += '?orderby=' + orderBy;
167				jQuery('.wpfMainWrapper').each(function () {
168					var filter = $(this).data('filter-settings');
169					if (typeof filter.settings.filters.defaults !== 'undefined') {
170						curUrl += '&' + filter.settings.filters.defaults.replace(';', '&').replace('|', '%7C');
171					}
172				});
173			} else {
174				if (curUrl.indexOf('orderby') === -1) {
175					curUrl += ((curUrl.indexOf('?') === -1) ? '?' : '&') + 'orderby=' + orderBy;
176				} else {
177					curUrl = curUrl.replace(/(orderby=)[^&]*/, '$1' + orderBy);
178				}
179			}
180			jQuery(location).attr('href', curUrl);
181			return false;
182		});
183	});
184
185	WpfFrontendPage.prototype.resizeWindow = (function() {
186		var _thisObj = this.$obj;
187		_thisObj.filterOptionsForDevices();
188		jQuery( window ).on('resize', function() {
189			_thisObj.filterOptionsForDevices();
190		});
191	});
192
193	WpfFrontendPage.prototype.copySelectsForSafari = (function() {
194		var _thisObj = this.$obj;
195		if (!_thisObj.isSafari) return;
196
197		jQuery('.wpfMainWrapper').each(function () {
198			var $wrapper = jQuery(this),
199				$selectsWrapper = $wrapper.find('.wpfSelectCopies');
200			if ($selectsWrapper.length == 0) {
201				jQuery('<div/>').addClass('wpfSelectCopies').appendTo($wrapper);
202				$selectsWrapper = $wrapper.find('.wpfSelectCopies');
203			}
204			if ($selectsWrapper.length == 0) return;
205
206			$wrapper.find('.wpfFilterWrapper[data-display-type="dropdown"] select').each(function() {
207				var $select = jQuery(this),
208					$filter = $select.closest('.wpfFilterWrapper'),
209					blockId = $filter.attr('id');
210				if ($selectsWrapper.find('select[data-block="' + blockId + '"]').length == 0) {
211					$select.clone().attr('data-block', blockId).appendTo($selectsWrapper);
212				}
213			});
214			_thisObj.removeHiddenOptionsForSafari($wrapper);
215		});
216	});
217
218	WpfFrontendPage.prototype.restoreSelectsForSafari = (function() {
219		var _thisObj = this.$obj;
220		if (!_thisObj.isSafari) return;
221
222		jQuery('.wpfMainWrapper').each(function () {
223			var $wrapper = jQuery(this),
224			$selectsWrapper = $wrapper.find('.wpfSelectCopies');
225			if ($selectsWrapper.length == 1) {
226
227				$selectsWrapper.find('select').each(function() {
228					var $select = jQuery(this),
229						blockId = $select.attr('data-block'),
230						$filterSelect = $wrapper.find('#' + blockId + ' select');
231					if ($filterSelect.length == 1) {
232						var value = $filterSelect.val();
233						$filterSelect.html($select.html());
234						$filterSelect.val(value);
235					}
236				});
237			}
238		});
239	});
240
241	/**
242	 * removeHiddenOptionsForSafari.
243	 *
244	 * @version 2.8.6
245	 */
246	WpfFrontendPage.prototype.removeHiddenOptionsForSafari = (function() {
247		var _thisObj = this.$obj;
248		if (!_thisObj.isSafari) return;
249
250		var $found = jQuery('.wpfFilterWrapper[data-display-type="dropdown"] select:visible option[style*="none"]');
251		if ($found.length) $found.remove();
252		else {
253			jQuery('.wpfFilterWrapper[data-display-type="dropdown"] select:visible option').each(function() {
254				if (jQuery(this).css('display') == 'none') jQuery(this).remove();
255			});
256		}
257	});
258
259	WpfFrontendPage.prototype.checkForceFilters = (function() {
260		var forceShowFilter = jQuery('.wpfMainWrapper[data-force="1"]');
261		if (!forceShowFilter.length) return;
262
263		jQuery('.wpfMainWrapper').each(function () {
264			var wrapper = jQuery(this),
265				forceShowCurrent = wrapper.attr('data-force');
266			if (!forceShowCurrent){
267				wrapper.remove();
268				if (wrapper.closest('.WpfWoofiltersWidget').length) {
269					wrapper.closest('.WpfWoofiltersWidget').remove();
270				}
271			}
272		});
273	});
274
275	WpfFrontendPage.prototype.showFiltersLoader = (function() {
276		jQuery('.wpfMainWrapper').each(function () {
277			var wrapper = jQuery(this);
278			wrapper.css('position','relative');
279			if (!wrapper.find('.wpfLoaderLayout').length){
280				jQuery('<div/>').addClass('wpfLoaderLayout').appendTo(wrapper);
281				wrapper.find('.wpfLoaderLayout').append('<i class="fa fa-spinner fa-pulse fa-3x fa-fw"/>');
282			}
283
284			wrapper.find('.wpfLoaderLayout').show();
285		});
286	});
287
288	WpfFrontendPage.prototype.hideFiltersLoader = (function() {
289		jQuery('.wpfMainWrapper').each(function () {
290			var wrapper = jQuery(this);
291
292			hideFilterLoader(wrapper);
293		});
294	});
295
296	WpfFrontendPage.prototype.chageRangeFieldWidth = (function () {
297		var _thisObj = this.$obj;
298		jQuery('.wpfFilterWrapper[data-filter-type="wpfPrice"]').each(function () {
299			var filter = jQuery(this),
300				input1 = filter.find('#wpfMinPrice'),
301				input2 = filter.find('#wpfMaxPrice'),
302				fontSize1 = input1.css('font-size'),
303				fontSize2 = input2.css('font-size'),
304				visbleBuffer1 = filter.find('.wpfVisibleBufferMin'),
305				visbleBuffer2 = filter.find('.wpfVisibleBufferMax');
306			if(fontSize1) visbleBuffer1.css('font-size', fontSize1);
307			if(fontSize2) visbleBuffer2.css('font-size', fontSize2);
308
309			jQuery(visbleBuffer1).text(input1.val());
310			jQuery(visbleBuffer2).text(input2.val());
311
312			if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
313				jQuery(input1).width(visbleBuffer1.width()+20);
314				jQuery(input2).width(visbleBuffer2.width()+20);
315			} else {
316				jQuery(input1).width(visbleBuffer1.width()+10);
317				jQuery(input2).width(visbleBuffer2.width()+10);
318			}
319		});
320	});
321
322	WpfFrontendPage.prototype.eventsPriceFilter = (function () {
323		var _thisObj = this.$obj;
324
325		jQuery('.wpfFilterWrapper[data-filter-type="wpfPrice"]').each(function () {
326			_thisObj.initDefaultSlider(jQuery(this));
327		});
328
329		//change price filters
330		jQuery('.wpfFilterWrapper[data-filter-type="wpfPrice"]').on('wpfPriceChange', function(event){
331			var filter = jQuery(this),
332				mainWrapper = filter.closest('.wpfMainWrapper');
333
334			mainWrapper.find('.wpfFilterWrapper[data-filter-type="wpfPriceRange"] input').prop('checked', false);
335			mainWrapper.find('.wpfFilterWrapper[data-filter-type="wpfPriceRange"] select')
336				.val(mainWrapper.find('.wpfFilterWrapper[data-filter-type="wpfPriceRange"] select option:first').val());
337
338			filter.removeClass('wpfNotActive');
339			mainWrapper.find('.wpfFilterWrapper[data-filter-type="wpfPriceRange"]').addClass('wpfNotActive');
340		});
341
342		//change price range
343		jQuery('.wpfFilterWrapper[data-filter-type="wpfPriceRange"] input, .wpfFilterWrapper[data-filter-type="wpfPriceRange"] select').on('change', function(e){
344			e.preventDefault();
345
346			jQuery('.wpfFilterWrapper[data-filter-type="wpfPrice"]').addClass('wpfNotActive');
347		});
348
349	});
350
351	WpfFrontendPage.prototype.initDefaultSlider = (function (filter, type) {
352		var _thisObj = this.$obj,
353			wrapper = filter.closest('.wpfMainWrapper'),
354			filterType = typeof type !== 'undefined' ? type : 'price',
355			getAttr = filter.data('get-attribute'),
356			minInputId = '#wpfMinPrice',
357			maxInputId = '#wpfMaxPrice',
358			triggerName = 'wpfPriceChange';
359
360		if (filterType === 'attr') {
361			minInputId = '#wpfMinAttrNum';
362			maxInputId = '#wpfMaxAttrNum';
363			triggerName = 'wpfAttrSliderChange';
364		}
365
366		var minSelector = wrapper.find(minInputId),
367			maxSelector = wrapper.find(maxInputId),
368			wpfDataStep = wrapper.find('#wpfDataStep').val()
369		if (wpfDataStep == '0.001') {
370			wpfDataStep = '0.00000001';
371		}
372		wpfDataStep = Number(wpfDataStep);
373
374		var valMin = parseFloat(minSelector.attr('min')),
375			valMax = parseFloat(maxSelector.attr('max')),
376			curUrl = window.location.href,
377			urlParams = _thisObj.findGetParameter(curUrl),
378			rate = filter.data('rate');
379
380		urlParams = _thisObj.getConvertedPrices(urlParams, rate);
381
382		var	minPriceGetParams = urlParams.wpf_min_price ? parseFloat(urlParams.wpf_min_price) : valMin,
383			maxPriceGetParams = urlParams.wpf_max_price ? parseFloat(urlParams.wpf_max_price) : valMax;
384
385		if (filterType === 'attr') {
386			if (urlParams[getAttr]) {
387				var idsAnd = urlParams[getAttr].split(','),
388					idsOr = urlParams[getAttr].split('|'),
389					isAnd = idsAnd.length > idsOr.length;
390				var filterTypeValues = isAnd ? idsAnd : idsOr;
391			}
392			minPriceGetParams = urlParams[getAttr] ? parseFloat(filterTypeValues[0]) : valMin;
393			maxPriceGetParams = urlParams[getAttr] ? parseFloat(filterTypeValues.pop()) : valMax;
394		}
395
396		var sliderWrapper = filter.find("#wpfSliderRange"),
397			autoFilteringEnable = (wrapper.find('.wpfFilterButton').length == 0),
398			skin = filter.attr('data-price-skin');
399		if(skin === 'default'){
400			sliderWrapper.slider({
401				range: true,
402				orientation: "horizontal",
403				min: valMin,
404				max: valMax,
405				step: wpfDataStep,
406				values: [minPriceGetParams, maxPriceGetParams],
407				slide: function (event, ui) {
408					minSelector.val(ui.values[0]);
409					maxSelector.val(ui.values[1]);
410					filter.trigger(triggerName);
411				},
412				start: function () {
413					filter.trigger(triggerName);
414				},
415				stop: function () {
416					if(autoFilteringEnable){
417						_thisObj.setCurrentLocation();
418						_thisObj.filtering(wrapper);
419					}
420				},
421			});
422			minSelector.val(sliderWrapper.slider("values", 0));
423			maxSelector.val(sliderWrapper.slider("values", 1));
424		}
425	});
426
427	// add/remove get query param
428	WpfFrontendPage.prototype.QStringWork = (function ($attr, $value, $noWooPage, $filterWrapper, $type) {
429
430		$noWooPage = false;
431		if (window.wpfAdminPage) {
432			$noWooPage = true;
433		}
434		if($type === 'change'){
435			var curUrl = changeUrl($attr, $value, $noWooPage, $filterWrapper );
436			$filterWrapper.attr('data-hide-url', decodeURI(curUrl));
437		}else if($type === 'remove'){
438			var curUrl = removeQString($attr, $noWooPage, $filterWrapper);
439			$filterWrapper.attr('data-hide-url', decodeURI(curUrl));
440		}
441	});
442
443	// slug generation
444	// New: Convert original param string to slug segments (use slugs for values)
445	WpfFrontendPage.prototype.convertParamsToSegments = function(paramString) {
446		var segments = [];
447		var exclude = ['wpf_count', 'wpf_fbv'];
448
449		if (!paramString) return segments;
450
451		// helper to safely use values in CSS attribute selectors
452		function escAttr(v) {
453			v = String(v);
454			if (window.CSS && CSS.escape) return CSS.escape(v);
455			// fallback escape (good enough for attr selectors)
456			return v.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
457		}
458
459		paramString = paramString.replace(/^[?&]/, '');
460		var pairs = paramString.split('&');
461
462		pairs.forEach(function(pair) {
463			var parts = pair.split('=');
464			var key = parts[0];
465			var val = parts.slice(1).join('='); // keep '=' inside values safe
466
467			if (!key || !val || exclude.indexOf(key) !== -1) return;
468
469			var decodedKey = decodeURIComponent(key);
470			var delim = getDelimiterForFilter(decodedKey);
471			var pathDelim = ('|' === delim) ? '~' : delim;
472			// decode full value first (important!)
473			var decodedVal = decodeURIComponent(val.replace(/\+/g, ' '));
474
475			var slugs = decodedVal.split(delim)
476				.map(s => s.trim())
477				.filter(Boolean)
478				.map(function(idRaw) {
479					var id = idRaw; // already decoded
480					var $wrap = jQuery('.wpfFilterWrapper[data-get-attribute="' + escAttr(decodedKey) + '"]');
481
482					// Try LI mapping (checkbox/radio)
483					var $li = $wrap.find('li[data-term-id="' + escAttr(id) + '"]');
484					if ($li.length) return ($li.attr('data-term-slug') || id);
485
486					// Fallback: try option mapping (dropdown)
487					var $opt = $wrap.find('option[value="' + escAttr(id) + '"]');
488					if ($opt.length) return ($opt.attr('data-term-slug') || $opt.data('term-slug') || id);
489
490					return id;
491				});
492
493			if (slugs.length) {
494				segments.push(decodedKey);
495				segments.push(slugs.join(pathDelim));
496			}
497		});
498
499		return segments;
500	};
501
502	// New: Convert slug segments back to param string (slugs → IDs)
503	function getDelimiterForFilter(key) {
504		var $filter = jQuery('.wpfFilterWrapper[data-get-attribute="' + key + '"]');
505		if (!$filter.length) return ','; // safe fallback
506
507		var logic = $filter.attr('data-query-logic') || 'or'; // default most filters to OR
508		return (logic === 'and') ? ',' : '|';
509	}
510
511	WpfFrontendPage.prototype.eventChangeFilter = (function (e) {
512		var _thisObj = this.$obj,
513			_this = jQuery(e.target),
514			mainWrapper = _this.closest('.wpfMainWrapper'),
515			settings = _thisObj.getFilterMainSettings(mainWrapper);
516		_thisObj.setCurrentLocation();
517
518		_this.closest('.wpfFilterWrapper').removeClass('wpfNotActive');
519		if(typeof(_thisObj.eventChangeFilterPro) == 'function') {
520			_thisObj.eventChangeFilterPro(_this, settings);
521		}
522
523		var redirectOnlyClick = Number(settings.settings.redirect_only_click),
524			autoUpdateFilter  = Number(settings.settings.auto_update_filter),
525			loaderEnable  = Number(settings.settings.filter_loader_icon_onload_enable),
526			isButton = ( mainWrapper.find('.wpfFilterButton').length > 0 ),
527			isCheckbox = _this.attr('type') == 'checkbox',
528			redirectLink = isCheckbox ? _this.closest('li' ).attr('data-link') : _this.find('option:selected').attr('data-link');
529
530		if (typeof redirectLink !== 'undefined' && isCheckbox) {
531			var filter = _this.closest('.wpfFilterWrapper');
532			if (filter.attr('data-display-type') != 'list' && _this.is(':checked')){
533				filter.find('input').prop('checked', false);
534				_this.prop('checked', true);
535			}
536		}
537
538		if (isButton) {
539			// if there is a button and autoUpdateFilter is selected, then we only change the filter.
540			// If redirectOnlyClick is selected, then we change the filter and products, but do not redirect until the button is clicked
541
542			if (autoUpdateFilter || redirectOnlyClick) {
543				if (loaderEnable) {
544					mainWrapper.find('.wpfLoaderLayout').show();
545				}
546				_thisObj.filterClick = false;
547				_thisObj.filtering(mainWrapper, false, redirectLink);
548			}
549
550		} else {
551			_thisObj.filterClick = true;
552			_thisObj.filtering(mainWrapper, false, redirectLink);
553		}
554	});
555
556	/**
557	 * WpfFrontendPage.prototype.eventsFrontend.
558	 *
559	 * @version 3.1.8
560	 */
561	WpfFrontendPage.prototype.eventsFrontend = (function () {
562		var _thisObj = this.$obj,
563			searchParams = jQuery.toQueryParams(window.location.search);
564
565		//for Impreza LoadMore Pagination
566		if (searchParams['all_products_filtering'] && searchParams['all_products_filtering'] == '1') {
567			jQuery( document ).ajaxSend(function( event, jqxhr, settings ) {
568				if (settings.data) {
569					var response = _thisObj.unserializeStr(settings.data);
570					if (response['action'] && response['action'] == 'us_ajax_grid') {
571						if (response['template_vars'] && response['template_vars'].length) {
572							try {
573								var query = JSON.parse(response['template_vars']);
574							}catch(e){
575								var query = false;
576							}
577							if (query && query['query_args']) {
578								var args = query['query_args'];
579								if (args['product_cat']) delete args.product_cat;
580								if (args['product_tag']) delete args.product_tag;
581								response['template_vars'] = JSON.stringify(query);
582								var result = [];
583								jQuery.each(response, function(key, val) {
584									result.push(encodeURIComponent(key) + "=" + encodeURIComponent(val));
585								});
586								settings.data = result.join("&").replace(/%20/g, "+");
587							}
588						}
589					}
590				}
591			});
592		}
593		//for Divi Filter LoadMore / eael-pagination / premium-woo-products
594		if (jQuery('.divi-filter-archive-loop, .eael-woo-pagination, .premium-woo-products-pagination, .uael-woocommerce-pagination').length) {
595			var actions = ['divi_filter_loadmore_ajax_handler', 'woo_product_pagination_product', 'get_woo_products', 'uael_get_products'];
596			jQuery( document ).ajaxSend(function( event, jqxhr, settings ) {
597				if (settings.data) {
598					var response = _thisObj.unserializeStr(settings.data);
599					if (response['action'] && actions.indexOf(response['action']) != -1) {
600						var s = window.location.search;
601						if (s && s.length > 1) {
602							response['with_wpf_filter'] = s.replace('?','');
603							var result = [];
604							jQuery.each(response, function(key, val) {
605								result.push(encodeURIComponent(key) + "=" + encodeURIComponent(val));
606							});
607							settings.data = result.join("&").replace(/%20/g, "+");
608						}
609					}
610				}
611			});
612		}
613		//for woocommerce-blocks (All products and others)
614		if ((typeof window.wpfFetchHookCreated == 'undefined' || window.wpfFetchHookCreated != 1) && !wpfIsThriveEditor()) {
615			window.fetch = new Proxy(window.fetch, {
616				apply(fetch, that, args) {
617					var url = args.length ? args[0] : '';
618					if (typeof url === 'string' && url.length) {
619						if (url.indexOf('wp-json/wc/store/') != -1 && url.indexOf('/products?') != -1 && url.indexOf('per_page=') != -1) {
620							var s = window.location.search;
621							if (s.length) args[0] += s.replace('?','&');
622							else {
623								var urlPreselects = '';
624								jQuery('.wpfMainWrapper').each(function() {
625									var settings = _thisObj.getFilterMainSettings(jQuery(this)),
626										preselects = typeof settings.settings.filters.preselect !== 'undefined' ? settings.settings.filters.preselect : '';
627									if (preselects.length) {
628										urlPreselects += '&'+preselects.replace(/;/g,'&');
629										if (settings.settings.filtering_by_variations=='1') urlPreselects += '&wpf_fbv=1';
630										if (settings.settings.exclude_backorder_variations=='1') urlPreselects += '&wpf_ebv=1';
631										if (settings.settings.display_product_variations=='1') urlPreselects += '&wpf_dpv=1';
632									}
633								});
634								if (urlPreselects.length) {
635									args[0] += urlPreselects + '&wpf_preselects=1';
636
637								}
638							}
639						} else {
640							//Elementor Loop Load More
641							if ((jQuery('.e-load-more-anchor').length == 1) && jQuery('.e-load-more-spinner').length && url.indexOf('?') == -1) {
642								var $elementorLoadMoreAnchor = jQuery('.e-load-more-anchor'),
643									s = window.location.search;
644								if (s.length) {
645									var nextPage = $elementorLoadMoreAnchor.attr('data-next-page');
646									if (nextPage == url) args[0]+= s;
647								}
648
649							}
650						}
651					}
652					const result = fetch.apply(that, args);
653					return result;
654				}
655			});
656			window.wpfFetchHookCreated = 1;
657		}
658
659		//for themes with ajax-paginations, ajax-ordering
660		jQuery(document).ajaxComplete(function(event, xhr, options) {
661			setTimeout(function() {
662				if (wpfIsThriveEditor()) {
663					return;
664				}
665				if (jQuery('.wpfLoaderLayout:visible').length) {
666					window.wpfFrontendPage.init();
667					if (typeof(window.wpfFrontendPage.eventsFrontendPro) == 'function') {
668						window.wpfFrontendPage.eventsFrontendPro();
669					}
670				}
671			}, 500);
672		});
673
674		jQuery('.wpfMainWrapper').find('select[multiple]').each(function(){
675			var select = jQuery(this),
676				selectAll = select.attr('data-placeholder'),
677				search = JSON.parse(select.attr('data-search')),
678				singleSelect = select.data('single-select'),
679				showCheckbox = (typeof select.data('hide-checkboxes') === 'undefined');
680
681			setTimeout(function () {
682				select.multiselect({
683					search: search.show,
684					columns: 1,
685					placeholder: selectAll ? selectAll : 'Select options',
686					optionAttributes: ['style', 'data-term-id'],
687					searchOptions: {'default': search.placeholder},
688					showCheckbox: showCheckbox,
689					onOptionClick: function (element, option) {
690						if (typeof singleSelect !== 'undefined') {
691							var value = jQuery(option).val();
692							jQuery(option).closest('ul').find('input[type="checkbox"][value!=' + value + ']').prop('checked', false);
693							jQuery(element).val(value);
694							jQuery(element).siblings('.ms-options-wrap').find('.ms-options:visible').hide();
695						}
696					},
697				});
698			}, 100);
699
700			if (search.show) {
701				jQuery('.ms-options-wrap').on('click', 'button', function () {
702					$(this).next('.ms-options').find('.ms-search input').focus();
703				});
704			}
705
706		});
707
708		if(jQuery('.wpfFilterWrapper[data-filter-type="wpfSortBy"]').length == 0) {
709			jQuery('.woocommerce-ordering').css('display', 'block');
710		}
711
712		jQuery('.wpfFilterWrapper[data-hide-single="1"]').each(function(){
713			var filter = jQuery(this),
714				selector = filter.find('.wpfColorsFilter').length ? 'li[data-term-slug]' : '[data-term-id]',
715				visible = 0;
716			if (filter.attr('data-display-type') == 'slider') {
717				var idsDef = filter.attr('data-ids-without-filtering').replaceAll(', ',',').split(',');
718				if (idsDef.length <= 1) filter.hide();
719			} else {
720				filter.find(selector).each(function(){
721					if (jQuery(this).css('display') != 'none') visible++;
722				});
723				if (visible <= 1) {
724					filter.hide();
725				}
726			}
727		});
728
729		//if no enabled filters hide all html
730		if(jQuery('.wpfFilterWrapper').length < 1){
731			jQuery('.wpfMainWrapper').addClass('wpfHidden');
732		}
733
734		//Start filtering
735		jQuery('body').on('mousedown', '.wpfFilterButton, .js-wpfFilterButtonSearch', function (e) {
736			e.preventDefault();
737			var $this = jQuery(this),
738				mainWrapper = $this.closest('.wpfMainWrapper'),
739				inputSearch = mainWrapper.find('.js-passiveFilterSearch');
740			if (inputSearch.length) {
741				inputSearch.each(function() {
742					var $sElem = jQuery(this);
743					if ($sElem.val() !== '') {
744						$sElem.closest('.wpfFilterWrapper').removeClass('wpfNotActive');
745					}
746					$sElem.trigger('blur');
747				});
748
749			}
750			applyFilter(_thisObj, $this);
751		});
752
753		jQuery('input.js-passiveFilterSearch').on('keydown', function (e) {
754			var char_code = e.which;
755			if (parseInt(char_code) == 13) {
756				e.preventDefault();
757				var $this = jQuery(this);
758				$this.closest('.wpfFilterWrapper').removeClass('wpfNotActive');
759				$this.trigger('blur');
760				applyFilter(_thisObj, $this);
761			}
762		});
763
764		//Clear filters
765		jQuery('body').on('click', '.wpfClearButton', function (e) {
766			e.preventDefault();
767			var $filterWrapper = jQuery(this).closest('.wpfMainWrapper'),
768				settings = _thisObj.getFilterMainSettings($filterWrapper),
769				resetAllFilters = typeof settings.settings.reset_all_filters !== 'undefined' ? settings.settings.reset_all_filters : 0;
770			_thisObj.setCurrentLocation();
771
772			if (resetAllFilters !== '0') {
773				jQuery('.wpfMainWrapper').each(function(){
774					_thisObj.clearFilters(jQuery(this).find('.wpfFilterWrapper'), true);
775				});
776			} else {
777				_thisObj.clearFilters($filterWrapper.find('.wpfFilterWrapper'), true);
778			}
779			if (Number(settings.settings.redirect_after_select) || Number(settings.settings.redirect_only_click)) {
780				_thisObj.filterClick = false;
781			}
782			_thisObj.filtering($filterWrapper, true);
783
784			if (typeof (_thisObj.initOneByOne) == 'function') {
785				_thisObj.initOneByOne($filterWrapper);
786			}
787
788		});
789
790		//price range choose only one checkbox
791		jQuery('.wpfFilterWrapper[data-filter-type="wpfPriceRange"] .wpfFilterContent input').on('change', function (e) {
792			e.preventDefault();
793			var input = jQuery(this),
794				inputs = input.closest('.wpfFilterWrapper').find('input');
795			if(input.is(":checked")){
796				inputs.prop('checked', false);
797				input.prop('checked', true);
798			}
799		});
800
801		//category/brand list choose only one checkbox
802		jQuery('.wpfFilterWrapper[data-filter-type="wpfCategory"], .wpfFilterWrapper[data-filter-type="wpfPerfectBrand"], .wpfFilterWrapper[data-filter-type="wpfAttribute"]').each(function() {
803			var categoryFilter = jQuery(this),
804				displayType = categoryFilter.data('display-type'),
805				categoryMulti = displayType == 'multi';
806			if (categoryFilter.data('filter-type') == 'wpfAttribute') {
807				if (displayType == 'list' || displayType == 'switch') categoryMulti = true;
808			}
809
810			categoryFilter.find('.wpfFilterContent input').on('change', function (e) {
811				e.preventDefault();
812				var input = jQuery(this);
813				if(categoryMulti) {
814					var mainWrapper = input.closest('.wpfMainWrapper'),
815						filterWrapper = input.closest('.wpfFilterWrapper'),
816						expandSelectedToChild = _thisObj.getFilterParam('f_multi_extend_parent_select', mainWrapper, filterWrapper);
817
818					if(expandSelectedToChild && input.is(':checked')) {
819						input.closest('li').find('ul input').prop('checked', true);
820					}
821
822					if (expandSelectedToChild && ! input.is(':checked') ) {
823						input.closest('li').find('ul input').prop('checked', false);
824					}
825				}
826			});
827		});
828
829		//rating choose only one checkbox
830		jQuery('.wpfFilterWrapper[data-filter-type="wpfRating"] .wpfFilterContent input').on('change', function (e) {
831			e.preventDefault();
832			var input = jQuery(this),
833				inputs = input.closest('.wpfFilterWrapper').find('input');
834			if(input.is(":checked")){
835				inputs.prop('checked', false);
836				input.prop('checked', true);
837			}
838		});
839
840		//after change input or dropdown make this filter active
841		//check if ajax mode enable and filtering on filter elements change
842		jQuery('body').off('change', '.wpfFilterWrapper select, .wpfFilterWrapper input:not(.passiveFilter)').on('change', '.wpfFilterWrapper select, .wpfFilterWrapper input:not(.passiveFilter)', function (e) {
843			e.preventDefault();
844			var isExeptionCase = _thisObj.checkExeptionCasesBeforeFiltering(this);
845			// exception checkbox in multidropdown
846			if (!isExeptionCase) {
847				var $this = jQuery(this);
848				if ($this.is('input') && $this.closest('.wpfFilterWrapper').data('display-type') == 'mul_dropdown') {
849					isExeptionCase = true;
850				}
851			}
852
853			if (!isExeptionCase) {
854				setTimeout(function() {
855					_thisObj.eventChangeFilter(e);
856				}, 100);
857			}
858		});
859
860		//after change input or dropdown make this filter active
861		jQuery('.wpfFilterWrapper input:not(.passiveFilter)').on('change', function (e) {
862			e.preventDefault();
863			// check if input change move to top
864			_thisObj.moveCheckedToTop(jQuery(this));
865			// check multi or single input (radio or checkbox)
866			_thisObj.detectSingleCheckbox(jQuery(this))
867			// Mark selected
868			_thisObj.markCheckboxSelected(jQuery(this).closest('.wpfFilterWrapper'));
869		});
870
871		jQuery('.wpfMainWrapper').each(function() {
872			var mainWrapper = jQuery(this),
873				settings = _thisObj.getFilterMainSettings(mainWrapper);
874			if (settings && settings.settings && settings.settings.checked_items_top === '1') {
875				mainWrapper.find('.wpfFilterWrapper input').attr('autocomplete', 'off');
876				mainWrapper.find('.wpfFilterWrapper input:checked').each(function() {
877					_thisObj.moveCheckedToTop(jQuery(this), false);
878				});
879			}
880		});
881
882		//search field work
883		jQuery('.wpfFilterWrapper .wpfSearchFieldsFilter').on('keyup', function (e) {
884			var _this = jQuery(this),
885				wrapper = _this.closest('.wpfFilterWrapper'),
886				searchVal = _this.val().toLowerCase(),
887				isIconFunc = typeof (_thisObj.getIcons) == 'function',
888				unfolding = (searchVal.length && _this.attr('data-unfolding') == '1' && isIconFunc),
889				collapse = (searchVal.length == 0 && _this.attr('data-collapse-search') == '1' && isIconFunc);
890			wrapper.find('.wpfFilterContent li:not(.wpfShowFewerWrapper)').filter(function() {
891				var $li = jQuery(this);
892				if ($li.find('.wpfValue').text().toLowerCase().indexOf(searchVal) > -1) {
893					$li.removeClass('wpfSearchHidden');
894					if (unfolding || collapse) {
895						var $parentLi = $li.closest('li');
896						while ($parentLi.length && $parentLi.closest('.wpfFilterWrapper')) {
897							var $label = $parentLi.children('label'),
898								$icon = $label.length ? $label.find('i.fa, svg') : '';
899							if ($icon.length) {
900								var $icons = _thisObj.getIcons($icon.eq(0));
901								if ($icons.collapsed && unfolding || !$icons.collapsed && collapse) {
902									_thisObj.collapsibleToggle($icon.eq(0), $icons, $parentLi);
903								}
904							}
905							$parentLi = $parentLi.closest('ul').closest('li');
906						}
907					}
908				} else {
909					$li.addClass('wpfSearchHidden');
910				}
911			});
912			if(typeof(_thisObj.initShowMore) == 'function') {
913				_thisObj.initShowMore(wrapper.find('.wpfFilterVerScroll'));
914			}
915		});
916
917		//uncheck one slug
918		jQuery('body').off('click', '.wpfSlugDelete').on('click', '.wpfSlugDelete', function(){
919			var _this = jQuery(this),
920				wrapper = _this.closest('.wpfSlug'),
921				filterType = wrapper.attr('data-filter-type'),
922				filterAttr = wrapper.attr('data-get-attribute'),
923				filterWrapper = false;
924			_thisObj.setCurrentLocation();
925
926			jQuery('.wpfFilterWrapper[data-filter-type="'+filterType+'"][data-get-attribute="'+filterAttr+'"]').each(function(){
927				var $this = jQuery(this),
928					filterType = $this.attr("data-filter-type");
929				if (filterType == 'wpfPrice' || filterType == 'wpfPriceRange') {
930					_thisObj.clearFilters($("[data-filter-type='wpfPrice']:not(.wpfSelectedParameter)"));
931					_thisObj.clearFilters($("[data-filter-type='wpfPriceRange']:not(.wpfSelectedParameter)"));
932				} else {
933					_thisObj.clearFilters($this);
934				}
935				if(filterWrapper == false) {
936					filterWrapper = $this.closest('.wpfMainWrapper');
937				}
938			});
939			if(filterWrapper != false) {
940				_thisObj.filtering(filterWrapper);
941			}
942		});
943
944		jQuery('body').off('click', '.wpfFilterWrapper .wpfFilterTitle').on('click', '.wpfFilterWrapper .wpfFilterTitle', function (e) {
945			e.preventDefault();
946			var _this = jQuery(this),
947				wrapper = _this.closest('.wpfMainWrapper'),
948				settings = _thisObj.getFilterMainSettings(wrapper),
949				content = _this.closest('.wpfFilterWrapper').find('.wpfFilterContent');
950
951			setTimeout(function () {
952				var toggle = _this.find('i.wpfTitleToggle, svg'),
953					icons  = {};
954				if (toggle.length) {
955					if (typeof (_thisObj.getIcons) == 'function') {
956						icons = _thisObj.getIcons(toggle);
957					} else {
958						icons = {collapsed: toggle.hasClass('fa-plus'), plusIcon: 'fa-plus', minusIcon: 'fa-minus'};
959					}
960
961					if (settings.settings.hide_filter_icon !== '0') {
962						if (icons.collapsed) {
963							_thisObj.openFilterToggle(toggle, content, true, icons);
964							_this.attr('aria-expanded', 'true');
965						} else {
966							_thisObj.closeFilterToggle(toggle, content, true, icons);
967							_this.attr('aria-expanded', 'false');
968						}
969					}
970				}
971			}, 100);
972		});
973
974		jQuery('body').off('keydown', '.wpfFilterWrapper .wpfFilterTitle').on('keydown', '.wpfFilterWrapper .wpfFilterTitle', function (e) {
975			if (e.which === 13 || e.which === 32) {
976				e.preventDefault();
977				jQuery(this).trigger('click');
978			}
979		});
980
981		jQuery('body').off('click', '.wpfFilterWrapper .wpfBlockClear').on('click', '.wpfFilterWrapper .wpfBlockClear',  function(){
982			var parent = jQuery(this).closest(".wpfFilterWrapper"),
983				parentAttr = parent.attr("data-filter-type");
984			_thisObj.setCurrentLocation();
985			if (parentAttr == 'wpfPrice' || parentAttr == 'wpfPriceRange') {
986				_thisObj.clearFilters($("[data-filter-type='wpfPrice']:not(.wpfSelectedParameter)"));
987				_thisObj.clearFilters($("[data-filter-type='wpfPriceRange']:not(.wpfSelectedParameter)"));
988			} else {
989				_thisObj.clearFilters(parent);
990			}
991			_thisObj.filtering(parent.closest('.wpfMainWrapper'));
992			return false;
993		});
994		//ajax pagination
995		jQuery('body').off('click', '.woocommerce-pagination a.page-numbers').on('click', '.woocommerce-pagination a.page-numbers', function (e) {
996			var wrapper = jQuery('.wpfMainWrapper').first();
997			// 1️⃣ If NoWooPage exists → let its handler handle it
998			if (wrapper.hasClass('wpfNoWooPage')) {
999				return;
1000			}
1001			// 2️⃣ If ajax pagination disabled → allow normal Woo pagination
1002			if (!wpfIsAjaxPaginationEnabled()) {
1003				return;
1004			}
1005			// 3️⃣ Otherwise → AJAX pagination
1006			e.preventDefault();
1007			var _this = jQuery(this),
1008				paginationWrapper = _this.closest('.woocommerce-pagination'),
1009				currentNumber = paginationWrapper.find('.current').text();
1010			if(!_this.hasClass('next') && !_this.hasClass('prev') ){
1011				var number = parseInt(_this.text(), 10) || 1;
1012			}else if(_this.hasClass('next')){
1013				var current = parseInt(currentNumber, 10) || 1;
1014				var number = current + 1;
1015			}else if(_this.hasClass('prev')){
1016				var current = parseInt(currentNumber, 10) || 1;
1017				var number = Math.max(current - 1, 1);
1018			}
1019			var wrapper = jQuery('.wpfMainWrapper').first(),
1020				$queryVars = wrapper.attr('data-settings');
1021			try{
1022				var settings = JSON.parse($queryVars);
1023			}catch(e){
1024				var settings = false;
1025			}
1026			if(settings){
1027				settings.paged = number;
1028				settings.pagination = 1;
1029				wrapper.attr('data-settings', JSON.stringify(settings) );
1030			}
1031			_thisObj.setCurrentLocation();
1032
1033			// todo: testing for two+ filters on page
1034			_thisObj.filtering( jQuery('.wpfMainWrapper') );
1035			_thisObj.setPagination(0);
1036		});
1037
1038		//ajax pagination
1039		jQuery('body').off('wpffiltering').on('wpffiltering', function () {
1040			_thisObj.setPagination(1);
1041			_thisObj.setCurrentLocation();
1042			_thisObj.filtering();
1043			_thisObj.setPagination(0);
1044		});
1045
1046		//click on new pagination link with page number
1047		jQuery('body').off('click', '.wpfNoWooPage .woocommerce-pagination a.page-numbers').on('click', '.wpfNoWooPage .woocommerce-pagination a.page-numbers', function (e) {
1048			e.preventDefault();
1049			var _this = jQuery(this),
1050				paginationWrapper = _this.closest('.woocommerce-pagination'),
1051				currentNumber = paginationWrapper.find('.current').text();
1052			if(!_this.hasClass('next') && !_this.hasClass('prev') ){
1053				var number = parseInt(_this.text(), 10) || 1;
1054			}else if(_this.hasClass('next')){
1055				var current = parseInt(currentNumber, 10) || 1;
1056				var number = current + 1;
1057			}else if(_this.hasClass('prev')){
1058				var current = parseInt(currentNumber, 10) || 1;
1059				var number = Math.max(current - 1, 1);
1060			}
1061			var wrapper = jQuery('.wpfMainWrapper').first(),
1062				$queryVars = wrapper.attr('data-settings');
1063			try{
1064				var settings = JSON.parse($queryVars);
1065			}catch(e){
1066				var settings = false;
1067			}
1068			if(settings){
1069				settings.paged = number;
1070				settings.pagination = 1;
1071				wrapper.attr('data-settings', JSON.stringify(settings) );
1072			}
1073			_thisObj.setCurrentLocation();
1074
1075			// todo: testing for two+ filters on page
1076			_thisObj.filtering( jQuery('.wpfMainWrapper') );
1077			_thisObj.setPagination(0);
1078		});
1079
1080		var prevLocation = location.href.split('#').shift();
1081		jQuery(window).on('popstate', function (e) {
1082
1083			var currentLocation = location.href.split('#').shift();
1084			if (location.href.split('#').length > 1 && prevLocation === currentLocation) {
1085				return;
1086			}
1087
1088			if (typeof window.wpfAdminPage === 'undefined' && !_thisObj.isSafari) {
1089				location.reload();
1090			}
1091		});
1092		jQuery('.wpfPreselected:not([data-filter-type="wpfPriceRange"]) .wpfCheckbox input').prop('checked', true);
1093
1094		jQuery('#wpfOverlay:not([data-filter]').each(function() {
1095			var $overlay = jQuery(this),
1096				$wrapper = $overlay.closest('.wpfMainWrapper');
1097			$overlay.attr('data-filter-for', $wrapper.attr('id')).attr('data-filter',$wrapper.attr('data-filter'));
1098			$overlay.appendTo('body');
1099		});
1100
1101	});
1102
1103	function applyFilter(_thisObj, $this) {
1104		var mainWrapper = $this.closest('.wpfMainWrapper');
1105		_thisObj.setCurrentLocation();
1106
1107		_thisObj.filterClick = true;
1108		_thisObj.filtering(mainWrapper);
1109	}
1110
1111	WpfFrontendPage.prototype.filterOptionsForDevices = (function () {
1112		var _thisObj = this.$obj;
1113		jQuery('.wpfMainWrapper .wpfFilterWrapper').each(function () {
1114			var _this = jQuery(this),
1115				wrapper = _this.closest('.wpfMainWrapper'),
1116				settings = _thisObj.getFilterMainSettings(wrapper),
1117				isMobile = false,
1118				screenSize = jQuery(window).width();
1119
1120			if (settings.settings !== undefined) {
1121				var isMobileBreakpoint = settings.settings.desctop_mobile_breakpoint_switcher,
1122					mobileBreakpoinWidth = isMobileBreakpoint && isMobileBreakpoint == '1' ? settings.settings.desctop_mobile_breakpoint_width : '0',
1123
1124					displayFor = settings.settings.display_for,
1125
1126					filterWidthDesktop          = settings.settings.filter_width,
1127					filterWidthDesktopUnit      = settings.settings.filter_width_in,
1128					filterWidthMobile           = settings.settings.filter_width_mobile,
1129					filterWidthMobileUnit       = settings.settings.filter_width_in_mobile,
1130					filterBlockWidthDesktop     = settings.settings.filter_block_width,
1131					filterBlockWidthDesktopUnit = settings.settings.filter_block_width_in,
1132					filterBlockWidthMobile      = settings.settings.filter_block_width_mobile,
1133					filterBlockWidthMobileUnit  = settings.settings.filter_block_width_in_mobile;
1134
1135				if (mobileBreakpoinWidth && '0' !== mobileBreakpoinWidth) {
1136					if (screenSize <= mobileBreakpoinWidth) {
1137						isMobile = true;
1138					}
1139
1140					// "Filter Width" and "Filter Block Width" options
1141					if (isMobile && filterBlockWidthMobile != '0') {
1142						wrapper.css('width', filterWidthMobile+filterWidthMobileUnit);
1143						_this.css('width', filterBlockWidthMobile+filterBlockWidthMobileUnit);
1144						if (filterBlockWidthMobile+filterBlockWidthMobileUnit != '100%') {
1145							_this.css('float', 'left');
1146						}
1147					} else if (!isMobile && filterBlockWidthDesktop != '0') {
1148						wrapper.css('width', filterWidthDesktop+filterWidthDesktopUnit);
1149						_this.css('width', filterBlockWidthDesktop+filterBlockWidthDesktopUnit);
1150						if (filterBlockWidthDesktop+filterBlockWidthDesktopUnit != '100%') {
1151							_this.css('float', 'left');
1152						}
1153					}
1154
1155					// "Display filter on"  option
1156					if (isMobile && displayFor == 'desktop') {
1157						wrapper.hide();
1158					} else if (!isMobile && displayFor == 'mobile') {
1159						wrapper.hide();
1160					}
1161
1162					// filters title
1163					_this.find('.wpfFilterTitle[data-show-on-mobile]').each(function() {
1164						jQuery(this).closest('.wpfFilterMainWrapper').find('wpfLoaderLayout').show();
1165							var showDesctop = jQuery(this).data('show-on-desctop'),
1166								showMobile = jQuery(this).data('show-on-mobile'),
1167								content = jQuery(this).closest('.wpfFilterWrapper').find('.wpfFilterContent'),
1168								title = jQuery(this).find('.wfpTitle'),
1169								icons = {};
1170						title.show();
1171
1172						var toggle = jQuery(this).closest('.wpfFilterWrapper').find('i.wpfTitleToggle, svg');
1173						setTimeout(function () {
1174							if (toggle.length) {
1175								toggle.show();
1176								if (typeof (_thisObj.getIcons) == 'function') {
1177									icons = _thisObj.getIcons(toggle);
1178								} else {
1179									icons = {collapsed: toggle.hasClass('fa-plus'), plusIcon: 'fa-plus', minusIcon: 'fa-minus'};
1180								}
1181
1182								if (isMobile) {
1183									if (showMobile == 'yes_open') {
1184										_thisObj.openFilterToggle(toggle, content, false, icons);
1185									} else if (showMobile == 'yes_close') {
1186										_thisObj.closeFilterToggle(toggle, content, false, icons);
1187									} else if (showMobile == 'no') {
1188										_thisObj.openFilterToggle(toggle, content, false, icons);
1189										toggle.hide();
1190										title.hide();
1191									}
1192								} else {
1193									if (showDesctop == 'yes_open') {
1194										_thisObj.openFilterToggle(toggle, content, false, icons);
1195									} else if (showDesctop == 'yes_close') {
1196										_thisObj.closeFilterToggle(toggle, content, false, icons);
1197									} else if (showDesctop == 'no') {
1198										_thisObj.openFilterToggle(toggle, content, false, icons);
1199										toggle.hide();
1200										title.hide();
1201									}
1202								}
1203							}
1204						}, 100);
1205					});
1206				}
1207			}
1208		});
1209	});
1210
1211	WpfFrontendPage.prototype.checkExeptionCasesBeforeFiltering = (function (filterInput) {
1212		var isExeption = false;
1213		// exception when custom price do not set but input activated
1214		if ( jQuery(filterInput).parent().hasClass('wpfPriceCheckboxCustom')) {
1215			var customPriceWrapper = jQuery(filterInput).closest('li'),
1216				customMin = customPriceWrapper.find('input[name=wpf_custom_min]').val(),
1217				customMax = customPriceWrapper.find('input[name=wpf_custom_max]').val();
1218
1219			if (!customMin && !customMax) {
1220				isExeption = true;
1221			}
1222		}
1223		return isExeption;
1224	});
1225
1226	WpfFrontendPage.prototype.detectSingleCheckbox = (function (checkedInput) {
1227		var filterWrapper = checkedInput.closest('.wpfFilterWrapper'),
1228			displayType = filterWrapper.data('display-type'),
1229			filterType = filterWrapper.data('filter-type');
1230
1231		if (filterType == 'wpfCategory' || filterType == 'wpfPerfectBrand'|| filterType == 'wpfBrand') {
1232			var isOne = displayType == 'list';
1233		} else {
1234			var isOne = displayType == 'radio';
1235		}
1236
1237		if (isOne) {
1238			var inputs = filterWrapper.find('input');
1239
1240			if (checkedInput.is(':checked')) {
1241				inputs.prop('checked', false);
1242				checkedInput.prop('checked', true);
1243			}
1244		}
1245	});
1246
1247	WpfFrontendPage.prototype.moveCheckedToTop = (function (checkedInput, setPause) {
1248		var _thisObj = this.$obj,
1249			sPause = setPause === false ? 0 : 200;
1250		setTimeout(function() {
1251			var checkboxWrapper = checkedInput.closest('li'),
1252				mainWrapper = checkedInput.closest('.wpfMainWrapper'),
1253				filterWrapper = checkedInput.closest('.wpfFilterWrapper'),
1254				isHierarchical = filterWrapper.data('show-hierarchical'),
1255				settings = _thisObj.getFilterMainSettings(mainWrapper),
1256				checkboxesWrapper = checkedInput.closest(isHierarchical ? 'ul' : '.wpfFilterVerScroll');
1257			if(settings && checkboxesWrapper.length) {
1258				settings = settings.settings;
1259				var checkedItemsTop = settings.checked_items_top === '1',
1260					isExeptionCase = _thisObj.checkExeptionCasesBeforeFiltering(checkedInput);
1261				if(checkedItemsTop && !isExeptionCase){
1262					if (checkedInput.is(":checked")) {
1263						checkboxesWrapper.prepend(checkboxWrapper);
1264					} else {
1265						checkboxesWrapper.append(checkboxWrapper);
1266						checkboxesWrapper.append(checkboxesWrapper.find('.wpfShowFewerWrapper,.wpfShowMoreWrapper'));
1267					}
1268					checkboxesWrapper.scrollTop(0);
1269				}
1270			}
1271		}, sPause);
1272	});
1273
1274	/**
1275	 * WpfFrontendPage.prototype.closeFilterToggle.
1276	 *
1277	 * @version 3.1.8
1278	 */
1279	WpfFrontendPage.prototype.closeFilterToggle = (function (toggle, content, isTimeout, icons) {
1280		if (toggle.hasClass(icons.minusIcon)) {
1281			toggle.removeClass(icons.minusIcon);
1282			toggle.addClass(icons.plusIcon);
1283			content.addClass('wpfBlockAnimated');
1284			if (typeof isTimeout !== 'undefined' && isTimeout) {
1285				setTimeout(function () {
1286					if (content.hasClass('wpfBlockAnimated')) {
1287						content.addClass('wpfHide');
1288						content.find('input, select, a, button').attr('tabindex', '-1');
1289					}
1290				}, 10);
1291			} else {
1292				if (content.hasClass('wpfBlockAnimated')) content.addClass('wpfHide');
1293			}
1294		}
1295	});
1296
1297	/**
1298	 * WpfFrontendPage.prototype.closeFilterToggle.
1299	 *
1300	 * @version 3.1.8
1301	 */
1302	WpfFrontendPage.prototype.openFilterToggle = (function (toggle, content, isTimeout, icons) {
1303		if (toggle.hasClass(icons.plusIcon)) {
1304			toggle.removeClass(icons.plusIcon);
1305			toggle.addClass(icons.minusIcon);
1306			content.removeClass('wpfHide');
1307			content.find('input, select, a, button').removeAttr('tabindex');
1308			if (typeof isTimeout !== 'undefined' && isTimeout) {
1309				setTimeout(function () {
1310					if (!content.hasClass('wpfHide')) content.removeClass('wpfBlockAnimated');
1311				}, 400);
1312			} else {
1313				if (!content.hasClass('wpfHide')) content.removeClass('wpfBlockAnimated');
1314			}
1315		}
1316	});
1317
1318	WpfFrontendPage.prototype.setPagination = (function (pagination) {
1319		var wrapper = jQuery('.wpfMainWrapper').first(),
1320			$queryVars = wrapper.attr('data-settings');
1321		try{
1322			var settings = JSON.parse($queryVars);
1323		}catch(e){
1324			var settings = false;
1325		}
1326		if(settings){
1327			settings.pagination = pagination;
1328			wrapper.attr('data-settings', JSON.stringify(settings) );
1329		}
1330	});
1331
1332	WpfFrontendPage.prototype.setCurrentLocation = (function() {
1333		app.wpfOldUrl = window.location.href;
1334		app.wpfNewUrl = app.wpfOldUrl;
1335	});
1336
1337	//prepare url param
1338	WpfFrontendPage.prototype.prepareUrlParams = function(currentUrl) {
1339		// Step 1: Create a URL object to easily parse the current URL
1340		var finalUrl = new URL(currentUrl);
1341		// Step 2: Extract the path segments (e.g., /wbw/wpf_filter_cat_0/hoodies)
1342		var pathSegments = finalUrl.pathname.split('/').filter(Boolean); // Remove empty segments
1343		// Step 3: Initialize URLSearchParams to handle query parameters
1344		var urlParams = new URLSearchParams(finalUrl.search);
1345		// Step 4: Process the path segments and convert them into query parameters
1346		for (var i = 0; i < pathSegments.length; i++) {
1347			var segment = pathSegments[i];
1348
1349			// Check if the segment is a filter key (e.g., wpf_filter_cat_0, pr_stock, etc.)
1350			if (segment.indexOf('wpf_filter_') === 0) {
1351				var filterKey = segment; // e.g., 'wpf_filter_cat_0'
1352				var filterValue = pathSegments[i + 1]; // e.g., 'hoodies'
1353				// You may need to resolve the term ID here based on the slug (e.g., 'hoodies' -> 34)
1354				// For now, we'll use the value directly, but you can integrate a lookup if needed
1355
1356				// Add the filter to the query parameters
1357				urlParams.set(filterKey, filterValue); // Map the filterKey to filterValue
1358			}
1359		}
1360
1361		// Step 5: Rebuild the URL with the updated parameters
1362		finalUrl.search = urlParams.toString();  // Set the new query string
1363		// Step 6: Return the final URL with updated query parameters
1364		return finalUrl.toString();  // Return the full URL with updated parameters
1365	};
1366	//prepare url param
1367
1368	/**
1369	 * filtering.
1370	 *
1371	 * @version 3.3.0
1372	 */
1373	WpfFrontendPage.prototype.filtering = (function ($filterWrapper, clearAll, redirectLink, onlyRecalcFilter) {
1374		var _thisObj = this.$obj;
1375		_thisObj.chageRangeFieldWidth();
1376		if(_thisObj.isAdminPreview) return;
1377
1378		if(typeof $filterWrapper == 'undefined' || $filterWrapper.length == 0) {
1379			$filterWrapper = jQuery('.wpfMainWrapper').first();
1380		}
1381		if (_thisObj.filterClick && $filterWrapper.length) {
1382			_thisObj.createOverlay($filterWrapper.attr('id'));
1383		}
1384		if (typeof (_thisObj.beforeFilteringPro) === 'function') {
1385			_thisObj.beforeFilteringPro($filterWrapper);
1386		}
1387
1388		_thisObj.isSynchro = false;
1389		_thisObj.isStatistics = false;
1390
1391		if ($filterWrapper.length !== 0) {
1392			_thisObj.filteringId++;
1393			_thisObj.lastFids[$filterWrapper.data('viewid')] = _thisObj.filteringId;
1394
1395			var $filtersDataBackend = [],
1396				$filtersDataFrontend = [],
1397				noWooPage = _thisObj.noWoo,
1398				$generalSettings = _thisObj.getFilterMainSettings($filterWrapper);
1399			_thisObj.isSynchro = $generalSettings['settings']['use_filter_synchro'] && ($generalSettings['settings']['use_filter_synchro'] == '1') ? true : false;
1400			_thisObj.isStatistics = $filterWrapper.attr('data-is-stats') == 1;
1401
1402			if(_thisObj.isSynchro) {
1403				_thisObj.syncronizeFilters($filterWrapper);
1404			}
1405
1406			(_thisObj.isSynchro ? jQuery('.wpfMainWrapper') : $filterWrapper).find('.wpfFilterWrapper:not(.wpfNotActive), .wpfFilterWrapper.wpfPreselected').each(function () {
1407				var $filter = jQuery(this),
1408					filterType = $filter.attr('data-filter-type'),
1409					filterName = $filter.attr('data-get-attribute'),
1410					wrapper = $filter.closest('.wpfMainWrapper'),
1411					idFilter = wrapper.data('filter'),
1412					uniqId = $filter.attr('data-uniq-id'),
1413					allSettings = _thisObj.getFilterOptionsByType($filter, filterType),
1414					valueToPushBackend = {},
1415					valueToPushFrontend = {},
1416					logic = $filter.attr('data-query-logic'),
1417					isGroup = false,
1418					cgIndex = null;
1419				if(_thisObj.isStatistics && typeof (_thisObj.prepareStatisticsData) == 'function') {
1420					_thisObj.prepareStatisticsData($filter, allSettings);
1421				}
1422
1423				try {
1424					var order = JSON.parse(_thisObj.getFilterMainSettings(wrapper).settings.filters.order);
1425					jQuery.each(order, function (i, v) {
1426						if (v.uniqId === uniqId) {
1427							jQuery.each(v.settings, function (i, v) {
1428								cgIndex = i.match(/^f_cglist\[(\d+)\]/);
1429								if (cgIndex !== null && typeof cgIndex[1] !== 'undefined' && v !== '') {
1430									isGroup = true;
1431								}
1432							});
1433						}
1434					});
1435				} catch (e) {
1436				}
1437
1438				if (typeof logic === 'undefined') {
1439					logic = 'or';
1440				} else if (logic == 'not') {
1441					var notIds = $filter.attr('data-not-ids');
1442					if (notIds && notIds.length > 0) {
1443						allSettings = {backend: notIds.split(',')};
1444					}
1445				}
1446				var withChildren = $filter.attr('data-query-children');
1447				if (typeof withChildren === 'undefined') {
1448					withChildren = '1';
1449				}
1450
1451				if (allSettings['backend'].length && typeof allSettings['backend'] !== 'undefined' || filterType === 'wpfSearchText'  || filterType === 'wpfSearchNumber') {
1452					valueToPushBackend['id'] = filterType;
1453					valueToPushBackend['uniqId'] = uniqId;
1454					valueToPushBackend['logic'] = logic;
1455					valueToPushBackend['children'] = withChildren;
1456					valueToPushBackend['settings'] = allSettings['backend'];
1457					valueToPushBackend['name'] = filterName;
1458					$filtersDataBackend.push(valueToPushBackend);
1459				}
1460				if ('frontend' in allSettings) {
1461
1462					valueToPushFrontend['id'] = filterType;
1463
1464					var logicDelimetrList = {
1465						or: '|',
1466						and: ',',
1467						not_in: ';'
1468					}
1469
1470					valueToPushFrontend['delim'] = logicDelimetrList[logic];
1471					valueToPushFrontend['children'] = withChildren;
1472					valueToPushFrontend['settings'] = allSettings['frontend'];
1473					valueToPushFrontend['name'] = filterName;
1474					if (isGroup) {
1475						valueToPushFrontend['idFilter'] = idFilter;
1476						valueToPushFrontend['idBlock'] = uniqId.replace(/^wpf/, '');
1477					}
1478					$filtersDataFrontend.push(valueToPushFrontend);
1479				}
1480			});
1481
1482			var redirectTerm = typeof redirectLink !== 'undefined';
1483			if (redirectTerm || (typeof $filterWrapper.data('redirect-page-url') !== 'undefined' && _thisObj.filterClick)) {
1484				history.pushState({state: 1, rand: Math.random(), wpf: true}, '', location.protocol + '//' + location.host + location.pathname);
1485			}
1486
1487			var filterId = $filterWrapper.data('filter');
1488			if (typeof filterId !== 'undefined') {
1489				jQuery('span.wpfHidden').each(function () {
1490					var $span = jQuery(this),
1491						attribute = $span.data('shortcode-attribute'),
1492						fclass = 'wpf-filter-' + filterId;
1493					if ((attribute.class !== '' && fclass === attribute.class) || $span.closest('.'+fclass).length) {
1494						_thisObj.QStringWork('wpf_id', filterId, noWooPage, $filterWrapper, 'change');
1495					}
1496				});
1497			}
1498
1499			_thisObj.changeUrlByFilterParams($filtersDataFrontend);
1500			_thisObj.QStringWork('wpf_reload', '', noWooPage, $filterWrapper, 'remove');
1501
1502			//get paged params from html
1503			var $queryVars = $filterWrapper.attr('data-settings'),
1504				$defQuery = $filterWrapper.attr('data-default-query'),
1505				$queryVarsSettings = JSON.parse($queryVars);
1506
1507			var $filterSettings = $generalSettings === false ? {} : {
1508				'wpf_fid': _thisObj.filteringId,
1509				'filter_recount': $generalSettings['settings']['filter_recount'] && ($generalSettings['settings']['filter_recount'] == '1') ? true : false,
1510				'filter_recount_price': $generalSettings['settings']['filter_recount_price'] && ($generalSettings['settings']['filter_recount_price'] == '1') ? true : false,
1511				'text_no_products': $generalSettings['settings']['text_no_products'] ? $generalSettings['settings']['text_no_products'] : '',
1512				'count_product_shop': $generalSettings['settings']['count_product_shop'] ? parseInt($generalSettings['settings']['count_product_shop']) : 0,
1513				'f_multi_logic': $generalSettings['settings']['f_multi_logic'] ? $generalSettings['settings']['f_multi_logic'] : 'and',
1514				'remove_actions': $generalSettings['settings']['remove_actions'] && ($generalSettings['settings']['remove_actions'] == '1') ? true : false,
1515				'filtering_by_variations': $generalSettings['settings']['filtering_by_variations'] && ($generalSettings['settings']['filtering_by_variations'] == '1') ? true : false,
1516				'form_filter_by_variations': $generalSettings['settings']['form_filter_by_variations'] && ($generalSettings['settings']['form_filter_by_variations'] == '1') ? true : false,
1517				'exclude_backorder_variations': $generalSettings['settings']['exclude_backorder_variations'] && ($generalSettings['settings']['exclude_backorder_variations'] == '1') ? true : false,
1518				'display_product_variations': $generalSettings['settings']['display_product_variations'] && ($generalSettings['settings']['display_product_variations'] == '1') ? true : false,
1519				'all_products_filtering': $generalSettings['settings']['all_products_filtering'] && ($generalSettings['settings']['all_products_filtering'] == '1') ? true : false,
1520				'do_not_use_shortcut': $generalSettings['settings']['do_not_use_shortcut'] && ($generalSettings['settings']['do_not_use_shortcut'] == '1') ? true : false,
1521				'use_category_filtration': $generalSettings['settings']['use_category_filtration'] ? $generalSettings['settings']['use_category_filtration'] : 1,
1522				'product_list_selector': $generalSettings['settings']['product_list_selector'] ? $generalSettings['settings']['product_list_selector'] : '',
1523				'product_container_selector': $generalSettings['settings']['product_container_selector'] ? $generalSettings['settings']['product_container_selector'] : '',
1524				'auto_update_filter' : Number($generalSettings['settings']['auto_update_filter']),
1525				'redirect_only_click' : Number($generalSettings['settings']['redirect_only_click']),
1526				'display_status_private' : $generalSettings['settings']['display_status_private'] && ($generalSettings['settings']['display_status_private'] == '1') ? true : false,
1527				'open_one_by_one': $generalSettings['settings']['open_one_by_one'] ? $generalSettings['settings']['open_one_by_one'] : '',
1528				'obo_only_children': $generalSettings['settings']['obo_only_children'] ? $generalSettings['settings']['obo_only_children'] : '',
1529				'display_only_children_category': $generalSettings['settings']['display_only_children_category'] ? $generalSettings['settings']['display_only_children_category'] : '',
1530			};
1531			var $withPerPage = $filterWrapper.find('select.wpfPerPageDD'),
1532				perPageCount = $withPerPage.length ? $withPerPage.find('option:selected') : '';
1533			if (perPageCount.length) {
1534				$filterSettings['count_product_shop'] = perPageCount.val();
1535			}
1536
1537			$filterSettings['sort_by_title'] = ($generalSettings['settings']['sort_by_title'] != undefined && $generalSettings['settings']['sort_by_title'] == '1' ? true : false);
1538			if (typeof $defQuery !== 'undefined' && $defQuery.length) $filterSettings['default_query'] = JSON.parse($defQuery);
1539
1540			// find woocommerce product loop type ( shortcode, loop )
1541			var productContainerSelector = _thisObj.fixSelector($filterSettings['product_container_selector'], ''),
1542				productContainerElem = (productContainerSelector !== '')
1543					? jQuery(productContainerSelector)
1544					: jQuery(document);
1545
1546			$queryVars = JSON.parse($queryVars);
1547			var shortcode = jQuery('span[data-shortcode-attribute]', productContainerElem),
1548				$shortcodeAttr = {};
1549
1550			if (shortcode.length) {
1551				$shortcodeAttr = shortcode.data('shortcode-attribute');
1552
1553				if ($shortcodeAttr['limit'] > 0) {
1554					$queryVars['posts_per_page'] = $shortcodeAttr['limit'];
1555				}
1556
1557				$queryVars['wc_loop_type'] = 'shortcode';
1558				$queryVars['paginate_type'] = 'shortcode';
1559				$queryVars['paginate_base'] = 'product-page';
1560			} else {
1561				$queryVars['wc_loop_type'] = 'loop';
1562			}
1563
1564			// for plugin WooCommerce Products Per Page
1565			var $wppp = jQuery('.wppp-select').first();
1566			if ($wppp.length) {
1567				$queryVars['posts_per_page'] = $wppp.val();
1568			}
1569
1570			$queryVars = JSON.stringify($queryVars);
1571			$shortcodeAttr = JSON.stringify($shortcodeAttr);
1572
1573			if (clearAll) {
1574				var newUrl = getCurrentUrlPartsWpf();
1575				if (newUrl.search.length && newUrl.search.indexOf('wpf_')) clearAll = false;
1576			}
1577
1578			if ($filterSettings['count_product_shop'] > 0 && !clearAll) {
1579				_thisObj.QStringWork('wpf_count', $filterSettings['count_product_shop'], noWooPage, $filterWrapper, 'change');
1580			}
1581			if ($filterSettings['sort_by_title']) {
1582				_thisObj.QStringWork('wpf_order', 'title', noWooPage, $filterWrapper, 'change');
1583			}
1584			if ($filterSettings['filtering_by_variations'] && !clearAll) {
1585				_thisObj.QStringWork('wpf_fbv', 1, noWooPage, $filterWrapper, 'change');
1586			}
1587			if ($filterSettings['exclude_backorder_variations'] && !clearAll) {
1588				_thisObj.QStringWork('wpf_ebv', 1, noWooPage, $filterWrapper, 'change');
1589			}
1590			if ($filterSettings['display_product_variations'] && !clearAll) {
1591				_thisObj.QStringWork('wpf_dpv', 1, noWooPage, $filterWrapper, 'change');
1592			}
1593			if ($filterSettings['all_products_filtering'] && !clearAll) {
1594				_thisObj.QStringWork('all_products_filtering', '1', noWooPage, $filterWrapper, 'change');
1595			}
1596			if ($filtersDataBackend.length === 0) {
1597				_thisObj.QStringWork('all_products_filtering', '', noWooPage, $filterWrapper, 'remove');
1598			}
1599			if ($filterSettings['f_multi_logic'] !== 'and' && !clearAll) {
1600				_thisObj.QStringWork('wpf_filter_tax_block_logic', $filterSettings['f_multi_logic'], noWooPage, $filterWrapper, 'change');
1601			}
1602			if ($filtersDataBackend.length === 0) {
1603				_thisObj.QStringWork('wpf_filter_tax_block_logic', '', noWooPage, $filterWrapper, 'remove');
1604			}
1605			// we always start from first page after filtering
1606			_thisObj.QStringWork($queryVarsSettings['paginate_base'], '', noWooPage, $filterWrapper, 'remove');
1607			_thisObj.QStringWork('product-page', '', noWooPage, $filterWrapper, 'remove');
1608			_thisObj.QStringWork('shopPage', '', noWooPage, $filterWrapper, 'remove');
1609			_thisObj.QStringWork('avia-element-paging', '', noWooPage, $filterWrapper, 'remove');
1610			_thisObj.QStringWork('bpage', '', noWooPage, $filterWrapper, 'remove');
1611
1612			var curUrl = getCurrentUrlPartsWpf();
1613			if (curUrl.search.length) {
1614				// Remove any URL parameters that start with 'e-page-'
1615				var ePageMatch = curUrl.search.match(/[?&](e-page-[^=&]+)=/);
1616				if (ePageMatch && ePageMatch[1]) {
1617					_thisObj.QStringWork(ePageMatch[1], '', noWooPage, $filterWrapper, 'remove');
1618				}
1619
1620				var $pages = curUrl.search.match(/query-\d+-page/i);
1621				if ($pages != null && $pages.length) _thisObj.QStringWork($pages[0], '', noWooPage, $filterWrapper, 'remove');
1622			}
1623
1624			var $woocommerceSettings = {};
1625			if (jQuery('.wpfFilterWrapper[data-filter-type="wpfSortBy"]').length == 0) {
1626				var $wooCommerceSort = jQuery('.woocommerce-ordering select');
1627				if ($wooCommerceSort.length > 0) {
1628					$woocommerceSettings['woocommercefSortBy'] = $wooCommerceSort.eq(0).val();
1629				}
1630			}
1631			if (onlyRecalcFilter) {
1632				// this block for forced filter refresh without product filtering
1633				// you can call this with custom js: window.wpfFrontendPage.filtering(jQuery('.wpfMainWrapper[data-filter="1"]'),false,false,true);
1634				var requestData =_thisObj.getAjaxRequestData($filtersDataBackend, $queryVars, $filterSettings, $generalSettings, $shortcodeAttr, $woocommerceSettings);
1635				_thisObj.ajaxOnlyRecount(requestData, $filterWrapper.attr('id'));
1636				return;
1637			}
1638			var redirect = (typeof $filterWrapper.data('redirect-page-url') !== 'undefined'),
1639				$needUrl = $filterSettings['open_one_by_one'] == '1' && $filterSettings['obo_only_children'] == '1';
1640			//slug generation
1641			if (history.pushState && app.wpfNewUrl != window.wpfOldUrl && ((!redirect && !redirectTerm) || $needUrl)) {
1642				var slugFormat=_thisObj.slugFormat;
1643				var newUrl = app.wpfNewUrl.indexOf('pr_search_') > 0 ? app.wpfNewUrl.replace('+', '%2b') : app.wpfNewUrl;
1644				var finalUrl = newUrl;
1645				if (slugFormat !== "" && slugFormat !== 0 && slugFormat && slugFormat !== "0") {
1646					var search = newUrl ? new URL(newUrl).search : window.location.search;
1647					var segments = _thisObj.convertParamsToSegments(search);
1648					finalUrl = $generalSettings.settings.shop_base_url + 'wbw/' + segments.join('/');
1649					if (segments.length === 0) finalUrl = $generalSettings.settings.shop_base_url;
1650				}
1651				history.pushState({state: 1, rand: Math.random(), wpf: true}, '', finalUrl);
1652				app.wpfOldUrl = app.wpfNewUrl;
1653				_thisObj.changeSlugByUrl();
1654			}
1655			//slug generation
1656			if (redirectTerm || (redirect && _thisObj.filterClick)) {
1657				let queryString = app.wpfNewUrl.split('?')[1] || '';
1658				if (queryString !== '') {
1659					if (_thisObj.isStatistics) {
1660						var requestData =_thisObj.getAjaxRequestData($filtersDataBackend, $queryVars, $filterSettings, $generalSettings, $shortcodeAttr, $woocommerceSettings);
1661						wpfDoActionsAfterLoad(_thisObj.filteringId, -1, requestData);
1662					}
1663					var redLink = (redirectTerm ? redirectLink : $filterWrapper.data('redirect-page-url'));
1664					jQuery(location).attr('href', redLink + (redLink.indexOf('?') == -1 ? '?' : '&') + queryString + '&redirect');
1665				}
1666			} else {
1667				if ($generalSettings && $generalSettings.settings.enable_ajax !== '1') {
1668					if (_thisObj.isStatistics) {
1669						var requestData =_thisObj.getAjaxRequestData($filtersDataBackend, $queryVars, $filterSettings, $generalSettings, $shortcodeAttr, $woocommerceSettings);
1670						wpfDoActionsAfterLoad(_thisObj.filteringId, -1, requestData);
1671					}
1672					if (_thisObj.isSafari || navigator.userAgent.match(/firefox|fxios/i)) location.reload(true);
1673					else location.reload();
1674					return;
1675				}
1676
1677				_thisObj.currentFilterBackend = $filtersDataBackend;
1678				// event for custom javascript hook
1679				var customEvent = document.createEvent('Event');
1680				customEvent.initEvent('wpfAjaxStart', false, true);
1681				document.dispatchEvent(customEvent);
1682				//ajax call to server
1683				_thisObj.currentLoadId = $filterWrapper.attr('id');
1684
1685				var $wtbpFilterWrapper = $filterWrapper.closest('.wpfFilterForWtbp');
1686				if ($wtbpFilterWrapper.length == 0) {
1687					if ($filterWrapper.closest('.wpfFilterForWtbpFloating').length) {
1688						$wtbpFilterWrapper = $('.wpfFilterForWtbp[data-wpf-id="'+$filterWrapper.attr('data-filter')+'"]');
1689					}
1690				}
1691				if ($wtbpFilterWrapper.length == 1) {
1692					var wtbpTableId = $wtbpFilterWrapper.closest('.wtbpTableWrapper').attr('data-table-id'),
1693						wtbpTable = wtbpTableId ? window.woobewoo.WooTablepress.getTableInstanceById(wtbpTableId) : false;
1694					if (wtbpTable && wtbpTable.isSSP) {
1695						wtbpTable.ajax.reload();
1696						return;
1697					}
1698				}
1699				_thisObj.sendFiltersOptionsByAjax(_thisObj.currentFilterBackend, $queryVars, $filterSettings, $generalSettings, $woocommerceSettings, $shortcodeAttr);
1700				if (_thisObj.isSynchro) {
1701					jQuery('.wpfMainWrapper:not(#'+_thisObj.currentLoadId+')').each(function(){
1702						var $synchroWrapper = jQuery(this);
1703
1704						$generalSettings = _thisObj.getFilterMainSettings($synchroWrapper);
1705						var requestData =_thisObj.getAjaxRequestData($filtersDataBackend, $queryVars, $filterSettings, $generalSettings, $shortcodeAttr, $woocommerceSettings);
1706
1707						_thisObj.ajaxOnlyRecount(requestData, $synchroWrapper.attr('id'));
1708
1709					});
1710				}
1711			}
1712		}
1713	});
1714
1715	WpfFrontendPage.prototype.getAjaxRequestData = (function ($filtersDataBackend, $queryVars, $filterSettings, $generalSettings, $shortcodeAttr, $woocommerceSettings) {
1716		$generalSettings = $generalSettings ? $generalSettings['settings']['filters']['order'] : [];
1717		var typeSettings = typeof $generalSettings;
1718		if (typeSettings == 'undefined') $generalSettings = '[]';
1719		else if (typeSettings != 'string') $generalSettings = JSON.stringify($generalSettings);
1720
1721		return {
1722			mod: 'woofilters',
1723			action: 'woobewoo_pf_filters_frontend',
1724			filtersDataBackend: JSON.stringify($filtersDataBackend),
1725			queryvars: $queryVars,
1726			filterSettings: JSON.stringify($filterSettings),
1727			generalSettings: $generalSettings,
1728			shortcodeAttr: $shortcodeAttr,
1729			woocommerceSettings: JSON.stringify($woocommerceSettings),
1730			currenturl: window.location.href,
1731		};
1732	});
1733
1734	WpfFrontendPage.prototype.createOverlay = (function (filterId) {
1735		var selector = '#wpfOverlay';
1736		if (typeof filterId != 'undefined') selector += '[data-filter-for="'+filterId+'"]';
1737		jQuery(selector).css({'display':'block'});
1738	});
1739
1740	WpfFrontendPage.prototype.removeOverlay = (function () {
1741		jQuery('#wpfOverlay').css({'display':'none'});
1742		jQuery('#wpfOverlay[data-filter-for]').css({'display':'none'});
1743	});
1744
1745	WpfFrontendPage.prototype.syncronizeFilters = (function ($filterWrapper) {
1746		var _thisObj = this.$obj,
1747			filterId = $filterWrapper.attr('id');
1748
1749		$filterWrapper.find('.wpfFilterWrapper').each(function () {
1750			var $filter = jQuery(this),
1751				filterType = $filter.attr('data-filter-type'),
1752				filterDisplay = $filter.attr('data-display-type'),
1753				filterSlug = $filter.attr('data-slug'),
1754				filterTaxonomy = $filter.attr('data-taxonomy'),
1755				selector = '.wpfMainWrapper:not(#'+filterId+') .wpfFilterWrapper[data-filter-type="'+filterType+'"]';
1756			if (filterDisplay) selector += '[data-display-type="'+filterDisplay+'"]';
1757			if (filterSlug) selector += '[data-slug="'+filterSlug+'"]';
1758			if (filterTaxonomy) selector += '[data-taxonomy="'+filterTaxonomy+'"]';
1759			var $synchroFilters = jQuery(selector);
1760			if ($synchroFilters.length) {
1761				$synchroFilters.find('input').prop('checked', false).trigger('wpf-synchro');
1762				$filter.find('input:checked').each(function(){
1763					var $li = jQuery(this).closest('[data-term-id]');
1764					if ($li) {
1765						var $synchroInput = $synchroFilters.find('[data-term-id="'+$li.attr('data-term-id')+'"] input');
1766						if ($synchroInput.length == 0 && filterDisplay == 'colors') $synchroInput = $synchroFilters.find('input[data-term-id="'+$li.attr('data-term-id')+'"]');
1767						if ($synchroInput.length) $synchroInput.prop('checked', true).trigger('wpf-synchro');
1768					}
1769				});
1770				if (filterType === 'wpfPrice'){
1771					var min = $filter.find('#wpfMinPrice').val(),
1772						max = $filter.find('#wpfMaxPrice').val();
1773					$synchroFilters.each(function() {
1774						var $slider = jQuery(this);
1775						$slider.find('#wpfMinPrice').val(min);
1776						$slider.find('#wpfMaxPrice').val(max);
1777					});
1778				} else if (filterDisplay == 'mul_dropdown') {
1779					$synchroFilters.find('select').val($filter.find('select').val());
1780					$synchroFilters.find('select.jqmsLoaded').multiselect('reload');
1781				} else if(filterDisplay == 'text') {
1782					$synchroFilters.find('input').val($filter.find('input').val());
1783				} else {
1784					var value = $filter.find('select').val();
1785					$synchroFilters.find('select').each(function() {
1786						if (jQuery(this).find('option[value="'+value+'"]').length) jQuery(this).val(value);
1787					});
1788				}
1789
1790				if(typeof(_thisObj.syncronizeFiltersPro) == 'function') {
1791					_thisObj.syncronizeFiltersPro($filter, $synchroFilters);
1792				}
1793
1794				if ($filter.hasClass('wpfNotActive')) $synchroFilters.addClass('wpfNotActive');
1795				else $synchroFilters.removeClass('wpfNotActive');
1796			}
1797
1798		});
1799
1800	});
1801
1802	WpfFrontendPage.prototype.clearFilters = (function (filter, clearAll) {
1803		var _thisObj = this.$obj,
1804			noWooPage = _thisObj.noWoo,
1805			clearAll = typeof clearAll == 'undefined' ? false : true;
1806
1807		(filter ? filter : jQuery('.wpfFilterWrapper')).each(function () {
1808			var $filter = jQuery(this),
1809				$filterWrapper = $filter.closest('.wpfMainWrapper'),
1810				filterAttribute = $filter.attr('data-get-attribute'),
1811				filterType = $filter.attr('data-display-type'),
1812				defValue = $filter.attr('data-filter-default');
1813			if (typeof defValue === 'undefined') {
1814				defValue = '';
1815			}
1816
1817			filterAttribute = filterAttribute.split(",");
1818			var count = filterAttribute.length;
1819			for(var i = 0; i < count; i++){
1820				_thisObj.QStringWork(filterAttribute[i], '', noWooPage, $filterWrapper, 'remove');
1821			}
1822
1823			if($filter.hasClass('wpfHidden')){
1824				$filter.removeClass('wpfNotActive');
1825			} else {
1826				$filter.find('input').prop('checked', false);
1827
1828				if(filterType == 'mul_dropdown') {
1829					$filter.find('select').val('');
1830					$filter.find('select.jqmsLoaded').multiselect('reload');
1831				} else if(filterType == 'text') {
1832					$filter.find('input').val('');
1833				} else {
1834					$filter.find("select").val($filter.find("select option:first").val());
1835				}
1836				if (defValue.length && clearAll) {
1837					if(filterType == 'dropdown') {
1838						$filter.find('select').val($filter.find('select option[data-term-slug="'+defValue+'"]').val());
1839					} else {
1840						$filter.find('li[data-term-slug="'+defValue+'"] input').prop('checked', true);
1841					}
1842					$filter.removeClass('wpfNotActive');
1843				} else {
1844					$filter.addClass('wpfNotActive');
1845				}
1846			}
1847
1848			if($filter.attr('data-filter-type') === 'wpfPrice'){
1849				var min = $filter.find('#wpfMinPrice').attr('min'),
1850					max = $filter.find('#wpfMaxPrice').attr('max');
1851				$filter.find('#wpfMinPrice').val(min);
1852				$filter.find('#wpfMaxPrice').val(max);
1853
1854				jQuery( "#wpfSliderRange" ).slider( "option", "values", [ min, max ] );
1855			}
1856
1857			if(typeof(_thisObj.clearFiltersPro) == 'function') {
1858				_thisObj.clearFiltersPro($filter);
1859			}
1860			if(typeof(_thisObj.eventChangeFilterPro) == 'function') {
1861				_thisObj.eventChangeFilterPro($filter);
1862			}
1863			if(clearAll) {
1864				_thisObj.QStringWork('wpf_order', '', noWooPage, $filterWrapper, 'remove');
1865				_thisObj.QStringWork('wpf_count', '', noWooPage, $filterWrapper, 'remove');
1866				_thisObj.QStringWork('all_products_filtering', '', noWooPage, $filterWrapper, 'remove');
1867				_thisObj.QStringWork('wpf_oistock', '', noWooPage, $filterWrapper, 'remove');
1868				_thisObj.QStringWork('wpf_fbv', '', noWooPage, $filterWrapper, 'remove');
1869				_thisObj.QStringWork('wpf_dpv', '', noWooPage, $filterWrapper, 'remove');
1870				_thisObj.QStringWork('wpf_ebv', '', noWooPage, $filterWrapper, 'remove');
1871			}
1872		});
1873
1874		_thisObj.markCheckboxSelected(filter);
1875	});
1876
1877	/**
1878	 * getFilterMainSettings.
1879	 *
1880	 * @version 3.3.0
1881	 */
1882	WpfFrontendPage.prototype.getFilterMainSettings = (
1883		function ( $selector ) {
1884			var settingsStr = $selector.attr( 'data-filter-settings' );
1885			if ( ! settingsStr ) {
1886				return false;
1887			}
1888			try {
1889				var settings = JSON.parse( settingsStr );
1890			} catch ( e ) {
1891				var settings = false;
1892			}
1893			if ( settings === false ) {
1894				settingsStr = settingsStr.replace( '}]"', '}]' ).replace( '"[{', '[{' );
1895				try {
1896					settings = JSON.parse( settingsStr );
1897				} catch ( e ) {
1898					settings = false;
1899				}
1900			}
1901			return settings;
1902		}
1903	);
1904
1905	WpfFrontendPage.prototype.getFilterParam = (function (paramSlug, mainWrapper, filterWrapper) {
1906		var paramValue = null,
1907			_thisObj = this.$obj,
1908			mainSettings = _thisObj.getFilterMainSettings(mainWrapper),
1909			orderKey = filterWrapper.attr('data-order-key');
1910		if (mainSettings.settings.filters.order && typeof orderKey !== undefined) {
1911			var filtersOderList = JSON.parse(mainSettings.settings.filters.order);
1912			if ( typeof filtersOderList[orderKey] !== undefined ) {
1913				var filterParamList = filtersOderList[orderKey].settings;
1914				if ( typeof filterParamList[paramSlug] !== undefined ) {
1915					paramValue = filterParamList[paramSlug];
1916				}
1917			}
1918		}
1919		return paramValue;
1920	});
1921
1922	WpfFrontendPage.prototype.checkNoWooPage = (function () {
1923		var noWooPage = false;
1924		if(jQuery('.wpfMainWrapper').first().attr('data-nowoo')){
1925			noWooPage = true;
1926		}
1927		return noWooPage;
1928	});
1929
1930	WpfFrontendPage.prototype.changeLmpButton = (function () {
1931		var lmpBtn = jQuery('.br_lmp_button_settings .lmp_button');
1932		if (lmpBtn.length) {
1933			var parentStyle = lmpBtn.parent().attr('style').replace(' ', '');
1934			if (parentStyle.indexOf('display:none') > -1) {
1935				return;
1936			}
1937			var url = lmpBtn.attr('href').split('?')[0];
1938			url += window.location.search;
1939			url = url.indexOf('/page/2') > -1 ? url : url.replace(/\/page\/[0-9]{1,}/ig, '/page/2');
1940			lmpBtn.attr('href', url);
1941			setTimeout(function(){
1942				jQuery('.woocommerce-pagination').addClass('wpfHidden');
1943			}, 1000);
1944		}
1945	});
1946
1947	WpfFrontendPage.prototype.changeUrlByFilterParams = (function ($filtersDataFrontend) {
1948		var _thisObj = this.$obj,
1949			noWooPage = _thisObj.noWoo;
1950		if (typeof $filtersDataFrontend !== 'undefined' && $filtersDataFrontend.length > 0) {
1951			// the array is defined and has at least one element
1952			var count = $filtersDataFrontend.length,
1953				filterWrapper = jQuery('.wpfMainWrapper'),
1954				priceFlag = true;
1955			for(var i = 0; i < count; i++){
1956				switch ($filtersDataFrontend[i]['id']){
1957					case 'wpfPrice':
1958					case 'wpfPriceRange':
1959						if (priceFlag) {
1960							var minPrice = $filtersDataFrontend[i]['settings']['wpf_min_price'],
1961								maxPrice = $filtersDataFrontend[i]['settings']['wpf_max_price'],
1962								tax = $filtersDataFrontend[i]['settings']['tax'];
1963
1964							if (typeof minPrice !== 'undefined' && minPrice.length > 0) {
1965								_thisObj.QStringWork('wpf_min_price', minPrice, noWooPage, filterWrapper, 'change');
1966							} else {
1967								_thisObj.QStringWork('wpf_min_price', '', noWooPage, filterWrapper, 'remove');
1968							}
1969							if (typeof maxPrice !== 'undefined' && maxPrice.length > 0) {
1970								_thisObj.QStringWork('wpf_max_price', maxPrice, noWooPage, filterWrapper, 'change');
1971							} else {
1972								_thisObj.QStringWork('wpf_max_price', '', noWooPage, filterWrapper, 'remove');
1973							}
1974							if (typeof tax !== 'undefined') {
1975								_thisObj.QStringWork('tax', tax, noWooPage, filterWrapper, 'change');
1976							} else {
1977								_thisObj.QStringWork('tax', '', noWooPage, filterWrapper, 'remove');
1978							}
1979							priceFlag = false;
1980						}
1981						break;
1982					case 'wpfSortBy':
1983						var orderby = $filtersDataFrontend[i]['settings']['orderby'],
1984							oistock = $filtersDataFrontend[i]['settings']['oistock'];
1985						if (typeof orderby !== 'undefined' && orderby.length > 0 ) {
1986							_thisObj.QStringWork('orderby', orderby, noWooPage, filterWrapper, 'change');
1987						}else{
1988							_thisObj.QStringWork('orderby', '', noWooPage, filterWrapper, 'remove');
1989						}
1990						if (typeof oistock !== 'undefined' && oistock == 1 ) {
1991							_thisObj.QStringWork('wpf_oistock', 1, noWooPage, filterWrapper, 'change');
1992						}else{
1993							_thisObj.QStringWork('wpf_oistock', '', noWooPage, filterWrapper, 'remove');
1994						}
1995						break;
1996					case 'wpfCategory':
1997					case 'wpfPerfectBrand':
1998						var product_cat = $filtersDataFrontend[i]['settings']['settings'],
1999							name = $filtersDataFrontend[i]['name'],
2000							delim = $filtersDataFrontend[i]['delim'];
2001						product_cat = product_cat.join(delim ? delim : '|');
2002						if (typeof product_cat !== 'undefined' && product_cat.length > 0) {
2003							_thisObj.QStringWork(name, product_cat, noWooPage, filterWrapper, 'change');
2004						}else{
2005							_thisObj.QStringWork(name, '', noWooPage, filterWrapper, 'remove');
2006						}
2007						break;
2008					case 'wpfTags':
2009						var product_tag = $filtersDataFrontend[i]['settings']['settings'],
2010							name = $filtersDataFrontend[i]['name'],
2011							delim = $filtersDataFrontend[i]['delim'];
2012						product_tag = product_tag.join(delim ? delim : '|');
2013						if (typeof product_tag !== 'undefined' && product_tag.length > 0) {
2014							_thisObj.QStringWork(name, product_tag, noWooPage, filterWrapper, 'change');
2015						}else{
2016							_thisObj.QStringWork(name, '', noWooPage, filterWrapper, 'remove');
2017						}
2018						break;
2019					case 'wpfCustomField':
2020						var name  = $filtersDataFrontend[i]['name'];
2021						var delim = $filtersDataFrontend[i]['delim'] || '|';
2022						// Your custom field stores frontend settings as: settings[name] = "A|B"
2023						// (not as settings.settings = ["A","B"])
2024						var settingsObj = $filtersDataFrontend[i]['settings'] || {};
2025						var cfValues = (typeof settingsObj.settings !== 'undefined')
2026							? settingsObj.settings
2027							: settingsObj[name];
2028
2029						if (Array.isArray(cfValues)) {
2030							cfValues = cfValues.join(delim);
2031						}
2032
2033						if (typeof cfValues === 'string' && cfValues.length > 0) {
2034							_thisObj.QStringWork(name, cfValues, noWooPage, filterWrapper, 'change');
2035						} else {
2036							_thisObj.QStringWork(name, '', noWooPage, filterWrapper, 'remove');
2037						}
2038						break;
2039					case 'wpfAttribute':
2040						var product_taxonomy = $filtersDataFrontend[i]['settings']['taxonomy'],
2041							product_attr = $filtersDataFrontend[i]['settings']['settings'],
2042							delim = $filtersDataFrontend[i]['delim'];
2043						product_attr = product_attr.join(delim ? delim : '|');
2044						if (typeof product_attr !== 'undefined' && product_attr.length > 0) {
2045							_thisObj.QStringWork(product_taxonomy, product_attr, noWooPage, filterWrapper, 'change');
2046						}else{
2047							_thisObj.QStringWork(product_taxonomy, '', noWooPage, filterWrapper, 'remove');
2048						}
2049
2050						if (typeof $filtersDataFrontend[i]['idBlock']!== 'undefined' && typeof $filtersDataFrontend[i]['idFilter']!== 'undefined' ) {
2051							_thisObj.QStringWork('group' + product_taxonomy.replace('filter', '') + $filtersDataFrontend[i]['idBlock'], $filtersDataFrontend[i]['idFilter'], noWooPage, filterWrapper, 'change');
2052						}
2053						break;
2054					case 'wpfAuthor':
2055						var authorVal = $filtersDataFrontend[i]['settings']['settings'],
2056							name = $filtersDataFrontend[i]['name'],
2057							delim = $filtersDataFrontend[i]['delim'];
2058							authorVal = authorVal.join(delim ? delim : '|');
2059						if (typeof authorVal !== 'undefined' && authorVal.length > 0) {
2060							_thisObj.QStringWork('pr_author', authorVal, noWooPage, filterWrapper, 'change');
2061						}else{
2062							_thisObj.QStringWork('pr_author', '', noWooPage, filterWrapper, 'remove');
2063						}
2064						break;
2065					case 'wpfFeatured':
2066						var featureVal = $filtersDataFrontend[i]['settings']['settings'];
2067						if (typeof featureVal !== 'undefined' && featureVal.length > 0) {
2068							_thisObj.QStringWork('pr_featured', featureVal, noWooPage, filterWrapper, 'change');
2069						}else{
2070							_thisObj.QStringWork('pr_featured', '', noWooPage, filterWrapper, 'remove');
2071						}
2072						break;
2073					case 'wpfOnSale':
2074						var onSaleVal = $filtersDataFrontend[i]['settings']['settings'];
2075						if (typeof onSaleVal !== 'undefined' && onSaleVal.length > 0) {
2076							_thisObj.QStringWork('pr_onsale', onSaleVal, noWooPage, filterWrapper, 'change');
2077						}else{
2078							_thisObj.QStringWork('pr_onsale', '', noWooPage, filterWrapper, 'remove');
2079						}
2080						break;
2081					case 'wpfInStock':
2082						var pr_stock = $filtersDataFrontend[i]['settings']['settings'];
2083						pr_stock = pr_stock.join(delim ? delim : '|');
2084						if (typeof pr_stock !== 'undefined' && pr_stock.length > 0 ) {
2085							_thisObj.QStringWork('pr_stock', pr_stock, noWooPage, filterWrapper, 'change');
2086						}else{
2087							_thisObj.QStringWork('pr_stock', '', noWooPage, filterWrapper, 'remove');
2088						}
2089						break;
2090					case 'wpfRating':
2091						var ratingVal = $filtersDataFrontend[i]['settings']['settings'];
2092						if (typeof ratingVal !== 'undefined' && checkArray(ratingVal) && ratingVal.length > 0 ) {
2093							_thisObj.QStringWork('pr_rating', ratingVal, noWooPage, filterWrapper, 'change');
2094						}else{
2095							_thisObj.QStringWork('pr_rating', '', noWooPage, filterWrapper, 'remove');
2096						}
2097						break;
2098					default:
2099						if(typeof(_thisObj.changeUrlByFilterParamsPro) == 'function') {
2100							_thisObj.changeUrlByFilterParamsPro($filtersDataFrontend[i], noWooPage, filterWrapper);
2101						}
2102						break;
2103				}
2104			}
2105		}else{
2106			return false;
2107		}
2108
2109	});
2110
2111	/**
2112	 * changeSlugByUrl.
2113	 *
2114	 * @version 2.8.6
2115	 */
2116	WpfFrontendPage.prototype.changeSlugByUrl = (function () {
2117		jQuery('.wpfSlugWrapper .wpfSlug').remove();
2118		var _thisObj = this.$obj,
2119			noWooPage = _thisObj.noWoo,
2120			searchParams = jQuery.toQueryParams(window.location.search);
2121		if (noWooPage) {
2122			if( jQuery('.wpfMainWrapper').first().attr('data-hide-url')) {
2123				searchParams =  jQuery.toQueryParams(jQuery('.wpfMainWrapper').first().attr('data-hide-url'));
2124			}
2125		}
2126
2127		var isRedirect = 'redirect' in searchParams && searchParams['redirect'] == 1;
2128
2129		for (var key in searchParams) {
2130			if(key === 'wpf_min_price'){
2131				key = 'wpf_min_price,wpf_max_price,tax';
2132			}
2133			var $elem = jQuery('.wpfFilterWrapper[data-get-attribute="'+key+'"]');
2134			if (!$elem.length && isRedirect) {
2135				var parts = key.split('_'),
2136					cnt = parts.length;
2137				if (cnt > 2 && isNumber(parts[cnt-1])) {
2138					parts.pop();
2139					$elem = jQuery('.wpfFilterWrapper[data-get-attribute^="'+parts.join('_')+'"]');
2140					_thisObj.QStringWork(key, '', false, $elem.closest('.wpfMainWrapper'), 'remove');
2141
2142				}
2143			}
2144			if($elem.length > 0) {
2145				var elem = $elem.first(),
2146					$slug = elem.attr('data-slug'),
2147					$label = elem.attr('data-label'),
2148					$title = elem.attr('data-title'),
2149					$getAttr = elem.attr('data-get-attribute'),
2150					$filterType = elem.attr('data-filter-type');
2151				if(typeof $title != 'undefined') $label = $title;
2152				else if(typeof $label == 'undefined') $label = $slug;
2153
2154				var html = '';
2155				if(jQuery('.wpfSlugWrapper').length > 0){
2156					if( !jQuery('.wpfSlugWrapper .wpfSlug[data-slug="'+$slug+'"]').length > 0 ) {
2157						html += '<div class="wpfSlug" data-slug="'+$slug+'" data-get-attribute="'+$getAttr+'" data-filter-type="'+$filterType+'"><div class="wpfSlugTitle">'+$label+'</div><div class="wpfSlugDelete">x</div></div>';
2158						jQuery('.wpfSlugWrapper').append(html);
2159					}
2160				}else{
2161					if( !jQuery('.wpfSlugWrapper .wpfSlug[data-slug="'+$slug+'"]').length > 0 ) {
2162						html += '<div class="wpfSlugWrapper">';
2163						html += '<div class="wpfSlug" data-slug="'+$slug+'" data-get-attribute="'+$getAttr+'" data-filter-type="'+$filterType+'"><div class="wpfSlugTitle">'+$label+'</div><div class="wpfSlugDelete">x</div></div>';
2164						html += '</div>';
2165						jQuery('.storefront-sorting').append(html);
2166					}
2167				}
2168			}
2169			if (isRedirect && history.pushState && app.wpfNewUrl != window.wpfOldUrl)  {
2170				history.pushState({state: 1, rand: Math.random(), wpf: true}, '', app.wpfNewUrl);
2171				app.wpfOldUrl = app.wpfNewUrl;
2172			}
2173		}
2174
2175	});
2176
2177	WpfFrontendPage.prototype.sendFiltersOptionsByAjax = (function ($filtersDataBackend, $queryVars, $filterSettings, $generalSettings, $woocommerceSettings, $shortcodeAttr) {
2178		var _thisObj = this.$obj,
2179			$wrapperSettings = [];
2180		if ( window.wpfAdminPage ) {
2181			return false;
2182		}
2183		_thisObj.currentAjaxJSLoaded = false;
2184		_thisObj.currentProductBlock = false;
2185
2186		if (_thisObj.filterLoadTypes[_thisObj.currentLoadId] && _thisObj.filterLoadTypes[_thisObj.currentLoadId] == 'reload') {
2187			location.reload();
2188			return;
2189		}
2190		var ajax_leave_products = $generalSettings && $generalSettings['settings'] && $generalSettings['settings']['ajax_leave_products'] == '1'
2191
2192		if (typeof $generalSettings !== 'undefined') {
2193			$wrapperSettings = $generalSettings['settings'];
2194		}
2195
2196		var customListSelector = $filterSettings['product_list_selector'],
2197			productListSelector = _thisObj.fixSelector(customListSelector, _thisObj.defaultProductSelector),
2198			productContainerSelector = _thisObj.fixSelector($filterSettings['product_container_selector'], ''),
2199			forceThemeTemplates = ($wrapperSettings['force_theme_templates'] == 1);
2200
2201		var productContainerElem = (productContainerSelector !== '')
2202			? jQuery(productContainerSelector)
2203			: jQuery(document);
2204
2205		if (productContainerElem.length === 0) {
2206			location.reload();
2207			return;
2208		}
2209
2210		var productListElem = jQuery(productListSelector, productContainerElem);
2211		if (productListElem.hasClass('wpfNoWooPage') || productListElem.closest('.wpfNoWooPage').length) {
2212			forceThemeTemplates = false;
2213		}
2214
2215		if (productListElem.length && (_thisObj.filterClick)) {
2216			if (_thisObj.enableFiltersLoaderPro && ajax_leave_products) {
2217				_thisObj.enableFiltersLoaderPro(_thisObj.currentLoadId, productListElem);
2218			} else {
2219				_thisObj.enableFiltersLoader(_thisObj.currentLoadId, productListElem);
2220			}
2221		}
2222
2223		var onlyRecount = false;
2224		if ($filterSettings === undefined) {
2225			$filterSettings = [];
2226		} else {
2227			if (!_thisObj.filterClick && $filterSettings.auto_update_filter && !$filterSettings.redirect_only_click) {
2228				onlyRecount = true;
2229			}
2230		}
2231
2232		var requestData =_thisObj.getAjaxRequestData($filtersDataBackend, $queryVars, $filterSettings, $generalSettings, $shortcodeAttr, $woocommerceSettings);
2233
2234		if (onlyRecount) {
2235			_thisObj.ajaxOnlyRecount(requestData, _thisObj.currentLoadId, $wrapperSettings);
2236			return;
2237		} else if (forceThemeTemplates || _thisObj.filterLoadTypes[_thisObj.currentLoadId] == 'force') {
2238			_thisObj.ajaxForceThemeTemplates(productContainerSelector, productListSelector, requestData, $wrapperSettings);
2239			return;
2240		}
2241
2242		/**
2243		 * There are some cases when we do not provide ajax functionlity
2244		 */
2245		if ( window.InfiniteScroll && window.InfiniteScroll.prototype ) {
2246			/**
2247			 * Flatsome theme compatibility
2248			 * We do not provide ajax functionality with infinite scroll
2249			 *
2250			 * @link https://themeforest.net/item/flatsome-multipurpose-responsive-woocommerce-theme/5484319
2251			 */
2252			if (_thisObj.filterClick && jQuery('body').hasClass('theme-flatsome')) {
2253				location.reload();
2254				return;
2255			}
2256		}
2257		_thisObj.filterLoadTypes[_thisObj.currentLoadId] = 'ajax';
2258
2259		jQuery.sendFormWpf({
2260			data: requestData,
2261			onSuccess: function(res) {
2262				if (!res.error) {
2263					if ('fid' in res.data && toeInArray(res.data['fid'], _thisObj.lastFids) == -1) {
2264						return false;
2265					}
2266					if ('optionsHtml' in res.data) {
2267						var optionsHtml = res.data['optionsHtml'];
2268
2269						jQuery('.wpfMainWrapper .wpfFilterWrapper[data-order-key]').each(function() {
2270							var $filter = jQuery(this),
2271								orderKey = $filter.attr('data-order-key'),
2272								$select = $filter.find('select');
2273
2274							if (typeof optionsHtml[orderKey] !== 'undefined' && $select.length){
2275								var selectedValues = [];
2276								$select.find('option:selected').each(function() {
2277									selectedValues.push(jQuery(this).val());
2278								});
2279
2280								$select.html(optionsHtml[orderKey]);
2281
2282								if (selectedValues.length) {
2283									$select.val(selectedValues);
2284								}
2285
2286							}
2287						});
2288					}
2289					if ( res.data.filter_state ) {
2290						let state = res.data.filter_state;
2291
2292						wpfShowHideFiltersAtts(
2293							state.exists,
2294							state.existsUsers,
2295							state.synchroId
2296						);
2297
2298						if ( state.recount ) {
2299							wpfChangeFiltersCount(
2300								state.exists,
2301								state.synchroId
2302							);
2303						}
2304
2305						if ( state.fid ) {
2306							wpfDoActionsAfterLoad(
2307								state.fid,
2308								state.havePosts ? 1 : 0
2309							);
2310						}
2311
2312						if ( state.prices ) {
2313							wpfChangePriceFiltersCount( state.prices );
2314						}
2315					}
2316					if (_thisObj.filterClick) {
2317						if (customListSelector !== '' && productListElem.length) {
2318							var loopContainer = productListElem;
2319							loopContainer.html(res.data['productHtml']);
2320						} else {
2321							var catSelector = wpfGetSelector(res.data['categoryHtml'], true, _thisObj.defaultProductSelector, 1, false, productContainerElem),
2322								loopSelector = wpfGetSelector(res.data['loopStartHtml'], true, _thisObj.defaultProductSelector, 3, false, productContainerElem),
2323								loopContainer = jQuery(loopSelector, productContainerElem);
2324
2325							if (!loopContainer.length) {
2326								// trying to obtain loop container without dynamically change classes with numbers in it names
2327								loopSelector = wpfGetSelector(res.data['loopStartHtml'], true, _thisObj.defaultProductSelector, 3, true, productContainerElem);
2328								loopContainer = jQuery(loopSelector, productContainerElem);
2329							}
2330
2331							loopContainer.prev('.brand-description').remove();
2332							if (typeof res.data['beforeProductHtml'] !== 'undefined') {
2333								loopContainer.before('<div class="brand-description">' + res.data['beforeProductHtml'] + '</div>');
2334							}
2335							if (typeof jQuery('.product-categories-wrapper', productContainerElem) !== 'undefined' && jQuery('.product-categories-wrapper > ul.products', productContainerElem).length > 0) {
2336								//replace cats html
2337								if (res.data['categoryHtml'].length) {
2338									jQuery('.product-categories-wrapper > ul.products', productContainerElem).html(res.data['categoryHtml']);
2339								}
2340								//replace products html
2341								jQuery(_thisObj.defaultProductSelector, productContainerElem).eq(1).html(res.data['productHtml']);
2342							} else if (jQuery('.elementor-widget-container ul.products', productContainerElem).length > 0) {
2343								jQuery('.elementor-widget-container ul.products', productContainerElem).each(function () {
2344									if (!jQuery(this).find('.product-category').length) {
2345										jQuery(this).html(res.data['categoryHtml'] + res.data['productHtml']);
2346									}
2347								});
2348							} else if (jQuery('.woocommerce > .products[data-filterargs][data-innerargs]', productContainerElem).length > 0) {
2349								jQuery('.woocommerce > .products[data-filterargs][data-innerargs]', productContainerElem).html(res.data['categoryHtml'] + res.data['productHtml']);
2350							} else {
2351								if (!loopContainer.length) {
2352									if (!jQuery('.wpfMainWrapper', productContainerElem).attr('data-nowoo') !== typeof undefined
2353										&& !jQuery('.wpfMainWrapper', productContainerElem).attr('data-nowoo') !== false)
2354										_thisObj.ajaxForceThemeTemplates(productContainerSelector, productListSelector, requestData, $wrapperSettings);
2355									else {
2356										location.reload(true);
2357									}
2358									_thisObj.afterAjaxFiltering($wrapperSettings);
2359									return false;
2360								}
2361
2362								loopContainer.each(function () {
2363									//replace cats html
2364									jQuery(this).html(res.data['categoryHtml']);
2365									//replace products html
2366									jQuery(this).append(res.data['productHtml']);
2367								});
2368							}
2369						}
2370
2371						var countSelector = wpfGetSelector(res.data['resultCountHtml'], true, '.woocommerce-result-count', 1, false, productContainerElem),
2372							wooCount = jQuery(countSelector, productContainerElem);
2373						if (wooCount.length > 0) {
2374							wooCount.replaceWith(res.data['resultCountHtml']);
2375						}
2376
2377						var isLeerPagination = res.data['paginationHtml'] == '',
2378							paginationSelector = wpfGetSelector(res.data[isLeerPagination ? 'paginationLeerHtml' : 'paginationHtml'], false, '.woocommerce-pagination', 1, false, productContainerElem),
2379							wooPagination = jQuery(paginationSelector, productContainerElem),
2380							newPagination = res.data['paginationHtml'];
2381
2382						if (wooPagination.length > 0) {
2383							if (typeof _thisObj.paginationClasses == 'undefined') {
2384								_thisObj.paginationClasses = wooPagination.attr('class');
2385							}
2386							if (isLeerPagination) {
2387								wooPagination.css({'display': 'none'});
2388								wooPagination.empty();
2389							} else {
2390								wooPagination.replaceWith(newPagination);
2391							}
2392						} else if (!isLeerPagination) {
2393							var afterLoop = jQuery('.after-shop-loop', productContainerElem);
2394							if (afterLoop.length > 0) {
2395								afterLoop.prepend(newPagination);
2396							} else {
2397								wooCount = jQuery('.storefront-sorting ' + countSelector, productContainerElem);
2398								if (wooCount.length > 0) {
2399									wooCount.after(newPagination);
2400								} else {
2401									let shortcodeData = productContainerElem.find('span[data-shortcode-attribute]'),
2402										isPaginate = shortcodeData.length ? shortcodeData.data('shortcode-attribute').paginate : true;
2403									if (typeof isPaginate === 'undefined' || isPaginate) {
2404										loopContainer.eq(0).after(newPagination);
2405									}
2406								}
2407							}
2408						}
2409						if (typeof _thisObj.paginationClasses != 'undefined') {
2410							jQuery(paginationSelector, productContainerElem).attr('class', _thisObj.paginationClasses);
2411						}
2412						_thisObj.currentProductBlock = loopContainer.selector;
2413						if (!_thisObj.currentProductBlock) {
2414							loopContainer.addClass('wpfCurrentProductBlock');
2415							_thisObj.currentProductBlock = '.wpfCurrentProductBlock';
2416						}
2417					}
2418
2419					_thisObj.afterAjaxFiltering($wrapperSettings);
2420					jQuery('.wpfLoaderLayout').hide();
2421				}
2422			}
2423		});
2424	});
2425
2426	WpfFrontendPage.prototype.ajaxForceThemeTemplates = (function (productContainerSelector, productListSelector, requestData, $wrapperSettings) {
2427		var _thisObj = this.$obj,
2428			curUrl = window.location.href,
2429			isContainer = (productContainerSelector != '');
2430
2431		_thisObj.filterLoadTypes[_thisObj.currentLoadId] = 'force';
2432
2433		jQuery.ajax({
2434			type: "GET",
2435			url: curUrl + (curUrl.indexOf('?') == -1 ? '?' : '&') + 'wpf_skip=1&wpf_fid=' + _thisObj.filteringId,
2436			cache: false,
2437			dataType: 'html',
2438			success: function(data){
2439				var block = '',
2440					foundContainer = false,
2441					noProducts = false,
2442					$loadedData = jQuery(data),
2443					$loadedJS = $loadedData.find('.wpfExistsTermsJS');
2444				if ($loadedJS.length) {
2445					if (toeInArray($loadedJS.eq(0).attr('data-fid'), _thisObj.lastFids) == -1) {
2446						return false;
2447					}
2448				}
2449
2450				if (isContainer) {
2451					block = jQuery(data).find(productContainerSelector);
2452				}
2453				if (block.length) {
2454					foundContainer = true;
2455				} else {
2456					block = jQuery(data).find(productListSelector);
2457				}
2458				var pageBlock = jQuery(isContainer && (foundContainer || block.length == 0) ? productContainerSelector : productListSelector);
2459				if (block.length == 0 || pageBlock.length == 0) {
2460					if ($wrapperSettings.recalculate_filters === '1') {
2461						var existsTermsJS = jQuery(data).find('.wpfExistsTermsJS').html();
2462						_thisObj.setAjaxJScript(existsTermsJS);
2463					}
2464					if ($wrapperSettings.no_redirect_by_no_products === '1' && pageBlock.length > 0) {
2465						block = jQuery('<div><div class="wpfNoProducts">' + $wrapperSettings.text_no_products + '</div></div>');
2466						noProducts = true;
2467					} else {
2468						_thisObj.filterLoadTypes[_thisObj.currentLoadId] = 'reload';
2469						location.reload();
2470						return;
2471					}
2472				}
2473				if ($wrapperSettings.recalculate_filters !== '1') {
2474					_thisObj.ajaxOnlyRecount(requestData);
2475				}
2476
2477				_thisObj.currentProductBlock = (typeof pageBlock.selector !== 'undefined') ? pageBlock.selector : productListSelector ;
2478
2479				block.each(function (index, value) {
2480					var blockWhere = pageBlock.eq(index),
2481						blockWhat = jQuery(value);
2482
2483					if (!foundContainer && !noProducts) {
2484						blockWhere = blockWhere.parent();
2485						blockWhat = blockWhat.parent();
2486					}
2487					// some plugins save url parameters in input fields
2488					blockWhat.find('input[name="wpf_skip"]').remove();
2489
2490					blockWhere.html(blockWhat.html().replace(/wpf_skip=1/g, '').replace(/wpf_fid=[0-9]*/g, '').replace(/&amp;&amp;/g, '&amp;'));
2491
2492					// if pagination is not in the block to be replaced, we will try to find and replace it
2493					var paginationPageBlock = jQuery(blockWhere).find('.woocommerce-pagination');
2494					if (!paginationPageBlock.length) {
2495						var paginationPage = jQuery('.woocommerce-pagination');
2496						var paginationResponse = jQuery(data).find('.woocommerce-pagination');
2497						if (paginationResponse.length) {
2498							paginationResponse = paginationResponse.eq(0).html().replace(/wpf_skip=1/g, '').replace(/wpf_fid=[0-9]*/g, '').replace(/&amp;&amp;/g, '&amp;');
2499							if (paginationPage.length) {
2500								paginationPage.html(paginationResponse);
2501							} else {
2502								jQuery(blockWhere).parent().after('<nav class="woocommerce-pagination">' + paginationResponse + '</nav>');
2503							}
2504						} else if (paginationPage.length) {
2505							paginationPage.remove();
2506						}
2507					}
2508
2509					// if result count is not in the block to be replaced, we will try to find and replace it
2510					var resultCountBlock = jQuery(blockWhere).find('.woocommerce-result-count');
2511					var resultCountResponse = jQuery(data).find('.woocommerce-result-count');
2512					if (!resultCountBlock.length && resultCountResponse.length) {
2513						var resultCount = jQuery('.woocommerce-result-count');
2514						if (resultCount.length) {
2515							resultCount.replaceWith(resultCountResponse);
2516						}
2517					}
2518				});
2519				// for Divi archive loop
2520				var $styleObj = jQuery('style[id^="et-builder-module-design-"]');
2521				if ($styleObj.length == 1) {
2522					var $styleObjLoaded = $loadedData.find('style[id^="et-builder-module-design-"]');
2523					if ($styleObjLoaded.length == 0) $styleObjLoaded = $loadedData.filter('style[id^="et-builder-module-design-"]');
2524					if ($styleObjLoaded.length == 1) $styleObj.html($styleObjLoaded.html());
2525				}
2526
2527				_thisObj.afterAjaxFiltering($wrapperSettings);
2528				_thisObj.runReadyList();
2529				if ($wrapperSettings.recalculate_filters === '1') {
2530					var existsTermsJS = jQuery(data).find('.wpfExistsTermsJS').html();
2531					_thisObj.setAjaxJScript(existsTermsJS);
2532				}
2533
2534			}
2535		});
2536
2537		return false;
2538	});
2539
2540	WpfFrontendPage.prototype.ajaxOnlyRecount = (function (requestData, filterId, $wrapperSettings) {
2541		var _thisObj = this.$obj;
2542
2543		if (!_thisObj.currentAjaxJSLoaded && requestData) {
2544			requestData['only_recound'] = 1;
2545
2546			if (typeof filterId !==  'undefined') {
2547				requestData['synchro_filter_id'] = filterId;
2548			}
2549
2550			jQuery.sendFormWpf({
2551				data: requestData,
2552				onSuccess: function (res) {
2553
2554					if (typeof $wrapperSettings !== 'undefined'
2555						&& typeof $wrapperSettings.filter_loader_icon_onload_enable !== 'undefined'
2556						&& Number($wrapperSettings.filter_loader_icon_onload_enable)) {
2557						hideFilterLoader(jQuery('#' + filterId));
2558					}
2559
2560					if ( ! res.error && res.data && res.data.filter_state ) {
2561						const state = res.data.filter_state;
2562
2563						wpfShowHideFiltersAtts(
2564							state.exists,
2565							state.existsUsers,
2566							state.synchroId
2567						);
2568
2569						if ( state.recount ) {
2570							wpfChangeFiltersCount(
2571								state.exists,
2572								state.synchroId
2573							);
2574						}
2575
2576						if ( state.fid ) {
2577							wpfDoActionsAfterLoad(
2578								state.fid,
2579								state.havePosts ? 1 : 0
2580							);
2581						}
2582
2583						if ( state.prices ) {
2584							wpfChangePriceFiltersCount( state.prices );
2585						}
2586					}
2587					_thisObj.removeOverlay();
2588				}
2589			});
2590		}
2591
2592	});
2593
2594	WpfFrontendPage.prototype.setAjaxJScript = (function(jscript, filterId){
2595		var _thisObj = this.$obj,
2596			filter = jQuery('#' + (typeof(filterId) == 'undefined' ? _thisObj.currentLoadId : filterId));
2597		if (filter.length && jscript != '') {
2598			var jsBlock = filter.find('.wpfAjaxJSBlock');
2599			if (jsBlock.length == 0) {
2600				jQuery('<div class="wpfAjaxJSBlock wpfHidden"></div>').appendTo(filter);
2601			}
2602			filter.find('.wpfAjaxJSBlock').html(jscript);
2603		}
2604		_thisObj.currentAjaxJSLoaded = true;
2605	});
2606
2607	WpfFrontendPage.prototype.afterAjaxFiltering = (function($wrapperSettings){
2608		var _thisObj = this.$obj;
2609
2610		//if changed min/max price and we have wpfPrice filter
2611		//we need change slider
2612		_thisObj.getUrlParamsChangeFiltersValues();
2613
2614		_thisObj.disableFiltersLoader();
2615		_thisObj.removeOverlay();
2616		toggleClear();
2617
2618		// fix for OceanWP theme
2619		if ( jQuery('body').find('.products').hasClass('oceanwp-row') ) {
2620			var products = jQuery('body').find('.products'),
2621				aligns = ['center', 'left', 'right'];
2622			products.find('li:first').addClass('col');
2623			for (var i = 1; i <= 7; i++) {
2624				if (products.find('li').hasClass('span_1_of_' + i)) {
2625					products.find('li:first').addClass('span_1_of_' + i);
2626					break;
2627				}
2628			}
2629			for (var j = 0; j < aligns.length; j++) {
2630				if (products.find('li').hasClass('owp-content-' + aligns[j])) {
2631					products.find('li:first').addClass('owp-content-' + aligns[j]);
2632					break;
2633				}
2634			}
2635		}
2636
2637		_thisObj.changeLmpButton();
2638
2639		// for yith quick view
2640		jQuery(document).trigger('yith_wcqv_wcajaxnav_update');
2641
2642		if (typeof (_thisObj.scrollToProductsPro) == 'function') {
2643			_thisObj.scrollToProductsPro($wrapperSettings);
2644		}
2645
2646		if (jQuery(_thisObj.defaultProductSelector).closest('.et_pb_shop').length && jQuery(_thisObj.defaultProductSelector).find('[loading="lazy"]').length == 0) {
2647			heightIdenticalInRow('.et_pb_shop li.product');
2648		}
2649
2650		// Improve compatibility with 'Woocommerce Products Per Page'
2651		jQuery('.form-wppp-select').each( function () {
2652			var $form = jQuery(this);
2653			$form.attr('action', jQuery('#'+_thisObj.currentLoadId).attr('data-hide-url'));
2654			$form.find('input[type="hidden"]').remove();
2655		});
2656		// Improve compatibility with Theme Bricks + Bricks Builder
2657		if (typeof(bricksLazyLoad) == 'function') {
2658			bricksLazyLoad();
2659		}
2660
2661		// event for custom javascript hook, example: document.addEventListener('wpfAjaxSuccess', function(event) {console.log('Custom js');});
2662		//document.dispatchEvent(new Event('wpfAjaxSuccess')); - not work in IE11
2663		var customEvent = document.createEvent('Event');
2664		customEvent.initEvent('wpfAjaxSuccess', false, true);
2665		document.dispatchEvent(customEvent);
2666	});
2667
2668	WpfFrontendPage.prototype.runReadyList = (function(){
2669		if (window.readyList && readyList.length) {
2670			var _thisObj = this.$obj;
2671			if (_thisObj.disableScrollJs) {
2672				jQuery(window).off("yith_infs_start").off("scroll touchstart");
2673				if (typeof(jQuery.fn) == 'object' && typeof(jQuery.fn.init_infinitescroll) == 'function') {
2674					jQuery.fn.init_infinitescroll();
2675				}
2676			}
2677			jQuery(window.readyList).each(function(i, el) {
2678				var strFunc = el['a'][0].toString();
2679				if (strFunc.indexOf('WpfFrontendPage') == -1) {
2680					for(var i = 0; i < _thisObj.readyFuncs.length; i++) {
2681						if (strFunc.indexOf(_thisObj.readyFuncs[i]) != -1 && (strFunc.indexOf('.ajaxComplete(') == -1 || i == 3 || i == 4)) {
2682							try {
2683								window.originalReadyMethod.apply(el['c'], el['a']);
2684							} catch(e) {
2685								console.log(e);
2686							}
2687							break;
2688						}
2689					}
2690				}
2691			});
2692		}
2693		jQuery(window).trigger("fusion-element-render-fusion_woo_product_grid");
2694		var fusionPrInfinite = jQuery(".fusion-products-container-infinite");
2695		if (fusionPrInfinite.length && typeof(fusionPrInfinite.infinitescroll) == 'function') {
2696			fusionPrInfinite.infinitescroll('unbind');
2697			fusionPrInfinite.infinitescroll('bind');
2698		}
2699
2700		if (typeof elementorFrontend !== 'undefined') {
2701			jQuery(window).trigger('resize');
2702
2703			var $eaPagination = jQuery('.elementor-widget-eicon-woocommerce');
2704			if ($eaPagination.length && window.elementorFrontend && window.elementorFrontend.hooks) {
2705				window.elementorFrontend.hooks.doAction('frontend/element_ready/eicon-woocommerce.default', $eaPagination, jQuery);
2706			}
2707		}
2708
2709		// AVADA infinitescroll
2710		if (jQuery('.fusion-grid-container-infinite').length == 1) {
2711			jQuery(document).trigger('fusion-element-render-fusion_post_cards');
2712			jQuery('.fusion-grid-container-infinite').infinitescroll('unbind');
2713			jQuery('.fusion-grid-container-infinite').infinitescroll('bind');
2714		}
2715	});
2716
2717	WpfFrontendPage.prototype.enableFiltersLoader = (function(idWrapper, productListElem){
2718		var preview = jQuery('#' + idWrapper + ' .wpfPreviewLoader').first().clone().removeClass('wpfHidden');
2719		productListElem.html(preview);
2720	});
2721
2722	WpfFrontendPage.prototype.disableFiltersLoader =(function(){
2723		jQuery('.wpfPreviewLoader').first().clone().addClass('wpfHidden');
2724	});
2725
2726	//after load change price and price range filters params if find get params
2727	WpfFrontendPage.prototype.getUrlParamsChangeFiltersValues = (function(){
2728		var _thisObj = this.$obj,
2729			noWooPage = _thisObj.noWoo;
2730		var $generalSettings = _thisObj.getFilterMainSettings(jQuery('.wpfMainWrapper'));
2731		var slugFormat=_thisObj.slugFormat;
2732		// Check if 'slug_format' exists and is valid
2733		if(noWooPage || slugFormat !== "" && slugFormat !== 0 && slugFormat && slugFormat !== "0"){
2734			var curUrl = jQuery('.wpfMainWrapper').first().attr('data-hide-url');
2735		}else{
2736			var curUrl = window.location.href;
2737		}
2738		if(!curUrl){
2739			return;
2740		}
2741		//get all get params
2742		var urlParams = _thisObj.findGetParameter(curUrl);
2743		jQuery('.wpfFilterWrapper').each(function () {
2744			var $filter = jQuery(this),
2745				filterType = $filter.attr('data-filter-type'),
2746				settings = _thisObj.getFilterMainSettings($filter.closest('.wpfMainWrapper'));
2747
2748			switch(filterType){
2749				case 'wpfAttribute':
2750					if(typeof(_thisObj.eventChangeFilterPro) == 'function') {
2751						_thisObj.eventChangeFilterPro($filter, settings);
2752					}
2753					break;
2754				case 'wpfPrice':
2755					var rate = $filter.data('rate');
2756					urlParams = _thisObj.getConvertedPrices(urlParams, rate);
2757					var minPrice = urlParams.wpf_min_price ? urlParams.wpf_min_price : $filter.attr('data-minvalue'),
2758						maxPrice = urlParams.wpf_max_price ? urlParams.wpf_max_price : $filter.attr('data-maxvalue'),
2759						skin = 'default';
2760
2761					if(minPrice){
2762						$filter.find('#wpfMinPrice').val(minPrice);
2763					}
2764					if(maxPrice){
2765						$filter.find('#wpfMaxPrice').val(maxPrice);
2766					}
2767					if(settings){
2768						skin = $filter.attr('data-price-skin');
2769					}
2770					if(skin === 'default'){
2771						var sliderWrapper = $filter.find("#wpfSliderRange");
2772					}else{
2773						var sliderCurBefore = ($filter.attr('data-slider-currency-before') != undefined) ? $filter.attr('data-slider-currency-before') : '';
2774						var sliderCurAfter = ($filter.attr('data-slider-currency-after') != undefined) ? $filter.attr('data-slider-currency-after') : '';
2775						var sliderWrapper = $filter.find('.ion-range-slider').data('ionRangeSlider');
2776						$filter.addClass('wpfNotActiveSlider');
2777
2778						if (sliderCurBefore || sliderCurAfter) {
2779							setTimeout(function()
2780							{
2781								$filter.find('span.irs-min:first').html(sliderCurBefore + sliderWrapper['result'].min_pretty + sliderCurAfter);
2782								$filter.find('span.irs-max:first').html(sliderCurBefore + sliderWrapper['result'].max_pretty + sliderCurAfter);
2783								$filter.find('span.irs-from:first').html(sliderCurBefore + sliderWrapper['result'].from_pretty + sliderCurAfter);
2784								$filter.find('span.irs-to:first').html(sliderCurBefore + sliderWrapper['result'].to_pretty + sliderCurAfter);
2785							}, 500);
2786						}
2787					}
2788					if(minPrice && maxPrice){
2789						if(skin === 'default'){
2790							sliderWrapper.slider({
2791								values: [minPrice, maxPrice]
2792							});
2793						}else if(typeof(sliderWrapper) != 'undefined') {
2794							sliderWrapper.update({from: minPrice, to: maxPrice});
2795							$filter.removeClass('wpfNotActiveSlider');
2796						}
2797					}
2798					_thisObj.chageRangeFieldWidth();
2799					if(typeof(_thisObj.eventChangeFilterPro) == 'function') {
2800						_thisObj.eventChangeFilterPro($filter, settings);
2801					}
2802					break;
2803				case 'wpfPriceRange':
2804					var rate = $filter.data('rate');
2805					urlParams = _thisObj.getConvertedPrices(urlParams, rate);
2806					var minPrice = urlParams.wpf_min_price ? parseFloat(urlParams.wpf_min_price) : false,
2807						maxPrice = urlParams.wpf_max_price ? parseFloat(urlParams.wpf_max_price) : false,
2808						$options = $filter.find('li');
2809					$options.find('input[type="checkbox"]').prop('checked', false);
2810					$options.each(function () {
2811						var _this = jQuery(this),
2812							range = _this.attr('data-range');
2813						if(typeof range != 'undefined') {
2814							range = range.split(',');
2815							var minRange = range[0] == '' ? false : parseFloat(range[0]),
2816								maxRange = range[1] == '' ? false : parseFloat(range[1]),
2817								minPrices = [minPrice - 1, minPrice, minPrice + 1], // rounding error correction
2818								maxPrices = [maxPrice - 1, maxPrice, maxPrice + 1]; // rounding error correction
2819
2820							if(minPrices.includes(minRange) && maxPrices.includes(maxRange)){
2821								_this.find('input[type="checkbox"]').prop('checked', true);
2822								return false;
2823							}
2824						}
2825					});
2826					if(typeof(_thisObj.eventChangeFilterPro) == 'function') {
2827						_thisObj.eventChangeFilterPro($filter, settings);
2828					}
2829					break;
2830			}
2831		});
2832
2833	});
2834
2835	WpfFrontendPage.prototype.findGetParameter =(function(url){
2836		// This function is anonymous, is executed immediately and
2837		// the return value is assigned to QueryString!
2838		var query_string = {},
2839			usefulParam = url.split("?")[1] || "",
2840			query = usefulParam || "",
2841			vars = query.split("&");
2842
2843		for (var i = 0; i < vars.length; i++) {
2844			var pair = vars[i].split("=");
2845
2846			// If first entry with this name
2847			if (typeof query_string[pair[0]] === "undefined") {
2848				query_string[pair[0]] = decodeURIComponent(pair[1]);
2849				// If second entry with this name
2850			} else if (typeof query_string[pair[0]] === "string") {
2851				var arr = [query_string[pair[0]], decodeURIComponent(pair[1])];
2852				query_string[pair[0]] = arr;
2853				// If third or later entry with this name
2854			} else {
2855				query_string[pair[0]].push(decodeURIComponent(pair[1]));
2856			}
2857		}
2858		return query_string;
2859	});
2860
2861	WpfFrontendPage.prototype.getClearLabel = (function (label, withCount) {
2862		if(withCount) {
2863			var cnt = label.lastIndexOf('(');
2864			if(cnt == -1) cnt = label.lastIndexOf('<span');
2865			if(cnt != -1) label = label.substring(0, cnt).trim();
2866		}
2867
2868		label = label.replace(/&nbsp;/g,'');
2869
2870		return label;
2871	});
2872
2873	WpfFrontendPage.prototype.getFilterOptionsByType = (function($filter, filterType){
2874		var _thisObj = this.$obj;
2875		return _thisObj['get' + filterType.replace('wpf', '') + 'FilterOptions']($filter);
2876	});
2877
2878	WpfFrontendPage.prototype.getPriceFilterOptions = (function ($filter) {
2879		var _thisObj = this.$obj,
2880			optionsArray = [],
2881			options = [],
2882			minPrice = $filter.find('#wpfMinPrice').val(),
2883			maxPrice = $filter.find('#wpfMaxPrice').val(),
2884			tax = $filter.data('tax'),
2885			rate = $filter.data('rate'),
2886			str = '';
2887
2888		[minPrice, maxPrice, tax] = _thisObj.getConvertedPrices([minPrice, maxPrice, tax], rate);
2889		str = minPrice + ',' + maxPrice;
2890		options.push(str);
2891
2892		//options for frontend(change url)
2893		var frontendOptions = [],
2894			getParams = $filter.attr('data-get-attribute');
2895		frontendOptions['rate'] = rate;
2896
2897		getParams = getParams.split(",");
2898		for (var i = 0; i < getParams.length; i++) {
2899			if (i === 0) {
2900				frontendOptions[getParams[i]] = minPrice;
2901			}
2902			if (i === 1) {
2903				frontendOptions[getParams[i]] = maxPrice;
2904			}
2905			if (i === 2 && tax !== '') {
2906				frontendOptions[getParams[i]] = tax;
2907			}
2908		}
2909		var symbol = $filter.find('.wpfCurrencySymbol'),
2910			symbolB = symbol.length && !symbol.is(':last-child') ? symbol.html() : '',
2911			symbolA = symbol.length && symbol.is(':last-child') ? symbol.html() : '',
2912			selectedOptions = {'is_one': true, 'list': [symbolB + minPrice + symbolA + ' - ' + symbolB + maxPrice + symbolA]};
2913
2914		optionsArray['backend'] = options;
2915		optionsArray['frontend'] = frontendOptions;
2916		optionsArray['selected'] = selectedOptions;
2917		optionsArray['stats'] = [[minPrice, maxPrice]];
2918
2919		return optionsArray;
2920	});
2921
2922	WpfFrontendPage.prototype.getPriceRangeFilterOptions = (function ($filter) {
2923		var _thisObj = this.$obj,
2924			optionsArray = [],
2925			options = [],
2926			frontendOptions = [],
2927			selectedOptions = {'is_one': true, 'list': []},
2928			statistics = [],
2929			i = 0,
2930			rate = $filter.data('rate');
2931
2932		if ($filter.attr('data-display-type') === 'list') {
2933			if ($filter.find("input:checked").length) {
2934				var li = $filter.find('input:checked').closest('li');
2935				options[i] = li.attr('data-range');
2936				selectedOptions['list'][i] = li.find('.wpfValue').html();
2937			}
2938		}else if($filter.attr('data-display-type') === 'dropdown'){
2939			if($filter.find(":selected").attr('data-range')){
2940				var option = $filter.find(":selected");
2941				options[i] = option.attr('data-range');
2942				selectedOptions['list'][i] = option.html();
2943			}
2944
2945		}
2946
2947		//options for frontend(change url)
2948		if (typeof options !== 'undefined' && options.length > 0) {
2949			var getParams = $filter.attr('data-get-attribute'),
2950				tax = $filter.data('tax');
2951			frontendOptions['rate'] = rate;
2952			getParams = getParams.split(",");
2953			if (typeof options[0] !== 'undefined' && options[0].length > 0) {
2954				var prices = options[0].split(',');
2955				[prices[0], prices[1], tax] = _thisObj.getConvertedPrices([prices[0], prices[1], tax], rate);
2956				frontendOptions[getParams[0]] = prices[0];
2957				frontendOptions[getParams[1]] = prices[1];
2958				if (typeof tax !== 'undefined') {
2959					frontendOptions[getParams[2]] = tax;
2960				}
2961			}
2962		}
2963		if (options.length == 0) {
2964			var defRange = $filter.attr('data-default');
2965			if (typeof defRange != 'undefined' && defRange.length) {
2966				options[i] = defRange;
2967			}
2968		}
2969
2970		if (typeof rate !== 'undefined') {
2971			var minPrice = '',
2972				maxPrice = '';
2973			options = options.map(function (elem) {
2974				[minPrice, maxPrice] = _thisObj.getConvertedPrices(elem.split(","), rate);
2975				return minPrice + ',' + maxPrice;
2976			});
2977		}
2978
2979		if (options.length) {
2980			statistics = options.map(function (elem) {
2981				return elem.split(",");
2982			});
2983		}
2984		optionsArray['backend'] = options;
2985		optionsArray['frontend'] = frontendOptions;
2986		optionsArray['selected'] = selectedOptions;
2987		optionsArray['stats'] = statistics;
2988
2989		return optionsArray;
2990	});
2991
2992	WpfFrontendPage.prototype.getSortByFilterOptions = (function ($filter) {
2993		var optionsArray = [],
2994			options = [],
2995			frontendOptions = [],
2996			selectedOptions = {'is_one': true, 'list': []},
2997			value = '';
2998		if ($filter.data('display-type') === 'radio') {
2999			var elem = $filter.find('input:checked').closest('li'),
3000				name = elem.find('.wpfFilterTaxNameWrapper').html();
3001		} else {
3002			var elem = $filter.find('select:not(.wpfPerPageDD)').find('option:selected'),
3003				name = elem.html();
3004		}
3005		if (elem.length) {
3006			value = elem.data('term-slug');
3007			//options for backend (filtering)
3008			options.push(value);
3009
3010			//options for frontend(change url)
3011			var getParams = $filter.attr('data-get-attribute');
3012			frontendOptions[getParams] = value;
3013			selectedOptions['list'][0] = name;
3014			optionsArray['stats'] = [name];
3015		}
3016		if ($filter.data('first-instock') == '1') {
3017			frontendOptions['oistock'] = 1;
3018			options.push('oistock');
3019		}
3020
3021		optionsArray['backend'] = options;
3022		optionsArray['frontend'] = frontendOptions;
3023		optionsArray['selected'] = selectedOptions;
3024		return optionsArray;
3025	});
3026
3027	WpfFrontendPage.prototype.getInStockFilterOptions = (function ($filter) {
3028		var optionsArray = [],
3029			frontendOptions = [],
3030			options = [],
3031			filterType = $filter.attr('data-display-type'),
3032			selectedOptions = {'is_one': (filterType === 'dropdown'), 'list': []},
3033			statistics = [],
3034			i = 0;
3035
3036		//options for backend (filtering)
3037		if(filterType === 'dropdown'){
3038			var option = $filter.find(":selected"),
3039				value = option.attr('data-slug');
3040			if(value != '') {
3041				options[i] = value;
3042				frontendOptions[i] = value;
3043				var name = option.html();
3044				selectedOptions['list'][i] = name;
3045				statistics.push(name);
3046			}
3047		} else {
3048			$filter.find('input:checked').each(function () {
3049				var li = jQuery(this).closest('li'),
3050					slug = li.attr('data-term-slug'),
3051					name = li.find('.wpfFilterTaxNameWrapper').length ? li.find('.wpfFilterTaxNameWrapper').html() : li.find('.wpfValue').html();
3052				options[i] = slug;
3053				frontendOptions[i] = slug;
3054				selectedOptions['list'][li.attr('data-term-id')] = name;
3055				statistics.push(name);
3056				i++;
3057			});
3058		}
3059		optionsArray['backend'] = options;
3060
3061		//options for frontend(change url)
3062		var getParams = $filter.attr('data-get-attribute');
3063
3064		optionsArray['frontend'] = [];
3065		optionsArray['frontend']['taxonomy'] = getParams;
3066		optionsArray['frontend']['settings'] = frontendOptions;
3067		optionsArray['selected'] = selectedOptions;
3068		optionsArray['stats'] = statistics;
3069
3070		return optionsArray;
3071	});
3072
3073	//custom field
3074	WpfFrontendPage.prototype.getCustomFieldFilterOptions = (function ($filter) {
3075		var optionsArray = [],
3076			frontendOptions = {},
3077			options = [],
3078			statistics = [],
3079			filterType = $filter.attr('data-display-type') || $filter.data('display-type'),
3080			getParams = $filter.attr('data-get-attribute'),
3081			selectedOptions = {'is_one': (filterType === 'radio'), 'list': []},
3082			i = 0;
3083		if (!getParams) {
3084			optionsArray['backend']  = [];
3085			optionsArray['frontend'] = {};
3086			optionsArray['selected'] = selectedOptions;
3087			optionsArray['stats']    = [];
3088			return optionsArray;
3089		}
3090		if (filterType === 'radio') {
3091			var $sel = $filter.find('input[type="radio"]:checked');
3092			if ($sel.length) {
3093				var value = $sel.val();
3094				var label = $sel.closest('label').text().trim();
3095				options.push(value);
3096				var logic = $filter.attr('data-query-logic') || 'or';
3097				var joinDelim = (logic === 'and') ? ',' : '|';
3098				frontendOptions[getParams] = options.join(joinDelim);
3099				selectedOptions['list'] = [label];
3100				statistics = [label];
3101			}
3102		} else { // checkbox
3103			$filter.find('input[type="checkbox"]:checked').each(function () {
3104				var value = jQuery(this).val();
3105				var label = jQuery(this).closest('label').text().trim();
3106
3107				options.push(value);
3108				selectedOptions['list'].push(label);
3109				statistics.push(label);
3110			});
3111
3112			if (options.length) {
3113				frontendOptions[getParams] = options.join('|'); // ✅ key=Red|Green (correct)
3114			}
3115		}
3116		optionsArray['backend']  = options;
3117		optionsArray['frontend'] = frontendOptions;
3118		optionsArray['selected'] = selectedOptions;
3119		optionsArray['stats']    = statistics;
3120		return optionsArray;
3121	});
3122	//customfield
3123
3124	WpfFrontendPage.prototype.getCategoryFilterOptions = (function ($filter) {
3125		var _thisObj = this.$obj,
3126			optionsArray = [],
3127			frontendOptions = [],
3128			options = [],
3129			filterType = $filter.attr('data-display-type'),
3130			useSlugs = $filter.attr('data-use-slugs') == '1',
3131			selectedOptions = {'is_one': (filterType == 'list' || filterType == 'dropdown'), 'list': []},
3132			statistics = [],
3133			i = 0;
3134
3135		//options for backend (filtering)
3136		if(filterType === 'dropdown'){
3137			var option = $filter.find(":selected"),
3138				id = option.attr('data-term-id'),
3139				value = option.val();
3140			if(value != '') {
3141				options[i] = value;
3142				var name = _thisObj.getClearLabel(option.html(), $filter.hasClass('wpfShowCount'));
3143				selectedOptions['list'][id] = name;
3144				statistics.push(name);
3145			}
3146			frontendOptions[i] = (useSlugs ? option.attr('data-term-slug') : id);
3147		} else if(filterType === 'mul_dropdown'){
3148			$filter.find(':selected').each(function () {
3149				var option = jQuery(this),
3150					id = option.attr('data-term-id');
3151				options[i] = option.val();
3152				frontendOptions[i] = (useSlugs ? option.attr('data-term-slug') : id);
3153				var name = _thisObj.getClearLabel(option.html(), $filter.hasClass('wpfShowCount'));
3154				selectedOptions['list'][id] = name;
3155				statistics.push(name);
3156				i++;
3157			});
3158		} else {
3159			var removeSelectedList = [];
3160			$filter.find('input').each(function () {
3161				var inputCurent = jQuery(this),
3162					liCurent = inputCurent.closest('li'),
3163					id = liCurent.data('term-id'),
3164					isParent = liCurent.children('ul').length > 0,
3165					isChecked = inputCurent.is(':checked'),
3166					hierarchicalLogic = $filter.attr('data-logic-hierarchical'),
3167					type = $filter.attr('data-display-type'),
3168					isHierarchical = $filter.attr('data-show-hierarchical'),
3169					isHierarchicalLogic = isHierarchical === 'true' && type === 'multi' || type === 'text';
3170
3171				if ( isParent ) {
3172					var isAllChildChecked = true,
3173						childList = [];
3174
3175					liCurent.find('ul li').each(function() {
3176						var childId = jQuery(this).data('term-id'),
3177							childLi = jQuery(this),
3178							childInput = childLi.find('input'),
3179							isChildChecked = childInput.prop('checked');
3180
3181						childList.push(childId);
3182
3183						if (!isChildChecked) {
3184							isAllChildChecked = false;
3185							return false;
3186						}
3187					});
3188
3189					if (isChecked && isAllChildChecked) {
3190						removeSelectedList = removeSelectedList.concat(childList);
3191
3192						var onlyUnique = function(value, index, self) {
3193							return self.indexOf(value) === index;
3194						}
3195
3196						removeSelectedList = removeSelectedList.filter( onlyUnique );
3197						selectedOptions.removeSelected = removeSelectedList;
3198					}
3199				}
3200
3201				if (jQuery(this).is(':checked')) {
3202					if ( isHierarchicalLogic && hierarchicalLogic == 'child' ) {
3203						var liElements = liCurent.find('li'),
3204							isChildChicked = false;
3205
3206						for (var j = 0; j < liElements.length; ++j) {
3207							 var li = liElements[j];
3208							if (jQuery(li).find('input').prop('checked')) {
3209								isChildChicked = true;
3210							}
3211						}
3212						if (!isChildChicked) {
3213							options[i] = id;
3214							frontendOptions[i] = (useSlugs ? liCurent.attr('data-term-slug') : id);
3215						}
3216					} else if(isHierarchicalLogic && hierarchicalLogic == 'parent') {
3217						var parents = liCurent.parents('li'),
3218							isChildChicked = false;
3219
3220						for (var j = 0; j < parents.length; ++j) {
3221							 var li = parents[j];
3222							if (jQuery(li).find('input').prop('checked')) {
3223								isChildChicked = true;
3224							}
3225						}
3226						if (!isChildChicked) {
3227							options[i] = id;
3228							frontendOptions[i] = (useSlugs ? liCurent.attr('data-term-slug') : id);
3229						}
3230					} else {
3231						options[i] = id;
3232						frontendOptions[i] = (useSlugs ? liCurent.attr('data-term-slug') : id);
3233					}
3234					var name = liCurent.find('.wpfValue').html();
3235					selectedOptions['list'][id] = name;
3236					statistics.push(liCurent.find('.wpfFilterTaxNameWrapper:first').length ? liCurent.find('.wpfFilterTaxNameWrapper:first').html() : name);
3237					i++;
3238				}
3239			});
3240		}
3241
3242		var options = options.filter(function (el) {
3243			return el != null;
3244		});
3245		var frontendOptions = frontendOptions.filter(function (el) {
3246			return el != null;
3247		});
3248
3249		optionsArray['backend'] = options;
3250
3251		//options for frontend(change url)
3252		var getParams = $filter.attr('data-get-attribute');
3253
3254		optionsArray['frontend'] = [];
3255		optionsArray['frontend']['taxonomy'] = getParams;
3256		optionsArray['frontend']['settings'] = frontendOptions;
3257		optionsArray['selected'] = selectedOptions;
3258		optionsArray['stats'] = statistics;
3259
3260		return optionsArray;
3261	});
3262
3263	WpfFrontendPage.prototype.getPerfectBrandFilterOptions = (function ($filter) {
3264		return this.$obj.getCategoryFilterOptions($filter);
3265	});
3266
3267	WpfFrontendPage.prototype.getTagsFilterOptions = (function ($filter) {
3268		var _thisObj = this.$obj,
3269			optionsArray = [],
3270			options = [],
3271			frontendOptions = [],
3272			filterType = $filter.attr('data-display-type'),
3273			selectedOptions = {'is_one': (filterType == 'dropdown'), 'list': []},
3274			statistics = [],
3275			withCount = $filter.hasClass('wpfShowCount'),
3276			i = 0,
3277			proFilterType = [
3278				'colors'
3279			];
3280
3281		//options for backend (filtering)
3282		if(filterType === 'dropdown'){
3283			var option = $filter.find(":selected"),
3284				value = option.val();
3285			if(value != '') {
3286				options[i] = value;
3287				frontendOptions[i] = option.attr('data-slug');
3288				var name = _thisObj.getClearLabel(option.html(), withCount);
3289				selectedOptions['list'][option.attr('data-term-id')] = name;
3290				statistics.push(name);
3291			}
3292		} else if (filterType === 'mul_dropdown'){
3293			$filter.find(':selected').each(function () {
3294				var option = jQuery(this);
3295				options[i] = option.val();
3296				frontendOptions[i] = option.attr('data-slug');
3297				var name = _thisObj.getClearLabel(option.html(), withCount);
3298				selectedOptions['list'][option.attr('data-term-id')] = name;
3299				statistics.push(name);
3300				i++;
3301			});
3302		} else if (jQuery.inArray(filterType, proFilterType) == -1 ) {
3303			$filter.find('input:checked').each(function () {
3304				var li = jQuery(this).closest('li'),
3305					id = li.attr('data-term-id');
3306				options[i] = id;
3307				frontendOptions[i] = li.attr('data-term-slug');
3308				var name = li.find('.wpfValue').html();
3309				selectedOptions['list'][id] = name;
3310				statistics.push(li.find('.wpfFilterTaxNameWrapper').length ? li.find('.wpfFilterTaxNameWrapper').html() : name);
3311				i++;
3312			});
3313		}
3314
3315		var data = {
3316			options : options,
3317			frontendOptions : frontendOptions,
3318			selectedOptions : selectedOptions,
3319			statistics : statistics,
3320			i : i,
3321		}
3322
3323		if (typeof window.wpfFrontendPage.getTagsFilterOptionsPro == 'function') {
3324			data = window.wpfFrontendPage.getTagsFilterOptionsPro($filter, data);
3325		}
3326
3327		optionsArray['backend'] = data.options;
3328
3329		//options for frontend(change url)
3330		var getParams = $filter.attr('data-get-attribute');
3331
3332		optionsArray['frontend'] = [];
3333		optionsArray['frontend']['taxonomy'] = getParams;
3334		optionsArray['frontend']['settings'] = data.frontendOptions;
3335		optionsArray['selected'] = data.selectedOptions;
3336		optionsArray['stats'] = data.statistics;
3337
3338		return optionsArray;
3339	});
3340
3341	WpfFrontendPage.prototype.getAttributeFilterOptions = (function ($filter) {
3342		var _thisObj = this.$obj,
3343			optionsArray = [],
3344			options = [],
3345			frontendOptions = [],
3346			filterType = $filter.attr('data-display-type'),
3347			selectedOptions = {'is_one': (filterType == 'dropdown'), 'list': []},
3348			statistics = [],
3349			withCount = $filter.hasClass('wpfShowCount'),
3350			i = 0,
3351			proFilterType = [
3352				'slider',
3353				'colors'
3354			];
3355
3356		//options for backend (filtering)
3357		if (filterType === 'dropdown'){
3358			var option = $filter.find(":selected"),
3359				value = option.val();
3360			if (value != '') {
3361				options[i] = value;
3362				frontendOptions[i] = option.attr('data-slug');
3363				var name = _thisObj.getClearLabel(option.html(), withCount);
3364				selectedOptions['list'][option.attr('data-term-id')] = name;
3365				statistics.push(name);
3366			}
3367		} else if (filterType === 'mul_dropdown'){
3368			$filter.find(':selected').each(function () {
3369				var option = jQuery(this);
3370				options[i] = option.val();
3371				frontendOptions[i] = option.attr('data-slug');
3372				var name = _thisObj.getClearLabel(option.html(), withCount);
3373				selectedOptions['list'][option.attr('data-term-id')] = name;
3374				statistics.push(name);
3375				i++;
3376			});
3377		} else if (jQuery.inArray(filterType, proFilterType) == -1 ) {
3378			$filter.find('input:checked').each(function () {
3379				var li = jQuery(this).closest('li'),
3380					id = li.attr('data-term-id');
3381				options[i] = id;
3382				frontendOptions[i] = li.attr('data-term-slug');
3383				var name = li.find('.wpfValue').html();
3384				selectedOptions['list'][id] = name;
3385				statistics.push(li.find('.wpfFilterTaxNameWrapper').length ? li.find('.wpfFilterTaxNameWrapper').html() : name);
3386				i++;
3387			});
3388		}
3389
3390		var data = {
3391			options : options,
3392			frontendOptions : frontendOptions,
3393			selectedOptions : selectedOptions,
3394			statistics : statistics,
3395			i : i,
3396		}
3397
3398		if (typeof window.wpfFrontendPage.getAttributeFilterOptionsPro == 'function') {
3399			data = window.wpfFrontendPage.getAttributeFilterOptionsPro($filter, data);
3400		}
3401
3402		optionsArray['backend'] = data.options;
3403
3404		//options for frontend(change url)
3405		var getParams = $filter.attr('data-get-attribute');
3406
3407		optionsArray['frontend'] = [];
3408		optionsArray['frontend']['taxonomy'] = getParams;
3409		optionsArray['frontend']['settings'] = data.frontendOptions;
3410		optionsArray['selected'] = data.selectedOptions;
3411		optionsArray['stats'] = data.statistics;
3412
3413		return optionsArray;
3414	});
3415
3416	WpfFrontendPage.prototype.getAuthorFilterOptions = (function ($filter) {
3417		var _thisObj = this.$obj,
3418			optionsArray = [],
3419			options = [],
3420			frontendOptions = [],
3421			filterType = $filter.attr('data-display-type'),
3422			selectedOptions = {'is_one': (filterType == 'dropdown'), 'list': []},
3423			statistics = [],
3424			i = 0;
3425
3426		//options for backend (filtering)
3427		if(filterType === 'list'){
3428			$filter.find('input:checked').each(function () {
3429				var li = jQuery(this).closest('li'),
3430					id = li.attr('data-term-id');
3431				options[i] = id;
3432				frontendOptions[i] = li.attr('data-term-slug');
3433				var name = li.find('.wpfValue').html();
3434				selectedOptions['list'][id] = name;
3435				statistics.push(li.find('.wpfFilterTaxNameWrapper').length ? li.find('.wpfFilterTaxNameWrapper').html() : name);
3436				i++;
3437			});
3438		} else if (filterType === 'mul_dropdown'){
3439			$filter.find(':selected').each(function () {
3440				var option = jQuery(this);
3441				options[i] = option.val();
3442				frontendOptions[i] = option.attr('data-slug');
3443				var name = _thisObj.getClearLabel(option.html());
3444				selectedOptions['list'][option.attr('data-term-id')] = name;
3445				statistics.push(name);
3446				i++;
3447			});
3448		} else if (filterType === 'dropdown'){
3449			var option = $filter.find(":selected"),
3450				value = option.val();
3451			options[i] = value;
3452			if(value != '') {
3453				frontendOptions[i] = option.attr('data-slug');
3454				var name = option.html();
3455				selectedOptions['list'][option.attr('data-term-id')] = name;
3456				statistics.push(name);
3457			}
3458		}
3459		optionsArray['backend'] = options;
3460
3461		//options for frontend(change url)
3462		var getParams = $filter.attr('data-get-attribute');
3463
3464		optionsArray['frontend'] = [];
3465		optionsArray['frontend']['taxonomy'] = getParams;
3466		optionsArray['frontend']['settings'] = frontendOptions;
3467		optionsArray['selected'] = selectedOptions;
3468		optionsArray['stats'] = statistics;
3469
3470		return optionsArray;
3471	});
3472
3473	WpfFrontendPage.prototype.getFeaturedFilterOptions = (function ($filter) {
3474		var optionsArray = [],
3475			options = [],
3476			frontendOptions = [],
3477			filterType = $filter.attr('data-display-type'),
3478			selectedOptions = {'is_one': (filterType == 'dropdown'), 'list': []},
3479			statistics = [],
3480			i = 0;
3481
3482		$filter.find('input:checked').each(function () {
3483			var li = jQuery(this).closest('li'),
3484				id = li.attr('data-term-id');
3485			options[i] = id;
3486			frontendOptions[i] = li.attr('data-term-slug');
3487			var name = li.find('.wpfValue').html();
3488			selectedOptions['list'][id] = name;
3489			statistics.push(li.find('.wpfFilterTaxNameWrapper').length ? li.find('.wpfFilterTaxNameWrapper').html() : name);
3490			i++;
3491		});
3492		optionsArray['backend'] = options;
3493
3494		//options for frontend(change url)
3495		var getParams = $filter.attr('data-get-attribute');
3496
3497		optionsArray['frontend'] = [];
3498		optionsArray['frontend']['taxonomy'] = getParams;
3499		optionsArray['frontend']['settings'] = frontendOptions;
3500		optionsArray['selected'] = selectedOptions;
3501		optionsArray['stats'] = statistics;
3502
3503		return optionsArray;
3504	});
3505
3506	WpfFrontendPage.prototype.getOnSaleFilterOptions = (function ($filter) {
3507		var optionsArray = [],
3508			options = [],
3509			frontendOptions = [],
3510			filterType = $filter.attr('data-display-type'),
3511			selectedOptions = {'is_one': (filterType == 'dropdown'), 'list': []},
3512			statistics = [],
3513			i = 0;
3514
3515		$filter.find('input:checked').each(function () {
3516			var li = jQuery(this).closest('li'),
3517				id = li.attr('data-term-id');
3518			options[i] = id;
3519			frontendOptions[i] = li.attr('data-term-slug');
3520			var name = li.find('.wpfValue').html();
3521			selectedOptions['list'][id] = name;
3522			statistics.push(li.find('.wpfFilterTaxNameWrapper').length ? li.find('.wpfFilterTaxNameWrapper').html() : name);
3523			i++;
3524		});
3525		optionsArray['backend'] = options;
3526
3527		//options for frontend(change url)
3528		var getParams = $filter.attr('data-get-attribute');
3529
3530		optionsArray['frontend'] = [];
3531		optionsArray['frontend']['taxonomy'] = getParams;
3532		optionsArray['frontend']['settings'] = frontendOptions;
3533		optionsArray['selected'] = selectedOptions;
3534		optionsArray['stats'] = statistics;
3535
3536		return optionsArray;
3537	});
3538
3539	WpfFrontendPage.prototype.getRatingFilterOptions = (function ($filter) {
3540		var optionsArray = [],
3541			frontendOptions = [],
3542			options = [],
3543			filterType = $filter.attr('data-display-type'),
3544			selectedOptions = {'is_one': true, 'list': []},
3545			statistics = [],
3546			i = 0;
3547
3548		//options for backend (filtering)
3549		if(filterType == 'linestars' || filterType == 'liststars'){
3550			var input = $filter.find('input.wpfStarInput:checked'),
3551				rating = input.val();
3552			options[i] = rating;
3553			frontendOptions[i] = rating;
3554			var name = input.attr('data-label');
3555			selectedOptions['list'][i] = name;
3556			statistics.push(name);
3557		}else if(filterType == 'list'){
3558			$filter.find('input:checked').each(function () {
3559				var li = jQuery(this).closest('li'),
3560					id = li.attr('data-term-id');
3561				options[i] = id;
3562				frontendOptions[i] = li.attr('data-term-slug');
3563				var name = li.find('.wpfValue').html();
3564				selectedOptions['list'][id] = name;
3565				statistics.push(li.find('.wpfFilterTaxNameWrapper').length ? li.find('.wpfFilterTaxNameWrapper').html() : name);
3566				i++;
3567			});
3568		}else if(filterType == 'dropdown'){
3569			var option = $filter.find(":selected"),
3570				value = option.val();
3571			options[i] = value;
3572			if(value != '') {
3573				frontendOptions[i] = option.attr('data-slug');
3574				var name = option.html();
3575				selectedOptions['list'][option.attr('data-term-id')] = name;
3576				statistics.push(name);
3577			}
3578		}
3579		optionsArray['backend'] = options;
3580
3581		//options for frontend(change url)
3582		var getParams = $filter.attr('data-get-attribute');
3583
3584		optionsArray['frontend'] = [];
3585		optionsArray['frontend']['taxonomy'] = getParams;
3586		optionsArray['frontend']['settings'] = frontendOptions;
3587		optionsArray['selected'] = selectedOptions;
3588		optionsArray['stats'] = statistics;
3589
3590		return optionsArray;
3591	});
3592
3593	WpfFrontendPage.prototype.disableLeerOptions = (function () {
3594		var _thisObj = this.$obj;
3595		jQuery('.wpfMainWrapper').each(function () {
3596			var mainWrapper = jQuery(this),
3597				settings = _thisObj.getFilterMainSettings(mainWrapper);
3598			if(settings && settings.settings.filter_null_disabled === '1') {
3599				var filters = mainWrapper.find('.wpfFilterWrapper.wpfShowCount');
3600				if(filters.length) {
3601					filters.find('option[data-term-id]').prop('disabled', false);
3602					filters.find('option[data-term-id][data-count="0"]').prop('disabled', true);
3603					filters.find('.wpfCount').each(function(){
3604						var cntObj = jQuery(this),
3605							leer = cntObj.html() == '(0)',
3606							el = cntObj.closest('[data-term-id]'),
3607							input = false;
3608						if(el.length == 0) {
3609							el = cntObj.closest('[data-term-slug]');
3610						}
3611						if(el.length) {
3612							if(el.is('input')) {
3613								input = el;
3614								el = input.parent();
3615							} else {
3616								input = el.find('input');
3617							}
3618							input.prop('disabled', leer);
3619							if(leer) el.addClass('wpfOptionDisabled');
3620							else el.removeClass('wpfOptionDisabled');
3621						}
3622					});
3623				}
3624			}
3625		});
3626	});
3627
3628	WpfFrontendPage.prototype.addSpecificPluginActions = (function() {
3629		// elementor plugin, action when widgets in admin panek are ready
3630		jQuery(window).on('load', function() {
3631			if ( window.elementorFrontend ) {
3632				if ( window.elementorFrontend.hooks ) {
3633					elementorFrontend.hooks.addAction( 'frontend/element_ready/widget', function( $scope ) {
3634						var wrapper = $scope.find('.wpfMainWrapper');
3635
3636						hideFilterLoader(wrapper);
3637					});
3638				}
3639			} else if ( jQuery('.elementor .wpfMainWrapper').length ) {
3640				setTimeout(function() {
3641					jQuery('.elementor .wpfMainWrapper').each(function() {
3642						var wrapper = jQuery(this);
3643						hideFilterLoader(wrapper);
3644					});
3645				}, 2000);
3646			}
3647		});
3648	});
3649
3650	WpfFrontendPage.prototype.fixSelector = (function(selector, defaultSelector) {
3651		if (typeof selector == 'undefined' || selector === '') {
3652			return typeof defaultSelector == 'undefined' ? '' : defaultSelector;
3653		}
3654		return (selector.search(/\.|#/) === -1) ? '.' + selector.replace(/(\s+)(\w+)/g, ' .$2')	: selector ;
3655	});
3656
3657	WpfFrontendPage.prototype.markCheckboxSelected = (function ($filter, first) {
3658		if ($filter.length) {
3659			var settings = this.getFilterMainSettings($filter.closest('.wpfMainWrapper'));
3660			if(settings) {
3661				if (settings.settings.checked_items_bold == '1') {
3662					var wpfMainWrapper = $filter.closest('.wpfMainWrapper');
3663					wpfMainWrapper.find('.wpfDisplay').css('font-weight', '');
3664					wpfMainWrapper.find('.wpfAttrLabel').css('font-weight', '');
3665
3666					wpfMainWrapper.find('input:checked').each(function () {
3667						var wpfDisplay = jQuery(this).closest('.wpfLiLabel').find('.wpfDisplay'),
3668							wpfAttrLabel = jQuery(this).closest('.wpfColorsColBlock').find('.wpfAttrLabel');
3669
3670						wpfDisplay.css('font-weight', 'bold');
3671						wpfAttrLabel.css('font-weight', 'bold');
3672					});
3673				}
3674			}
3675			if (first) {
3676				//need to delete automatic checked inputs by goback in browser Chrome/FF
3677				setTimeout(function () {
3678					$filter.find('input').each(function() {
3679						var input = this;
3680						if (input.type == "checkbox") {
3681							if (input.defaultChecked == true) {
3682								if (input.checked != true) input.checked = true;
3683							} else {
3684								if (input.checked == true) {
3685									input.checked = false;
3686									jQuery(input).closest('.wpfLiLabel').find('.wpfDisplay').removeClass('selected').css('font-weight', '');
3687								}
3688							}
3689
3690						}
3691					});
3692				}, 100);
3693			}
3694		}
3695	});
3696
3697	window.wpIinitialiseImmediately = typeof wpIinitialiseImmediately !== 'undefined' ? wpIinitialiseImmediately : 0;
3698	jQuery(document).ready(function () {
3699		if (!window.wpfFrontendPage) window.wpfFrontendPage = new WpfFrontendPage();
3700		if (typeof isElementorEditMode == 'undefined') {
3701			window.wpfFrontendPage.init();
3702		}
3703	});
3704
3705	WpfFrontendPage.prototype.unserializeStr = function(serializedString){
3706		var str = decodeURI(serializedString);
3707		var pairs = str.split('&');
3708		var obj = {}, p, idx;
3709		for (var i=0, n=pairs.length; i < n; i++) {
3710			p = pairs[i].split('=');
3711			idx = p[0];
3712			if (obj[idx] === undefined) {
3713				obj[idx] = unescape(p[1]).replace ( /\+/g, ' ' );
3714			}else{
3715				if (typeof obj[idx] == "string") {
3716					obj[idx]=[obj[idx]];
3717				}
3718				obj[idx].push(unescape(p[1]).replace ( /\+/g, ' ' ));
3719			}
3720		}
3721		return obj;
3722	};
3723
3724	WpfFrontendPage.prototype.getConvertedPrices = function (data, rate) {
3725		if (typeof rate !== 'undefined' && rate !== 1 ) {
3726			if (typeof data[0] !== 'undefined') {
3727				data[0] = String(Math.round(data[0] / rate));
3728				if (typeof data[1] !== 'undefined') {
3729					data[1] = String(Math.round(data[1] / rate));
3730				}
3731				if (typeof data[2] !== 'undefined') {
3732					data[2] = String(Math.round(data[2] / rate));
3733				}
3734			} else {
3735				if (data.wpf_min_price) {
3736					data.wpf_min_price = String(Math.round(data.wpf_min_price * rate));
3737				}
3738				if (data.wpf_max_price) {
3739					data.wpf_max_price = String(Math.round(data.wpf_max_price * rate));
3740				}
3741				if (data.tax) {
3742					data.tax = String(Math.round(data.tax * rate));
3743				}
3744			}
3745		}
3746		return data;
3747	};
3748
3749	if (jQuery('.variations_form').length > 0 && typeof $(this).wc_variation_form == 'function') {
3750		document.addEventListener('wpfAjaxSuccess', function (event) {
3751			$('.variations_form').each(function () {
3752				$(this).wc_variation_form();
3753			});
3754		});
3755	}
3756
3757	if (jQuery('.jetpack-lazy-image').length > 0) {
3758		document.addEventListener('wpfAjaxSuccess', function (event) {
3759			jQuery('.jetpack-lazy-image').each(function () {
3760				jQuery(this).removeAttr('srcset');
3761			});
3762		});
3763	}
3764	if (jQuery('.jetpack-lazy-image').length > 0) {
3765		document.addEventListener('wpfAjaxSuccess', function (event) {
3766			jQuery('.jetpack-lazy-image').each(function () {
3767				jQuery(this).removeAttr('srcset');
3768			});
3769		});
3770	}
3771
3772	// added for ElementorPro Loop Load More
3773	if (jQuery('div.elementor-widget[data-widget_type="loop-grid.product"]').length > 0) {
3774		document.addEventListener('wpfAjaxSuccess', function (event) {
3775			if (window.elementorFrontend && window.elementorFrontend.elementsHandler) {
3776				var $products = jQuery('div.elementor-widget[data-widget_type="loop-grid.product"]');
3777				if ($products.length == 1 && $products.find('.e-load-more-anchor').length == 1) {
3778					$products.removeClass('e-load-more-pagination-end');
3779					window.elementorFrontend.elementsHandler.runReadyTrigger($products);
3780				}
3781			}
3782		});
3783	}
3784
3785	// added for plugin: WooCommerce Load More Products
3786	jQuery(document).ready(function () {
3787		if (jQuery('a.lmp_button').length > 0) {
3788			document.addEventListener('wpfAjaxSuccess', function (event) {
3789				if (!window.wpfDoNotLoadMore && typeof load_next_page == 'function') {
3790					load_next_page(true, decodeURIComponent(location.href));
3791				}
3792			});
3793		}
3794	});
3795
3796	// plugin event woocommerce-product-search
3797	// https://docs.woocommerce.com/documentation/plugins/woocommerce/woocommerce-extensions/woocommerce-product-search/
3798	jQuery(document).on('ixProductFilterRequestProcessed', function (event) {
3799		window.wpfFrontendPage.filtering();
3800	});
3801	if (window.wpIinitialiseImmediately) {
3802		window.wpfFrontendPage = new WpfFrontendPage();
3803	}
3804}(window.jQuery, window));
3805
3806var objQueryString={};
3807
3808toggleClear();
3809
3810// try to get jquery selector from random html string
3811function wpfGetSelector(html, controlExist, defSelector, countChilds, removeDynamicClasses, context) {
3812	if(html.length == 0) return defSelector;
3813
3814	var elem     = (typeof context !== 'undefined') ? jQuery(html, context) : jQuery(html),
3815		selector = '',
3816		i = 0;
3817
3818	if (typeof countChilds == 'undefined') {
3819		countChilds = 1;
3820	}
3821
3822	while (i < countChilds && elem && elem.length) {
3823		if (i > 0) {
3824			selector += ' ';
3825		}
3826
3827		i++;
3828
3829		if (elem.length > 1) {
3830			elem = elem.last();
3831		}
3832
3833		var elemId = elem.attr('id');
3834		if (typeof elemId != 'undefined') {
3835			selector += '#' + elemId;
3836		} else {
3837			var elemClass = elem.attr('class');
3838
3839			// try to remove some dynamically changed classes that contains a number in it name
3840			if (removeDynamicClasses) {
3841				classList = elemClass.split(' ');
3842				classList.forEach( function( className, key ) {
3843					var hasNumber = /\d/.test(className);
3844					if ( hasNumber ) {
3845						classList.splice(key, 1);
3846					}
3847				});
3848				elemClass = classList.join(' ');
3849			}
3850
3851			if ( typeof elemClass != 'undefined' && elemClass != '' ) {
3852				if (elemClass == 'container' && countChilds == 1) countChilds = 2;
3853				selector += elem.get(0).tagName + '.' + elemClass.trim().replace(/ +/g, '.');
3854			}
3855		}
3856
3857		if (controlExist && selector != '' && jQuery(selector).length == 0) {
3858			selector = '';
3859			break;
3860		}
3861
3862		var elem = elem.children();
3863	}
3864
3865	return selector.length == 0 ? defSelector : selector;
3866}
3867
3868function getUrlParams () {
3869	var params={};
3870	window.location.search
3871		.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(str,key,value) {
3872			params[key] = value;
3873		}
3874	);
3875	return params;
3876}
3877
3878function toggleClear() {
3879	var params = getUrlParams();
3880	jQuery(".wpfBlockClear").hide();
3881	jQuery(".wpfFilterWrapper").each(function(){
3882		var attr = jQuery(this).attr('data-get-attribute');
3883		if (attr in params) {
3884			jQuery(this).find(".wpfBlockClear").show();
3885		}
3886	});
3887	if ('wpf_min_price' in params || 'wpf_max_price' in params) {
3888		jQuery("[data-filter-type='wpfPrice']").find(".wpfBlockClear").show();
3889		jQuery("[data-filter-type='wpfPriceRange']").find(".wpfBlockClear").show();
3890	}
3891}
3892
3893//Get querystring value
3894function getParameterByName(name, searchUrl) {
3895	name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
3896	var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
3897		results = regex.exec(searchUrl);
3898	return results === null ? "" : decodeURIComponent(results[1]);//decodeURIComponent(results[1].replace(/\+/g, " "));
3899}
3900
3901function getCurrentUrlPartsWpf() {
3902	var parts = window.wpfNewUrl.split('?'),
3903		s = (parts[1] || '');
3904	return {href: window.wpfNewUrl, path: parts[0].replace(/#.*$/, ''), search: (s.length ? '?' + s : '')};
3905}
3906
3907//Add or modify querystring
3908function changeUrl(filterSlug, filterValue, $wooPage, $filterWrapper) {
3909	removePageQString();
3910	//Get query string filterValue
3911	$wooPage = (typeof $wooPage != 'undefined' ? $wooPage: false);
3912
3913	var curUrl = getCurrentUrlPartsWpf();
3914	if(!$wooPage){
3915		var searchUrl = decodeURIComponent(curUrl.search);
3916	}else{
3917		if($filterWrapper.attr('data-hide-url')){
3918			var searchUrl=$filterWrapper.attr('data-hide-url');
3919		} else {
3920			var searchUrl = '';
3921		}
3922	}
3923
3924	// New: Check if slug format enabled
3925	var wrapper = $filterWrapper.closest('.wpfMainWrapper');
3926
3927	var urlValue;
3928	if (searchUrl.indexOf("redirect")!==-1) {
3929		searchUrl = '';
3930	}
3931
3932	if(searchUrl.indexOf("?")== "-1") {
3933		var urlValue = curUrl.path + '?'+filterSlug+'='+filterValue;
3934	} else {
3935		//Check for filterSlug in query string, if not present
3936		if(searchUrl.indexOf('&'+filterSlug+'=')== "-1" && searchUrl.indexOf('?'+filterSlug+'=')== "-1") {
3937			var urlValue=searchUrl+'&'+filterSlug+'='+filterValue;
3938		//If filterSlug present in query string
3939		} else {
3940			var oldValue = getParameterByName(filterSlug, searchUrl);
3941			if(searchUrl.indexOf("?"+filterSlug+"=")!= "-1") {
3942				var urlValue = searchUrl.replace('?'+filterSlug+'='+oldValue,'?'+filterSlug+'='+filterValue);
3943			// add existing in url filter with another option
3944			} else {
3945				var urlValue = searchUrl.replace('&'+filterSlug+'='+oldValue,'&'+filterSlug+'='+filterValue);
3946			}
3947		}
3948		urlValue = curUrl.path + urlValue;
3949
3950		//history.pushState function is used to add history state.
3951		//It takes three parameters: a state object, a title (which is currently ignored), and (optionally) a URL.
3952	}
3953
3954	if(!$wooPage){
3955		window.wpfNewUrl = encodeURI(urlValue).indexOf('%25') === -1 ? encodeURI(urlValue) : urlValue;
3956	}
3957	objQueryString.key=filterValue;
3958	return urlValue;
3959}
3960
3961/**
3962 * removePageQString.
3963 *
3964 * @version 3.3.0
3965 */
3966function removePageQString() {
3967	var curUrl = getCurrentUrlPartsWpf(),
3968		path = curUrl.path,
3969		page = path.indexOf('/page/');
3970	if(page != -1 && history.pushState) {
3971		window.wpfNewUrl = path.substr(0, page + 1) + curUrl.search;
3972	} else {
3973		// also strip Brizy Pro's /bpage/N/ path segment
3974		var bpage = path.indexOf('/bpage/');
3975		if (bpage != -1 && history.pushState) {
3976			window.wpfNewUrl = path.substr(0, bpage + 1) + curUrl.search;
3977		} else {
3978			window.wpfNewUrl = curUrl.path + removePagenum(curUrl.search);
3979		}
3980	}
3981}
3982
3983function removePagenum(url) {
3984	return url.replace(/([&?])pagenum=\d+(&|$)/g, function(match, prefix, suffix) {
3985		return prefix === '?' && suffix === '&' ? '?' :
3986			   prefix === '&' && suffix === '' ? '' :
3987			   prefix;
3988	});
3989}
3990
3991/**
3992 * Removes querystring.
3993 *
3994 * @version 3.1.2
3995 */
3996function removeQString(key, $wooPage, $filterWrapper) {
3997	removePageQString();
3998	//Get query string value
3999	var curUrl = getCurrentUrlPartsWpf(),
4000		urlValue=decodeURI(curUrl.href);
4001	$wooPage = (typeof $wooPage != 'undefined' ? $wooPage: false);
4002	if(!$wooPage){
4003		var searchUrl=decodeURIComponent(curUrl.search);
4004	}else{
4005		if($filterWrapper.attr('data-hide-url')){
4006			var searchUrl=decodeURI($filterWrapper.attr('data-hide-url'));
4007		}else {
4008			var searchUrl = '';
4009		}
4010		var urlValue=curUrl.href + searchUrl;
4011	}
4012	if(key!="") {
4013		const oldValue = getParameterByName(key, searchUrl);
4014		const newUrlValue = new URL(urlValue);
4015		newUrlValue.searchParams.delete(key, oldValue);
4016		urlValue = newUrlValue.toString().replace(/\+/g, '%20');
4017		if($wooPage){
4018			urlValue = urlValue.replace(curUrl.href,'');
4019		}
4020	} else {
4021		if(!$wooPage){
4022			var searchUrl=decodeURIComponent(curUrl.search);
4023			urlValue=urlValue.replace(searchUrl,'');
4024		}else{
4025			var searchUrl=$filterWrapper.attr('data-hide-url');
4026			urlValue=urlValue.replace(searchUrl,'');
4027			urlValue = urlValue.replace(curUrl.href,'');
4028		}
4029	}
4030	if(!$wooPage){
4031		window.wpfNewUrl = encodeURI(urlValue).indexOf('%25') === -1 ? encodeURI(urlValue) : urlValue;
4032	}
4033	return urlValue.indexOf('%25') !== -1 ? decodeURI(urlValue) : urlValue;
4034}
4035
4036function checkArray(my_arr){
4037	for(var i=0;i<my_arr.length;i++){
4038		if(my_arr[i] === "")
4039			return false;
4040	}
4041	return true;
4042}
4043
4044jQuery.toQueryParams = function(str, separator) {
4045	separator = separator || '&';
4046	var obj = {};
4047	if (str.length == 0)
4048		return obj
4049	var c = str.substr(0,1),
4050		s = c=='?' || c=='#'  ? str.substr(1) : str,
4051		a = s.split(separator);
4052	for (var i=0; i<a.length; i++) {
4053		var p = a[i].indexOf('=');
4054		if (p < 0) {
4055			obj[a[i]] = '';
4056			continue
4057		}
4058		var k = decodeURIComponent(a[i].substr(0,p)),
4059			v = decodeURIComponent(a[i].substr(p+1)),
4060			bps = k.indexOf('[');
4061		if (bps < 0) {
4062			obj[k] = v
4063			continue;
4064		}
4065
4066		var bpe = k.substr(bps+1).indexOf(']');
4067		if (bpe < 0) {
4068			obj[k] = v
4069			continue;
4070		}
4071
4072		var bpv = k.substr(bps+1, bps+bpe-1),
4073			k = k.substr(0,bps);
4074		if (bpv.length <= 0) {
4075			if (typeof(obj[k]) != 'object') obj[k] = [];
4076			obj[k].push(v);
4077		} else {
4078			if (typeof(obj[k]) != 'object') obj[k] = {};
4079			obj[k][bpv] = v;
4080		}
4081	}
4082	return obj;
4083}
4084
4085function wpfChangeFiltersCount (wpfExistTerms, synchroFilterId) {
4086
4087	var wpfPage = window.wpfFrontendPage,
4088		curFilter = wpfPage.isSynchro ? (typeof(synchroFilterId) != 'undefined' && synchroFilterId.length ? '#'+synchroFilterId : '#'+wpfPage.currentLoadId) : 'body';
4089
4090	jQuery(curFilter).find(".wpfShowCount").find(".wpfCount").html("(0)");
4091	jQuery(curFilter).find(".wpfShowCount select:not([multiple]) option[data-count]").each(function(){
4092		var attr = jQuery(this).attr("data-term-name");
4093		jQuery(this).attr('data-count', 0).html(attr+" (0)");
4094	});
4095	jQuery(curFilter).find(".wpfShowCount select[multiple]").find("option").each(function(){
4096		attr = jQuery(this).attr("data-term-name");
4097		jQuery(this).attr('data-count', 0).html(attr+" (0)");
4098	});
4099
4100	jQuery(curFilter).find(".wpfShowCount").each(function(filterCounter){
4101
4102		var filter = jQuery(this);
4103		if (filter.attr("data-filter-type").length > 0) {
4104			var taxonomy = filter.data('taxonomy');
4105			if(typeof taxonomy == 'undefined' || taxonomy.length == 0) taxonomy = filter.data('slug');
4106
4107			if (taxonomy in wpfExistTerms) {
4108
4109				if (typeof (wpfExistTerms[taxonomy].relation) !== 'undefined') {
4110					var htmlArray = {};
4111					jQuery(curFilter).find('div.wpfShowCount[data-taxonomy="' + taxonomy + '"] li').each(function () {
4112						htmlArray[jQuery(this).data('term-id')] = jQuery('.wpfFilterTaxNameWrapper', this).html();
4113					});
4114
4115					jQuery.each(wpfExistTerms[taxonomy].relation, function (index, value) {
4116						jQuery.each(htmlArray, function (i, v) {
4117							if (v === value && i !== index) {
4118								wpfExistTerms[taxonomy][i] = wpfExistTerms[taxonomy][index];
4119								delete wpfExistTerms[taxonomy][index];
4120							}
4121						});
4122					});
4123				}
4124
4125				jQuery.each(wpfExistTerms[taxonomy], function (index, value) {
4126					changeCount(taxonomy, index, value, curFilter);
4127				});
4128
4129				delete wpfExistTerms[taxonomy];
4130			}
4131
4132		}
4133	});
4134
4135	window.wpfFrontendPage.disableLeerOptions();
4136	var multi = jQuery('.wpfShowCount').find('select[multiple]');
4137	if (multi.length) multi.multiselect('reload');
4138};
4139
4140function changeCount(taxonomy, index, value, curFilter) {
4141
4142	var oIndex = index;
4143	index = index.toLowerCase();
4144	var els = jQuery(curFilter).find('div.wpfShowCount[data-taxonomy="' + taxonomy + '"] [data-term-id="' + oIndex + '"]');
4145	if (els.length === 0) {
4146		els = jQuery(curFilter).find('div.wpfShowCount[data-slug="' + taxonomy + '"] [data-term-id="' + oIndex + '"]');
4147	}
4148	if (els.length === 0) {
4149		els = jQuery(curFilter).find('div.wpfShowCount[data-taxonomy="' + taxonomy + '"] [data-term-id="' + index + '"]');
4150	}
4151	if (els.length === 0) {
4152		els = jQuery(curFilter).find('div.wpfShowCount[data-slug="' + taxonomy + '"] [data-term-id="' + index + '"]');
4153	}
4154	if (els.length > 0) {
4155		els.each(function () {
4156			var el = jQuery(this);
4157			if (el.find('.wpfCount').length > 0) {
4158				el.find('.wpfCount:first').html('(' + value + ')');
4159			} else if (el.parent().attr('class') == 'wpfColorsColBlock') {
4160				el.parent().find('.wpfCount').html('(' + value + ')');
4161			} else {
4162				var attrname = el.attr('data-term-name');
4163				var tooltipstered = el.siblings('.tooltipstered');
4164				if (tooltipstered.length) {
4165					attrname = tooltipstered.attr('data-term-name');
4166					tooltipstered.tooltipster('content', '' + attrname + ' (' + value + ')');
4167					if (tooltipstered.attr('data-show-count')) tooltipstered.text(value);
4168				} else if (attrname !== undefined) {
4169					el.html('' + attrname + ' (' + value + ')');
4170				} else {
4171					el.html('' + index + ' (' + value + ')');
4172				}
4173			}
4174			if (el.is('option')) {
4175				el.attr('data-count', value);
4176			}
4177		});
4178	}
4179}
4180
4181// show/hide individual filter items
4182function wpfShowHideFiltersAtts(wpfExistTerms, wpfExistUsers, synchroFilterId) {
4183
4184	var wpfPage = window.wpfFrontendPage,
4185		curFilter = typeof(synchroFilterId) != 'undefined' && synchroFilterId.length ? synchroFilterId : wpfPage.currentLoadId;
4186
4187	wpfPage.restoreSelectsForSafari();
4188
4189	jQuery((curFilter ? '#' + curFilter + ' ' : '') + '.wpfFilterWrapper').each(function(){
4190		var filter = jQuery(this),
4191			filterType = filter.data('filter-type'),
4192			isTextFilter = filter.attr('data-display-type') == 'text',
4193			filterContentType = isTextFilter && filter.attr('data-control-products') == '1' ? 'taxonomy' : filter.data('content-type'),
4194			taxonomy = filter.data('taxonomy'),
4195			getAttr = filter.data('get-attribute'),
4196			isFilterCurentlyActivated = getParameterByName(getAttr, location.search),
4197			isHideActive = filter.data('hide-active'),
4198			isShowAll = Boolean(filter.data('show-all')),
4199			isNotInLogic = getAttr.indexOf('pr_filter') == -1 ? false : true,
4200			userExistIds = [];
4201
4202		switch (filterContentType) {
4203			case 'user':
4204				jQuery.each(wpfExistUsers, function (index, value) {
4205					userExistIds.push(parseInt(value.ID));
4206				});
4207				if (!isFilterCurentlyActivated && userExistIds.length > 0) {
4208					filter.find('[data-term-id]').each(function () {
4209						var el = jQuery(this),
4210							userId = el.data('term-id');
4211						if (userExistIds.indexOf(userId) >= 0) {
4212							el.show();
4213						} else {
4214							el.hide();
4215						}
4216					});
4217				}
4218				break;
4219			case 'taxonomy':
4220				if (typeof taxonomy == 'undefined' || taxonomy.length == 0) {
4221					taxonomy = filter.data('slug');
4222				}
4223
4224				if ((!isFilterCurentlyActivated || isHideActive) && !isNotInLogic && !isShowAll ) {
4225					if (taxonomy in wpfExistTerms || isFilterCurentlyActivated) {
4226						var termIds = wpfExistTerms[taxonomy] || {};
4227						filter.find('[data-term-id]').each(function () {
4228							var elem = jQuery(this),
4229								id = elem.data('term-id'),
4230								selected = isFilterCurentlyActivated && (elem.is('input:checked') || elem.find('input:checked').length || elem.is('option:selected'));
4231							if (id in termIds || selected) {
4232								if(elem.closest('.wpfButtonsFilter').length) elem.css('display', 'inline-block');
4233								else elem.show();
4234								if (elem.parent().hasClass('wpfColorsColBlock')) {
4235									elem.parent().parent().show();
4236								}
4237								if (elem.closest('.wpfColorsRow').length) {
4238									elem.parent().css('display', 'inline-block');
4239								}
4240							} else {
4241								elem.hide();
4242								elem.find('input').prop('checked', false);
4243								if (elem.parent().hasClass('wpfColorsColBlock')) {
4244									elem.parent().parent().hide();
4245								}
4246								if (elem.closest('.wpfColorsRow').length) {
4247									elem.parent().hide();
4248								}
4249							}
4250						});
4251
4252						if (filter.attr('data-display-type') == 'slider' ) {
4253							if (typeof(wpfPage.updateAttrSlider) == 'function') {
4254								wpfPage.updateAttrSlider(filter, termIds);
4255							}
4256						} else {
4257							// all terms display block already has css display none
4258							var hideSingle = filter.attr('data-hide-single') == '1',
4259								preSelector = hideSingle && filter.find('select[multiple]').length ? 'option' : '',
4260								selector = hideSingle && filter.find('.wpfColorsFilter').length ? 'li[data-term-slug]' : '[data-term-id]',
4261								cntAll = isTextFilter ? 1 : filter.find(preSelector+selector).length,
4262								cntHidden = filter.find(preSelector+selector+'[style*="none"]').length,
4263								limit = hideSingle ? 1 : 0;
4264							if (cntAll-cntHidden <= limit) {
4265								filter.hide();
4266							} else {
4267								filter.show();
4268							}
4269						}
4270					} else {
4271						filter.find('input').prop('checked', false);
4272						filter.find('select').val('');
4273						filter.hide();
4274					}
4275				}
4276				var multi = filter.find('select[multiple]');
4277				if (multi.length) multi.multiselect('reload');
4278
4279				if(typeof(window.wpfFrontendPage.wpfShowHideFiltersAttsPro) == 'function') {
4280					window.wpfFrontendPage.wpfShowHideFiltersAttsPro(filter);
4281				}
4282				break;
4283			default:
4284				// Sorry, we are out of ${expr}.
4285		}
4286	});
4287	wpfPage.removeHiddenOptionsForSafari();
4288}
4289
4290function wpfChangePriceFiltersCount(prices) {
4291	var _thisObj = window.wpfFrontendPage,
4292		noWooPage = _thisObj.noWoo,
4293		filterWrapper = jQuery('.wpfMainWrapper'),
4294		priceFilters = jQuery('.wpfFilterWrapper[data-filter-type="wpfPrice"].wpfNotActive');
4295
4296	jQuery('.wpfFilterWrapper[data-filter-type="wpfPrice"]').each(function () {
4297		var wpfPrice = jQuery(this);
4298		wpfPrice.attr('data-minvalue', prices.wpf_min_price).attr('data-maxvalue', prices.wpf_max_price);
4299
4300		wpfPrice.find('#wpfMinPrice').attr('min', prices.wpf_min_price).val(prices.wpf_min_price);
4301		wpfPrice.find('#wpfMaxPrice').attr('max', prices.wpf_max_price).val(prices.wpf_max_price);
4302
4303		if (wpfPrice.find(".ion-range-slider").length) {
4304			wpfPrice.find(".ion-range-slider").each(function () {
4305				jQuery(this).attr('data-min', prices.wpf_min_price).attr('data-max', prices.wpf_max_price);
4306				var ionSlider = jQuery(this).data("ionRangeSlider");
4307				ionSlider.update({
4308					min: prices.wpf_min_price,
4309					max: prices.wpf_max_price,
4310				});
4311			});
4312		}
4313	});
4314	window.wpfFrontendPage.eventsPriceFilter();
4315	_thisObj.getUrlParamsChangeFiltersValues();
4316}
4317
4318function hideFilterLoader( wrapper ) {
4319	wrapper.find('.wpfLoaderLayout').hide();
4320	wrapper.css({
4321		position: ''
4322	});
4323	wrapper.find('.wpfFilterWrapper').css({
4324		visibility: 'inherit'
4325	});
4326}
4327
4328function heightIdenticalInRow(selector) {
4329	var setMaxHeight = function (elements) {
4330		if (elements.length > 1) {
4331			var elementHeightMax = elements[0].height;
4332			for (var j = 1; j < elements.length; j++) {
4333				if (elements[j].height > elementHeightMax) {
4334					elementHeightMax = elements[j].height;
4335				}
4336			}
4337			for (var j = 0; j < elements.length; j++) {
4338				jQuery(elements[j].selector).height(elementHeightMax);
4339			}
4340		}
4341	};
4342	var elementsHeight = [];
4343	var rowIndex = 0;
4344	var elementIndex = 0;
4345
4346	jQuery(selector).each(function (index, element) {
4347		if (!elementsHeight[rowIndex]) {
4348			elementsHeight[rowIndex] = [];
4349		}
4350		if (
4351			elementsHeight[rowIndex][elementsHeight[rowIndex].length - 1]
4352			&&
4353			elementsHeight[rowIndex][elementsHeight[rowIndex].length - 1].top
4354			&&
4355			elementsHeight[rowIndex][elementsHeight[rowIndex].length - 1].top !== jQuery(element).offset().top
4356		) {
4357
4358			setMaxHeight(elementsHeight[rowIndex]);
4359			rowIndex++;
4360		}
4361		if (!elementsHeight[rowIndex]) {
4362			elementsHeight[rowIndex] = [];
4363		}
4364		elementsHeight[rowIndex].push({
4365			selector: selector + ':eq(' + elementIndex + ')',
4366			height: jQuery(element).height(),
4367			top: jQuery(element).offset().top
4368		});
4369		elementIndex++;
4370	});
4371	if (elementsHeight[rowIndex]) {
4372		setMaxHeight(elementsHeight[rowIndex]);
4373	}
4374}
4375
4376function wpfDoActionsAfterLoad (fid, isFound, requestData) {
4377	if (typeof (window.wpfFrontendPage.saveStatistics) == 'function') {
4378		window.wpfFrontendPage.saveStatistics(fid, isFound, requestData);
4379	}
4380}
4381
4382if (window.wpIinitialiseImmediately && window.wpfFrontendPage) {
4383	if (typeof isElementorEditMode == 'undefined') window.wpfFrontendPage.init();
4384}

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.