PageSourceSearch

https://www.agrofilm.sk/media/com_hikashop/js/hikashop.js?v=611

js agrofilm.sk collected 2026-09-24 22:45:49 UTC 71,878 bytes, 2,291 lines download raw bytes

1/**
2 * @package    HikaShop for Joomla!
3 * @version    6.1.1
4 * @author     hikashop.com
5 * @copyright  (C) 2010-2025 HIKARI SOFTWARE. All rights reserved.
6 * @license    GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
7 */
8(function() {
9
10function preventDefault() { this.returnValue = false; }
11function stopPropagation() { this.cancelBubble = true; }
12
13var Oby = {
14	version: 20171104,
15	ajaxEvents : {},
16
17	hasClass: function(o,n) {
18		if(o.classList && o.classList.contains)
19			return o.classList.contains(n);
20		if(o.className == '' ) return false;
21		var reg = new RegExp("(^|\\s+)"+n+"(\\s+|$)");
22		return reg.test(o.className);
23	},
24	addClass: function(o,n) {
25		if(o.classList && o.classList.add)
26			return o.classList.add(n);
27		if( !this.hasClass(o,n) ) {
28			if( o.className == '' ) {
29				o.className = n;
30			} else {
31				o.className += ' '+n;
32			}
33		}
34	},
35	trim: function(s) {
36		if(s.trim) return s.trim();
37		return (s ? '' + s : '').replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
38	},
39	removeClass: function(e, c) {
40		if(e.classList && e.classList.remove)
41			return e.classList.remove(c);
42		var t = this;
43		if( t.hasClass(e,c) ) {
44			var cn = ' ' + e.className + ' ';
45			e.className = t.trim(cn.replace(' '+c+' ',' '));
46		}
47	},
48	toggleClass: function(e,c) {
49		if(e.classList && e.classList.toggle)
50			return e.classList.toggle(c);
51		var t = this;
52		if( t.hasClass(e,c) ) {
53			return t.removeClass(e,c);
54		}
55		return t.addClass(e,c);
56	},
57	addEvent: function(d,e,f) {
58		if( d.attachEvent )
59			d.attachEvent('on' + e, f);
60		else if (d.addEventListener)
61			d.addEventListener(e, f, false);
62		else
63			d['on' + e] = f;
64		return f;
65	},
66	removeEvent: function(d,e,f) {
67		try {
68			if( d.detachEvent )
69				d.detachEvent('on' + e, f);
70			else if( d.removeEventListener)
71				d.removeEventListener(e, f, false);
72			else
73				d['on' + e] = null;
74		} catch(e) {}
75	},
76	cancelEvent: function(e) {
77		if( !e ) {
78			e = window.event;
79			if( !e )
80				return false;
81		}
82		if(e.stopPropagation)
83			e.stopPropagation();
84		else
85			 e.cancelBubble = true;
86		if( e.preventDefault )
87			e.preventDefault();
88		else
89			e.returnValue = false;
90		return false;
91	},
92	fireEvent: function(obj,e,data) {
93		var d = document, evt = null;
94		if(document.createEvent) {
95			evt = d.createEvent('HTMLEvents');
96			evt.initEvent(e, false, true);
97			if(data) evt.data = data;
98			obj.dispatchEvent(evt);
99			return;
100		}
101		if(data && d.createEventObject) {
102			evt = d.createEventObject();
103			evt.data = data;
104			obj.fireEvent('on'+e, evt);
105			return;
106		}
107		obj.fireEvent('on'+e);
108	},
109	fireAjax: function(name,params) {
110		var t = this, ev, r = null, ret = [];
111		if( t.ajaxEvents[name] === undefined )
112			return false;
113		for(var e in t.ajaxEvents[name]) {
114			if( e == '_id' )
115				continue;
116			ev = t.ajaxEvents[name][e];
117			if(!ev || typeof(ev) != 'function')
118				continue;
119			try {
120				r = ev(params);
121				if(r !== undefined)
122					ret.push(r);
123			}catch(e){}
124		}
125		return ret;
126	},
127	registerAjax: function(name, fct) {
128		var t = this;
129		if(typeof(name) == 'object') {
130			var r = [];
131			for(var k = name.length - 1; k >= 0; k--) {
132				r[r.length] = t.registerAjax(name[k], fct);
133			}
134			return r;
135		}
136		if( t.ajaxEvents[name] === undefined )
137			t.ajaxEvents[name] = {'_id':0};
138		var id = t.ajaxEvents[name]['_id'];
139		t.ajaxEvents[name]['_id'] += 1;
140		t.ajaxEvents[name][id] = fct;
141		return id;
142	},
143	unregisterAjax: function(name, id) {
144		if( t.ajaxEvents[name] === undefined || t.ajaxEvents[name][id] === undefined)
145			return false;
146		t.ajaxEvents[name][id] = null;
147		return true;
148	},
149	ready: function(fct) {
150		var w = window, d = document, t = this;
151		if(d.readyState === "complete") {
152			fct();
153			return;
154		}
155		var done = false, top = true, root = d.documentElement,
156			init = function(e) {
157				if(e.type == 'readystatechange' && d.readyState != 'complete') return;
158				t.removeEvent((e.type == 'load' ? w : d), e.type, init);
159				if(!done && (done = true))
160					fct();
161			},
162			poll = function() {
163				try{ root.doScroll('left'); } catch(e){ setTimeout(poll, 50); return; }
164				init('poll');
165			};
166		if(d.createEventObject && root.doScroll) {
167			try{ top = !w.frameElement; } catch(e){}
168			if(top) poll();
169		}
170		t.addEvent(d,'DOMContentLoaded',init);
171		t.addEvent(d,'readystatechange',init);
172		t.addEvent(w,'load',init);
173	},
174	evalJSON: function(text, secure) {
175		if( typeof(text) != "string" || !text.length) return null;
176		if(JSON !== undefined && typeof(JSON.parse) == 'function') {
177			try { var ret = JSON.parse(text); return ret; } catch(e) {
178				return this.extractJSON(text);
179			}
180		}
181		if(secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(text.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) return null;
182		try { var ret = eval('(' + text + ')'); return ret; } catch(e) { }
183		return null;
184	},
185	extractJSON: function(str) {
186		var firstOpen, firstClose, candidate;
187		firstOpen = str.indexOf('{', firstOpen + 1);
188		do {
189			firstClose = str.lastIndexOf('}');
190			if(firstClose <= firstOpen) {
191				return null;
192			}
193			do {
194				candidate = str.substring(firstOpen, firstClose + 1);
195				try {
196					var res = JSON.parse(candidate);
197					return res;
198				}
199				catch(e) {
200					console.log('failed parsing JSON in string below:');
201					console.log(candidate);
202				}
203				firstClose = str.substr(0, firstClose).lastIndexOf('}');
204			} while(firstClose > firstOpen);
205			firstOpen = str.indexOf('{', firstOpen + 1);
206		} while(firstOpen != -1);
207		return null;
208	},
209	getXHR: function() {
210		var xhr = null, w = window;
211		if(w.XMLHttpRequest || w.ActiveXObject) {
212			if(w.ActiveXObject) {
213				try {
214					xhr = new ActiveXObject("Microsoft.XMLHTTP");
215				} catch(e) {}
216			} else
217				xhr = new w.XMLHttpRequest();
218		}
219		return xhr;
220	},
221	xRequest: function(url, options, cb, cbError) {
222		var t = this, xhr = t.getXHR();
223		if(!options) options = {};
224		if(!cb) cb = function(){};
225		options.mode = options.mode || 'GET';
226		options.update = options.update || false;
227		xhr.onreadystatechange = function() {
228			if(xhr.readyState != 4)
229				return;
230			if( xhr.status == 200 || (xhr.status == 0 && xhr.responseText > 0) || !cbError ) {
231				if(cb)
232					cb(xhr,options.params);
233				if(options.update)
234					t.updateElem(options.update, xhr.responseText);
235			} else {
236				cbError(xhr,options.params);
237			}
238		};
239		xhr.open(options.mode, url, true);
240		if(options.mode.toUpperCase() == 'POST' && typeof(options.data) == 'string') {
241			xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
242		}
243		if(typeof Joomla !== 'undefined' && Joomla && Joomla.getOptions) {
244			var csrf = Joomla.getOptions("csrf.token", "");
245			if(csrf) {
246				xhr.setRequestHeader("X-CSRF-Token", csrf);
247			}
248		}
249		xhr.send( options.data );
250	},
251	getFormData: function(target, encoded) {
252		var d = document, ret = {};
253		if(encoded === undefined) encoded = true;
254		if( typeof(target) == 'string' )
255			target = d.getElementById(target);
256		if( target === undefined )
257			target = d;
258		var typelist = ['input','select','textarea'];
259		for(var t in typelist) {
260			if(!typelist.hasOwnProperty(t))
261				continue;
262			t = typelist[t];
263			var inputs = target.getElementsByTagName(t);
264			for(var i = 0; i < inputs.length; i++) {
265				if( !inputs[i].name || inputs[i].disabled )
266					continue;
267				var evalue = inputs[i].value, n = inputs[i].name, etype = '';
268				if( t == 'input' )
269					etype = inputs[i].type.toLowerCase();
270				if( (etype == 'radio' || etype == 'checkbox') && !inputs[i].checked )
271					evalue = null;
272				if(t == 'select' && inputs[i].multiple) {
273					for(var k = inputs[i].options.length - 1; k >= 0; k--) {
274						if(!inputs[i].options[k].selected)
275							continue;
276						//if( ret != '' ) ret += '&';
277						//ret += encodeURI(inputs[i].name) + '=' + encodeURIComponent(inputs[i].options[k].value);
278						if(ret.hasOwnProperty(n)) {
279							if(typeof(ret[n]) != 'object')
280								ret[n] = [ ret[n] ];
281							ret[n][ ret[n].length ] = inputs[i].options[k].value;
282						} else
283							ret[ n ] = inputs[i].options[k].value;
284						evalue = null;
285					}
286				}
287				if( (etype != 'file' && etype != 'submit') && evalue != null ) {
288					//if( ret != '' ) ret += '&';
289					//ret += encodeURI(inputs[i].name) + '=' + encodeURIComponent(evalue);
290
291					if(ret.hasOwnProperty(n)) {
292						if(typeof(ret[n]) != 'object')
293							ret[n] = [ ret[n] ];
294						ret[n][ ret[n].length ] = evalue;
295					} else
296						ret[ n ] = evalue;
297				}
298			}
299		}
300		if(encoded)
301			return this.encodeFormData(ret);
302		return ret;
303	},
304	encodeFormData: function(data) {
305		var ret = '', v = null;
306		if(typeof(data) == "string")
307			return data;
308		for(var k in data) {
309			if(!data.hasOwnProperty(k))
310				continue;
311			v = data[k];
312			if(typeof(v) == 'object') {
313				for(var i in v) {
314					if(!v.hasOwnProperty(i))
315						continue;
316					if( ret != '' ) ret += '&';
317					ret += encodeURI(k) + '=' + encodeURIComponent(v[i]);
318				}
319			} else {
320				if( ret != '' ) ret += '&';
321				ret += encodeURI(k) + '=' + encodeURIComponent(v);
322			}
323		}
324		return ret;
325	},
326	updateElem: function(elem, data) {
327		var d = document, scripts = '';
328		if( typeof(elem) == 'string' )
329			elem = d.getElementById(elem);
330		var text = data.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, code){
331			if(all.indexOf('type="application/json"')>=0 || all.indexOf('type="application/ld+json"')>=0)
332				return all;
333			scripts += code + '\n';
334			return '';
335		});
336		elem.innerHTML = text;
337		if( scripts != '' ) {
338			var script = d.createElement('script');
339			script.setAttribute('type', 'text/javascript');
340			script.text = scripts;
341			try {
342				d.head.appendChild(script);
343				d.head.removeChild(script);
344			} catch(e) {}
345		}
346	},
347	ease: function(v) {
348		return 1+Math.pow(v-1,3);
349	},
350	easeInOut: function(t,s,dt,du) {
351		return dt/2 * (1 - Math.cos(Math.PI*t/du)) + s;
352	},
353	scrollTo: function(name, anim, visible, margin) {
354		var t = this, d = document, w = window,
355			elem = d.getElementById(name);
356		if(!elem)
357			return;
358		if(margin === undefined) margin = 0;
359		if(!anim) {
360			window.scrollTo(0, elem.offsetTop - margin);
361			return;
362		}
363		if( t.anim && t.anim.timer )
364			clearInterval( t.anim.timer );
365		t.anim = { timer:null, s:null, dt:0, du:150, t:0, inc:10 };
366		if( w.scrollY )
367			t.anim.s = w.scrollY;
368		else if( d.documentElement.scrollTop )
369			t.anim.s = d.documentElement.scrollTop;
370		else
371			t.anim.s = d.body.scrollTop;
372		if(visible) {
373			if( d.documentElement.scrollTop )
374				h = d.documentElement.clientHeight;
375			else
376				h = d.body.clientHeight;
377			if(t.anim.s <= elem.offsetTop && (t.anim.s + h - 150) > elem.offsetTop)
378				return;
379		}
380		t.anim.dt = elem.offsetTop - t.anim.s - margin;
381		var o = this;
382		t.anim.timer = setInterval( function() {
383			var a = o.anim;
384			if( !a || !a.timer )
385				return;
386			a.t += a.inc;
387			if( a.t < a.du ) {
388				window.scrollTo(0, o.easeInOut(a.t, a.s, a.dt, a.du), false, margin);
389			} else {
390				window.scrollTo(0, a.s + a.dt, false, margin);
391				clearInterval(a.timer);
392				a.timer = null;
393			}
394		}, t.anim.inc );
395	}
396};
397if((typeof(window.Oby) == 'undefined') || window.Oby.version < Oby.version) {
398	window.Oby = Oby;
399	window.obscurelighty = Oby;
400}
401
402var oldHikaShop = window.hikashop || hikashop;
403
404var hikashop = {
405	translations: {},
406	translations_url: null,
407	submitFct: null,
408	filterRefreshTimer: false,
409
410	setCookie: function (name,value,delay) {
411		document.cookie = name + "=" + (value || "")  +  "; expires=" + delay + "; path=/";
412   	},
413	submitBox: function(data) {
414		var t = this, d = document, w = window;
415		if( t.submitFct ) {
416			try {
417				t.submitFct(data);
418			} catch(err) {}
419		}
420		t.closeBox();
421	},
422	deleteId: function(id) {
423		var t = this, d = document, el = id;
424		if( typeof(id) == "string") {
425			el = d.getElementById(id);
426		}
427		if(!el)
428			return;
429		el.parentNode.removeChild(el);
430	},
431	dup: function(tplName, htmlblocks, id, extraData, appendTo) {
432		var d = document, tplElem = d.getElementById(tplName);
433		if(!tplElem) return;
434		var container = tplElem.parentNode;
435		elem = tplElem.cloneNode(true);
436		if(!appendTo) {
437			container.insertBefore(elem, tplElem);
438		} else {
439			if(typeof(appendTo) == "string")
440				appendTo = d.getElementById(appendTo);
441			appendTo.appendChild(elem);
442		}
443		elem.style.display = "";
444		elem.id = '';
445		if(id)
446			elem.id = id;
447		for(var k in htmlblocks) {
448			elem.innerHTML = elem.innerHTML.replace(new RegExp("{"+k+"}","g"), htmlblocks[k]);
449			elem.innerHTML = elem.innerHTML.replace(new RegExp("%7B"+k+"%7D","g"), htmlblocks[k]);
450		}
451		if(extraData) {
452			for(var k in extraData) {
453				elem.innerHTML = elem.innerHTML.replace(new RegExp('{'+k+'}','g'), extraData[k]);
454				elem.innerHTML = elem.innerHTML.replace(new RegExp('%7B'+k+'%7D','g'), extraData[k]);
455			}
456		}
457		return elem;
458	},
459	deleteRow: function(id) {
460		var t = this, d = document, el = id;
461		if( typeof(id) == "string") {
462			el = d.getElementById(id);
463		} else {
464			while(el != null && el.tagName.toLowerCase() != 'tr') {
465				el = el.parentNode;
466			}
467		}
468		if(!el)
469			return;
470		var table = el.parentNode;
471		table.removeChild(el);
472		if( table.tagName.toLowerCase() == 'tbody' )
473			table = table.parentNode;
474		t.cleanTableRows(table);
475		return;
476	},
477	dupRow: function(tplName, htmlblocks, id, extraData) {
478		var d = document, tplLine = d.getElementById(tplName),
479				tableUser = tplLine.parentNode;
480		if(!tplLine) return;
481		trLine = tplLine.cloneNode(true);
482		tableUser.insertBefore(trLine, tplLine);
483		trLine.style.display = "";
484		trLine.id = "";
485		if(id)
486			trLine.id = id;
487		for(var i = tplLine.cells.length - 1; i >= 0; i--) {
488			if(trLine.cells[i]) {
489				for(var k in htmlblocks) {
490					if(!htmlblocks.hasOwnProperty(k))
491						continue;
492					trLine.cells[i].innerHTML = trLine.cells[i].innerHTML.replace(new RegExp("{"+k+"}","g"), htmlblocks[k]);
493					trLine.cells[i].innerHTML = trLine.cells[i].innerHTML.replace(new RegExp("%7B"+k+"%7D","g"), htmlblocks[k]);
494				}
495				if(extraData) {
496					for(var k in extraData) {
497						if(!extraData.hasOwnProperty(k))
498							continue;
499						trLine.cells[i].innerHTML = trLine.cells[i].innerHTML.replace(new RegExp('{'+k+'}','g'), extraData[k]);
500						trLine.cells[i].innerHTML = trLine.cells[i].innerHTML.replace(new RegExp('%7B'+k+'%7D','g'), extraData[k]);
501					}
502				}
503			}
504		}
505		if(tplLine.className == "row0") tplLine.className = "row1";
506		else if(tplLine.className == "row1") tplLine.className = "row0";
507		return trLine;
508	},
509	cleanTableRows: function(id) {
510		var d = document, el = id;
511		if(typeof(id) == "string")
512			el = d.getElementById(id);
513		if(el == null || el.tagName.toLowerCase() != 'table')
514			return;
515
516		var k = 0, c = '', line = null, lines = el.getElementsByTagName('tr');
517		for(var i = 0; i < lines.length; i++) {
518			line = lines[i];
519			if( line.style.display != "none") {
520				c = ' '+line.className+' ';
521				if( c.indexOf(' row0 ') >= 0 || c.indexOf(' row1 ') >= 0 ) {
522					line.className = c.replace(' row'+(1-k)+' ', ' row'+k+' ').replace(/^\s*|\s*$/g, '');
523					k = 1 - k;
524				}
525			}
526		}
527	},
528	checkRow: function(id) {
529		var t = this, d = document, el = id;
530		if(typeof(id) == "string")
531			el = d.getElementById(id);
532		if(el == null || el.tagName.toLowerCase() != 'input')
533			return;
534		if(this.clicked) {
535			this.clicked = null;
536			t.isChecked(el);
537			return;
538		}
539		el.checked = !el.checked;
540		t.isChecked(el);
541	},
542	isChecked: function(id,cancel) {
543		var d = document, el = id;
544		if(typeof(id) == "string")
545			el = d.getElementById(id);
546		if(el == null || el.tagName.toLowerCase() != 'input')
547			return;
548		if(el.form.boxchecked) {
549			if(el.checked)
550				el.form.boxchecked.value++;
551			else
552				el.form.boxchecked.value--;
553		}
554	},
555	checkAll: function(checkbox, stub) {
556		stub = stub || 'cb';
557		if(!checkbox.form)
558			return false;
559		var o = window.Oby, cb = checkbox.form, c = 0;
560		for(var i = 0, n = cb.elements.length; i < n; i++) {
561			var e = cb.elements[i];
562			if (e != checkbox && e.type == checkbox.type && ((stub && e.id.indexOf(stub) == 0) || !stub)) {
563				e.checked = checkbox.checked;
564				o.fireEvent(e, 'change');
565				o.fireEvent(e, 'click');
566				c += (e.checked == true ? 1 : 0);
567			}
568		}
569		if (cb.boxchecked) {
570			cb.boxchecked.value = c;
571		}
572		return true;
573	},
574	submitform: function(task, form, extra) {
575		var d = document;
576		if(typeof form == 'string') {
577			var f = d.getElementById(form);
578			if(!f)
579				f = d.forms[form];
580			if(!f)
581				return true;
582			form = f;
583		}
584		if(task) {
585			form.task.value = task;
586		}
587		if(typeof form.onsubmit == 'function')
588			form.onsubmit();
589		form.submit();
590		return false;
591	},
592	get: function(elem, target) {
593		window.hikashop.xRequest(elem.getAttribute('href'), {update: target});
594		return false;
595	},
596	form: function(elem, target) {
597		var data = window.Oby.getFormData(target);
598		window.hikashop.xRequest(elem.getAttribute('href'), {update: target, mode: 'POST', data: data});
599		return false;
600	},
601	openBox: function(elem, url, jqmodal) {
602		var w = window;
603		if(typeof(elem) == "string")
604			elem = document.getElementById(elem);
605		if(!elem)
606			return false;
607		try {
608			var hkpopup = elem.getAttribute('data-hk-popup');
609			if(jqmodal === undefined) {
610				jqmodal = false;
611				var test_rel = elem.getAttribute('rel');
612				if(test_rel == null && hkpopup == null && typeof(jQuery) != "undefined")
613					jqmodal = true;
614			}
615			if(hkpopup) {
616				var fct = this['openBox_' + hkpopup.toLowerCase()];
617				if(fct) {
618					var ret = fct(elem, url);
619					if(ret == true)
620						return false;
621				}
622			}
623			if(!jqmodal && this.openBox_squeezebox(elem, url))
624				return false;
625			if(this.openBox_bootstrap(elem, url))
626				return false;
627			console.log('no popup system found');
628		} catch(e) { console.log(e); }
629		return false;
630	},
631	openBox_squeezebox: function(elem, url) {
632		if(window.SqueezeBox === undefined)
633			return false;
634		if(url !== undefined && url !== null)
635			elem.href = url;
636		if(!elem.rel && elem.getAttribute('data-hk-popup') == 'squeezebox')
637			elem.rel = elem.getAttribute('data-squeezebox');
638		if(window.SqueezeBox.open !== undefined)
639			SqueezeBox.open(elem, {parse: 'rel'});
640		else if(window.SqueezeBox.fromElement !== undefined)
641			SqueezeBox.fromElement(elem);
642		setTimeout(function(){
643			jQuery('#sbox-content').find('iframe').attr('name', 'hikashop_popup_iframe');
644		},500);
645		return true;
646	},
647	openBox_bootstrap: function(elem, url) {
648		if(typeof(jQuery) == "undefined")
649			return false;
650		var id = elem.getAttribute('id');
651		jQuery('#modal-' + id).modal('show');
652		if(!url)
653			return true;
654		if(document.getElementById('modal-' + id + '-container'))
655			jQuery('#modal-' + id + '-container').find('iframe').attr('src', url);
656		else
657			jQuery('#modal-' + id).find('iframe').attr('src', url);
658		jQuery('#modal-' + id).find('iframe').attr('name', 'hikashop_popup_iframe');
659		return true;
660	},
661	openBox_vex: function(elem, url) {
662		if(typeof(vex) == "undefined")
663			return false;
664		var href = elem.href || null;
665		if(url !== undefined && url !== null)
666			href = url;
667		if(!href) href = elem.getAttribute('href');
668		settings = window.Oby.evalJSON(elem.getAttribute('data-vex'));
669		if(settings.x && settings.y && href) {
670			settings.content = '<iframe style="border:0;margin:0;padding:0;" name="hikashop_popup_iframe" width="'+settings.x+'px" height="'+settings.y+'px" src="'+href+'"></iframe>';
671			settings.afterOpen = function(context) { context.width(settings.x + 'px'); };
672		}
673		vex.defaultOptions.className = 'vex-theme-default';
674		vex.open( settings );
675		return true;
676	},
677	closeBox: function(parent) {
678		var d = document, w = window;
679		if(parent) {
680			d = window.parent.document;
681			w = window.parent;
682		}
683		try {
684			var e = d.getElementById('sbox-window');
685			if(e && typeof(e.close) != "undefined") {
686				e.close();
687			} else if(typeof(w.jQuery) != "undefined" && w.jQuery('div.modal.in') && w.jQuery('div.modal.in').hasClass('in')) {
688				w.jQuery('div.modal.in').modal('hide');
689			} else if(typeof(vex) != 'undefined' && vex.close && vex.close() === true) {
690				return;
691			} else if(w.SqueezeBox !== undefined) {
692				w.SqueezeBox.close();
693			}
694		} catch(err) {}
695	},
696	submitPopup: function(id, task, form) {
697		var d = document, t = this, el = d.getElementById('modal-'+id+'-iframe');
698		if(!el) {
699			if(document.getElementById('modal-' + id + '-container'))
700				el = jQuery('#modal-' + id + '-container').find('iframe').get(0);
701			else
702				el = jQuery('#modal-' + id).find('iframe').get(0);
703		}
704		if(el && el.contentWindow.hikashop) {
705			if(task === undefined) task = null;
706			if(form === undefined) form = 'adminForm';
707			el.contentWindow.hikashop.submitform(task, form);
708		}
709		return false;
710	},
711	tabSelect: function(m,c,id) {
712		var d = document, sub = null;
713		if(typeof m == 'string')
714			m = d.getElementById(m);
715		if(!m) return;
716		if(typeof id == 'string')
717			id = d.getElementById(id);
718		sub = m.getElementsByTagName('div');
719		if(sub) {
720			for(var i = sub.length - 1; i >= 0; i--) {
721				if(sub[i].getAttribute('class') == c) {
722					sub[i].style.display = 'none';
723				}
724			}
725		}
726		if(id) id.style.display = '';
727	},
728	changeState: function(el, id, url) {
729		var d = document;
730		if(!d.getElementById(id + '_container'))
731			return false;
732		var mainDiv = el.closest('.hikashop_checkout_address');
733		if(mainDiv)
734			window.checkout.setLoading(mainDiv, true, true);
735		window.Oby.xRequest(url, null, function(xhr){
736			var w = window;
737			w.hikashop.updateElem(id + '_container', xhr.responseText);
738			var defaultVal = '', defaultValInput = d.getElementById(id + '_default_value'), stateSelect = d.getElementById(id);
739			if(defaultValInput) { defaultVal = defaultValInput.value; }
740			if(stateSelect && w.hikashop.optionValueIndexOf(stateSelect.options, defaultVal) >= 0)
741				stateSelect.value = defaultVal;
742			if(typeof(jQuery) != "undefined" && jQuery().chosen) { jQuery('#'+id).chosen(); }
743			if(mainDiv)
744				window.checkout.setLoading(mainDiv, false);
745			w.Oby.fireAjax('hikashop.stateupdated', {id: id, elem: stateSelect});
746		});
747	},
748	optionValueIndexOf: function(options, value) {
749		for(var i = options.length - 1; i >= 0; i--) {
750			if(options[i].value == value)
751				return i;
752		}
753		return -1;
754	},
755	getOffset: function(el) {
756		var x = 0, y = 0;
757		while(el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop )) {
758			x += el.offsetLeft - el.scrollLeft;
759			y += el.offsetTop - el.scrollTop;
760			el = el.offsetParent;
761		}
762		return { top: y, left: x };
763	},
764	dataStore: function(name, value) {
765		if(localStorage) {
766			localStorage.setItem(name, value);
767		} else {
768			var expire = new Date(); expire.setDate(expire.getDate() + 5);
769			document.cookie = name+"="+value+"; expires="+expire;
770		}
771	},
772	dataGet: function(name) {
773		if(localStorage) {
774			return localStorage.getItem(name);
775		}
776		if(document.cookie.length > 0 && document.cookie.indexOf(name+"=") != -1) {
777			var s = name+"=", o = document.cookie.indexOf(s) + s.length, e = document.cookie.indexOf(";",o);
778			if(e == -1) e = document.cookie.length;
779			return unescape(document.cookie.substring(o, e));
780		}
781		return null;
782	},
783	setArrayDisplay: function(fields, displayValue) {
784		var d = document, e = null;
785		if(displayValue === true) displayValue = '';
786		if(displayValue === false) displayValue = 'none';
787		for(var i = 0; i < fields.length; i++) {
788			e = d.getElementById(fields[i]);
789			if(e) e.style.display = displayValue;
790		}
791	},
792	ready: function(fct) {
793		var w = window, d = w.document;
794		if(d.readyState === "complete") {
795			fct();
796			return;
797		}
798		if(w.jQuery !== undefined) {
799			jQuery(d).ready(fct);
800		} else if(window.addEvent) {
801			w.addEvent("domready", fct);
802		} else
803			w.Oby.ready(fct);
804	},
805	noChzn: function() {
806		if(!window.jQuery)
807			return false;
808		jQuery('.no-chzn').each(function(i,el) {
809			var id = el.getAttribute('id'), chzn = null;
810			if(id) {
811				id = id.replace('{','_').replace('}','_');
812				chzn = jQuery('#'+id+'_chzn');
813			} else {
814				chzn = el.nextSibling;
815			}
816			if(chzn) chzn.remove();
817			jQuery(el).removeClass('chzn-done').show();
818		});
819		return true;
820	},
821	switchTab: function(el) {
822		if(!el || !el.parentNode || !el.parentNode.parentNode) return false;
823		var d = document, w = window, o = w.Oby,
824			c = el.parentNode.parentNode,
825			r = c.getAttribute('rel'),
826			current = el.getAttribute('rel'),
827			dest = null;
828		if(!r || r.substring(0,5) != 'tabs:') return false;
829		if(current.substring(0,4) != 'tab:') return false;
830		var id = r.substring(5),
831			tabs = c.childNodes;
832		current = current.substring(4);
833		dest = d.getElementById(id + current);
834		if(!dest) return false;
835		for(var k = 0; k < tabs.length; k++) {
836			if(!tabs[k] || tabs[k].nodeName.toLowerCase() != 'li') continue;
837			var i = 0, l = tabs[k].childNodes[i], lr = null;
838			while(l.nodeName.toLowerCase() != 'a' && i < tabs[k].childNodes.length)
839				l = tabs[k].childNodes[++i];
840			if(l.nodeName.toLowerCase() == 'a')
841				lr = l.getAttribute('rel');
842			if(!lr || lr.substring(0,4) != 'tab:')
843				continue;
844			var lid = lr.substring(4);
845			if(lid == current) continue;
846			o.removeClass(tabs[k], 'active');
847			var ld = d.getElementById(id + lid);
848			if(ld) ld.style.display = 'none';
849		}
850		dest.style.display = '';
851		o.addClass(el.parentNode, 'active');
852		el.blur();
853		return false;
854	},
855	dlTitle: function(parent) {
856		var t = this, d = document, w = window;
857		if(parent && typeof(parent) == 'string')
858			parent = d.getElementById(parent);
859		if(!parent)
860			parent = d;
861		var dt = parent.getElementsByTagName('dt'), val = null,
862			hkTip = (typeof(hkjQuery) != "undefined" && hkjQuery().hktooltip);
863		for(var i = 0; i < dt.length; i++) {
864			if(dt[i].offsetWidth === 0) {
865				dt[i].dlTitleFct = function(evt){
866					t.dlTitle(this.parentNode);
867					if(hkTip)
868						hkjQuery(this).hktooltip('show');
869					this.removeEventListener('mouseover', this.dlTitleFct);
870					this.dlTitleFct = null;
871				};
872				dt[i].addEventListener('mouseover', dt[i].dlTitleFct);
873			}
874			if(dt[i].offsetWidth < dt[i].scrollWidth && !dt[i].getAttribute('title')) {
875				val = (dt[i].innerText !== undefined) ? dt[i].innerText : dt[i].textContent;
876
877				if(hkTip) {
878					dt[i].setAttribute('data-title', val);
879					hkjQuery(dt[i]).hktooltip({"html": true,"container": "body"});
880				} else
881					dt[i].setAttribute('title', val);
882			}
883		}
884	},
885	checkConsistency: function() {
886		if(!document.querySelectorAll)
887			return;
888		var s = null, elems = null,
889			parents = document.querySelectorAll('[data-consistencyheight]');
890		if(!parents || !parents.length)
891			return;
892		for(var i = parents.length - 1; i >= 0; i--) {
893			s = parents[i].getAttribute('data-consistencyheight');
894			if(s == '' || s == 'true')
895				continue;
896			var reg = new RegExp('^\.[-_a-z0-9]+$', 'i');
897			if(reg.test(s) && document.getElementsByClassName)
898				elems = parents[i].getElementsByClassName(s.substring(1));
899			else
900				elems = parents[i].querySelectorAll(s);
901			if(!elems || !elems.length)
902				continue;
903			if(this.setConsistencyHeight(elems, 'min') === false)
904				continue;
905			parents[i].setAttribute('data-consistencyheight-done', s);
906			parents[i].removeAttribute('data-consistencyheight');
907		}
908	},
909	setConsistencyHeight: function(elems, mode) {
910		if(!elems || !elems.length || elems.length == 0)
911			return;
912		var maxHeight = 0, cpt = 0, h = 0, w = window;
913		for(var i = elems.length - 1; i >= 0; i--) {
914			try {
915				h = parseFloat( w.getComputedStyle(elems[i], '').getPropertyValue('height') );
916				h = Math.ceil(h);
917			} catch(e) {
918				h = NaN;
919			}
920			if(isNaN(h))
921				h = (elems[i].currentStyle ? elems[i].currentStyle.height : elems[i].clientHeight);
922
923			if(maxHeight > 0 && h < maxHeight) {
924				cpt++;
925			} else if(h > maxHeight) {
926				maxHeight = h;
927				cpt++;
928			}
929		}
930		if(maxHeight <= 0)
931			return false;
932
933		if(cpt <= 1)
934			return;
935		for(var i = elems.length - 1; i >= 0; i--) {
936			if(mode !== undefined && mode == 'min')
937				elems[i].style.minHeight = maxHeight + 'px';
938			else
939				elems[i].style.height = maxHeight + 'px';
940		}
941	},
942	refreshFilters: function (el, skipSelf) {
943		"use strict";
944		var d = document, t = this, o = window.Oby,
945		container = null, data = null, containerName = el.getAttribute('data-container-div');
946
947		if(containerName)
948			container = d.forms[containerName];
949
950		if(!container)
951			return false;
952
953		var url = container.getAttribute('action');
954		var scrollToTop = container.getAttribute('data-scroll');
955
956		// delay timer to avoid too many ajax calls
957		if(t.filterRefreshTimer !== false) clearTimeout(t.filterRefreshTimer);
958		t.filterRefreshTimer = setTimeout(function() {
959
960			data = o.getFormData(container);
961			data += '&tmpl=raw';
962			o.xRequest(url, {mode:'POST', data: data}, function(xhr) {
963				var resp = o.evalJSON(xhr.responseText);
964
965				if(resp.newURL) {
966					var urlInHistory = resp.newURL.replace('tmpl=raw&', '', 'g').replace('tmpl=component&', '', 'g').replace('filter=1&', '', 'g').replace('&tmpl=raw', '', 'g').replace('&tmpl=component', '', 'g').replace('&filter=1', '', 'g');
967					window.history.pushState(data, d.title, urlInHistory);
968
969					window.addEventListener('popstate', function(e) {
970						if(window.location.href.includes('hikashop_url_reload=1')) {
971							window.location.href.replace('&hikashop_url_reload=1','').reload();
972						}
973					});
974				}
975
976				var refreshAreas = document.querySelectorAll('.filter_refresh_div');
977
978				var triggers = o.fireAjax('filters.update', {el: el, refreshAreas : refreshAreas, resp: resp});
979				if(triggers !== false && triggers.length > 0)
980					return true;
981
982				var refreshUrl = null;
983				t.refreshCounter = 0;
984				for(let i = 0; i < refreshAreas.length; i++) {
985					var currentArea = refreshAreas[i];
986					if(skipSelf && currentArea.querySelector('#'+el.id))
987						continue;
988
989					if(resp.newURL && currentArea.getAttribute('data-use-url')) {
990						refreshUrl = resp.newURL;
991					} else {
992						refreshUrl = currentArea.getAttribute('data-refresh-url');
993						if(resp.params) {
994							refreshUrl += '&' + resp.params + '&return_url=' + encodeURIComponent(window.location.href);
995						}
996					}
997					if(!refreshUrl)
998						continue;
999					t.refreshCounter++;
1000					var className = currentArea.getAttribute('data-refresh-class');
1001					if(className) o.addClass(currentArea, className);
1002					t.refreshOneArea(refreshUrl, currentArea, el, refreshAreas, resp);
1003				}
1004
1005				if(scrollToTop) {
1006					window.hikashop.smoothScroll();
1007				}
1008			});
1009			t.filterRefreshTimer = false;
1010		}, 300);
1011		return false;
1012	},
1013	smoothScroll: function(target) {
1014		var target = document.querySelector('div[id^="hikashop_category_information_menu_"]');
1015		if(!target)
1016			return;
1017		var currentScroll = document.documentElement.scrollTop || document.body.scrollTop;
1018		if (currentScroll > target.offsetTop) {
1019			window.requestAnimationFrame(window.hikashop.smoothScroll);
1020			window.scrollTo (target.offsetTop, currentScroll - (currentScroll/5));
1021		}
1022	},
1023	refreshOneArea: function(refreshUrl, currentArea, el, refreshAreas, resp) {
1024		var d = document, t = this, o = window.Oby;
1025		o.xRequest(refreshUrl, {mode:'GET'}, function (xhr2) {
1026			var div = d.createElement('div');
1027			var scripts = '';
1028			var text = xhr2.responseText.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, code){
1029				if(all.indexOf('type="application/json"') != -1)
1030					return '';
1031				if(all.indexOf('type="application/ld+json"') != -1)
1032					return '';
1033				scripts += code + '\n';
1034				return '';
1035			});
1036
1037			var body = /<body.*?>([\s\S]*)<\/body>/.exec(text);
1038			if(!body)
1039				body = text;
1040			else
1041				body = body[1];
1042			window.hikashop.updateElem(div, body);
1043			var newElem = div.querySelector('.filter_refresh_div');
1044
1045			// to avoid scroll in chrome
1046			setTimeout(function(){
1047				if(!currentArea) {
1048					t.refreshCounter--;
1049					return;
1050				}
1051				var className = currentArea.getAttribute('data-refresh-class');
1052				if(className) o.removeClass(currentArea, className);
1053				if(!newElem) {
1054					t.refreshCounter--;
1055					return;
1056				}
1057				var parentNode = currentArea.parentNode;
1058				if(!parentNode) {
1059					t.refreshCounter--;
1060					return;
1061				}
1062				parentNode.replaceChild(newElem, currentArea);
1063				if( scripts != '' ) {
1064					new Promise((resolve, reject)=>{
1065						var script = d.createElement('script');
1066						script.setAttribute('type', 'text/javascript');
1067
1068						var windowErrorHandler = (event) =>{
1069							event.preventDefault();
1070							var error = event.error;
1071							error.stack = error.stack + '\n\n' + scripts;
1072							window.removeEventListener('error', windowErrorHandler);
1073							reject(error);
1074						};
1075						window.addEventListener('error', windowErrorHandler);
1076
1077						var rejectHandler = (error) =>{
1078							window.removeEventListener('error', windowErrorHandler);
1079							reject(error);
1080						};
1081						script.addEventListener('error', rejectHandler);
1082						script.addEventListener('abort', rejectHandler);
1083						var loadedHandler = ()=>{
1084							window.removeEventListener('error', windowErrorHandler);
1085							resolve();
1086						};
1087
1088						script.addEventListener('load', loadedHandler);
1089						script.text = scripts.replaceAll('let jch_', 'jch_').replaceAll('const jch', 'window.hikashop.jch');
1090						try {
1091							d.head.appendChild(script);
1092							d.head.removeChild(script);
1093						} catch (e) {
1094							if (e instanceof SyntaxError) {
1095							}
1096						}
1097					})
1098					.catch(error => {
1099						console.warn('Could not process JavaScript code:\n', error);
1100					})
1101					.then(()=>{
1102					});
1103				}
1104
1105				if(!window.localPage) window.localPage = {};
1106				window.localPage.infiniteScrollPage = 1;
1107
1108				setTimeout(function(){
1109					var needHeightConsistency = currentArea.querySelector('[data-consistencyheight]');
1110					if(needHeightConsistency) {
1111						var elems = parentNode.querySelectorAll('.hikashop_subcontainer');
1112						if(elems && elems.length)
1113							window.hikashop.setConsistencyHeight(elems, 'min');
1114					}
1115
1116					if(window.hikaVotes)
1117						initVote(currentArea);
1118					if(hkjQuery && hkjQuery.hktooltip)
1119						hkjQuery('[data-toggle="hk-tooltip"]').hktooltip({"html": true,"container": "body"});
1120
1121					t.refreshCounter--;
1122					if(t.refreshCounter == 0) {
1123						o.fireAjax('filters.updated', {el: el, refreshAreas : refreshAreas, resp: resp});
1124					}
1125				}, 200);
1126			}, 0);
1127		});
1128	},
1129	addToCart: function(el, type, container, data) {
1130
1131		var d = document, t = this, o = window.Oby,
1132			product_id = 0,
1133			url = el.getAttribute('href'),
1134			cart_type = ((type !== 'wishlist') ? 'cart' : 'wishlist'),
1135			containerName = el.getAttribute('data-addTo-div'),
1136			extraContainer = el.getAttribute('data-addTo-extra'),
1137			dest_id = el.getAttribute('data-addTo-cartid');
1138
1139		product_id = (cart_type == 'cart') ? el.getAttribute('data-addToCart') : el.getAttribute('data-addToWishlist');
1140		dest_id = (dest_id ? parseInt(dest_id) : 0);
1141		if(!url)
1142			url = el.getAttribute('data-href');
1143
1144		// Avoid bots and crawlers to add products in the cart
1145		var r = /bot|googlebot|crawler|spider|robot|crawling/i;
1146		if(navigator && navigator.userAgent && r.test(navigator.userAgent))
1147			return false;
1148
1149		var process = true;
1150		window.Oby.fireAjax(cart_type+'-button.clicked', {el: el, product_id: product_id, type: cart_type, cart_id: dest_id, process: process});
1151		if(!process)
1152			return true;
1153
1154		// No product ID - fallback mode
1155		if(!product_id || !url) {
1156			if(containerName && d.forms[containerName]) {
1157				d.forms[containerName].submit();
1158				return false;
1159			}
1160			return true;
1161		}
1162
1163		if(typeof container !== 'undefined') {
1164			// container is provided, just use it
1165		}else if(containerName && product_id) {
1166			// search for the container on the page
1167			container = d.forms['hikashop_product_form_' + product_id + '_' + containerName] || d.forms[containerName];
1168		}
1169
1170		url += (url.indexOf('?') >= 0 ? '&' : '?') + 'tmpl=raw';
1171		if(typeof data !== 'undefined') {
1172		} else if(container) {
1173			if(window.FormData)
1174				data = new FormData(container);
1175			else
1176				data = o.getFormData(container);
1177			if(extraContainer) {
1178				extraContainer = d.forms[extraContainer] || d.getElementById(extraContainer);
1179				if(window.FormData) {
1180					extra = o.getFormData(extraContainer, false);
1181					for(var k in extra) {
1182						if(!extra.hasOwnProperty(k))
1183							continue;
1184						if(k == 'product_id')
1185							extra[k] = product_id;
1186						if(typeof(extra[k]) == 'object') {
1187							for(var i in extra[k]) {
1188								data.append(k, extra[k][i]);
1189							}
1190						} else
1191							data.append(k, extra[k]);
1192					}
1193				} else {
1194					var extra = o.getFormData(extraContainer);
1195					if(extra)
1196						data += '&' + extra;
1197					data += '&product_id='+product_id;
1198				}
1199			}
1200			if(window.FormData) {
1201				data.append('cart_type', cart_type);
1202				if(dest_id)
1203					data.append('cart_id', dest_id);
1204			} else {
1205				data += '&cart_type=' + cart_type;
1206				if(dest_id)
1207					data += '&cart_id+' + dest_id;
1208			}
1209		} else {
1210			data = 'cart_type=' + cart_type;
1211			if(dest_id)
1212				data += '&cart_id+' + dest_id;
1213		}
1214
1215		var className = el.getAttribute('data-addTo-class');
1216		if(className) o.addClass(el, className);
1217
1218		// if we are in a popup we want the add to cart to happen in the parent frame.
1219		// however, this can cause issues if the website is inside an iframe from another domain so we add a try/catch so that the add to cart can work
1220		if(window.self !== window.top) {
1221			try {
1222				if(window.top.hikashop)
1223					return window.top.hikashop.addToCart(el, type, container, data);
1224			} catch(e) {}
1225		}
1226
1227		o.xRequest(url, {mode:'POST', data: data}, function(xhr) {
1228			var className = el.getAttribute('data-addTo-class');
1229			if(className) o.removeClass(el, className);
1230
1231			var resp = Oby.evalJSON(xhr.responseText);
1232			var cart_id = (resp && (resp.ret || resp.ret === 0)) ? resp.ret : parseInt(xhr.responseText);
1233			if(isNaN(cart_id)) {
1234				console.log('cart_id was not returned in addToCart AJAX call');
1235				console.log(resp);
1236				return false;
1237			}
1238
1239			var triggers = window.Oby.fireAjax(cart_type+'.updated', {id: cart_id, el: el, product_id: product_id, type: cart_type, resp: resp});
1240			if(triggers !== false && triggers.length > 0)
1241				return true;
1242			if(window.localPage && cart_type == 'cart' && window.localPage.cartRedirect && typeof(window.localPage.cartRedirect) == 'function')
1243				return window.localPage.cartRedirect(cart_id, product_id, resp);
1244			if(window.localPage && cart_type == 'wishlist' && window.localPage.wishlistRedirect && typeof(window.localPage.wishlistRedirect) == 'function')
1245				return window.localPage.wishlistRedirect(cart_id, product_id, resp);
1246		});
1247		return false;
1248	},
1249	addToWishlist: function(el) {
1250		return this.addToCart(el, 'wishlist');
1251	},
1252	checkQuantity: function(el) {
1253		var value = parseInt(el.value), old = el.getAttribute('data-hk-qty-old'),
1254			min = parseInt(el.getAttribute('data-hk-qty-min')),
1255			max = parseInt(el.getAttribute('data-hk-qty-max')),
1256			allowZero = el.getAttribute('data-hk-allow-zero') == 'true';
1257		if(old)
1258			old = parseInt(old);
1259		// No values - return
1260		if(isNaN(value)) {
1261			el.value = old || (isNaN(min) ? 1 : min);
1262			return false;
1263		}
1264		if(''+value != el.value)
1265			el.value = value;
1266		if(isNaN(min) || isNaN(max))
1267			return false;
1268		var triggers = window.Oby.fireAjax("quantity.checked", {el:el, value:value, max:max, min:min});
1269		if(
1270			(triggers !== false && triggers.length > 0) ||
1271			(value == 0 && allowZero) ||
1272			((value <= max || max == 0) && value >= min)
1273		) {
1274			// quantity change is ok
1275
1276			// trigger add to cart if the quantity input is synchronized with the cart
1277			var isSynch = document.getElementById(el.id + '_synch');
1278			if(isSynch) {
1279				isSynch.value = value;
1280				var addToCartButton = document.getElementById(el.id + '_add_to_cart_button');
1281				if(addToCartButton) {
1282					addToCartButton.onclick();
1283				}
1284			}
1285			return true;
1286		}
1287		if(max > 0 && value > max) {
1288			el.value = max;
1289			if(hkjQuery.notify) {
1290				this.translate(['QUANTITY_CHANGE_IMPOSSIBLE', 'MAXIMUM_FOR_PRODUCT_IS_X'], function(trans){
1291					hkjQuery(el).notify({title:trans[0],text:trans[1].replace('%s', max), image:'<i class="fa fa-3x fa-exclamation-circle"></i>'},{style:"metro",className:"warning",arrowShow:true,position:"top left"});
1292				});
1293			}
1294		} else if(value < min) {
1295			el.value = min;
1296			if(hkjQuery.notify) {
1297				this.translate(['QUANTITY_CHANGE_IMPOSSIBLE', 'MINIMUM_FOR_PRODUCT_IS_X'], function(trans){
1298					hkjQuery(el).notify({title:trans[0],text:trans[1].replace('%s', min), image:'<i class="fa fa-3x fa-exclamation-circle"></i>'},{style:"metro",className:"warning",arrowShow:true,position:"top left"});
1299				});
1300			}
1301		}
1302		// should not happen ?
1303		return true;
1304	},
1305	translate: function(keys, callback) {
1306		var t = this, trans = {}, missingKeys = [], o = window.Oby;
1307
1308		for(var c = 0; c < keys.length; c++) {
1309			var key = keys[c];
1310			if(!t.translations[key]) {
1311				missingKeys.push(key);
1312			} else {
1313				trans[c] = t.translations[key];
1314			}
1315		}
1316
1317		if(!missingKeys.length) {
1318			callback(trans);
1319			return;
1320		}
1321
1322		if(!t.translations_url) {
1323			console.log('missing translations URL');
1324			return;
1325		}
1326		o.xRequest(t.translations_url, {mode:'POST', data: 'translations=' + missingKeys.join(',')}, function(xhr) {
1327			var resp = o.evalJSON(xhr.responseText);
1328			foundKeys = Object.getOwnPropertyNames(resp);
1329			for(var c = 0; c < foundKeys.length; c++) {
1330				var key = foundKeys[c];
1331				trans[keys.indexOf(key)] = resp[key];
1332				t.translations[key] = resp[key];
1333			}
1334			callback(trans);
1335		});
1336	},
1337	addTrans: function(data) {
1338		for(var k in data) {
1339			if(!data.hasOwnProperty(k)) continue;
1340			this.translations[k] = data[k];
1341		}
1342	},
1343	updateQuantity: function(el, dataInput, mod) {
1344		var d = document, input = el;
1345		if(!el)
1346			return false;
1347		if(dataInput === undefined || !dataInput)
1348			dataInput = el.getAttribute('data-hk-qty-input');
1349		if(d.getElementById(dataInput))
1350			input = d.getElementById(dataInput);
1351		if(mod === undefined || !mod)
1352			mod =  parseInt(el.getAttribute('data-hk-qty-mod'));
1353		if(isNaN(mod) || mod == 0)
1354			mod = 1;
1355		var value = parseInt(input.value);
1356		if(isNaN(value))
1357			value = 0;
1358		input.value = (value + mod);
1359		this.checkQuantity(input);
1360		if(el.tagName.toLowerCase() == 'a')
1361			el.blur();
1362		return false;
1363	},
1364	deleteFromCart: function(el, cart_type, container) {
1365		if(el.processing)
1366			return false;
1367
1368		var d = document, t = this, o = window.Oby,
1369			url = el.getAttribute('href');
1370		if(!cart_type || cart_type === undefined)
1371			cart_type = el.getAttribute('data-cart-type');
1372		if(!cart_type || cart_type == '')
1373			return true;
1374
1375		url += (url.indexOf('?') >= 0 ? '&' : '?') + 'tmpl=raw';
1376		var cart_id = parseInt(el.getAttribute('data-cart-id')),
1377			cart_product_id = parseInt(el.getAttribute('data-cart-product-id'));
1378		if(cart_id === NaN || cart_product_id === NaN)
1379			return true;
1380
1381		if(container && typeof(container) == 'string')
1382			container = d.getElementById(container);
1383
1384		el.processing = true;
1385		if(container)
1386			o.addClass(container, "hikashop_checkout_loading");
1387		var data = 'cart_type=' + cart_type + '&cart_id=' + cart_id + '&cart_product_id=' + cart_product_id;
1388
1389		o.xRequest(url, {mode:'POST', data: data}, function(xhr) {
1390			el.processing = false;
1391			if(container)
1392				o.removeClass(container, "hikashop_checkout_loading");
1393
1394			var resp = Oby.evalJSON(xhr.responseText);
1395			cart_id = (resp && resp.ret) ? resp.ret : ((resp && resp.empty && resp.empty == 'true') ? cart_id : parseInt(xhr.responseText));
1396			if(cart_id === NaN)
1397				return;
1398			resp.cart_product_id = cart_product_id;
1399			resp.quantity = 0;
1400			var params = {id: cart_id, type: cart_type, resp: resp, notify: false};
1401			window.Oby.fireAjax(cart_type+'.updated', params);
1402		});
1403		return false;
1404	},
1405	submitCartModule: function(form, container, cart_type) {
1406		this.formAjaxSubmit(form, container, function(data, params) {
1407			var resp = window.Oby.evalJSON(data);
1408			var cart_id = (resp && resp.ret) ? resp.ret : parseInt(data);
1409			if(cart_id === NaN)
1410				return;
1411			var updatedElements = [];
1412			for (var key of params.keys()) {
1413				if(key.startsWith('item[') && key.endsWith('][cart_product_quantity]')) {
1414					updatedElements.push({ cart_product_id: key.replace('item[', '').replace('][cart_product_quantity]', ''), quantity_requested: params.get(key)});
1415				}
1416			}
1417			window.Oby.fireAjax(cart_type+'.updated', {id: cart_id, type: cart_type, resp: resp, updated_elements: updatedElements, notify: false});
1418		});
1419		return false;
1420	},
1421	formAjaxSubmit: function(form, container, cb) {
1422		var d = document, o = window.Oby,
1423			url = form.action;
1424		if(form.processing)
1425			return false;
1426		if(container && typeof(container) == 'string')
1427			container = d.getElementById(container);
1428		if(window.FormData) {
1429			data = new FormData(form);
1430			data.append('tmpl', 'raw');
1431		} else {
1432			data = o.getFormData(form);
1433			data += '&tmpl=raw';
1434		}
1435		form.processing = true;
1436		if(container)
1437			o.addClass(container, "hikashop_checkout_loading");
1438		o.xRequest(url, {mode:'POST', data: data}, function(xhr) {
1439			form.processing = false;
1440			if(container)
1441				o.removeClass(container, "hikashop_checkout_loading");
1442			if(!cb)
1443				o.updateElem(container, xhr.responseText);
1444			cb(xhr.responseText, data);
1445		});
1446		return false;
1447	},
1448	syncInit : function() {
1449		window.hikashop.noChzn();
1450		window.Oby.registerAjax(['cart.updated'], function(params){
1451			window.hikashop.refreshSync(params);
1452		});
1453		window.Oby.registerAjax(['hkContentChanged'], function(params){
1454			window.Oby.xRequest(window.hikashop.cartInfoUrl, {}, function(xhr) {
1455				var resp = Oby.evalJSON(xhr.responseText);
1456				var params = {resp: resp};
1457				window.hikashop.refreshSync(params);
1458			});
1459		});
1460
1461		window.Oby.registerAjax(['hkCustomFieldChanged'], function(params){
1462			if(params.field_type != 'item')
1463				return;
1464			window.Oby.xRequest(window.hikashop.cartInfoUrl, {}, function(xhr) {
1465				var resp = Oby.evalJSON(xhr.responseText);
1466				var params = {resp: resp};
1467				window.hikashop.refreshSync(params);
1468			});
1469		});
1470
1471		if(window.hikashop.cartInfo) {
1472			var params = {resp: window.hikashop.cartInfo};
1473			window.hikashop.refreshSync(params);
1474		}
1475	},
1476	xRequest: function(url, options, cb, cbError) {
1477		var t = this, xhr = window.Oby.getXHR();
1478		if(!options) options = {};
1479		if(!cb) cb = function(){};
1480		options.mode = options.mode || 'GET';
1481		options.update = options.update || false;
1482		options.replace = options.replace === undefined || options.replace;
1483		xhr.onreadystatechange = function() {
1484			if(xhr.readyState != 4)
1485				return;
1486			if( xhr.status == 200 || (xhr.status == 0 && xhr.responseText > 0) || !cbError ) {
1487				if(cb)
1488					cb(xhr,options.params);
1489				if(options.update)
1490					t.updateElem(options.update, xhr.responseText, options.replace);
1491			} else {
1492				cbError(xhr,options.params);
1493			}
1494		};
1495		xhr.open(options.mode, url, true);
1496		if(options.mode.toUpperCase() == 'POST' && typeof(options.data) == 'string') {
1497			xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
1498		}
1499		if(typeof Joomla !== 'undefined' && Joomla && Joomla.getOptions) {
1500			var csrf = Joomla.getOptions("csrf.token", "");
1501			if(csrf) {
1502				xhr.setRequestHeader("X-CSRF-Token", csrf);
1503			}
1504		}
1505		xhr.send( options.data );
1506	},
1507	updateElem: function(elem, data, replace = true) {
1508		var d = document, scripts = [], json = '';
1509		if( typeof(elem) == 'string' )
1510			elem = d.getElementById(elem);
1511
1512		// extract the javascript files and scripts from the HTML
1513		var files = [];
1514		var scriptsAlreadyLoaded = document.getElementsByTagName("script");
1515		var text = data.replace(/<script([^>]*)>([\s\S]*?)<\/script>/gi, function(all, attributes, code){
1516			if(all.indexOf('type="application/json"') != -1) {
1517				json += code + '\n';
1518				return '';
1519			}
1520			if(all.indexOf('type="application/ld+json"') != -1)
1521				return '';
1522
1523			if(all.indexOf('type="importmap"') != -1)
1524				return '';
1525			regex = RegExp('src="([^"]+)"', 'gi');
1526			result = regex.exec(attributes);
1527			if(result) {
1528				result[1] = result[1].replace(/\.js\?[0-9a-f\.]{1,128}/gi, '.js').replace(/&amp;/g, '&');
1529				for(var i = 0; i < scriptsAlreadyLoaded.length; i++) {
1530					var src = scriptsAlreadyLoaded[i].getAttribute('src');
1531					if(src && src.includes(result[1]))
1532						return '';
1533				}
1534				files.push(result[1]);
1535				return '';
1536			}
1537			scripts.push(code.replace('document.addEventListener(\'DOMContentLoaded\',', 'window.hikashop.ready(').replace('document.addEventListener("DOMContentLoaded",', 'window.hikashop.ready(').replace('$(document).ready(', 'window.hikashop.ready(').replace( 'find("select").chosen(', 'find("select").filter(":visible").chosen('));
1538			return '';
1539		});
1540
1541		// add the HTML without the javascript elements to the element on the page
1542		if(text.indexOf('id="hikashop_main_content"')) {
1543			var wrapper = document.createElement('div');
1544			wrapper.innerHTML = text;
1545			var mainArea = wrapper.querySelector('#hikashop_main_content');
1546			if(mainArea) {
1547				if(replace)
1548					elem.innerHTML = '';
1549				elem.appendChild(mainArea);
1550				text = false;
1551			}
1552		}
1553		if(text !== false) {
1554			if(!replace)
1555				elem.insertAdjacentHTML('beforeend',text);
1556			else
1557				elem.innerHTML = text;
1558		}
1559
1560		// add the javascript elements and run them
1561		if( json != '' && Joomla) {
1562			var option = JSON.parse(json);
1563			if (option) {
1564				Joomla.loadOptions(option);
1565			}
1566		}
1567
1568		if(files.length) {
1569			this.loadScripts(files, function() {
1570				window.hikashop.addScript(scripts);
1571			});
1572		} else {
1573			window.hikashop.addScript(scripts);
1574		}
1575	},
1576	addScript: function (code, url) {
1577		if(!code.length)
1578			return;
1579		for(var k=0; k < code.length; k++) {
1580			try {
1581				var oNew = document.createElement("script");
1582				oNew.type = "text/javascript";
1583				oNew.textContent = code[k];
1584				document.getElementsByTagName("head")[0].appendChild(oNew);
1585			} catch (e) {
1586				if (e instanceof SyntaxError) {
1587					console.log(e.message + ' for ' + url);
1588					console.log(code);
1589				}
1590			}
1591		}
1592	},
1593	loadScripts: function(scripts, complete) {
1594		var xhr = window.Oby.getXHR();
1595		var loadScript = function( src ) {
1596			xhr.open("GET", src , true);
1597			xhr.send();
1598		};
1599		xhr.onreadystatechange = function() {
1600			if (xhr.readyState != 4)
1601				return;
1602			if (xhr.status == 200) {
1603				try {
1604					window.hikashop.addScript([xhr.responseText], xhr.responseURL);
1605				} catch (e) {
1606					if (e instanceof SyntaxError) {
1607						console.log(e.message + ' for ' + xhr.responseURL);
1608						console.log(xhr.responseText);
1609					}
1610				}
1611			}
1612			var next = scripts.shift();
1613			if ( next ) {
1614				loadScript(next);
1615			} else if ( typeof complete == 'function' ) {
1616				complete();
1617			}
1618		}
1619		loadScript( scripts.shift() );
1620	},
1621	refreshSync : function(params) {
1622		// the cart is empty so reset all the synched elements and refresh them
1623		if(params.resp.empty) {
1624			synchronizedEls = document.querySelectorAll('.synchronized_add_to_cart');
1625			for(var i=0; i < synchronizedEls.length; i++) {
1626				var el = synchronizedEls[i];
1627				el.value = 0;
1628				el.setAttribute('data-cart-product-id', 0);
1629				var id = el.getAttribute('data-id');
1630				window.hikashop.syncQuantity(id, el.value, el.value);
1631			}
1632		}
1633		// the cart is updated from the cart module
1634		else if(params.resp.products) {
1635			// loop on all the products on the page
1636			var els = document.querySelectorAll('.synchronized_add_to_cart');
1637
1638			if(!els.length)
1639				return;
1640			for(var k=0; k < els.length; k++) {
1641				var el = els[k];
1642				var id = el.getAttribute('data-id');
1643				var productId = el.getAttribute('data-product-id');
1644				var options = [];
1645				if(el.form) {
1646					var optionsTable = el.form.querySelector('.hikashop_product_options_table');
1647					if(optionsTable) {
1648						options = hikaProductOptions.getOptions();
1649					}
1650				}
1651				var found = false;
1652				// see if we have the product in the cart
1653				for(var i=0; i < params.resp.products.length; i++) {
1654					var result = params.resp.products[i];
1655					// get the current quantity from the response of the server and update the quantity for the quantity input of the current loop
1656					if(productId == result.product_id) {
1657						if(options.length || (result.options && result.options.length)) {
1658							// no options selected on the product page or no options selected in the product in the cart -> products are different
1659							if(!options.length || !result.options || !result.options.length)
1660								continue;
1661							var match = true;
1662							// check that both arrays contain the same elements
1663							for(var j=0; j < options.length; j++) {
1664								if(!result.options.includes(options[j])) {
1665									match = false;
1666									break;
1667								}
1668							}
1669							for(var j=0; j < result.options.length; j++) {
1670								if(!options.includes(result.options[j])) {
1671									match = false;
1672									break;
1673								}
1674							}
1675							if(!match)
1676								continue;
1677						}
1678						found = true;
1679						el.value = result.quantity;
1680					}
1681				}
1682				// TODO: add custom item fields
1683				if(!found) {
1684					el.value = 0;
1685					el.setAttribute('data-cart-product-id', 0);
1686				}
1687				window.hikashop.syncQuantity(id, el.value, el.value);
1688			}
1689		}
1690	},
1691	syncQuantity : function(id, qtyInCart, qtyInInput) {
1692		// refresh the quantity in the input field
1693		if(typeof qtyInInput !== 'undefined') {
1694
1695			var inputField = document.getElementById(id+'_select');
1696			if(!inputField)
1697				inputField = document.getElementById(id);
1698			if(inputField) {
1699				if(qtyInInput == 0) {
1700					var minQty = inputField.getAttribute('data-hk-qty-min');
1701					if(minQty == 0)
1702						qtyInInput = 1;
1703					else
1704						qtyInInput = minQty;
1705				}
1706				inputField.value = qtyInInput;
1707			}
1708		}
1709
1710		// update the display of the quantity input field and the buttons
1711		var quantityArea = document.getElementById(id + '_area');
1712		var cartButtonArea = document.getElementById(id + '_add_to_cart_button');
1713		var wishlistButtonArea = document.getElementById(id + '_add_to_wishlist_button');
1714		if(!quantityArea || !cartButtonArea)
1715			return;
1716		if(qtyInCart > 0) {
1717			quantityArea.style.display = '';
1718			cartButtonArea.style.display = 'none';
1719			if(wishlistButtonArea)
1720				wishlistButtonArea.style.display = 'none';
1721		} else {
1722			quantityArea.style.display = 'none';
1723			cartButtonArea.style.display = '';
1724			if(wishlistButtonArea)
1725				wishlistButtonArea.style.display = '';
1726		}
1727	},
1728	toggleOverlayBlock: function(el, type, state) {
1729		var t = this, d = document, w = window, o = w.Oby;
1730		if(typeof(el) == 'string')
1731			el = d.getElementById(el);
1732		if(!el)
1733			return false;
1734		var open = !!el.toggleOpen; // (el.style.display != 'none');
1735		if(type != 'hover' && type != 'toggle' && type != 'drawer')
1736			type = 'click';
1737		if(type == 'drawer') {
1738			if(open)
1739				hkDrawer.closeDrawer(el);
1740			else
1741				hkDrawer.openDrawer(el);
1742			return true;
1743		}
1744		if(type == 'hover' && (!state && open) || (state && !open))
1745			return;
1746
1747		if(jQuery) {
1748			jQuery(el).slideToggle('fast');
1749		} else {
1750			el.style.display = (el.style.display == 'none')?'block':'none';
1751		}
1752
1753		el.toggleOpen = !el.toggleOpen;
1754
1755		if(open) {
1756			if(type == 'hover') {
1757				o.removeEvent(el, "mouseout", el.toggleFunctionHover);
1758				el.toggleFunctionHover = null;
1759			}
1760			if(el.toggleFunction)
1761				o.removeEvent(document, "click", el.toggleFunction);
1762			el.toggleFunction = null;
1763			return true;
1764		}
1765		if(type == 'hover') {
1766			el.toggleFunctionHover = function(event) {
1767				if(event.target && this != event.target)
1768					return false;
1769				window.hikashop.toggleOverlayBlock(el, 'hover', true);
1770			};
1771			if(jQuery) {
1772				jQuery(el).mouseleave(el.toggleFunctionHover);
1773			} else {
1774				o.addEvent(el, "mouseout", el.toggleFunctionHover);
1775			}
1776		}
1777		var f = function(evt) {
1778			if (!evt) var evt = window.event;
1779			var trg = (window.event) ? evt.srcElement : evt.target;
1780			while(trg != null) {
1781				if(trg == el)
1782					return;
1783				trg = trg.parentNode;
1784			}
1785			t.toggleOverlayBlock(el);
1786			o.removeEvent(document, "click", f);
1787			el.toggleFunction = null;
1788		};
1789		el.toggleFunction = f;
1790		setTimeout(function(){ o.addEvent(document, "click", f); }, 100);
1791		return true;
1792	},
1793	addToCompare: function(el) {
1794		var t = this, d = document, w = window, o = w.Oby;
1795		if(!t.compare_list)
1796			t.compare_list = {};
1797
1798		if(el.disabled)
1799			return false;
1800
1801		var product_id = parseInt(el.getAttribute('data-addToCompare')),
1802			product_name = el.getAttribute('data-product-name'),
1803			css = el.getAttribute('data-addTo-class');
1804
1805		if(isNaN(product_id) || product_id <= 0)
1806			return false;
1807		if(!css || css == '')
1808			css = 'hika-compare';
1809
1810		var adding = !t.compare_list.hasOwnProperty(product_id);
1811		if(adding)
1812			t.compare_list[product_id] = product_name;
1813		else
1814			delete t.compare_list[product_id];
1815
1816		var elems = d.querySelectorAll('[data-addToCompare="'+product_id+'"]');
1817		if(elems && elems.forEach) {
1818			elems.forEach(function(e){
1819				if(e.nodeName.toLowerCase() == 'input' && e.type.toLowerCase() == 'checkbox')
1820					e.checked = adding;
1821				if(adding)
1822					o.addClass(e, css);
1823				else
1824					o.removeClass(e, css);
1825			});
1826		}
1827		var size = 0;
1828		if(Object.keys) {
1829			size = Object.keys(t.compare_list).length;
1830		} else {
1831			for(var k in t.compare_list) {
1832				if(compare_list.hasOwnProperty(k))
1833					size++;
1834			}
1835		}
1836		var triggers = window.Oby.fireAjax('compare.updated', {el: el, product_id: product_id, added: adding, list: t.compare_list, size: size});
1837		if(triggers !== false && triggers.length > 0)
1838			return false;
1839		return false;
1840	},
1841	toggleOptions: function() {
1842		var d = document, btnText = d.getElementById('openSearch_btn'),
1843		tagsDiv = d.getElementById('hikashop_listing_filters_id');
1844		if(tagsDiv.classList.contains("hidden-features") ) {
1845			tagsDiv.classList.remove("hidden-features");
1846			tagsDiv.classList.add("show-features");
1847			btnText.innerHTML = "<i class='fas fa-chevron-up'></i>";
1848		} else {
1849			tagsDiv.classList.remove("show-features");
1850			tagsDiv.classList.add("hidden-features");
1851			btnText.innerHTML = "<i class='fas fa-chevron-down'></i>";
1852		}
1853		return false;
1854	},
1855	clearOptions: function(options, defaults) {
1856		var d = document, btnText = d.getElementById('openSearch_btn'),
1857		tagsDiv = d.getElementById('hikashop_listing_filters_id');
1858		if(!options)
1859			return false;
1860		for(var i = options.length - 1; i >= 0; i--) {
1861			var name = 'filter_' + options[i];
1862			var el = d.getElementById(name);
1863			if(!el) {
1864				console.log('Filter option '+name+' not found');
1865				continue;
1866			}
1867			el.value = defaults[i];
1868		}
1869		var	clearEl = document.getElementById('hkclear');
1870		if(clearEl) {
1871			clearEl.value = 1;
1872		}
1873		return true;
1874	},
1875	clearSearch: function(el, id, all) {
1876		if(el.form.limitstart)
1877			el.form.limitstart.value = 0;
1878		var search = document.getElementById(id);
1879		if(search)
1880			search.value = '';
1881		if(all) {
1882			var v, els = el.form.querySelectorAll('[data-search-clear]');
1883			for(var i = els.length - 1; i >= 0; i--) {
1884				v = els[i].getAttribute('data-search-clear');
1885				els[i].value = v;
1886			}
1887		} else
1888			all = false;
1889		var triggers = window.Oby.fireAjax('search.cleared', {el: el, id: id, all: all});
1890		if(triggers !== false && triggers.length > 0)
1891			return false;
1892		el.form.submit();
1893		return true;
1894	},
1895	compareProducts: function(el, elems) {
1896		var t = this, params = '',
1897			url = el.getAttribute('data-compare-href');
1898		if(!url)
1899			return false;
1900		if(!elems)
1901			elems = t.compare_list;
1902		if(!elems)
1903			return false;
1904		for(var k in elems) {
1905			if(!elems.hasOwnProperty)
1906				continue;
1907			if(params != '') params += '&';
1908			params += 'cid[]=' + k;
1909		}
1910		el.href = url + ((url.indexOf('?') >= 0) ? '&' : '?') + params;
1911		return true;
1912	},
1913	toggleField: function(new_value, namekey, field_type, id, prefix, type) {
1914		var d = document, checked = 0, size = 0, obj = null, specialField = false,
1915			checkedGood = [], count = [], el = null,
1916			arr = d.getElementsByName('data['+field_type+']['+namekey+'][]');
1917
1918		// handle when this is passed in new_value
1919		// it allows for better handling of radios and checkboxes
1920		if(new_value instanceof Element) {
1921			if(new_value.type == 'radio' || new_value.type == 'checkbox') {
1922				elements = d.getElementsByName(new_value.name);
1923				for(cpt = 0; cpt < elements.length; cpt++) {
1924					if(elements[cpt].checked) {
1925						new_value = elements[cpt].value;
1926					}
1927				}
1928				if(new_value instanceof Element) {
1929					new_value = '';
1930				}
1931			} else {
1932				new_value = new_value.value;
1933			}
1934		} 
1935		if(!arr)
1936			return false;
1937
1938		if( new_value === null) {
1939			if(d.getElementById(type + namekey))
1940				new_value = d.getElementById(type + namekey).value;
1941			else {
1942				inputs = d.getElementsByName('data['+field_type+']['+namekey+']');
1943				for(var i = inputs.length - 1; i >= 0; i--) {
1944					if(inputs[i].checked)
1945						new_value = inputs[i].value;
1946				}
1947			}
1948		}
1949
1950		if(!this.fields_data && window.hikashopFieldsJs) {
1951			this.fields_data = window.hikashopFieldsJs;
1952		} else {
1953			for(var n in window.hikashopFieldsJs) {
1954				if(!window.hikashopFieldsJs.hasOwnProperty(n)) continue;
1955				if(this.fields_data[n]) continue;
1956				this.fields_data[n] = window.hikashopFieldsJs[n];
1957			}
1958		}
1959		if(this.fields_data === undefined || this.fields_data[field_type] === undefined) {
1960
1961		} else {
1962			size = (arr[0] && arr[0].length !== undefined) ? arr[0].length : arr.length;
1963
1964			if(prefix === undefined || !prefix || prefix.length == 0 || prefix.substr(-1) != '_')
1965				prefix = 'hikashop_';
1966
1967			var elementName = prefix + field_type + '_' + namekey;
1968			if(id)
1969				elementName = elementName + '_' + id;
1970			el = document.getElementById(elementName);
1971			var parentHidden = (el && el.style.display && el.style.display == 'none');
1972
1973			for(var c = 0; c < size; c++) {
1974				if(arr && arr[0] != undefined && arr[0].length != undefined)
1975					obj = d.getElementsByName('data['+field_type+']['+namekey+'][]').item(0).item(c);
1976				else
1977					obj = d.getElementsByName('data['+field_type+']['+namekey+'][]').item(c);
1978
1979				if(obj.checked || obj.selected)
1980					checked++;
1981
1982				if((obj.type && obj.type == 'checkbox') || obj.selected)
1983					specialField = true;
1984			}
1985			var data = this.fields_data[field_type][namekey];
1986
1987			for(var k in data) {
1988				if(typeof data[k] != 'object')
1989					continue;
1990
1991				for(var l in data[k]) {
1992					if(typeof data[k][l] != 'string')
1993						continue;
1994
1995					if (typeof count[k] == 'undefined') {
1996						count[k] = 0;
1997						checkedGood[k] = 0;
1998					}
1999					count[k]++;
2000					newEl = d.getElementById(namekey + '_' + k);
2001					if(newEl && (newEl.checked || newEl.selected)) {
2002						checkedGood[k]++;
2003						break;
2004					}
2005				}
2006			}
2007
2008			specialField = specialField || (arr[0] && arr[0].length && count.length > 1);
2009
2010			for(var j in data) {
2011				if(typeof data[j] != 'object')
2012					continue;
2013				for(var i in data[j]) {
2014					if(typeof data[j][i] != 'string')
2015						continue;
2016
2017					var elementName = prefix + field_type + '_' + data[j][i];
2018					if(id)
2019						elementName = elementName + '_' + id;
2020					el = document.getElementById(elementName);
2021					if(!el)
2022						continue;
2023					var condition = 'IS';
2024					if(data[j]['condition'] && data[j]['condition'][i])
2025						condition = data[j]['condition'][i];
2026					if( condition != 'IS NOT') {
2027						var display = 'none';
2028						var value = '';
2029					} else {
2030						var display = '';
2031						var value = el.value;
2032					}
2033					if(!parentHidden &&
2034						(
2035							(specialField && checkedGood[j] == count[j] && new_value != '')
2036							||
2037							(!specialField &&
2038								(
2039									j == new_value
2040									||
2041									(checkedGood[j] && count[j] && checkedGood[j] == count[j])
2042								)
2043							)
2044						)
2045					) {
2046						if(condition != 'IS NOT') {
2047							display = '';
2048							value = el.value;
2049						} else {
2050							display = 'none';
2051							value = '';
2052						}
2053					}
2054
2055					// set and unset the required attribute so that HTML5 validation works properly with hidden fields
2056					var input = document.getElementById(data[j][i]);
2057					if(input && input.hasAttribute('aria-required')) {
2058						if(display == 'none') {
2059							input.removeAttribute('required');
2060							input.classList.remove('required', 'invalid', 'form-control-danger');
2061							input.setAttribute('aria-invalid', 'false');
2062							var label = document.querySelector("label[for='"+data[j][i]+"']");
2063							if (label) {
2064								label.classList.remove("invalid");
2065								var fb = label.querySelector('.form-control-feedback');
2066								if (fb) {
2067									fb.remove();
2068								}
2069							}
2070						} else {
2071							input.setAttribute('required', 'required');
2072							input.classList.add('required');
2073						}
2074					}
2075
2076					el.style.display = display;
2077					this.toggleField(value, data[j][i], field_type, id, prefix);
2078				}
2079			}
2080		}
2081		if(window.Oby && window.Oby.fireAjax)
2082			window.Oby.fireAjax("hkCustomFieldChanged", {field_type: field_type, namekey: namekey});
2083		return false;
2084	}
2085};
2086window.hikashop = hikashop;
2087
2088if(oldHikaShop && oldHikaShop instanceof Object) {
2089	for (var attr in oldHikaShop) {
2090		if (oldHikaShop.hasOwnProperty(attr) && !window.hikashop.hasOwnProperty(attr))
2091			window.hikashop[attr] = oldHikaShop[attr];
2092	}
2093}
2094})();
2095
2096function tableOrdering(order, dir, task) {
2097	var form = document.adminForm;
2098	form.filter_order.value = order;
2099	form.filter_order_Dir.value	= dir;
2100	submitform(task);
2101}
2102
2103function submitform(pressbutton) {
2104	var d = document;
2105	if(!d.adminForm)
2106		return false;
2107	if(pressbutton)
2108		d.adminForm.task.value = pressbutton;
2109
2110	// old codeMirror code
2111	if(typeof(CodeMirror) == 'function') {
2112		for(x in CodeMirror.instances) {
2113			d.getElementById(x).value = CodeMirror.instances[x].getCode();
2114		}
2115	}
2116	// Creating the event
2117	var event = new Event('submit', {
2118		'bubbles'    : true, // Whether the event will bubble up through the DOM or not
2119		'cancelable' : true  // Whether the event may be canceled or not
2120	});
2121	if(d.adminForm.dispatchEvent( event )) {
2122		d.adminForm.submit();
2123	}
2124	return false;
2125}
2126
2127if(!window.submitbutton) {
2128	window.submitbutton = function(name) { submitform(name); };
2129}
2130
2131function hikashopCheckChangeForm(type, form) {
2132	if(!form)
2133		return true;
2134	var varform = document[form];
2135
2136	if(typeof(hikashopFieldsJs) == 'undefined' || typeof(hikashopFieldsJs['reqFieldsComp']) == 'undefined' || typeof(hikashopFieldsJs['reqFieldsComp'][type]) == 'undefined' || hikashopFieldsJs['reqFieldsComp'][type].length <= 0)
2137		return true;
2138
2139	var d = document;
2140	for(var i = 0; i < hikashopFieldsJs['reqFieldsComp'][type].length; i++) {
2141		elementName = 'data['+type+']['+hikashopFieldsJs['reqFieldsComp'][type][i]+']';
2142		if(typeof(varform.elements[elementName]) == 'undefined')
2143			elementName = type+'_'+hikashopFieldsJs['reqFieldsComp'][type][i];
2144
2145		elementToCheck = varform.elements[elementName];
2146		elementId = 'hikashop_'+type+'_'+ hikashopFieldsJs['reqFieldsComp'][type][i];
2147		el = d.getElementById(elementId);
2148
2149		if(elementToCheck && (typeof el == 'undefined' || el == null || typeof el.style == 'undefined' || el.style.display!='none') && !hikashopCheckField(elementToCheck,type,i,elementName,varform.elements)) {
2150			if(typeof(hikashopFieldsJs['entry_id']) == 'undefined')
2151				return false;
2152
2153			for(var j = 1; j <= hikashop['entry_id']; j++) {
2154				elementName = 'data['+type+'][entry_'+j+']['+hikashopFieldsJs['reqFieldsComp'][type][i]+']';
2155				elementToCheck = varform.elements[elementName];
2156				elementId = 'hikashop_'+type+'_'+ hikashopFieldsJs['reqFieldsComp'][type][i] + '_' + j;
2157				el = d.getElementById(elementId);
2158				if(elementToCheck && (typeof el == 'undefined' || el == null || typeof el.style == 'undefined' || el.style.display != 'none') && !hikashopCheckField(elementToCheck,type,i,elementName,varform.elements)) {
2159					return false;
2160				}
2161			}
2162		}
2163	}
2164
2165	if(type == 'register') {
2166		// check the password confirmation field only if we are in selector registration and that the user selected "registration" or "simplified registration", or that the registration is on "all in one page" and that the password confirmation field is there
2167		var register = d.getElementById('data_register_registration_method0');
2168		if(!register)
2169			register = d.getElementById('data[register][registration_method]0');
2170
2171		var simplified_pwd = d.getElementById('data_register_registration_method3');
2172		if(!simplified_pwd)
2173			simplified_pwd = d.getElementById('data[register][registration_method]3');
2174
2175		if((simplified_pwd && simplified_pwd.checked) || (register && register.checked) || (!simplified_pwd && !register)) {
2176			// check password
2177			if(typeof(varform.elements['data[register][password]']) != 'undefined' && typeof(varform.elements['data[register][password2]']) != 'undefined') {
2178				passwd = varform.elements['data[register][password]'];
2179				passwd2 = varform.elements['data[register][password2]'];
2180				if(passwd.value != passwd2.value) {
2181					alert(hikashopFieldsJs['password_different']);
2182					return false;
2183				}
2184			}
2185		}
2186
2187		//check email
2188		var emailField = varform.elements['data[register][email]'];
2189		emailField.value = emailField.value.replace(/ /g,"");
2190		var filter = /^([a-z0-9_'&\.\-\+])+\@(([a-z0-9\-])+\.)+([a-z0-9]{2,14})+$/i;
2191		if(!emailField || !filter.test(emailField.value)) {
2192			alert(hikashopFieldsJs['valid_email']);
2193			return false;
2194		}
2195	} else if(type == 'address' && typeof(varform.elements['data[address][address_telephone]']) != 'undefined') {
2196		var phoneField = varform.elements['data[address][address_telephone]'], filter = /[0-9]+/i;
2197		if(phoneField) {
2198			phoneField.value = phoneField.value.replace(/ /g,"");
2199			if(phoneField.value.length > 0 && !filter.test(phoneField.value)) {
2200				alert(hikashopFieldsJs['valid_phone']);
2201				return false;
2202			}
2203		}
2204	}
2205
2206	return true;
2207}
2208
2209function hikashopCheckField(elementToCheck, type, i, elementName, form) {
2210	if(!elementToCheck)
2211		return true;
2212
2213	var d = document, isValid = false;
2214	if(typeof(elementToCheck.value) != 'undefined') {
2215		if(elementToCheck.value == ' ' && typeof(form[elementName+'[]']) != 'undefined') {
2216			if(form[elementName+'[]'].checked) {
2217				isValid = true;
2218			} else {
2219				for(var a = form[elementName+'[]'].length - 1; a >= 0; a--) {
2220					if(form[elementName+'[]'][a].checked && form[elementName+'[]'][a].value.length > 0)
2221						isValid = true;
2222				}
2223			}
2224		} else if(elementToCheck.value.length > 0){
2225			var found = false;
2226			for(var j in hikashopFieldsJs['regexFieldsComp'][type]) {
2227				if(hikashopFieldsJs['regexFieldsComp'][type][j] == hikashopFieldsJs['reqFieldsComp'][type][i]) found = j;
2228			}
2229			if(typeof(hikashopFieldsJs['regexFieldsComp']) != 'undefined' && typeof(hikashopFieldsJs['regexFieldsComp'][type]) != 'undefined' && found){
2230				myregexp = new RegExp(hikashopFieldsJs['regexValueFieldsComp'][type][found]);
2231				if(myregexp.test(elementToCheck.value)){
2232					isValid = true;
2233				}
2234			}else{
2235				isValid = true;
2236			}
2237		}
2238	} else {
2239		for(var a = elementToCheck.length - 1; a >= 0; a--) {
2240			 if(elementToCheck[a].checked && elementToCheck[a].value.length > 0)
2241			 	isValid = true;
2242		}
2243	}
2244
2245	// Case for the switcher display, ignore check according to the method selected
2246	// joomla 3 ids are differents than joomla 1.5...
2247	var simplified_pwd = d.getElementById('data_register_registration_method3');
2248	if(!simplified_pwd) simplified_pwd = d.getElementById('data[register][registration_method]3');
2249
2250	var simplified = d.getElementById('data_register_registration_method1');
2251	if(!simplified) simplified = d.getElementById('data[register][registration_method]1');
2252
2253	var guest = d.getElementById('data_register_registration_method2');
2254	if(!guest) guest = d.getElementById('data[register][registration_method]2');
2255
2256	if(!isValid && ((simplified && simplified.checked) || (guest && guest.checked) ) && (elementName == 'data[register][password]' || elementName == 'data[register][password2]')){
2257		window.Oby.addClass(elementToCheck, 'invalid');
2258		return true;
2259	}
2260
2261	if(!isValid && ( (simplified && simplified.checked) || (guest && guest.checked) || (simplified_pwd && simplified_pwd.checked) ) && (elementName == 'data[register][name]' || elementName == 'data[register][username]')) {
2262		window.Oby.addClass(elementToCheck, 'invalid');
2263		return true;
2264	}
2265	if(!isValid) {
2266		window.Oby.addClass(elementToCheck, 'invalid');
2267		alert(hikashopFieldsJs['validFieldsComp'][type][i]);
2268		return false;
2269	} else {
2270		window.Oby.removeClass(elementToCheck, 'invalid');
2271	}
2272	return true;
2273}
2274
2275window.hikashop.ready(function(){
2276	if(window.jQuery && typeof(jQuery.noConflict) == "function" && !window.hkjQuery) {
2277		window.hkjQuery = jQuery.noConflict();
2278	}
2279	if(window.hikaVotes && typeof(initVote) == 'function')
2280		initVote();
2281	// timeout to make sure that everything is rendered before triggering the height calculations
2282	window.setTimeout(
2283		function(){
2284			window.hikashop.checkConsistency();
2285		},
2286		50
2287	);
2288});
2289if(window.jQuery && typeof(jQuery.noConflict) == "function" && !window.hkjQuery) {
2290	window.hkjQuery = jQuery.noConflict();
2291}

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.