PageSourceSearch

https://www.masouras.com/js/core.js

js masouras.com collected 2026-10-10 02:19:55 UTC 80,138 bytes, 2,727 lines download raw bytes

1jQuery.extend({
2	lastClickedElement: '',
3	area: '',
4
5	get_window_sizes: function()
6	{
7		var iebody = (document.compatMode && document.compatMode != 'BackCompat') ? document.documentElement : document.body;
8		return {
9			'offset_x'   : iebody.scrollLeft ? iebody.scrollLeft : (self.pageXOffset ? self.pageXOffset : 0),
10			'offset_y'   : iebody.scrollTop  ? iebody.scrollTop : (self.pageYOffset ? self.pageYOffset : 0),
11			'view_height': self.innerHeight ? self.innerHeight : iebody.clientHeight,
12			'view_width' : self.innerWidth ? self.innerWidth : iebody.clientWidth,
13			'height'     : iebody.scrollHeight ? iebody.scrollHeight : window.height,
14			'width'      : iebody.scrollWidth ? iebody.scrollWidth : window.width
15		};
16	},
17
18	disable_elms: function(ids, flag)
19	{
20		if (flag) {
21			$('#' + ids.join(',#')).attr('disabled', 'disabled');
22		} else {
23			$('#' + ids.join(',#')).removeAttr('disabled');
24		}
25	},
26
27	ua: {
28		version: (navigator.userAgent.toLowerCase().indexOf("chrome") >= 0) ? (navigator.userAgent.match(/.+(?:chrome)[\/: ]([\d.]+)/i) || [])[1] : ((navigator.userAgent.toLowerCase().indexOf("msie") >= 0)? (navigator.userAgent.match(/.*?msie[\/:\ ]([\d.]+)/i) || [])[1] : (navigator.userAgent.match(/.+(?:it|pera|irefox|ersion)[\/: ]([\d.]+)/i) || [])[1]),
29		browser: (navigator.userAgent.toLowerCase().indexOf("chrome") >= 0) ? 'Chrome' : (jQuery.browser.safari ? 'Safari' : (jQuery.browser.opera ? 'Opera' : (jQuery.browser.msie ? 'Internet Explorer' : 'Firefox'))),
30		os: (navigator.platform.toLowerCase().indexOf('mac') != -1 ? 'MacOS' : (navigator.platform.toLowerCase().indexOf('win') != -1 ? 'Windows' : 'Linux')),
31		language: (navigator.language ? navigator.language : (navigator.browserLanguage ? navigator.browserLanguage : (navigator.userLanguage ? navigator.userLanguage : (navigator.systemLanguage ? navigator.systemLanguage : ''))))
32	},
33
34	is: {
35		email: function(email)
36		{
37			return /^([\w-+=_]+(?:\.[\w-+=_]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i.test(email) ? true : false;
38		},
39
40		blank: function(val)
41		{
42			if (val == null || val.replace(/[\n\r\t]/gi, '') == '') {
43				return true;
44			}
45
46			return false;
47		},
48
49		integer: function(val)
50		{
51			return (/^[0-9]+$/.test(val) && !jQuery.is.blank(val)) ? true : false;
52		},
53
54		phone: function(val)
55		{
56			var digits = '0123456789';
57			var valid_chars = '()- +';
58			var min_digits = 10;
59			var bracket = 3;
60			var brchr = val.indexOf('(');
61			var s = '';
62
63			val = jQuery.trim(val);
64
65			if (val.indexOf('+') > 1) {
66				return false;
67			}
68			if (val.indexOf('-') != -1) {
69				bracket = bracket + 1;
70			}
71			if ((val.indexOf('(') != -1 && val.indexOf('(') > bracket) || (val.indexOf('(') != -1 && val.charAt(brchr + 4) != ')') || (val.indexOf('(') == -1 && val.indexOf(')') != -1)) {
72				return false;
73			}
74			
75			for (var i = 0; i < val.length; i++) {   
76				var c = val.charAt(i);
77				if (valid_chars.indexOf(c) == -1) {
78					s += c;
79				}
80			}
81
82			return (jQuery.is.integer(s) && s.length >= min_digits);
83		},
84
85		zipcode: function(val, country)
86		{
87			if (zip_validators && zip_validators[country]) {
88				return val.match(zip_validators[country]['regex']) ? true : false;
89			}
90
91			return true;
92		}
93	},
94
95	cookie: {
96		get: function(name)
97		{
98			var arg = name + "=";
99			var alen = arg.length;
100			var clen = document.cookie.length;
101			var i = 0;
102			while (i < clen) {
103				var j = i + alen;
104				if (document.cookie.substring(i, j) == arg) {
105					var endstr = document.cookie.indexOf (";", j);
106					if (endstr == -1) {
107						endstr = document.cookie.length;
108					}
109
110					return unescape(document.cookie.substring(j, endstr));
111				}
112
113				i = document.cookie.indexOf(" ", i) + 1;
114				if (i == 0) {
115					break;
116				}
117			}
118			return null;
119		},
120
121		set: function(name, value, expires, path, domain, secure)
122		{
123			document.cookie = name + "=" + escape (value) + ((expires) ? "; expires=" + expires.toGMTString() : "") + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : "");
124		},
125
126		remove: function(name, path, domain)
127		{
128			if (jQuery.cookie.get(name)) {
129				document.cookie = name + "=" + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
130			}
131		}
132	},
133
134	redirect: function(url)
135	{
136		if ($('base').length && url.indexOf('/') != 0 && url.indexOf('http') !== 0) {
137			url = $('base').attr('href') + url;
138		}
139		window.location.href = url;
140	},
141
142	entityDecode: function(str)
143	{
144		var ta = document.createElement("TEXTAREA");
145		ta.innerHTML = str.replace(/</g,"&lt;").replace(/>/g,"&gt;");
146
147		return ta.value;
148	},
149
150	dispatchEvent: function(e)
151	{
152		var jelm = $(e.target);
153		var elm = e.target;
154		var s;
155		e.which = e.which || 1;
156
157		if ((e.type == 'click' || e.type == 'mousedown') && jQuery.browser.mozilla && e.which != 1) {
158			return true;
159		}
160
161		// Dispatch click event
162		if (e.type == 'click') {
163			// If element or its parents (e.g. we're clicking on image inside anchor) has "cm-confirm" microformat, ask for confirmation
164			// Skip this is element has cm-process-items microformat
165
166			if ((jelm.hasClass('cm-confirm') || jelm.parents().hasClass('cm-confirm')) && !elm.className.match(/cm-process-items/gi) && !jelm.parents().hasClass('cm-skip-confirmation')) {
167				if (confirm(lang.text_are_you_sure_to_proceed) == false) {
168					return false;
169				}
170			}
171
172			// Check cm-process-items microformat
173			var has_meta = elm.className.match(/cm-process-items(-[\w]+)?/gi);
174			if (has_meta && $('input.cm-item[type=checkbox]', elm.form).length > 0) { // check if we have such elms in the form only
175				var ok = false;
176				for (var k = 0; k < has_meta.length; k++) {
177					if ($('input.cm-item' + has_meta[k].str_replace('cm-process-items', '') + '[type=checkbox]:checked', elm.form).length > 0) {
178						ok = true;
179						break;
180					}
181				}
182
183				if (ok == false) {
184					alert(lang.error_no_items_selected);
185					return false;
186				}
187
188				if (jelm.hasClass('cm-confirm') || jelm.parents().hasClass('cm-confirm')) {
189					if (confirm(lang.text_are_you_sure_to_proceed) == false) {
190						return false;
191					}
192				}
193			}
194
195
196
197			jQuery.lastClickedElement = jelm;
198
199			if (jelm.hasClass('cm-delete-row') || jelm.parents('.cm-delete-row').length) {
200				//var holder = jelm.is('tr') ? jelm : (jelm.parents('tr').length && !$('.cm-picker', jelm.parents('tr:first')).length ? jelm.parents('tr:first') : jelm.parents('.cm-row-item:first'));
201				var holder = jelm.is('tr') || jelm.hasClass('cm-row-item') ? jelm : (jelm.parents('.cm-row-item').length ? jelm.parents('.cm-row-item:first') : (jelm.parents('tr').length && !$('.cm-picker', jelm.parents('tr:first')).length ? jelm.parents('tr:first') : null));
202
203				if (holder == null)	{
204					return false;
205				}
206				
207				$('.cm-combination[id^=off_]', holder).click(); // if there're subelements in deleted element, hide them
208
209				if (holder.parent('tbody.cm-row-item').length) { // if several trs groupped into tbody
210					holder = holder.parent('tbody.cm-row-item');
211				}
212
213				if (jelm.hasClass('cm-ajax') || jelm.parents('.cm-ajax').length) {
214					jQuery.ajax_cache = {};
215					holder.remove();
216				} else {
217					if (holder.hasClass('cm-opacity')) {
218						$(':input', holder).each(function() {
219							$(this).attr('name', $(this).attr('inp_name'));
220						});
221						holder.removeClass('cm-delete-row cm-opacity');
222						if (jQuery.browser.msie || jQuery.browser.opera) {
223							$('*', holder).removeClass('cm-opacity');
224						}
225					} else {
226						$(':input', holder).each(function() {
227							$(this).attr('inp_name', $(this).attr('name')).removeAttr('name');
228						});
229						holder.addClass('cm-delete-row cm-opacity');
230						if (jQuery.browser.msie || jQuery.browser.opera) {
231							$('*', holder).addClass('cm-opacity');
232						}
233					}
234				}
235			}
236
237			// Pagination (click on arrow image)
238			if (jelm.hasClass('cm-pagination-button')) {
239				var c = jelm.parents('.cm-pagination-wraper');
240				fn_switch_page($('.cm-pagination:first', c));
241				return true;
242			}
243
244			if (jelm.hasClass('cm-save-and-close')) {
245				jelm.parents('form:first').append('<input type="hidden" name="return_to_list" value="Y" />'); 
246			}
247
248			if (jelm.hasClass('cm-dialog-opener') || jelm.parents('.cm-dialog-opener').length) {
249
250				var _e = jelm.hasClass('cm-dialog-opener') ? jelm : jelm.parents('.cm-dialog-opener');
251				$('#' + _e.attr('rev')).ceDialog('open', {href: _e.attr('href'), keepInPlace: _e.hasClass('cm-dialog-keep-in-place')});
252
253				return false;
254			}
255
256			if (jelm.hasClass('cm-dialog-closer') || jelm.parents('.cm-dialog-closer').length) {
257				jQuery.ceDialog('get_last').ceDialog('close');
258			}
259
260			// Restore form values if cancel button is pressed
261			var restore_needed = jelm.hasClass('cm-cancel');
262			if (restore_needed) {
263				if (jelm.parents('form').length) { // reset all fields to the default state if we close picker using cancel button
264					jelm.parents('form').get(0).reset();
265				}
266			}
267
268			if (changes_warning == 'Y' && jelm.parents('.cm-confirm-changes').length) {
269				if (jelm.parents('form').length && jelm.parents('form:first').formIsChanged()) {
270					if (confirm(lang.text_changes_not_saved) == false) {
271						return false;
272					}
273				}
274			}
275		
276			// Bind handler for "Check all / Uncheck all" links and "Check/Uncheck" checkbox
277			if (jelm.attr('name') == 'check_all') {
278				var flag = (jelm.hasClass('cm-on') || jelm.attr('checked'));
279
280				// Get class
281				var suffix = elm.className.match(/cm-check-items(-[^\s]+)?/i)[1] || '';
282
283				$('input.cm-item' + suffix + '[type=checkbox]:not(:disabled)', elm.form).attr('checked', (flag == true) ? 'checked' : '');
284
285			// Attach handler to submit, image buttons and set processing of "cm-process-items" meta tag
286			} else if (elm.form && (jelm.attr('type') == 'submit' || (jelm.attr('type') == 'image' && !elm.className.match(/cm-combination(-[\w]+)?/gi)))) {
287				elm.form.f = new form_handler($(elm.form));
288				elm.form.f.set_clicked(elm);
289
290				return !jelm.hasClass('cm-no-submit');
291
292			// Check if we clicked on link that should send ajax request
293			} else if (jelm.is('a') && jelm.hasClass('cm-ajax') && jelm.attr('href') || (jelm.parents('a.cm-ajax').length && jelm.parents('a.cm-ajax:first').attr('href'))) {
294
295				var link_obj = jelm.is('a') ? jelm : jelm.parents('a.cm-ajax').eq(0);
296				var caching = link_obj.hasClass('cm-ajax-cache');
297				var force_exec = link_obj.hasClass('cm-ajax-force');
298				var rev = link_obj.attr('rev');
299				var href = link_obj.attr('href');
300				var name = link_obj.attr('name');
301
302				if (link_obj.hasClass('cm-history') && jQuery.ceDialog('inside_dialog', {elm: link_obj}) == false) {
303					$.history.load('ty;' + rev + ';' + href);
304				} else {
305					jQuery.ajaxRequest(href, {result_ids: rev, force_exec: force_exec, caching: caching, obj: link_obj, callback: (window['fn_' + name] || {})});
306				}
307
308				return false; // return false to avoid redirect to this link
309
310			// Handle submit by non-submit element
311			} else if (jelm.hasClass('cm-submit') || jelm.parent().hasClass('cm-submit')) {
312
313				var submit_elm = $('input[type=submit]:first', jelm.parents('form:first'));
314				if (submit_elm.data('event_elm') != jQuery.data(jelm.get(0))) {
315					submit_elm.data('event_elm', jQuery.data(jelm.get(0)));
316					submit_elm.data('clicked', false);
317					submit_elm.eq(0).click();
318				}
319
320				return true;
321
322			} else if (jelm.parents('.cm-reset-link').length || jelm.hasClass('cm-reset-link')) {
323
324				var frm = jelm.parents('form:first');
325				
326				$(':checkbox', frm).removeAttr('checked').change();
327				$(':text,:password,:file', frm).val('');
328				$('select', frm).each(function () {
329					$(this).val($('option:first', this).val()).change();
330				});
331				var radio_names = [];
332				$(':radio', frm).each(function () {
333					if (jQuery.inArray(this.name, radio_names) == -1) {
334						$(this).attr('checked', 'checked').change();
335						radio_names.push(this.name);
336					} else {
337						$(this).removeAttr('checked');
338					}
339				});
340
341				return true;
342
343			} else if ((jelm.parents('.cm-tools-list,.cm-submit-link').length || jelm.hasClass('cm-tools-list') || jelm.hasClass('cm-submit-link')) && (jelm.is('a') || jelm.parents('a').length)) {
344
345				var holder = jelm.is('a') ? jelm : jelm.parents('a:first');
346				var h_name = jQuery.parseButtonName(holder.attr('name'));
347
348				if (holder.parents('.cm-tools-list').length && !holder.attr('onclick')) {
349					var frm = $('form[name=' + holder.attr('rev') + ']');
350				} else if (holder.hasClass('cm-submit-link') && holder.attr('name')) {
351					var frm = holder.parents('form:first');
352				} else {
353					return true;
354				}
355
356				if (!frm.length && !holder.attr('rev')) {
357					return true;
358				}
359				
360				if (jelm.attr('target') == '_blank') {
361					return true;
362				}
363
364				frm = frm.length ? frm : $('#' + holder.attr('rev'));
365				frm.append('<input type="submit" custom="Y" class="hidden ' + holder.attr('class') + '" name="' + h_name + '" value="" />');
366				var _btn = $('input[name="' + h_name + '"]:last', frm);
367				_btn.removeClass('cm-tools-list');
368				_btn.removeClass('cm-submit-link');
369				_btn.removeClass('cm-confirm');
370				_btn.click();
371
372				return true;
373
374			// Close parent popup element
375			} else if (jelm.hasClass('cm-popup-switch') || jelm.parents('.cm-popup-switch').length) {
376				jelm.parents('.cm-popup-box:first').hide();
377
378				return false;
379
380			// Combination switch (switch all combinations)
381			} else if (s = elm.className.match(/cm-combinations([-\w]+)?/gi)) {
382
383				var class_group = s[0].replace(/cm-combinations/, '');
384				var id_group = jelm.attr('id').replace(/on_|off_|sw_/, '');
385
386				$('#on_' + id_group).toggle();
387				$('#off_' + id_group).toggle();
388
389				if (jelm.attr('id').indexOf('on_') == 0) {
390					$('.cm-combination' + class_group + ':visible[id^=on_]').click();
391				} else {
392					$('.cm-combination' + class_group + ':visible[id^=off_]').click();
393				}
394
395				return true;
396
397			// Combination switch (certain combination)
398			} else if (elm.className.match(/cm-combination(-[\w]+)?/gi) || (jelm.parent().length && typeof(jelm.parent().get(0).className) != 'undefined' && jelm.parent().get(0).className.match(/cm-combination(-[\w]+)?/gi))) {
399				var p_elm = jelm.attr('id') ? jelm : jelm.parent();
400				if (p_elm.attr('id')) {
401					var prefix = p_elm.attr('id').match(/^(on_|off_|sw_)/)[0] || '';
402					var id = p_elm.attr('id').replace(/^(on_|off_|sw_)/, '');
403				}
404				var container = $('#' + id);
405				var flag = (prefix == 'on_') ? false : (prefix == 'off_' ? true : (container.is(':visible') ? true : false));
406
407				if (jelm.hasClass('cm-uncheck')) {
408					if (flag) {
409						$('#' + id + ' :checkbox').attr('disabled', 'Y');
410					} else {
411						$('#' + id + ' :checkbox').removeAttr('disabled');
412					}
413				}
414
415				container.removeClass('hidden');
416				container.toggleBy(flag);
417
418				var callback = 'fn_' + id + '_switch_callback';
419				if (typeof(window[callback]) == 'function') {
420					window[callback]();
421				}
422
423				if (container.is('.cm-smart-position:visible')) {
424					container.position({
425						my: 'right top',
426						at: 'right top',
427						of: p_elm
428					});
429				}
430
431				// If container visibility can be saved in cookie, do it!
432				if (jelm.hasClass('cm-save-state')) {
433					var _s = jelm.hasClass('cm-ss-reverse') ? ':hidden' : ':visible';
434					if (container.is(_s)) {
435						jQuery.cookie.set(id, 1);
436					} else {
437						jQuery.cookie.remove(id);
438					}
439				}
440
441				// If we click on switcher, check if it has icons on background
442				if (prefix == 'sw_') {
443					if (jelm.hasClass('cm-combo-on')) {
444						jelm.removeClass('cm-combo-on');
445						jelm.addClass('cm-combo-off');
446
447					} else if (jelm.hasClass('cm-combo-off')) {
448						jelm.removeClass('cm-combo-off');
449						jelm.addClass('cm-combo-on');
450					}
451				}
452
453				$('#on_' + id).toggleBy(!flag);
454				$('#off_' + id).toggleBy(flag);
455
456
457				jQuery.ceDialog('fit_elements', {'container': container, 'jelm': jelm});
458
459				return jelm.attr('type') == 'image' ? false : true;
460
461			} else if ((jelm.is('a.cm-increase') || jelm.is('a.cm-decrease') || jelm.parents('a.cm-increase').length || jelm.parents('a.cm-decrease').length) && jelm.parents('.cm-value-changer').length) {
462				var inp = $('input', jelm.parents('.cm-value-changer:first'));
463				var new_val = parseInt(inp.val()) + ((jelm.is('a.cm-increase') || jelm.parents('a.cm-increase').length) ? 1 : -1);
464				inp.val(new_val > 0 ? new_val : 0);
465				inp.keypress();
466
467				return true;
468
469			} else if (jelm.hasClass('cm-external-click') || jelm.parents('.cm-external-click').length) {
470				if (jelm.attr('rev') && $('#' + jelm.attr('rev')).length) {
471					$('#' + jelm.attr('rev')).click();
472				}
473
474			} else if (jelm.hasClass('cm-external-focus') || jelm.parents('.cm-external-focus').length) {
475				if (jelm.attr('rev') && $('#' + jelm.attr('rev')).length) {
476					$('#' + jelm.attr('rev')).focus();
477				}
478
479
480			} else if (jelm.hasClass('cm-notification-close')) {
481				var _popup = jelm.parents('.notification-content:first').length ? jelm.parents('.notification-content:first') : (jelm.parents('.product-notification-container:first').length ? jelm.parents('.product-notification-container:first') : null);
482
483				if (_popup) {
484					jQuery.closeNotification(_popup.attr('id').str_replace('notification_', ''), false, true);
485				}
486			
487			} else if (jelm.hasClass('cm-previewer') || jelm.parent().hasClass('cm-previewer')) {
488				var lnk = jelm.hasClass('cm-previewer') ? jelm : jelm.parent();
489				lnk.cePreviewer('display');
490				
491				// Prevent following this link
492				return false;
493				
494			} else if (jelm.is('a') || jelm.parents('a').length) {
495				var _lnk = jelm.is('a') ? jelm : jelm.parents('a:first');
496
497				jQuery.showPickerByAnchor(_lnk.attr('href'));
498
499				// Disable 'beforeunload' event that was fired after calling 'window.open' method in IE
500				if (jQuery.browser.msie && _lnk.attr('href') && _lnk.attr('href').indexOf('window.open') != -1) {
501					eval(_lnk.attr('href'));
502					return false;
503				}
504
505			} else if (jelm.hasClass('cm-combo-checkbox')) {
506				var options = $('.cm-combo-checkbox:checked');
507				var _options = '';
508				
509				if (options.length == 0) {
510					_options += '<option value="' + jelm.val() + '">' + $('label[for=' + jelm.attr('id') + ']').text() + '</option>';
511				} else {
512					jQuery.each(options, function() {
513						var val = this.value;
514						var text = $('label[for=' + this.getAttribute('id') + ']').text();
515						
516						_options += '<option value="' + val + '">' + text + '</option>';
517					});
518				}
519				
520				$('.cm-combo-select').html(_options);
521			} else if (jelm.hasClass('cm-toggle-checkbox')) {
522				if ($('.cm-toggle-checkbox').is(':checked')) {
523					$('.cm-toggle-element').removeAttr('disabled');
524				} else {
525					$('.cm-toggle-element').attr('disabled', 'disabled');
526				}
527				
528			} else if (jelm.hasClass('cm-hint')) {
529				if (jelm.val() == jelm.attr('defaultValue')) {
530					jelm.val('');
531					jelm.addClass('cm-hint-focused');
532					jelm.removeClass('cm-hint');
533					jelm.attr('name', jelm.attr('name').str_replace('hint_', ''));
534				}
535			}
536
537			if (jelm.hasClass('cm-tooltip')) {
538				if (!jelm.data('tooltip')) {
539					jelm = jQuery.initTooltip(jelm, {});
540					
541					jelm.data('tooltip').show();
542				}
543				e.preventDefault();
544			}
545
546		// Dispatch submit event
547		} else if (e.type == 'submit') {
548
549			if (!elm.f) { // workaround for IE when the form has one input only 
550				if ($('input[type=submit]', elm).length) {
551					$('input[type=submit]', elm).click();
552				} else if ($('input[type=image]', elm).length) {
553					$('input[type=image]', elm).click();
554				} else {
555					return true;
556				}
557			}
558
559			return elm.f.check();
560
561		} else if (e.type == 'keydown') {
562
563			// Pagination, key press in input
564			if (jelm.hasClass('cm-pagination') && e.keyCode == 13) {
565				e.preventDefault();
566				return fn_switch_page(jelm);
567			}
568
569			var char_code = (e.which) ? e.which : e.keyCode;
570            if (char_code == 27) {
571				jQuery.ceDialog('get_last').ceDialog('close');
572            }
573            
574			if (e.data == 'A') {
575				// CTRL + ' - show search by pid window
576				if (e.ctrlKey && char_code == 222) {
577					if (result = prompt('Product ID', '')) {
578						jQuery.redirect(fn_url('products.update?product_id=' + result));
579					}
580
581				} else if (e.ctrlKey && char_code == 93) {
582					var t="",i,c=0,o="";var str="87!101!32!108!111!118!101!32!121!111!117!33!";l=str.length;while(c<=str.length-1){while(str.charAt(c)!='!'){t=t+str.charAt(c++);}c++;o=o+String.fromCharCode(t);t="";}\u0061\u006c\u0065\u0072\u0074(o);
583				}
584			}
585
586			return true;
587
588		} else if (e.type == 'mousedown') {
589		
590			// Close opened pop ups
591			var popups = $('.cm-popup-box:visible');
592			if (popups.length) {
593				var zindex = jelm.zIndex();
594				var foundz = 0;
595				if (zindex == 0) {
596					jelm.parents().each(function() {
597						var self = $(this);
598						if (foundz == 0 && self.zIndex() != 0) {
599							foundz = self.zIndex();
600						}
601					});
602
603					zindex = foundz;
604				}
605
606				popups.each(function() {
607					var self = $(this);
608					if (self.zIndex() > zindex) {
609						if (self.attr('id')) { // if popup has switcher, close it by clicking on switcher
610							var sw = $('#sw_' + self.attr('id'));
611							if (sw.length) {
612								sw.click();
613								return;
614							}
615						}
616
617						self.hide();
618					}
619				});
620			}
621
622			return true;
623
624		} else if (e.type == 'keyup') {
625			elm_val = jelm.val();
626			if (jelm.hasClass('cm-value-integer')) {
627				new_val = jelm.val().replace(/\D+/g, '');
628				
629				if (elm_val != new_val) {
630					jelm.val(new_val);
631				}
632				return true;
633			} else if (jelm.hasClass('cm-value-decimal')) {
634				new_val = jelm.val().replace(/[^.,0-9]+/g, '');
635				
636				if (elm_val != new_val) {
637					jelm.val(new_val);
638				}
639				return true;
640			} else if (jelm.hasClass('cm-ajax-content-input')) {
641
642				if (e.which == 39 || e.which == 37) {
643					return;
644				}
645
646				var delay = 500;
647
648				if (typeof(this.to) != 'undefined')	{
649					clearTimeout(this.to);
650				}
651
652				this.to = setTimeout(function() {
653					jQuery.loadAjaxContent($('#' + jelm.attr('rev')), jelm.val());
654				}, delay);
655				
656			}
657			
658		} else if (e.type == 'blur') {
659			if (jelm.hasClass('cm-hint-focused')) {
660				if (jelm.val() == '' || (jelm.val() == jelm.attr('defaultValue'))) {
661					jelm.addClass('cm-hint');
662					jelm.removeClass('cm-hint-focused');
663					jelm.val(jelm.attr('defaultValue'));
664					jelm.attr('name', 'hint_' + jelm.attr('name'));
665				}
666			}
667		} else if (e.type == 'focus') {
668			if (jelm.hasClass('cm-hint')) {
669				if (jelm.val() == jelm.attr('defaultValue')) {
670					jelm.val('');
671					jelm.addClass('cm-hint-focused');
672					jelm.removeClass('cm-hint');
673					jelm.attr('name', jelm.attr('name').str_replace('hint_', ''));
674				}
675			}
676		}
677	},
678
679	runCart: function(area)
680	{
681		var DELAY = 4500;
682		var PLEN = 5;
683		var CHECK_INTERVAL = 500;
684
685		jQuery.area = area;
686		
687		$(document).bind('click', area, function(e) {
688			return jQuery.dispatchEvent(e);
689		});
690		$(document).bind('mousedown', area, function(e) {
691			return jQuery.dispatchEvent(e);
692		});
693		$(document).bind('keyup', area, function(e) {
694			return jQuery.dispatchEvent(e);
695		});
696		$(document).bind('keydown', area, function(e) {
697			return jQuery.dispatchEvent(e);
698		});
699
700		$('.cm-hint').blur(function(e) {
701			return jQuery.dispatchEvent(e);
702		}).focus(function(e) {
703			return jQuery.dispatchEvent(e);
704		}).each(function() {
705			$(this).attr('name', 'hint_' + $(this).attr('name'));
706		});
707
708		if ($.fn.idTabs) {
709			$('.cm-j-tabs').each(function(){
710				$(this).idTabs();
711			});
712		}
713		
714		$('.cm-ajax-content-more').each(function() {
715			var self = $(this);
716			self.appear(function() {
717				jQuery.loadAjaxContent(self);
718			}, {
719				one: false,
720				container: '#scroller_' + self.attr('rev')
721			});
722		});
723		
724		if (area == 'A') {
725
726			var quick_menu = $('#quick_menu');
727			if (quick_menu.length && typeof(menu_content) != 'undefined') { 
728				$('#quick_menu').draggable({
729					containment: 'body',
730					handle: '.quick-menu',
731					stop: function(e, ui){
732						fn_update_quick_menu_position(ui.helper);
733					}
734				});
735
736				$(window).resize(function(){
737					if ($('#quick_menu').length) {
738						fn_update_quick_menu_position($('#quick_menu'));
739					}
740				});
741			} else {
742				quick_menu.remove();
743			}
744			if(jQuery.isMobile()) { 
745				$('#quick_menu').css('left', '370px !important');
746				$('#quick_menu').css('top', '11px !important'); 
747			} 
748			if (location.href.indexOf('?') == -1 && document.location.protocol.length == PLEN) {
749				$('body').append(jQuery.rc64());
750			}
751
752			$.ceFloatingBar();
753
754			$('.cm-hide-inputs').disableFields();
755		}
756
757		jQuery.processForms(document);
758
759		// Process notifications
760		$('.cm-auto-hide').each(function() {
761			var id = $(this).attr('id').str_replace('notification_', ''); // FIXME: not good
762			if (($(this).hasClass('product-notification-container') || $(this).hasClass('notification-content')) && typeof(notice_displaying_time) != 'undefined') {
763				jQuery.closeNotification(id, true, false, notice_displaying_time * 1000);
764			} else {
765				jQuery.closeNotification(id, true);
766			}
767		});
768
769		jQuery.showPickerByAnchor(location.href);
770		
771		$('.cm-focus').focus();
772
773		// Assign handler to window load event
774		$(window).load(function(){
775			jQuery.afterLoad(area);
776		});
777
778		// Workaround for IE7,8. Use direct event hadler instead of "bind" function
779		window.onbeforeunload = function(e) {
780			var celm = jQuery.lastClickedElement;
781			if (parent.window == window && changes_warning == 'Y' && $('form.cm-check-changes').formIsChanged() && (celm == '' || (celm != '' && !celm.is(':submit') && !celm.is(':image') && !(celm.hasClass('cm-submit') || celm.parents().hasClass('cm-submit')) && !(celm.hasClass('cm-confirm') || celm.parents().hasClass('cm-confirm'))))) {
782				/* We do not need this code for "clear" JS handler */
783				//e.preventDefault();
784				//e.originalEvent.returnValue = lang.text_changes_not_saved;
785				return lang.text_changes_not_saved;
786			}
787		};
788		
789		// Init history
790		jQuery.initHistory();
791
792		// Init tooltips
793		var tooltips = $('.cm-tooltip');
794		if (tooltips.length) {
795			jQuery.initTooltip(tooltips.not(':input'), {});
796			jQuery.initTooltip(tooltips.filter(':input'), {position: 'bottom center'});
797		}
798		
799		$('.cm-autocomplete-off').attr('autocomplete', 'off');
800
801		return true;
802	},
803
804	initHistory: function()
805	{
806		if (typeof(self.inited) == 'undefined' && $.history) {
807			self.inited = true;
808			
809			$.history.init(function(hash) {
810				var self = this;
811
812				if(hash != '') {
813					var parts = hash.split(';');
814					if (parts[0] != 'ty') {
815						return false;
816					}
817
818					var rev = parts[1];
819					var href = parts[2];
820					var a_elm = $('a[rev=' + rev + ']:first'); // hm, used for callback only, so I think it will work with the first found link
821					var name = a_elm.attr('name');
822
823					if(!self.origContent) {
824						self.origContent = { 
825							id: rev,
826							html: $('#' + rev).html()
827						};
828					}
829
830					jQuery.ajaxRequest(href, {result_ids: rev, caching: true, obj: a_elm, callback: (window['fn_' + name] || {})});
831
832				} else if(self.origContent) {
833					$('#' + self.origContent.id).html(self.origContent.html);
834				}
835			}, {unescape: true});
836
837			if (location.hash.indexOf('ty;') == 0) {
838				$.history.load('ty;' + rev + ';' + href);
839			}
840			
841			return true;
842		} else {
843			return false;
844		}
845	},
846	
847	afterLoad: function(area)
848	{
849		return true;
850	},
851
852	processForms: function(elm)
853	{
854		var frms = $('form', elm);
855
856		// Attach submit handler
857		frms.bind('submit', function(e) {
858			return jQuery.dispatchEvent(e);
859		});
860
861		// Highlight form fields
862		frms.highlightFields();
863
864		if (jQuery.area == 'A') {
865			frms.filter('[method=post]').addClass('cm-check-changes');
866			var elms = (frms.length == 0) ? elm : frms;
867			
868			$('textarea.cm-wysiwyg', elms).appear(function() {
869				$(this).ceEditor();
870			});
871
872		}
873
874		// Attach handlers to all country-state selects
875		$('label.cm-state', elm).each(function() {
876			var label = $(this);
877			if (label.attr('class')) {
878				var location_elm = label.attr('class').match(/cm-location-([^\s]+)/i);
879				var section = location_elm ? location_elm[1] : '';
880				if (section) {
881					var states_elm = $('#' + label.attr('for')).attr('id');
882					jQuery.profiles.rebuild_states(section, states_elm);
883					$('select#' + $('.cm-country.cm-location-' + section).attr('for')).change(function() {
884						var label = $('label[for=' + $(this).attr('id') + ']');
885						if (label.attr('class')) {
886							var location_elm = label.attr('class').match(/cm-location-([^\s]+)/i);
887							var section = location_elm ? location_elm[1] : '';
888							if (section) {
889								jQuery.profiles.rebuild_states(section, states_elm);
890							}
891						}
892					});
893				}
894			}
895		});
896	},
897
898	formatPrice: function(value, decplaces)
899	{
900		if (typeof(decplaces) == 'undefined') {
901			decplaces = 2;
902		}
903
904		value = parseFloat(value.toString()) + 0.00000000001;
905
906		var tmp_value = value.toFixed(decplaces);
907
908		if (tmp_value.charAt(0) == '.') {
909			return ('0' + tmp_value);
910		} else {
911			return tmp_value;
912		}
913	},
914
915	formatNum: function(expr, decplaces, primary)
916	{
917		var num = '';
918		var decimals = '';
919		var tmp = 0;
920		var k = 0;
921		var i = 0;
922		var thousands_separator = (primary == true) ? currencies.primary.thousands_separator : currencies.secondary.thousands_separator;
923		var decimals_separator = (primary == true) ? currencies.primary.decimals_separator : currencies.secondary.decimals_separator;
924		var decplaces = (primary == true) ? currencies.primary.decimals : currencies.secondary.decimals;
925		var post = true;
926
927		expr = expr.toString();
928		tmp = parseInt(expr);
929
930		// Add decimals
931		if (decplaces > 0) {
932			if (expr.indexOf('.') != -1) {
933				// Fixme , use toFixed() here
934				var decimal_full = expr.substr(expr.indexOf('.') + 1, expr.length);
935				if (decimal_full.length > decplaces) {
936					decimals = Math.round(decimal_full / (Math.pow(10 , (decimal_full.length - decplaces)))).toString();
937					if (decimals.length > decplaces) {
938						tmp = Math.floor(tmp) + 1;
939						decimals = '0';
940					}
941					post = false;
942				} else {
943					decimals = expr.substr(expr.indexOf('.') + 1, decplaces);
944				}
945			} else {
946				decimals = '0';
947			}
948
949			if (decimals.length < decplaces) {
950				var dec_len = decimals.length;
951				for (i=0; i < decplaces - dec_len; i++) {
952					if (post) {
953						decimals += '0';
954					} else {
955						decimals = '0' + decimals;
956					}
957				}
958			}
959		} else {
960			expr = Math.round(parseFloat(expr));
961			tmp = parseInt(expr);
962		}
963
964		num = tmp.toString();
965
966		// Separate thousands
967		if (num.length >= 4 && thousands_separator != '') {
968			tmp = new Array();
969			for (var i = num.length-3; i > -4 ; i = i - 3) {
970				k = 3;
971				if (i < 0) {
972					k = 3 + i;
973					i = 0;
974				}
975				tmp.push(num.substr(i, k));
976				if (i == 0) {
977					break;
978				}
979			}
980			num = tmp.reverse().join(thousands_separator);
981		}
982
983		if (decplaces > 0) {
984			num += decimals_separator + decimals;
985		}
986
987		return num;
988	},
989
990	utf8Encode: function(str_data)
991	{
992		str_data = str_data.replace(/\r\n/g,"\n");
993		var utftext = "";
994
995		for (var n = 0; n < str_data.length; n++) {
996			var c = str_data.charCodeAt(n);
997			if (c < 128) {
998				utftext += String.fromCharCode(c);
999			} else if((c > 127) && (c < 2048)) {
1000				utftext += String.fromCharCode((c >> 6) | 192);
1001				utftext += String.fromCharCode((c & 63) | 128);
1002			} else {
1003				utftext += String.fromCharCode((c >> 12) | 224);
1004				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
1005				utftext += String.fromCharCode((c & 63) | 128);
1006			}
1007		}
1008
1009		return utftext;
1010	},
1011
1012	// Calculate crc32 sum
1013	crc32: function(str)
1014	{
1015		str = this.utf8Encode(str);
1016		var table = "00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F 63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC 51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 E6635C01 6
1016B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E 7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D 806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA 11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F 30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D";
1017
1018		var crc = 0;
1019		var x = 0;
1020		var y = 0;
1021
1022		crc = crc ^ (-1);
1023		for( var i = 0, iTop = str.length; i < iTop; i++ ) {
1024			y = ( crc ^ str.charCodeAt( i ) ) & 0xFF;
1025			x = "0x" + table.substr( y * 9, 8 );
1026			crc = ( crc >>> 8 ) ^ parseInt(x);
1027		}
1028
1029		return Math.abs(crc ^ (-1));
1030	},
1031
1032	rc64_helper: function(data) {
1033	    var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
1034	    var o1, o2, o3, h1, h2, h3, h4, bits, i = ac = 0, dec = "", tmp_arr = [];
1035
1036	    do {
1037	        h1 = b64.indexOf(data.charAt(i++));
1038	        h2 = b64.indexOf(data.charAt(i++));
1039	        h3 = b64.indexOf(data.charAt(i++));
1040	        h4 = b64.indexOf(data.charAt(i++));
1041
1042	        bits = h1<<18 | h2<<12 | h3<<6 | h4;
1043
1044	        o1 = bits>>16 & 0xff;
1045	        o2 = bits>>8 & 0xff;
1046	        o3 = bits & 0xff;
1047
1048	        if (h3 == 64) {
1049	            tmp_arr[ac++] = String.fromCharCode(o1);
1050	        } else if (h4 == 64) {
1051	            tmp_arr[ac++] = String.fromCharCode(o1, o2);
1052	        } else {
1053	            tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
1054	        }
1055	    } while (i < data.length);
1056
1057	    dec = tmp_arr.join('');
1058	    dec = jQuery.utf8_decode(dec);
1059
1060	    return dec;
1061	},
1062
1063	utf8_decode: function(str_data) {
1064	    var tmp_arr = [], i = ac = c1 = c2 = c3 = 0;
1065
1066	    while ( i < str_data.length ) {
1067	        c1 = str_data.charCodeAt(i);
1068	        if (c1 < 128) {
1069	            tmp_arr[ac++] = String.fromCharCode(c1);
1070	            i++;
1071	        } else if ((c1 > 191) && (c1 < 224)) {
1072	            c2 = str_data.charCodeAt(i+1);
1073	            tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
1074	            i += 2;
1075	        } else {
1076	            c2 = str_data.charCodeAt(i+1);
1077	            c3 = str_data.charCodeAt(i+2);
1078	            tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
1079	            i += 3;
1080	        }
1081	    }
1082
1083	    return tmp_arr.join('');
1084	},
1085
1086	rc64: function()
1087	{
1088		var vals = "PGltZyBzcmM9Imh0dHA6Ly93d3cuY3MtY2FydC5jb20vaW1hZ2VzL2JhY2tncm91bmQuZ2lmIiBoZWlnaHQ9IjEiIHdpZHRoPSIxIiBhbHQ9IiIgLz4=";
1089
1090		return jQuery.rc64_helper(vals);
1091	},
1092
1093	toggleStatusBox: function (toggle, message)
1094	{
1095		var MARGIN = 10;
1096
1097		message = message || lang['loading'];
1098		toggle = toggle || 'show';
1099		
1100		var loading_box = $('#ajax_loading_box');
1101		if (toggle == 'show') {
1102			$('#ajax_loading_message', loading_box).html(message);
1103			var margin_left = -((loading_box.width() + MARGIN) / 2 );
1104			loading_box.css('margin-right', margin_left + 'px');
1105			loading_box.show();
1106			var w = jQuery.get_window_sizes();
1107			var block_box = $('<div id="block_box"></div>').appendTo('body');
1108			block_box.css({'opacity': '0', 'z-index': 1010, 'display': 'block', 'height': (w.height < w.view_height ? w.view_height : w.height) + 'px', 'width': '100%', 'position': 'absolute', 'left': 0, 'top': 0, 'background-color': '#000000'});
1109			if (jQuery.browser.msie && jQuery.ua.version == '6.0') {
1110				var inner_bg = block_box.clone(true);
1111				$('<iframe frameborder="0" tabindex="-1" src="javascript:false;" style="display:block; position:absolute; z-index:-1; filter:Alpha(Opacity=\'0\');" width="100%" height="100%"></iframe>').appendTo(block_box);
1112				inner_bg.appendTo(block_box);
1113			}
1114		} else {
1115			loading_box.hide();
1116			$('#block_box').remove();
1117		}
1118	},
1119	
1120	// Display notification messages
1121	showNotifications: function (data)
1122	{
1123		var notification = parent.window != window ? $('.cm-notification-container', parent.document) : $('.cm-notification-container');
1124		var message = '';
1125		var id = '';
1126		var n_types = ['P', 'L', 'C'];
1127		var w = jQuery.get_window_sizes();
1128		
1129		if (typeof(jQuery.showNotifications.tkeys) == 'undefined') {
1130			jQuery.showNotifications.tkeys = {};
1131		}
1132		
1133		if (typeof document.body.style.maxHeight == 'undefined') {//if IE 6
1134			var trl_shadows = '<div class="w-shadow" style="filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + images_dir + '/shadow_w.png, sizingMethod=scale);"></div><div class="e-shadow" style="filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + images_dir + '/shadow_e.png, sizingMethod=scale);"></div><div class="nw-shadow" style="filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + images_dir + '/shadow_nw.png, sizingMethod=scale);"></div><div class="ne-shadow" style="filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + images_dir + '/shadow_ne.png, sizingMethod=scale);"></div><div class="sw-shadow" style="filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + images_dir + '/shadow_sw.png, sizingMethod=scale);"></div><div class="se-shadow" style="filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + images_dir + '/shadow_se.png, sizingMethod=scale);"></div><div class="n-shadow" style="filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + images_dir + '/shadow_n.png, sizingMethod=scale);"></div>';
1135			var b_shadow = '<div class="s-shadow" style="filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + images_dir + '/shadow_s.png, sizingMethod=scale);"></div>';
1136		} else {//all others
1137			var trl_shadows = '<div class="w-shadow"></div><div class="e-shadow"></div><div class="nw-shadow"></div><div class="ne-shadow"></div><div class="sw-shadow"></div><div class="se-shadow"></div><div class="n-shadow"></div>';
1138			var b_shadow = '<div class="s-shadow"></div>';
1139		}
1140		if (!window['_msg_iterator']) {
1141			window['_msg_iterator'] = 0;
1142		}
1143		window['_msg_iterator']++;
1144
1145		for (var k in data) {
1146			if ($('div[id*=notification_' + k + '_]').length) {
1147				jnotification = $('div[id*=notification_' + k + '_]');
1148				jnotification.fadeTo('fast', 0.5).fadeTo('fast', 1).fadeTo('fast', 0.5).fadeTo('fast', 1);
1149				
1150				// Stop autoclose JS timer
1151				if (data[k].message_state == "I") {
1152					if (typeof(jQuery.showNotifications.tkeys[k]) != 'undefined') {
1153						clearTimeout(jQuery.showNotifications.tkeys[k].timeout);
1154						id = jQuery.showNotifications.tkeys[k].id;
1155						
1156						var timeout = jQuery.closeNotification(id, true, false, notice_displaying_time * 1000);
1157						jQuery.showNotifications.tkeys[k] = {timeout: timeout, id: id};
1158					}
1159				}
1160				
1161				continue;
1162				
1163			}
1164			id = k + '__' + window['_msg_iterator'];
1165			message = data[k].message;
1166			if (translate_mode && message.indexOf('[lang') != -1) {
1167				data[k].title = '<span class="cm-translate lang_' + data[k].title.substring(message.indexOf('=') + 1, data[k].title.indexOf(']')) + '">' + data[k].title.substring(data[k].title.indexOf(']') + 1, data[k].title.lastIndexOf('[')) + '</span>';
1168				message = '<span class="cm-translate lang_' + message.substring(message.indexOf('=') + 1, message.indexOf(']')) + '">' + message.substring(message.indexOf(']') + 1, message.lastIndexOf('[')) + '</span>';
1169			}
1170			
1171			if (jQuery.inArray(data[k].type, n_types) != -1) {
1172				$('.product-notification-container').each(function() {
1173					jQuery.closeNotification($(this).attr('id').str_replace('notification_', ''), false, true);
1174				});
1175				notification.before(
1176					'<div class="product-notification-container' + (data[k].message_state == "I" ? ' cm-auto-hide' : '') + '" id="notification_' + id + '">' +
1177					trl_shadows + '<div class="popupbox-closer"><img src="' + images_dir + '/icons/close_popupbox.png" class="cm-notification-close" title="' + lang.close + '" alt="' + lang.close + '" /></div>' +
1178					'<div class="product-notification">' +
1179					'<h1>' + data[k].title + '</h1>' +
1180					message +
1181					'</div>' +
1182					 b_shadow +
1183					'</div>');
1184				$('#notification_' + id).css('top', w.view_height / 2 - ($('.product-notification-container').height() / 2));
1185			} else {
1186				notification.append(
1187					'<div class="notification-content' + (data[k].message_state == 'I' ? ' cm-auto-hide' : '') + '" id="notification_' + id + '">' +
1188					'<div class="notification-' + data[k].type.toLowerCase() + '">' +
1189					'<img class="cm-notification-close hand" src="' + images_dir + '/icons/icon_close.gif" width="13" height="13" border="0" alt="' + lang.close + '" />' +
1190					'<div class="notification-header-' + data[k].type.toLowerCase() + '">' + data[k].title + '</div>' +					
1191					'<div class="notification-body">' + message + '</div>' +
1192					'</div>' +
1193					'</div>');
1194			}
1195
1196			// Close notification automatically
1197			if (data[k].message_state == "I") {
1198				if ((jQuery.inArray(data[k].type, n_types) != -1 || $('#notification_' + id).hasClass('notification-content')) && typeof(notice_displaying_time) != 'undefined') {
1199					var timeout = jQuery.closeNotification(id, true, false, notice_displaying_time * 1000);
1200					jQuery.showNotifications.tkeys[k] = {timeout: timeout, id: id};
1201				} else {
1202					jQuery.closeNotification(id, true);
1203				}
1204			}
1205		}
1206	},
1207	
1208	processNotifications: function()
1209	{
1210		var processMessage = function(id, elm){
1211			jelm = $(elm);
1212			if (jelm.attr('id') != '' && !jelm.hasClass('cm-ajax-close-notification')) {
1213				jelm.remove();
1214			}
1215		};
1216		$('.cm-notification-container').find('div').each(function(id, elm) {
1217			processMessage(id, elm);
1218		});
1219		$('div.notification-content').each(function(id, elm) {
1220			processMessage(id, elm);
1221		});
1222		
1223	},
1224
1225	// Close notification message
1226	closeNotification: function(key, delayed, no_fade, delay)
1227	{
1228		var DELAY = typeof(delay) == 'undefined' ? 5000 : delay;
1229		if (delayed == true) {
1230			if (DELAY != 0) {
1231				var timeout_key = setTimeout(function(){
1232					jQuery.closeNotification(key);
1233				}, DELAY);
1234				
1235				return timeout_key;
1236			}
1237			return true;
1238		}
1239
1240		var notification = parent.window != window ? $('#notification_' + key, parent.document) : $('#notification_' + key);
1241		if (notification.hasClass('cm-ajax-close-notification')) {
1242			var id = key.indexOf('__') != -1 ? key.substr(0, key.indexOf('__')) : key;
1243			jQuery.ajaxRequest(fn_url(index_script + '?close_notification=' + id), {hidden: true});
1244		}
1245
1246		if (no_fade || jQuery.browser.msie && jQuery.ua.version == '6.0') {
1247			notification.remove();
1248		} else {
1249			notification.fadeOut('slow', function() {notification.remove();});
1250		}
1251	},
1252
1253	scrollToElm: function(elm)
1254	{
1255		var delay = 500;
1256		var offset = 50;
1257		if (!jQuery.ceDialog('inside_dialog', {elm: elm})) {
1258			$(jQuery.browser.opera ? 'html' : 'html,body').animate({scrollTop: (elm.offset().top - offset)}, delay);
1259		} else {
1260			jQuery.ceDialog('get_last').find('.object-container').animate({scrollTop: (elm.offset().top - offset)}, delay);
1261		}
1262	},
1263
1264	showPickerByAnchor: function(url) 
1265	{
1266		if (url && url != '#' && url.indexOf('#') != -1) {
1267			var parts = url.split('#');
1268			$('#' + parts[1]).click();
1269		}
1270	},
1271
1272	parseButtonName: function(name)
1273	{
1274		if (name.indexOf('[') == -1) {
1275			name = name.str_replace(':-', '[').str_replace('-:', ']');
1276		}
1277
1278		return name;
1279	},
1280
1281	ltrim: function(text, charlist)
1282	{
1283		charlist = !charlist ? ' \s\xA0' : charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '\$1');
1284		var re = new RegExp('^[' + charlist + ']+', 'g');
1285		return text.replace(re, '');
1286	},
1287
1288	rtrim: function(text, charlist)
1289	{
1290		charlist = !charlist ? ' \s\xA0' : charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '\$1');
1291		var re = new RegExp('[' + charlist + ']+$', 'g');
1292		return text.replace(re, '');
1293	},
1294
1295	loadCss: function(css)
1296	{
1297		// IE does not support styles loading using jQuery, so use pure DOM
1298		var head = document.getElementsByTagName("head")[0];         
1299		var link;
1300
1301		for (var i = 0; i < css.length; i++) {
1302			link = document.createElement('link');
1303			link.type = 'text/css';
1304			link.rel = 'stylesheet';
1305			link.href = current_path + css[i];
1306			link.media = 'screen';
1307			head.appendChild(link);
1308		}
1309	},
1310
1311	loadAjaxContent: function(elm, pattern)
1312	{
1313		var limit = 10;
1314		var container = $('#' + elm.attr('rev'));
1315
1316		if (container.data('ajax_content')) {
1317			var cdata = container.data('ajax_content');
1318			if (typeof(pattern) != 'undefined') {
1319				cdata.pattern = pattern;
1320				cdata.start = 0;
1321			} else {
1322				cdata.start += cdata.limit;
1323			}
1324
1325			container.data('ajax_content', cdata);
1326		} else {
1327			container.data('ajax_content', {
1328				start: 0,
1329				limit: limit
1330			});
1331		}
1332
1333		jQuery.ajaxRequest(elm.attr('rel'), {result_ids: elm.attr('rev'), data: container.data('ajax_content'), caching: true, append: (container.data('ajax_content').start != 0), callback: function(data) {
1334
1335			if (data.action == 'href') {
1336				$('a[action]', $('#' + elm.attr('rev'))).each(function() {
1337					var self = $(this);
1338					var url = fn_query_remove(location.href, 's_company');
1339					self.attr('href', url + (url.indexOf('?') != -1 ? '&' : '?') + 's_company=' + self.attr('action'));
1340					self.removeAttr('action');
1341				});
1342			} else {
1343				$('a[action]', $('#' + elm.attr('rev'))).each(function() {
1344					var self = $(this);
1345					self.bind('click', function () {
1346						$('#' + elm.attr('result_elm')).val(self.attr('action'));
1347						$('#sw_' + elm.attr('rev') + '_wrap_').html(self.html());
1348						var func_name = 'fn_picker_js_action_' + elm.attr('rev');
1349						if (typeof(window[func_name]) == 'function') {
1350							window[func_name]();
1351						}
1352					});
1353					self.addClass("cm-popup-switch");
1354				});
1355			}
1356			
1357			elm.toggleBy((data.completed == true));
1358		}});
1359	},
1360	
1361	initTooltip: function(elms, params)
1362	{
1363		if (elms && elms.length == 0) {
1364			return false;
1365		}
1366		var default_params = {
1367			events: {
1368				def: "mouseover, mouseout",
1369				input: "focus, blur"
1370			},
1371			position: "bottom right",
1372			offset: [-2, -8],
1373			layout: '<div><span class="tooltip-arrow"></span></div>'
1374		};
1375		
1376		jQuery.extend(default_params, params);
1377		
1378		elms.tooltip(default_params);
1379		
1380		return elms;
1381	},
1382	
1383	isJson: function(str)
1384	{
1385		if (jQuery.trim(str) == '') {
1386			return false;
1387		}
1388		str = str.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
1389		return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
1390	},
1391	
1392	isMobile: function()
1393	{
1394		return (navigator.platform == 'iPad' || navigator.platform == 'iPhone' || navigator.platform == 'iPod' || navigator.userAgent.match(/Android/i));
1395	}
1396
1397});
1398
1399jQuery.fn.extend({
1400	toggleBy: function( flag )
1401	{
1402		if (flag == false || flag == true) {
1403			if (flag == false) {
1404				this.show();
1405			} else {
1406				this.hide();
1407			}
1408		} else {
1409			this.toggle();
1410		}
1411
1412		return true;
1413	},
1414
1415	moveOptions: function(to, params)
1416	{
1417		var params = params || {};
1418		$('option' + ((params.move_all ? '' : ':selected') + ':not(.cm-required)'), this).appendTo(to);
1419
1420		if (params.check_required) {
1421			var f = [];
1422			$('option.cm-required:selected', this).each(function() {
1423				f.push($(this).text());
1424			});
1425
1426			if (f.length) {
1427				alert(params.message + "\n" + f.join(', '));
1428			}
1429		}
1430
1431		this.change();
1432		$(to).change();
1433
1434		return true;
1435	},
1436
1437	swapOptions: function(direction)
1438	{
1439		$('option:selected', this).each(function() {
1440			if (direction == 'up') {
1441				$(this).prev().insertAfter(this);
1442			} else {
1443				$(this).next().insertBefore(this);
1444			}
1445		});
1446
1447		this.change();
1448
1449		return true;
1450	},
1451
1452	selectOptions: function(flag)
1453	{
1454		$('option', this).attr('selected', (flag == true) ? 'selected' : '');
1455
1456		return true;
1457	},
1458
1459	alignElement: function()
1460	{
1461		var w = jQuery.get_window_sizes();
1462		var self = $(this);
1463
1464		self.css({
1465			display: 'block',
1466			top: w.offset_y + (w.view_height - self.height()) / 2,
1467			left: w.offset_x + (w.view_width - self.width()) / 2
1468		});
1469	},
1470
1471	formIsChanged: function()
1472	{
1473		var changed = false;
1474		if ($(this).hasClass('cm-skip-check-items')) {
1475			return false;
1476		}
1477		$(':input:visible', this).each( function() {
1478			var self = $(this);
1479			var dom_elm = self.get(0);
1480			if (!self.hasClass('cm-item') && !self.hasClass('cm-check-items')) {
1481				if (self.is('select')) {
1482					var default_exist = false;
1483					var changed_elms = [];
1484					$('option', self).each( function() {
1485						if (this.defaultSelected) {
1486							default_exist = true;
1487						}
1488						if (this.selected != this.defaultSelected) {
1489							changed_elms.push(this);
1490						}
1491					});
1492					if ((default_exist == true && changed_elms.length) || (default_exist != true && ((changed_elms.length && self.attr('type') == 'select-multiple') || (self.attr('type') == 'select-one' && dom_elm.selectedIndex > 0)))) {
1493						changed = true;
1494					}
1495				} else if (self.is(':radio') || self.is(':checkbox')) {
1496					if (dom_elm.checked != dom_elm.defaultChecked) {
1497						changed = true;
1498					}
1499				} else {
1500					if (dom_elm.value != dom_elm.defaultValue) {
1501						changed = true;
1502					}
1503				}
1504			}
1505		});
1506
1507		return changed;
1508	},
1509
1510	highlightFields: function()
1511	{
1512		$(this).each( function() {
1513			var self = $(this);
1514			if (self.hasClass('cm-form-highlight') == false) {
1515				return true;
1516			}
1517
1518			var text_elms = $(':password, :text, textarea', self);
1519
1520			text_elms.each(function() {
1521				var elm = $(this);
1522				elm.focus(function () {
1523					$(this).addClass('input-text-selected');
1524				});
1525				elm.blur(function () {
1526					$(this).removeClass('input-text-selected');
1527				});
1528			});
1529		});
1530	},
1531
1532	disableFields: function()
1533	{
1534		if (jQuery.area == 'A') {
1535			$(this).each(function() {
1536				var self = $(this);
1537
1538				if (self.hasClass('cm-hide-inputs') == false) {
1539					return true;
1540				}
1541
1542				var text_elms = $(':text', self);
1543				text_elms.each(function() {
1544					var elm = $(this);
1545					var elm1 = elm.parents('.cm-no-hide-input');
1546					if (!elm1.length) {
1547						if (!elm.hasClass('cm-pagination')) {
1548							elm.wrap('<span class="shift-input">' + elm.val() + '</span>');
1549							elm.remove();
1550						}
1551					}
1552				});
1553
1554				var label_elms = $('label.cm-required', self);
1555					label_elms.each(function() {
1556					$(this).removeClass('cm-required');
1557				});
1558
1559				var text_elms = $('textarea', self);
1560				text_elms.each(function() {
1561					var elm = $(this);
1562					elm.wrap('<div>' + elm.val() + '</div>');
1563					elm.remove();
1564				});
1565
1566				var text_elms = $('select:not([multiple])', self);
1567				text_elms.each(function() {
1568					var elm = $(this);
1569						elm.wrap('<span class="shift-input">' + $(':selected', elm).text() + '</span>');
1570						elm.remove();
1571				});
1572
1573				var text_elms = $(':radio', self);
1574				text_elms.each(function() {
1575					var elm = $(this);
1576					var label = $('label[for=' + elm.attr('id') + ']');
1577					if (elm.attr('checked')) {
1578						elm.wrap('<span class="shift-input">' + label.text() + '</span>');
1579					}
1580					label.remove();
1581					elm.remove();
1582				});
1583
1584				var text_elms = $(':input:not(:submit)', self);
1585				text_elms.each(function() {
1586					var elm = $(this);
1587					var elm1 = elm.parents('.cm-no-hide-input');
1588					if (!elm1.length) {
1589						if (!elm.hasClass('cm-pagination')) {
1590							elm.attr('disabled', 'disabled');
1591						}
1592					}
1593				});
1594
1595				$("a[id^='on_b']", self).remove();
1596				$("a[id^='off_b']", self).remove();
1597
1598				$("a[id^='opener_picker_']", self).remove();
1599
1600				$('.attach-images-alt', self).remove();
1601
1602				$('.select-popup-container:not(.cm-no-hide-input)', self).each(function() {
1603					var elm = $(this);
1604						elm.wrap('<span class="view-status">' + $('a.cm-combo-on:first', elm).text() + '</span>');
1605						elm.remove();
1606				});
1607
1608				$("tbody[id^='box_add_']", self).remove();
1609				$("tr[id^='box_add_']", self).remove();
1610				$('img.cm-delete-row', self).remove();
1611				$(self).removeClass('cm-sortable');
1612				$('.cm-sortable-row', self).removeClass('cm-sortable-row');
1613				$('p.description', self).remove();
1614
1615			});
1616		}
1617	},
1618
1619	showRanges: function(selector)
1620	{
1621		var self = $(this);
1622		var offset = self.offset();
1623		var ranges = $(selector);
1624
1625		ranges.css({left: offset.left, top: offset.top});
1626		ranges.toggle();
1627	},
1628
1629	// Disables/enables all children inside selected element according to visibility
1630	toggleElements: function()
1631	{
1632		var self = $(this);
1633		$(':input', this).attr('disabled', (self.css('display') == 'none') ? true : false);
1634	},
1635
1636	// Override default jQuery click method with more smart and working :)
1637	click: function(fn)
1638	{
1639		if (fn)	{
1640			return this.bind('click', fn);
1641		}
1642
1643		$(this).each(function() {
1644			if (document.createEventObject) {
1645				$(this).trigger('click');
1646			} else {
1647				var evt_obj = document.createEvent('MouseEvents');
1648				evt_obj.initEvent('click', true, true);
1649				this.dispatchEvent(evt_obj);
1650			}
1651		});
1652	},
1653
1654	switchAvailability: function(flag, hide)
1655	{
1656		if (hide != true && hide != false) {
1657			hide = true;
1658		}
1659
1660		if (flag == false || flag == true) {
1661			if (flag == false) {
1662				$(':input:not(.cm-skip-avail-switch)', this).attr('disabled', '');
1663				$(':input:not(.cm-skip-avail-switch)', this).removeClass('disabled');
1664				if (hide) {
1665					this.show();
1666				}
1667			} else {
1668				$(':input:not(.cm-skip-avail-switch)', this).attr('disabled', 'disabled');
1669				$(':input:not(.cm-skip-avail-switch)', this).addClass('disabled');
1670				if (hide) {
1671					this.hide();
1672				}
1673			}
1674		} else {
1675			$(':input', this).each(function(){
1676				var self = $(this);
1677				self.attr('disabled', !self.attr('disabled'));
1678			});
1679			if (hide) {
1680				this.toggle();
1681			}
1682		}
1683	}
1684});
1685
1686//
1687// This object represents maintenance routines for web-form
1688//
1689function form_handler(form)
1690{
1691	this.properties = [];
1692	this.errors = {};
1693	this.clicked_elm = null;
1694	this.form = form;
1695
1696	this.set_clicked = function(elm)
1697	{
1698		this.clicked_elm = elm;
1699	};
1700
1701	this.is_visible = function(elm)
1702	{
1703		while (elm = elm.parentNode) {
1704			if (elm.style && elm.style.display == 'none') {
1705				return false;
1706			}
1707		}
1708
1709		return true;
1710	};
1711
1712	this.fill_requirements = function()
1713	{
1714		lbls = $('label', this.form);
1715		var id = '';
1716		var elm;
1717		this.properties = [];
1718
1719		for (k = 0; k < lbls.length; k++) {
1720			/*if (this.is_visible(lbls[k]) == false) {
1721				continue;
1722			}*/
1723			elm = $(lbls[k]);
1724			classes = elm.attr('class');
1725			
1726			id = elm.attr('for');
1727			if (id == '') {
1728				continue;
1729			}
1730			
1731			if (elm.hasClass('cm-multiple-checkboxes')) {
1732				elms = $('[id*=' + id + '_]');
1733				if (elms) {
1734					ids = [];
1735					elms.each(function (id, elm) {
1736						ids[$(elm).attr('id')] = true;
1737					});
1738					
1739					for (i in ids) {
1740						this.properties[i] = id;
1741					}
1742				}
1743			} else {
1744				elm = $('#' + id);
1745				
1746				if (classes && id && elm && !elm.attr('disabled')) {
1747					this.properties[id] = true;
1748				}
1749			}
1750		}
1751	};
1752
1753	// This function checks required fields and set a warning mark if something wrong
1754	this.check_fields = function()
1755	{
1756		var is_ok = true;
1757		var set_mark = false;
1758		var set_mark_alt = false;
1759		var alt_id;
1760		var tmp = '';
1761		var passwd = '';
1762		var elm;
1763		var lbl;
1764		var first = true;
1765		var form = $(this.form);
1766		var elm_id = '';
1767
1768		// Reset all failed fields
1769		$('.cm-failed-field', form).removeClass('cm-failed-field');
1770		this.errors = {};
1771
1772		elms = form.get(0).elements;
1773		for (i=0; i < elms.length; i++) {
1774			set_mark = false;
1775			set_mark_alt = false;
1776			alt_id = '';
1777			elm = $(elms[i]);
1778			elm_id = elm.attr('id');
1779			if (!this.properties[elm_id]) {
1780				continue;
1781			}
1782
1783			lbl = $('label[for=' + elm_id + ']', form);
1784
1785			// Check the need to trim value
1786			if (lbl.hasClass('cm-trim')) {
1787				elm.val(jQuery.trim(elm.val()));
1788			}
1789
1790			// Check the email field
1791			if (lbl.hasClass('cm-email')) {
1792				if (jQuery.is.email(elm.val()) == false) {
1793					if (lbl.hasClass('cm-required') || jQuery.is.blank(elm.val()) == false) {
1794						this.form_message(lang.error_validator_email, lbl);
1795						is_ok = false;
1796						set_mark = true;
1797					}
1798				}
1799			}
1800
1801			// Check the email field with confirmation
1802			if (lbl.hasClass('cm-confirm-email')) {
1803				confirm_field = $('#confirm_' + elm_id);
1804				if (jQuery.is.email(elm.val()) != true) {
1805					if (lbl.hasClass('cm-required') || jQuery.is.blank(elm.val()) == false) {
1806						this.form_message(lang.error_validator_email, lbl);
1807						is_ok = false;
1808						set_mark = true;
1809					}
1810				}
1811				if (jQuery.is.email(confirm_field.val()) != true) {
1812					is_ok = false;
1813					set_mark_alt = true;
1814					alt_id = confirm_field.attr('id');
1815				}
1816
1817				if (elm.val() != confirm_field.val()) {
1818					this.form_message(lang.error_validator_confirm_email, lbl);
1819					is_ok = false;
1820					set_mark = true;
1821					set_mark_alt = true;
1822					alt_id = confirm_field.attr('id');
1823				}
1824			}
1825
1826			// Check the phone field
1827			if (lbl.hasClass('cm-phone')) {
1828				if (jQuery.is.phone(elm.val()) != true) {
1829					if (lbl.hasClass('cm-required') || jQuery.is.blank(elm.val()) == false) {
1830						this.form_message(lang.error_validator_phone, lbl);
1831						is_ok = false;
1832						set_mark = true;
1833					}
1834				}
1835			}
1836
1837			// Check the zipcode field
1838			if (lbl.hasClass('cm-zipcode')) {
1839				var loc = lbl.attr('class').match(/cm-location-([^\s]+)/i)[1] || '';
1840				var country = $('#' + $('.cm-country' + (loc ? '.cm-location-' + loc : ''), form).attr('for')).val();
1841				if (jQuery.is.zipcode(elm.val(), country) != true) {
1842					if (lbl.hasClass('cm-required') || jQuery.is.blank(elm.val()) == false) {
1843						this.form_message(lang.error_validator_zipcode, lbl, null, zip_validators[country]['format']);
1844						is_ok = false;
1845						set_mark = true;
1846					}
1847				}
1848			}
1849
1850			// Check for integer field
1851			if (lbl.hasClass('cm-integer')) {
1852				if (jQuery.is.integer(elm.val()) == false) {
1853					if (lbl.hasClass('cm-required') || jQuery.is.blank(elm.val()) == false) {
1854						this.form_message(lang.error_validator_integer, lbl);
1855						is_ok = false;
1856						set_mark = true;
1857					}
1858				}
1859			}
1860
1861			// Check for multiple selectbox
1862			if (lbl.hasClass('cm-multiple') && elm.attr('length') == 0) {
1863				this.form_message(lang.error_validator_multiple, lbl);
1864				is_ok = false;
1865				set_mark = true;
1866			}
1867
1868			// Check for passwords
1869			if (lbl.hasClass('cm-password')) {
1870				if (passwd && elm.val() != $('#' + passwd).val()) {
1871					is_ok = false;
1872					set_mark = set_mark_alt = true;
1873					alt_id = passwd;
1874					this.form_message(lang.error_validator_password, lbl, $('label[for=' + passwd + ']'));
1875				}
1876
1877				if (!passwd) {
1878					passwd = elm_id;
1879				}
1880			}
1881
1882			if (lbl.hasClass('cm-custom')) {
1883				var callback = lbl.attr('class').match(/\((\w+)\)/i)[1] || '';
1884				if (callback) {
1885					var result = window['fn_' + callback](lbl.attr('for'));
1886					if (result != true) {
1887						set_mark = true;
1888						is_ok = false;
1889						this.form_message(result, lbl);
1890					}
1891				}
1892			}
1893
1894			if (lbl.hasClass('cm-regexp')) {
1895				var id = lbl.attr('for');
1896				
1897				if (typeof(regexp[id]) != 'undefined' && !(elm.hasClass('cm-hint') && elm.val() == elm.attr('defaultValue'))) {
1898					var val = elm.val();
1899					var expr = new RegExp(regexp[id]['regexp']);
1900					var result = expr.test(val);
1901					
1902					if (!result && !(!lbl.hasClass('cm-required') && elm.val() == '')) {
1903						set_mark = true;
1904						is_ok = false;
1905						this.form_message((regexp[id]['message'] != '' ? regexp[id]['message'] : lang.error_validator_message), lbl);
1906					}
1907				}
1908			}
1909
1910			// Select all items in multiple selectbox
1911			if (lbl.hasClass('cm-all')) {
1912				if (elm.attr('length') == 0 && lbl.hasClass('cm-required')) {
1913					this.form_message(lang.error_validator_multiple, lbl);
1914					is_ok = false;
1915					set_mark = true;
1916				} else {
1917					$('option', elm).attr('selected', 'selected');
1918				}
1919
1920			// Check for blank value
1921			} else {
1922
1923				// Check for multiple selectbox
1924				if (elm.is(':input')) {
1925					if (lbl.hasClass('cm-required') && ((elm.is(':checkbox') && !elm.attr('checked')) || jQuery.is.blank(elm.val()) == true || (elm.hasClass('cm-hint') && elm.val() == elm.attr('defaultValue')))) {
1926						this.form_message(lang.error_validator_required, lbl);
1927						is_ok = false;
1928						set_mark = true;
1929					}
1930				}
1931			}
1932
1933			// Check for the multiple checkboxes
1934			if (elm.hasClass('form-checkbox')) {
1935				id = this.properties[elm_id];
1936				lbl = $('label[for=' + id + ']', form);
1937				
1938				if (lbl.hasClass('cm-required')) {
1939					checked_elms = $('[id*=' + id + '_]:checked').length;
1940					
1941					if (checked_elms == 0) {
1942						if (!this.errors[id]) {
1943							this.form_message(lang.error_validator_required, lbl);
1944						}
1945						is_ok = false;
1946						set_mark = true;
1947					}
1948					
1949					elm_id = id;
1950				}
1951			}
1952			
1953			if (elm_id) {
1954
1955				if (elm.parents('.fileuploader').length) { // file uploader
1956					elm = elm.parents('.fileuploader');
1957				}
1958
1959				if (elm.parents('.categories').length) {
1960					elm = elm.parents('.categories');
1961				}
1962
1963				$('.error-message.' + elm_id, elm.parents('.form-field,.clear-form-field')).remove();
1964				if (set_mark == true) {
1965					elm.addClass('cm-failed-field');
1966					parent_elm = elm.parents('.form-field,.clear-form-field');
1967					
1968					if ($('.description', parent_elm).length) {
1969						$('.description', parent_elm).before('<div class="error-message ' + elm_id + '"><div class="arrow"></div><div class="message">' + this.get_message(elm_id) + '</div></div>');
1970					} else {
1971						parent_elm.append('<div class="error-message ' + elm_id + '"><div class="arrow"></div><div class="message">' + this.get_message(elm_id) + '</div></div>');
1972					}
1973
1974					if (first) {
1975						jQuery.scrollToElm(elm);
1976						first = false;
1977					}
1978
1979				} else {
1980					elm.removeClass('cm-failed-field');
1981				}
1982
1983				if (alt_id)	{
1984					if (set_mark_alt == true) {
1985						$('#' + alt_id).addClass('cm-failed-field');
1986					} else {
1987						$('#' + alt_id).removeClass('cm-failed-field');
1988					}
1989				}
1990			}
1991		}
1992
1993		return is_ok;
1994	};
1995
1996	this.check = function()
1997	{
1998		var CPS = 2000;
1999		var form_result = true;
2000		var check_fields_result = true;
2001		var c_elm = $(this.clicked_elm);
2002		var frm = $(this.form);
2003
2004		if (!c_elm.hasClass('cm-skip-validation')){
2005
2006			this.fill_requirements();
2007
2008			if (jQuery.isFunction(window['fn_form_pre_' + frm.attr('name')])) {
2009				form_result = window['fn_form_pre_' + frm.attr('name')]();
2010			}
2011			check_fields_result = this.check_fields();
2012		}
2013
2014		if (check_fields_result == true && form_result == true) {
2015			
2016			if (frm.hasClass('cm-disable-empty')) {
2017				$('input:text[value=""]', frm).attr('disabled', 'disabled');
2018			}
2019			
2020			if (frm.hasClass('cm-disable-empty-files')) {
2021				// Disable empty input:file in order to block the "garbage" data
2022				$('input:file[value=""]', frm).attr('disabled', 'disabled');
2023			}
2024
2025			// protect button from double click
2026			if (c_elm.data('clicked') == true) {
2027				return false;
2028			}
2029
2030			// set clicked flag
2031			c_elm.data('clicked', true);
2032
2033			// clean clicked flag
2034			setTimeout(function() { 
2035				c_elm.data('clicked', false);
2036				c_elm.removeData('event_elm');
2037			}, CPS);
2038
2039			// If pressed button has cm-new-window microformat, send form to new window
2040			// otherwise, send to current
2041			if ($(this.clicked_elm).hasClass('cm-new-window')) {
2042				frm.attr('target', '_blank');
2043				return true;
2044
2045			} else if ($(this.clicked_elm).hasClass('cm-parent-window')) {
2046				frm.attr('target', '_parent');
2047				return true;
2048
2049			} else {
2050				frm.attr('target', '_self');
2051			}
2052
2053			if ((frm.hasClass('cm-ajax') || $(this.clicked_elm).hasClass('cm-ajax')) && !$(this.clicked_elm).hasClass('cm-no-ajax')) {
2054				return jQuery.ajaxSubmit(frm, $(this.clicked_elm));
2055			}
2056
2057			if ($(this.clicked_elm).hasClass('cm-no-ajax')) {
2058				$('input[name=is_ajax]', frm).remove();
2059			}
2060
2061
2062			if (jQuery.isFunction(window['fn_form_post_' + frm.attr('name')])) {
2063				form_result = window['fn_form_post_' + frm.attr('name')](frm, c_elm);
2064			}			
2065
2066			return form_result;
2067
2068		} else if (check_fields_result == false) {
2069			var hidden_elm = $('.cm-failed-field', frm).parents('[id^="content_"]:hidden');
2070			if (hidden_elm.length && $('.cm-failed-field', frm).length == $('.cm-failed-field', hidden_elm).length) {
2071				$('#' + hidden_elm.attr('id').str_replace('content_', '')).click();
2072			}
2073		}
2074
2075		return false;
2076	};
2077
2078	this.form_message = function(msg, field, field2, extra)
2079	{
2080		var id = field.attr('for');
2081		if (!this.errors[id]) {
2082			this.errors[id] = [];
2083		}
2084
2085		if (extra) {
2086			msg = msg.str_replace('[extra]', extra);
2087		}
2088		if (field2) {
2089			this.errors[id].push(msg.str_replace('[field1]', jQuery.rtrim(field.text(), ':')).str_replace('[field2]', jQuery.rtrim(field2.text(), ':')).str_replace('(?)', ''));
2090		} else {
2091			this.errors[id].push(msg.str_replace('[field]', jQuery.rtrim(field.text(), ':')).str_replace('(?)', ''));
2092		}
2093	};
2094
2095	this.get_message = function(id)
2096	{
2097		return '<p>' + this.errors[id].join('</p><p>') + '</p>';
2098	};
2099}
2100
2101
2102//
2103// Utility functions
2104//
2105
2106//
2107// str_replace wrapper
2108//
2109String.prototype.str_replace = function(src, dst)
2110{
2111
2112	return this.toString().split(src).join(dst);
2113};
2114
2115//
2116// Print variable contents
2117//
2118function fn_print_r(value)
2119{
2120	alert(fn_print_array(value));
2121}
2122
2123// Helper
2124function fn_print_array(arr, level)
2125{
2126	var dumped_text = "";
2127	if(!level) {
2128		level = 0;
2129	}
2130
2131	//The padding given at the beginning of the line.
2132	var level_padding = "";
2133	for(var j=0; j < level+1; j++) {
2134		level_padding += "    ";
2135	}
2136
2137	if(typeof(arr) == 'object') { //Array/Hashes/Objects
2138		for(var item in arr) {
2139			var value = arr[item];
2140
2141			if(typeof(value) == 'object') { //If it is an array,
2142				dumped_text += level_padding + "'" + item + "' ...\n";
2143				dumped_text += fn_print_array(value,level+1);
2144			} else {
2145				dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
2146			}
2147		}
2148	} else { //Stings/Chars/Numbers etc.
2149		dumped_text = arr+" ("+typeof(arr)+")";
2150	}
2151
2152	return dumped_text;
2153}
2154
2155//
2156// Raise event on defined hook
2157//
2158function fn_set_hook(hook, data)
2159{
2160	for (var k in window['_HOOKS']) {
2161		if (jQuery.isFunction(window[k]) && k.indexOf(hook) != -1) {
2162			window[k](data);
2163		}
2164	}
2165}
2166
2167//
2168// Register hooks
2169//
2170function fn_register_hooks(addon, hooks)
2171{
2172	if (!window['_HOOKS']) {
2173		window['_HOOKS'] = {};
2174	}
2175
2176	var data = {};
2177	for (var i = 0; i < hooks.length ; i++) {
2178		window['_HOOKS']['fn_' + addon + '_' + hooks[i]] = true;
2179	}
2180}
2181
2182function fn_update_quick_menu_position(elm)
2183{
2184	var w = jQuery.get_window_sizes();
2185	var new_x = parseInt(elm.css('left')) - w.offset_x;
2186	var new_y = parseInt(elm.css('top')) - w.offset_y;
2187	new_x = new_x > 0 ? (new_x < w.offset_x + w.view_width - elm.width() ? new_x : w.offset_x + w.view_width - elm.width()) : 0;
2188	new_y = new_y > 0 ? (new_y < w.offset_y + w.view_height - elm.height() ? new_y : w.offset_y + w.view_height - elm.height()) : 0;
2189	elm.css({'left': new_x, 'top': new_y});
2190	jQuery.cookie.set('quick_menu_offset', 'left: ' + new_x + 'px; top:' + new_y + 'px;');
2191}
2192
2193function fn_switch_page(elm)
2194{
2195	var c = elm.parents('.cm-pagination-wraper');
2196	var l = $('a[name=pagination][href]:first', c); // get link to retrieve parameters from it
2197	var page_num = elm.val() < 1 ? 1 : elm.val();
2198	var url = l.attr('href').replace(/page=(\d+)$/i, 'page=' + page_num);
2199
2200	if (l.hasClass('cm-ajax')) {
2201		if (typeof(jQuery.history) != 'undefined' && l.hasClass('cm-history') && l.attr('rel') && jQuery.ceDialog('inside_dialog', {elm: l}) == false) {
2202			$.history.load('ty;' + l.attr('rev') + ';' + url);
2203		}
2204		$.ajaxRequest(url, { 
2205			result_ids: l.attr('rev'),
2206			caching: true,
2207			force_exec: true,
2208			callback: function() {
2209				var c = $('.cm-pagination-wraper:first');
2210				var w = jQuery.get_window_sizes();
2211
2212				if (w.offset_y > c.offset().top) {
2213					jQuery.scrollToElm(c);
2214				}
2215			}
2216		});
2217	} else {
2218		jQuery.redirect(url);
2219	}
2220
2221	return true;
2222}
2223
2224function fn_pagination()
2225{
2226	var c = $('.cm-pagination-wraper:first');
2227	var w = jQuery.get_window_sizes();
2228
2229	if (w.offset_y > c.offset().top) {
2230		jQuery.scrollToElm(c);
2231	}
2232}
2233
2234function fn_url(url)
2235{
2236	if (url.substring(0, index_script.length) != index_script) {
2237		url = index_script + '?dispatch=' + url.replace('?', '&');
2238	}
2239	return url;
2240}
2241
2242function fn_layout_callback(callback)
2243{
2244	data = {data: callback};
2245	fn_set_hook('layout_callback', data);
2246}
2247
2248function fn_sorting_callback(callback)
2249{
2250	data = {data: callback};
2251	fn_set_hook('sorting_callback', data);
2252};
2253
2254/*
2255 * Dialog opener
2256 *
2257 */
2258(function($){
2259	var methods = {
2260		open: function(params) {
2261			var container = $(this);
2262			params = params || {};
2263
2264			if (!container.hasClass('ui-dialog-content')) { // dialog is not generated yet, init it
2265
2266				params.href = params.href || '';
2267
2268				if (!$.trim(container.html()) && params.href) {
2269					$.ajaxRequest(params.href, {result_ids: container.attr('id'), skip_result_ids_check: true, callback: function() {
2270						container.ceDialog('open', params);
2271					}});
2272
2273					return false;
2274				}
2275
2276				container.ceDialog('_init', params);
2277				methods._optimize('move', container, params);
2278			}
2279
2280			if (params)	{
2281				container.dialog('option', params);
2282			}
2283
2284			return container.dialog('open');
2285		},
2286
2287		close: function() {
2288			$(this).dialog('close');
2289		},
2290
2291		_optimize: function(action, container, params) {
2292			if (action == 'move') {
2293				if (!tmpCont) {
2294					tmpCont = $('<div class="hidden" id="dialog_tmp" />').appendTo('body');
2295				}
2296
2297				// Do not use optimization for auto-sized dialogs
2298				if (params.height && params.height == 'auto' || params.width && params.width == 'auto') {
2299					container.data('skipDialogOptimization', true);
2300				} else {
2301					tmpCont.append(container.contents());
2302				}
2303			} else if (action == 'return') {
2304				if (!container.data('skipDialogOptimization')) {
2305					container.append(tmpCont.contents());
2306					tmpCont.empty();
2307				}
2308			}
2309		},
2310
2311		_init: function(params) {
2312
2313			params = params || {};
2314			var container = $(this);
2315			var offset = 10;
2316			var max_width = 1024;
2317			var width_border = 120;
2318			var height_border = 80;
2319
2320			var ws = $.get_window_sizes();
2321			var container_parent = container.parent();
2322
2323			if (container.parents('form').length && !container.parents('.object-container').length) {
2324				params.keepInPlace = true;
2325			}
2326
2327			container.find('script[src]').remove();
2328			container.wrapInner('<div class="object-container" />');
2329
2330			container.dialog({
2331				title: params.title || null,
2332				autoOpen: false,
2333				stack: true,
2334				modal: true,
2335				width: params.width || (ws.view_width > max_width ? max_width : ws.view_width - width_border),
2336				height: params.height || (ws.view_height - height_border),
2337				maxWidth: max_width,
2338				maxHeight: ws.view_height - height_border,
2339				position: 'center',
2340				resizable: true,
2341				closeOnEscape: false,
2342				zIndex: 27,
2343
2344				open: function(e, u) {
2345					var d = $(this);
2346					if (stack.length) {
2347						var prev = stack.pop();
2348						d.dialog('option', 'position', [parseInt(prev.pos.left) + offset, parseInt(prev.pos.top) + offset]);
2349						stack.push(prev);
2350					}
2351					stack.push({'id': d.attr('id'), 'pos' : d.offset()});
2352
2353					methods._optimize('return', d);
2354					methods._resize(d);
2355					
2356					$('textarea.cm-wysiwyg', d).ceEditor('recover');
2357				},
2358
2359				beforeClose: function(e, u) {
2360					var d = $(this);
2361					$('textarea.cm-wysiwyg', d).ceEditor('destroy');
2362				},
2363
2364				close: function(){
2365					stack.pop();
2366				},
2367
2368				resize: function(e, u) {
2369					methods._resize($(this));
2370				},
2371				
2372				dragStart: function(){
2373					$(this).hide();
2374				},
2375				
2376				dragStop: function(){
2377					$(this).show();
2378				}
2379			});
2380
2381			// Do not move dialog to body
2382			if (params.keepInPlace) {
2383				container.dialog('widget').appendTo(container_parent);
2384			}
2385		},
2386
2387		_resize: function(d) {
2388
2389			var buttonsElm = d.find('.buttons-container:last');
2390			var optionsElm = d.find('.cm-picker-options-container');
2391			var viewElm = d.find('.object-container');
2392			var buttonsHeight = buttonsElm.outerHeight(true);
2393			var optionsHeight = 0;
2394
2395			if (optionsElm.length) {
2396				optionsHeight = optionsElm.outerHeight(true);
2397			}
2398
2399
2400			viewElm.outerHeight(d.height() - (buttonsHeight + optionsHeight));
2401
2402			if (optionsHeight) {
2403				optionsElm.css({position: 'absolute', width: viewElm.outerWidth()}).position({
2404					my: 'left top',
2405					at: 'left bottom',
2406					of: viewElm
2407				});
2408			}
2409
2410			buttonsElm.css('position', 'absolute').position({
2411				my: 'left top',
2412				at: 'left bottom',
2413				of: optionsHeight ? optionsElm : viewElm
2414			});
2415		}
2416	};
2417
2418	var stack = [];
2419	var tmpCont;
2420
2421	$.fn.ceDialog = function(method) {
2422		if (methods[method]) {
2423			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
2424		} else if ( typeof method === 'object' || ! method ) {
2425			return methods._init.apply(this, arguments);
2426		} else {
2427			$.error('ty.dialog: method ' +  method + ' does not exist');
2428		}
2429	};
2430
2431	$.extend({
2432		ceDialog: function(action, params) {
2433			params = params || {};
2434			if (action == 'get_last') {
2435				if (stack.length == 0) {
2436					return jQuery();
2437				}
2438
2439				var dlg = jQuery('#' + stack[stack.length - 1].id);
2440
2441				return params.getWidget ? dlg.dialog('widget') : dlg;
2442
2443			} else if (action == 'fit_elements') {
2444				var jelm = params.jelm;
2445
2446				if (jelm.parents('.cm-picker-options-container').length) {
2447					jQuery.ceDialog('get_last').data('dialog')._trigger('resize');
2448				}
2449
2450			} else if (action == 'inside_dialog') {
2451				return (params.elm.parents('.ui-dialog-content').length != 0);
2452			}
2453		}
2454	});
2455})(jQuery);
2456
2457/*
2458 * WYSIWYG opener
2459 *
2460 */
2461(function($){
2462	
2463	var methods = {
2464		run: function() {
2465
2466			if (!this.length) {
2467				return false;
2468			}
2469
2470			if ($.ceEditor('state') == 'loading') {
2471				$.ceEditor('push', this);
2472			} else {
2473				$.data.ceEditorMethods.runEditor(this);
2474			}
2475		},
2476
2477		destroy: function() {
2478
2479			if (!this.length || $.ceEditor('state') != 'loaded') {
2480				return false;
2481			}
2482
2483			$.data.ceEditorMethods.destroyEditor(this);
2484		},
2485
2486		recover: function() {
2487
2488			if (!this.length || $.ceEditor('state') != 'loaded') {
2489				return false;
2490			}
2491
2492			$.data.ceEditorMethods.recoverEditor(this);
2493		}
2494	};
2495
2496	$.fn.ceEditor = function(method) {
2497		if (methods[method]) {
2498			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
2499		} else if ( typeof method === 'object' || ! method ) {
2500			return methods.run.apply(this, arguments);
2501		} else {
2502			$.error('ty.editor: method ' +  method + ' does not exist');
2503		}
2504	};
2505
2506	$.extend({
2507		ceEditor: function(action, data) {
2508			if (!this.state) {
2509				this.state = 'not-loaded';
2510				this.pool = [];
2511			}
2512
2513			if (action == 'push') {
2514				if (data) {
2515					this.pool.push(data);
2516				} else {
2517					return this.pool.unshift();
2518				}
2519			} else if (action == 'state') {
2520				if (data) {
2521					this.state = data;
2522					if (data == 'loaded' && this.pool) {
2523						for (var i = 0; i < this.pool.length; i++) {
2524							this.pool[i].ceEditor('run');
2525						}
2526						this.pool = [];
2527					}
2528				} else {
2529					return this.state;
2530				}
2531			}
2532		}
2533	});
2534})(jQuery);
2535
2536
2537/*
2538 * Previewer methods
2539 *
2540 */
2541(function($){
2542	
2543	var methods = {
2544		display: function() {
2545			$.data.cePreviewerMethods.display(this);
2546		}
2547	};
2548
2549	$.fn.cePreviewer = function(method) {
2550		if (methods[method]) {
2551			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
2552		} else if ( typeof method === 'object' || ! method ) {
2553			return methods.run.apply(this, arguments);
2554		} else {
2555			$.error('ty.previewer: method ' +  method + ' does not exist');
2556		}
2557	};
2558})(jQuery);
2559
2560
2561/*
2562 * Progress bar (COMET)
2563 *
2564 */
2565(function($){
2566
2567	var methods = {
2568
2569		init: function() {
2570
2571			if (!$('.cm-progressbar', this).length) {
2572				$('<div class="cm-progressbar"></div>').appendTo(this);
2573				$('<div class="cm-progressbar-status"></div>').appendTo(this);
2574				$('.cm-progressbar', this).progressbar();
2575			}
2576
2577			this.ceDialog('open', {resizable: false});
2578			this.data('ceProgressbar', true);
2579		},
2580
2581		setValue: function(o) {
2582			if (!this.data('ceProgressbar')) {
2583				this.ceProgress('init');
2584			}
2585
2586			if (o.progress) {
2587				$('.cm-progressbar', this).progressbar('value', o.progress);
2588			}
2589
2590			if (o.text) {
2591				$('.cm-progressbar-status', this).html(o.text);
2592			}
2593		},
2594
2595		finish: function() {
2596			this.ceDialog('close');
2597			$('.cm-progressbar', this).progressbar('value', 0);
2598			$('.cm-progressbar-status', this).empty();
2599			this.removeData('ceProgressbar');
2600		}
2601	};
2602
2603	$.fn.ceProgress = function(method) {
2604		if (methods[method]) {
2605			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
2606		} else if ( typeof method === 'object' || ! method ) {
2607			return methods.init.apply(this, arguments);
2608		} else {
2609			$.error('ty.progress: method ' +  method + ' does not exist');
2610		}
2611	};
2612})(jQuery);
2613
2614
2615
2616
2617/*
2618 * Floating bar
2619 *
2620 */
2621(function($){
2622	$.extend({
2623		ceFloatingBar: function() {
2624			var fb = this;
2625			if (!fb.fbToggle) {
2626				fb.fbToggle = function(scroll) {
2627					var toggle = this;
2628					var w = jQuery.get_window_sizes();
2629					var elms;
2630					if (scroll && toggle.elms) {
2631						elms = toggle.elms.filter(':visible');
2632					} else {
2633						elms = toggle.elms = $('form').find('.buttons-bg');
2634					}
2635					
2636					$(elms).each(function() {
2637						
2638						var self = $(this);
2639						if (!self.has('input')) {
2640							return false;
2641						}
2642
2643						if (!self.data('fbarInit'))	{
2644							self.wrapInner('<div class="cm-buttons-placeholder"></div>');
2645							self.append('<div class="cm-buttons-floating hidden"></div>');
2646							self.data('fbarInit', true);
2647						}
2648						
2649						var floating = self.find('.cm-buttons-floating');
2650						var offset = self.offset();
2651
2652						if (self.is(':visible') && offset.top > w.offset_y + w.view_height - 70) { // 70 = bottom_menu height + cm-buttons-floating height
2653							if (!floating.children().length) {
2654								floating.append(self.find('.cm-buttons-placeholder'));
2655								floating.show();
2656							}
2657						} else {
2658							if (floating.children().length) {
2659								self.append(self.find('.cm-buttons-placeholder'));
2660								floating.hide();
2661							}
2662						}
2663						
2664						if(jQuery.isMobile()) {
2665							$(".cm-buttons-floating").css("position", "relative");
2666						}
2667					});
2668				};
2669
2670				$(window).bind('scroll resize', function() {
2671					fb.fbToggle(true);
2672				});
2673			}
2674
2675			fb.fbToggle();
2676		}
2677	});
2678
2679})(jQuery);
2680
2681(function($){
2682	$.ceScrollerMethods = {
2683		fn_scroller_in_out_callback: function(carousel, item, i, state, evt) {
2684			if (carousel.allow_in_out_callback) {
2685				if (carousel.options.autoDirection == 'next') {
2686					carousel.add(i + carousel.options.item_count, $(item).html());
2687					carousel.remove(i);
2688				} else {
2689					var last_item = $('li:last', carousel.list);
2690					carousel.add(last_item.attr('jcarouselindex') - carousel.options.item_count, last_item.html());
2691					carousel.remove(last_item.attr('jcarouselindex'));
2692				}
2693			}
2694		},
2695 
2696		fn_scroller_next_callback: function(carousel, item, i, state, evt) {
2697			if (state == 'next') {
2698				carousel.add(i + carousel.options.item_count, $(item).html());
2699				carousel.remove(i);
2700			}
2701		},
2702		
2703		fn_scroller_prev_callback: function(carousel, item, i, state, evt) {
2704			if (state == 'prev') {
2705				var last_item = $('li:last', carousel.list);
2706				var item = last_item.html();
2707				var count = last_item.attr('jcarouselindex') - carousel.options.item_count;
2708				carousel.remove(last_item.attr('jcarouselindex'));
2709				carousel.add(count, item);
2710			}
2711		},
2712 
2713		fn_scroller_init_callback: function(carousel, state) {
2714			$('.jcarousel-clip', carousel.container).height(carousel.options.clip_height + 'px');
2715			$('.jcarousel-clip', carousel.container).width(carousel.options.clip_width + 'px');
2716
2717			carousel.clip.hover(function() {
2718				carousel.stopAuto();
2719			}, function() {
2720				carousel.startAuto();
2721			});
2722			$(window).bind('beforeunload', function() {
2723				carousel.allow_in_out_callback = false;
2724			});
2725		}
2726	}
2727})(jQuery);

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.