PageSourceSearch

https://oookaller.ru/catalog/view/javascript/mf/mega_filter.js?v2.0.4.4.7

js oookaller.ru collected 2026-10-07 03:34:19 UTC 86,867 bytes, 3,322 lines download raw bytes

1/**
2 * Mega Filter
3 */
4
5if( typeof Array.prototype.indexOf == 'undefined' ) {
6	Array.prototype.indexOf = function(obj, start) {
7		for( var i = ( start || 0 ), j = this.length; i < j; i++ ) {
8			if( this[i] === obj ) {return i;}
9		}
10		
11		return -1;
12   };
13};
14
15var MegaFilterINSTANCES = typeof MegaFilterINSTANCES == 'undefined' ? [] : MegaFilterINSTANCES;
16
17var MegaFilter = function(){ };
18
19MegaFilter.prototype = {
20	
21	/**
22	 * Kontener filtrów
23	 */
24	_box: null,
25			
26	/**
27	 * Opcje
28	 */
29	_options: null,
30			
31	/**
32	 * @var int
33	 */
34	_timeoutAjax: null,
35	
36	_timeoutSearchFiled: null,
37		
38	/**
39	* @var string
40	*/
41	_url			: null,
42	
43	/**
44	 * Separator URL
45	 * 
46	 * @var string
47	 */
48	_urlSep			: null,
49	
50	/**
51	 * Lista parametrów
52	 *
53	 * @var object
54	 */
55	_params			: null,
56	
57	/**
58	 * Lista scrolls
59	 * 
60	 * @var array
61	 */
62	_scrolls		: null,
63	
64	/**
65	 * Lista guzików
66	 * 
67	 * @var array
68	 */
69	_buttonsMore	: null,
70	
71	_liveFilters	: null,
72	
73	/**
74	 * Kontener główny
75	 *
76	 * @var jQuery
77	 */
78	_jqContent		: null,
79		
80	/**
81	 * Loader over results
82	 *
83	 * @var jQuery
84	 */
85	_jqLoader		: null,
86	
87	/**
88	 * Loader over filter
89	 * 
90	 * @var jQuery
91	 */
92	_jqLoaderFilter	: null,
93	
94	/**
95	 * Slidery
96	 * 
97	 * @type array
98	 */
99	_sliders		: null,
100		
101	/**
102	 * ID kontenera głównego
103	 *
104	 * @var string
105	 */
106	_contentId		: '#content',
107	
108	/**
109	 * Trwa oczekiwanie na odpowiedź serwera
110	 * 
111	 * @var bool
112	 */
113	_busy			: false,
114	
115	/**
116	 * W trakcie ładowania danych z serwra wprowadzono zmiany
117	 * 
118	 * @var bool
119	 */
120	_waitingChanges	: false,
121	
122	/**
123	 * Ostania odpowiedź serwera
124	 * 
125	 * @var string
126	 */
127	_lastResponse	: '',
128	
129	_refreshPrice : function(){},
130	
131	_inUrl : null,
132	
133	_isInit: false,
134	
135	_cache: null,
136	
137	_relativeScroll: null,
138	
139	_selectOptions: null,
140	
141	_lastUrl: null,
142	
143	_urlToFilters: null,
144	
145	_instanceIdx: 0,
146	
147	_inlineHorizontalUpdate: null,
148	
149	_lastEvent: null,
150	
151	_startUrl: null,
152	
153	_history: 1,
154	
155	_changed: false,
156	
157	_ajaxPagination: null,
158	
159	_seoAliases: null,
160	
161	////////////////////////////////////////////////////////////////////////////
162	
163	/**
164	 * Inicjuj klasę
165	 */
166	init: function( box, options ) {
167		var self = this,
168			i;
169		
170		self._instanceIdx = MegaFilterINSTANCES.length;
171			
172		if( options.routeHome == options.route && options.homePageAJAX ) {
173			self._contentId = options.homePageContentSelector;
174		} else if( options.contentSelector ) {
175			self._contentId = options.contentSelector;
176		}
177		
178		self._jqContent	= jQuery(self._contentId);
179		self._options	= options;
180		
181		if( ! self._jqContent.length ) {
182			self._contentId = '#maincontent';
183			
184			self._jqContent	= jQuery(self._contentId);
185		}
186		
187		if( self._startUrl === null ) {
188			self._startUrl = self.location();
189		}
190		
191		self._seoAliases				= {};
192		self._scrolls					= [];
193		self._buttonsMore				= [];
194		self._liveFilters				= [];
195		self._sliders					= [];
196		self._inlineHorizontalUpdate	= [];
197		self._box						= box;
198		self._selectOptions				= {};
199		self._cache						= {
200			'lastResponse'	: {},
201			'mainContent'	: {}
202		};
203		
204		self._box.find('[data-mf-toggle="tooltip"]').tooltip({
205			'viewport' : 'body',
206			'container' : 'body'
207		});
208		
209		self.initResponsive();
210		
211		if( self._options.manualInit && ! self._isInit ) {
212			var items = self._box.find('> .mfilter-content').find('> ul,> div').hide(),
213				$init = jQuery('<a href="#" style="padding: 10px; text-align: center; display: block;">' + self._options.text.init_filter + '</a>').appendTo( self._box.find('> .mfilter-content') );
214			
215			$init.click(function(){
216				$init.text( self._options.text.initializing );
217				
218				setTimeout(function(){
219					items.show();
220					self.boot();
221					$init.remove();
222				},100);
223				
224				return false;
225			});
226		} else {
227			self.boot();
228		}
229		
230		return self;
231	},
232	
233	boot: function() {
234		var self = this,
235			i;
236		
237		self.initUrls();
238
239		for( i in self._options.params ) {
240			if( typeof self._options.params[i] == 'function' ) continue;
241
242			if( typeof self._params[i] == 'undefined' ) {
243				self._params[i] = self._options.params[i];
244			}
245		}
246
247		self.initSliders();
248
249		//var t = this.microtime(true);
250		for( i in self ) {
251			if( i.indexOf( '_init' ) === 0 ) {
252				self[i]();
253			}
254		}
255		//alert(this.microtime(true)-t);
256		self._isInit = true;
257	},
258	
259	microtime: function(get_as_float) {
260		var now = new Date()
261			.getTime() / 1000;
262		var s = parseInt(now, 10);
263
264		return (get_as_float) ? now : (Math.round((now - s) * 1000) / 1000) + ' ' + s;
265	},
266
267	keys: function( obj ) {
268		var keys = [];
269		
270		for( var i in obj ) {
271			keys.push( i );
272		}
273		
274		return keys;
275	},
276	
277	base64_decode: function(data) {
278		var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
278+/=';
279		var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
280		  ac = 0,
281		  dec = '',
282		  tmp_arr = [];
283
284		if (!data) {
285		  return data;
286		}
287
288		data += '';
289
290		do { // unpack four hexets into three octets using index points in b64
291		  h1 = b64.indexOf(data.charAt(i++));
292		  h2 = b64.indexOf(data.charAt(i++));
293		  h3 = b64.indexOf(data.charAt(i++));
294		  h4 = b64.indexOf(data.charAt(i++));
295
296		  bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
297
298		  o1 = bits >> 16 & 0xff;
299		  o2 = bits >> 8 & 0xff;
300		  o3 = bits & 0xff;
301
302		  if (h3 == 64) {
303			tmp_arr[ac++] = String.fromCharCode(o1);
304		  } else if (h4 == 64) {
305			tmp_arr[ac++] = String.fromCharCode(o1, o2);
306		  } else {
307			tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
308		  }
309		} while (i < data.length);
310
311		dec = tmp_arr.join('');
312
313		return dec.replace(/\0+$/, '');
314	},
315	
316	sortKeys: function( data ) {
317		var keys = [],
318			sortData = [],
319			i;
320			
321		for( i in data ) {
322			sortData.push( [ i, data[i] ] );
323		}
324		
325		sortData.sort(function(a,b){
326			var sa = typeof a[1].sort_order == 'undefined' ? 0 : a[1].sort_order,
327				sb = typeof b[1].sort_order == 'undefined' ? 0 : b[1].sort_order;
328			
329			if( sa > sb ) {
330				return 1;
331			} else if( sa < sb ) {
332				return -1;
333			}
334			
335			return 0;
336		});
337		
338		for( i = 0; i < sortData.length; i++ ) {
339			keys.push( sortData[i][0] );
340		}
341		
342		return keys;
343	},
344	
345	/**
346	 * Inicjuj slidery
347	 * 
348	 * @return void
349	 */
350	initSliders: function(){
351		var self = this,
352			_init = false;
353		
354		function d( txt ) {
355			var $i = jQuery('<div>').html( txt ),
356				txt2 = $i.text();
357			$i.remove();
358			return txt2;
359		}		
360		
361		self._box.find('li.mfilter-filter-item.mfilter-slider').each(function(i){
362			var _this		= jQuery(this).attr('data-slider-id', i),
363				seo_name	= _this.attr('data-seo-name'),
364				data		= jQuery.parseJSON(self.base64_decode(_this.find('.mfilter-slider-data').html())),
365				$min		= _this.find('.mfilter-opts-slider-min'),
366				$max		= _this.find('.mfilter-opts-slider-max'),
367				$slider		= _this.find('.mfilter-slider-slider'),
368				update		= false,
369				keys, values, map;
370			
371			function init( data, update ) {
372				if( update ) {
373					return;
374				}
375				
376				keys	= self.sortKeys( data );
377				
378				if( _init ) {
379					if( ! keys.length ) {
380						$slider.slider().slider('disable');
381
382						return;
383					} else {
384						$slider.slider().slider('enable');
385					}
386				}
387				
388				if( keys.length == 1 ) {
389					data['copy'] = data[keys[0]];
390					keys.push('copy');
391				}
392				
393				var filters = /*update ? self.filters() :*/ self.urlToFilters();
394				
395				values	= typeof filters[seo_name] != 'undefined' ? (function(){ 
396					var d = [];
397					
398					for( var i = 0; i < filters[seo_name].length; i++ ) {
399						d[i] = self.decode( decodeURIComponent( filters[seo_name][i] ) );
400					} 
401					
402					return d;
403				})() : [ data[keys[0]].key, data[keys[keys.length-1]].key ];
404				map		= (function(){
405					var m = [ keys.indexOf( values[0] ), keys.indexOf( values[values.length-1] ) ];
406
407					if( m[0] != -1 && m[1] != -1 ) {
408						return typeof filters[seo_name] == 'undefined' ? [ 0, keys.length-1 ] : m;
409					}
410
411					for( var i = 0; i < keys.length; i++ ) {
412						if( m[0] == -1 ) {
413							if( values[0] == d( data[keys[i]].value ) ) {
414								m[0] = i;
415							}
416						} else if( m[1] == -1 ) {
417							if( values[values.length-1] == d( data[keys[i]].value ) ) {
418								m[1] = typeof data['copy'] == 'undefined' ? i : ( typeof filters[seo_name] == 'undefined' ? 1 : m[0] );
419							}
420						} else {
421							break;
422						}
423					}
424					
425					if( m[0] == -1 ) {
426						m[0] = 0;
427					}
428
429					if( m[1] == -1 ) {
430						m[1] = m[0];//keys.length-1;
431					}
432
433					return m;
434				})();
435				
436				$min.attr('data-key',map[0]).attr('data-min',0).val( d( data[keys[map[0]]].name ) );
437				$max.attr('data-key',map[1]).attr('data-max',keys.length-1).val( d( data[keys[map[1]]].name ) );
438				
439				$slider.slider({
440					range	: true,
441					min		: 0,
442					max		: keys.length-1,
443					values	: map,
444					slide	: function( e, ui ) {
445						if( typeof keys[ui.values[0]] == 'undefined' || typeof data[keys[ui.values[0]]] == 'undefined' )
446							return;
447						
448						if( typeof keys[ui.values[1]] == 'undefined' || typeof data[keys[ui.values[1]]] == 'undefined' )
449							return;
450						
451						$min.attr('data-key',ui.values[0]).val( d( data[keys[ui.values[0]]].name ) );
452						$max.attr('data-key',ui.values[1]).val( d( data[keys[ui.values[1]]].name ) );
453					},
454					stop	: function( e, ui ) {
455						update = true;
456						
457						if( self._options['refreshResults'] != 'using_button' ) {
458							self.runAjax();
459						}
460					}
461				});
462				
463				if( _init ) {
464					$slider.slider( 'value', $slider.slider('value') );
465				}
466				
467				_init = true;
468			}
469			
470			init( data );
471			
472			var s_idx = self._sliders.length;
473			
474			self._sliders.push({
475				data: data,
476				init: function( data, update ) {
477					init( data, update );
478				},
479				resetValues: function(){					
480					data = self._sliders[s_idx].data;
481					keys = self.sortKeys( data );
482					
483					$min.attr('data-key',0).attr('data-min',0).val( d( data[keys[map[0]]].name ) );
484					$max.attr('data-key',keys.length-1).attr('data-max',keys.length-1).val( d( data[typeof keys[map[1]] != 'undefined' ? keys[map[1]] : keys[map[0]]].name ) );
485					
486					$slider.slider( 'option', 'min', parseInt( $min.attr('data-min') ) );
487					$slider.slider( 'option', 'max', parseInt( $max.attr('data-max') ) );
488					$slider.slider( 'option', 'values', [
489						$min.attr('data-min'),
490						$max.attr('data-max')
491					]);
492					$slider.slider( 'value', $slider.slider( 'value' ) );
493					
494					update = true;
495				},
496				setValues: function(){
497					var vals = $slider.slider('values');
498					
499					$min.attr('data-key',vals[0]).val( d( data[keys[vals[0]]].name ) );
500					$max.attr('data-key',vals[1]).val( d( data[typeof keys[map[1]] != 'undefined' ? keys[map[1]] : keys[map[0]]].name ) );
501				},
502				getValues: function(){
503					if( $min.attr('data-key') == $min.attr('data-min') && $max.attr('data-key') == $max.attr('data-max') && self.keys( data ).length == self.keys( self._sliders[s_idx].data ).length ) {
504						return [];
505					}
506					
507					var min		= parseInt( $min.attr('data-key') ),
508						max		= parseInt( $max.attr('data-key') ),
509						vals	= [];
510					
511					for( var i = min; i <= max; i++ ) {
512						var key = keys[i];
513						
514						if( ! key ) continue;
515						
516						if( typeof data[key] == 'undefined' ) {
517							key = keys[0];
518						}
519						
520						vals.push( encodeURIComponent( self.encode( d( data[key].value ) ) ) );
521					}
522					
523					return vals;
524				}
525			});
526		});
527	},
528	
529	initResponsive: function(){
530		var self	= this,
531			column	= null,
532			moved	= false,
533			hidden	= true;
534	
535		if( self._box.hasClass( 'mfilter-hide-container' ) ) {
536			column = self._box.parent();
537			self._box.removeClass( 'mfilter-content_top mfilter-modern-horizontal mfilter-hide' );
538		} else if( self._box.hasClass( 'mfilter-column_left' ) ) {
539			column = jQuery('#column-left');
540		} else if( self._box.hasClass( 'mfilter-column_right' ) ) {
541			column = jQuery('#column-right');
542		} else {
543			return;
544		}
545		
546		var id = 'mfilter-free-container-' + jQuery('[id^="mfilter-free-container"]').length,
547			cnt = jQuery('<div class="mfilter-free-container mfilter-free-container-closed mfilter-direction-' + self._options.direction + '">')
548				.prependTo( jQuery('body') ),
549			btn = jQuery('<div class="mfilter-free-button">')
550				.appendTo( cnt )
551				.click(function(){
552					if( hidden ) {
553						cnt.animate(self._options.direction == 'rtl' ? {
554							'marginRight' : 0
555						} : {
556							'marginLeft' : 0
557						}, 500, function(){
558							self._relativeScroll.refresh();
559							cnt.addClass('mfilter-free-container-opened').removeClass('mfilter-free-container-closed');
560						});
561					} else {
562						cnt.animate(self._options.direction == 'rtl' ? {
563							'marginRight' : - ( cnt.outerWidth(true)<cnt.outerWidth()?cnt.outerWidth():cnt.outerWidth(true) )
564						} : {
565							'marginLeft' : - cnt.outerWidth(true)
566						}, 500, function(){
567							cnt.addClass('mfilter-free-container-closed').removeClass('mfilter-free-container-opened');
568						});
569					}
570			
571					hidden = ! hidden;
572				}),
573			cnt2 = jQuery('<div>')
574				.css('overflow','hidden')
575				.attr('id', id)
576				.appendTo( cnt ),
577			cnt3 = jQuery('<div>')
578				.appendTo( cnt2 ),
579			src = jQuery('<span class="mfilter-before-box">');
580		
581		function reinit() {
582			var scroll = new IScroll( '#' + id, {
583				bounce: false,
584				scrollbars: true,
585				mouseWheel: true,
586				interactiveScrollbars: true,
587				mouseWheelSpeed: 120
588			});
589			
590			scroll.reinit = function(){
591				if( ! cnt.hasClass('mfilter-free-container-opened') ) return;
592				
593				var top = $('#' + id + ' > div:first').attr('style');
594						
595				if( typeof top != 'undefined' ) {
596					top = top.match(/translate\(([\-0-9]+)px, ([\-0-9]+)px\)/);
597				}
598				
599				self._relativeScroll.destroy();
600				
601				self._relativeScroll = reinit();
602				
603				if( top && typeof top[1] != 'undefined' && typeof top[2] != 'undefined' ) {
604					self._relativeScroll.scrollTo( parseInt( top[1] ), parseInt( top[2] ) );
605				}
606			};
607			
608			return scroll;
609		}
610	
611		self._relativeScroll = reinit();
612		
613		self._box.before( src );
614		
615		if( ! column.length ) {
616			column = self._box.parent();
617		}
618		
619		function isVisible() {
620			var visible = column.is(':visible'),
621				height	= jQuery(window).height() - 50;
622			
623			if( visible && moved ) {
624				cnt.hide();
625				
626				src.after( self._box );
627				
628				if( ! hidden )
629					btn.trigger('click');
630				
631				moved = false;
632			} else if( ! visible && ! moved ) {
633				cnt.show();
634				
635				cnt3.append( self._box );
636				
637				moved = true;
638			}
639			
640			if( moved ) {
641				cnt2.css( 'max-height', height + 'px' );
642				self._relativeScroll.refresh();
643			}
644		}
645		
646		jQuery(window).resize(function() {
647			isVisible();
648		});
649		
650		isVisible();
651	},
652	
653	location: function(){
654		var self = this,
655			url = document.location.href.toString();
656		
657		if( self._options.seo.alias != '' ) {
658			url = url.replace( '/' + encodeURIComponent( self._options.seo.alias ), '' );
659		}
660		
661		for( var i in self._seoAliases ) {
662			url = url.replace( '/' + encodeURIComponent( i ), '' );
663		}
664		
665		return url;
666	},
667	
668	locationPath: function(){
669		var self = this,
670			location = self.location();
671		
672		return decodeURIComponent( self.parse_url( location ).path ).replace( /\/mfp,([a-z0-9\-_]+\[[^\]]*\],?)+/g, '' ); 
673	/*	return self.parse_url( location ).path; */
674	},
675	
676	initUrls: function( url ) {
677		var self = this;
678
679		if( typeof url == 'undefined' ) {
680			url	 = self.location().split('#')[0];
681		}
682		
683		self._urlSep	= self._parseSep( url ).urlSep;
684		self._url		= self._parseSep( url ).url;
685		self._params	= self._parseUrl( url );
686		self._inUrl		= self._parseUrl( url );
687	},
688	
689	_initMfImage: function() {
690		var self = this;
691		
692		self._box.find('.mfilter-image input').change(function(){
693			var s = jQuery(this).is(':checked'),
694				t = jQuery(this).attr('type');
695				
696			if( t == 'radio' ) {
697				jQuery(this).parent().parent().find('.mfilter-image-checked').removeClass('mfilter-image-checked');
698			}
699			
700			jQuery(this).parent()[s?'addClass':'removeClass']('mfilter-image-checked');
701		});
702		
703		self._box.find('.mfilter-image input:checked').parent().addClass('mfilter-image-checked');
704	},
705	
706	__initTreeCategoryEvents: function() {
707		var self = this,
708			$path = self._box.find('input[name="path"]');
709		
710		self._box.find('li.mfilter-filter-item.mfilter-tree.mfilter-categories')[self._box.find('.mfilter-category-tree > ul > li').length?'show':'hide']();
711			
712		self._box.find('.mfilter-category-tree').each(function(){
713			var _this = jQuery(this),
714				ul = _this.find('> ul'),
715				top_url = ul.attr('data-top-url'),
716				top_path = ul.attr('data-top-path').split('_');
717		
718			_this.find('.mfilter-to-parent a').unbind('click').bind('click', function(){
719				var parts = (jQuery(this).attr('data-path')?jQuery(this).attr('data-path'):$path.val()).split('_');
720
721				parts.pop();
722
723				if( top_url != '' && parts.length <= top_path.length ) {
724					window.location.href = self.createUrl(top_url);
725				} else {
726					$path.val( parts.join('_') );
727
728					self.runAjax();
729				}
730
731				return false;
732			});
733				
734			_this.find('a[data-parent-id]').click(function(){
735				if( self._busy ) return false;
736
737				var id = jQuery(this).attr('data-id'),
738					path = $path.val(),
739					parts = path.split('_'),
740					last = parts[parts.length-1].split(',');
741					
742				self._cache['cat_'+id] = jQuery(this).text();
743				
744				if( last.indexOf( id ) == -1 ) {				
745					if( path != '' ) {
746						path += '_';
747					}
748
749					path += id;
750				
751					$path.val( path );
752				}
753				
754				self.runAjax();
755
756				return false;
757			});
758		});
759	},
760	
761	_initTreeCategory: function( force ) {
762		var self = this,
763			$path = self._box.find('input[name="path"]');
764		
765		if( self._isInit && force !== true ) {
766			self.__initTreeCategoryEvents();
767			
768			return;
769		}
770		
771		if( ! $path.val() && ! self._isInit ) {
772			if( typeof self._options.params.mfp_path != 'undefined' ) {
773				$path.val( self._options.params.mfp_path );
774			} else if( typeof self._options.params.mfp_org_path != 'undefined' ) {
775				$path.val( self._options.params.mfp_org_path );
776			} else if( typeof self._options.params.path != 'undefined' ) {
777				$path.val( self._options.params.path );
778			}
779		}
780		
781		self._box.find('.mfilter-category-tree').each(function(){
782			if( $path.val().indexOf( '_' ) > -1 || ( $path.val() && ! self._options.params.path ) || ( $path.val() && self._options.route != self._options.routeCategory ) ) {
783				jQuery(this).find('ul').prepend(jQuery('<li class="mfilter-to-parent">')
784					.append(jQuery('<a>')
785						.html((function(){
786							var parts = $path.val().split('_'),
787								cat = parts[parts.length-1];
788							
789							return typeof self._cache['cat_'+cat] != 'undefined' ? self._cache['cat_'+cat] : self._options.text.go_to_top;
790						}))
791					)
792				);
793			}
794		});
795		
796		self.__initTreeCategoryEvents();
797	},
798	
799	_initBox: function() {
800		var self = this;
801		
802		if( self._isInit ) return;
803		
804		if( self._box.hasClass( 'mfilter-content_top' ) ) {
805			self._box.find('.mfilter-content > ul > li').each(function(i){
806				if( i && i % 4 == 0 ) {
807					jQuery(this).before('<li style="clear:both; display:block;"></li>');
808				}
809			});
810		}
811	},
812	
813	_initTextFields: function() {
814		var self = this;
815		
816		self._box.find('.mfilter-filter-item.mfilter-text').each(function(){
817			var _this	= jQuery(this),
818				name	= _this.attr('data-seo-name'),
819				input	= _this.find('input[type=text]');
820				
821			function clear() {
822				if( self._cache['txt_field_'+name] ) {
823					clearTimeout( self._cache['txt_field_'+name] );
824				}
825				
826				self._cache['txt_field_'+name] = null;
827			}
828				
829			input.bind('keydown', function(e){
830				if( e.keyCode == 13 ) {
831					clear();
832					
833					self.ajax();
834					
835					return false;
836				}
837			}).bind('keyup.mf_shv', function(){
838				input[input.val()?'addClass':'removeClass']('mfilter-text-has-value');
839			}).bind('keyup', function(e){
840				clear();
841				
842				if( self._options['refreshResults'] != 'using_button' ) {
843					self._cache['txt_field_'+name] = setTimeout(function(){
844						self.ajax();
845
846						self._cache['txt_field_'+name] = null;
847					}, 1000);
848				}
849			}).trigger('keyup.mf_shv');
850		});
851	},
852	
853	_initSearchFiled: function() {
854		var self = this,
855			searchField = self._box.find('input[id="mfilter-opts-search"]'),
856			searchButton = self._box.find('[id="mfilter-opts-search_button"]');
857			
858		if( ! searchField.length )
859			return;
860			
861		var refreshDelay = parseInt( searchField.unbind('keyup keydown click').attr('data-refresh-delay').toString().replace(/[^0-9\-]+/, '') ),
862			lastValue = searchField.val();
863		
864		function clearInt() {
865			if( self._timeoutSearchFiled )
866				clearTimeout( self._timeoutSearchFiled );
867			
868			self._timeoutSearchFiled = null;
869		}
870	
871		if( refreshDelay != '-1' ) {
872			searchField.bind('keyup', function(e){
873				if( jQuery(this).val() == lastValue )
874					return;
875				
876				if( ! refreshDelay ) {
877					self.ajax();
878				} else if( e.keyCode != 13 ) {
879					clearInt();
880					
881					self._timeoutSearchFiled = setTimeout(function(){
882						self.ajax();
883						
884						self._timeoutSearchFiled = null;
885					}, refreshDelay);
886				}
887				
888				lastValue = searchField.val();
889			});
890		}
891		
892		searchField.bind('keydown', function(e){
893			if( e.keyCode == 13 ) {
894				clearInt();
895				
896				self.ajax();
897				
898				return false;
899			}
900		}).bind('keyup.mf_shv', function(){
901			jQuery(this)[jQuery(this).val()?'addClass':'removeClass']('mfilter-search-has-value');
902		}).trigger('keyup.mf_shv');
903	
904		searchButton.bind('click', function(){
905			clearInt();
906			
907			self.ajax();
908			
909			return false;
910		});
911	},
912	
913	encode: function( string ) {	
914		string = string.replace( /,/g, 'LA==' );
915		string = string.replace( /\[/g, 'Ww==' );
916		string = string.replace( /\]/g, 'XQ==' );
917		string = string.replace( /"/g, 'Ig==' );
918		string = string.replace( /'/g, 'Jw==' );
919		string = string.replace( /&/g, 'Jg==' );
920		
921		return string;
922	},
923	
924	decode: function( string ) {	
925		string = string.replace( /LA==/g, ',' );
926		string = string.replace( /Ww==/g, '[' );
927		string = string.replace( /XQ==/g, ']' );
928		string = string.replace( /Ig==/g, '"' );
929		string = string.replace( /Jw==/g, "'" );
930		string = string.replace( /Jg==/g, '&' );
931		
932		return string;
933	},
934	
935	_parseSep: function( url ) {
936		var self = this,
937			urlSep = null;
938		
939		if( typeof url == 'undefined' )
940			url = self._url;
941		
942		if( ! self._options.smp.isInstalled || self._options.smp.disableConvertUrls ) {
943			url		= self.parse_url( url );
944			url		= url.scheme + '://' + url.host + (url.port ? ':'+url.port: '') + url.path;
945			url		= url.split('&')[0];
946		} else {
947			url		= url.indexOf('?') > -1 ? url.split('?')[0] : url.split(';')[0];
948		}
949		
950		urlSep	= {
951			'f' : '?',
952			'n' : '&'
953		};
954		
955		return {
956			url : url,
957			urlSep : urlSep
958		};
959	},
960	
961	/**
962	 * Inicjuj kontener
963	 */
964	_initContent: function() {
965		var self = this;
966		
967		self._jqContent
968			.css('position', 'relative');
969	},
970	
971	/**
972	 * @return {scheme: 'http', host: 'hostname', user: 'username', pass: 'password', path: '/path', query: 'arg=value', fragment: 'anchor'}
973	 */
974	parse_url: function(str, component) {
975		var query, key = ['source', 'scheme', 'authority', 'userInfo', 'user', 'pass', 'host', 'port',
976			'relative', 'path', 'directory', 'file', 'query', 'fragment'
977			],
978			ini = (this.php_js && this.php_js.ini) || {},
979			mode = (ini['phpjs.parse_url.mode'] &&
980			ini['phpjs.parse_url.mode'].local_value) || 'php',
981			parser = {
982			php: /^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
983			strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
984			loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/\/?)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // Added one optional slash to post-scheme to catch file:/// (should restrict this)
985			};
986
987		var m = parser[mode].exec(str),
988			uri = {},
989			i = 14;
990		while (i--) {
991			if (m[i]) {
992			uri[key[i]] = m[i];
993			}
994		}
995
996		if (component) {
997			return uri[component.replace('PHP_URL_', '')
998			.toLowerCase()];
999		}
1000		if (mode !== 'php') {
1001			var name = (ini['phpjs.parse_url.queryKey'] &&
1002			ini['phpjs.parse_url.queryKey'].local_value) || 'queryKey';
1003			parser = /(?:^|&)([^&=]*)=?([^&]*)/g;
1004			uri[name] = {};
1005			query = uri[key[12]] || '';
1006			query.replace(parser, function($0, $1, $2) {
1007			if ($1) {
1008				uri[name][$1] = $2;
1009			}
1010			});
1011		}
1012		delete uri.source;
1013		return uri;
1014	},
1015	
1016	baseTypes: function( skip ) {
1017		var self	= this,
1018			types	= [];
1019		
1020		function find( self ) {
1021			self._box.find('[data-base-type]').each(function(){
1022				var baseType = jQuery(this).attr('data-base-type'),
1023					type = jQuery(this).attr('data-type');
1024
1025				if( baseType == 'categories' ) {
1026					baseType += ':' + type;
1027				}
1028
1029				if( types.indexOf( baseType ) > -1 ) return;
1030				if( typeof skip != 'undefined' && skip.indexOf( baseType ) > -1 ) return;
1031				
1032				if( type == 'text' ) return;
1033
1034				types.push( baseType );
1035			});
1036		}
1037		
1038		find( self );
1039		
1040		for( var i = 0; i < MegaFilterINSTANCES.length; i++ ) {
1041			if( i == self._instanceIdx ) continue;
1042			
1043			find( MegaFilterINSTANCES[i] );
1044		}
1045		
1046		return types;
1047	},
1048	
1049	_ajaxUrl: function( url ) {
1050		if( this.parse_url( document.location.toString() ).scheme == 'https' && this.parse_url( url ).scheme == 'http' ) {
1051			url = url.replace( 'http://', 'https://' );
1052		}
1053		
1054		url = url.replace( /\/mfp,([a-z0-9\-_]+\[[^\]]*\],?)+/g, '' );
1055		
1056		var self = this,
1057			params = url.indexOf('?') > -1 ? url.split('?')[1] : '',
1058			parts = ( url.indexOf('?') > -1 ? url.split('?')[0] : url ).split('/');
1059		
1060		for( i = 0; i < parts.length; i++ ) {
1061			if( /page-[0-9]+/.test( parts[i] ) ) {
1062				delete parts[i];
1063			}
1064		}
1065		
1066		url = parts.join('/');
1067		url = url.replace('://', '###URL###');
1068		url = url.replace( /\/+/g, '/' );
1069		url = url.replace('###URL###', '://');
1070		
1071		if( params != '' ) {
1072			url += '?' + params;
1073		}
1074		
1075		if( self._options.mijoshop ) {
1076			return url + ( url.indexOf('?') > -1 ? '&' : '?' ) + 'option=com_mijoshop&format=raw';
1077		}
1078		
1079		if( self._options.joo_cart != false ) {
1080			function parse( u ) {
1081				u = u.replace( 'index.php', '' );
1082				u = u.replace( /\/$/, '' );
1083				
1084				return u + '/';
1085			}
1086		
1087			var site_url 	= parse( self._options.joo_cart.site_url ),
1088				main_url 	= parse( self._options.joo_cart.main_url ),
1089				route 		= url.indexOf( 'index.php' ) > -1 ? self._parseUrl( url, {} ).route : url.replace( main_url, '' ),
1090				query		= self.parse_url( url ).query;
1091			
1092			if( typeof route == 'undefined' ) {
1093				route = '';
1094			}
1095			
1096			if( typeof query == 'undefined' ) {
1097				query = '';
1098			}
1099			
1100			if( route.indexOf('?') > -1 ) {
1101				route = route.split('?')[0];
1102			}
1103			
1104			if( route == 'module/mega_filter/getajaxinfo' ) {
1105				return site_url + 'index.php?route=' + route + ( query ? '&' + query : '' ) + '&option=com_opencart&format=raw';
1106			}
1107		}
1108		
1109		return url;
1110	},
1111	
1112	/**
1113	 * Inicjuj informacje o ilości
1114	 */
1115	_initCountInfo: function() {
1116		var self = this;
1117		
1118		if( ! self._options.calculateNumberOfProducts || self._isInit )
1119			return;
1120		
1121		jQuery.ajax({
1122			'url'		: self._ajaxUrl( self.createUrl( self._options.ajaxGetInfoUrl, jQuery.extend( {}, self._params ), true ) ),
1123			'type'		: 'GET',
1124			'data'		: {
1125				'mfilterIdx'	: self._options.idx,
1126				'mfilterRoute'	: self._options.route,
1127				'mfilterBTypes'	: self.baseTypes(['categories:tree','categories:cat_checkbox']).join(','),
1128				'mfilterLPath'	: self.locationPath()
1129			},
1130			'success'	: function( response ) {
1131				var $tmp = jQuery('<tmp>').html( response );
1132				
1133				self._parseInfo( self.base64_decode($tmp.find('#mfilter-json').html()) );
1134				
1135				/*self._cache.mainContent[self.location()] = {
1136					'html'	: self._jqContent.html(),
1137					'json'	: response
1138				};*/
1139			},
1140			'error'		: function() {
1141				
1142			}
1143		});
1144		
1145		self._parseInfo('{"stock_status":[],"manufacturers":[],"rating":[],"attributes":[],"options":[],"filters":[]}',true);
1146	},
1147	
1148	_parseInfo: function( data, first ) {
1149		var self	= this,
1150			filters	= self.filters(),
1151			json	= jQuery.parseJSON( data );
1152		
1153		for( var i in json ) {
1154			switch( i ) {
1155				case 'categories:tree' : {
1156					self._box.find('.mfilter-category-tree > ul > li').remove();
1157					
1158					for( var j = 0; j < json[i].length; j++ ) {
1159						if( self._options.hideInactiveValues && json[i][j].cnt == '0' ) continue;
1160						
1161						self._box.find('.mfilter-category-tree > ul').append(jQuery('<li class="mfilter-tb-as-tr">')
1162							.append(jQuery('<div class="mfilter-tb-as-td">')
1163								.append(jQuery('<a>')
1164									.attr('data-id', json[i][j].id)
1165									.attr('data-parent-id', json[i][j].pid)
1166									.html( json[i][j].name )
1167								)
1168							)
1169							.append('<div class="mfilter-tb-as-td mfilter-col-count"><span class="mfilter-counter">' + json[i][j].cnt + '</span></div>')
1170						);
1171					}
1172					
1173					self._initTreeCategory( true );
1174					
1175					break;
1176				}
1177				case 'categories:cat_checkbox' : {
1178					var cnt = {};
1179					
1180					for( var j in json[i] ) {
1181						cnt[json[i][j].id] = json[i][j].cnt;
1182					}
1183					
1184					self._box.find('.mfilter-filter-item.mfilter-cat_checkbox').each(function(){
1185						var $self = jQuery(this),
1186							cx = 0,
1187							idx = 0;
1188						
1189						$self.find('input[value]').each(function(i){
1190							var $self2 = $(this),
1191								$parent = $self2.parent().parent(),
1192								$cnt = $parent.find('.mfilter-counter'),
1193								checked = $self2.is(':checked'),
1194								id = $self2.val(),
1195								c = typeof cnt[id] == 'undefined' ? 0 : parseInt( cnt[id] ),
1196								ct = c;
1197							
1198							if( typeof filters['path'] != 'undefined' ) {
1199								if( filters['path'].indexOf( encodeURIComponent( id ) ) == -1 ) {
1200									ct = '+' + ct;
1201								}
1202							}
1203								
1204							$cnt.text( ct )[checked?'addClass':'removeClass']('mfilter-close');
1205							
1206							if( c ) {
1207								cx++;
1208								$parent.removeClass('mfilter-hide mfilter-first-child');
1209							}
1210							
1211							if( checked || c ) {
1212								$self2.removeAttr('disabled');
1213								$parent.removeClass('mfilter-disabled');
1214							} else {
1215								$self2.attr('disabled',true);
1216								$parent.addClass('mfilter-disabled');
1217							}
1218							
1219							if( ! $parent.hasClass('mfilter-hide') ) {
1220								if( i > 0 && idx == 0 ) {
1221									$parent.addClass('mfilter-first-child');
1222								}
1223								idx++;
1224							}
1225						});
1226						
1227						if( cx ) {
1228							$self.removeClass('mfilter-hide');
1229						}
1230					});
1231					
1232					break;
1233				}
1234				case 'price' : {
1235					var priceRange = self.getPriceRange();
1236					
1237					if( priceRange.min == self._options.priceMin && priceRange.max == self._options.priceMax ) {
1238						self._box.find('[id="mfilter-opts-price-min"]').val( json[i].min );
1239						self._box.find('[id="mfilter-opts-price-max"]').val( json[i].max );
1240					}
1241					
1242					self._options.priceMin = json[i].min;
1243					self._options.priceMax = json[i].max;
1244					
1245					self._refreshPrice();
1246					
1247					break;
1248				}
1249				case 'tags' :
1250				case 'model' :
1251				case 'sku' :
1252				case 'upc' :
1253				case 'ean' :
1254				case 'jan' :
1255				case 'isbn' :
1256				case 'mpn' :
1257				case 'location' :
1258				case 'length' :
1259				case 'width' :
1260				case 'height' :
1261				case 'weight' :
1262				case 'rating' :
1263				case 'attributes' :
1264				case 'filters' :
1265				case 'options' :
1266				case 'manufacturers' :
1267				case 'stock_status' : {				
1268					self._box.find('.mfilter-filter-item.mfilter-' + i).each(function(){
1269						var $item		= jQuery(this),
1270							seo			= $item.attr('data-seo-name'),
1271							id			= $item.attr('data-id'),
1272							$items		= $item.find( '.mfilter-options .mfilter-option'),
1273							hidden		= 0;
1274						
1275						$items.each(function(){
1276							var $self		= jQuery(this),
1277								$input		= $self.find('input[type=checkbox],input[type=radio],select'),
1278								val			= $input.val(),
1279								$counter	= jQuery(this).find('.mfilter-counter'),
1280								text		= '',
1281								cnt			= json[i];							
1282							
1283							if( id && typeof cnt[id] != 'undefined' ) {
1284								cnt = cnt[id];
1285							}
1286							
1287							if( $self.hasClass( 'mfilter-select' ) ) {
1288								var $options	= $input.find('option'),
1289									hOptions	= 0,
1290									val			= $input.val(),
1291									idx			= $input.prop('selectedIndex');
1292								
1293								if( typeof self._selectOptions[seo] == 'undefined' ) {
1294									self._selectOptions[seo] = [];
1295									
1296									$options.each(function(){
1297										self._selectOptions[seo].push({
1298											'name'	: jQuery(this).attr('data-name'),
1299											'id'	: jQuery(this).attr('id'),
1300											'value'	: jQuery(this).attr('value'),
1301											'text'	: jQuery(this).html()
1302										});
1303									});
1304								}
1305								
1306								$options.remove();
1307								
1308								(function(){
1309									function add( $option ) {
1310										$input.append( $option );
1311										
1312										if( val == $option.val() ) {
1313											idx = $input.find('option').length-1;
1314										}
1315									}
1316									
1317									for( var i = 0; i < self._selectOptions[seo].length; i++ ) {
1318										var $option = jQuery('<option>')
1319											.attr('value', self._selectOptions[seo][i].value);
1320
1321										if( self._selectOptions[seo][i].name ) {
1322											$option.attr('data-name', self._selectOptions[seo][i].name);
1323										}
1324
1325										if( self._selectOptions[seo][i].id ) {
1326											$option.attr('id', self._selectOptions[seo][i].id);
1327										}
1328
1329										if( self._selectOptions[seo][i].id ) {
1330											var idd = self._selectOptions[seo][i].id.split('-').pop();
1331
1332											if( first || typeof cnt[idd] != 'undefined' ) {
1333												$option.html( ( ! first && self._options.showNumberOfProducts ? '(' + cnt[idd] + ') ' : '' ) + self._selectOptions[seo][i].name );
1334												
1335												add( $option );
1336											} else {
1337												$option.attr('disabled', true).html( ( self._options.showNumberOfProducts ? '(0)' : '' ) + self._selectOptions[seo][i].name );
1338
1339												if( ! self._options.hideInactiveValues ) {
1340													add( $option );
1341												}
1342
1343												hOptions++;
1344											}
1345										} else {
1346											$option.html( self._selectOptions[seo][i].text );
1347											add( $option );
1348										}
1349									}
1350								})();
1351								
1352								if( idx >= 0 ) {
1353									$input.prop('selectedIndex', idx);
1354								}
1355								
1356								if( hOptions == self._selectOptions[seo].length ) {
1357									hidden++;
1358								}
1359							} else if( $self.hasClass( 'mfilter-slider' ) ) {
1360								//if( self._options.hideInactiveValues ) {
1361									self._box.find('[data-id="' + id + '"][data-slider-id]').each(function(){
1362										var slider_id = jQuery(this).attr('data-slider-id'),
1363											data = {};
1364
1365										for( var i in self._sliders[slider_id].data ) {
1366											if( typeof cnt != 'undefined' && typeof cnt[i] != 'undefined' && parseInt( cnt[i] ) > 0 ) {
1367												data[i] = self._sliders[slider_id].data[i];
1368											}
1369										}
1370										
1371										self._sliders[slider_id].init( data, true );
1372									});
1373								//}
1374							} else if( $self.hasClass( 'mfilter-text' ) ) {
1375								$input = $self.find('input[type=text]');
1376								
1377								if( typeof filters[seo] != 'undefined' ) {
1378									
1379								} else {
1380									
1381								}
1382							} else {
1383								var idd = $input.attr('id').split('-').pop();
1384								
1385								if( typeof filters[seo] != 'undefined' ) {
1386									if( filters[seo].indexOf( encodeURIComponent( self.encode( val ) ) ) > -1 ) {
1387										$counter.addClass( 'mfilter-close' );
1388									} else {
1389										if( ! $item.hasClass( 'mfilter-radio' ) && ! $item.hasClass('mfilter-image_list_radio') /*&& base_type != 'option'*/ )
1390											text += '+';
1391
1392										$counter.removeClass( 'mfilter-close' );
1393									}
1394								} else {
1395									$counter.removeClass( 'mfilter-close' );
1396								}
1397								
1398								$self.removeClass('mfilter-first-child mfilter-last-child mfilter-disabled mfilter-hide mfilter-visible');
1399								$self.parent().removeClass('mfilter-hide');
1400
1401								if( typeof cnt[idd] != 'undefined' && parseInt( cnt[idd] ) > 0 ) {
1402									text += cnt[idd];
1403
1404									$self.addClass('mfilter-visible');
1405									$input.attr('disabled', false);
1406								} else {
1407									text = '0';
1408									hidden++;
1409									
1410									$self.addClass('mfilter-disabled');
1411									$input.attr('disabled',true);
1412										
1413									if( first !== true && self._options.hideInactiveValues ) {
1414										$self.addClass('mfilter-hide');
1415										
1416										if( self._box.hasClass('mfilter-content_top') ) {
1417											$self.parent().addClass('mfilter-hide');
1418										}
1419									}
1420								}
1421
1422								$counter.text( text );
1423							}
1424						});
1425						
1426						if( first !== true && self._options.hideInactiveValues ) {
1427							$item[hidden==$items.length?'addClass':'removeClass']('mfilter-hide');
1428							$item.find('.mfilter-option').not('.mfilter-hide,.mfilter-hide-by-live-filter').first().addClass('mfilter-first-child');
1429							$item.find('.mfilter-option').not('.mfilter-hide,.mfilter-hide-by-live-filter').last().addClass('mfilter-last-child');
1430						}
1431					});
1432					
1433					break;
1434				}
1435			}
1436		}
1437						
1438		if( first !== true && ( self._options.hideInactiveValues || self._box.find('[data-display-live-filter!="0"]').length ) ) {							
1439			for( var s = 0; s < self._scrolls.length; s++ ) {
1440				self._scrolls[s].refresh();
1441			}
1442
1443			for( var b = 0; b < self._buttonsMore.length; b++ ) {
1444				self._buttonsMore[b].refresh();
1445			}
1446			
1447			for( var f = 0; f < self._liveFilters.length; f++ ) {
1448				self._liveFilters[f].refresh();
1449			}
1450
1451			if( self._relativeScroll != null ) {
1452				self._relativeScroll.refresh();
1453			}
1454		}
1455		
1456		self._updateInlineHorizontal();
1457	},
1458	
1459	_initAlwaysSearch: function() {
1460		var self	= this;
1461			
1462		function search() {
1463			self._jqContent.find('[name^=filter_],[name=search],[name=category_id],[name=sub_category],[name=description]').each(function(){
1464				var name	= jQuery(this).attr('name'),
1465					value	= jQuery(this).val(),
1466					type	= jQuery(this).attr('type');
1467
1468				if( [ 'checkbox', 'radio' ].indexOf( type ) > -1 && ! jQuery(this).is(':checked') )
1469					value = '';
1470					
1471				if( name ) {
1472					self._inUrl[name] = value;
1473					self._params[name] = value;
1474				}
1475			});
1476			
1477			self.reload();
1478			//self.ajax();
1479		}
1480			
1481		jQuery('#button-search').unbind('click').click(function(e){
1482			e.preventDefault();
1483				
1484			search();
1485		});
1486			
1487		self._jqContent.find('input[name=filter_name],input[name=search]').unbind('keydown').unbind('keyup').bind('keydown', function(e){
1488			if( e.keyCode == 13 ) {
1489				e.preventDefault();
1490					
1491				search();
1492			}
1493		});
1494	},
1495	
1496	hexToRgb: function(str) {
1497		if ( /^#([0-9a-f]{3}|[0-9a-f]{6})$/ig.test(str) ) { 
1498			var hex = str.substr(1);
1499			hex = hex.length == 3 ? hex.replace(/(.)/g, '$1$1') : hex;
1500			var rgb = parseInt(hex, 16);               
1501			return [(rgb >> 16) & 255, (rgb >> 8) & 255, rgb & 255].join(',');
1502		} 
1503		
1504		return '255,255,255';
1505	},
1506	
1507	_initAlwaysAjaxPagination: function(){
1508		var self = this;
1509		
1510		if( ! self._options.ajaxPagination ) return;
1511		
1512		self._jqContent.find('.pagination a').click(function(){
1513			var url = jQuery(this).attr('href'),
1514				params = self._parseUrl( url );
1515			
1516			if( typeof params.page != 'undefined' ) {
1517				self._ajaxPagination = params.page;
1518				
1519				self.ajax( url );
1520				
1521				return false;
1522			}
1523		});
1524	},
1525		
1526	__initLoader: function() {
1527		var color = this.hexToRgb(typeof this._options.color == 'undefined' ? '#ffffff' : this._options.color.loader_over_results);
1528		
1529		this._jqLoader = jQuery('<span class="mfilter-ajax-loader-container" style="cursor: wait; z-index: 100; margin: 0; padding: 0; position: absolute; text-align: center; background-color: rgba(' + color + ',0.7);"></span>')
1530			.prependTo( this._jqContent )
1531			.html( '<img src="catalog/view/theme/default/stylesheet/mf/images/ajax-loader.gif?v2" alt="" />' )
1532			.hide();
1533	},
1534	
1535	__initLoaderFilter: function() {
1536		var color = this.hexToRgb(typeof this._options.color == 'undefined' ? '#ffffff' : this._options.color.loader_over_filter);
1537		
1538		this._jqLoaderFilter = jQuery('<span style="cursor: wait; z-index: 10000; margin: 0; padding: 0; position: absolute; background-color: rgba(' + color + ',0.7);"></span>')
1539			.prependTo( this._box )
1540			.hide();
1541	},
1542	
1543	/**
1544	 * Inicjuj wyświetlanie listy
1545	 */
1546	_initDisplayItems: function() {
1547		var self = this,
1548			isContentTop = self._box.hasClass( 'mfilter-content_top' ),
1549			params = self.urlToFilters();
1550		
1551		self._box.find('.mfilter-filter-item').each(function(i){
1552			var _level0				= jQuery(this),
1553				type				= _level0.attr('data-type'),
1554				seo_name			= _level0.attr('data-seo-name'),
1555				displayLiveFilter	= parseInt( _level0.attr('data-display-live-filter') ),
1556				displayListOfItems	= _level0.attr('data-display-list-of-items');
1557					
1558			if( ! displayListOfItems ) {
1559				displayListOfItems = self._options.displayListOfItems.type;
1560			}
1561
1562			if( type == 'price' || type == 'rating' ) return;
1563			
1564			var wrapper = _level0.find('.mfilter-content-wrapper'),
1565				content	= _level0.find('> .mfilter-content-opts'),
1566				heading	= _level0.find('> .mfilter-heading'),
1567				idx = null;
1568
1569			if( ! isContentTop && heading.hasClass( 'mfilter-collapsed' ) ) {
1570				if( typeof params[seo_name] == 'undefined' ) {
1571					content.show();
1572				}
1573			}
1574			
1575			if( displayListOfItems == 'scroll' ) {
1576				if( ( wrapper.actual ? wrapper.actual( 'outerHeight', { includeMargin: true } ) : wrapper.outerHeight(true) ) > self._options.displayListOfItems.maxHeight-1 ) {
1577					if( self._options.displayListOfItems.standardScroll || jQuery.browser && jQuery.browser.msie && jQuery.browser.version < 9 ) {
1578						wrapper
1579							.css({
1580								'max-height': self._options.displayListOfItems.maxHeight + 'px',
1581								'overflow-y': 'scroll'
1582							});
1583					} else {
1584						wrapper
1585							.attr('id', 'mfilter-content-opts-' + self._instanceIdx + '-' + i);
1586
1587						(function(){
1588							var iscroll = new IScroll( '#mfilter-content-opts-' + self._instanceIdx + '-' + i, {
1589									bounce: false,
1590									scrollbars: true,
1591									mouseWheel: true,
1592									interactiveScrollbars: true,
1593									mouseWheelSpeed: 120
1594								}),
1595								start = false;
1596
1597							iscroll.on('moveStart', function(e){
1598								if( ! start ) return;
1599
1600								self._relativeScroll._end(e);
1601
1602								start = false;
1603							});
1604
1605							iscroll.on('moveStop', function(e){
1606								if( start ) return;
1607
1608								self._relativeScroll._start(e);
1609
1610								start = true;
1611							});
1612
1613							iscroll.on('scrollEnd', function(e){
1614								if( e == null ) return;
1615
1616								self._relativeScroll._end(e);
1617
1618								start = false;
1619							});
1620
1621							idx = self._scrolls.length;
1622
1623							self._scrolls.push({
1624								refresh: function(){
1625									iscroll.refresh();
1626								}
1627							});
1628						})();
1629					}
1630				}
1631			} else if( displayListOfItems == 'button_more' && ! isContentTop && type != 'image' && type != 'image_radio' ) {
1632				self._buttonsMore.push((function( _level0 ){		
1633					function init( first ) {
1634						var lessHeight	= 0,
1635							$cnt 		= _level0.find('.mfilter-options-container'),
1636							moreHeight	= $cnt.actual ? $cnt.actual( 'outerHeight', { includeMargin: true } ) : $cnt.outerHeight(true),
1637							show		= false,
1638							count		= 0,
1639							idx			= 0;
1640						
1641						_level0.find('.mfilter-option.mfilter-tb-as-tr').each(function(i){
1642							var _this = jQuery(this);
1643							
1644							if( _this.hasClass('mfilter-hide') || _this.hasClass('mfilter-hide-by-live-filter') ) return;
1645
1646							if( idx < self._options.displayListOfItems.limit_of_items ) {
1647								lessHeight += _this.actual ? _this.actual( 'outerHeight', { includeMargin: true } ) : _this.outerHeight(true);
1648							} else {
1649								count++;
1650							}
1651							
1652							idx++;
1653						});
1654
1655						if( count ) {
1656							wrapper.css('overflow','hidden').css('height', lessHeight+'px');
1657							
1658							function sh( show, force ) {
1659								if( force ) {
1660									wrapper.height( moreHeight );
1661								} else {
1662									wrapper.animate({
1663										'height' : ! show ? moreHeight : lessHeight
1664									}, 500, function(){
1665										if( self._relativeScroll != null )
1666											self._relativeScroll.refresh();
1667									});
1668								}
1669										
1670								_level0.find('a.mfilter-button-more').text(show?self._options.displayListOfItems.textMore.replace( '%s', count ):self._options.displayListOfItems.textLess);
1671							}
1672
1673							_level0.find('.mfilter-content-opts').append(jQuery('<div>')
1674								.addClass( 'mfilter-button-more' )
1675								.append(jQuery('<a>')
1676									.attr( 'href', '#' )
1677									.addClass( 'mfilter-button-more' )
1678									.text( self._options.displayListOfItems.textMore.replace( '%s', count ) )
1679									.bind('click', function(){
1680										sh( show );
1681
1682										show = ! show;
1683										
1684										wrapper[show?'addClass':'removeClass']('mfilter-slide-down');
1685
1686										return false;
1687									})
1688								)
1689							);
1690						
1691							if( wrapper.hasClass('mfilter-slide-down') ) {
1692								sh( false, true );
1693								show = true;
1694							}
1695						}
1696					}
1697					
1698					init( true );
1699					
1700					idx = self._buttonsMore.length;
1701					
1702					return {
1703						refresh: function() {
1704							_level0.find('.mfilter-content-wrapper').removeAttr('style');
1705							_level0.find('.mfilter-button-more').remove();
1706							
1707							init();
1708						}
1709					};
1710				})( _level0 ));
1711			}
1712			
1713			if( type == 'cat_checkbox' ) {
1714				(function(){
1715					var cnt = 0;
1716					
1717					content.find('.mfilter-category .mfilter-option').each(function(i){
1718						if( jQuery(this).find('.mfilter-counter').text() != '0' ) {							
1719							if( i && ! cnt ) {
1720								jQuery(this).addClass('mfilter-first-child');
1721							}
1722							
1723							cnt++;
1724						} else {
1725							jQuery(this).addClass('mfilter-hide');
1726						}
1727					});
1728					
1729					if( ! cnt ) {
1730						_level0.addClass('mfilter-hide');
1731					}
1732				})();
1733			}
1734			
1735			(function(){
1736				if( isContentTop ) {
1737					return;
1738				}
1739				
1740				if( displayLiveFilter < 1 || content.find('.mfilter-option').length < displayLiveFilter || type == 'image' || type == 'image_radio' ) {
1741					displayLiveFilter = 0;
1742					
1743					return;
1744				}
1745				
1746				content.prepend('<div class="mfilter-live-filter"><input type="text" class="form-control" id="mfilter-live-filter-input-' + self._instanceIdx + '-' + i + '" /></div>');
1747				
1748				wrapper.find('> .mfilter-options > div').attr('id', 'mfilter-live-filter-list-' + self._instanceIdx + '-' + i);
1749
1750				_level0.addClass('mfilter-live-filter-init');
1751
1752				jQuery('#mfilter-live-filter-list-' + self._instanceIdx + '-' + i).liveFilter('#mfilter-live-filter-input-'+self._instanceIdx + '-' + i, '.mfilter-visible,.mfilter-should-visible,.mfilter-disabled,.mfilter-option:not(.mfilter-filter-item)', {
1753					'filterChildSelector' : 'label',
1754					'after' : function(contains, containsNot){
1755						var list = jQuery('#mfilter-live-filter-list-' + self._instanceIdx + '-' + i);
1756
1757						contains.removeClass('mfilter-should-visible').addClass('mfilter-visible');
1758						containsNot.removeClass('mfilter-visible').addClass('mfilter-should-visible');
1759
1760						list.find('> .mfilter-option').removeClass('mfilter-first-child mfilter-last-child');
1761						
1762						list.find('> .mfilter-option:not(.mfilter-hide):not(.mfilter-hide-by-live-filter):first').addClass('mfilter-first-child');
1763						list.find('> .mfilter-option:not(.mfilter-hide):not(.mfilter-hide-by-live-filter):last').addClass('mfilter-last-child');
1764
1765						if( idx !== null ) {
1766							if( displayListOfItems == 'scroll' ) {
1767								self._scrolls[idx].refresh();
1768							} else if( displayListOfItems == 'button_more' ) {
1769								self._buttonsMore[idx].refresh();
1770							}
1771						}
1772						
1773						if( self._relativeScroll != null ) {
1774							self._relativeScroll.refresh();
1775						}
1776					}
1777				});
1778					
1779				_level0.addClass('mfilter-live-filter-init');
1780				
1781				self._liveFilters.push({
1782					refresh: function(){
1783						content.find('.mfilter-live-filter')[content.find('.mfilter-option:not(.mfilter-hide)').length <= displayLiveFilter?'hide':'show']();
1784					},
1785					check: function() {
1786						jQuery('#mfilter-live-filter-input-'+self._instanceIdx + '-' + i).trigger('keyup');
1787					}
1788				});
1789				
1790				self._liveFilters[self._liveFilters.length-1].refresh();
1791			})();
1792
1793			if( ! isContentTop && heading.hasClass( 'mfilter-collapsed' ) ) {
1794				if( typeof params[seo_name] == 'undefined' ) {
1795					content.hide();
1796				}
1797			}
1798		});
1799	},
1800			
1801	/**
1802	 * Inicjuj nagłówki
1803	 */
1804	_initHeading: function() {
1805		var self = this;
1806		
1807		if( self._box.hasClass('mfilter-content_top') )
1808			return;
1809		
1810		self._box.find('.mfilter-heading').click(function(){
1811			var opts = jQuery(this).parent().find('> .mfilter-content-opts');
1812
1813			if( jQuery(this).hasClass('mfilter-collapsed') ) {
1814				opts.slideDown('normal', function(){
1815					if( self._relativeScroll != null )
1816						self._relativeScroll.refresh();
1817				});
1818				jQuery(this).removeClass('mfilter-collapsed');
1819			} else {
1820				opts.slideUp('normal', function(){
1821					if( self._relativeScroll != null )
1822						self._relativeScroll.refresh();
1823				});
1824				jQuery(this).addClass('mfilter-collapsed');
1825			}
1826		});
1827	},
1828	
1829	_updateInlineHorizontal: function() {
1830		for( var i = 0; i < this._inlineHorizontalUpdate.length; i++ ) {
1831			this._inlineHorizontalUpdate[i]();
1832		}
1833	},
1834	
1835	_initInlineHorizontal: function() {
1836		var self = this;
1837		
1838		if( ! self._box.hasClass( 'mfilter-content_top' ) ) {
1839			return;
1840		}
1841		
1842		self._box.find('li[data-inline-horizontal="1"][data-type="checkbox"],li[data-inline-horizontal="1"][data-type="radio"]').each(function(){
1843			var $container = jQuery(this).addClass('mfilter-inline-horizontal').find('.mfilter-opts-container'),
1844				$wrapper = $container.find('> .mfilter-content-wrapper'),
1845				$options = $wrapper.find('> .mfilter-options'),
1846				$optionsCnt = $options.find('> .mfilter-options-container'),
1847				$tb = $optionsCnt.find('> .mfilter-tb'),
1848				left = 0;
1849			
1850			function width() {
1851				var w = 0,
1852					b = false;
1853				
1854				left = 0;
1855				
1856				$tb.find('> .mfilter-tb').each(function(){
1857					var ww = jQuery(this).outerWidth(true);
1858					
1859					if( self._lastEvent ) {
1860						var $el = jQuery(this).find('[id="' + self._lastEvent + '"]');
1861						
1862						if( $el.length ) {
1863							b = true;
1864						} else if( ! b ) {
1865							left += ww;
1866						}
1867					}
1868					
1869					w += ww;
1870				});
1871				
1872				return w;
1873			}
1874			
1875			self._inlineHorizontalUpdate[self._inlineHorizontalUpdate.length] = function() {
1876				$optionsCnt.removeAttr('style');
1877				$tb.removeAttr('style').css('margin-left',$tb.attr('data-mgr')+'px');
1878				
1879				o1 = w1;
1880				o2 = w2;
1881				
1882				w1 = $optionsCnt.width()-2*8;
1883				w2 = width();
1884				
1885				$optionsCnt.css('width', w1);
1886				$tb.css('width', w2+fix);
1887				
1888				if( w2 > w1 ) {
1889					$right.addClass('mf-active');
1890					
1891					if( x >= w2-w1 && $left.hasClass('mf-active') ) {
1892						t=0;
1893						$right.trigger('click');
1894					} else if( self._lastEvent ) {
1895						var $el = $tb.find('[id="' + self._lastEvent + '"]');
1896						
1897						if( $el.length ) {
1898							var w = $el.parent().parent().parent().outerWidth(true);
1899							
1900							if( x > left ) {
1901								t=0;
1902								x=left-w+w1;
1903								$left.trigger('click');
1904							} else if( x+w1 < left+w ) {
1905								t=0;
1906								x=x+(w*2)-w1;
1907								$right.trigger('click');
1908							}
1909						}
1910					}
1911				} else {
1912					t=x=0;
1913					$left.addClass('mf-active').trigger('click');
1914					$right.removeClass('mf-active');
1915				}
1916				
1917				/*if( ! $right.hasClass('mf-active') ) {
1918					if( w2 > w1 ) {
1919						//t=0;
1920						$right.addClass('mf-active');//.trigger('click');
1921					} else {
1922						t=x=0;
1923						$left.addClass('mf-active').trigger('click');
1924						//$right.removeClass('mf-active');
1925					}
1926				} else {
1927					if( w2 <= w1 ) {
1928						$right.removeClass('mf-active');
1929					}
1930				}*/
1931			};
1932			
1933			var $left = jQuery('<a href="#"></a>'),
1934				$right = jQuery('<a href="#"></a>');
1935			
1936			$wrapper.prepend(jQuery('<div class="mfilter-scroll-left"></div>').append($left));
1937			$wrapper.append(jQuery('<div class="mfilter-scroll-right"></div>').append($right));
1938			
1939			var w1 = $optionsCnt.width(),
1940				w2 = width(),
1941				o1 = -1,
1942				o2 = -1,
1943				x = 0,
1944				fix = 50,
1945				t = 'normal';
1946			
1947			if( w2 > w1 ) {
1948				$right.addClass('mf-active');
1949			}
1950			
1951			$optionsCnt.css('width', w1);
1952			$tb.css('width', w2+fix).attr('data-mgr','0');
1953			
1954			$left.click(function(){
1955				var $self = jQuery(this);
1956				
1957				if( ! $self.hasClass('mf-active') ) return false;
1958				
1959				x -= w1;
1960				
1961				if( x <= 0 ) {
1962					x = 0;
1963					$self.removeClass('mf-active');
1964				}
1965				
1966				$tb.attr('data-mgr', -x).stop().animate({
1967					'marginLeft' : -x
1968				}, t);
1969				
1970				t = 'normal';
1971				
1972				$right.addClass('mf-active');
1973				
1974				return false;
1975			});
1976			$right.click(function(){
1977				var $self = jQuery(this);
1978				
1979				if( ! $self.hasClass('mf-active') ) return false;
1980				
1981				x += w1;
1982				
1983				if( x >= w2-w1 ) {
1984					x = w2-w1;
1985					$self.removeClass('mf-active');
1986				}
1987				
1988				$tb.attr('data-mgr', -x).stop().animate({
1989					'marginLeft' : -x
1990				}, t);
1991				
1992				t = 'normal';
1993				
1994				$left.addClass('mf-active');
1995				
1996				return false;
1997			});
1998		});
1999	},
2000	
2001	_initCategoryRelated: function() {
2002		var self	= this;
2003		
2004		self._box.find('.mfilter-filter-item.mfilter-related').each(function(){
2005			var $li			= jQuery(this),
2006				seoName		= $li.attr('data-seo-name'),
2007				autoLevels	= $li.attr('data-auto-levels'),
2008				fields		= $li.find('select[data-type="category-related"]');
2009			
2010			fields.each(function(i){
2011				if( ! autoLevels && i == fields.length - 1 ) {
2012					jQuery(this).change(function(){
2013						if( self._options['refreshResults'] != 'using_button' ) {
2014							self.runAjax();
2015						}
2016					});
2017				} else {						
2018					function eChange( $self, id ) {
2019						var $this = $self.parent().attr('data-id', id),
2020							labels = $this.parent().attr('data-labels').split('#|#');
2021						
2022						$self.change(function(){
2023							var cat_id = $self.val();
2024							
2025							$next = $this.next().find('select');
2026							$parent = $next.parent();
2027							label = typeof labels[id+1] == 'undefined' ? $parent.attr('data-next-label') : labels[id+1];
2028
2029							if( cat_id ) {
2030								$next.html('<option value="">' + self._options.text.loading + '</option>');
2031								$next.prop('selectedIndex', 0);
2032
2033								jQuery.post( self._ajaxUrl( self._options.ajaxGetCategoryUrl ), { 'cat_id' : cat_id }, function( response ){
2034									var data = jQuery.parseJSON( response );
2035
2036									if( data.length && autoLevels ) {
2037										var $li = jQuery('<li>');
2038
2039										$this.after( $li );
2040										$next = jQuery('<select>').appendTo( $li );
2041										
2042										if( ! label )
2043											label = MegaFilterLang.text_select;
2044
2045										eChange( $next, id+1 );
2046									}
2047
2048									$next.html('<option value="">' + label + '</option>');
2049									$next.prop('selectedIndex', 0);
2050
2051									for( var i = 0; i < data.length; i++ ) {
2052										$next.append( '<option value="' + data[i].id + '">' + data[i].name + '</option>' );
2053									}
2054
2055									if( autoLevels ) {
2056										if( ! data.length ) {
2057											if( self._options['refreshResults'] != 'using_button' ) {
2058												self.runAjax();
2059											}
2060										}
2061									} else if( ! data.length ) {
2062										if( self._options['refreshResults'] != 'using_button' ) {
2063											self.runAjax();
2064										}
2065									}
2066								});
2067							}
2068
2069							var $p = $parent;
2070
2071							while( $p.length ) {
2072								if( autoLevels ) {
2073									var $t = $p;
2074									$p = $p.next();
2075									$t.remove();
2076								} else {
2077									$p.find('select').prop('selectedIndex', 0).find('option[value!=""]').remove();
2078									$p = $p.next();
2079								}
2080							}
2081
2082							if( ! cat_id ) {
2083								var beforeVal	= self.urlToFilters()[seoName],
2084									afterVal	= self.filters()[seoName];
2085
2086								if( typeof beforeVal == 'undefined' )
2087									beforeVal = [-1];
2088
2089								if( typeof afterVal == 'undefined' )
2090									afterVal = [-1];
2091
2092								if( beforeVal.toString() != afterVal.toString() )
2093									self.runAjax();
2094							}
2095						});
2096					}
2097
2098					eChange( jQuery(this), i );
2099				}
2100			});
2101		});
2102	},
2103	
2104	/**
2105	 * Inicjuj zdarzenia
2106	 */
2107	_initEvents: function() {
2108		var self = this;
2109		
2110		function val( $input ) {
2111			var val = $input.val(),
2112				parent = $input.parent().parent();
2113			
2114			if( $input.attr('type') == 'checkbox' || $input.attr('type') == 'radio' ) {
2115				parent.find('.mfilter-counter').unbind('click').bind('click', function(){
2116					if( ! jQuery(this).hasClass( 'mfilter-close' ) ) return;
2117					
2118					$input.prop('checked', false).trigger('change');
2119				});
2120				
2121				val = $input.is(':checked');
2122				
2123				if( ! self._options.calculateNumberOfProducts ) {
2124					if( self._isInit && $input.attr('type') == 'radio' ) {
2125						parent.parent().find('.mfilter-counter').removeClass('mfilter-close');
2126					}
2127					
2128					parent.find('.mfilter-counter')[val?'addClass':'removeClass']('mfilter-close');
2129				}
2130				
2131				if( $input.attr('type') == 'radio' ) {
2132					parent.parent().parent().parent().parent().parent().parent().find('.mfilter-input-active').removeClass('mfilter-input-active');
2133				}
2134			}
2135			
2136			parent[val?'addClass':'removeClass']('mfilter-input-active');
2137		}
2138		
2139		self._box.find('input[type=checkbox],input[type=radio],select:not([data-type="category-related"])').change(function(){
2140			self._lastEvent = jQuery(this).attr('id');
2141			
2142			if( self._options['refreshResults'] != 'using_button' ) {
2143				self.runAjax();
2144			}
2145			
2146			val(jQuery(this));
2147		});
2148		
2149		self._box.find('.mfilter-options .mfilter-option input[type=checkbox]:checked,.mfilter-options .mfilter-option input[type=radio]:checked').each(function(){
2150			val(jQuery(this));
2151		});
2152		
2153		self._box.find('.mfilter-button a').bind('click', function(){
2154			self._lastEvent = null;
2155			
2156			if( jQuery(this).hasClass( 'mfilter-button-reset' ) ) {
2157				self.eachInstances(function( self ){
2158					self.resetFilters();
2159				});
2160			}
2161			
2162			self.ajax();
2163			
2164			return false;
2165		});
2166	},
2167			
2168	/**
2169	 * Uruchom ładowanie
2170	 */
2171	runAjax: function() {
2172		var self = this;
2173				
2174		switch( self._options['refreshResults'] ) {
2175			case 'using_button' :
2176			case 'immediately' : {
2177				self.ajax();
2178					
2179				break;
2180			}
2181			case 'with_delay' : {
2182				if( self._timeoutAjax )
2183					clearTimeout( self._timeoutAjax );
2184					
2185				self._timeoutAjax = setTimeout(function(){
2186					self.ajax();
2187							
2188					self._timeoutAjax = null;
2189				}, self._options['refreshDelay'] );
2190					
2191				break;
2192			}
2193		}
2194	},
2195	
2196	/**
2197	 * Pobierz aktualny zakres cen
2198	 */
2199	getPriceRange: function() {
2200		var self		= this,
2201			minInput	= self._box.find('[id="mfilter-opts-price-min"]'),
2202			maxInput	= self._box.find('[id="mfilter-opts-price-max"]'),
2203			min			= minInput.val(),
2204			max			= maxInput.val();		
2205			
2206		if( ! /^[0-9]+$/.test( min ) || min < self._options.priceMin )
2207			min = self._options.priceMin;
2208		
2209		if( ! /^[0-9]+$/.test( max ) || max > self._options.priceMax )
2210			max = self._options.priceMax;
2211		
2212		return {
2213			min : parseInt( min ),
2214			max : parseInt( max )
2215		};
2216	},
2217	
2218	/**
2219	 * Inicjuj przedział cenowy
2220	 */
2221	_initPrice: function() {
2222		var self		= this,
2223			priceRange	= self.getPriceRange(),
2224			filters		= self.urlToFilters(),
2225			minInput	= self._box.find('[id="mfilter-opts-price-min"]').unbind('change').bind('change', function(){
2226				changePrice();
2227			}).val( filters.price ? filters.price[0] : priceRange.min ),
2228			maxInput	= self._box.find('[id="mfilter-opts-price-max"]').unbind('change').bind('change', function(){
2229				changePrice();
2230			}).val( filters.price ? filters.price[1] : priceRange.max ),
2231			slider		= self._box.find('[id="mfilter-price-slider"]');
2232		
2233		self._refreshPrice = function( minMax ) {
2234			var priceRange = self.getPriceRange();
2235			
2236			if( priceRange.min < self._options.priceMin ) {
2237				priceRange.min = self._options.priceMin;
2238			}
2239			
2240			if( priceRange.max > self._options.priceMax ) {
2241				priceRange.max = self._options.priceMax;
2242			}
2243			
2244			if( priceRange.min > priceRange.max ) {
2245				priceRange.min = priceRange.max;
2246			}
2247			
2248			if( priceRange.min.toString() != minInput.val() ) {
2249				minInput.val( priceRange.min );
2250			}
2251			
2252			if( priceRange.max.toString() != maxInput.val() ) {
2253				maxInput.val( priceRange.max );
2254			}
2255			
2256			slider.slider( 'option', 'values', [ priceRange.min, priceRange.max ] );
2257			
2258			if( minMax !== false ) {
2259				slider.slider( 'option', 'min', self._options.priceMin );
2260				slider.slider( 'option', 'max', self._options.priceMax );
2261				slider.slider( 'value', slider.slider('value') );
2262			}
2263		};
2264			
2265		function changePrice() {
2266			self._refreshPrice( false );
2267			
2268			if( self._options['refreshResults'] != 'using_button' ) {
2269				self.runAjax();
2270			}
2271		}
2272		
2273		slider.slider({
2274			range	: true,
2275			min		: self._options.priceMin ,
2276			max		: self._options.priceMax,
2277			values	: [ priceRange.min, priceRange.max ],
2278			slide	: function( e, ui ) {
2279				minInput.val( ui.values[0] );
2280				maxInput.val( ui.values[1] );
2281			},
2282			stop	: function( e, ui ) {
2283				if( self._options['refreshResults'] != 'using_button' )
2284					self.runAjax();
2285			}
2286		});
2287	},
2288	
2289	_initWindowOnPopState: function(){
2290		var self = this;
2291			
2292		if( self._isInit ) return;
2293		
2294		function update() {
2295			self.eachInstances(function( self ){
2296				self._urlToFilters = null;
2297				self.initUrls();
2298				self.setFiltersByUrl();
2299			});
2300		}
2301
2302		function setFilters( url ) {
2303			var params = self._parseUrl( url );
2304
2305			if( typeof params.mfp != 'undefined' ) {				
2306				self.setFiltersByUrl( self.__urlToFilters( decodeURIComponent( params.mfp ) ) );
2307			} else {
2308				self.resetFilters();
2309			}
2310		}
2311
2312		window.onpopstate = function(e){
2313			if( e.state ) {
2314				update();
2315
2316				self._render( e.state.html, e.state.json, true );
2317
2318				setFilters( e.state.url );
2319			} else if( typeof self._cache.mainContent[self.location()] != 'undefined' && self._history > 0 ) {
2320				update();
2321
2322				self._render( self._cache.mainContent[self.location()].html, self._cache.mainContent[self.location()].json, true );
2323
2324				setFilters( self.location() );
2325			} else if( self._changed && self._history > 0 ) {
2326				setFilters( self._startUrl.toString() );
2327
2328				self.ajax( null, true );
2329			}
2330
2331			self._history--;
2332		};
2333	},
2334	
2335	count: function( obj ) {
2336		var c = 0;
2337		
2338		for( var i in obj ) {
2339			c++;
2340		}
2341		
2342		return c;
2343	},
2344	
2345	setFiltersByUrl: function( params ) {
2346		var self	= this;
2347		
2348		if( typeof params == 'undefined' ) {
2349			params = self.urlToFilters();
2350		}
2351		
2352		self.resetFilters();
2353		
2354		self._box.find('li[data-type]').each(function(){
2355			var _this	= jQuery(this),
2356				type	= _this.attr('data-type'),
2357				seoName	= _this.attr('data-seo-name'),
2358				value	= params[seoName];
2359			
2360			if( typeof value == 'undefined' || typeof value[0] == 'undefined' )
2361				return;
2362					
2363			switch( type ) {
2364				case 'rating' :
2365				case 'stock_status' :
2366				case 'manufacturers' :
2367				case 'image' :
2368				case 'image_radio' :
2369				case 'radio' :
2370				case 'image_list_radio' :
2371				case 'image_list_checkbox' :
2372				case 'checkbox' : {
2373					for( var i in value ) {
2374						if( typeof value[i] == 'function' ) continue;
2375						
2376						if( type == 'image_radio' || type == 'radio' || type == 'image_list_radio' ) {
2377							_this.find('.mfilter-image-checked').removeClass('mfilter-image-checked');
2378						}
2379						
2380						var $p1 = _this.find('input[value="' + self.decode( decodeURIComponent( value[i] ) ).replace( /"/g, '&quot;' ) + '"]').prop('checked', true)
2381							.parent();
2382						
2383						$p1.parent()
2384							.addClass('mfilter-input-active').find('.mfilter-counter').addClass('mfilter-close');
2385						
2386						if( $p1.hasClass( 'mfilter-image' ) ) {
2387							$p1.addClass('mfilter-image-checked');
2388						}
2389					}
2390					
2391					break;
2392				}
2393				case 'select' : {
2394					_this.find('select option[value="' + self.decode( decodeURIComponent( value[0] ) ).replace( /"/g, '&quot;' ) + '"]').attr('selected', true);
2395						
2396					break;
2397				}
2398				case 'price' : {
2399					if( typeof value[0] != 'undefined' && typeof value[1] != 'undefined' ) {
2400						_this.find('input[id="mfilter-opts-price-min"]').val( value[0] );
2401						_this.find('input[id="mfilter-opts-price-max"]').val( value[1] );
2402
2403						_this.find('[id="mfilter-price-slider"]').each(function(){					
2404							//jQuery(this).slider( 'option', 'min', value[0] );
2405							//jQuery(this).slider( 'option', 'max', value[1] );
2406							jQuery(this).slider( 'option', 'values', [ value[0], value[1] ] );
2407							jQuery(this).slider( 'value', jQuery(this).slider('value') );
2408						});
2409					}
2410					
2411					break;
2412				}
2413				case 'text' :
2414				case 'search' : {
2415					_this.find('input').val( self.decode( decodeURIComponent( value[0] ) ) );
2416					
2417					break;
2418				}
2419			}
2420		});
2421		
2422		for( var i = 0; i < self._sliders.length; i++ ) {
2423			self._sliders[i].setValues();
2424		}
2425	},
2426	
2427	/**
2428	 * Pokaż loader
2429	 */
2430	_showLoader: function() {
2431		var self = this;
2432				
2433		if( self._jqLoader == null && self._options.showLoaderOverResults ) {
2434			self.__initLoader();
2435		}
2436		
2437		if( self._jqLoaderFilter == null && self._options.showLoaderOverFilter ) {
2438			self.__initLoaderFilter();
2439		}
2440		
2441		if( self._options.showLoaderOverResults ) {
2442			(function(){
2443				var w = self._jqContent.outerWidth(),
2444					h = self._jqContent.outerHeight(),
2445					j = self._jqContent.find('.product-list'),
2446					k = j.length ? j : self._jqContent.find('.product-grid'),
2447					l = k.length ? k : self._jqContent,
2448					t = k.length ? k.offset().top - 150 : l.offset().top;
2449
2450				self._jqLoader
2451					.css('width', w + 'px')
2452					.css('height', h + 'px')
2453					.fadeTo('normal', 1)
2454					.find('img')
2455					.css('margin-top', t + 'px');
2456			})();
2457		}
2458		
2459		if( self._options.showLoaderOverFilter ) {
2460			(function(){
2461				var w = self._box.outerWidth(),
2462					h = self._box.outerHeight();
2463				
2464				self._jqLoaderFilter
2465					.css('width', w + 'px')
2466					.css('height', h + 'px')
2467					.fadeTo('normal',1);
2468			})();
2469		}
2470		
2471		if( self._options.autoScroll ) {
2472			jQuery('html,body').stop().animate({
2473				scrollTop: self._jqContent.offset().top + self._options.addPixelsFromTop
2474			}, 'low', function(){
2475				self._busy = false;
2476				self.render();
2477			});
2478		} else {
2479			self._busy = false;
2480			self.render();
2481		}
2482	},
2483	
2484	/**
2485	 * Ukryj loader
2486	 */
2487	_hideLoader: function() {
2488		var self = this;
2489		
2490		if( self._jqLoader !== null ) {		
2491			self._jqLoader.remove();
2492			self._jqLoader = null;
2493		}
2494		
2495		if( self._jqLoaderFilter !== null ) {
2496			self._jqLoaderFilter.remove();
2497			self._jqLoaderFilter = null;
2498		}
2499	},
2500	
2501	/**
2502	 * Pokaż wczytane dane
2503	 */
2504	render: function( history ) {
2505		var self = this;
2506		
2507		if( self._lastResponse === '' || self._busy ) {
2508			return;
2509		}
2510		
2511		self._hideLoader();
2512		
2513		// usuń wszystkie linki do skryptów JS
2514		self._lastResponse = self._lastResponse.replace( /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '' );
2515		
2516		var tmp = jQuery('<tmp>').html( self._lastResponse ),
2517			content = tmp.find(self._contentId), // znajdź treść główną
2518			json = tmp.find('#mfilter-json'); // informacje JSON zawierające dane o ilości produktów wg kategorii
2519			
2520		if( ! content.length && self._contentId != '#content' ) {
2521			content = tmp.find('#content');
2522		}
2523			
2524		if( content.length ) {
2525			var styles = self._jqContent.html().match( /<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi );
2526			
2527			if( styles != null && styles.length ) {
2528				for( var i = 0; i < styles.length; i++ ) {
2529					jQuery('head:first').append( styles[i] );
2530				}
2531			}
2532			
2533			self._render( content.html(), json && json.length ? self.base64_decode(json.html()) : null, history );
2534			
2535			self._lastResponse = '';
2536		} else {
2537			self.reload();
2538		}
2539	},
2540	
2541	_render: function( html, json, history ) {
2542		var self = this;
2543		
2544		if( history !== true ) {
2545			self._lastUrl = self.createUrl();
2546			
2547			if( self._ajaxPagination !== null ) {
2548				self._lastUrl += self._lastUrl.indexOf( '?' ) > -1 ? '&' : '?';
2549				self._lastUrl += 'page=' + self._ajaxPagination;
2550				
2551				self._ajaxPagination = null;
2552			}
2553			
2554			self._urlToFilters = null;
2555			
2556			if( self._options.seo.enabled ) {
2557				var u = self.parse_url( self._lastUrl );
2558				var data = jQuery.parseJSON( json );
2559				
2560				self._lastUrl = '';
2561				self._lastUrl += u.scheme + '://';
2562				self._lastUrl += u.host;
2563				self._lastUrl += decodeURIComponent( u.path ).replace( /\/mfp,([a-z0-9\-_]+\[[^\]]*\],?)+/g, '' );
2564				
2565				if( typeof data['url_alias'] != 'undefined' ) {
2566					self._seoAliases[data['url_alias']] = data['url_alias'];
2567				}
2568				
2569				if( typeof u.query != 'undefined' && u.query ) {					
2570					//if( u.path != '/' ) {
2571						var mfp = u.query.match( /mfp=([^&]+)/ );
2572						
2573						self._lastUrl = self._lastUrl.replace( /\/$/, '' );
2574						
2575						if( mfp ) {
2576							self._lastUrl += typeof data['url_alias'] == 'undefined' ? '/mfp,' + mfp[1] : '/' + data['url_alias'];
2577							u.query = u.query.replace( 'mfp=' + mfp[1], '' );
2578							u.query = u.query.replace( /^(\?|&)|&$/g, '' );
2579						}
2580						
2581						if( u.query != '' ) {
2582							self._lastUrl += '?' + u.query;
2583						}
2584					//} else {
2585					//	self._lastUrl += '?' + u.query;
2586					//}
2587				}
2588			}
2589			
2590			try {
2591				window.history.pushState({
2592					'html'	: html,
2593					'json'	: json,
2594					'url'	: self._lastUrl
2595				}, '', self._lastUrl );
2596				
2597				self._history++;
2598			} catch( e ) {}
2599		}
2600		
2601		if( json ) {
2602			self.eachInstances(function( self ){
2603				self._parseInfo( json );
2604			});
2605		}
2606		
2607		self.beforeRender( self._lastResponse, html, json );
2608			
2609		self._jqContent.html( html );
2610			
2611		/*if( self._box.hasClass( 'mfilter-content_top' ) ) {
2612			self._jqContent.prepend( self._box.removeClass('init') );
2613			self.init( self._box, self._options );
2614		}*/
2615			
2616		if( typeof jQuery.totalStorage == 'function' && jQuery.totalStorage('display') ) {
2617			display_MFP( jQuery.totalStorage('display') );
2618		} else if( typeof jQuery.cookie == 'function' && jQuery.cookie('display') ) {
2619			display_MFP( jQuery.cookie('display') );
2620		} else {
2621			display_MFP( 'list' );
2622		}
2623			
2624		for( var i in self ) {
2625			if( i.indexOf( '_initAlways' ) === 0 && typeof self[i] == 'function' ) {
2626				self[i]();
2627			}
2628		}
2629		
2630		for( var f = 0; f < self._liveFilters.length; f++ ) {
2631			self._liveFilters[f].check();
2632		}
2633		
2634		// Support for Product Quantity Extension (15186)
2635		if( typeof pq_initExt == 'function' ) {
2636			pq_initExt();
2637		}
2638		
2639		if( self._options.routeHome == self._options.route && self._options.homePageAJAX ) {
2640			self._jqContent.find('.pagination > li > a').unbind('click').bind('click', function(){
2641				self.ajax( jQuery(this).attr('href') );
2642				
2643				return false;
2644			});
2645		}
2646		
2647		if( self._relativeScroll ) {
2648			self._relativeScroll.reinit();
2649		}
2650		
2651		self.afterRender( self._lastResponse, html, json );
2652	},
2653	
2654	beforeRequest: function(){},
2655	
2656	beforeRender: function(){},
2657	
2658	afterRender: function(){},
2659	
2660	eachInstances: function( fn, skipCurrent ) {
2661		for( var i = 0; i < MegaFilterINSTANCES.length; i++ ) {
2662			if( skipCurrent === true && i == this._instanceIdx ) continue;
2663			
2664			fn( MegaFilterINSTANCES[i] );
2665		}
2666	},
2667	
2668	/**
2669	 * Załaduj dane
2670	 */
2671	ajax: function( url, history ) {
2672		var self = this;
2673		
2674		if( self._busy ) {
2675			self._waitingChanges = true;
2676			
2677			return;
2678		}
2679		
2680		(function(){
2681			var filters = self.filters( true );
2682			
2683			self.eachInstances(function( self ){
2684				var params = $.extend( self.filters(), filters );
2685				
2686				self.setFiltersByUrl( params );
2687			}, true);
2688		})();
2689		
2690		if( typeof url == 'undefined' || url === null ) {
2691			//url	= [ self._options.routeProduct, self._options.routeHome ].indexOf( self._options.route ) > -1 ? self.createUrl( self._options.ajaxResultsUrl ) : self.createUrl();
2692			url = [ self._options.routeProduct, self._options.routeHome, self._options.routeInformation, self._options.routeManufacturerList ].indexOf( self._options.route ) > -1 ? self.createUrl( self._options.ajaxResultsUrl ) : self.createUrl();
2693		}
2694		
2695		var cname	= url + self._options.idx;
2696		
2697		if( ( ! self._options.homePageAJAX && self._options.routeHome == self._options.route ) || [ self._options.routeProduct, self._options.routeInformation, self._options.routeManufacturerList ].indexOf( self._options.route ) > -1 ) {
2698		//if( ( ! self._options.homePageAJAX && self._options.routeHome == self._options.route ) || self._options.routeProduct == self._options.route ) {
2699			window.location.href = url;return;
2700		}
2701		
2702		self.eachInstances(function( self ){
2703			self._busy = true;
2704			self._lastResponse = '';
2705		});
2706		
2707		self._showLoader();
2708		
2709		if( typeof self._params['page'] != 'undefined' ) {
2710			delete self._params['page'];
2711		}
2712		
2713		if( typeof self._cache.lastResponse[cname] != 'undefined' ) {
2714			self.eachInstances(function( self2 ){
2715				self2._lastResponse = self._cache.lastResponse[cname];
2716			});
2717			
2718			setTimeout(function(){
2719				self.eachInstances(function( self ){
2720					self._busy = false;
2721				});
2722				
2723				self.render( history );
2724			}, 100);
2725			
2726			return;
2727		}
2728		
2729		if( self.beforeRequest() === false ) {
2730			return;
2731		}
2732		
2733		self._changed = true;
2734		
2735		jQuery.ajax({
2736			'type'		: 'GET',
2737			'url'		: self._ajaxUrl( url.replace(/\+/g,"%20") ),
2738			'timeout'	: 60 * 1000,
2739			'cache'		: false,
2740			'data'		: {
2741				'mfilterAjax'	: '1',
2742				'mfilterIdx'	: self._options.idx,
2743				'mfilterBTypes'	: self.baseTypes().join(','),
2744				'mfilterPath'	: typeof self._options.params.mfp_org_path != 'undefined' ? self._options.params.mfp_org_path : self._options.params.path,
2745				'mfilterLPath'	: self.locationPath()
2746			},
2747			'success'	: function( response ) {
2748				self.eachInstances(function( self ){
2749					self._busy = false;
2750				});
2751				
2752				if( response ) {
2753					self.eachInstances(function( self ){
2754						self._lastResponse	= response;
2755						self._cache.lastResponse[cname]	= response;
2756					});
2757					
2758					self.render( history );
2759					
2760					if( self._waitingChanges ) {
2761						self._waitingChanges = false;
2762						self.ajax();
2763					}
2764				} else {
2765					self.reload();
2766				}
2767			},
2768			'error'		: function() {
2769				self.reload();
2770			}
2771		});
2772	},
2773	
2774	/**
2775	 * Utwórz pełny adres URL
2776	 */
2777	createUrl: function( url, attribs, force ) {
2778		var self	= this,
2779			params	= self.paramsToUrl( url, attribs ),
2780			filters	= self.filtersToUrl(),
2781			urlSep	= self._urlSep;
2782		
2783		if( typeof url == 'undefined' ) {
2784			url = self._url;
2785		} else {
2786			urlSep = self._parseSep( url.split('#')[0] ).urlSep;
2787			url = self._parseSep( url.split('#')[0] ).url;
2788		}
2789		
2790		url = decodeURIComponent( url ).replace( /\/mfp,([a-z0-9\-_]+\[[^\]]*\],?)+/, '' );
2791		
2792		if( params || filters ) {
2793			url += urlSep.f;
2794			
2795			if( params ) {
2796				url += params;
2797			}
2798			
2799			if( filters ) {
2800				if( params ) {
2801					url += urlSep.n;
2802				}
2803				
2804				url += 'mfp' + ( urlSep.n == '&' ? '=' : urlSep.n ) + filters;
2805			} else if( force ) {
2806				var mfp = self.filtersToUrl( self.urlToFilters() );
2807
2808				if( mfp ) {
2809					url += urlSep.n;
2810					url += 'mfp' + ( urlSep.n == '&' ? '=' : urlSep.n ) + mfp;
2811				}
2812			}
2813		}
2814		
2815		return url;
2816	},
2817	
2818	/**
2819	 * Sprawdź poprawność wpisanego zakresu cen
2820	 * 
2821	 * @return bool
2822	 */
2823	_validPrice: function( min, max ) {
2824		var self = this;
2825		
2826		min = parseInt( min );
2827		max = parseInt( max );
2828		
2829		if( min < self._options.priceMin )
2830			return false;
2831		
2832		if( max > self._options.priceMax )
2833			return false;
2834		
2835		if( min > max )
2836			return false;
2837		
2838		if( min == max && min == self._options.priceMin && max == self._options.priceMax )
2839			return false;
2840		
2841		return true;
2842	},
2843	
2844	/**
2845	 * Przekształć parametry z adresu URL na obiekt
2846	 * 
2847	 * @return object
2848	 */
2849	urlToFilters: function() {
2850		if( this._urlToFilters !== null ) {
2851			return this._urlToFilters;
2852		}
2853		
2854		var self = this;
2855			
2856		self._urlToFilters = {};
2857		
2858		if( ! self._params.mfp )
2859			return self._urlToFilters;
2860		
2861		self._params.mfp =  decodeURIComponent( self._params.mfp );
2862		
2863		self._urlToFilters = self.__urlToFilters( self._params.mfp );
2864		
2865		return self._urlToFilters;
2866	},
2867	
2868	__urlToFilters: function( mfp ) {
2869		var self	= this,
2870			obj		= {},
2871			matches	= mfp.match( /[a-z0-9\-_]+\[[^\]]+\]/g );
2872		
2873		if( ! matches ) {
2874			return obj;
2875		}
2876		
2877		for( var i = 0; i < matches.length; i++ ) {
2878			var key = matches[i].match( /([a-z0-9\-_]+)\[[^\]]+\]/ )[1],
2879				val = matches[i].match( /[a-z0-9\-_]+\[([^\]]+)\]/ )[1].split(',');
2880			
2881			switch( key ) {
2882				case 'price' : {
2883					if( typeof val[0] != 'undefined' && val[1] != 'undefined' ) {
2884						if( self._validPrice( val[0], val[1] ) )
2885							obj[key] = val;
2886					}
2887					
2888					break;
2889				}
2890				default : {
2891					obj[key] = val;
2892				}
2893			}
2894		}
2895		
2896		return obj;
2897	},
2898	
2899	resetFilters: function(){
2900		var self	= this;
2901		
2902		self._box.find('li[data-type]').each(function(){
2903			var _this		= jQuery(this),
2904				type		= _this.attr('data-type'),
2905				baseType	= _this.attr('data-base-type'),
2906				defaultVal	= null;
2907				
2908			_this.find('.mfilter-input-active').removeClass('mfilter-input-active');
2909			
2910			if( baseType == 'stock_status' && self._options.inStockDefaultSelected ) {
2911				defaultVal = self._options.inStockStatus;
2912			}
2913			
2914			switch( type ) {
2915				case 'image_radio' :
2916				case 'image' : {
2917					_this.find('input[type=checkbox]:checked,input[type=radio]:checked').prop('checked', false).parent().removeClass('mfilter-image-checked');
2918					
2919					break;
2920				}
2921				case 'cat_checkbox' : {
2922					_this.find('input[type=checkbox]:checked').prop('checked', false);
2923					_this.find('.mfilter-counter').removeClass('mfilter-close');
2924					
2925					break;
2926				}
2927				case 'tree' : {
2928					_this.find('input[name=path]').val( typeof self._options.params.path == 'undefined' ? '' : self._options.params.path );
2929					
2930					break;
2931				}
2932				case 'rating' :
2933				case 'stock_status' :
2934				case 'manufacturers' :
2935				case 'checkbox' : 
2936				case 'image_list_checkbox' : 
2937				case 'image_list_radio' : 
2938				case 'radio' : {
2939					_this.find('input[type=checkbox]:checked,input[type=radio]:checked').prop('checked', false);
2940					_this.find('.mfilter-counter').removeClass('mfilter-close');
2941					
2942					if( defaultVal !== null ) {
2943						_this.find('input[value="' + defaultVal.replace( /"/g, '&quot;' ) + '"]').prop('checked', true)
2944							.parent().parent().find('.mfilter-counter').addClass('mfilter-close');
2945					}
2946					
2947					break;
2948				}
2949				case 'search_oc' :
2950				case 'search' : {
2951					_this.find('input[id="mfilter-opts-search"]').val( '' );
2952						
2953					break;
2954				}
2955				case 'text' : {
2956					_this.find('input[type=text]').val( '' );
2957					
2958					break;
2959				}
2960				case 'slider' : {					
2961					
2962					
2963					break;
2964				}
2965				case 'price' : {
2966					_this.find('input[id="mfilter-opts-price-min"]').val( self._options.priceMin );
2967					_this.find('input[id="mfilter-opts-price-max"]').val( self._options.priceMax );
2968					_this.find('[id="mfilter-price-slider"]').each(function(){					
2969						jQuery(this).slider( 'option', 'min', self._options.priceMin );
2970						jQuery(this).slider( 'option', 'max', self._options.priceMax );
2971						jQuery(this).slider( 'option', 'values', [ self._options.priceMin, self._options.priceMax ] );
2972						jQuery(this).slider( 'value', jQuery(this).slider('value') );
2973					});
2974					
2975					break;
2976				}
2977				case 'related' :
2978				case 'select' : {
2979					_this.find('select option').removeAttr('selected');
2980					
2981					if( defaultVal !== null ) {
2982						_this.find('select option').each(function(i){
2983							if( jQuery(this).val() == defaultVal ) {
2984								jQuery(this).attr('selected', true);
2985								_this.find('select').prop('selectedIndex', i);
2986								
2987								return false;
2988							}
2989						});
2990					} else {
2991						_this.find('select option:first').attr('selected', true);
2992						_this.find('select').prop('selectedIndex', 0);
2993					}
2994					
2995					if( type == 'related' ) {
2996						_this.find('select').each(function(i){
2997							if( i ) {
2998								if( _this.attr('data-auto-levels') ) {
2999									jQuery(this).parent().remove();
3000								} else {
3001									jQuery(this).find('option[value!=""]').remove();
3002								}
3003							}
3004						});
3005					}
3006					
3007					break;
3008				}
3009			}
3010		});
3011		
3012		for( var i = 0; i < self._sliders.length; i++ ) {
3013			self._sliders[i].resetValues();
3014		}
3015	},
3016	
3017	/**
3018	 * Pobierz aktualne wartości filtrów
3019	 * 
3020	 * @return object
3021	 */
3022	filters: function( alsoEmpty ) {
3023		var self	= this,
3024			params	= { },
3025			stockStatusExist = self._box.find('li[data-base-type="stock_status"]').length ? true : false;
3026				
3027		self._box.find('li[data-type]').each(function(){
3028			var _this	= jQuery(this),
3029				type	= _this.attr('data-type'),
3030				seoName	= _this.attr('data-seo-name');
3031				
3032			if( alsoEmpty === true ) {
3033				if( typeof params[seoName] == 'undefined' ) {
3034					params[seoName] = [];
3035				}
3036			}
3037					
3038			switch( type ) {
3039				case 'cat_checkbox' : 
3040				case 'rating' :
3041				case 'stock_status' : 
3042				case 'manufacturers' :
3043				case 'image_list_checkbox' :
3044				case 'image' :
3045				case 'checkbox' : {
3046					_this.find('input[type=checkbox]:checked').each(function(){
3047						if( typeof params[seoName] == 'undefined' ) {
3048							params[seoName] = [];
3049							
3050							/*if( type == 'cat_checkbox' ) {
3051								if( typeof self._options.params.mfp_org_path != 'undefined' ) {
3052									params[seoName].push( self._options.params.mfp_org_path );
3053								} else if( typeof self._options.params.path != 'undefined' ) {
3054									params[seoName].push( self._options.params.path );
3055								}
3056							}*/
3057						}
3058						
3059						params[seoName].push( encodeURIComponent( self.encode( jQuery(this).val() ) ) );
3060					});
3061					
3062					break;
3063				}
3064				case 'image_radio' :
3065				case 'image_list_radio' :
3066				case 'radio' : {
3067					_this.find('input[type=radio]:checked').each(function(){
3068						params[seoName] = [ encodeURIComponent( self.encode( jQuery(this).val() ) ) ];
3069					});
3070						
3071					break;
3072				}
3073				case 'slider' : {
3074					var slider_id = _this.attr('data-slider-id'),
3075						slider_vals = self._sliders[slider_id].getValues();
3076						
3077					if( slider_vals.length ) {
3078						params[seoName] = slider_vals;
3079					}
3080					
3081					break;
3082				}
3083				case 'price' : {
3084					var priceRange = self.getPriceRange();
3085					
3086					if( priceRange.min != self._options.priceMin || priceRange.max != self._options.priceMax ) {
3087						if( self._validPrice( priceRange.min, priceRange.max ) )
3088							params[seoName] = [ priceRange.min, priceRange.max ];
3089					}
3090					
3091					break;
3092				}
3093				case 'search_oc' :
3094				case 'search' : {
3095					_this.find('input[id="mfilter-opts-search"]').each(function(){
3096						if( jQuery(this).val() !== '' ) {
3097							params[seoName] = [ encodeURIComponent( self.encode( jQuery(this).val() ) ) ];
3098						}
3099					});
3100					
3101					break;
3102				}
3103				case 'text' : {
3104					_this.find('input[type=text]').each(function(){
3105						if( jQuery(this).val() != '' ) {
3106							params[seoName] = [ encodeURIComponent( self.encode( jQuery(this).val() ) ) ];
3107						}
3108					});
3109					
3110					break;
3111				}
3112				case 'select' : {
3113					_this.find('select').each(function(){
3114						if( jQuery(this).val() )
3115							params[seoName] = [ encodeURIComponent( self.encode( jQuery(this).val() ) ) ];
3116					});
3117						
3118					break;
3119				}
3120				case 'related' : {
3121					//if( _this.find('select:last').val() ) {
3122						_this.find('select').each(function(){
3123							var val = jQuery(this).val();
3124							
3125							if( val ) {							
3126								if( typeof params[seoName] == 'undefined' )
3127									params[seoName] = [];
3128
3129								params[seoName].push( val );
3130							}
3131						});
3132					//}
3133				}
3134				case 'tree' : {
3135					_this.find('input').each(function(){
3136						var val = jQuery(this).val(),
3137							path = typeof self._options.params.mfp_org_path == 'undefined' ? self._options.params.path : self._options.params.mfp_org_path;
3138						
3139						if( val && val != path ) {
3140							params['path'] = [ val ];
3141						}
3142					});
3143					
3144					break;
3145				}
3146			}
3147		});
3148		
3149		// sprawdź czy domyślnie powinna być zaznaczona opcja "in stock"
3150		if( self._options.inStockDefaultSelected && typeof params['stock_status'] == 'undefined' ) {
3151			params['stock_status'] = stockStatusExist ? [] : [ self._options.inStockStatus ];
3152		}
3153		
3154		return params;
3155	},
3156			
3157	/**
3158	 * Utwórz URL na podstawie parametrów
3159	 */
3160	filtersToUrl: function( params ) {
3161		var self	= this,
3162			url		= '';
3163		
3164		if( typeof params == 'undefined' ) {
3165			params	= self.filters();
3166		
3167			self.eachInstances(function( self ){
3168				params = $.extend( self.filters(), params );
3169			}, true);
3170		}
3171				
3172		for( var i in params ) {
3173			url += url ? ',' : '';
3174			url += '' + i + '[' + params[i].join(',') + ']';
3175		}
3176			
3177		return url;
3178	},
3179	
3180	/**
3181	 * Przekształć parametry na adres URL
3182	 * 
3183	 * @return string
3184	 */
3185	paramsToUrl: function( url, attribs ) {
3186		var self	= this,
3187			params	= typeof url == 'undefined' ? self._params : self._parseUrl( url, attribs ),
3188			urlSep	= typeof url == 'undefined' ? self._urlSep : self._parseSep( url ).urlSep;
3189		
3190		return self._paramsToUrl( params, {
3191			'skip'	: [ 'mfilter-ajax', 'mfp', 'page' ],
3192			'sep'	: urlSep.n,
3193			'sep2'	: urlSep.n == '&' ? '=' : urlSep.n,
3194			'fn'	: function( i ) {
3195				return typeof url == 'undefined' && typeof self._inUrl[i] == 'undefined';
3196			}
3197		});
3198	},
3199	
3200	_paramsToUrl: function( params, o ) {
3201		var url = '';
3202		
3203		o = jQuery.extend({
3204			'skip'	: [],
3205			'sep'	: '&',
3206			'sep2'	: '=',
3207			'fn'	: function(){}
3208		}, typeof o == 'object' ? o : {});
3209		
3210		for( var i in params ) {
3211			if( o.skip.indexOf( i ) > -1 ) continue;
3212			
3213			if( o.fn( i, params[i] ) ) continue;
3214			
3215			url += url ? o.sep : '';
3216			url += i + o.sep2 + params[i];
3217		}
3218		
3219		return url;
3220	},
3221		
3222	/**
3223	 * @param url string
3224	 * @param attribs object
3225	 * @return object
3226	 */
3227	_parseUrl: function( url, attribs ) {		
3228		if( typeof attribs != 'object' )
3229			attribs = {
3230				'mfilter-ajax'	: '1'
3231			};
3232		
3233		if( typeof url == 'undefined' )
3234			return attribs;
3235			
3236		var self	= this,
3237			params, i, name, value, param,
3238			mfp;
3239		
3240		url = url.split('#')[0];
3241		mfp = url.match( /\/mfp,([a-z0-9\-_]+\[[^\]]*\],?)+/g );
3242		
3243		if( mfp ) {
3244			attribs['mfp'] = mfp[0].replace( /^\/mfp,/, '' );
3245		}
3246		
3247		if( url.indexOf( '?' ) > -1 || url.indexOf( '&' ) > -1 ) {
3248			params = typeof self.parse_url( url ).query != 'undefined' ? self.parse_url( url ).query.split('&') : url.split('&');
3249			
3250			for( i = 0; i < params.length; i++ ) {
3251				if( params[i].indexOf( '=' ) < 0 ) continue;
3252				
3253				param	= params[i].split('=');
3254				name	= param[0];
3255				value	= param[1];
3256
3257				if( ! name ) continue;
3258
3259				attribs[name] = value;
3260			}
3261		} else {
3262			params	= url.split( ';' );
3263			name	= null;
3264				
3265			for( i = 1; i < params.length; i++ ) {
3266				if( name === null )
3267					name = params[i];
3268				else {
3269					attribs[name] = params[i];
3270					name = null;
3271				}
3272			}
3273		}
3274		
3275		return attribs;
3276	},
3277	
3278	/**
3279	 * Przeładuj stronę
3280	 */
3281	reload: function() {
3282		var self = this;
3283		
3284		window.location.href = self.createUrl();
3285	}
3286};
3287var MegaFilterLang = {};
3288
3289function display_MFP(view) {
3290	// Product List
3291	$('#list-view').click(function() {
3292		$('#content .product-grid > .clearfix').remove();
3293
3294		$('#content .row > .product-grid').attr('class', 'product-layout product-list col-xs-12');
3295
3296		localStorage.setItem('display', 'list');
3297	});
3298
3299	// Product Grid
3300	$('#grid-view').click(function() {
3301		$('#content .product-layout > .clearfix').remove();
3302		
3303		// What a shame bootstrap does not take into account dynamically loaded columns
3304		var cols = $('#column-right, #column-left').length;
3305
3306		if (cols == 2) {
3307			$('#content .product-list').attr('class', 'product-layout product-grid col-lg-6 col-md-6 col-sm-12 col-xs-12');
3308		} else if (cols == 1) {
3309			$('#content .product-list').attr('class', 'product-layout product-grid col-lg-4 col-md-4 col-sm-6 col-xs-12');
3310		} else {
3311			$('#content .product-list').attr('class', 'product-layout product-grid col-lg-3 col-md-3 col-sm-6 col-xs-12');
3312		}
3313
3314		localStorage.setItem('display', 'grid');
3315	});
3316
3317	if (localStorage.getItem('display') == 'list') {
3318		$('#list-view').trigger('click');
3319	} else {
3320		$('#grid-view').trigger('click');
3321	}
3322}

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.