PageSourceSearch

https://infostart.ru/bitrix/cache/js/ru/sandbox_empty/kernel_main/kernel_main.js?1789575312246964

js infostart.ru collected 2026-10-02 03:27:22 UTC 246,964 bytes, 11,090 lines download raw bytes

1; /* /bitrix/js/main/core/core_window.js*/
2; /* /bitrix/js/main/core/core.js*/
3; /* /bitrix/js/main/core/core_ajax.js*/
4; /* /bitrix/js/main/json/json2.min.js*/
5; /* /bitrix/js/main/core/core_ls.js*/
6; /* /bitrix/js/main/session.js*/
7
8; /* Start:/bitrix/js/main/core/core.js*/
9/**********************************************************************/
10/*********** Bitrix JS Core library ver 0.9.0 beta ********************/
11/**********************************************************************/
12
13;(function(window){
14
15if (!!window.BX && !!window.BX.extend)
16	return;
17
18var _bxtmp;
19if (!!window.BX)
20{
21	_bxtmp = window.BX;
22}
23
24window.BX = function(node, bCache)
25{
26	if (BX.type.isNotEmptyString(node))
27	{
28		var ob;
29
30		if (!!bCache && null != NODECACHE[node])
31			ob = NODECACHE[node];
32		ob = ob || document.getElementById(node);
33		if (!!bCache)
34			NODECACHE[node] = ob;
35
36		return ob;
37	}
38	else if (BX.type.isDomNode(node))
39		return node;
40	else if (BX.type.isFunction(node))
41		return BX.ready(node);
42
43	return null;
44};
45
46// language utility
47BX.message = function(mess)
48{
49	if (BX.type.isString(mess))
50	{
51		if (typeof BX.message[mess] == "undefined")
52		{
53			BX.onCustomEvent("onBXMessageNotFound", [mess]);
54			if (typeof BX.message[mess] == "undefined")
55			{
56				BX.debug("message undefined: " + mess);
57				BX.message[mess] = "";
58			}
59
60		}
61
62		return BX.message[mess];
63	}
64	else
65	{
66		for (var i in mess)
67		{
68			if (mess.hasOwnProperty(i))
69			{
70				BX.message[i] = mess[i];
71			}
72		}
73		return true;
74	}
75};
76
77if(!!_bxtmp)
78{
79	for(var i in _bxtmp)
80	{
81		if(_bxtmp.hasOwnProperty(i))
82		{
83			if(!BX[i])
84			{
85				BX[i]=_bxtmp[i];
86			}
87			else if(i=='message')
88			{
89				for(var j in _bxtmp[i])
90				{
91					if(_bxtmp[i].hasOwnProperty(j))
92					{
93						BX.message[j]=_bxtmp[i][j];
94					}
95				}
96			}
97		}
98	}
99
100	_bxtmp = null;
101}
102
103var
104
105/* ready */
106__readyHandler = null,
107readyBound = false,
108readyList = [],
109
110/* list of registered proxy functions */
111proxySalt = Math.random(),
112proxyId = 1,
113proxyList = [],
114deferList = [],
115
116/* getElementById cache */
117NODECACHE = {},
118
119/* List of denied event handlers */
120deniedEvents = [],
121
122/* list of registered event handlers */
123eventsList = [],
124
125/* list of registered custom events */
126customEvents = {},
127
128/* list of external garbage collectors */
129garbageCollectors = [],
130
131/* list of loaded CSS files */
132cssList = [],
133cssInit = false,
134
135/* list of loaded JS files */
136jsList = [],
137jsInit = false,
138
139
140/* browser detection */
141bSafari = navigator.userAgent.toLowerCase().indexOf('webkit') != -1,
142bOpera = navigator.userAgent.toLowerCase().indexOf('opera') != -1,
143bFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') != -1,
144bChrome = navigator.userAgent.toLowerCase().indexOf('chrome') != -1,
145bIE = document.attachEvent && !bOpera,
146
147/* regexps */
148r = {
149	script: /<script([^>]*)>/ig,
150	script_end: /<\/script>/ig,
151	script_src: /src=["\']([^"\']+)["\']/i,
152	script_type: /type=["\']([^"\']+)["\']/i,
153	space: /\s+/,
154	ltrim: /^[\s\r\n]+/g,
155	rtrim: /[\s\r\n]+$/g,
156	style: /<link.*?(rel="stylesheet"|type="text\/css")[^>]*>/i,
157	style_href: /href=["\']([^"\']+)["\']/i
158},
159
160eventTypes = {
161	click: 'MouseEvent',
162	dblclick: 'MouseEvent',
163	mousedown: 'MouseEvent',
164	mousemove: 'MouseEvent',
165	mouseout: 'MouseEvent',
166	mouseover: 'MouseEvent',
167	mouseup: 'MouseEvent',
168	focus: 'MouseEvent',
169	blur: 'MouseEvent'
170},
171
172lastWait = [],
173
174CHECK_FORM_ELEMENTS = {tagName: /^INPUT|SELECT|TEXTAREA|BUTTON$/i},
175
176PRELOADING = 1, PRELOADED = 2, LOADING = 3, LOADED = 4,
177assets = {},
178isAsync = null;
179
180BX.MSLEFT = 1;
181BX.MSMIDDLE = 2;
182BX.MSRIGHT = 4;
183
184BX.ext = function(ob)
185{
186	for (var i in ob)
187	{
188		if(ob.hasOwnProperty(i))
189		{
190			this[i] = ob[i];
191		}
192	}
193};
194
195/* OO emulation utility */
196BX.extend = function(child, parent)
197{
198	var f = function() {};
199	f.prototype = parent.prototype;
200
201	child.prototype = new f();
202	child.prototype.constructor = child;
203
204	child.superclass = parent.prototype;
205	if(parent.prototype.constructor == Object.prototype.constructor)
206	{
207		parent.prototype.constructor = parent;
208	}
209};
210
211BX.namespace = function(namespace)
212{
213	var parts = namespace.split(".");
214	var parent = BX;
215
216	if (parts[0] === "BX")
217	{
218		parts = parts.slice(1);
219	}
220
221	for (var i = 0; i < parts.length; i++) {
222
223		if (typeof parent[parts[i]] === "undefined")
224		{
225			parent[parts[i]] = {};
226		}
227		parent = parent[parts[i]];
228	}
229
230	return parent;
231};
232
233BX.debug = function()
234{
235	if (window.BXDEBUG)
236	{
237		if (window.console && window.console.log)
238			window.console.log('BX.debug: ', arguments.length > 0 ? arguments : arguments[0]);
239		if (window.console && window.console.trace)
240			console.trace();
241	}
242};
243
244BX.is_subclass_of = function(ob, parent_class)
245{
246	if (ob instanceof parent_class)
247		return true;
248
249	if (parent_class.superclass)
250		return BX.is_subclass_of(ob, parent_class.superclass);
251
252	return false;
253};
254
255BX.clearNodeCache = function()
256{
257	NODECACHE = {};
258	return false;
259};
260
261BX.bitrix_sessid = function() {return BX.message("bitrix_sessid"); };
262
263/* DOM manipulation */
264BX.create = function(tag, data, context)
265{
266	context = context || document;
267
268	if (null == data && typeof tag == 'object' && tag.constructor !== String)
269	{
270		data = tag; tag = tag.tag;
271	}
272
273	var elem;
274	if (BX.browser.IsIE() && !BX.browser.IsIE9() && null != data && null != data.props && (data.props.name || data.props.id))
275	{
276		elem = context.createElement('<' + tag + (data.props.name ? ' name="' + data.props.name + '"' : '') + (data.props.id ? ' id="' + data.props.id + '"' : '') + '>');
277	}
278	else
279	{
280		elem = context.createElement(tag);
281	}
282
283	return data ? BX.adjust(elem, data) : elem;
284};
285
286BX.adjust = function(elem, data)
287{
288	var j,len;
289
290	if (!elem.nodeType)
291		return null;
292
293	if (elem.nodeType == 9)
294		elem = elem.body;
295
296	if (data.attrs)
297	{
298		for (j in data.attrs)
299		{
300			if(data.attrs.hasOwnProperty(j))
301			{
302				if (j == 'class' || j == 'className')
303					elem.className = data.attrs[j];
304				else if (j == 'for')
305					elem.htmlFor = data.attrs[j];
306				else if(data.attrs[j] == "")
307					elem.removeAttribute(j);
308				else
309					elem.setAttribute(j, data.attrs[j]);
310			}
311		}
312	}
313
314	if (data.style)
315	{
316		for (j in data.style)
317		{
318			if(data.style.hasOwnProperty(j))
319			{
320				elem.style[j] = data.style[j];
321			}
322		}
323	}
324
325	if (data.props)
326	{
327		for (j in data.props)
328		{
329			if(data.props.hasOwnProperty(j))
330			{
331				elem[j] = data.props[j];
332			}
333		}
334	}
335
336	if (data.events)
337	{
338		for (j in data.events)
339		{
340			if(data.events.hasOwnProperty(j))
341			{
342				BX.bind(elem, j, data.events[j]);
343			}
344		}
345	}
346
347	if (data.children && data.children.length > 0)
348	{
349		for (j=0,len=data.children.length; j<len; j++)
350		{
351			if (BX.type.isNotEmptyString(data.children[j]))
352				elem.innerHTML += data.children[j];
353			else if (BX.type.isElementNode(data.children[j]))
354				elem.appendChild(data.children[j]);
355		}
356	}
357	else if (data.text)
358	{
359		BX.cleanNode(elem);
360		elem.appendChild((elem.ownerDocument || document).createTextNode(data.text));
361	}
362	else if (data.html)
363	{
364		elem.innerHTML = data.html;
365	}
366
367	return elem;
368};
369
370BX.remove = function(ob)
371{
372	if (ob && null != ob.parentNode)
373		ob.parentNode.removeChild(ob);
374	ob = null;
375	return null;
376};
377
378BX.cleanNode = function(node, bSuicide)
379{
380	node = BX(node);
381	bSuicide = !!bSuicide;
382
383	if (node && node.childNodes)
384	{
385		while(node.childNodes.length > 0)
386			node.removeChild(node.firstChild);
387	}
388
389	if (node && bSuicide)
390	{
391		node = BX.remove(node);
392	}
393
394	return node;
395};
396
397BX.html = function(node, html)
398{
399	if(typeof html == 'undefined')
400		return node.innerHTML;
401	
402	node.innerHTML = html;
403}
404
405BX.insertAfter = function(node, dstNode)
406{
407	dstNode.parentNode.insertBefore(node, dstNode.nextSibling);
408}
409
410BX.prepend = function(node, dstNode)
411{
412	dstNode.insertBefore(node, dstNode.firstChild);
413}
414
415BX.append = function(node, dstNode)
416{
417	dstNode.appendChild(node);
418}
419
420BX.addClass = function(ob, value)
421{
422	var classNames;
423	ob = BX(ob);
424
425	value = BX.util.trim(value);
426	if (value == '')
427		return ob;
428
429	if (ob)
430	{
431		if (!ob.className)
432		{
433			ob.className = value
434		}
435		else if (!!ob.classList && value.indexOf(' ') < 0)
436		{
437			ob.classList.add(value);
438		}
439		else
440		{
441			classNames = (value || "").split(r.space);
442
443			var className = " " + ob.className + " ";
444			for (var j = 0, cl = classNames.length; j < cl; j++)
445			{
446				if (className.indexOf(" " + classNames[j] + " ") < 0)
447				{
448					ob.className += " " + classNames[j];
449				}
450			}
451		}
452	}
453
454	return ob;
455};
456
457BX.removeClass = function(ob, value)
458{
459	ob = BX(ob);
460	if (ob)
461	{
462		if (ob.className && !!value)
463		{
464			if (BX.type.isString(value))
465			{
466				if (!!ob.classList && value.indexOf(' ') < 0)
467				{
468					ob.classList.remove(value);
469				}
470				else
471				{
472					var classNames = value.split(r.space), className = " " + ob.className + " ";
473					for (var j = 0, cl = classNames.length; j < cl; j++)
474					{
475						className = className.replace(" " + classNames[j] + " ", " ");
476					}
477
478					ob.className = BX.util.trim(className);
479				}
480			}
481			else
482			{
483				ob.className = "";
484			}
485		}
486	}
487
488	return ob;
489};
490
491BX.toggleClass = function(ob, value)
492{
493	var className;
494	ob = BX(ob);
495
496	if (BX.type.isArray(value))
497	{
498		className = ' ' + ob.className + ' ';
499		for (var j = 0, len = value.length; j < len; j++)
500		{
501			if (BX.hasClass(ob, value[j]))
502			{
503				className = (' ' + className + ' ').replace(' ' + value[j] + ' ', ' ');
504				className += ' ' + value[j >= len-1 ? 0 : j+1];
505
506				j--;
507				break;
508			}
509		}
510
511		if (j == len)
512			ob.className += ' ' + value[0];
513		else
514			ob.className = className;
515
516		ob.className = BX.util.trim(ob.className);
517	}
518	else if (BX.type.isNotEmptyString(value))
519	{
520		if (!!ob.classList)
521		{
522			ob.classList.toggle(value);
523		}
524		else
525		{
526			className = ob.className;
527			if (BX.hasClass(ob, value))
528			{
529				className = (' ' + className + ' ').replace(' ' + value + ' ', ' ');
530			}
531			else
532			{
533				className += ' ' + value;
534			}
535
536			ob.className = BX.util.trim(className);
537		}
538	}
539
540	return ob;
541};
542
543BX.hasClass = function(el, className)
544{
545	el = BX(el);
546	if (!el || !BX.type.isDomNode(el))
547	{
548		BX.debug(el);
549		return false;
550	}
551
552	if (!el.className || !className)
553	{
554		return false;
555	}
556
557	if (!!el.classList && !!className && className.indexOf(' ') < 0)
558	{
559		return el.classList.contains(BX.util.trim(className));
560	}
561	else
562		return ((" " + el.className + " ").indexOf(" " + className + " ")) >= 0;
563};
564
565BX.setOpacity = function(ob, percentage)
566{
567	if (ob.style.filter != null)
568	{
569		//IE
570		ob.style.zoom = "100%";
571
572		if (percentage == 100)
573		{
574			ob.style.filter = "";
575		}
576		else
577		{
578			ob.style.filter = 'alpha(opacity=' + percentage.toString() + ')';
579		}
580	}
581	else if (ob.style.opacity != null)
582	{
583		// W3C
584		ob.style.opacity = (percentage / 100).toString();
585	}
586	else if (ob.style.MozOpacity != null)
587	{
588		// Mozilla
589		ob.style.MozOpacity = (percentage / 100).toString();
590	}
591};
592
593BX.hoverEvents = function(el)
594{
595	if (el)
596		return BX.adjust(el, {events: BX.hoverEvents()});
597	else
598		return {mouseover: BX.hoverEventsHover, mouseout: BX.hoverEventsHout};
599};
600
601BX.hoverEventsHover = function(){BX.addClass(this,'bx-hover');this.BXHOVER=true;};
602BX.hoverEventsHout = function(){BX.removeClass(this,'bx-hover');this.BXHOVER=false;};
603
604BX.focusEvents = function(el)
605{
606	if (el)
607		return BX.adjust(el, {events: BX.focusEvents()});
608	else
609		return {mouseover: BX.focusEventsFocus, mouseout: BX.focusEventsBlur};
610};
611
612BX.focusEventsFocus = function(){BX.addClass(this,'bx-focus');this.BXFOCUS=true;};
613BX.focusEventsBlur = function(){BX.removeClass(this,'bx-focus');this.BXFOCUS=false;};
614
615BX.setUnselectable = function(node)
616{
617	BX.addClass(node, 'bx-unselectable');
618	node.setAttribute('unSelectable', 'on');
619};
620
621BX.setSelectable = function(node)
622{
623	BX.removeClass(node, 'bx-unselectable');
624	node.removeAttribute('unSelectable');
625};
626
627BX.styleIEPropertyName = function(name)
628{
629	if (name == 'float')
630		name = BX.browser.IsIE() ? 'styleFloat' : 'cssFloat';
631	else
632	{
633		var res = BX.browser.isPropertySupported(name);
634		if (res)
635		{
636			name = res;
637		}
638		else
639		{
640			var reg = /(\-([a-z]){1})/g;
641			if (reg.test(name))
642			{
643				name = name.replace(reg, function () {return arguments[2].toUpperCase();});
644			}
645		}
646	}
647	return name;
648};
649
650/* CSS-notation should be used here */
651BX.style = function(el, property, value)
652{
653	if (!BX.type.isElementNode(el))
654		return null;
655
656	if (value == null)
657	{
658		var res;
659
660		if(el.currentStyle)
661			res = el.currentStyle[BX.styleIEPropertyName(property)];
662		else if(window.getComputedStyle)
663		{
664			var q = BX.browser.isPropertySupported(property, true);
665			if (!!q)
666				property = q;
667
668			res = BX.GetContext(el).getComputedStyle(el, null).getPropertyValue(property);
669		}
670
671		if(!res)
672			res = '';
673		return res;
674	}
675	else
676	{
677		el.style[BX.styleIEPropertyName(property)] = value;
678		return el;
679	}
680};
681
682BX.focus = function(el)
683{
684	try
685	{
686		el.focus();
687		return true;
688	}
689	catch (e)
690	{
691		return false;
692	}
693};
694
695BX.firstChild = function(el)
696{
697	var e = el.firstChild;
698	while (e && !BX.type.isElementNode(e))
699	{
700		e = e.nextSibling;
701	}
702
703	return e;
704};
705
706BX.lastChild = function(el)
707{
708	var e = el.lastChild;
709	while (e && !BX.type.isElementNode(e))
710	{
711		e = e.previousSibling;
712	}
713
714	return e;
715};
716
717BX.previousSibling = function(el)
718{
719	var e = el.previousSibling;
720	while (e && !BX.type.isElementNode(e))
721	{
722		e = e.previousSibling;
723	}
724
725	return e;
726};
727
728BX.nextSibling = function(el)
729{
730	var e = el.nextSibling;
731	while (e && !BX.type.isElementNode(e))
732	{
733		e = e.nextSibling;
734	}
735
736	return e;
737};
738
739/*
740	params: {
741		obj : html node
742		className : className value
743		recursive : used only for older browsers to optimize the tree traversal, in new browsers the search is always recursively, default - true
744	}
745
746	Search all nodes with className
747*/
748BX.findChildrenByClassName = function(obj, className, recursive)
749{
750	if(!obj || !obj.childNodes) return null;
751
752	var result = [];
753	if (typeof(obj.getElementsByClassName) == 'undefined')
754	{
755		recursive = recursive !== false;
756		result = BX.findChildren(obj, {className : className}, recursive);
757	}
758	else
759	{
760		var col = obj.getElementsByClassName(className);
761		for (i=0,l=col.length;i<l;i++)
762		{
763			result[i] = col[i];
764		}
765	}
766	return result;
767};
768
769/*
770	params: {
771		obj : html node
772		className : className value
773		recursive : used only for older browsers to optimize the tree traversal, in new browsers the search is always re
773cursively, default - true
774	}
775
776	Search first node with className
777*/
778BX.findChildByClassName = function(obj, className, recursive)
779{
780	if(!obj || !obj.childNodes) return null;
781
782	var result = null;
783	if (typeof(obj.getElementsByClassName) == 'undefined')
784	{
785		recursive = recursive !== false;
786		result = BX.findChild(obj, {className : className}, recursive);
787	}
788	else
789	{
790		var col = obj.getElementsByClassName(className);
791		if (col && typeof(col[0]) != 'undefined')
792		{
793			result = col[0];
794		}
795		else
796		{
797			result = null;
798		}
799	}
800	return result;
801};
802
803/*
804	params: {
805		tagName|tag : 'tagName',
806		className|class : 'className',
807		attribute : {attribute : value, attribute : value} | attribute | [attribute, attribute....],
808		property : {prop: value, prop: value} | prop | [prop, prop]
809	}
810
811	all values can be RegExps or strings
812*/
813BX.findChildren = function(obj, params, recursive)
814{
815	return BX.findChild(obj, params, recursive, true);
816};
817
818BX.findChild = function(obj, params, recursive, get_all)
819{
820	if(!obj || !obj.childNodes) return null;
821
822	recursive = !!recursive; get_all = !!get_all;
823
824	var n = obj.childNodes.length, result = [];
825
826	for (var j=0; j<n; j++)
827	{
828		var child = obj.childNodes[j];
829
830		if (_checkNode(child, params))
831		{
832			if (get_all)
833				result.push(child);
834			else
835				return child;
836		}
837
838		if(recursive == true)
839		{
840			var res = BX.findChild(child, params, recursive, get_all);
841			if (res)
842			{
843				if (get_all)
844					result = BX.util.array_merge(result, res);
845				else
846					return res;
847			}
848		}
849	}
850
851	if (get_all || result.length > 0)
852		return result;
853	else
854		return null;
855};
856
857BX.findParent = function(obj, params, maxParent)
858{
859	if(!obj)
860		return null;
861
862	var o = obj;
863	while(o.parentNode)
864	{
865		var parent = o.parentNode;
866
867		if (_checkNode(parent, params))
868			return parent;
869
870		o = parent;
871
872		if (!!maxParent &&
873			(BX.type.isFunction(maxParent)
874				|| typeof maxParent == 'object'))
875		{
876			if (BX.type.isElementNode(maxParent))
877			{
878				if (o == maxParent)
879					break;
880			}
881			else
882			{
883				if (_checkNode(o, maxParent))
884					break;
885			}
886		}
887	}
888	return null;
889};
890
891BX.findNextSibling = function(obj, params)
892{
893	if(!obj)
894		return null;
895	var o = obj;
896	while(o.nextSibling)
897	{
898		var sibling = o.nextSibling;
899		if (_checkNode(sibling, params))
900			return sibling;
901		o = sibling;
902	}
903	return null;
904};
905
906BX.findPreviousSibling = function(obj, params)
907{
908	if(!obj)
909		return null;
910
911	var o = obj;
912	while(o.previousSibling)
913	{
914		var sibling = o.previousSibling;
915		if(_checkNode(sibling, params))
916			return sibling;
917		o = sibling;
918	}
919	return null;
920};
921
922BX.findFormElements = function(form)
923{
924	if (BX.type.isString(form))
925		form = document.forms[form]||BX(form);
926
927	var res = [];
928
929	if (BX.type.isElementNode(form))
930	{
931		if (form.tagName.toUpperCase() == 'FORM')
932		{
933			res = form.elements;
934		}
935		else
936		{
937			res = BX.findChildren(form, CHECK_FORM_ELEMENTS, true);
938		}
939	}
940
941	return res;
942};
943
944BX.isParentForNode = function(whichNode, forNode)
945{
946
947	if(!BX.type.isDomNode(whichNode) || !BX.type.isDomNode(forNode))
948		return false;
949
950	while(true){
951
952		if(whichNode == forNode)
953			return true;
954
955		if(forNode && forNode.parentNode)
956			forNode = forNode.parentNode;
957		else
958			break;
959	}
960
961	return false;
962}
963
964BX.clone = function(obj, bCopyObj)
965{
966	var _obj, i, l;
967	if (bCopyObj !== false)
968		bCopyObj = true;
969
970	if (obj === null)
971		return null;
972
973	if (BX.type.isDomNode(obj))
974	{
975		_obj = obj.cloneNode(bCopyObj);
976	}
977	else if (typeof obj == 'object')
978	{
979		if (BX.type.isArray(obj))
980		{
981			_obj = [];
982			for (i=0,l=obj.length;i<l;i++)
983			{
984				if (typeof obj[i] == "object" && bCopyObj)
985					_obj[i] = BX.clone(obj[i], bCopyObj);
986				else
987					_obj[i] = obj[i];
988			}
989		}
990		else
991		{
992			_obj =  {};
993			if (obj.constructor)
994			{
995				if (obj.constructor === Date)
996					_obj = new Date(obj);
997				else
998					_obj = new obj.constructor();
999			}
1000
1001			for (i in obj)
1002			{
1003				if (typeof obj[i] == "object" && bCopyObj)
1004					_obj[i] = BX.clone(obj[i], bCopyObj);
1005				else
1006					_obj[i] = obj[i];
1007			}
1008		}
1009
1010	}
1011	else
1012	{
1013		_obj = obj;
1014	}
1015
1016	return _obj;
1017};
1018
1019BX.merge = function(){
1020	var arg = Array.prototype.slice.call(arguments);
1021
1022	if(arg.length < 2)
1023		return {};
1024
1025	var result = arg.shift();
1026
1027	for(var i = 0; i < arg.length; i++)
1028	{
1029		for(var k in arg[i]){
1030
1031			if(typeof arg[i] == 'undefined' || arg[i] == null)
1032				continue;
1033
1034			if(arg[i].hasOwnProperty(k)){
1035
1036				if(typeof arg[i][k] == 'undefined' || arg[i][k] == null)
1037					continue;
1038
1039				if(typeof arg[i][k] == 'object' && !BX.type.isDomNode(arg[i][k]) && (typeof arg[i][k]['isUIWidget'] == 'undefined')){
1040
1041					// go deeper
1042
1043					var isArray = 'length' in arg[i][k];
1044
1045					if(typeof result[k] != 'object')
1046						result[k] = isArray ? [] : {};
1047
1048					if(isArray)
1049						BX.util.array_merge(result[k], arg[i][k]);
1050					else
1051						BX.merge(result[k], arg[i][k]);
1052
1053				}else
1054					result[k] = arg[i][k];
1055			}
1056		}
1057	}
1058
1059	return result;
1060};
1061
1062/* events */
1063BX.bind = function(el, evname, func)
1064{
1065	if (!el)
1066	{
1067		return;
1068	}
1069
1070	if (evname === 'mousewheel')
1071	{
1072		BX.bind(el, 'DOMMouseScroll', func);
1073	}
1074	else if (evname === 'transitionend')
1075	{
1076		BX.bind(el, 'webkitTransitionEnd', func);
1077		BX.bind(el, 'msTransitionEnd', func);
1078		BX.bind(el, 'oTransitionEnd', func);
1079		// IE8-9 doesn't support this feature!
1080	}
1081	else if (evname === 'bxchange')
1082	{
1083		BX.bind(el, "change", func);
1084		BX.bind(el, "cut", func);
1085		BX.bind(el, "paste", func);
1086		BX.bind(el, "drop", func);
1087		BX.bind(el, "keyup", func);
1088
1089		return;
1090	}
1091
1092	if (el.addEventListener) // Gecko / W3C
1093	{
1094		el.addEventListener(evname, func, false);
1095	}
1096	else if (el.attachEvent) // IE
1097	{
1098		el.attachEvent("on" + evname, BX.proxy(func, el));
1099	}
1100	else
1101	{
1102		el["on" + evname] = func;
1103	}
1104
1105	eventsList[eventsList.length] = {'element': el, 'event': evname, 'fn': func};
1106};
1107
1108BX.unbind = function(el, evname, func)
1109{
1110	if (!el)
1111	{
1112		return;
1113	}
1114
1115	if (evname === 'mousewheel')
1116	{
1117		BX.unbind(el, 'DOMMouseScroll', func);
1118	}
1119	else if (evname === 'transitionend')
1120	{
1121		BX.unbind(el, 'webkitTransitionEnd', func);
1122		BX.unbind(el, 'msTransitionEnd', func);
1123		BX.unbind(el, 'oTransitionEnd', func);
1124	}
1125	else if (evname === 'bxchange')
1126	{
1127		BX.unbind(el, "change", func);
1128		BX.unbind(el, "cut", func);
1129		BX.unbind(el, "paste", func);
1130		BX.unbind(el, "drop", func);
1131		BX.unbind(el, "keyup", func);
1132
1133		return;
1134	}
1135
1136	if(el.removeEventListener) // Gecko / W3C
1137	{
1138		el.removeEventListener(evname, func, false);
1139	}
1140	else if(el.detachEvent) // IE
1141	{
1142		el.detachEvent("on" + evname, BX.proxy(func, el));
1143	}
1144	else
1145	{
1146		el["on" + evname] = null;
1147	}
1148};
1149
1150BX.getEventButton = function(e)
1151{
1152	e = e || window.event;
1153
1154	var flags = 0;
1155
1156	if (typeof e.which != 'undefined')
1157	{
1158		switch (e.which)
1159		{
1160			case 1: flags = flags|BX.MSLEFT; break;
1161			case 2: flags = flags|BX.MSMIDDLE; break;
1162			case 3: flags = flags|BX.MSRIGHT; break;
1163		}
1164	}
1165	else if (typeof e.button != 'undefined')
1166	{
1167		flags = event.button;
1168	}
1169
1170	return flags || BX.MSLEFT;
1171};
1172
1173BX.unbindAll = function(el)
1174{
1175	if (!el)
1176		return;
1177
1178	for (var i=0,len=eventsList.length; i<len; i++)
1179	{
1180		try
1181		{
1182			if (eventsList[i] && (null==el || el==eventsList[i].element))
1183			{
1184				BX.unbind(eventsList[i].element, eventsList[i].event, eventsList[i].fn);
1185				eventsList[i] = null;
1186			}
1187		}
1188		catch(e){}
1189	}
1190
1191	if (null==el)
1192	{
1193		eventsList = [];
1194	}
1195};
1196
1197var captured_events = null, _bind = null;
1198BX.CaptureEvents = function(el_c, evname_c)
1199{
1200	if (_bind)
1201		return;
1202
1203	_bind = BX.bind;
1204	captured_events = [];
1205
1206	BX.bind = function(el, evname, func)
1207	{
1208		if (el === el_c && evname === evname_c)
1209			captured_events.push(func);
1210
1211		_bind.apply(this, arguments);
1212	}
1213};
1214
1215BX.CaptureEventsGet = function()
1216{
1217	if (_bind)
1218	{
1219		BX.bind = _bind;
1220
1221		var captured = captured_events;
1222
1223		_bind = null;
1224		captured_events = null;
1225		return captured;
1226	}
1227	return null;
1228};
1229
1230// Don't even try to use it for submit event!
1231BX.fireEvent = function(ob,ev)
1232{
1233	var result = false, e = null;
1234	if (BX.type.isDomNode(ob))
1235	{
1236		result = true;
1237		if (document.createEventObject)
1238		{
1239			// IE
1240			if (eventTypes[ev] != 'MouseEvent')
1241			{
1242				e = document.createEventObject();
1243				e.type = ev;
1244				result = ob.fireEvent('on' + ev, e);
1245			}
1246
1247			if (ob[ev])
1248			{
1249				ob[ev]();
1250			}
1251		}
1252		else
1253		{
1254			// non-IE
1255			e = null;
1256
1257			switch (eventTypes[ev])
1258			{
1259				case 'MouseEvent':
1260					e = document.createEvent('MouseEvent');
1261					e.initMouseEvent(ev, true, true, top, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, null);
1262				break;
1263				default:
1264					e = document.createEvent('Event');
1265					e.initEvent(ev, true, true);
1266			}
1267
1268			result = ob.dispatchEvent(e);
1269		}
1270	}
1271
1272	return result;
1273};
1274
1275BX.getWheelData = function(e)
1276{
1277	e = e || window.event;
1278	e.wheelData = e.detail ? e.detail * -1 : e.wheelDelta / 40;
1279	return e.wheelData;
1280};
1281
1282BX.proxy_context = null;
1283
1284BX.delegate = function (func, thisObject)
1285{
1286	if (!func || !thisObject)
1287		return func;
1288
1289	return function() {
1290		var cur = BX.proxy_context;
1291		BX.proxy_context = this;
1292		var res = func.apply(thisObject, arguments);
1293		BX.proxy_context = cur;
1294		return res;
1295	}
1296};
1297
1298BX.delegateLater = function (func_name, thisObject, contextObject)
1299{
1300	return function()
1301	{
1302		if (thisObject[func_name])
1303		{
1304			var cur = BX.proxy_context;
1305			BX.proxy_context = this;
1306			var res = thisObject[func_name].apply(contextObject||thisObject, arguments);
1307			BX.proxy_context = cur;
1308			return res;
1309		}
1310		return null;
1311	}
1312};
1313
1314BX._initObjectProxy = function(thisObject)
1315{
1316	if (typeof thisObject['__proxy_id_' + proxySalt] == 'undefined')
1317	{
1318		thisObject['__proxy_id_' + proxySalt] = proxyList.length;
1319		proxyList[thisObject['__proxy_id_' + proxySalt]] = {};
1320	}
1321};
1322
1323BX.proxy = function(func, thisObject)
1324{
1325	if (!func || !thisObject)
1326		return func;
1327
1328	BX._initObjectProxy(thisObject);
1329
1330	if (typeof func['__proxy_id_' + proxySalt] == 'undefined')
1331		func['__proxy_id_' + proxySalt] = proxyId++;
1332
1333	if (!proxyList[thisObject['__proxy_id_' + proxySalt]][func['__proxy_id_' + proxySalt]])
1334		proxyList[thisObject['__proxy_id_' + proxySalt]][func['__proxy_id_' + proxySalt]] = BX.delegate(func, thisObject);
1335
1336	return proxyList[thisObject['__proxy_id_' + proxySalt]][func['__proxy_id_' + proxySalt]];
1337};
1338
1339BX.defer = function(func, thisObject)
1340{
1341	if (!!thisObject)
1342		return BX.defer_proxy(func, thisObject);
1343	else
1344		return function() {
1345			var arg = arguments;
1346			setTimeout(function(){func.apply(this,arg)}, 10);
1347		};
1348};
1349
1350BX.defer_proxy = function(func, thisObject)
1351{
1352	if (!func || !thisObject)
1353		return func;
1354
1355	BX.proxy(func, thisObject);
1356
1357	this._initObjectProxy(thisObject);
1358
1359	if (typeof func['__defer_id_' + proxySalt] == 'undefined')
1360		func['__defer_id_' + proxySalt] = proxyId++;
1361
1362	if (!proxyList[thisObject['__proxy_id_' + proxySalt]][func['__defer_id_' + proxySalt]])
1363	{
1364		proxyList[thisObject['__proxy_id_' + proxySalt]][func['__defer_id_' + proxySalt]] = BX.defer(
1364BX.delegate(func, thisObject));
1365	}
1366
1367	return proxyList[thisObject['__proxy_id_' + proxySalt]][func['__defer_id_' + proxySalt]];
1368};
1369
1370BX.bindDelegate = function (elem, eventName, isTarget, handler)
1371{
1372	var h = BX.delegateEvent(isTarget, handler);
1373	BX.bind(elem, eventName, h);
1374	return h;
1375};
1376
1377BX.delegateEvent = function(isTarget, handler)
1378{
1379	return function(e)
1380	{
1381		e = e || window.event;
1382		var target = e.target || e.srcElement;
1383
1384		while (target != this)
1385		{
1386			if (_checkNode(target, isTarget))
1387			{
1388				return handler.call(target, e);
1389			}
1390			if (target && target.parentNode)
1391				target = target.parentNode;
1392			else
1393				break;
1394		}
1395		return null;
1396	}
1397};
1398
1399BX.False = function() {return false;};
1400BX.DoNothing = function() {};
1401
1402// TODO: also check event handlers set via BX.bind()
1403BX.denyEvent = function(el, ev)
1404{
1405	deniedEvents.push([el, ev, el['on' + ev]]);
1406	el['on' + ev] = BX.DoNothing;
1407};
1408
1409BX.allowEvent = function(el, ev)
1410{
1411	for(var i=0, len=deniedEvents.length; i<len; i++)
1412	{
1413		if (deniedEvents[i][0] == el && deniedEvents[i][1] == ev)
1414		{
1415			el['on' + ev] = deniedEvents[i][2];
1416			BX.util.deleteFromArray(deniedEvents, i);
1417			return;
1418		}
1419	}
1420};
1421
1422BX.fixEventPageXY = function(event)
1423{
1424	BX.fixEventPageX(event);
1425	BX.fixEventPageY(event);
1426	return event;
1427};
1428
1429BX.fixEventPageX = function(event)
1430{
1431	if (event.pageX == null && event.clientX != null)
1432	{
1433		event.pageX =
1434			event.clientX +
1435			(document.documentElement && document.documentElement.scrollLeft || document.body && document.body.scrollLeft || 0) -
1436			(document.documentElement.clientLeft || 0);
1437	}
1438
1439	return event;
1440};
1441
1442BX.fixEventPageY = function(event)
1443{
1444	if (event.pageY == null && event.clientY != null)
1445	{
1446		event.pageY =
1447			event.clientY +
1448			(document.documentElement && document.documentElement.scrollTop || document.body && document.body.scrollTop || 0) -
1449			(document.documentElement.clientTop || 0);
1450	}
1451
1452	return event;
1453};
1454
1455BX.PreventDefault = function(e)
1456{
1457	if(!e) e = window.event;
1458	if(e.stopPropagation)
1459	{
1460		e.preventDefault();
1461		e.stopPropagation();
1462	}
1463	else
1464	{
1465		e.cancelBubble = true;
1466		e.returnValue = false;
1467	}
1468	return false;
1469};
1470
1471BX.eventReturnFalse = function(e)
1472{
1473	e=e||window.event;
1474	if (e && e.preventDefault) e.preventDefault();
1475	else e.returnValue = false;
1476	return false;
1477};
1478
1479BX.eventCancelBubble = function(e)
1480{
1481	e=e||window.event;
1482	if(e && e.stopPropagation)
1483		e.stopPropagation();
1484	else
1485		e.cancelBubble = true;
1486};
1487
1488/* custom events */
1489/*
1490	BX.addCustomEvent(eventObject, eventName, eventHandler) - set custom event handler for particular object
1491	BX.addCustomEvent(eventName, eventHandler) - set custom event handler for all objects
1492*/
1493BX.addCustomEvent = function(eventObject, eventName, eventHandler)
1494{
1495	/* shift parameters for short version */
1496	if (BX.type.isString(eventObject))
1497	{
1498		eventHandler = eventName;
1499		eventName = eventObject;
1500		eventObject = window;
1501	}
1502
1503	eventName = eventName.toUpperCase();
1504
1505	if (!customEvents[eventName])
1506		customEvents[eventName] = [];
1507
1508	customEvents[eventName].push(
1509		{
1510			handler: eventHandler,
1511			obj: eventObject
1512		}
1513	);
1514};
1515
1516BX.removeCustomEvent = function(eventObject, eventName, eventHandler)
1517{
1518	/* shift parameters for short version */
1519	if (BX.type.isString(eventObject))
1520	{
1521		eventHandler = eventName;
1522		eventName = eventObject;
1523		eventObject = window;
1524	}
1525
1526	eventName = eventName.toUpperCase();
1527
1528	if (!customEvents[eventName])
1529		return;
1530
1531	for (var i = 0, l = customEvents[eventName].length; i < l; i++)
1532	{
1533		if (!customEvents[eventName][i])
1534			continue;
1535		if (customEvents[eventName][i].handler == eventHandler && customEvents[eventName][i].obj == eventObject)
1536		{
1537			delete customEvents[eventName][i];
1538			return;
1539		}
1540	}
1541};
1542
1543// Warning! Don't use secureParams with DOM nodes in arEventParams
1544BX.onCustomEvent = function(eventObject, eventName, arEventParams, secureParams)
1545{
1546	/* shift parameters for short version */
1547	if (BX.type.isString(eventObject))
1548	{
1549		secureParams = arEventParams;
1550		arEventParams = eventName;
1551		eventName = eventObject;
1552		eventObject = window;
1553	}
1554
1555	eventName = eventName.toUpperCase();
1556
1557	if (!customEvents[eventName])
1558		return;
1559
1560	if (!arEventParams)
1561		arEventParams = [];
1562
1563	var h;
1564	for (var i = 0, l = customEvents[eventName].length; i < l; i++)
1565	{
1566		h = customEvents[eventName][i];
1567		if (!h || !h.handler)
1568			continue;
1569
1570		if (h.obj == window || /*eventObject == window || */h.obj == eventObject) //- only global event handlers will be called
1571		{
1572			h.handler.apply(eventObject, !!secureParams ? BX.clone(arEventParams) : arEventParams);
1573		}
1574	}
1575};
1576
1577BX.bindDebouncedChange = function(node, fn, fnInstant, timeout, ctx)
1578{
1579	ctx = ctx || window;
1580	timeout = timeout || 300;
1581
1582	var dataTag = 'bx-dc-previous-value';
1583	BX.data(node, dataTag, node.value);
1584
1585	var act = function(fn, val){
1586
1587		var pVal = BX.data(node, dataTag);
1588
1589		if(typeof pVal == 'undefined' || pVal != val){
1590			if(typeof ctx != 'object')
1591				fn(val);
1592			else
1593				fn.apply(ctx, [val]);
1594		}
1595	};
1596
1597	var actD = BX.debounce(function(){
1598		var val = node.value;
1599		act(fn, val);
1600		BX.data(node, dataTag, val);
1601	}, timeout);
1602
1603	BX.bind(node, 'keyup', actD);
1604	BX.bind(node, 'change', actD);
1605	BX.bind(node, 'input', actD);
1606
1607	if(BX.type.isFunction(fnInstant)){
1608
1609		var actI = function(){
1610			act(fnInstant, node.value);
1611		};
1612
1613		BX.bind(node, 'keyup', actI);
1614		BX.bind(node, 'change', actI);
1615		BX.bind(node, 'input', actI);
1616	}
1617}
1618
1619BX.parseJSON = function(data, context)
1620{
1621	var result = null;
1622	if (BX.type.isString(data))
1623	{
1624		try {
1625			if (data.indexOf("\n") >= 0)
1626				eval('result = ' + data);
1627			else
1628				result = (new Function("return " + data))();
1629		} catch(e) {
1630			BX.onCustomEvent(context, 'onParseJSONFailure', [data, context])
1631		}
1632	}
1633
1634	return result;
1635};
1636
1637/* ready */
1638BX.isReady = false;
1639BX.ready = function(handler)
1640{
1641	bindReady();
1642
1643	if (!BX.type.isFunction(handler))
1644	{
1645		BX.debug('READY: not a function! ', handler);
1646	}
1647	else
1648	{
1649		if (BX.isReady)
1650			handler.call(document);
1651		else if (readyList)
1652			readyList.push(handler);
1653	}
1654};
1655
1656BX.submit = function(obForm, action_name, action_value, onAfterSubmit)
1657{
1658	action_name = action_name || 'save';
1659	if (!obForm['BXFormSubmit_' + action_name])
1660	{
1661		obForm['BXFormSubmit_' + action_name] = obForm.appendChild(BX.create('INPUT', {
1662			'props': {
1663				'type': 'submit',
1664				'name': action_name,
1665				'value': action_value || 'Y'
1666			},
1667			'style': {
1668				'display': 'none'
1669			}
1670		}));
1671	}
1672
1673	if (obForm.sessid)
1674		obForm.sessid.value = BX.bitrix_sessid();
1675
1676	setTimeout(BX.delegate(function() {BX.fireEvent(this, 'click'); if (onAfterSubmit) onAfterSubmit();}, obForm['BXFormSubmit_' + action_name]), 10);
1677};
1678
1679BX.debounce = function(fn, timeout, ctx){
1680
1681	var timer = 0;
1682
1683	return function(){
1684
1685		ctx = ctx || this;
1686		var args = arguments;
1687
1688		clearTimeout(timer);
1689
1690		timer = setTimeout(function(){
1691			fn.apply(ctx, args);
1692		}, timeout);
1693	}
1694}
1695
1696BX.throttle = function(fn, timeout, ctx){
1697
1698	var timer = 0,
1699		args = null,
1700		invoke;
1701
1702	return function(){
1703
1704		ctx = ctx || this;
1705		args = arguments;
1706		invoke = true;
1707
1708		if(!timer){
1709			(function(){
1710
1711				if(invoke) {
1712					fn.apply(ctx, args);
1713					invoke = false;
1714					timer = setTimeout(arguments.callee, timeout);
1715				}
1716				else
1717					timer = null;
1718			})();
1719		}
1720
1721	};
1722}
1723
1724/* browser detection */
1725BX.browser = {
1726
1727	IsIE: function()
1728	{
1729		return bIE;
1730	},
1731
1732	IsIE6: function()
1733	{
1734		return (/MSIE 6/i.test(navigator.userAgent));
1735	},
1736
1737	IsIE7: function()
1738	{
1739		return (/MSIE 7/i.test(navigator.userAgent));
1740	},
1741
1742	IsIE8: function()
1743	{
1744		return (/MSIE 8/i.test(navigator.userAgent));
1745	},
1746
1747	IsIE9: function()
1748	{
1749		return !!document.documentMode && document.documentMode >= 9;
1750	},
1751
1752	IsIE10: function()
1753	{
1754		return !!document.documentMode && document.documentMode >= 10;
1755	},
1756
1757	IsIE11: function()
1758	{
1759		return BX.browser.DetectIeVersion() >= 11;
1760	},
1761
1762	IsOpera: function()
1763	{
1764		return bOpera;
1765	},
1766
1767	IsSafari: function()
1768	{
1769		return bSafari;
1770	},
1771
1772	IsFirefox: function()
1773	{
1774		return bFirefox;
1775	},
1776
1777	IsChrome: function()
1778	{
1779		return bChrome;
1780	},
1781
1782	IsMac: function()
1783	{
1784		return (/Macintosh/i.test(navigator.userAgent));
1785	},
1786
1787	IsAndroid: function()
1788	{
1789		return (/Android/i.test(navigator.userAgent));
1790	},
1791
1792	IsIOS: function()
1793	{
1794		return (/(iPad;)|(iPhone;)/i.test(navigator.userAgent));
1795	},
1796
1797	DetectIeVersion: function()
1798	{
1799		if(BX.browser.IsOpera() || BX.browser.IsSafari() || BX.browser.IsFirefox() || BX.browser.IsChrome())
1800		{
1801			return -1;
1802		}
1803
1804		var rv = -1;
1805		if (!!(window.MSStream) && !(window.ActiveXObject) && ("ActiveXObject" in window))
1806		{
1807			//Primary check for IE 11 based on ActiveXObject behaviour (please see http://msdn.microsoft.com/en-us
1807/library/ie/dn423948%28v=vs.85%29.aspx)
1808			rv = 11;
1809		}
1810		else if (BX.browser.IsIE10())
1811		{
1812			rv = 10;
1813		}
1814		else if (BX.browser.IsIE9())
1815		{
1816			rv = 9;
1817		}
1818		else if (BX.browser.IsIE())
1819		{
1820			rv = 8;
1821		}
1822
1823		if (rv == -1 || rv == 8)
1824		{
1825			var re;
1826			if (navigator.appName == "Microsoft Internet Explorer")
1827			{
1828				re = new RegExp("MSIE ([0-9]+[\.0-9]*)");
1829				if (re.exec(navigator.userAgent) != null)
1830					rv = parseFloat( RegExp.$1 );
1831			}
1832			else if (navigator.appName == "Netscape")
1833			{
1834				//Alternative check for IE 11
1835				rv = 11;
1836				re = new RegExp("Trident/.*rv:([0-9]+[\.0-9]*)");
1837				if (re.exec(navigator.userAgent) != null)
1838					rv = parseFloat( RegExp.$1 );
1839			}
1840		}
1841
1842		return rv;
1843	},
1844
1845	IsDoctype: function(pDoc)
1846	{
1847		pDoc = pDoc || document;
1848
1849		if (pDoc.compatMode)
1850			return (pDoc.compatMode == "CSS1Compat");
1851
1852		return (pDoc.documentElement && pDoc.documentElement.clientHeight);
1853	},
1854
1855	SupportLocalStorage: function()
1856	{
1857		return !!BX.localStorage && !!BX.localStorage.checkBrowser()
1858	},
1859
1860	addGlobalClass: function() {
1861
1862		var globalClass = "";
1863
1864		//Mobile
1865		if (BX.browser.IsIOS())
1866		{
1867			globalClass += " bx-ios";
1868		}
1869		else if (BX.browser.IsMac())
1870		{
1871			globalClass += " bx-mac";
1872		}
1873		else if (BX.browser.IsAndroid())
1874		{
1875			globalClass += " bx-android";
1876		}
1877
1878		globalClass += (BX.browser.IsIOS() || BX.browser.IsAndroid() ? " bx-touch" : " bx-no-touch");
1879		globalClass += (BX.browser.isRetina() ? " bx-retina" : " bx-no-retina");
1880
1881		//Desktop
1882		var ieVersion = -1;
1883		if (/AppleWebKit/.test(navigator.userAgent))
1884		{
1885			globalClass += " bx-chrome";
1886		}
1887		else if ((ieVersion = BX.browser.DetectIeVersion()) > 0)
1888		{
1889			globalClass += " bx-ie bx-ie" + ieVersion;
1890			if (ieVersion > 7 && ieVersion < 10 && !BX.browser.IsDoctype())
1891			{
1892				// it seems IE10 doesn't have any specific bugs like others event in quirks mode
1893				globalClass += " bx-quirks";
1894			}
1895		}
1896		else if (/Opera/.test(navigator.userAgent))
1897		{
1898			globalClass += " bx-opera";
1899		}
1900		else if (/Gecko/.test(navigator.userAgent))
1901		{
1902			globalClass += " bx-firefox";
1903		}
1904
1905		BX.addClass(document.documentElement, globalClass);
1906
1907		BX.browser.addGlobalClass = BX.DoNothing;
1908	},
1909
1910	isPropertySupported: function(jsProperty, bReturnCSSName)
1911	{
1912		if (!BX.type.isNotEmptyString(jsProperty))
1913			return false;
1914
1915		var property = jsProperty.indexOf("-") > -1 ? getJsName(jsProperty) : jsProperty;
1916		bReturnCSSName = !!bReturnCSSName;
1917
1918		var ucProperty = property.charAt(0).toUpperCase() + property.slice(1);
1919		var properties = (property + ' ' + ["Webkit", "Moz", "O", "ms"].join(ucProperty + " ") + ucProperty).split(" ");
1920		var obj = document.body || document.documentElement;
1921
1922		for (var i = 0; i < properties.length; i++)
1923		{
1924			var prop = properties[i];
1925			if (obj.style[prop] !== undefined)
1926			{
1927				var prefix = prop == property
1928							? ""
1929							: "-" + prop.substr(0, prop.length - property.length).toLowerCase() + "-";
1930				return bReturnCSSName ? prefix + getCssName(property) : prop;
1931			}
1932		}
1933
1934		function getCssName(propertyName)
1935		{
1936			return propertyName.replace(/([A-Z])/g, function() { return "-" + arguments[1].toLowerCase(); } )
1937		}
1938
1939		function getJsName(cssName)
1940		{
1941			var reg = /(\-([a-z]){1})/g;
1942			if (reg.test(cssName))
1943				return cssName.replace(reg, function () {return arguments[2].toUpperCase();});
1944			else
1945				return cssName;
1946		}
1947
1948		return false;
1949	},
1950
1951	addGlobalFeatures : function(features, prefix)
1952	{
1953		if (!BX.type.isArray(features))
1954			return;
1955
1956		var classNames = [];
1957		for (var i = 0; i < features.length; i++)
1958		{
1959			var support = !!BX.browser.isPropertySupported(features[i]);
1960			classNames.push( "bx-" + (support ? "" : "no-") + features[i].toLowerCase());
1961		}
1962		BX.addClass(document.documentElement, classNames.join(" "));
1963	},
1964
1965	isRetina : function()
1966	{
1967		return window.devicePixelRatio && window.devicePixelRatio >= 2;
1968	}
1969};
1970
1971/* low-level fx funcitons*/
1972BX.show = function(ob, displayType)
1973{
1974	if (ob.BXDISPLAY || !_checkDisplay(ob, displayType))
1975	{
1976		ob.style.display = ob.BXDISPLAY;
1977	}
1978};
1979
1980BX.hide = function(ob, displayType)
1981{
1982	if (!ob.BXDISPLAY)
1983		_checkDisplay(ob, displayType);
1984
1985	ob.style.display = 'none';
1986};
1987
1988BX.toggle = function(ob, values)
1989{
1990	if (!values && BX.type.isElementNode(ob))
1991	{
1992		var bShow = true;
1993		if (ob.BXDISPLAY)
1994			bShow = !_checkDisplay(ob);
1995		else
1996			bShow = ob.style.display == 'none';
1997
1998		if (bShow)
1999			BX.show(ob);
2000		else
2001			BX.hide(ob);
2002	}
2003	else if (BX.type.isArray(values))
2004	{
2005		for (var i=0,len=values.length; i<len; i++)
2006		{
2007			if (ob == values[i])
2008			{
2009				ob = values[i==len-1 ? 0 : i+1];
2010				break;
2011			}
2012		}
2013		if (i==len)
2014			ob = values[0];
2015	}
2016
2017	return ob;
2018};
2019
2020/* some useful util functions */
2021
2022BX.util = {
2023	array_values: function(ar)
2024	{
2025		if (!BX.type.isArray(ar))
2026			return BX.util._array_values_ob(ar);
2027		var arv = [];
2028		for(var i=0,l=ar.length;i<l;i++)
2029			if (ar[i] !== null && typeof ar[i] != 'undefined')
2030				arv.push(ar[i]);
2031		return arv;
2032	},
2033
2034	_array_values_ob: function(ar)
2035	{
2036		var arv = [];
2037		for(var i in ar)
2038			if (ar[i] !== null && typeof ar[i] != 'undefined')
2039				arv.push(ar[i]);
2040		return arv;
2041	},
2042
2043	array_keys: function(ar)
2044	{
2045		if (!BX.type.isArray(ar))
2046			return BX.util._array_keys_ob(ar);
2047		var arv = [];
2048		for(var i=0,l=ar.length;i<l;i++)
2049			if (ar[i] !== null && typeof ar[i] != 'undefined')
2050				arv.push(i);
2051		return arv;
2052	},
2053
2054	_array_keys_ob: function(ar)
2055	{
2056		var arv = [];
2057		for(var i in ar)
2058			if (ar[i] !== null && typeof ar[i] != 'undefined')
2059				arv.push(i);
2060		return arv;
2061	},
2062
2063	array_merge: function(first, second)
2064	{
2065		if (!BX.type.isArray(first)) first = [];
2066		if (!BX.type.isArray(second)) second = [];
2067
2068		var i = first.length, j = 0;
2069
2070		if (typeof second.length === "number")
2071		{
2072			for (var l = second.length; j < l; j++)
2073			{
2074				first[i++] = second[j];
2075			}
2076		}
2077		else
2078		{
2079			while (second[j] !== undefined)
2080			{
2081				first[i++] = second[j++];
2082			}
2083		}
2084
2085		first.length = i;
2086
2087		return first;
2088	},
2089
2090	array_unique: function(ar)
2091	{
2092		var i=0,j,len=ar.length;
2093		if(len<2) return ar;
2094
2095		for (; i<len-1;i++)
2096		{
2097			for (j=i+1; j<len;j++)
2098			{
2099				if (ar[i]==ar[j])
2100				{
2101					ar.splice(j--,1); len--;
2102				}
2103			}
2104		}
2105
2106		return ar;
2107	},
2108
2109	in_array: function(needle, haystack)
2110	{
2111		for(var i=0; i<haystack.length; i++)
2112		{
2113			if(haystack[i] == needle)
2114				return true;
2115		}
2116		return false;
2117	},
2118
2119	array_search: function(needle, haystack)
2120	{
2121		for(var i=0; i<haystack.length; i++)
2122		{
2123			if(haystack[i] == needle)
2124				return i;
2125		}
2126		return -1;
2127	},
2128
2129	object_search_key: function(needle, haystack)
2130	{
2131		if (typeof haystack[needle] != 'undefined')
2132			return haystack[needle];
2133
2134		for(var i in haystack)
2135		{
2136			if (typeof haystack[i] == "object")
2137			{
2138				var result = BX.util.object_search_key(needle, haystack[i]);
2139				if (result !== false)
2140					return result;
2141			}
2142		}
2143		return false;
2144	},
2145
2146	trim: function(s)
2147	{
2148		if (BX.type.isString(s))
2149			return s.replace(r.ltrim, '').replace(r.rtrim, '');
2150		else
2151			return s;
2152	},
2153
2154	urlencode: function(s){return encodeURIComponent(s);},
2155
2156	// it may also be useful. via sVD.
2157	deleteFromArray: function(ar, ind) {return ar.slice(0, ind).concat(ar.slice(ind + 1));},
2158	insertIntoArray: function(ar, ind, el) {return ar.slice(0, ind).concat([el]).concat(ar.slice(ind));},
2159
2160	htmlspecialchars: function(str)
2161	{
2162		if(!str.replace) return str;
2163
2164		return str.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
2165	},
2166
2167	htmlspecialcharsback: function(str)
2168	{
2169		if(!str.replace) return str;
2170
2171		return str.replace(/\&quot;/g, '"').replace(/&#39;/g, "'").replace(/\&lt;/g, '<').replace(/\&gt;/g, '>').replace(/\&amp;/g, '&');
2172	},
2173
2174	// Quote regular expression characters plus an optional character
2175	preg_quote: function(str, delimiter)
2176	{
2177		if(!str.replace)
2178			return str;
2179		return str.replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
2180	},
2181
2182	jsencode: function(str)
2183	{
2184		if (!str || !str.replace)
2185			return str;
2186
2187		var escapes =
2188		[
2189			{ c: "\\\\", r: "\\\\" }, // should be first
2190			{ c: "\\t", r: "\\t" },
2191			{ c: "\\n", r: "\\n" },
2192			{ c: "\\r", r: "\\r" },
2193			{ c: "\"", r: "\\\"" },
2194			{ c: "'", r: "\\'" },
2195			{ c: "<", r: "\\x3C" },
2196			{ c: ">", r: "\\x3E" },
2197			{ c: "\\u2028", r: "\\u2028" },
2198			{ c: "\\u2029", r: "\\u2029" }
2199		];
2200		for (var i = 0; i < escapes.length; i++)
2201			str = str.replace(new RegExp(escapes[i].c, 'g'), escapes[i].r);
2202		return str;
2203	},
2204
2205	str_pad: function(input, pad_length, pad_string, pad_type)
2206	{
2207		pad_string = pad_string || ' ';
2208		pad_type = pad_type || 'right';
2209		input = input.toString();
2210
2211		if (pad_type == 'left')
2212			return BX.util.str_pad_left(input, pad_length, pad_string);
2213		else
2214			return BX.util.str_pad_right(input, pad_length, pad_string);
2215
2216	},
2217
2218	str_pad_left: function(input, pad_length, pad_string)
2219	{
2220		var i = input.length, q=pad_string.length;
2221		if (i >= pad_length) return input;
2222
2223		for(;i<pad_length;i+=q)
2224			input = pad_string + input;
2225
2226		return input;
2227	},
2228
2229	str_pad_right: function(input, pad_length, pad_string)
2230	{
2231		var i = input.length, q=pad_string.length;
2232		if (i >= pad_length) return input;
2233
2234		for(;i<pad_length;i+=q)
2235			input += pad_string;
2236
2237		return input;
2238	},
2239
2240	strip_tags: function(str)
2241	{
2242		return str.split(/<[^>]+>/g).join('');
2243	},
2244
2245	strip_php_tags: function(str)
2246	{
2247		return str.replace(/<\?(.|[\r\n])*?\?>/g, '');
2248	},
2249
2250	popup: function(url, width, height)
2251	{
2252		var w, h;
2253		if(BX.browser.IsOpera())
2254		{
2255			w = document.body.offsetWidth;
2256			h = document.body.offsetHeight;
2257		}
2258		else
2259		{
2260			w = screen.width;
2261			h = screen.height;
2262		}
2263		return window.open(url, '', 'status=no,scrollbars=yes,resizable=yes,width='+width+',height='+height+',top='+Math.floor((h - height)/2-14)+',left='+Math.floor((w - width)/2-5));
2264	},
2265
2266	// BX.util.objectSort(object, sortBy, sortDir) - Sort object by property
2267	// function params: 1 - object for sort, 2 - sort by property, 3 - sort direction (asc/desc)
2268	// return: sort array [[objectElement], [objectElement]] in sortDir direction
2269
2270	// example: BX.util.objectSort({'L1': {'name': 'Last'}, 'F1': {'name': 'First'}}, 'name', 'asc');
2271	// return: [{'name' : 'First'}, {'name' : 'Last'}]
2272	objectSort: function(object, sortBy, sortDir)
2273	{
2274		sortDir = sortDir == 'asc'? 'asc': 'desc';
2275
2276		var arItems = [], i;
2277		for (i in object)
2278		{
2279			if (object.hasOwnProperty(i) && object[i][sortBy])
2280			{
2281				arItems.push([i, object[i][sortBy]]);
2282			}
2283		}
2284
2285		if (sortDir == 'asc')
2286		{
2287			arItems.sort(function(i, ii) {
2288				var s1, s2;
2289				if (!isNaN(i[1]) && !isNaN(ii[1]))
2290				{
2291					s1 = parseInt(i[1]);
2292					s2 = parseInt(ii[1]);
2293				}
2294				else
2295				{
2296					s1 = i[1].toString().toLowerCase();
2297					s2 = ii[1].toString().toLowerCase();
2298				}
2299
2300				if (s1 > s2)
2301					return 1;
2302				else if (s1 < s2)
2303					return -1;
2304				else
2305					return 0;
2306			});
2307		}
2308		else
2309		{
2310			arItems.sort(function(i, ii) {
2311				var s1, s2;
2312				if (!isNaN(i[1]) && !isNaN(ii[1]))
2313				{
2314					s1 = parseInt(i[1]);
2315					s2 = parseInt(ii[1]);
2316				}
2317				else
2318				{
2319					s1 = i[1].toString().toLowerCase();
2320					s2 = ii[1].toString().toLowerCase();
2321				}
2322				if (s1 < s2)
2323					return 1;
2324				else if (s1 > s2)
2325					return -1;
2326				else
2327					return 0;
2328			});
2329		}
2330
2331		var arReturnArray = Array();
2332		for (i = 0; i < arItems.length; i++)
2333		{
2334			arReturnArray.push(object[arItems[i][0]]);
2335		}
2336
2337		return arReturnArray;
2338	},
2339
2340	// #fdf9e5 => {r=253, g=249, b=229}
2341	hex2rgb: function(color)
2342	{
2343		var rgb = color.replace(/[# ]/g,"").replace(/^(.)(.)(.)$/,'$1$1$2$2$3$3').match(/.{2}/g);
2344		for (var i=0;  i<3; i++)
2345		{
2346			rgb[i] = parseInt(rgb[i], 16);
2347		}
2348		return {'r':rgb[0],'g':rgb[1],'b':rgb[2]};
2349	},
2350
2351	remove_url_param: function(url, param)
2352	{
2353		if (BX.type.isArray(param))
2354		{
2355			for (var i=0; i<param.length; i++)
2356			{
2357				url = BX.util.remove_url_param(url, param[i]);
2358			}
2359		}
2360		else
2361		{
2362			var pos, params;
2363			if((pos = url.indexOf('?')) >= 0 && pos != url.length-1)
2364			{
2365				params = url.substr(pos + 1);
2366				url = url.substr(0, pos + 1);
2367
2368				params = params.replace(new RegExp('(^|&)'+param+'=[^&#]*', 'i'), '');
2369				params = params.replace(/^&/, '');
2370				url = url + params;
2371			}
2372		}
2373
2374		return url;
2375	},
2376
2377	/*
2378	{'param1': 'value1', 'param2': 'value2'}
2379	 */
2380	add_url_param: function(url, params)
2381	{
2382		var param;
2383		var additional = '';
2384		var hash = '';
2385		var pos;
2386
2387		for(param in params)
2388		{
2389			url = this.remove_url_param(url, param);
2390			additional += (additional != ''? '&':'') + param + '=' + params[param];
2391		}
2392
2393		if((pos = url.indexOf('#')) >= 0)
2394		{
2395			hash = url.substr(pos);
2396			url = url.substr(0, pos);
2397		}
2398
2399		if((pos = url.indexOf('?')) >= 0)
2400		{
2401			url = url + (pos != url.length-1? '&' : '') + additional + hash;
2402		}
2403		else
2404		{
2405			url = url + '?' + additional + hash;
2406		}
2407
2408		return url;
2409	},
2410
2411	even: function(digit)
2412	{
2413		return (parseInt(digit) % 2 == 0);
2414	},
2415
2416	hashCode: function(str)
2417	{
2418		if(!BX.type.isNotEmptyString(str))
2419		{
2420			return 0;
2421		}
2422
2423		var hash = 0;
2424		for (var i = 0; i < str.length; i++)
2425		{
2426			var c = str.charCodeAt(i);
2427			hash = ((hash << 5) - hash) + c;
2428			hash = hash & hash;
2429		}
2430		return hash;
2431	},
2432
2433	getRandomString: function (length) {
2434		var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
2435		var charQty = chars.length;
2436
2437		length = parseInt(length);
2438		if(isNaN(length) || length <= 0)
2439		{
2440			length = 8;
2441		}
2442
2443		var result = "";
2444		for (var i = 0; i < length; i++)
2445		{
2446			result += chars.charAt(Math.floor(Math.random() * charQty));
2447		}
2448		return result;
2449	},
2450
2451	number_format: function(number, decimals, dec_point, thousands_sep)
2452	{
2453		var i, j, kw, kd, km, sign = '';
2454		decimals = Math.abs(decimals);
2455		if (isNaN(decimals) || decimals < 0)
2456		{
2457			decimals = 2;
2458		}
2459		dec_point = dec_point || ',';
2460		thousands_sep = thousands_sep || '.';
2461
2462		number = (+number || 0).toFixed(decimals);
2463		if (number < 0)
2464		{
2465			sign = '-';
2466			number = -number;
2467		}
2468
2469		i = parseInt(number, 10) + '';
2470		j = (i.length > 3 ? i.length % 3 : 0);
2471
2472		km = (j ? i.substr(0, j) + thousands_sep : '');
2473		kw = i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands_sep);
2474		kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).replace(/-/, '0').slice(2) : '');
2475
2476		return sign + km + kw + kd;
2477	},
2478
2479	getExtension: function (url)
2480	{
2481		url = url || "";
2482		var items = url.split("?")[0].split(".");
2483		return items[items.length-1].toLowerCase();
2484	},
2485	addObjectToForm: function(object, form, prefix)
2486	{
2487		if(!BX.type.isString(prefix))
2488		{
2489			prefix = "";
2490		}
2491
2492		for(var key in object)
2493		{
2494			if(!object.hasOwnProperty(key))
2495			{
2496				continue;
2497			}
2498
2499			var value = object[key];
2500			var name = prefix !== "" ? (prefix + "[" + key + "]") : key;
2501			if(BX.type.isArray(value))
2502			{
2503				for(var i = 0; i < value.length; i++)
2504				{
2505					BX.util.addObjectToForm(value[i], form, (name + "[" + i.toString() + "]"));
2506				}
2507			}
2508			else if(BX.type.isPlainObject(value))
2509			{
2510				BX.util.addObjectToForm(value, form, name);
2511			}
2512			else
2513			{
2514				value = BX.type.isFunction(value.toString) ? value.toString() : "";
2515				if(value !== "")
2516				{
2517					form.appendChild(BX.create("INPUT", { attrs: { type: "hidden", name: name, value: value } }));
2518				}
2519			}
2520		}
2521	},
2522
2523	observe: function(object, enable)
2524	{
2525		if (!BX.browser.IsChrome() || typeof(object) != 'object')
2526			return false;
2527
2528		enable = enable !== false;
2529
2530		var observer = function(options)
2531		{
2532			options.forEach(function(option){
2533				var groupName = option.name + ' changed';
2534				console.groupCollapsed(groupName);
2535				console.log('Old value: ', option.oldValue);
2536				console.log('New value: ', option.object[option.name]);
2537				console.groupEnd(groupName);
2538			});
2539		}
2540		if (enable)
2541		{
2542			Object.observe(object, observer);
2543		}
2544		else
2545		{
2546			Object.unobserve(object, observer);
2547		}
2548
2549		return enable;
2550	}
2551};
2552
2553BX.type = {
2554	isString: function(item) {
2555		return item === '' ? true : (item ? (typeof (item) == "string" || item instanceof String) : false);
2556	},
2557	isNotEmptyString: function(item) {
2558		return BX.type.isString(item) ? item.length > 0 : false;
2559	},
2560	isBoolean: function(item) {
2561		return item === true || item === false;
2562	},
2563	isNumber: function(item) {
2564		return item === 0 ? true : (item ? (typeof (item) == "number" || item instanceof Number) : false);
2565	},
2566	isFunction: function(item) {
2567		return item === null ? false : (typeof (item) == "function" || item instanceof Function);
2568	},
2569	isElementNode: function(item) {
2570		//document.body.ELEMENT_NODE;
2571		return item && typeof (item) == "object" && "nodeType" in item && item.nodeType == 1 && item.tagName && item.tagName.toUpperCase() != 'SCRIPT' && item.tagName.toUpperCase() != 'STYLE' && item.tagName.toUpperCase() != 'LINK';
2572	},
2573	isDomNode: function(item) {
2574		return item && typeof (item) == "object" && "nodeType" in item;
2575	},
2576	isArray: function(item) {
2577		return item && Object.prototype.toString.call(item) == "[object Array]";
2578	},
2579	isDate : function(item) {
2580		return item && Object.prototype.toString.call(item) == "[object Date]";
2581	},
2582	isPlainObject: function(item)
2583	{
2584		if(!item || typeof(item) !== "object" || item.nodeType)
2585		{
2586			return false;
2587		}
2588
2589		var hasProp = Object.prototype.hasOwnProperty;
2590		try
2591		{
2592			if ( item.constructor && !hasProp.call(item, "constructor") && !hasProp.call(item.constructor.prototype, "isPrototypeOf") )
2593			{
2594				return false;
2595			}
2596		}
2597		catch (e)
2598		{
2599			return false;
2600		}
2601
2602		var key;
2603		for (key in item)
2604		{
2605		}
2606		return typeof(key) === "undefined" || hasProp.call(item, key);
2607	}
2608};
2609
2610BX.isNodeInDom = function(node, doc)
2611{
2612	return node === (doc || document) ? true :
2613		(node.parentNode ? BX.isNodeInDom(node.parentNode) : false);
2614};
2615
2616BX.isNodeHidden = function(node)
2617{
2618	if (node === document)
2619		return false;
2620	else if (BX.style(node, 'display') == 'none')
2621		return true;
2622	else
2623		return (node.parentNode ? BX.isNodeHidden(node.parentNode) : true);
2624};
2625
2626BX.evalPack = function(code)
2627{
2628	while (code.length > 0)
2629	{
2630		var c = code.shift();
2631
2632		if (c.TYPE == 'SCRIPT_EXT' || c.TYPE == 'SCRIPT_SRC')
2633		{
2634			BX.loadScript(c.DATA, function() {BX.evalPack(code)});
2635			return;
2636		}
2637		else if (c.TYPE == 'SCRIPT')
2638		{
2639			BX.evalGlobal(c.DATA);
2640		}
2641	}
2642};
2643
2644BX.evalGlobal = function(data)
2645{
2646	if (data)
2647	{
2648		var head = document.getElementsByTagName("head")[0] || document.documentElement,
2649			script = document.createElement("script");
2650
2651		script.type = "text/javascript";
2652
2653		if (!BX.browser.IsIE())
2654		{
2655			script.appendChild(document.createTextNode(data));
2656		}
2657		else
2658		{
2659			script.text = data;
2660		}
2661
2662		head.insertBefore(script, head.firstChild);
2663		head.removeChild(script);
2664	}
2665};
2666
2667BX.processHTML = function(data, scriptsRunFirst)
2668{
2669	var matchScript, matchStyle, matchSrc, matchHref, matchType, scripts = [], styles = [];
2670	var textIndexes = [];
2671	var lastIndex = r.script.lastIndex = r.script_end.lastIndex = 0;
2672
2673	while ((matchScript = r.script.exec(data)) !== null)
2674	{
2675		r.script_end.lastIndex = r.script.lastIndex;
2676		var matchScriptEnd = r.script_end.exec(data);
2677		if (matchScriptEnd === null)
2678		{
2679			break;
2680		}
2681
2682		// skip script tags of special types
2683		var skipTag = false;
2684		if ((matchType = matchScript[1].match(r.script_type)) !== null)
2685		{
2686			if(matchType[1] == 'text/html' || matchType[1] == 'text/template')
2687				skipTag = true;
2688		}
2689
2690		if(skipTag)
2691		{
2692			textIndexes.push([lastIndex, r.script_end.lastIndex - lastIndex]);
2693		}
2694		else
2695		{
2696			textIndexes.push([lastIndex, matchScript.index - lastIndex]);
2697
2698			var bRunFirst = scriptsRunFirst || (matchScript[1].indexOf('bxrunfirst') != '-1');
2699
2700			if ((matchSrc = matchScript[1].match(r.script_src)) !== null)
2701			{
2702				scripts.push({"bRunFirst": bRunFirst, "isInternal": false, "JS": matchSrc[1]});
2703			}
2704			else
2705			{
2706				var start = matchScript.index + matchScript[0].length;
2707				var js = data.substr(start, matchScriptEnd.index-start);
2708
2709				scripts.push({"bRunFirst": bRunFirst, "isInternal": true, "JS": js});
2710			}
2711		}
2712
2713		lastIndex = matchScriptEnd.index + 9;
2714		r.script.lastIndex = lastIndex;
2715	}
2716
2717	textIndexes.push([lastIndex, lastIndex === 0 ? data.length : data.length - lastIndex]);
2718	var pureData = "";
2719	for (var i = 0, length = textIndexes.length; i < length; i++)
2720	{
2721		pureData += data.substr(textIndexes[i][0], textIndexes[i][1]);
2722	}
2723
2724	while ((matchStyle = pureData.match(r.style)) !== null)
2725	{
2726		if ((matchHref = matchStyle[0].match(r.style_href)) !== null && matchStyle[0].indexOf('media="') < 0)
2727		{
2728			styles.push(matchHref[1]);
2729		}
2730
2731		pureData = pureData.replace(matchStyle[0], '');
2732	}
2733
2734	return {'HTML': pureData, 'SCRIPT': scripts, 'STYLE': styles};
2735};
2736
2737BX.garbage = function(call, thisObject)
2738{
2739	garbageCollectors.push({callback: call, context: thisObject});
2740};
2741
2742/* window pos functions */
2743
2744BX.GetDocElement = function (pDoc)
2745{
2746	pDoc = pDoc || document;
2747	return (BX.browser.IsDoctype(pDoc) ? pDoc.documentElement : pDoc.body);
2748};
2749
2750BX.GetContext = function(node)
2751{
2752	if (BX.type.isElementNode(node))
2753		return node.ownerDocument.parentWindow || node.ownerDocument.defaultView || window;
2754	else if (BX.type.isDomNode(node))
2755		return node.parentWindow || node.defaultView || window;
2756	else
2757		return window;
2758};
2759
2760BX.GetWindowInnerSize = function(pDoc)
2761{
2762	var width, height;
2763
2764	pDoc = pDoc || document;
2765
2766	if (window.innerHeight) // all except Explorer
2767	{
2768		width = BX.GetContext(pDoc).innerWidth;
2769		height = BX.GetContext(pDoc).innerHeight;
2770	}
2771	else if (pDoc.documentElement && (pDoc.documentElement.clientHeight || pDoc.documentElement.clientWidth)) // Explorer 6 Strict Mode
2772	{
2773		width = pDoc.documentElement.clientWidth;
2774		height = pDoc.documentElement.clientHeight;
2775	}
2776	else if (pDoc.body) // other Explorers
2777	{
2778		width = pDoc.body.clientWidth;
2779		height = pDoc.body.clientHeight;
2780	}
2781	return {innerWidth : width, innerHeight : height};
2782};
2783
2784BX.GetWindowScrollPos = function(pDoc)
2785{
2786	var left, top;
2787
2788	pDoc = pDoc || document;
2789
2790	if (window.pageYOffset) // all except Explorer
2791	{
2792		left = BX.GetContext(pDoc).pageXOffset;
2793		top = BX.GetContext(pDoc).pageYOffset;
2794	}
2795	else if (pDoc.documentElement && (pDoc.documentElement.scrollTop || pDoc.documentElement.scrollLeft)) // Explorer 6 Strict
2796	{
2797		left = pDoc.documentElement.scrollLeft;
2798		top = pDoc.documentElement.scrollTop;
2799	}
2800	else if (pDoc.body) // all other Explorers
2801	{
2802		left = pDoc.body.scrollLeft;
2803		top = pDoc.body.scrollTop;
2804	}
2805	return {scrollLeft : left, scrollTop : top};
2806};
2807
2808BX.GetWindowScrollSize = function(pDoc)
2809{
2810	var width, height;
2811	if (!pDoc)
2812		pDoc = document;
2813
2814	if ( (pDoc.compatMode && pDoc.compatMode == "CSS1Compat"))
2815	{
2816		width = pDoc.documentElement.scrollWidth;
2817		height = pDoc.documentElement.scrollHeight;
2818	}
2819	else
2820	{
2821		if (pDoc.body.scrollHeight > pDoc.body.offsetHeight)
2822			height = pDoc.body.scrollHeight;
2823		else
2824			height = pDoc.body.offsetHeight;
2825
2826		if (pDoc.body.scrollWidth > pDoc.body.offsetWidth ||
2827			(pDoc.compatMode && pDoc.compatMode == "BackCompat") ||
2828			(pDoc.documentElement && !pDoc.documentElement.clientWidth)
2829		)
2830			width = pDoc.body.scrollWidth;
2831		else
2832			width = pDoc.body.offsetWidth;
2833	}
2834	return {scrollWidth : width, scrollHeight : height};
2835};
2836
2837BX.GetWindowSize = function(pDoc)
2838{
2839	var innerSize = this.GetWindowInnerSize(pDoc);
2840	var scrollPos = this.GetWindowScrollPos(pDoc);
2841	var scrollSize = this.GetWindowScrollSize(pDoc);
2842
2843	return  {
2844		innerWidth : innerSize.innerWidth, innerHeight : innerSize.innerHeight,
2845		scrollLeft : scrollPos.scrollLeft, scrollTop : scrollPos.scrollTop,
2846		scrollWidth : scrollSize.scrollWidth, scrollHeight : scrollSize.scrollHeight
2847	};
2848};
2849
2850BX.scrollTop = function(node, val){
2851	if(typeof val != 'undefined'){
2852
2853		if(node == window){
2854			throw new Error('scrollTop() for window is not implemented');
2855		}else
2856			node.scrollTop = parseInt(val);
2857
2858	}else{
2859
2860		if(node == window)
2861			return BX.GetWindowScrollPos().scrollTop;
2862
2863		return node.scrollTop;
2864	}
2865}
2866
2867BX.scrollLeft = function(node, val){
2868	if(typeof val != 'undefined'){
2869
2870		if(node == window){
2871			throw new Error('scrollLeft() for window is not implemented');
2872		}else
2873			node.scrollLeft = parseInt(val);
2874
2875	}else{
2876
2877		if(node == window)
2878			return BX.GetWindowScrollPos().scrollLeft;
2879
2880		return node.scrollLeft;
2881	}
2882}
2883
2884BX.hide_object = function(ob)
2885{
2886	ob = BX(ob);
2887	ob.style.position = 'absolute';
2888	ob.style.top = '-1000px';
2889	ob.style.left = '-1000px';
2890	ob.style.height = '10px';
2891	ob.style.width = '10px';
2892};
2893
2894BX.is_relative = function(el)
2895{
2896	var p = BX.style(el, 'position');
2897	return p == 'relative' || p == 'absolute';
2898};
2899
2900BX.is_float = function(el)
2901{
2902	var p = BX.style(el, 'float');
2903	return p == 'right' || p == 'left';
2904};
2905
2906BX.is_fixed = function(el)
2907{
2908	var p = BX.style(el, 'position');
2909	return p == 'fixed';
2910};
2911
2912BX.pos = function(el, bRelative)
2913{
2914	var r = { top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 };
2915	bRelative = !!bRelative;
2916	if (!el)
2917		return r;
2918	if (typeof (el.getBoundingClientRect) != "undefined" && el.ownerDocument == document && !bRelative)
2919	{
2920		var clientRect = {};
2921
2922		// getBoundingClientRect can return undefined and generate exception in some cases in IE8.
2923		try
2924		{
2925			clientRect = el.getBoundingClientRect();
2926		}
2927		catch(e)
2928		{
2929			clientRect =
2930			{
2931				top: el.offsetTop,
2932				left: el.offsetLeft,
2933				width: el.offsetWidth,
2934				height: el.offsetHeight,
2935				right: el.offsetLeft + el.offsetWidth,
2936				bottom: el.offsetTop + el.offsetHeight
2937			};
2938		}
2939
2940		var root = document.documentElement;
2941		var body = document.body;
2942
2943		r.top = clientRect.top + (root.scrollTop || body.scrollTop);
2944		r.left = clientRect.left + (root.scrollLeft || body.scrollLeft);
2945		r.width = clientRect.right - clientRect.left;
2946		r.height = clientRect.bottom - clientRect.top;
2947		r.right = clientRect.right + (root.scrollLeft || body.scrollLeft);
2948		r.bottom = clientRect.bottom + (root.scrollTop || body.scrollTop);
2949	}
2950	else
2951	{
2952		var x = 0, y = 0, w = el.offsetWidth, h = el.offsetHeight;
2953		var first = true;
2954		for (; el != null; el = el.offsetParent)
2955		{
2956			if (!first && bRelative && BX.is_relative(el))
2957				break;
2958
2959			x += el.offsetLeft;
2960			y += el.offsetTop;
2961			if (first)
2962			{
2963				first = false;
2964				continue;
2965			}
2966
2967			var elBorderLeftWidth = parseInt(BX.style(el, 'border-left-width')),
2968				elBorderTopWidth = parseInt(BX.style(el, 'border-top-width'));
2969
2970			if (!isNaN(elBorderLeftWidth) && elBorderLeftWidth > 0)
2971				x += elBorderLeftWidth;
2972			if (!isNaN(elBorderTopWidth) && elBorderTopWidth > 0)
2973				y += elBorderTopWidth;
2974		}
2975
2976		r.top = y;
2977		r.left = x;
2978		r.width = w;
2979		r.height = h;
2980		r.right = r.left + w;
2981		r.bottom = r.top + h;
2982	}
2983
2984	for(var i in r)
2985	{
2986		if(r.hasOwnProperty(i))
2987		{
2988			r[i] = parseInt(r[i]);
2989		}
2990	}
2991
2992	return r;
2993};
2994
2995BX.width = function(node, val){
2996	if(typeof val != 'undefined')
2997		BX.style(node, 'width', parseInt(val)+'px');
2998	else{
2999
3000		if(node == window)
3001			return window.innerWidth;
3002
3003		//return parseInt(BX.style(node, 'width'));
3004		return BX.pos(node).width;
3005	}
3006}
3007
3008BX.height = function(node, val){
3009	if(typeof val != 'undefined')
3010		BX.style(node, 'height', parseInt(val)+'px');
3011	else{
3012
3013		if(node == window)
3014			return window.innerHeight;
3015
3016		//return parseInt(BX.style(node, 'height'));
3017		return BX.pos(node).height;
3018	}
3019}
3020
3021BX.align = function(pos, w, h, type)
3022{
3023	if (type)
3024		type = type.toLowerCase();
3025	else
3026		type = '';
3027
3028	var pDoc = document;
3029	if (BX.type.isElementNode(pos))
3030	{
3031		pDoc = pos.ownerDocument;
3032		pos = BX.pos(pos);
3033	}
3034
3035	var x = pos["left"], y = pos["bottom"];
3036
3037	var scroll = BX.GetWindowScrollPos(pDoc);
3038	var size = BX.GetWindowInnerSize(pDoc);
3039
3040	if((size.innerWidth + scroll.scrollLeft) - (pos["left"] + w) < 0)
3041	{
3042		if(pos["right"] - w >= 0 )
3043			x = pos["right"] - w;
3044		else
3045			x = scroll.scrollLeft;
3046	}
3047
3048	if(((size.innerHeight + scroll.scrollTop) - (pos["bottom"] + h) < 0) || ~type.indexOf('top'))
3049	{
3050		if(pos["top"] - h >= 0 || ~type.indexOf('top'))
3051			y = pos["top"] - h;
3052		else
3053			y = scroll.scrollTop;
3054	}
3055
3056	return {'left':x, 'top':y};
3057};
3058
3059BX.scrollToNode = function(node)
3060{
3061	var obNode = BX(node);
3062
3063	if (obNode.scrollIntoView)
3064		obNode.scrollIntoView(true);
3065	else
3066	{
3067		var arNodePos = BX.pos(obNode);
3068		window.scrollTo(arNodePos.left, arNodePos.top);
3069	}
3070};
3071
3072/* non-xhr loadings */
3073BX.showWait = function(node, msg)
3074{
3075	node = BX(node) || document.body || document.documentElement;
3076	msg = msg || BX.message('JS_CORE_LOADING');
3077
3078	var container_id = node.id || Math.random();
3079
3080	var obMsg = node.bxmsg = document.body.appendChild(BX.create('DIV', {
3081		props: {
3082			id: 'wait_' + container_id,
3083			className: 'bx-core-waitwindow'
3084		},
3085		text: msg
3086	}));
3087
3088	setTimeout(BX.delegate(_adjustWait, node), 10);
3089
3090	lastWait[lastWait.length] = obMsg;
3091	return obMsg;
3092};
3093
3094BX.closeWait = function(node, obMsg)
3095{
3096	if(node && !obMsg)
3097		obMsg = node.bxmsg;
3098	if(node && !obMsg && BX.hasClass(node, 'bx-core-waitwindow'))
3099		obMsg = node;
3100	if(node && !obMsg)
3101		obMsg = BX('wait_' + node.id);
3102	if(!obMsg)
3103		obMsg = lastWait.pop();
3104
3105	if (obMsg && obMsg.parentNode)
3106	{
3107		for (var i=0,len=lastWait.length;i<len;i++)
3108		{
3109			if (obMsg == lastWait[i])
3110			{
3111				lastWait = BX.util.deleteFromArray(lastWait, i);
3112				break;
3113			}
3114		}
3115
3116		obMsg.parentNode.removeChild(obMsg);
3117		if (node) node.bxmsg = null;
3118		BX.cleanNode(obMsg, true);
3119	}
3120};
3121
3122BX.setJSList = function(scripts)
3123{
3124	if (BX.type.isArray(scripts))
3125	{
3126		jsList = scripts;
3127	}
3128};
3129
3130BX.getJSList = function()
3131{
3132	initJsList();
3133	return jsList;
3134};
3135
3136BX.setCSSList = function(scripts)
3137{
3138	if (BX.type.isArray(scripts))
3139	{
3140		cssList = scripts;
3141	}
3142};
3143
3144BX.getCSSList = function()
3145{
3146	initCssList();
3147	return cssList;
3148};
3149
3150BX.getJSPath = function(js)
3151{
3152	return js.replace(/^(http[s]*:)*\/\/[^\/]+/i, '');
3153};
3154
3155BX.getCSSPath = function(css)
3156{
3157	return css.replace(/^(http[s]*:)*\/\/[^\/]+/i, '');
3158};
3159
3160BX.getCDNPath = function(path)
3161{
3162	return path;
3163};
3164
3165BX.loadScript = function(script, callback, doc)
3166{
3167	if (!BX.isReady)
3168	{
3169		var _args = arguments;
3170		BX.ready(function() {
3171			BX.loadScript.apply(this, _args);
3172		});
3173		return;
3174	}
3175
3176	doc = doc || document;
3177
3178	if (BX.type.isString(script))
3179		script = [script];
3180	var _callback = function()
3181	{
3182		return (callback && BX.type.isFunction(callback)) ? callback() : null
3183	};
3184	var load_js = function(ind)
3185	{
3186		if(ind >= script.length)
3187			return _callback();
3188
3189		if(!!script[ind])
3190		{
3191			var fileSrc = BX.getJSPath(script[ind]);
3192			if(isScriptLoaded(fileSrc))
3193			{
3194				load_js(++ind);
3195			}
3196			else
3197			{
3198				var oHead = doc.getElementsByTagName("head")[0] || doc.documentElement;
3199				var oScript = doc.createElement('script');
3200				oScript.src = script[ind];
3201
3202				var bLoaded = false;
3203				oScript.onload = oScript.onreadystatechange = function()
3204				{
3205					if (!bLoaded && (!oScript.readyState || oScript.readyState == "loaded" || oScript.readyState == "complete"))
3206					{
3207						bLoaded = true;
3208						setTimeout(function (){load_js(++ind);}, 50);
3209
3210						oScript.onload = oScript.onreadystatechange = null;
3211						if (oHead && oScript.parentNode)
3212						{
3213							oHead.removeChild(oScript);
3214						}
3215					}
3216				};
3217
3218				jsList.push(fileSrc);
3219				return oHead.insertBefore(oScript, oHead.firstChild);
3220			}
3221		}
3222		else
3223		{
3224			load_js(++ind);
3225		}
3226		return null;
3227	};
3228
3229	load_js(0);
3230};
3231
3232BX.loadCSS = function(arCSS, doc, win)
3233{
3234	if (!BX.isReady)
3235	{
3236		var _args = arguments;
3237		BX.ready(function() {
3238			BX.loadCSS.apply(this, _args);
3239		});
3240		return null;
3241	}
3242
3243	var bSingle = false;
3244	if (BX.type.isString(arCSS))
3245	{
3246		bSingle = true;
3247		arCSS = [arCSS];
3248	}
3249
3250	var i,
3251		l = arCSS.length,
3252		lnk = null,
3253		pLnk = [];
3254
3255	if (l == 0)
3256		return null;
3257
3258	doc = doc || document;
3259	win = win || window;
3260
3261	if (!win.bxhead)
3262	{
3263		var heads = doc.getElementsByTagName('HEAD');
3264		win.bxhead = heads[0];
3265
3266		if (!win.bxhead)
3267		{
3268			return null;
3269		}
3270	}
3271
3272	for (i = 0; i < l; i++)
3273	{
3274		var _check = BX.getCSSPath(arCSS[i]);
3275		if (isCssLoaded(_check))
3276		{
3277			continue;
3278		}
3279
3280		lnk = document.createElement('LINK');
3281		lnk.href = arCSS[i];
3282		lnk.rel = 'stylesheet';
3283		lnk.type = 'text/css';
3284
3285		var templateLink = getTemplateLink(win.bxhead);
3286		if (templateLink !== null)
3287		{
3288			templateLink.parentNode.insertBefore(lnk, templateLink);
3289		}
3290		else
3291		{
3292			win.bxhead.appendChild(lnk);
3293		}
3294
3295		pLnk.push(lnk);
3296		cssList.push(_check);
3297	}
3298
3299	if (bSingle)
3300		return lnk;
3301
3302	return pLnk;
3303};
3304
3305BX.load = function(items, callback, doc)
3306{
3307	if (!BX.isReady)
3308	{
3309		var _args = arguments;
3310		BX.ready(function() {
3311			BX.load.apply(this, _args);
3312		});
3313		return null;
3314	}
3315
3316	doc = doc || document;
3317	if (isAsync === null)
3318	{
3319		isAsync = "async" in doc.createElement("script") || "MozAppearance" in doc.documentElement.style || window.opera;
3320	}
3321
3322	return isAsync ? loadAsync(items, callback, doc) : loadAsyncEmulation(items, callback, doc);
3323};
3324
3325function loadAsync(items, callback, doc)
3326{
3327	if (!BX.type.isArray(items))
3328	{
3329		return;
3330	}
3331
3332	function allLoaded(items)
3333	{
3334		items = items || assets;
3335		for (var name in items)
3336		{
3337			if (items.hasOwnProperty(name) && items[name].state !== LOADED)
3338			{
3339				return false;
3340			}
3341		}
3342
3343		return true;
3344	}
3345
3346	function one(callback)
3347	{
3348		callback = callback || BX.DoNothing;
3349
3350		if (callback._done)
3351		{
3352			return;
3353		}
3354
3355		callback();
3356		callback._done = 1;
3357	}
3358
3359	if (!BX.type.isFunction(callback))
3360	{
3361		callback = null;
3362	}
3363
3364	var itemSet = {}, item, i;
3365	for (i = 0; i < items.length; i++)
3366	{
3367		item = items[i];
3368		item = getAsset(item);
3369		itemSet[item.name] = item;
3370	}
3371
3372	for (i = 0; i < items.length; i++)
3373	{
3374		item = items[i];
3375		item = getAsset(item);
3376		load(item, function () {
3377			if (allLoaded(itemSet))
3378			{
3379				one(callback);
3380			}
3381		}, doc);
3382	}
3383}
3384
3385function loadAsyncEmulation(items, callback, doc)
3386{
3387	function onPreload(asset)
3388	{
3389		asset.state = PRELOADED;
3390		if (BX.type.isArray(asset.onpreload) && asset.onpreload)
3391		{
3392			for (var i = 0; i < asset.onpreload.length; i++)
3393			{
3394				asset.onpreload[i].call();
3395			}
3396		}
3397	}
3398
3399	function preLoad(asset)
3400	{
3401		if (asset.state === undefined)
3402		{
3403			asset.state = PRELOADING;
3404			asset.onpreload = [];
3405
3406			loadAsset(
3407				{ url: asset.url, type: "cache", ext: asset.ext},
3408				function () { onPreload(asset); },
3409				doc
3410			);
3411		}
3412	}
3413
3414	if (!BX.type.isArray(items))
3415	{
3416		return;
3417	}
3418
3419	if (!BX.type.isFunction(callback))
3420	{
3421		callback = null;
3422	}
3423
3424	var rest = [].slice.call(items, 1);
3425	for (var i = 0; i < rest.length; i++)
3426	{
3427		preLoad(getAsset(rest[i]));
3428	}
3429
3430	load(getAsset(items[0]), items.length === 1 ? callback : function () {
3431		loadAsyncEmulation.apply(null, [rest, callback]);
3432	}, doc);
3433}
3434
3435function load(asset, callback, doc)
3436{
3437	callback = callback || BX.DoNothing;
3438
3439	if (asset.state === LOADED)
3440	{
3441		callback();
3442		return;
3443	}
3444
3445	if (asset.state === PRELOADING)
3446	{
3447		asset.onpreload.push(function () {
3448			load(asset, callback, doc);
3449		});
3450		return;
3451	}
3452
3453	asset.state = LOADING;
3454
3455	loadAsset(
3456		asset,
3457		function () {
3458			asset.state = LOADED;
3459			callback();
3460		},
3461		doc
3462	);
3463}
3464
3465function loadAsset(asset, callback, doc)
3466{
3467	callback = callback || BX.DoNothing;
3468
3469	function error(event)
3470	{
3471		ele.onload = ele.onreadystatechange = ele.onerror = null;
3472		callback();
3473	}
3474
3475	function process(event)
3476	{
3477		event = event || window.event;
3478		if (event.type === "load" || (/loaded|complete/.test(ele.readyState) && (!doc.documentMode || doc.documentMode < 9)))
3479		{
3480			window.clearTimeout(asset.errorTimeout);
3481			window.clearTimeout(asset.cssTimeout);
3482			ele.onload = ele.onreadystatechange = ele.onerror = null;
3483			callback();
3484		}
3485	}
3486
3487	function isCssLoaded()
3488	{
3489		if (asset.state !== LOADED && asset.cssRetries <= 20)
3490		{
3491			for (var i = 0, l = doc.styleSheets.length; i < l; i++)
3492			{
3493				if (doc.styleSheets[i].href === ele.href)
3494				{
3495					process({"type": "load"});
3496					return;
3497				}
3498			}
3499
3500			asset.cssRetries++;
3501			asset.cssTimeout = window.setTimeout(isCssLoaded, 250);
3502		}
3503	}
3504
3505	var ele;
3506	var ext = BX.type.isNotEmptyString(asset.ext) ? asset.ext : BX.util.getExtension(asset.url);
3507
3508	if (ext === "css")
3509	{
3510		ele = doc.createElement("link");
3511		ele.type = "text/" + (asset.type || "css");
3512		ele.rel = "stylesheet";
3513		ele.href = asset.url;
3514
3515		asset.cssRetries = 0;
3516		asset.cssTimeout = window.setTimeout(isCssLoaded, 500);
3517	}
3518	else
3519	{
3520		ele = doc.createElement("script");
3521		ele.type = "text/" + (asset.type || "javascript");
3522		ele.src = asset.url;
3523	}
3524
3525	ele.onload = ele.onreadystatechange = process;
3526	ele.onerror = error;
3527
3528	ele.async = false;
3529	ele.defer = false;
3530
3531	asset.errorTimeout = window.setTimeout(function () {
3532		error({type: "timeout"});
3533	}, 7000);
3534
3535	if (ext === "css")
3536	{
3537		cssList.push(BX.getCSSPath(asset.url));
3538	}
3539	else
3540	{
3541		jsList.push(BX.getJSPath(asset.url));
3542	}
3543
3544	var templateLink = null;
3545	var head = doc.head || doc.getElementsByTagName("head")[0];
3546	if (ext === "css" && (templateLink = getTemplateLink(head)) !== null)
3547	{
3548		templateLink.parentNode.insertBefore(ele, templateLink);
3549	}
3550	else
3551	{
3552		head.insertBefore(ele, head.lastChild);
3553	}
3554}
3555
3556function getAsset(item)
3557{
3558	var asset = {};
3559	if (typeof item === "object")
3560	{
3561		asset = item;
3562		asset.name = asset.name ? asset.name : BX.util.hashCode(item.url);
3563	}
3564	else
3565	{
3566		asset = { name: BX.util.hashCode(item), url : item };
3567	}
3568
3569	var ext = BX.type.isNotEmptyString(asset.ext) ? asset.ext : BX.util.getExtension(asset.url);
3570	if ((ext === "css" && isCssLoaded(asset.url)) || isScriptLoaded(asset.url))
3571	{
3572		asset.state = LOADED;
3573	}
3574
3575	var existing = assets[asset.name];
3576	if (existing && existing.url === asset.url)
3577	{
3578		return existing;
3579	}
3580
3581	assets[asset.name] = asset;
3582	return asset;
3583}
3584
3585function isCssLoaded(fileSrc)
3586{
3587	initCssList();
3588	return (BX.util.in_array(BX.getCSSPath(fileSrc), cssList));
3589}
3590
3591function initCssList()
3592{
3593	if(!cssInit)
3594	{
3595		var linksCol = document.getElementsByTagName('LINK'), links = [];
3596
3597		if(!!linksCol && linksCol.length > 0)
3598		{
3599			for(var i = 0; i < linksCol.length; i++)
3600			{
3601				var href = linksCol[i].getAttribute('href');
3602				if (BX.type.isNotEmptyString(href))
3603				{
3604					cssList.push(BX.getCSSPath(href));
3605				}
3606			}
3607		}
3608		cssInit = true;
3609	}
3610}
3611
3612function getTemplateLink(head)
3613{
3614	var findLink = function(tag)
3615	{
3616		var links = head.getElementsByTagName(tag);
3617		for (var i = 0, length = links.length; i < length; i++)
3618		{
3619			var templateStyle = links[i].getAttribute("data-template-style");
3620			if (BX.type.isNotEmptyString(templateStyle) && templateStyle == "true")
3621			{
3622				return links[i];
3623			}
3624		}
3625
3626		return null;
3627	};
3628
3629	var link = findLink("link");
3630	if (link === null)
3631	{
3632		link = findLink("style");
3633	}
3634
3635	return link;
3636}
3637
3638function isScriptLoaded(fileSrc)
3639{
3640	initJsList();
3641	return BX.util.in_array(BX.getJSPath(fileSrc), jsList);
3642}
3643
3644function initJsList()
3645{
3646	if(!jsInit)
3647	{
3648		var scriptCol = document.getElementsByTagName('script'), script = [];
3649
3650		if(!!scriptCol && scriptCol.length > 0)
3651		{
3652			for(var i=0; i<scriptCol.length; i++)
3653			{
3654				var src = scriptCol[i].getAttribute('src');
3655
3656				if (BX.type.isNotEmptyString(src))
3657				{
3658					jsList.push(BX.getJSPath(src));
3659				}
3660			}
3661		}
3662		jsInit = true;
3663	}
3664}
3665
3666BX.reload = function(back_url, bAddClearCache)
3667{
3668	if (back_url === true)
3669	{
3670		bAddClearCache = true;
3671		back_url = null;
3672	}
3673
3674	var new_href = back_url || top.location.href;
3675
3676	var hashpos = new_href.indexOf('#'), hash = '';
3677
3678	if (hashpos != -1)
3679	{
3680		hash = new_href.substr(hashpos);
3681		new_href = new_href.substr(0, hashpos);
3682	}
3683
3684	if (bAddClearCache && new_href.indexOf('clear_cache=Y') < 0)
3685		new_href += (new_href.indexOf('?') == -1 ? '?' : '&') + 'clear_cache=Y';
3686
3687	if (hash)
3688	{
3689		// hack for clearing cache in ajax mode components with history emulation
3690		if (bAddClearCache && (hash.substr(0, 5) == 'view/' || hash.substr(0, 6) == '#view/') && hash.indexOf('clear_cache%3DY') < 0)
3691			hash += (hash.indexOf('%3F') == -1 ? '%3F' : '%26') + 'clear_cache%3DY';
3692
3693		new_href = new_href.replace(/(\?|\&)_r=[\d]*/, '');
3694		new_href += (new_href.indexOf('?') == -1 ? '?' : '&') + '_r='+Math.round(Math.random()*10000) + hash;
3695	}
3696
3697	top.location.href = new_href;
3698};
3699
3700BX.clearCache = function()
3701{
3702	BX.showWait();
3703	BX.reload(true);
3704};
3705
3706BX.template = function(tpl, callback, bKillTpl)
3707{
3708	BX.ready(function() {
3709		_processTpl(BX(tpl), callback, bKillTpl);
3710	});
3711};
3712
3713BX.isAmPmMode = function()
3714{
3715	return (BX.message('FORMAT_DATETIME').match('T') != null);
3716};
3717
3718BX.formatDate = function(date, format)
3719{
3720	date = date || new Date();
3721
3722	var bTime = date.getHours() || date.getMinutes() || date.getSeconds(),
3723		str = !!format
3724			? format :
3725			(bTime ? BX.message('FORMAT_DATETIME') : BX.message('FORMAT_DATE')
3726		);
3727
3728	return str.replace(/YYYY/ig, date.getFullYear())
3729		.replace(/MMMM/ig, BX.util.str_pad_left((date.getMonth()+1).toString(), 2, '0'))
3730		.replace(/MM/ig, BX.util.str_pad_left((date.getMonth()+1).toString(), 2, '0'))
3731		.replace(/DD/ig, BX.util.str_pad_left(date.getDate().toString(), 2, '0'))
3732		.replace(/HH/ig, BX.util.str_pad_left(date.getHours().toString(), 2, '0'))
3733		.replace(/MI/ig, BX.util.str_pad_left(date.getMinutes().toString(), 2, '0'))
3734		.replace(/SS/ig, BX.util.str_pad_left(date.getSeconds().toString(), 2, '0'));
3735};
3736
3737BX.getNumMonth = function(month)
3738{
3739	var wordMonthCut = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
3740	var wordMonth = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
3741
3742	var q = month.toUpperCase();
3743	for (i = 1; i <= 12; i++)
3744	{
3745		if (q == BX.message('MON_'+i).toUpperCase() || q == BX.message('MONTH_'+i).toUpperCase() || q == wordMonthCut[i-1].toUpperCase() || q == wordMonth[i-1].toUpperCase())
3746		{
3747			return i;
3748		}
3749	}
3750	return month;
3751};
3752
3753BX.parseDate = function(str, bUTC)
3754{
3755	if (BX.type.isNotEmptyString(str))
3756	{
3757		var regMonths = '';
3758		for (i = 1; i <= 12; i++)
3759		{
3760			regMonths = regMonths + '|' + BX.message('MON_'+i);
3761		}
3762
3763		var expr = new RegExp('([0-9]+|[a-z]+' + regMonths + ')', 'ig');
3764		var aDate = str.match(expr),
3765			aFormat = BX.message('FORMAT_DATE').match(/(DD|MI|MMMM|MM|M|YYYY)/ig),
3766			i, cnt,
3767			aDateArgs=[], aFormatArgs=[],
3768			aResult={};
3769
3770		if (!aDate)
3771			return null;
3772
3773		if(aDate.length > aFormat.length)
3774		{
3775			aFormat = BX.message('FORMAT_DATETIME').match(/(DD|MI|MMMM|MM|M|YYYY|HH|H|SS|TT|T|GG|G)/ig);
3776		}
3777
3778		for(i = 0, cnt = aDate.length; i < cnt; i++)
3779		{
3780			if(BX.util.trim(aDate[i]) != '')
3781			{
3782				aDateArgs[aDateArgs.length] = aDate[i];
3783			}
3784		}
3785
3786		for(i = 0, cnt = aFormat.length; i < cnt; i++)
3787		{
3788			if(BX.util.trim(aFormat[i]) != '')
3789			{
3790				aFormatArgs[aFormatArgs.length] = aFormat[i];
3791			}
3792		}
3793
3794
3795		var m = BX.util.array_search('MMMM', aFormatArgs);
3796		if (m > 0)
3797		{
3798			aDateArgs[m] = BX.getNumMonth(aDateArgs[m]);
3799			aFormatArgs[m] = "MM";
3800		}
3801		else
3802		{
3803			m = BX.util.array_search('M', aFormatArgs);
3804			if (m > 0)
3805			{
3806				aDateArgs[m] = BX.getNumMonth(aDateArgs[m]);
3807				aFormatArgs[m] = "MM";
3808			}
3809		}
3810
3811		for(i = 0, cnt = aFormatArgs.length; i < cnt; i++)
3812		{
3813			var k = aFormatArgs[i].toUpperCase();
3814			aResult[k] = k == 'T' || k == 'TT' ? aDateArgs[i] : parseInt(aDateArgs[i], 10);
3815		}
3816
3817		if(aResult['DD'] > 0 && aResult['MM'] > 0 && aResult['YYYY'] > 0)
3818		{
3819			var d = new Date();
3820
3821			if(bUTC)
3822			{
3823				d.setUTCDate(1);
3824				d.setUTCFullYear(aResult['YYYY']);
3825				d.setUTCMonth(aResult['MM'] - 1);
3826				d.setUTCDate(aResult['DD']);
3827				d.setUTCHours(0, 0, 0);
3828			}
3829			else
3830			{
3831				d.setDate(1);
3832				d.setFullYear(aResult['YYYY']);
3833				d.setMonth(aResult['MM'] - 1);
3834				d.setDate(aResult['DD']);
3835				d.setHours(0, 0, 0);
3836			}
3837
3838			if(
3839				(!isNaN(aResult['HH']) || !isNaN(aResult['GG']) || !isNaN(aResult['H']) || !isNaN(aResult['G']))
3840					&& !isNaN(aResult['MI'])
3841			)
3842			{
3843				if (!isNaN(aResult['H']) || !isNaN(aResult['G']))
3844				{
3845					var bPM = (aResult['T']||aResult['TT']||'am').toUpperCase()=='PM';
3846					var h = parseInt(aResult['H']||aResult['G']||0, 10);
3847					if(bPM)
3848					{
3849						aResult['HH'] = h + (h == 12 ? 0 : 12);
3850					}
3851					else
3852					{
3853						aResult['HH'] = h < 12 ? h : 0;
3854					}
3855				}
3856				else
3857				{
3858					aResult['HH'] = parseInt(aResult['HH']||aResult['GG']||0, 10);
3859				}
3860
3861				if (isNaN(aResult['SS']))
3862					aResult['SS'] = 0;
3863
3864				if(bUTC)
3865				{
3866					d.setUTCHours(aResult['HH'], aResult['MI'], aResult['SS']);
3867				}
3868				else
3869				{
3870					d.setHours(aResult['HH'], aResult['MI'], aResult['SS']);
3871				}
3872			}
3873
3874			return d;
3875		}
3876	}
3877
3878	return null;
3879};
3880
3881BX.selectUtils =
3882{
3883	addNewOption: function(oSelect, opt_value, opt_name, do_sort, check_unique)
3884	{
3885		oSelect = BX(oSelect);
3886		if(oSelect)
3887		{
3888			var n = oSelect.length;
3889			if(check_unique !== false)
3890			{
3891				for(var i=0;i<n;i++)
3892				{
3893					if(oSelect[i].value==opt_value)
3894					{
3895						return;
3896					}
3897				}
3898			}
3899
3900			oSelect.options[n] = new Option(opt_name, opt_value, false, false);
3901		}
3902
3903		if(do_sort === true)
3904		{
3905			this.sortSelect(oSelect);
3906		}
3907	},
3908
3909	deleteOption: function(oSelect, opt_value)
3910	{
3911		oSelect = BX(oSelect);
3912		if(oSelect)
3913		{
3914			for(var i=0;i<oSelect.length;i++)
3915			{
3916				if(oSelect[i].value==opt_value)
3917				{
3918					oSelect.remove(i);
3919					break;
3920				}
3921			}
3922		}
3923	},
3924
3925	deleteSelectedOptions: function(oSelect)
3926	{
3927		oSelect = BX(oSelect);
3928		if(oSelect)
3929		{
3930			var i=0;
3931			while(i<oSelect.length)
3932			{
3933				if(oSelect[i].selected)
3934				{
3935					oSelect[i].selected=false;
3936					oSelect.remove(i);
3937				}
3938				else
3939				{
3940					i++;
3941				}
3942			}
3943		}
3944	},
3945
3946	deleteAllOptions: function(oSelect)
3947	{
3948		oSelect = BX(oSelect);
3949		if(oSelect)
3950		{
3951			for(var i=oSelect.length-1; i>=0; i--)
3952			{
3953				oSelect.remove(i);
3954			}
3955		}
3956	},
3957
3958	optionCompare: function(record1, record2)
3959	{
3960		var value1 = record1.optText.toLowerCase();
3961		var value2 = record2.optText.toLowerCase();
3962		if (value1 > value2) return(1);
3963		if (value1 < value2) return(-1);
3964		return(0);
3965	},
3966
3967	sortSelect: function(oSelect)
3968	{
3969		oSelect = BX(oSelect);
3970		if(oSelect)
3971		{
3972			var myOptions = [];
3973			var n = oSelect.options.length;
3974			var i;
3975			for (i=0;i<n;i++)
3976			{
3977				myOptions[i] = {
3978					optText:oSelect[i].text,
3979					optValue:oSelect[i].value
3980				};
3981			}
3982			myOptions.sort(this.optionCompare);
3983			oSelect.length=0;
3984			n = myOptions.length;
3985			for(i=0;i<n;i++)
3986			{
3987				oSelect[i] = new Option(myOptions[i].optText, myOptions[i].optValue, false, false);
3988			}
3989		}
3990	},
3991
3992	selectAllOptions: function(oSelect)
3993	{
3994		oSelect = BX(oSelect);
3995		if(oSelect)
3996		{
3997			var n = oSelect.length;
3998			for(var i=0;i<n;i++)
3999			{
4000				oSelect[i].selected=true;
4001			}
4002		}
4003	},
4004
4005	selectOption: function(oSelect, opt_value)
4006	{
4007		oSelect = BX(oSelect);
4008		if(oSelect)
4009		{
4010			var n = oSelect.length;
4011			for(var i=0;i<n;i++)
4012			{
4013				oSelect[i].selected = (oSelect[i].value == opt_value);
4014			}
4015		}
4016	},
4017
4018	addSelectedOptions: function(oSelect, to_select_id, check_unique, do_sort)
4019	{
4020		oSelect = BX(oSelect);
4021		if(!oSelect)
4022			return;
4023		var n = oSelect.length;
4024		for(var i=0; i<n; i++)
4025			if(oSelect[i].selected)
4026				this.addNewOption(to_select_id, oSelect[i].value, oSelect[i].text, do_sort, check_unique);
4027	},
4028
4029	moveOptionsUp: function(oSelect)
4030	{
4031		oSelect = BX(oSelect);
4032		if(!oSelect)
4033			return;
4034		var n = oSelect.length;
4035		for(var i=0; i<n; i++)
4036		{
4037			if(oSelect[i].selected && i>0 && oSelect[i-1].selected == false)
4038			{
4039				var option = new Option(oSelect[i].text, oSelect[i].value);
4040				oSelect[i] = new Option(oSelect[i-1].text, oSelect[i-1].value);
4041				oSelect[i].selected = false;
4042				oSelect[i-1] = option;
4043				oSelect[i-1].selected = true;
4044			}
4045		}
4046	},
4047
4048	moveOptionsDown: function(oSelect)
4049	{
4050		oSelect = BX(oSelect);
4051		if(!oSelect)
4052			return;
4053		var n = oSelect.length;
4054		for(var i=n-1; i>=0; i--)
4055		{
4056			if(oSelect[i].selected && i<n-1 && oSelect[i+1].selected == false)
4057			{
4058				var option = new Option(oSelect[i].text, oSelect[i].value);
4059				oSelect[i] = new Option(oSelect[i+1].text, oSelect[i+1].value);
4060				oSelect[i].selected = false;
4061				oSelect[i+1] = option;
4062				oSelect[i+1].selected = true;
4063			}
4064		}
4065	}
4066};
4067
4068BX.getEventTarget = function(e)
4069{
4070	if(e.target)
4071	{
4072		return e.target;
4073	}
4074	else if(e.srcElement)
4075	{
4076		return e.srcElement;
4077	}
4078	return null;
4079};
4080
4081/******* HINT ***************/
4082// if function has 2 params - the 2nd one is hint html. otherwise hint_html is third and hint_title - 2nd;
4083// '<div onmouseover="BX.hint(this, 'This is &lt;b&gt;Hint&lt;/b&gt;')"'>;
4084// BX.hint(el, 'This is <b>Hint</b>') - this won't work, use constructor
4085BX.hint = function(el, hint_title, hint_html, hint_id)
4086{
4087	if (null == hint_html)
4088	{
4089		hint_html = hint_title;
4090		hint_title = '';
4091	}
4092
4093	if (null == el.BXHINT)
4094	{
4095		el.BXHINT = new BX.CHint({
4096			parent: el, hint: hint_html, title: hint_title, id: hint_id
4097		});
4098		el.BXHINT.Show();
4099	}
4100};
4101
4102BX.hint_replace = function(el, hint_title, hint_html)
4103{
4104	if (null == hint_html)
4105	{
4106		hint_html = hint_title;
4107		hint_title = '';
4108	}
4109
4110	if (!el || !el.parentNode || !hint_html)
4111			return null;
4112
4113	var obHint = new BX.CHint({
4114		hint: hint_html,
4115		title: hint_title
4116	});
4117
4118	obHint.CreateParent();
4119
4120	el.parentNode.insertBefore(obHint.PARENT, el);
4121	el.parentNode.removeChild(el);
4122
4123	obHint.PARENT.style.marginLeft = '5px';
4124
4125	return el;
4126};
4127
4128BX.CHint = function(params)
4129{
4130	this.PARENT = BX(params.parent);
4131
4132	this.HINT = params.hint;
4133	this.HINT_TITLE = params.title;
4134
4135	this.PARAMS = {};
4136	for (var i in this.defaultSettings)
4137	{
4138		if (null == params[i])
4139			this.PARAMS[i] = this.defaultSettings[i];
4140		else
4141			this.PARAMS[i] = params[i];
4142	}
4143
4144	if (null != params.id)
4145		this.ID = params.id;
4146
4147	this.timer = null;
4148	this.bInited = false;
4149	this.msover = true;
4150
4151	if (this.PARAMS.showOnce)
4152	{
4153		this.__show();
4154		this.msover = false;
4155		this.timer = setTimeout(BX.proxy(this.__hide, this), this.PARAMS.hide_timeout);
4156	}
4157	else if (this.PARENT)
4158	{
4159		BX.bind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
4160		BX.bind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
4161	}
4162
4163	BX.addCustomEvent('onMenuOpen', BX.delegate(this.disable, this));
4164	BX.addCustomEvent('onMenuClose', BX.delegate(this.enable, this));
4165};
4166
4167BX.CHint.prototype.defaultSettings = {
4168	show_timeout: 1000,
4169	hide_timeout: 500,
4170	dx: 2,
4171	showOnce: false,
4172	preventHide: true,
4173	min_width: 250
4174};
4175
4176BX.CHint.prototype.CreateParent = function(element, params)
4177{
4178	if (this.PARENT)
4179	{
4180		BX.unbind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
4181		BX.unbind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
4182	}
4183
4184	if (!params) params = {};
4185	var type = 'icon';
4186
4187	if (params.type && (params.type == "link" || params.type == "icon"))
4188		type = params.type;
4189
4190	if (element)
4191		type = "element";
4192
4193	if (type == "icon")
4194	{
4195		element = BX.create('IMG', {
4196			props: {
4197				src: params.iconSrc
4198					? params.iconSrc
4199					: "/bitrix/js/main/core/images/hint.gif"
4200			}
4201		});
4202	}
4203	else if (type == "link")
4204	{
4205		element = BX.create("A", {
4206			props: {href: 'javascript:void(0)'},
4207			html: '[?]'
4208		});
4209	}
4210
4211	this.PARENT = element;
4212
4213	BX.bind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
4214	BX.bind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
4215
4216	return this.PARENT;
4217};
4218
4219BX.CHint.prototype.Show = function()
4220{
4221	this.msover = true;
4222
4223	if (null != this.timer)
4224		clearTimeout(this.timer);
4225
4226	this.timer = setTimeout(BX.proxy(this.__show, this), this.PARAMS.show_timeout);
4227};
4228
4229BX.CHint.prototype.Hide = function()
4230{
4231	this.msover = false;
4232
4233	if (null != this.timer)
4234		clearTimeout(this.timer);
4235
4236	this.timer = setTimeout(BX.proxy(this.__hide, this), this.PARAMS.hide_timeout);
4237};
4238
4239BX.CHint.prototype.__show = function()
4240{
4241	if (!this.msover || this.disabled) return;
4242	if (!this.bInited) this.Init();
4243
4244	if (this.prepareAdjustPos())
4245	{
4246		this.DIV.style.display = 'block';
4247		this.adjustPos();
4248
4249		BX.bind(window, 'scroll', BX.proxy(this.__onscroll, this));
4250
4251		if (this.PARAMS.showOnce)
4252		{
4253			this.timer = setTimeout(BX.proxy(this.__hide, this), this.PARAMS.hide_timeout);
4254		}
4255	}
4256};
4257
4258BX.CHint.prototype.__onscroll = function()
4259{
4260	if (!BX.admin || !BX.admin.panel || !BX.admin.panel.isFixed()) return;
4261
4262	if (this.scrollTimer) clearTimeout(this.scrollTimer);
4263
4264	this.DIV.style.display = 'none';
4265	this.scrollTimer = setTimeout(BX.proxy(this.Reopen, this), this.PARAMS.show_timeout);
4266};
4267
4268BX.CHint.prototype.Reopen = function()
4269{
4270	if (null != this.timer) clearTimeout(this.timer);
4271	this.timer = setTimeout(BX.proxy(this.__show, this), 50);
4272};
4273
4274BX.CHint.prototype.__hide = function()
4275{
4276	if (this.msover) return;
4277	if (!this.bInited) return;
4278
4279	BX.unbind(window, 'scroll', BX.proxy(this.Reopen, this));
4280
4281	if (this.PARAMS.showOnce)
4282	{
4283		this.Destroy();
4284	}
4285	else
4286	{
4287		this.DIV.style.display = 'none';
4288	}
4289};
4290
4291BX.CHint.prototype.__hide_immediately = function()
4292{
4293	this.msover = false;
4294	this.__hide();
4295};
4296
4297BX.CHint.prototype.Init = function()
4298{
4299	this.DIV = document.body.appendChild(BX.create('DIV', {
4300		props: {className: 'bx-panel-tooltip'},
4301		style: {display: 'none'},
4302		children: [
4303			BX.create('DIV', {
4304				props: {className: 'bx-panel-tooltip-top-border'},
4305				html: '<div class="bx-panel-tooltip-corner bx-panel-tooltip-left-corner"></div><div class="bx-panel-tooltip-border"></div><div class="bx-panel-tooltip-corner bx-panel-tooltip-right-corner"></div>'
4306			}),
4307			(this.CONTENT = BX.create('DIV', {
4308				props: {className: 'bx-panel-tooltip-content'},
4309				children: [
4310					BX.create('DIV', {
4311						props: {className: 'bx-panel-tooltip-underlay'},
4312						children: [
4313							BX.create('DIV', {props: {className: 'bx-panel-tooltip-underlay-bg'}})
4314						]
4315					})
4316				]
4317			})),
4318
4319			BX.create('DIV', {
4320				props: {className: 'bx-panel-tooltip-bottom-border'},
4321				html: '<div class="bx-panel-tooltip-corner bx-panel-tooltip-left-corner"></div><div class="bx-panel-tooltip-border"></div><div class="bx-panel-tooltip-corner bx-panel-tooltip-right-corner"></div>'
4322			})
4323		]
4324	}));
4325
4326	if (this.ID)
4327	{
4328		this.CONTENT.insertBefore(BX.create('A', {
4329			attrs: {href: 'javascript:void(0)'},
4330			props: {className: 'bx-panel-tooltip-close'},
4331			events: {click: BX.delegate(this.Close, this)}
4332		}), this.CONTENT.firstChild)
4333	}
4334
4335	if (this.HINT_TITLE)
4336	{
4337		this.CONTENT.appendChild(
4338			BX.create('DIV', {
4339				props: {className: 'bx-panel-tooltip-title'},
4340				text: this.HINT_TITLE
4341			})
4342		)
4343	}
4344
4345	if (this.HINT)
4346	{
4347		this.CONTENT_TEXT = this.CONTENT.appendChild(BX.create('DIV', {props: {className: 'bx-panel-tooltip-text'}})).appendChild(BX.create('SPAN', {html: this.HINT}));
4348	}
4349
4350	if (this.PARAMS.preventHide)
4351	{
4352		BX.bind(this.DIV, 'mouseout', BX.proxy(this.Hide, this));
4353		BX.bind(this.DIV, 'mouseover', BX.proxy(this.Show, this));
4354	}
4355
4356	this.bInited = true;
4357};
4358
4359BX.CHint.prototype.setContent = function(content)
4360{
4361	this.HINT = content;
4362
4363	if (this.CONTENT_TEXT)
4364		this.CONTENT_TEXT.innerHTML = this.HINT;
4365	else
4366		this.CONTENT_TEXT = this.CONTENT.appendChild(BX.create('DIV', {props: {className: 'bx-panel-tooltip-text'}})).appendChild(BX.create('SPAN', {html: this.HINT}));
4367};
4368
4369BX.CHint.prototype.prepareAdjustPos = function()
4370{
4371	this._wnd = {scrollPos: BX.GetWindowScrollPos(),scrollSize:BX.GetWindowScrollSize()};
4372	return BX.style(this.PARENT, 'display') != 'none';
4373};
4374
4375BX.CHint.prototype.getAdjustPos = function()
4376{
4377	var res = {}, pos = BX.pos(this.PARENT), min_top = 0;
4378
4379	res.top = pos.bottom + this.PARAMS.dx;
4380
4381	if (BX.admin && BX.admin.panel.DIV)
4382	{
4383		min_top = BX.admin.panel.DIV.offsetHeight + this.PARAMS.dx;
4384
4385		if (BX.admin.panel.isFixed())
4386		{
4387			min_top += this._wnd.scrollPos.scrollTop;
4388		}
4389	}
4390
4391	if (res.top < min_top)
4392		res.top = min_top;
4393	else
4394	{
4395		if (res.top + this.DIV.offsetHeight > this._wnd.scrollSize.scrollHeight)
4396			res.top = pos.top - this.PARAMS.dx - this.DIV.offsetHeight;
4397	}
4398
4399	res.left = pos.left;
4400	if (pos.left < this.PARAMS.dx)
4401		pos.left = this.PARAMS.dx;
4402	else
4403	{
4404		var floatWidth = this.DIV.offsetWidth;
4405
4406		var max_left = this._wnd.scrollSize.scrollWidth - floatWidth - this.PARAMS.dx;
4407
4408		if (res.left > max_left)
4409			res.left = max_left;
4410	}
4411
4412	return res;
4413};
4414
4415BX.CHint.prototype.adjustWidth = function()
4416{
4417	if (this.bWidthAdjusted) return;
4418
4419	var w = this.DIV.offsetWidth, h = this.DIV.offsetHeight;
4420
4421	if (w > this.PARAMS.min_width)
4422		w = Math.round(Math.sqrt(1.618*w*h));
4423
4424	if (w < this.PARAMS.min_width)
4425		w = this.PARAMS.min_width;
4426
4427	this.DIV.style.width = w + "px";
4428
4429	if (this._adjustWidthInt)
4430		clearInterval(this._adjustWidthInt);
4431	this._adjustWidthInt = setInterval(BX.delegate(this._adjustWidthInterval, this), 5);
4432
4433	this.bWidthAdjusted = true;
4434};
4435
4436BX.CHint.prototype._adjustWidthInterval = function()
4437{
4438	if (!this.DIV || this.DIV.style.display == 'none')
4439		clearInterval(this._adjustWidthInt);
4440
4441	var
4442		dW = 20,
4443		maxWidth = 1500,
4444		w = this.DIV.offsetWidth,
4445		w1 = this.CONTENT_TEXT.offsetWidth;
4446
4447	if (w > 0 && w1 > 0 && w - w1 < dW && w < maxWidth)
4448	{
4449		this.DIV.style.width = (w + dW) + "px";
4450		return;
4451	}
4452
4453	clearInterval(this._adjustWidthInt);
4454};
4455
4456BX.CHint.prototype.adjustPos = function()
4457{
4458	this.adjustWidth();
4459
4460	var pos = this.getAdjustPos();
4461
4462	this.DIV.style.top = pos.top + 'px';
4463	this.DIV.style.left = pos.left + 'px';
4464};
4465
4466BX.CHint.prototype.Close = function()
4467{
4468	if (this.ID && BX.WindowManager)
4469		BX.WindowManager.saveWindowOptions(this.ID, {display: 'off'});
4470	this.__hide_immediately();
4471	this.Destroy();
4472};
4473
4474BX.CHint.prototype.Destroy = function()
4475{
4476	if (this.PARENT)
4477	{
4478		BX.unbind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
4479		BX.unbind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
4480	}
4481
4482	if (this.DIV)
4483	{
4484		BX.unbind(this.DIV, 'mouseover', BX.proxy(this.Show, this));
4485		BX.unbind(this.DIV, 'mouseout', BX.proxy(this.Hide, this));
4486
4487		BX.cleanNode(this.DIV, true);
4488	}
4489};
4490
4491BX.CHint.prototype.enable = function(){this.disabled = false;};
4492BX.CHint.prototype.disable = function(){this.__hide_immediately(); this.disabled = true;};
4493
4494/* ready */
4495if (document.addEventListener)
4496{
4497	__readyHandler = function()
4498	{
4499		document.removeEventListener("DOMContentLoaded", __readyHandler, false);
4500		runReady();
4501	}
4502}
4503else if (document.attachEvent)
4504{
4505	__readyHandler = function()
4506	{
4507		if (document.readyState === "complete")
4508		{
4509			document.detachEvent("onreadystatechange", __readyHandler);
4510			runReady();
4511		}
4512	}
4513}
4514
4515function bindReady()
4516{
4517	if (!readyBound)
4518	{
4519		readyBound = true;
4520
4521		if (document.readyState === "complete")
4522		{
4523			return runReady();
4524		}
4525
4526		if (document.addEventListener)
4527		{
4528			document.addEventListener("DOMContentLoaded", __readyHandler, false);
4529			window.addEventListener("load", runReady, false);
4530		}
4531		else if (document.attachEvent) // IE
4532		{
4533			document.attachEvent("onreadystatechange", __readyHandler);
4534			window.attachEvent("onload", runReady);
4535
4536			var toplevel = false;
4537			try {toplevel = (window.frameElement == null);} catch(e) {}
4538
4539			if (document.documentElement.doScroll && toplevel)
4540				doScrollCheck();
4541		}
4542	}
4543
4544	return null;
4545}
4546
4547
4548function runReady()
4549{
4550	if (!BX.isReady)
4551	{
4552		if (!document.body)
4553			return setTimeout(runReady, 15);
4554
4555		BX.isReady = true;
4556
4557
4558		if (readyList && readyList.length > 0)
4559		{
4560			var fn, i = 0;
4561			while (readyList && (fn = readyList[i++]))
4562			{
4563				try{
4564					fn.call(document);
4565				}
4566				catch(e){
4567					BX.debug('BX.ready error: ', e);
4568				}
4569			}
4570
4571			readyList = null;
4572		}
4573		// TODO: check ready handlers binded some other way;
4574	}
4575	return null;
4576}
4577
4578// hack for IE
4579function doScrollCheck()
4580{
4581	if (BX.isReady)
4582		return;
4583
4584	try {document.documentElement.doScroll("left");} catch( error ) {setTimeout(doScrollCheck, 1); return;}
4585
4586	runReady();
4587}
4588/* \ready */
4589
4590function _adjustWait()
4591{
4592	if (!this.bxmsg) return;
4593
4594	var arContainerPos = BX.pos(this),
4595		div_top = arContainerPos.top;
4596
4597	if (div_top < BX.GetDocElement().scrollTop)
4598		div_top = BX.GetDocElement().scrollTop + 5;
4599
4600	this.bxmsg.style.top = (div_top + 5) + 'px';
4601
4602	if (this == BX.GetDocElement())
4603	{
4604		this.bxmsg.style.right = '5px';
4605	}
4606	else
4607	{
4608		this.bxmsg.style.left = (arContainerPos.right - this.bxmsg.offsetWidth - 5) + 'px';
4609	}
4610}
4611
4612function _checkDisplay(ob, displayType)
4613{
4614	if (typeof displayType != 'undefined')
4615		ob.BXDISPLAY = displayType;
4616
4617	var d = ob.style.display || BX.style(ob, 'display');
4618	if (d != 'none')
4619	{
4620		ob.BXDISPLAY = ob.BXDISPLAY || d;
4621		return true;
4622	}
4623	else
4624	{
4625		ob.BXDISPLAY = ob.BXDISPLAY || 'block';
4626		return false;
4627	}
4628}
4629
4630function _processTpl(tplNode, cb, bKillTpl)
4631{
4632	if (tplNode)
4633	{
4634		if (bKillTpl)
4635			tplNode.parentNode.removeChild(tplNode);
4636
4637		var res = {}, nodes = BX.findChildren(tplNode, {attribute: 'data-role'}, true);
4638
4639		for (var i = 0, l = nodes.length; i < l; i++)
4640		{
4641			res[nodes[i].getAttribute('data-role')] = nodes[i];
4642		}
4643
4644		cb.apply(tplNode, [res]);
4645	}
4646}
4647
4648function _checkNode(obj, params)
4649{
4650	params = params || {};
4651
4652	if (BX.type.isFunction(params))
4653		return params.call(window, obj);
4654
4655	if (!params.allowTextNodes && !BX.type.isElementNode(obj))
4656		return false;
4657	var i,j,len;
4658	for (i in params)
4659	{
4660		if(params.hasOwnProperty(i))
4661		{
4662			switch(i)
4663			{
4664				case 'tag':
4665				case 'tagName':
4666					if (BX.type.isString(params[i]))
4667					{
4668						if (obj.tagName.toUpperCase() != params[i].toUpperCase())
4669							return false;
4670					}
4671					else if (params[i] instanceof RegExp)
4672					{
4673						if (!params[i].test(obj.tagName))
4674							return false;
4675					}
4676				break;
4677
4678				case 'class':
4679				case 'className':
4680					if (BX.type.isString(params[i]))
4681					{
4682						if (!BX.hasClass(obj, params[i]))
4683							return false;
4684					}
4685					else if (params[i] instanceof RegExp)
4686					{
4687						if (!BX.type.isString(obj.className) || !params[i].test(obj.className))
4688							return false;
4689					}
4690				break;
4691
4692				case 'attr':
4693				case 'attribute':
4694					if (BX.type.isString(params[i]))
4695					{
4696						if (!obj.getAttribute(params[i]))
4697							return false;
4698					}
4699					else if (BX.type.isArray(params[i]))
4700					{
4701						for (j = 0, len = params[i].length; j < len; j++)
4702						{
4703							if (params[i] && !obj.getAttribute(params[i]))
4704								return false;
4705						}
4706					}
4707					else
4708					{
4709						for (j in params[i])
4710						{
4711							if(params[i].hasOwnProperty(j))
4712							{
4713								var q = obj.getAttribute(j);
4714								if (params[i][j] instanceof RegExp)
4715								{
4716									if (!BX.type.isString(q) || !params[i][j].test(q))
4717									{
4718										return false;
4719									}
4720								}
4721								else
4722								{
4723									if (q != '' + params[i][j])
4724									{
4725										return false;
4726									}
4727								}
4728							}
4729						}
4730					}
4731				break;
4732
4733				case 'property':
4734					if (BX.type.isString(params[i]))
4735					{
4736						if (!obj[params[i]])
4737							return false;
4738					}
4739					else if (BX.type.isArray(params[i]))
4740					{
4741						for (j = 0, len = params[i].length; j < len; j++)
4742						{
4743							if (params[i] && !obj[params[i]])
4744								return false;
4745						}
4746					}
4747					else
4748					{
4749						for (j in params[i])
4750						{
4751							if (BX.type.isString(params[i][j]))
4752							{
4753								if (obj[j] != params[i][j])
4754									return false;
4755							}
4756							else if (params[i][j] instanceof RegExp)
4757							{
4758								if (!BX.type.isString(obj[j]) || !params[i][j].test(obj[j]))
4759									return false;
4760							}
4761						}
4762					}
4763				break;
4764
4765				case 'callback':
4766					return params[i](obj);
4767			}
4768		}
4769	}
4770
4771	return true;
4772}
4773
4774/* garbage collector */
4775function Trash()
4776{
4777	var i,len;
4778
4779	for (i = 0, len = garbageCollectors.length; i<len; i++)
4780	{
4781		try {
4782			garbageCollectors[i].callback.apply(garbageCollectors[i].context || window);
4783			delete garbageCollectors[i];
4784			garbageCollectors[i] = null;
4785		} catch (e) {}
4786	}
4787
4788	try {BX.unbindAll();} catch(e) {}
4789/*
4790	for (i = 0, len = proxyList.length; i < len; i++)
4791	{
4792		try {
4793			delete proxyList[i];
4794			proxyList[i] = null;
4795		} catch (e) {}
4796	}
4797*/
4798}
4799
4800if(window.attachEvent) // IE
4801	window.attachEvent("onunload", Trash);
4802else if(window.addEventListener) // Gecko / W3C
4803	window.addEventListener('unload', Trash, false);
4804else
4805	window.onunload = Trash;
4806/* \garbage collector */
4807
4808// set empty ready handler
4809BX(BX.DoNothing);
4810window.BX = BX;
4811BX.browser.addGlobalClass();
4812BX.browser.addGlobalFeatures(["boxShadow", "borderRadius", "flexWrap", "boxDirection", "transition", "transform"])
4813
4814/* data storage */
4815BX.data = function(node, key, value)
4816{
4817	if(typeof node == 'undefined')
4818		return undefined;
4819
4820	if(typeof key == 'undefined')
4821		return undefined;
4822
4823	if(typeof value != 'undefined')
4824	{
4825		// write to manager
4826		dataStorage.set(node, key, value);
4827	}
4828	else
4829	{
4830		var values = [],
4831			data;
4832
4833		// from manager
4834		if((data = dataStorage.get(node, key, value)) != undefined)
4835			values.push(data);
4836
4837		// from attribute data-*
4838		key = 'data-'+key.toString();
4839
4840		if('getAttribute' in node && (data = node.getAttribute(key)))
4841			values.push(data);
4842
4843		// force to scalar value if only one found
4844		if(values.length == 1)
4845			return values[0];
4846		if(values.length == 0)
4847			return undefined;
4848
4849		return values;
4850	}
4851}
4852
4853BX.DataStorage = function()
4854{
4855
4856	this.keyOffset = 1;
4857	this.data = {};
4858	this.uniqueTag = 'BX-'+Math.random();
4859
4860	this.resolve = function(owner, create){
4861		if(typeof owner[this.uniqueTag] == 'undefined')
4862			if(create)
4863			{
4864				try 
4865				{
4866					Object.defineProperty(owner, this.uniqueTag, {
4867						value: this.keyOffset++
4868					});
4869				}
4870				catch(e)
4871				{
4872					owner[this.uniqueTag] = this.keyOffset++;
4873				}
4874			}
4875			else
4876				return undefined;
4877
4878		return owner[this.uniqueTag];
4879	};
4880	this.get = function(owner, key){
4881		if((owner != document && !BX.type.isElementNode(owner)) || typeof key == 'undefined') 
4882			return undefined;
4883
4884		owner = this.resolve(owner, false);
4885
4886		if(typeof owner == 'undefined' || typeof this.data[owner] == 'undefined')
4887			return undefined;
4888
4889		return this.data[owner][key];
4890	};
4891	this.set = function(owner, key, value){
4892
4893		if((owner != document && !BX.type.isElementNode(owner)) || typeof value == 'undefined') 
4894			return;
4895
4896		var o = this.resolve(owner, true);
4897
4898		if(typeof this.data[o] == 'undefined')
4899			this.data[o] = {};
4900
4901		this.data[o][key] = value;
4902	};
4903};
4904
4905// some internal variables for new logic
4906var dataStorage = new BX.DataStorage();	// manager which BX.data() uses to keep data
4907
4908})(window);
4909
4910/* End */
4911;
4912; /* Start:/bitrix/js/main/core/core_ajax.js*/
4913;(function(window){
4914
4915if (window.BX.ajax)
4916	return;
4917
4918var
4919	BX = window.BX,
4920
4921	tempDefaultConfig = {},
4922	defaultConfig = {
4923		method: 'GET', // request method: GET|POST
4924		dataType: 'html', // type of data loading: html|json|script
4925		timeout: 0, // request timeout in seconds. 0 for browser-default
4926		async: true, // whether request is asynchronous or not
4927		processData: true, // any data processing is disabled if false, only callback call
4928		scriptsRunFirst: false, // whether to run _all_ found scripts before onsuccess call. script tag can have an attribute "bxrunfirst" to turn  this flag on only for itself
4929		emulateOnload: true,
4930		skipAuthCheck: false, // whether to check authorization failure (SHOUD be set to true for CORS requests)
4931		start: true, // send request immediately (if false, request can be started manually via XMLHttpRequest object returned)
4932		cache: true, // whether NOT to add random addition to URL
4933		preparePost: true, // whether set Content-Type x-www-form-urlencoded in POST
4934		headers: false, // add additional headers, example: [{'name': 'If-Modified-Since', 'value': 'Wed, 15 Aug 2012 08:59:08 GMT'}, {'name': 'If-None-Match', 'value': '0'}]
4935		lsTimeout: 30, //local storage data TTL. useless without lsId.
4936		lsForce: false //wheter to force query instead of using localStorage data. useless without lsId.
4937/*
4938other parameters:
4939	url: url to get/post
4940	data: data to post
4941	onsuccess: successful request callback. BX.proxy may be used.
4942	onfailure: request failure callback. BX.proxy may be used.
4943
4944	lsId: local storage id - for constantly updating queries which can communicate via localStorage. core_ls.js needed
4945
4946any of the default parameters can be overridden. defaults can be changed by BX.ajax.Setup() - for all further requests!
4947*/
4948	},
4949	ajax_session = null,
4950	loadedScripts = {},
4951	loadedScriptsQueue = [],
4952	r = {
4953		'url_utf': /[^\034-\254]+/g,
4954		'script_self': /\/bitrix\/js\/main\/core\/core(_ajax)*.js$/i,
4955		'script_self_window': /\/bitrix\/js\/main\/core\/core_window.js$/i,
4956		'script_self_admin': /\/bitrix\/js\/main\/core\/core_admin.js$/i,
4957		'script_onload': /window.onload/g
4958	};
4959
4960// low-level method
4961BX.ajax = function(config)
4962{
4963	var status, data;
4964
4965	if (!config || !config.url || !BX.type.isString(config.url))
4966	{
4967		return false;
4968	}
4969
4970	for (var i in tempDefaultConfig)
4971		if (typeof (config[i]) == "undefined") config[i] = tempDefaultConfig[i];
4972
4973	tempDefaultConfig = {};
4974
4975	for (i in defaultConfig)
4976		if (typeof (config[i]) == "undefined") config[i] = defaultConfig[i];
4977
4978	config.method = config.method.toUpperCase();
4979
4980	if (!BX.localStorage)
4981		config.lsId = null;
4982
4983	if (BX.browser.IsIE())
4984	{
4985		var result = r.url_utf.exec(config.url);
4986		if (result)
4987		{
4988			do
4989			{
4990				config.url = config.url.replace(result, BX.util.urlencode(result));
4991				result = r.url_utf.exec(config.url);
4992			} while (result);
4993		}
4994	}
4995
4996	if(config.dataType == 'json')
4997		config.emulateOnload = false;
4998
4999	if (!config.cache && config.method == 'GET')
5000		config.url = BX.ajax._uncache(config.url);
5001
5002	if (config.method == 'POST' && config.preparePost)
5003	{
5004		config.data = BX.ajax.prepareData(config.data);
5005	}
5006
5007	var bXHR = true;
5008	if (config.lsId && !config.lsForce)
5009	{
5010		var v = BX.localStorage.get('ajax-' + config.lsId);
5011		if (v !== null)
5012		{
5013			bXHR = false;
5014
5015			var lsHandler = function(lsData) {
5016				if (lsData.key == 'ajax-' + config.lsId && lsData.value != 'BXAJAXWAIT')
5017				{
5018					var data = lsData.value,
5019						bRemove = !!lsData.oldValue && data == null;
5020					if (!bRemove)
5021						BX.ajax.__run(config, data);
5022					else if (config.onfailure)
5023						config.onfailure("timeout");
5024
5025					BX.removeCustomEvent('onLocalStorageChange', lsHandler);
5026				}
5027			};
5028
5029			if (v == 'BXAJAXWAIT')
5030			{
5031				BX.addCustomEvent('onLocalStorageChange', lsHandler);
5032			}
5033			else
5034			{
5035				setTimeout(function() {lsHandler({key: 'ajax-' + config.lsId, value: v})}, 10);
5036			}
5037		}
5038	}
5039
5040	if (bXHR)
5041	{
5042		config.xhr = BX.ajax.xhr();
5043		if (!config.xhr) return;
5044
5045		if (config.lsId)
5046		{
5047			BX.localStorage.set('ajax-' + config.lsId, 'BXAJAXWAIT', config.lsTimeout);
5048		}
5049
5050		config.xhr.open(config.method, config.url, config.async);
5051
5052		if (!config.skipBxHeader && !BX.ajax.isCrossDomain(config.url))
5053		{
5054			config.xhr.setRequestHeader('Bx-ajax', 'true');
5055		}
5056
5057		if (config.method == 'POST' && config.preparePost)
5058		{
5059			config.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
5060		}
5061		if (typeof(config.headers) == "object")
5062		{
5063			for (i = 0; i < config.headers.length; i++)
5064				config.xhr.setRequestHeader(config.headers[i].name, config.headers[i].value);
5065		}
5066
5067		var bRequestCompleted = false;
5068		var onreadystatechange = config.xhr.onreadystatechange = function(additional)
5069		{
5070			if (bRequestCompleted)
5071				return;
5072
5073			if (additional === 'timeout')
5074			{
5075				if (config.onfailure)
5076				{
5077					config.onfailure("timeout");
5078				}
5079
5080				BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['timeout', '', config]);
5081
5082				config.xhr.onreadystatechange = BX.DoNothing;
5083				config.xhr.abort();
5084
5085				if (config.async)
5086				{
5087					config.xhr = null;
5088				}
5089			}
5090			else
5091			{
5092				if (config.xhr.readyState == 4 || additional == 'run')
5093				{
5094					status = BX.ajax.xhrSuccess(config.xhr) ? "success" : "error";
5095					bRequestCompleted = true;
5096					config.xhr.onreadystatechange = BX.DoNothing;
5097
5098					if (status == 'success')
5099					{
5100						var authHeader = (!!config.skipAuthCheck || BX.ajax.isCrossDomain(config.url))
5101							? false
5102							: config.xhr.getResponseHeader('X-Bitrix-Ajax-Status');
5103
5104						if(!!authHeader && authHeader == 'Authorize')
5105						{
5106							if (config.onfailure)
5107							{
5108								config.onfailure("auth", config.xhr.status);
5109							}
5110
5111							BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['auth', config.xhr.status, config]);
5112						}
5113						else
5114						{
5115							var data = config.xhr.responseText;
5116
5117							if (config.lsId)
5118							{
5119								BX.localStorage.set('ajax-' + config.lsId, data, config.lsTimeout);
5120							}
5121
5122							BX.ajax.__run(config, data);
5123						}
5124					}
5125					else
5126					{
5127						if (config.onfailure)
5128						{
5129							config.onfailure("status", config.xhr.status);
5130						}
5131
5132						BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['status', config.xhr.status, config]);
5133					}
5134
5135					if (config.async)
5136					{
5137						config.xhr = null;
5138					}
5139				}
5140			}
5141		};
5142
5143		if (config.async && config.timeout > 0)
5144		{
5145			setTimeout(function() {
5146				if (config.xhr && !bRequestCompleted)
5147				{
5148					onreadystatechange("timeout");
5149				}
5150			}, config.timeout * 1000);
5151		}
5152
5153		if (config.start)
5154		{
5155			config.xhr.send(config.data);
5156
5157			if (!config.async)
5158			{
5159				onreadystatechange('run');
5160			}
5161		}
5162
5163		return config.xhr;
5164	}
5165};
5166
5167BX.ajax.xhr = function()
5168{
5169	if (window.XMLHttpRequest)
5170	{
5171		try {return new XMLHttpRequest();} catch(e){}
5172	}
5173	else if (window.ActiveXObject)
5174	{
5175		try { return new window.ActiveXObject("Msxml2.XMLHTTP.6.0"); }
5176			catch(e) {}
5177		try { return new window.ActiveXObject("Msxml2.XMLHTTP.3.0"); }
5178			catch(e) {}
5179		try { return new window.ActiveXObject("Msxml2.XMLHTTP"); }
5180			catch(e) {}
5181		try { return new window.ActiveXObject("Microsoft.XMLHTTP"); }
5182			catch(e) {}
5183		throw new Error("This browser does not support XMLHttpRequest.");
5184	}
5185
5186	return null;
5187};
5188
5189BX.ajax.isCrossDomain = function(url, location)
5190{
5191	location = location || window.location;
5192
5193	//Relative URL gets a current protocol
5194	if (url.indexOf("//") === 0)
5195	{
5196		url = location.protocol + url;
5197	}
5198
5199	//Fast check
5200	if (url.indexOf("http") !== 0)
5201	{
5202		return false;
5203	}
5204
5205	var link = window.document.createElement("a");
5206	link.href = url;
5207
5208	return  link.protocol !== location.protocol ||
5209			link.hostname !== location.hostname ||
5210			BX.ajax.getHostPort(link.protocol, link.host) !== BX.ajax.getHostPort(location.protocol, location.host);
5211};
5212
5213BX.ajax.getHostPort = function(protocol, host)
5214{
5215	var match = /:(\d+)$/.exec(host);
5216	if (match)
5217	{
5218		return match[1];
5219	}
5220	else
5221	{
5222		if (protocol === "http:")
5223		{
5224			return "80";
5225		}
5226		else if (protocol === "https:")
5227		{
5228			return "443";
5229		}
5230	}
5231
5232	return "";
5233};
5234
5235BX.ajax.__prepareOnload = function(scripts)
5236{
5237	if (scripts.length > 0)
5238	{
5239		BX.ajax['onload_' + ajax_session] = null;
5240
5241		for (var i=0,len=scripts.length;i<len;i++)
5242		{
5243			if (scripts[i].isInternal)
5244			{
5245				scripts[i].JS = scripts[i].JS.replace(r.script_onload, 'BX.aja
5245x.onload_' + ajax_session);
5246			}
5247		}
5248	}
5249
5250	BX.CaptureEventsGet();
5251	BX.CaptureEvents(window, 'load');
5252};
5253
5254BX.ajax.__runOnload = function()
5255{
5256	if (null != BX.ajax['onload_' + ajax_session])
5257	{
5258		BX.ajax['onload_' + ajax_session].apply(window);
5259		BX.ajax['onload_' + ajax_session] = null;
5260	}
5261
5262	var h = BX.CaptureEventsGet();
5263
5264	if (h)
5265	{
5266		for (var i=0; i<h.length; i++)
5267			h[i].apply(window);
5268	}
5269};
5270
5271BX.ajax.__run = function(config, data)
5272{
5273	if (!config.processData)
5274	{
5275		if (config.onsuccess)
5276		{
5277			config.onsuccess(data);
5278		}
5279
5280		BX.onCustomEvent(config.xhr, 'onAjaxSuccess', [data, config]);
5281	}
5282	else
5283	{
5284		data = BX.ajax.processRequestData(data, config);
5285	}
5286};
5287
5288
5289BX.ajax._onParseJSONFailure = function(data)
5290{
5291	this.jsonFailure = true;
5292	this.jsonResponse = data;
5293	this.jsonProactive = /^\[WAF\]/.test(data);
5294};
5295
5296BX.ajax.processRequestData = function(data, config)
5297{
5298	var result, scripts = [], styles = [];
5299	switch (config.dataType.toUpperCase())
5300	{
5301		case 'JSON':
5302			BX.addCustomEvent(config.xhr, 'onParseJSONFailure', BX.proxy(BX.ajax._onParseJSONFailure, config));
5303			result = BX.parseJSON(data, config.xhr);
5304			BX.removeCustomEvent(config.xhr, 'onParseJSONFailure', BX.proxy(BX.ajax._onParseJSONFailure, config));
5305
5306		break;
5307		case 'SCRIPT':
5308			scripts.push({"isInternal": true, "JS": data, bRunFirst: config.scriptsRunFirst});
5309			config.processScriptsConsecutive = true;
5310			result = data;
5311		break;
5312
5313		default: // HTML
5314			var ob = BX.processHTML(data, config.scriptsRunFirst);
5315			result = ob.HTML; scripts = ob.SCRIPT; styles = ob.STYLE;
5316		break;
5317	}
5318
5319	var bSessionCreated = false;
5320	if (null == ajax_session)
5321	{
5322		ajax_session = parseInt(Math.random() * 1000000);
5323		bSessionCreated = true;
5324	}
5325
5326	if (styles.length > 0)
5327		BX.loadCSS(styles);
5328
5329	if (config.emulateOnload)
5330			BX.ajax.__prepareOnload(scripts);
5331
5332	var cb = BX.DoNothing;
5333	if(config.emulateOnload || bSessionCreated)
5334	{
5335		cb = BX.defer(function()
5336		{
5337			if (config.emulateOnload)
5338				BX.ajax.__runOnload();
5339			if (bSessionCreated)
5340				ajax_session = null;
5341			BX.onCustomEvent(config.xhr, 'onAjaxSuccessFinish', [config]);
5342		});
5343	}
5344
5345	try
5346	{
5347		if (!!config.jsonFailure)
5348		{
5349			throw {type: 'json_failure', data: config.jsonResponse, bProactive: config.jsonProactive};
5350		}
5351
5352		config.scripts = scripts;
5353
5354		BX.ajax.processScripts(config.scripts, true);
5355
5356
5357		if (config.onsuccess)
5358		{
5359			config.onsuccess(result);
5360		}
5361
5362		BX.onCustomEvent(config.xhr, 'onAjaxSuccess', [result, config]);
5363
5364		if(!config.processScriptsConsecutive)
5365		{
5366			BX.ajax.processScripts(config.scripts, false, cb);
5367		}
5368		else
5369		{
5370			BX.ajax.processScriptsConsecutive(config.scripts, false);
5371			cb();
5372		}
5373	}
5374	catch (e)
5375	{
5376		if (config.onfailure)
5377			config.onfailure("processing", e);
5378		BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['processing', e, config]);
5379	}
5380};
5381
5382BX.ajax.processScripts = function(scripts, bRunFirst, cb)
5383{
5384	var scriptsExt = [], scriptsInt = '';
5385
5386	cb = cb || BX.DoNothing;
5387
5388	for (var i = 0, length = scripts.length; i < length; i++)
5389	{
5390		if (typeof bRunFirst != 'undefined' && bRunFirst != !!scripts[i].bRunFirst)
5391			continue;
5392
5393		if (scripts[i].isInternal)
5394			scriptsInt += ';' + scripts[i].JS;
5395		else
5396			scriptsExt.push(scripts[i].JS);
5397	}
5398
5399	scriptsExt = BX.util.array_unique(scriptsExt);
5400
5401	var l = scriptsExt.length;
5402	var l1 = l;
5403	var f = scriptsInt.length > 0 ? function() { BX.evalGlobal(scriptsInt); } : BX.DoNothing;
5404
5405	if (l > 0)
5406	{
5407		var c = function() {
5408			if (--l1 <= 0)
5409			{
5410				f();
5411				cb();
5412				f = BX.DoNothing;
5413			}
5414		};
5415
5416		for (i=0; i < l; i++)
5417		{
5418			BX.loadScript(scriptsExt[i], c);
5419		}
5420	}
5421	else
5422	{
5423		//f();BX.defer(cb)();
5424		f();
5425		cb();
5426	}
5427};
5428
5429BX.ajax.processScriptsConsecutive = function(scripts, bRunFirst)
5430{
5431	for (var i = 0, length = scripts.length; i < length; i++)
5432	{
5433		if (null != bRunFirst && bRunFirst != !!scripts[i].bRunFirst)
5434			continue;
5435
5436		if (scripts[i].isInternal)
5437		{
5438			BX.evalGlobal(scripts[i].JS);
5439		}
5440		else
5441		{
5442			BX.ajax.loadScriptAjax([scripts[i].JS]);
5443		}
5444	}
5445};
5446
5447// TODO: extend this function to use with any data objects or forms
5448BX.ajax.prepareData = function(arData, prefix)
5449{
5450	var data = '';
5451	if (BX.type.isString(arData))
5452		data = arData;
5453	else if (null != arData)
5454	{
5455		for(var i in arData)
5456		{
5457			if (arData.hasOwnProperty(i))
5458			{
5459				if (data.length > 0)
5460					data += '&';
5461				var name = BX.util.urlencode(i);
5462				if(prefix)
5463					name = prefix + '[' + name + ']';
5464				if(typeof arData[i] == 'object')
5465					data += BX.ajax.prepareData(arData[i], name);
5466				else
5467					data += name + '=' + BX.util.urlencode(arData[i]);
5468			}
5469		}
5470	}
5471	return data;
5472};
5473
5474BX.ajax.xhrSuccess = function(xhr)
5475{
5476	return (xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
5477};
5478
5479BX.ajax.Setup = function(config, bTemp)
5480{
5481	bTemp = !!bTemp;
5482
5483	for (var i in config)
5484	{
5485		if (bTemp)
5486			tempDefaultConfig[i] = config[i];
5487		else
5488			defaultConfig[i] = config[i];
5489	}
5490};
5491
5492BX.ajax.replaceLocalStorageValue = function(lsId, data, ttl)
5493{
5494	if (!!BX.localStorage)
5495		BX.localStorage.set('ajax-' + lsId, data, ttl);
5496};
5497
5498
5499BX.ajax._uncache = function(url)
5500{
5501	return url + ((url.indexOf('?') !== -1 ? "&" : "?") + '_=' + (new Date()).getTime());
5502};
5503
5504/* simple interface */
5505BX.ajax.get = function(url, data, callback)
5506{
5507	if (BX.type.isFunction(data))
5508	{
5509		callback = data;
5510		data = '';
5511	}
5512
5513	data = BX.ajax.prepareData(data);
5514
5515	if (data)
5516	{
5517		url += (url.indexOf('?') !== -1 ? "&" : "?") + data;
5518		data = '';
5519	}
5520
5521	return BX.ajax({
5522		'method': 'GET',
5523		'dataType': 'html',
5524		'url': url,
5525		'data':  '',
5526		'onsuccess': callback
5527	});
5528};
5529
5530BX.ajax.getCaptcha = function(callback)
5531{
5532	return BX.ajax.loadJSON('/bitrix/tools/ajax_captcha.php', callback);
5533};
5534
5535BX.ajax.insertToNode = function(url, node)
5536{
5537	node = BX(node);
5538	if (!!node)
5539	{
5540		var eventArgs = { cancel: false };
5541		BX.onCustomEvent('onAjaxInsertToNode', [{ url: url, node: node, eventArgs: eventArgs }]);
5542		if(eventArgs.cancel === true)
5543		{
5544			return;
5545		}
5546
5547		var show = null;
5548		if (!tempDefaultConfig.denyShowWait)
5549		{
5550			show = BX.showWait(node);
5551			delete tempDefaultConfig.denyShowWait;
5552		}
5553
5554		return BX.ajax.get(url, function(data) {
5555			node.innerHTML = data;
5556			BX.closeWait(node, show);
5557		});
5558	}
5559};
5560
5561BX.ajax.post = function(url, data, callback)
5562{
5563	data = BX.ajax.prepareData(data);
5564
5565	return BX.ajax({
5566		'method': 'POST',
5567		'dataType': 'html',
5568		'url': url,
5569		'data':  data,
5570		'onsuccess': callback
5571	});
5572};
5573
5574/* load and execute external file script with onload emulation */
5575BX.ajax.loadScriptAjax = function(script_src, callback, bPreload)
5576{
5577	if (BX.type.isArray(script_src))
5578	{
5579		for (var i=0,len=script_src.length;i<len;i++)
5580		{
5581			BX.ajax.loadScriptAjax(script_src[i], callback, bPreload);
5582		}
5583	}
5584	else
5585	{
5586		var script_src_test = script_src.replace(/\.js\?.*/, '.js');
5587
5588		if (r.script_self.test(script_src_test)) return;
5589		if (r.script_self_window.test(script_src_test) && BX.CWindow) return;
5590		if (r.script_self_admin.test(script_src_test) && BX.admin) return;
5591
5592		if (typeof loadedScripts[script_src_test] == 'undefined')
5593		{
5594			if (!!bPreload)
5595			{
5596				loadedScripts[script_src_test] = '';
5597				return BX.loadScript(script_src);
5598			}
5599			else
5600			{
5601				return BX.ajax({
5602					url: script_src,
5603					method: 'GET',
5604					dataType: 'script',
5605					processData: true,
5606					emulateOnload: false,
5607					scriptsRunFirst: true,
5608					async: false,
5609					start: true,
5610					onsuccess: function(result) {
5611						loadedScripts[script_src_test] = result;
5612						if (callback)
5613							callback(result);
5614					}
5615				});
5616			}
5617		}
5618		else if (callback)
5619		{
5620			callback(loadedScripts[script_src_test]);
5621		}
5622	}
5623};
5624
5625/* non-xhr loadings */
5626BX.ajax.loadJSON = function(url, data, callback, callback_failure)
5627{
5628	if (BX.type.isFunction(data))
5629	{
5630		callback_failure = callback;
5631		callback = data;
5632		data = '';
5633	}
5634
5635	data = BX.ajax.prepareData(data);
5636
5637	if (data)
5638	{
5639		url += (url.indexOf('?') !== -1 ? "&" : "?") + data;
5640		data = '';
5641	}
5642
5643	return BX.ajax({
5644		'method': 'GET',
5645		'dataType': 'json',
5646		'url': url,
5647		'onsuccess': callback,
5648		'onfailure': callback_failure
5649	});
5650};
5651
5652/*
5653arObs = [{
5654	url: url,
5655	type: html|script|json|css,
5656	callback: function
5657}]
5658*/
5659BX.ajax.load = function(arObs, callback)
5660{
5661	if (!BX.type.isArray(arObs))
5662		arObs = [arObs];
5663
5664	var cnt = 0;
5665
5666	if (!BX.type.isFunction(callback))
5667		callback = BX.DoNothing;
5668
5669	var handler = function(data)
5670		{
5671			if (BX.type.isFunction(this.callback))
5672				this.callback(data);
5673
5674			if (++cnt >= len)
5675				callback();
5676		};
5677
5678	for (var i = 0, len = arObs.length; i<len; i++)
5679	{
5680		switch(arObs[i].type.toUpperCase())
5681		{
5682			case 'SCRIPT':
5683				BX.loadScript([arObs[i].url], BX.proxy(handler, arObs[i]));
5684			break;
5685			case 'CSS':
5686				BX.loadCSS([arObs[i].url]);
5687
5688				if (++cnt >= len)
5689					callback();
5690			break;
5691			case 'JSON':
5692				BX.ajax.loadJSON(arObs[i].url, BX.proxy(handler, arObs[i]));
5693			break;
5694
5695			default:
5696				BX.ajax.get(arObs[i].url, '', BX.proxy(handler, arObs[i]));
5697			break;
5698		}
5699	}
5700};
5701
5702/* ajax form sending */
5703BX.ajax.submit = function(obForm, callback)
5704{
5705	if (!obForm.target)
5706	{
5707		if (null == obForm.BXFormTarget)
5708		{
5709			var frame_name = 'formTarget_' + Math.random();
5710			obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', {
5711				props: {
5712					name: frame_name,
5713					id: frame_name,
5714					src: 'javascript:void(0)'
5715				},
5716				style: {
5717					display: 'none'
5718				}
5719			}));
5720		}
5721
5722		obForm.target = obForm.BXFormTarget.name;
5723	}
5724
5725	obForm.BXFormCallback = callback;
5726	BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm));
5727
5728	BX.submit(obForm);
5729
5730	return false;
5731};
5732
5733BX.ajax.submitComponentForm = function(obForm, container, bWait)
5734{
5735	if (!obForm.target)
5736	{
5737		if (null == obForm.BXFormTarget)
5738		{
5739			var frame_name = 'formTarget_' + Math.random();
5740			obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', {
5741				props: {
5742					name: frame_name,
5743					id: frame_name,
5744					src: 'javascript:void(0)'
5745				},
5746				style: {
5747					display: 'none'
5748				}
5749			}));
5750		}
5751
5752		obForm.target = obForm.BXFormTarget.name;
5753	}
5754
5755	if (!!bWait)
5756		var w = BX.showWait(container);
5757
5758	obForm.BXFormCallback = function(d) {
5759		if (!!bWait)
5760			BX.closeWait(w);
5761
5762		var callOnload = function(){
5763			if(!!window.bxcompajaxframeonload)
5764			{
5765				setTimeout(function(){window.bxcompajaxframeonload();window.bxcompajaxframeonload=null;}, 10);
5766			}
5767		};
5768
5769		BX(container).innerHTML = d;
5770		BX.onCustomEvent('onAjaxSuccess', [null,null,callOnload]);
5771	};
5772
5773	BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm));
5774
5775	return true;
5776};
5777
5778// func will be executed in form context
5779BX.ajax._submit_callback = function()
5780{
5781	//opera and IE8 triggers onload event even on empty iframe
5782	try
5783	{
5784		if(this.BXFormTarget.contentWindow.location.href.indexOf('http') != 0)
5785			return;
5786	} catch (e) {
5787		return;
5788	}
5789
5790	if (this.BXFormCallback)
5791		this.BXFormCallback.apply(this, [this.BXFormTarget.contentWindow.document.body.innerHTML]);
5792
5793	BX.unbindAll(this.BXFormTarget);
5794};
5795
5796BX.ajax.prepareForm = function(obForm, data)
5797{
5798	data = (!!data ? data : {});
5799	var i, ii, el,
5800		_data = [],
5801		n = obForm.elements.length,
5802		files = 0, length = 0;
5803	if(!!obForm)
5804	{
5805		for (i = 0; i < n; i++)
5806		{
5807			el = obForm.elements[i];
5808			if (el.disabled)
5809				continue;
5810			switch(el.type.toLowerCase())
5811			{
5812				case 'text':
5813				case 'textarea':
5814				case 'password':
5815				case 'hidden':
5816				case 'select-one':
5817					_data.push({name: el.name, value: el.value});
5818					length += (el.name.length + el.value.length);
5819					break;
5820				case 'file':
5821					if (!!el.files)
5822					{
5823						for (ii = 0; ii < el.files.length; ii++)
5824						{
5825							files++;
5826							_data.push({name: el.name, value: el.files[ii], file : true});
5827							length += el.files[ii].size;
5828						}
5829					}
5830					break;
5831				case 'radio':
5832				case 'checkbox':
5833					if(el.checked)
5834					{
5835						_data.push({name: el.name, value: el.value});
5836						length += (el.name.length + el.value.length);
5837					}
5838					break;
5839				case 'select-multiple':
5840					for (var j = 0; j < el.options.length; j++)
5841					{
5842						if (el.options[j].selected)
5843						{
5844							_data.push({name : el.name, value : el.options[j].value});
5845							length += (el.name.length + el.options[j].length);
5846						}
5847					}
5848					break;
5849				default:
5850					break;
5851			}
5852		}
5853
5854		i = 0; length = 0;
5855		var current = data;
5856
5857		while(i < _data.length)
5858		{
5859			var p = _data[i].name.indexOf('[');
5860			if (p == -1) {
5861				current[_data[i].name] = _data[i].value;
5862				current = data;
5863				i++;
5864			}
5865			else
5866			{
5867				var name = _data[i].name.substring(0, p);
5868				var rest = _data[i].name.substring(p+1);
5869				if(!current[name])
5870					current[name] = [];
5871
5872				var pp = rest.indexOf(']');
5873				if(pp == -1)
5874				{
5875					current = data;
5876					i++;
5877				}
5878				else if(pp == 0)
5879				{
5880					//No index specified - so take the next integer
5881					current = current[name];
5882					_data[i].name = '' + current.length;
5883				}
5884				else
5885				{
5886					//Now index name becomes and name and we go deeper into the array
5887					current = current[name];
5888					_data[i].name = rest.substring(0, pp) + rest.substring(pp+1);
5889				}
5890			}
5891		}
5892	}
5893	return {data : data, filesCount : files, roughSize : length};
5894};
5895BX.ajax.submitAjax = function(obForm, config)
5896{
5897	config = (!!config && typeof config == "object" ? config : {});
5898	config.url = (config["url"] || obForm.getAttribute("action"));
5899	config.data = BX.ajax.prepareForm(obForm).data;
5900
5901	if (!window["FormData"])
5902	{
5903		BX.ajax(config);
5904	}
5905	else
5906	{
5907		var isFile = function(item)
5908		{
5909			var res = Object.prototype.toString.call(item);
5910			return (res == '[object File]' || res == '[object Blob]');
5911		},
5912		appendToForm = function(fd, key, val)
5913		{
5914			if (!!val && typeof val == "object" && !isFile(val))
5915			{
5916				for (var ii in val)
5917				{
5918					if (val.hasOwnProperty(ii))
5919					{
5920						appendToForm(fd, (key == '' ? ii : key + '[' + ii + ']'), val[ii]);
5921					}
5922				}
5923			}
5924			else
5925				fd.append(key, (!!val ? val : ''));
5926		},
5927		prepareData = function(arData)
5928		{
5929			var data = {};
5930			if (null != arData)
5931			{
5932				if(typeof arData == 'object')
5933				{
5934					for(var i in arData)
5935					{
5936						if (arData.hasOwnProperty(i))
5937						{
5938							var name = BX.util.urlencode(i);
5939							if(typeof arData[i] == 'object' && arData[i]["file"] !== true)
5940								data[name] = prepareData(arData[i]);
5941							else if (arData[i]["file"] === true)
5942								data[name] = arData[i]["value"];
5943							else
5944								data[name] = BX.util.urlencode(arData[i]);
5945						}
5946					}
5947				}
5948				else
5949					data = BX.util.urlencode(arData);
5950			}
5951			return data;
5952		},
5953		fd = new window.FormData();
5954
5955		if (config.method !== 'POST')
5956		{
5957			config.data = BX.ajax.prepareData(config.data);
5958			if (config.data)
5959			{
5960				config.url += (config.url.indexOf('?') !== -1 ? "&" : "?") + config.data;
5961				config.data = '';
5962			}
5963		}
5964		else
5965		{
5966			if (config.preparePost === true)
5967				config.data = prepareData(config.data);
5968			appendToForm(fd, '', config.data);
5969			config.data = fd;
5970		}
5971
5972		config.preparePost = false;
5973		config.start = false;
5974
5975		var xhr = BX.ajax(config);
5976		if (!!config["onprogress"])
5977			xhr.upload.addEventListener(
5978				'progress',
5979				function(e){
5980					var percent = null;
5981					if(e.lengthComputable && (e.total || e["totalSize"])) {
5982						percent = e.loaded * 100 / (e.total || e["totalSize"]);
5983					}
5984					config["onprogress"](e, percent);
5985				}
5986			);
5987		xhr.send(fd);
5988	}
5989};
5990
5991BX.ajax.UpdatePageData = function (arData)
5992{
5993	if (arData.TITLE)
5994		BX.ajax.UpdatePageTitle(arData.TITLE);
5995	if (arData.WINDOW_TITLE || arData.TITLE)
5996		BX.ajax.UpdateWindowTitle(arData.WINDOW_TITLE || arData.TITLE);
5997	if (arData.NAV_CHAIN)
5998		BX.ajax.UpdatePageNavChain(arData.NAV_CHAIN);
5999	if (arData.CSS && arData.CSS.length > 0)
6000		BX.loadCSS(arData.CSS);
6001	if (arData.SCRIPTS && arData.SCRIPTS.length > 0)
6002	{
6003		var f = function(result,config,cb){
6004
6005			if(!!config && BX.type.isArray(config.scripts))
6006			{
6007				for(var i=0,l=arData.SCRIPTS.length;i<l;i++)
6008				{
6009					config.scripts.push({isInternal:false,JS:arData.SCRIPTS[i]});
6010				}
6011			}
6012			else
6013			{
6014				BX.loadScript(arData.SCRIPTS,cb);
6015			}
6016
6017			BX.removeCustomEvent('onAjaxSuccess',f);
6018		};
6019		BX.addCustomEvent('onAjaxSuccess',f);
6020	}
6021	else
6022	{
6023		var f1 = function(result,config,cb){
6024			if(BX.type.isFunction(cb))
6025			{
6026				cb();
6027			}
6028			BX.removeCustomEvent('onAjaxSuccess',f1);
6029		};
6030		BX.addCustomEvent('onAjaxSuccess', f1);
6031	}
6032};
6033
6034BX.ajax.UpdatePageTitle = function(title)
6035{
6036	var obTitle = BX('pagetitle');
6037	if (obTitle)
6038	{
6039		obTitle.removeChild(obTitle.firstChild);
6040		if (!obTitle.firstChild)
6041			obTitle.appendChild(document.createTextNode(title));
6042		else
6043			obTitle.insertBefore(document.createTextNode(title), obTitle.firstChild);
6044	}
6045};
6046
6047BX.ajax.UpdateWindowTitle = function(title)
6048{
6049	document.title = title;
6050};
6051
6052BX.ajax.UpdatePageNavChain = function(nav_chain)
6053{
6054	var obNavChain = BX('navigation');
6055	if (obNavChain)
6056	{
6057		obNavChain.innerHTML = nav_chain;
6058	}
6059};
6060
6061/* user options handling */
6062BX.userOptions = {
6063	options: null,
6064	bSend: false,
6065	delay: 5000,
6066	path: '/bitrix/admin/user_options.php?'
6067};
6068
6069BX.userOptions.setAjaxPath = function(url)
6070{
6071	BX.userOptions.path = url.indexOf('?') == -1? url+'?': url+'&';
6072}
6073BX.userOptions.save = function(sCategory, sName, sValName, sVal, bCommon)
6074{
6075	if (null == BX.userOptions.options)
6076		BX.userOptions.options = {};
6077
6078	bCommon = !!bCommon;
6079	BX.userOptions.options[sCategory+'.'+sName+'.'+sValName] = [sCategory, sName, sValName, sVal, bCommon];
6080
6081	var sParam = BX.userOptions.__get();
6082	if (sParam != '')
6083		document.cookie = BX.message('COOKIE_PREFIX')+"_LAST_SETTINGS=" + sParam + "&sessid="+BX.bitrix_sessid()+"; expires=Thu, 31 Dec 2020 23:59:59 GMT; path=/;";
6084
6085	if(!BX.userOptions.bSend)
6086	{
6087		BX.userOptions.bSend = true;
6088		setTimeout(function(){BX.userOptions.send(null)}, BX.userOptions.delay);
6089	}
6090};
6091
6092BX.userOptions.send = function(callback)
6093{
6094	var sParam = BX.userOptions.__get();
6095	BX.userOptions.options = null;
6096	BX.userOptions.bSend = false;
6097
6098	if (sParam != '')
6099	{
6100		document.cookie = BX.message('COOKIE_PREFIX') + "_LAST_SETTINGS=; path=/;";
6101		BX.ajax({
6102			'method': 'GET',
6103			'dataType': 'html',
6104			'processData': false,
6105			'cache': false,
6106			'url': BX.userOptions.path+sParam+'&sessid='+BX.bitrix_sessid(),
6107			'onsuccess': callback
6108		});
6109	}
6110};
6111
6112BX.userOptions.del = function(sCategory, sName, bCommon, callback)
6113{
6114	BX.ajax.get(BX.userOptions.path+'action=delete&c='+sCategory+'&n='+sName+(bCommon == true? '&common=Y':'')+'&sessid='+BX.bitrix_sessid(), callback);
6115};
6116
6117BX.userOptions.__get = function()
6118{
6119	if (!BX.userOptions.options) return '';
6120
6121	var sParam = '', n = -1, prevParam = '', aOpt, i;
6122
6123	for (i in BX.userOptions.options)
6124	{
6125		if(BX.userOptions.options.hasOwnProperty(i))
6126		{
6127			aOpt = BX.userOptions.options[i];
6128
6129			if (prevParam != aOpt[0]+'.'+aOpt[1])
6130			{
6131				n++;
6132				sParam += '&p['+n+'][c]='+BX.util.urlencode(aOpt[0]);
6133				sParam += '&p['+n+'][n]='+BX.util.urlencode(aOpt[1]);
6134				if (aOpt[4] == true)
6135					sParam += '&p['+n+'][d]=Y';
6136				prevParam = aOpt[0]+'.'+aOpt[1];
6137			}
6138
6139			sParam += '&p['+n+'][v]['+BX.util.urlencode(aOpt[2])+']='+BX.util.urlencode(aOpt[3]);
6140		}
6141	}
6142
6143	return sParam.substr(1);
6144};
6145
6146BX.ajax.history = {
6147	expected_hash: '',
6148
6149	obParams: null,
6150
6151	obFrame: null,
6152	obImage: null,
6153
6154	obTimer: null,
6155
6156	bInited: false,
6157	bHashCollision: false,
6158	bPushState: !!(history.pushState && BX.type.isFunction(history.pushState)),
6159
6160	startState: null,
6161
6162	init: function(obParams)
6163	{
6164		if (BX.ajax.history.bInited)
6165			return;
6166
6167		this.obParams = obParams;
6168		var obCurrentState = this.obParams.getState();
6169
6170		if (BX.ajax.history.bPushState)
6171		{
6172			BX.ajax.history.expected_hash = window.location.pathname;
6173			if (window.location.search)
6174				BX.ajax.history.expected_hash += window.location.search;
6175
6176			BX.ajax.history.put(obCurrentState, BX.ajax.history.expected_hash, '', true);
6177			// due to some strange thing, chrome calls popstate event on page start. so we should delay it
6178			setTimeout(function(){BX.bind(window, 'popstate', BX.ajax.history.__hashListener);}, 500);
6179		}
6180		else
6181		{
6182			BX.ajax.history.expected_hash = window.location.hash;
6183
6184			if (!BX.ajax.history.expected_hash || BX.ajax.history.expected_hash == '#')
6185				BX.ajax.history.expected_hash = '__bx_no_hash__';
6186
6187			jsAjaxHistoryContainer.put(BX.ajax.history.expected_hash, obCurrentState);
6188			BX.ajax.history.obTimer = setTimeout(BX.ajax.history.__hashListener, 500);
6189
6190			if (BX.browser.IsIE())
6191			{
6192				BX.ajax.history.obFrame = document.createElement('IFRAME');
6193				BX.hide_object(BX.ajax.history.obFrame);
6194
6195				document.body.appendChild(BX.ajax.history.obFrame);
6196
6197				BX.ajax.history.obFrame.contentWindow.document.open();
6198				BX.ajax.history.obFrame.contentWindow.document.write(BX.ajax.history.expected_hash);
6199				BX.ajax.history.obFrame.contentWindow.document.close();
6200			}
6201			else if (BX.browser.IsOpera())
6202			{
6203				BX.ajax.history.obImage = document.createElement('IMG');
6204				BX.hide_object(BX.ajax.history.obImage);
6205
6206				document.body.appendChild(BX.ajax.history.obImage);
6207
6208				BX.ajax.history.obImage.setAttribute('src', 'javascript:location.href = \'javascript:BX.ajax.history.__hashListener();\';');
6209			}
6210		}
6211
6212		BX.ajax.history.bInited = true;
6213	},
6214
6215	__hashListener: function(e)
6216	{
6217		e = e || window.event || {state:false};
6218
6219		if (BX.ajax.history.bPushState)
6220		{
6221			BX.ajax.history.obParams.setState(e.state||BX.ajax.history.startState);
6222		}
6223		else
6224		{
6225			if (BX.ajax.history.obTimer)
6226			{
6227				window.clearTimeout(BX.ajax.history.obTimer);
6228				BX.ajax.history.obTimer = null;
6229			}
6230
6231			var current_hash;
6232			if (null != BX.ajax.history.obFrame)
6233				current_hash = BX.ajax.history.obFrame.contentWindow.document.body.innerText;
6234			else
6235				current_hash = window.location.hash;
6236
6237			if (!current_hash || current_hash == '#')
6238				current_hash = '__bx_no_hash__';
6239
6240			if (current_hash.indexOf('#') == 0)
6241				current_hash = current_hash.substring(1);
6242
6243			if (current_hash != BX.ajax.history.expected_hash)
6244			{
6245				var state = jsAjaxHistoryContainer.get(current_hash);
6246				if (state)
6247				{
6248					BX.ajax.history.obParams.setState(state);
6249
6250					BX.ajax.history.expected_hash = current_hash;
6251					if (null != BX.ajax.history.obFrame)
6252					{
6253						var __hash = current_hash == '__bx_no_hash__' ? '' : current_hash;
6254						if (window.location.hash != __hash && window.location.hash != '#' + __hash)
6255							window.location.hash = __hash;
6256					}
6257				}
6258			}
6259
6260			BX.ajax.history.obTimer = setTimeout(BX.ajax.history.__hashListener, 500);
6261		}
6262	},
6263
6264	put: function(state, new_hash, new_hash1, bStartState)
6265	{
6266		if (this.bPushState)
6267		{
6268			if(!bStartState)
6269			{
6270				history.pushState(state, '', new_hash);
6271			}
6272			else
6273			{
6274				BX.ajax.history.startState = state;
6275			}
6276		}
6277		else
6278		{
6279			if (typeof new_hash1 != 'undefined')
6280				new_hash = new_hash1;
6281			else
6282				new_hash = 'view' + new_hash;
6283
6284			jsAjaxHistoryContainer.put(new_hash, state);
6285			BX.ajax.history.expected_hash = new_hash;
6286
6287			window.location.hash = BX.util.urlencode(new_hash);
6288
6289			if (null != BX.ajax.history.obFrame)
6290			{
6291				BX.ajax.history.obFrame.contentWindow.document.open();
6292				BX.ajax.history.obFrame.contentWindow.document.write(new_hash);
6293				BX.ajax.history.obFrame.contentWindow.document.close();
6294			}
6295		}
6296	},
6297
6298	checkRedirectStart: function(param_name, param_value)
6299	{
6300		var current_hash = window.location.hash;
6301		if (current_hash.substring(0, 1) == '#') current_hash = current_hash.substring(1);
6302
6303		var test = current_hash.substring(0, 5);
6304		if (test == 'view/' || test == 'view%')
6305		{
6306			BX.ajax.history.bHashCollision = true;
6307			document.write('<' + 'div id="__ajax_hash_collision_' + param_value + '" style="display: none;">');
6308		}
6309	},
6310
6311	checkRedirectFinish: function(param_name, param_value)
6312	{
6313		document.write('</div>');
6314
6315		var current_hash = window.location.hash;
6316		if (current_hash.substring(0, 1) == '#') current_hash = current_hash.substring(1);
6317
6318		BX.ready(function ()
6319		{
6320			var test = current_hash.substring(0, 5);
6321			if (test == 'view/' || test == 'view%')
6322			{
6323				var obColNode = BX('__ajax_hash_collision_' + param_value);
6324				var obNode = obColNode.firstChild;
6325				BX.cleanNode(obNode);
6326				obColNode.style.display = 'block';
6327
6328				// IE, Opera and Chrome automatically modifies hash with urlencode, but FF doesn't ;-(
6329				if (test != 'view%')
6330					current_hash = BX.util.urlencode(current_hash);
6331
6332				current_hash += (current_hash.indexOf('%3F') == -1 ? '%3F' : '%26') + param_name + '=' + param_value;
6333
6334				var url = '/bitrix/tools/ajax_redirector.php?hash=' + current_hash;
6335
6336				BX.ajax.insertToNode(url, obNode);
6337			}
6338		});
6339	}
6340};
6341
6342BX.ajax.component = function(node)
6343{
6344	this.node = node;
6345};
6346
6347BX.ajax.component.prototype.getState = function()
6348{
6349	var state = {
6350		'node': this.node,
6351		'title': window.document.title,
6352		'data': BX(this.node).innerHTML
6353	};
6354
6355	var obNavChain = BX('navigation');
6356	if (null != obNavChain)
6357		state.nav_chain = obNavChain.innerHTML;
6358
6359	return state;
6360};
6361
6362BX.ajax.component.prototype.setState = function(state)
6363{
6364	BX(state.node).innerHTML = state.data;
6365	BX.ajax.UpdatePageTitle(state.title);
6366
6367	if (state.nav_chain)
6368		BX.ajax.UpdatePageNavChain(state.nav_chain);
6369};
6370
6371var jsAjaxHistoryContainer = {
6372	arHistory: {},
6373
6374	put: function(hash, state)
6375	{
6376		this.arHistory[hash] = state;
6377	},
6378
6379	get: function(hash)
6380	{
6381		return this.arHistory[hash];
6382	}
6383};
6384
6385
6386BX.ajax.FormData = function()
6387{
6388	this.elements = [];
6389	this.files = [];
6390	this.features = {};
6391	this.isSupported();
6392	this.log('BX FormData init');
6393};
6394
6395BX.ajax.FormData.isSupported = function()
6396{
6397	var f = new BX.ajax.FormData();
6398	var result = f.features.supported;
6399	f = null;
6400	return result;
6401};
6402
6403BX.ajax.FormData.prototype.log = function(o)
6404{
6405	if (false) {
6406		try {
6407			if (BX.browser.IsIE()) o = JSON.stringify(o);
6408			console.log(o);
6409		} catch(e) {}
6410	}
6411};
6412
6413BX.ajax.FormData.prototype.isSupported = function()
6414{
6415	var f = {};
6416	f.fileReader = (window.FileReader && window.FileReader.prototype.readAsBinaryString);
6417	f.readFormData = f.sendFormData = !!(window.FormData);
6418	f.supported = !!(f.readFormData && f.sendFormData);
6419	this.features = f;
6420	this.log('features:');
6421	this.log(f);
6422
6423	return f.supported;
6424};
6425
6426BX.ajax.FormData.prototype.append = function(name, value)
6427{
6428	if (typeof(value) === 'object') { // seems to be files element
6429		this.files.push({'name': name, 'value':value});
6430	} else {
6431		this.elements.push({'name': name, 'value':value});
6432	}
6433};
6434
6435BX.ajax.FormData.prototype.send = function(url, callbackOk, callbackProgress, callbackError)
6436{
6437	this.log('FD send');
6438	this.xhr = BX.ajax({
6439			'method': 'POST',
6440			'dataType': 'html',
6441			'url': url,
6442			'onsuccess': callbackOk,
6443			'onfailure': callbackError,
6444			'start': false,
6445			'preparePost':false
6446		});
6447
6448	if (callbackProgress)
6449	{
6450		this.xhr.upload.addEventListener(
6451			'progress',
6452			function(e) {
6453				if (e.lengthComputable)
6454					callbackProgress(e.loaded / (e.total || e.totalSize));
6455			},
6456			false
6457		);
6458	}
6459
6460	if (this.features.readFormData && this.features.sendFormData)
6461	{
6462		var fd = new FormData();
6463		this.log('use browser formdata');
6464		for (var i in this.elements)
6465		{
6466			if(this.elements.hasOwnProperty(i))
6467				fd.append(this.elements[i].name,this.elements[i].value);
6468		}
6469		for (i in this.files)
6470		{
6471			if(this.files.hasOwnProperty(i))
6472				fd.append(this.files[i].name, this.files[i].value);
6473		}
6474		this.xhr.send(fd);
6475	}
6476
6477	return this.xhr;
6478};
6479
6480BX.addCustomEvent('onAjaxFailure', BX.debug);
6481})(window);
6482
6483/* End */
6484;
6485; /* Start:/bitrix/js/main/json/json2.min.js*/
6486
6487var JSON;if(!JSON){JSON={};}
6488(function(){'use strict';function f(n){return n<10?'0'+n:n;}
6489if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+
6490f(this.getUTCMonth()+1)+'-'+
6491f(this.getUTCDate())+'T'+
6492f(this.getUTCHours())+':'+
6493f(this.getUTCMinutes())+':'+
6494f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}
6495var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];
6495return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}
6496function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}
6497if(typeof rep==='function'){value=rep.call(holder,key,value);}
6498switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
6499gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}
6500v=partial.length===0?'[]':gap?'[\n'+gap+partial.join(',\n'+gap)+'\n'+mind+']':'['+partial.join(',')+']';gap=mind;return v;}
6501if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){if(typeof rep[i]==='string'){k=rep[i];v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}
6502v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
6503if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}
6504rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}
6505return str('',{'':value});};}
6506if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}
6507return reviver.call(holder,key,value);}
6508text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+
6509('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
6510if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}
6511throw new SyntaxError('JSON.parse');};}}());
6512/* End */
6513;
6514; /* Start:/bitrix/js/main/core/core_ls.js*/
6515;(function(window){
6516if (window.BX.localStorage) return;
6517
6518var
6519	BX = window.BX,
6520	localStorageInstance = null,
6521	_prefix = null,
6522	_key = '_bxCurrentKey',
6523	_support = false;
6524
6525BX.localStorage = function()
6526{
6527	this.keyChanges = {}; // flag to skip self changes in IE
6528	BX.bind(
6529		(BX.browser.IsIE() && !BX.browser.IsIE9()) ? document : window, // HATE!
6530		'storage',
6531		BX.proxy(this._onchange, this)
6532	);
6533
6534	setInterval(BX.delegate(this._clear, this), 5000);
6535};
6536
6537/* localStorage public interface */
6538
6539BX.localStorage.checkBrowser = function()
6540{
6541	return _support;
6542};
6543
6544BX.localStorage.set = function(key, value, ttl)
6545{
6546	return BX.localStorage.instance().set(key, value, ttl);
6547};
6548
6549BX.localStorage.get = function(key)
6550{
6551	return BX.localStorage.instance().get(key);
6552};
6553
6554BX.localStorage.remove = function(key)
6555{
6556	return BX.localStorage.instance().remove(key);
6557};
6558
6559BX.localStorage.instance = function()
6560{
6561	if (!localStorageInstance)
6562	{
6563		var support = BX.localStorage.checkBrowser();
6564		if (support == 'native')
6565			localStorageInstance = new BX.localStorage();
6566		else if (support == 'ie8')
6567			localStorageInstance = new BX.localStorageIE8();
6568		else if (support == 'ie7')
6569			localStorageInstance = new BX.localStorageIE7();
6570		else
6571		{
6572			localStorageInstance = {
6573				'set' : BX.DoNothing,
6574				'get' : function(){return null},
6575				'remove' : BX.DoNothing
6576			};
6577		}
6578	}
6579	return localStorageInstance;
6580};
6581
6582/* localStorage prototype */
6583BX.localStorage.prototype.prefix = function()
6584{
6585	if (!_prefix)
6586	{
6587		_prefix = 'bx' + BX.message('USER_ID') + '-' + (BX.message('SITE_ID')||'admin') + '-';
6588	}
6589
6590	return _prefix;
6591};
6592
6593BX.localStorage.prototype._onchange = function(e)
6594{
6595	e = e || window.event;
6596
6597	if (!e.key)
6598		return;
6599
6600	if (BX.browser.DetectIeVersion() > 0 && this.keyChanges[e.key])
6601	{
6602		this.keyChanges[e.key] = false;
6603		return;
6604	}
6605
6606	if (!!e.key && e.key.substring(0,this.prefix().length) == this.prefix())
6607	{
6608		var d = {
6609			key: e.key.substring(this.prefix().length, e.key.length),
6610			value: !!e.newValue? this._decode(e.newValue.substring(11, e.newValue.length)): null,
6611			oldValue: !!e.oldValue? this._decode(e.oldValue.substring(11, e.oldValue.length)): null
6612		};
6613
6614		switch(d.key)
6615		{
6616			case 'BXGCE': // BX Global Custom Event
6617				if (d.value)
6618				{
6619					BX.onCustomEvent(d.value.e, d.value.p);
6620				}
6621			break;
6622			default:
6623				// normal event handlers
6624				if (e.newValue)
6625					BX.onCustomEvent(window, 'onLocalStorageSet', [d]);
6626				if (e.oldValue && !e.newValue)
6627					BX.onCustomEvent(window, 'onLocalStorageRemove', [d]);
6628
6629				BX.onCustomEvent(window, 'onLocalStorageChange', [d]);
6630			break;
6631		}
6632	}
6633};
6634
6635BX.localStorage.prototype._clear = function()
6636{
6637	var curDate = +new Date(), key, i;
6638
6639	for (i=0; i<localStorage.length; i++)
6640	{
6641		key = localStorage.key(i);
6642		if (key.substring(0,2) == 'bx')
6643		{
6644			var ttl = localStorage.getItem(key).split(':', 1)*1000;
6645			if (curDate >= ttl)
6646				localStorage.removeItem(key);
6647		}
6648	}
6649};
6650
6651BX.localStorage.prototype._encode = function(value)
6652{
6653	if (typeof(value) == 'object')
6654		value = JSON.stringify(value);
6655	else
6656		value = value.toString();
6657	return value;
6658};
6659
6660BX.localStorage.prototype._decode = function(value)
6661{
6662	var answer = null;
6663	if (!!value)
6664	{
6665		try {answer = JSON.parse(value);}
6666		catch(e) { answer = value; }
6667	}
6668	return answer;
6669};
6670
6671BX.localStorage.prototype._trigger_error = function(e, key, value, ttl)
6672{
6673	BX.onCustomEvent(this, 'onLocalStorageError', [e, {key: key, value: value, ttl: ttl}]);
6674};
6675
6676BX.localStorage.prototype.set = function(key, value, ttl)
6677{
6678	if (!ttl || ttl <= 0)
6679		ttl = 60;
6680
6681	if (key == undefined || key == null || value == undefined)
6682		return false;
6683
6684	this.keyChanges[this.prefix()+key] = true;
6685	try
6686	{
6687		localStorage.setItem(
6688			this.prefix()+key,
6689			(Math.round((+new Date())/1000)+ttl)+':'+this._encode(value)
6690		);
6691	}
6692	catch (e)
6693	{
6694		this._trigger_error(e, key, value, ttl);
6695	}
6696};
6697
6698BX.localStorage.prototype.get = function(key)
6699{
6700	var storageAnswer = localStorage.getItem(this.prefix()+key);
6701
6702	if (storageAnswer)
6703	{
6704		var ttl = storageAnswer.split(':', 1)*1000;
6705		if ((+new Date()) <= ttl)
6706		{
6707			storageAnswer = storageAnswer.substring(11, storageAnswer.length);
6708			return this._decode(storageAnswer);
6709		}
6710	}
6711
6712	return null;
6713};
6714
6715BX.localStorage.prototype.remove = function(key)
6716{
6717	this.keyChanges[this.prefix()+key] = true;
6718	localStorage.removeItem(this.prefix()+key);
6719};
6720
6721/************** IE 7 ******************/
6722
6723BX.localStorageIE7 = function()
6724{
6725	this.NS = 'BXLocalStorage';
6726	this.__current_state = {};
6727	this.keyChanges = {};
6728
6729	BX.ready(BX.delegate(this._Init, this));
6730};
6731
6732BX.extend(BX.localStorageIE7, BX.localStorage);
6733
6734BX.localStorageIE7.prototype._Init = function()
6735{
6736	this.storage_element = document.body.appendChild(BX.create('DIV'));
6737	this.storage_element.addBehavior('#default#userData');
6738	this.storage_element.load(this.NS);
6739
6740	var doc = this.storage_element.xmlDocument,
6741		len = doc.firstChild.attributes.length;
6742
6743	for (var i = 0; i<len; i++)
6744	{
6745		if (!!doc.firstChild.attributes[i])
6746		{
6747			var k = doc.firstChild.attributes[i].nodeName;
6748			if (k.substring(0,this.prefix().length) == this.prefix())
6749			{
6750				this.__current_state[k] = doc.firstChild.attributes[i].nodeValue;
6751			}
6752		}
6753	}
6754
6755	setInterval(BX.delegate(this._Listener, this), 500);
6756	setInterval(BX.delegate(this._clear, this), 5000);
6757};
6758
6759BX.localStorageIE7.prototype._Listener = function(bInit)
6760{
6761	this.storage_element.load(this.NS);
6762
6763	var doc = this.storage_element.xmlDocument,
6764		len = doc.firstChild.attributes.length,
6765		i,k,v;
6766
6767	var new_state = {}, arChanges = [];
6768
6769	for (i = 0; i<len; i++)
6770	{
6771		if (!!doc.firstChild.attributes[i])
6772		{
6773			k = doc.firstChild.attributes[i].nodeName;
6774			if (k.substring(0,this.prefix().length) == this.prefix())
6775			{
6776				v = doc.firstChild.attributes[i].nodeValue;
6777
6778				if (this.__current_state[k] != v)
6779				{
6780					arChanges.push({
6781						key: k, newValue: v, oldValue: this.__current_state[k]
6782					});
6783				}
6784
6785				new_state[k] = v;
6786				delete this.__current_state[k];
6787			}
6788		}
6789	}
6790
6791	for (i in this.__current_state)
6792	{
6793		if(this.__current_state.hasOwnProperty(i))
6794		{
6795			arChanges.push({
6796				key: i, newValue: undefined, oldValue: this.__current_state[i]
6797			});
6798		}
6799	}
6800
6801	this.__current_state = new_state;
6802
6803	for (i=0; i<arChanges.length; i++)
6804	{
6805		this._onchange(arChanges[i]);
6806	}
6807};
6808
6809BX.localStorageIE7.prototype._clear = function()
6810{
6811	this.storage_element.load(this.NS);
6812
6813	var doc = this.storage_element.xmlDocument,
6814		len = doc.firstChild.attributes.length,
6815		curDate = +new Date(),
6816		i,k,v,ttl;
6817
6818	for (i = 0; i<len; i++)
6819	{
6820		if (!!doc.firstChild.attributes[i])
6821		{
6822			k = doc.firstChild.attributes[i].nodeName;
6823			if (k.substring(0,2) == 'bx')
6824			{
6825				v = doc.firstChild.attributes[i].nodeValue;
6826				ttl = v.split(':', 1)*1000;
6827				if (curDate >= ttl)
6828				{
6829					doc.firstChild.removeAttribute(k)
6830				}
6831			}
6832		}
6833	}
6834
6835	this.storage_element.save(this.NS);
6836};
6837
6838BX.localStorageIE7.prototype.set = function(key, value, ttl)
6839{
6840	if (!ttl || ttl <= 0)
6841		ttl = 60;
6842
6843	try
6844	{
6845		this.storage_element.load(this.NS);
6846
6847		var doc = this.storage_element.xmlDocument;
6848
6849		this.keyChanges[this.prefix()+key] = true;
6850
6851		doc.firstChild.setAttribute(
6852			this.prefix()+key,
6853			(Math.round((+new Date())/1000)+ttl)+':'+this._encode(value)
6854		);
6855
6856		this.storage_element.save(this.NS);
6857	}
6858	catch(e)
6859	{
6860		this._trigger_error(e, key, value, ttl);
6861	}
6862};
6863
6864BX.localStorageIE7.prototype.get = function(key)
6865{
6866	this.storage_element.load(this.NS);
6867	var doc = this.storage_element.xmlDocument;
6868
6869	var storageAnswer = doc.firstChild.getAttribute(this.prefix()+key);
6870
6871	if (storageAnswer)
6872	{
6873		var ttl = storageAnswer.split(':', 1)*1000;
6874		if ((+new Date()) <= ttl)
6875		{
6876			storageAnswer = storageAnswer.substring(11, storageAnswer.length);
6877			return this._decode(storageAnswer);
6878		}
6879	}
6880
6881	return null;
6882};
6883
6884BX.localStorageIE7.prototype.remove = function(key)
6885{
6886	this.storage_element.load(this.NS);
6887
6888	var doc = this.storage_element.xmlDocument;
6889	doc.firstChild.removeAttribute(this.prefix()+key);
6890
6891	this.keyChanges[this.prefix()+key] = true;
6892	this.storage_element.save(this.NS);
6893};
6894
6895/************** IE 8 & FF 3.6 ***************/
6896
6897BX.localStorageIE8 = function()
6898{
6899	this.key = _key;
6900
6901	this.currentKey = null;
6902	this.currentValue = null;
6903
6904	BX.localStorageIE8.superclass.constructor.apply(this);
6905};
6906BX.extend(BX.localStorageIE8, BX.localStorage);
6907
6908BX.localStorageIE8.prototype._onchange = function(e)
6909{
6910	if (null == this.currentKey)
6911	{
6912		this.currentKey = localStorage.getItem(this.key);
6913		if (this.currentKey)
6914		{
6915			this.currentValue = localStorage.getItem(this.prefix() + this.currentKey);
6916		}
6917	}
6918	else
6919	{
6920		e = {
6921			key: this.prefix() + this.currentKey,
6922			newValue: localStorage.getItem(this.prefix() + this.currentKey),
6923			oldValue: this.currentValue
6924		};
6925
6926		this.currentKey = null;
6927		this.currentValue = null;
6928
6929		// especially for FF3.6
6930		if (this.keyChanges[e.key])
6931		{
6932			this.keyChanges[e.key] = false;
6933			return;
6934		}
6935
6936		BX.localStorageIE8.superclass._onchange.apply(this, [e]);
6937	}
6938};
6939
6940BX.localStorageIE8.prototype.set = function(key, value, ttl)
6941{
6942	this.currentKey = null;
6943	this.keyChanges[this.prefix()+key] = true;
6944
6945	try
6946	{
6947		localStorage.setItem(this.key, key);
6948		BX.localStorageIE8.superclass.set.apply(this, arguments);
6949	}
6950	catch(e)
6951	{
6952		this._trigger_error(e, key, value, ttl);
6953	}
6954};
6955
6956BX.localStorageIE8.prototype.remove = function(key)
6957{
6958	this.currentKey = null;
6959	this.keyChanges[this.prefix()+key] = true;
6960
6961	localStorage.setItem(this.key, key);
6962	BX.localStorageIE8.superclass.remove.apply(this, arguments);
6963};
6964
6965/* additional functions */
6966
6967BX.onGlobalCustomEvent = function(eventName, arEventParams, bSkipSelf)
6968{
6969	if (!!BX.localStorage.checkBrowser())
6970		BX.localStorage.set('BXGCE', {e:eventName,p:arEventParams}, 1);
6971
6972	if (!bSkipSelf)
6973		BX.onCustomEvent(eventName, arEventParams);
6974};
6975
6976/***************** initialize *********************/
6977
6978try {
6979	_support = !!localStorage.setItem;
6980} catch(e) {}
6981
6982if (_support)
6983{
6984	_support = 'native';
6985
6986	// hack to check FF3.6 && IE8
6987	var _target = (BX.browser.IsIE() && !BX.browser.IsIE9()) ? document : window,
6988		_checkFFnIE8 = function(e) {
6989		if (typeof(e||window.event).key == 'undefined')
6990			_support = 'ie8';
6991		BX.unbind(_target, 'storage', _checkFFnIE8);
6992		BX.localStorage.instance();
6993	};
6994	BX.bind(_target, 'storage', _checkFFnIE8);
6995	localStorage.setItem(_key, null);
6996}
6997else if (BX.browser.IsIE7())
6998{
6999	_support = 'ie7';
7000	BX.localStorage.instance();
7001}
7002
7003})(window);
7004
7005/* End */
7006;
7007; /* Start:/bitrix/js/main/session.js*/
7008function CBXSession()
7009{
7010	var _this = this;
7011	this.mess = {};
7012	this.timeout = null;
7013	this.sessid = null;
7014	this.bShowMess = true;
7015	this.dateStart = new Date();
7016	this.dateInput = new Date();
7017	this.dateCheck = new Date();
7018	this.activityInterval = 0;
7019	this.notifier = null;
7020	
7021	this.Expand = function(timeout, sessid, bShowMess, key)
7022	{
7023		this.timeout = timeout;
7024		this.sessid = sessid;
7025		this.bShowMess = bShowMess;
7026		this.key = key;
7027		
7028		BX.ready(function(){
7029			BX.bind(document, "keypress", _this.OnUserInput);
7030			BX.bind(document.body, "mousemove", _this.OnUserInput);
7031			BX.bind(document.body, "click", _this.OnUserInput);
7032			
7033			setTimeout(_this.CheckSession, (_this.timeout-60)*1000);
7034		})
7035	};
7036		
7037	this.OnUserInput = function()
7038	{
7039		var curr = new Date();
7040		_this.dateInput.setTime(curr.valueOf());
7041	};
7042	
7043	this.CheckSession = function()
7044	{
7045		var curr = new Date();
7046		if(curr.valueOf() - _this.dateCheck.valueOf() < 30000)
7047			return;
7048
7049		_this.activityInterval = Math.round((_this.dateInput.valueOf() - _this.dateStart.valueOf())/1000);
7050		_this.dateStart.setTime(_this.dateInput.valueOf());
7051		var interval = (_this.activityInterval > _this.timeout? (_this.timeout-60) : _this.activityInterval);
7052
7053		var config = {
7054			'method': 'GET',
7055			'dataType': 'html',
7056			'url': '/bitrix/tools/public_session.php?sessid='+_this.sessid+'&interval='+interval+'&k='+_this.key,
7057			'data':  '',
7058			'onsuccess': function(data){_this.CheckResult(data)},
7059			'lsId': 'sess_expand', //caching the result in the local storage for multiple tabs
7060			'lsTimeout': 60
7061		};
7062		if(interval > 0)
7063		{
7064			//forced request
7065			config.lsForce = true;
7066		}
7067		BX.ajax(config);
7068	};
7069	
7070	this.CheckResult = function(data)
7071	{
7072		if(data == 'SESSION_EXPIRED')
7073		{
7074			if(_this.bShowMess)
7075			{
7076				if(!_this.notifier)
7077				{
7078					_this.notifier = document.body.appendChild(BX.create('DIV', {
7079						props: {className: 'bx-session-message'},
7080						style: {top: '0px'},
7081						html: '<a class="bx-session-message-close" href="javascript:bxSession.Close()"></a>'+_this.mess.messSessExpired
7082					}));
7083
7084					var windowScroll = BX.GetWindowScrollPos();
7085					var windowSize = BX.GetWindowInnerSize();
7086
7087					_this.notifier.style.left = parseInt(windowScroll.scrollLeft + windowSize.innerWidth / 2 - parseInt(_this.notifier.clientWidth) / 2) + 'px';
7088
7089					if(BX.browser.IsIE())
7090					{
7091						_this.notifier.style.top = windowScroll.scrollTop + 'px';
7092
7093						BX.bind(window, 'scroll', function()
7094						{
7095							var windowScroll = BX.GetWindowScrollPos();
7096							_this.notifier.style.top = windowScroll.scrollTop + 'px';
7097						});
7098					}
7099					else
7100					{
7101						_this.notifier.style.position='fixed';
7102					}
7103				}
7104
7105				_this.notifier.style.display = '';
7106			}
7107		}
7108		else
7109		{
7110			var timeout;
7111			if(data == 'SESSION_CHANGED')
7112				timeout = (_this.timeout-60);
7113			else
7114				timeout = (_this.activityInterval < 60? 60 : (_this.activityInterval > _this.timeout? (_this.timeout-60) : _this.activityInterval));
7115
7116			var curr = new Date();
7117			_this.dateCheck.setTime(curr.valueOf());
7118			setTimeout(_this.CheckSession, timeout*1000);
7119		}
7120	};
7121	
7122	this.Close = function()
7123	{
7124		this.notifier.style.display = 'none';
7125	}
7126}
7127
7128var bxSession = new CBXSession();
7129/* End */
7130;
7131; /* Start:/bitrix/js/main/core/core_window.js*/
7132;(function(window) {
7133if (BX.WindowManager) return;
7134
7135/* windows manager */
7136BX.WindowManager = {
7137	_stack: [],
7138	_runtime_resize: {},
7139	_delta: 2,
7140	_delta_start: 1000,
7141	currently_loaded: null,
7142
7143	settings_category: 'BX.WindowManager.9.5',
7144
7145	register: function (w)
7146	{
7147		this.currently_loaded = null;
7148		var div = w.Get();
7149
7150		div.style.zIndex = w.zIndex = this.GetZIndex();
7151
7152		w.WM_REG_INDEX = this._stack.length;
7153		this._stack.push(w);
7154
7155		if (this._stack.length < 2)
7156		{
7157			BX.bind(document, 'keyup', BX.proxy(this.__checkKeyPress, this));
7158		}
7159	},
7160
7161	unregister: function (w)
7162	{
7163		if (null == w.WM_REG_INDEX)
7164			return null;
7165
7166		var _current;
7167		if (this._stack.length > 0)
7168		{
7169			while ((_current = this.__pop_stack()) != w)
7170			{
7171				if (!_current)
7172				{
7173					_current = null;
7174					break;
7175				}
7176			}
7177
7178			if (this._stack.length <= 0)
7179			{
7180				this.enableKeyCheck();
7181			}
7182
7183			return _current;
7184		}
7185		else
7186		{
7187			return null;
7188		}
7189	},
7190
7191	__pop_stack: function(clean)
7192	{
7193		if (this._stack.length > 0)
7194		{
7195			var _current = this._stack.pop();
7196			_current.WM_REG_INDEX = null;
7197			BX.onCustomEvent(_current, 'onWindowUnRegister', [clean === true]);
7198
7199			return _current;
7200		}
7201		else
7202			return null;
7203	},
7204
7205	clean: function()
7206	{
7207		while (this.__pop_stack(true)){}
7208		this._stack = null;
7209		this.disableKeyCheck();
7210	},
7211
7212	Get: function()
7213	{
7214		if (this.currently_loaded)
7215			return this.currently_loaded;
7216		else if (this._stack.length > 0)
7217			return this._stack[this._stack.length-1];
7218		else
7219			return null;
7220	},
7221
7222	setStartZIndex: function(value)
7223	{
7224		this._delta_start = value;
7225	},
7226
7227	restoreStartZIndex: function()
7228	{
7229		this._delta_start = 1000;
7230	},
7231
7232	GetZIndex: function()
7233	{
7234		var _current;
7235		return (null != (_current = this._stack[this._stack.length-1])
7236			? parseInt(_current.Get().style.zIndex) + this._delta
7237			: this._delta_start
7238		);
7239	},
7240
7241	__get_check_url: function(url)
7242	{
7243		var pos = url.indexOf('?');
7244		return pos == -1 ? url : url.substring(0, pos);
7245	},
7246
7247	saveWindowSize: function(url, params)
7248	{
7249		var check_url = this.__get_check_url(url);
7250		if (BX.userOptions)
7251		{
7252			BX.userOptions.save(this.settings_category, 'size_' + check_url, 'width', params.width);
7253			BX.userOptions.save(this.settings_category, 'size_' + check_url, 'height', params.height);
7254		}
7255
7256		this._runtime_resize[check_url] = params;
7257	},
7258
7259	saveWindowOptions: function(wnd_id, opts)
7260	{
7261		if (BX.userOptions)
7262		{
7263			for (var i in opts)
7264			{
7265				if(opts.hasOwnProperty(i))
7266				{
7267					BX.userOptions.save(this.settings_category, 'options_' + wnd_id, i, opts[i]);
7268				}
7269			}
7270		}
7271	},
7272
7273	getRuntimeWindowSize: function(url)
7274	{
7275		return this._runtime_resize[this.__get_check_url(url)];
7276	},
7277
7278	disableKeyCheck: function()
7279	{
7280		BX.unbind(document, 'keyup', BX.proxy(this.__checkKeyPress, this));
7281	},
7282
7283	enableKeyCheck: function()
7284	{
7285		BX.bind(document, 'keyup', BX.proxy(this.__checkKeyPress, this));
7286	},
7287
7288	__checkKeyPress: function(e)
7289	{
7290		if (null == e)
7291			e = window.event;
7292
7293		if (e.keyCode == 27)
7294		{
7295			var wnd = BX.WindowManager.Get();
7296			if (wnd && !wnd.unclosable) wnd.Close();
7297		}
7298	}
7299};
7300
7301BX.garbage(BX.WindowManager.clean, BX.WindowManager);
7302
7303/* base button class */
7304BX.CWindowButton = function(params)
7305{
7306	if (params.btn)
7307	{
7308		this.btn = params.btn;
7309		this.parentWindow = params.parentWindow;
7310
7311		if (/save|apply/i.test(this.btn.name))
7312		{
7313			BX.bind(this.btn, 'click', BX.delegate(this.disableUntilError, this));
7314		}
7315	}
7316	else
7317	{
7318		this.title = params.title; // html value attr
7319		this.hint = params.hint; // html title attr
7320		this.id = params.id; // html name and id attrs
7321		this.name = params.name; // html name or value attrs when id and title 're absent
7322		this.className = params.className; // className for button input
7323
7324		this.action = params.action;
7325		this.onclick = params.onclick;
7326
7327		// you can override button creation method
7328		if (params.Button && BX.type.isFunction(params.Button))
7329			this.Button = params.Button;
7330
7331		this.btn = null;
7332	}
7333};
7334
7335BX.CWindowButton.prototype.disable = function()
7336{
7337	if (this.btn)
7338		this.parentWindow.showWait(this.btn);
7339};
7340BX.CWindowButton.prototype.enable = function(){
7341	if (this.btn)
7342		this.parentWindow.closeWait(this.btn);
7343};
7344
7345BX.CWindowButton.prototype.emulate = function()
7346{
7347	if (this.btn && this.btn.disabled)
7348		return;
7349
7350	var act =
7351		this.action
7352		? BX.delegate(this.action, this)
7353		: (
7354			this.onclick
7355			? this.onclick
7356			: (
7357				this.btn
7358				? this.btn.getAttribute('onclick')
7359				: ''
7360			)
7361		);
7362
7363	if (act)
7364	{
7365		setTimeout(act, 50);
7366		if (this.btn && /save|apply/i.test(this.btn.name) && !this.action)
7367		{
7368			this.disableUntilError();
7369		}
7370	}
7371};
7372
7373BX.CWindowButton.prototype.Button = function(parentWindow)
7374{
7375	this.parentWindow = parentWindow;
7376
7377	var btn = {
7378		props: {
7379			'type': 'button',
7380			'name': this.id ? this.id : this.name,
7381			'value': this.title ? this.title : this.name,
7382			'id': this.id
7383		}
7384	};
7385
7386	if (this.hint)
7387		btn.props.title = this.hint;
7388	if (!!this.className)
7389		btn.props.className = this.className;
7390
7391	if (this.action)
7392	{
7393		btn.events = {
7394			'click': BX.delegate(this.action, this)
7395		};
7396	}
7397	else if (this.onclick)
7398	{
7399		if (BX.browser.IsIE())
7400		{
7401			btn.events = {
7402				'click': BX.delegate(function() {eval(this.onclick)}, this)
7403			};
7404		}
7405		else
7406		{
7407			btn.attrs = {
7408				'onclick': this.onclick
7409			};
7410		}
7411	}
7412
7413	this.btn = BX.create('INPUT', btn);
7414
7415	return this.btn;
7416};
7417
7418BX.CWindowButton.prototype.disableUntilError = function() {
7419	this.disable();
7420	if (!this.__window_error_handler_set)
7421	{
7422		BX.addCustomEvent(this.parentWindow, 'onWindowError', BX.delegate(this.enable, this));
7423		this.__window_error_handler_set = true;
7424	}
7425};
7426
7427/* base window class */
7428BX.CWindow = function(div, type)
7429{
7430	this.DIV = div || document.createElement('DIV');
7431
7432	this.SETTINGS = {
7433		resizable: false,
7434		min_height: 0,
7435		min_width: 0,
7436		top: 0,
7437		left: 0,
7438		draggable: false,
7439		drag_restrict: true,
7440		resize_restrict: true
7441	};
7442
7443	this.ELEMENTS = {
7444		draggable: [],
7445		resizer: [],
7446		close: []
7447	};
7448
7449	this.type = type == 'float' ? 'float' : 'dialog';
7450
7451	BX.adjust(this.DIV, {
7452		props: {
7453			className: 'bx-core-window'
7454		},
7455		style: {
7456			'zIndex': 0,
7457			'position': 'absolute',
7458			'display': 'none',
7459			'top': this.SETTINGS.top + 'px',
7460			'left': this.SETTINGS.left + 'px',
7461			'height': '100px',
7462			'width': '100px'
7463		}
7464	});
7465
7466	this.isOpen = false;
7467
7468	BX.addCustomEvent(this, 'onWindowRegister', BX.delegate(this.onRegister, this));
7469	BX.addCustomEvent(this, 'onWindowUnRegister', BX.delegate(this.onUnRegister, this));
7470
7471	this.MOUSEOVER = null;
7472	BX.bind(this.DIV, 'mouseover', BX.delegate(this.__set_msover, this));
7473	BX.bind(this.DIV, 'mouseout', BX.delegate(this.__unset_msover, this));
7474
7475	BX.ready(BX.delegate(function() {
7476		document.body.appendChild(this.DIV);
7477	}, this));
7478};
7479
7480BX.CWindow.prototype.Get = function () {return this.DIV};
7481BX.CWindow.prototype.visible = function() {return this.isOpen;};
7482
7483BX.CWindow.prototype.Show = function(bNotRegister)
7484{
7485	this.DIV.style.display = 'block';
7486
7487	if (!bNotRegister)
7488	{
7489		BX.WindowManager.register(this);
7490		BX.onCustomEvent(this, 'onWindowRegister');
7491	}
7492};
7493
7494BX.CWindow.prototype.Hide = function()
7495{
7496	BX.WindowManager.unregister(this);
7497	this.DIV.style.display = 'none';
7498};
7499
7500BX.CWindow.prototype.onRegister = function()
7501{
7502	this.isOpen = true;
7503};
7504
7505BX.CWindow.prototype.onUnRegister = function(clean)
7506{
7507	this.isOpen = false;
7508
7509	if (clean || (this.PARAMS && this.PARAMS.content_url))
7510	{
7511		if (clean) {BX.onCustomEvent(this, 'onWindowClose', [this, true]);}
7512
7513		if (this.DIV.parentNode)
7514			this.DIV.parentNode.removeChild(this.DIV);
7515	}
7516	else
7517	{
7518		this.DIV.style.display = 'none';
7519	}
7520};
7521
7522BX.CWindow.prototype.CloseDialog = // compatibility
7523BX.CWindow.prototype.Close = function(bImmediately)
7524{
7525	BX.onCustomEvent(this, 'onBeforeWindowClose', [this]);
7526	if (bImmediately !== true)
7527	{
7528		if (this.denyClose)
7529			return false;
7530	}
7531
7532	BX.onCustomEvent(this, 'onWindowClose', [this]);
7533
7534	//this crashes vis editor in ie via onWindowResizeExt event handler
7535	//if (this.bExpanded) this.__expand();
7536	// alternative version:
7537	if (this.bExpanded)
7538	{
7539		var pDocElement = BX.GetDocElement();
7540		BX.unbind(window, 'resize', BX.proxy(this.__expand_onresize, this));
7541		pDocElement.style.overflow = this.__expand_settings.overflow;
7542	}
7543
7544	BX.WindowManager.unregister(this);
7545
7546	return true;
7547};
7548
7549BX.CWindow.prototype.SetResize = function(elem)
7550{
7551	elem.style.cursor = 'se-resize';
7552	BX.bind(elem, 'mousedown', BX.proxy(this.__startResize, this));
7553
7554	this.ELEMENTS.resizer.push(elem);
7555	this.SETTINGS.resizable = true;
7556};
7557
7558BX.CWindow.prototype.SetExpand = function(elem, event_name)
7559{
7560	event_name = event_name || 'click';
7561	BX.bind(elem, event_name, BX.proxy(this.__expand, this));
7562};
7563
7564BX.CWindow.prototype.__expand_onresize = function()
7565{
7566	var windowSize = BX.GetWindowInnerSize();
7567	this.DIV.style.width = windowSize.innerWidth + "px";
7568	this.DIV.style.height = windowSize.innerHeight + "px";
7569
7570	BX.onCustomEvent(this, 'onWindowResize');
7571};
7572
7573BX.CWindow.prototype.__expand = function()
7574{
7575	var pDocElement = BX.GetDocElement();
7576
7577	if (!this.bExpanded)
7578	{
7579		var wndScroll = BX.GetWindowScrollPos(),
7580			wndSize = BX.GetWindowInnerSize();
7581
7582		this.__expand_settings = {
7583			resizable: this.SETTINGS.resizable,
7584			draggable: this.SETTINGS.draggable,
7585			width: this.DIV.style.width,
7586			height: this.DIV.style.height,
7587			left: this.DIV.style.left,
7588			top: this.DIV.style.top,
7589			scrollTop: wndScroll.scrollTop,
7590			scrollLeft: wndScroll.scrollLeft,
7591			overflow: BX.style(pDocElement, 'overflow')
7592		};
7593
7594		this.SETTINGS.resizable = false;
7595		this.SETTINGS.draggable = false;
7596
7597		window.scrollTo(0,0);
7598		pDocElement.style.overflow = 'hidden';
7599
7600		this.DIV.style.top = '0px';
7601		this.DIV.style.left = '0px';
7602
7603		this.DIV.style.width = wndSize.innerWidth + 'px';
7604		this.DIV.style.height = wndSize.innerHeight + 'px';
7605
7606		this.bExpanded = true;
7607
7608		BX.onCustomEvent(this, 'onWindowExpand');
7609		BX.onCustomEvent(this, 'onWindowResize');
7610
7611		BX.bind(window, 'resize', BX.proxy(this.__expand_onresize, this));
7612	}
7613	else
7614	{
7615		BX.unbind(window, 'resize', BX.proxy(this.__expand_onresize, this));
7616
7617		this.SETTINGS.resizable = this.__expand_settings.resizable;
7618		this.SETTINGS.draggable = this.__expand_settings.draggable;
7619
7620		pDocElement.style.overflow = this.__expand_settings.overflow;
7621
7622		this.DIV.style.top = this.__expand_settings.top;
7623		this.DIV.style.left = this.__expand_settings.left;
7624		this.DIV.style.width = this.__expand_settings.width;
7625		this.DIV.style.height = this.__expand_settings.height;
7626
7627		window.scrollTo(this.__expand_settings.scrollLeft, this.__expand_settings.scrollTop);
7628
7629		this.bExpanded = false;
7630
7631		BX.onCustomEvent(this, 'onWindowNarrow');
7632		BX.onCustomEvent(this, 'onWindowResize');
7633
7634	}
7635};
7636
7637BX.CWindow.prototype.Resize = function(x, y)
7638{
7639	var new_width = Math.max(x - this.pos.left + this.dx, this.SETTINGS.min_width);
7640	var new_height = Math.max(y - this.pos.top + this.dy, this.SETTINGS.min_height);
7641
7642	if (this.SETTINGS.resize_restrict)
7643	{
7644		var scrollSize = BX.GetWindowScrollSize();
7645
7646		if (this.pos.left + new_width > scrollSize.scrollWidth - this.dw)
7647			new_width = scrollSize.scrollWidth - this.pos.left - this.dw;
7648	}
7649
7650	this.DIV.style.width = new_width + 'px';
7651	this.DIV.style.height = new_height + 'px';
7652
7653	BX.onCustomEvent(this, 'onWindowResize');
7654};
7655
7656BX.CWindow.prototype.__startResize = function(e)
7657{
7658	if (!this.SETTINGS.resizable)
7659		return false;
7660
7661	if(!e) e = window.event;
7662
7663	this.wndSize = BX.GetWindowScrollPos();
7664	this.wndSize.innerWidth = BX.GetWindowInnerSize().innerWidth;
7665
7666	this.pos = BX.pos(this.DIV);
7667
7668	this.x = e.clientX + this.wndSize.scrollLeft;
7669	this.y = e.clientY + this.wndSize.scrollTop;
7670
7671	this.dx = this.pos.left + this.pos.width - this.x;
7672	this.dy = this.pos.top + this.pos.height - this.y;
7673	this.dw = this.pos.width - parseInt(this.DIV.style.width);
7674
7675	BX.bind(document, "mousemove", BX.proxy(this.__moveResize, this));
7676	BX.bind(document, "mouseup", BX.proxy(this.__stopResize, this));
7677
7678	if(document.body.setCapture)
7679		document.body.setCapture();
7680
7681	document.onmousedown = BX.False;
7682
7683	var b = document.body;
7684	b.ondrag = b.onselectstart = BX.False;
7685	b.style.MozUserSelect = this.DIV.style.MozUserSelect = 'none';
7686	b.style.cursor = 'se-resize';
7687
7688	BX.onCustomEvent(this, 'onWindowResizeStart');
7689
7690	return true;
7691};
7692
7693BX.CWindow.prototype.__moveResize = function(e)
7694{
7695	if(!e) e = window.event;
7696
7697	var windowScroll = BX.GetWindowScrollPos();
7698
7699	var x = e.clientX + windowScroll.scrollLeft;
7700	var y = e.clientY + windowScroll.scrollTop;
7701
7702	if(this.x == x && this.y == y)
7703		return;
7704
7705	this.Resize(x, y);
7706
7707	this.x = x;
7708	this.y = y;
7709};
7710
7711BX.CWindow.prototype.__stopResize = function()
7712{
7713	if(document.body.releaseCapture)
7714		document.body.releaseCapture();
7715
7716	BX.unbind(document, "mousemove", BX.proxy(this.__moveResize, this));
7717	BX.unbind(document, "mouseup", BX.proxy(this.__stopResize, this));
7718
7719	document.onmousedown = null;
7720
7721	var b = document.body;
7722	b.ondrag = b.onselectstart = null;
7723	b.style.MozUserSelect = this.DIV.style.MozUserSelect = '';
7724	b.style.cursor = '';
7725
7726	BX.onCustomEvent(this, 'onWindowResizeFinished')
7727};
7728
7729BX.CWindow.prototype.SetClose = function(elem)
7730{
7731	BX.bind(elem, 'click', BX.proxy(this.Close, this));
7732	this.ELEMENTS.close.push(elem);
7733};
7734
7735BX.CWindow.prototype.SetDraggable = function(elem)
7736{
7737	BX.bind(elem, 'mousedown', BX.proxy(this.__startDrag, this));
7738
7739	elem.style.cursor = 'move';
7740
7741	this.ELEMENTS.draggable.push(elem);
7742	this.SETTINGS.draggable = true;
7743};
7744
7745BX.CWindow.prototype.Move = function(x, y)
7746{
7747	var dxShadow = 1; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7748
7749	var left = parseInt(this.DIV.style.left)+x;
7750	var top = parseInt(this.DIV.style.top)+y;
7751
7752	if (this.SETTINGS.drag_restrict)
7753	{
7754		//Left side
7755		if (left < 0)
7756			left = 0;
7757
7758		//Right side
7759		var scrollSize = BX.GetWindowScrollSize();
7760		var floatWidth = this.DIV.offsetWidth;
7761		var floatHeight = this.DIV.offsetHeight;
7762
7763		if (left > (scrollSize.scrollWidth - floatWidth - dxShadow))
7764			left = scrollSize.scrollWidth - floatWidth - dxShadow;
7765
7766		if (top > (scrollSize.scrollHeight - floatHeight - dxShadow))
7767			top = scrollSize.scrollHeight - floatHeight - dxShadow;
7768
7769		//Top side
7770		if (top < 0)
7771			top = 0;
7772	}
7773
7774	this.DIV.style.left = left+'px';
7775	this.DIV.style.top = top+'px';
7776
7777	//this.AdjustShadow(div);
7778};
7779
7780BX.CWindow.prototype.__startDrag = function(e)
7781{
7782	if (!this.SETTINGS.draggable)
7783		return false;
7784
7785	if(!e) e = window.event;
7786
7787	this.x = e.clientX + document.body.scrollLeft;
7788	this.y = e.clientY + document.body.scrollTop;
7789
7790	this.__bWasDragged = false;
7791	BX.bind(document, "mousemove", BX.proxy(this.__moveDrag, this));
7792	BX.bind(document, "mouseup", BX.proxy(this.__stopDrag, this));
7793
7794	if(document.body.setCapture)
7795		document.body.setCapture();
7796
7797	document.onmousedown = BX.False;
7798
7799	var b = document.body;
7800	b.ondrag = b.onselectstart = BX.False;
7801	b.style.MozUserSelect = this.DIV.style.MozUserSelect = 'none';
7802	b.style.cursor = 'move';
7803	return BX.PreventDefault(e);
7804};
7805
7806BX.CWindow.prototype.__moveDrag = function(e)
7807{
7808	if(!e) e = window.event;
7809
7810	var x = e.clientX + document.body.scrollLeft;
7811	var y = e.clientY + document.body.scrollTop;
7812
7813	if(this.x == x && this.y == y)
7814		return;
7815
7816	this.Move((x - this.x), (y - this.y));
7817	this.x = x;
7818	this.y = y;
7819
7820	if (!this.__bWasDragged)
7821	{
7822		BX.onCustomEvent(this, 'onWindowDragStart');
7823		this.__bWasDragged = true;
7824		BX.bind(BX.proxy_context, "click", BX.PreventDefault);
7825	}
7826
7827	BX.onCustomEvent(this, 'onWindowDrag');
7828};
7829
7830BX.CWindow.prototype.__stopDrag = function(e)
7831{
7832	if(document.body.releaseCapture)
7833		document.body.releaseCapture();
7834
7835	BX.unbind(document, "mousemove", BX.proxy(this.__moveDrag, this));
7836	BX.unbind(document, "mouseup", BX.proxy(this.__stopDrag, this));
7837
7838	document.onmousedown = null;
7839
7840	var b = document.body;
7841	b.ondrag = b.onselectstart = null;
7842	b.style.MozUserSelect = this.DIV.style.MozUserSelect = '';
7843	b.style.cursor = '';
7844
7845	if (this.__bWasDragged)
7846	{
7847		BX.onCustomEvent(this, 'onWindowDragFinished');
7848		var _proxy_context = BX.proxy_context;
7849		setTimeout(function(){BX.unbind(_proxy_context, "click", BX.PreventDefault)}, 100);
7850		this.__bWasDragged = false;
7851	}
7852	return BX.PreventDefault(e);
7853};
7854
7855BX.CWindow.prototype.DenyClose = function()
7856{
7857	this.denyClose = true;
7858};
7859
7860BX.CWindow.prototype.AllowClose = function()
7861{
7862	this.denyClose = false;
7863};
7864
7865BX.CWindow.prototype.ShowError = function(str)
7866{
7867	BX.onCustomEvent(this, 'onWindowError', [str]);
7868
7869	if (this._wait)
7870		BX.closeWait(this._wait);
7871
7872	window.alert(str);
7873};
7874
7875BX.CWindow.prototype.__set_msover = function() {this.MOUSEOVER = true;};
7876BX.CWindow.prototype.__unset_msover = function() {this.MOUSEOVER = false;};
7877
7878/* dialog window class extends window class */
7879BX.CWindowDialog = function() {
7880	var a = arguments;
7881	a[1] = 'dialog';
7882	BX.CWindowDialog.superclass.constructor.apply(this, a);
7883
7884	this.DIV.style.top = '10px';
7885	this.OVERLAY = null;
7886};
7887BX.extend(BX.CWindowDialog, BX.CWindow);
7888
7889BX.CWindowDialog.prototype.__resizeOverlay = function()
7890{
7891	var windowSize = BX.GetWindowScrollSize();
7892	this.OVERLAY.style.width = windowSize.scrollWidth + "px";
7893};
7894
7895BX.CWindowDialog.prototype.CreateOverlay = function(zIndex)
7896{
7897	if (null == this.OVERLAY)
7898	{
7899		var windowSize = BX.GetWindowScrollSize();
7900		this.OVERLAY = document.body.appendChild(BX.create("DIV", {
7901			style: {
7902				position: 'absolute',
7903				top: '0px',
7904				left: '0px',
7905				zIndex: zIndex || (parseInt(this.DIV.style.zIndex)-2),
7906				width: windowSize.scrollWidth + "px",
7907				height: windowSize.scrollHeight + "px"
7908			}
7909		}));
7910	}
7911
7912	return this.OVERLAY;
7913};
7914
7915BX.CWindowDialog.prototype.Show = function()
7916{
7917	BX.CWindowDialog.superclass.Show.apply(this, arguments);
7918
7919	this.CreateOverlay();
7920
7921	this.OVERLAY.style.display = 'block';
7922	this.OVERLAY.style.zIndex = parseInt(this.DIV.style.zIndex)-2;
7923
7924	BX.unbind(window, 'resize', BX.proxy(this.__resizeOverlay, this));
7925	BX.bind(window, 'resize', BX.proxy(this.__resizeOverlay, this));
7926};
7927
7928BX.CWindowDialog.prototype.onUnRegister = function(clean)
7929{
7930	BX.CWindowDialog.superclass.onUnRegister.apply(this, arguments);
7931
7932	if (this.clean)
7933	{
7934		if (this.OVERLAY.parentNode)
7935			this.OVERLAY.parentNode.removeChild(this.OVERLAY);
7936	}
7937	else
7938	{
7939		this.OVERLAY.style.display = 'none';
7940	}
7941
7942	BX.unbind(window, 'resize', BX.proxy(this.__resizeOverlay, this));
7943};
7944
7945/* standard bitrix dialog extends BX.CWindowDialog */
7946/*
7947	arParams = {
7948		(
7949			title: 'dialog title',
7950			head: 'head block html',
7951			content: 'dialog content',
7952			icon: 'head icon classname or filename',
7953
7954			resize_id: 'some id to save resize information'// useless if resizable = false
7955		)
7956		or
7957		(
7958			content_url: url to content load
7959				loaded content scripts can use BX.WindowManager.Get() to get access to the current window object
7960		)
7961
7962		height: window_height_in_pixels,
7963		width: window_width_in_pixels,
7964
7965		draggable: true|false,
7966		resizable: true|false,
7967
7968		min_height: min_window_height_in_pixels, // useless if resizable = false
7969		min_width: min_window_width_in_pixels, // useless if resizable = false
7970
7971		buttons: [
7972			'html_code',
7973			BX.CDialog.btnSave, BX.CDialog.btnCancel, BX.CDialog.btnClose
7974		]
7975	}
7976*/
7977BX.CDialog = function(arParams)
7978{
7979	BX.CDialog.superclass.constructor.apply(this);
7980
7981	this._sender = 'core_window_cdialog';
7982
7983	this.PARAMS = arParams || {};
7984
7985	for (var i in this.defaultParams)
7986	{
7987		if (typeof this.PARAMS[i] == 'undefined')
7988			this.PARAMS[i] = this.defaultParams[i];
7989	}
7990
7991	this.PARAMS.width = (!isNaN(parseInt(this.PARAMS.width)))
7992		? this.PARAMS.width
7993		: this.defaultParams['width'];
7994	this.PARAMS.height = (!isNaN(parseInt(this.PARAMS.height)))
7995		? this.PARAMS.height
7996		: this.defaultParams['height'];
7997
7998	if (this.PARAMS.resize_id || this.PARAMS.content_url)
7999	{
8000		var arSize = BX.WindowManager.getRuntimeWindowSize(this.PARAMS.resize_id || this.PARAMS.content_url);
8001		if (arSize)
8002		{
8003			this.PARAMS.width = arSize.width;
8004			this.PARAMS.height = arSize.height;
8005		}
8006	}
8007
8008	BX.addClass(this.DIV, 'bx-core-adm-dialog');
8009	this.DIV.id = 'bx-admin-prefix';
8010
8011	this.PARTS = {};
8012
8013	this.DIV.style.height = null;
8014	this.DIV.style.width = null;
8015
8016	this.PARTS.TITLEBAR = this.DIV.appendChild(BX.create('DIV', {props: {
8017			className: 'bx-core-adm-dialog-head'
8018		}
8019	}));
8020
8021	this.PARTS.TITLE_CONTAINER = this.PARTS.TITLEBAR.appendChild(BX.create('SPAN', {
8022		props: {className: 'bx-core-adm-dialog-head-inner'},
8023		text: this.PARAMS.title
8024	}));
8025
8026	this.PARTS.TITLEBAR_ICONS = this.PARTS.TITLEBAR.appendChild(BX.create('DIV', {
8027		props: {
8028			className: 'bx-core-adm-dialog-head-icons'
8029		},
8030		children: (this.PARAMS.resizable ? [
8031			BX.create('SPAN', {props: {className: 'bx-core-adm-icon-expand', title: BX.message('JS_CORE_WINDOW_EXPAND')}}),
8032			BX.create('SPAN', {props: {className: 'bx-core-adm-icon-close', title: BX.message('JS_CORE_WINDOW_CLOSE')}})
8033		] : [
8034			BX.create('SPAN', {props: {className: 'bx-core-adm-icon-close', title: BX.message('JS_CORE_WINDOW_CLOSE')}})
8035		])
8036	}));
8037
8038
8039	this.PARTS.CONTENT = this.DIV.appendChild(BX.create('DIV', {
8040		props: {className: 'bx-core-adm-dialog-content-wrap adm-workarea'}
8041	}));
8042
8043	this.PARTS.CONTENT_DATA = this.PARTS.CONTENT.appendChild(BX.create('DIV', {
8044		props: {className: 'bx-core-adm-dialog-content'},
8045		style: {
8046			height: this.PARAMS.height + 'px',
8047			width: this.PARAMS.width + 'px'
8048		}
8049	}));
8050
8051	this.PARTS.HEAD = this.PARTS.CONTENT_DATA.appendChild(BX.create('DIV', {
8052		props: {
8053			className: 'bx-core-adm-dialog-head-block' + (this.PARAMS.icon ? ' ' + this.PARAMS.icon : '')
8054		}
8055	}));
8056
8057	this.SetHead(this.PARAMS.head);
8058	this.SetContent(this.PARAMS.content);
8059	this.SetTitle(this.PARAMS.title);
8060	this.SetClose(this.PARTS.TITLEBAR_ICONS.lastChild);
8061
8062	if (this.PARAMS.resizable)
8063	{
8064		this.SetExpand(this.PARTS.TITLEBAR_ICONS.firstChild);
8065		this.SetExpand(this.PARTS.TITLEBAR, 'dblclick');
8066
8067		BX.addCustomEvent(this, 'onWindowExpand', BX.proxy(this.__onexpand, this));
8068		BX.addCustomEvent(this, 'onWindowNarrow', BX.proxy(this.__onexpand, this));
8069	}
8070
8071	this.PARTS.FOOT = this.PARTS.BUTTONS_CONTAINER = this.PARTS.CONTENT.appendChild(BX.create('DIV', {
8072			props: {
8073				className: 'bx-core-adm-dialog-buttons'
8074			},
8075			//events: {
8076			//	'click': BX.delegateEvent({property:{type: /button|submit/}}, BX.delegate(function() {this.showWait(BX.proxy_context)}, this))
8077			//},
8078			children: this.ShowButtons()
8079		}
8080	));
8081
8082	if (this.PARAMS.draggable)
8083		this.SetDraggable(this.PARTS.TITLEBAR);
8084
8085	if (this.PARAMS.resizable)
8086	{
8087		this.PARTS.RESIZER = this.DIV.appendChild(BX.create('DIV', {
8088			props: {className: 'bx-core-resizer'}
8089		}));
8090
8091		this.SetResize(this.PARTS.RESIZER);
8092
8093		this.SETTINGS.min_width = this.PARAMS.min_width;
8094		this.SETTINGS.min_height = this.PARAMS.min_height;
8095	}
8096
8097	this.auth_callback = BX.delegate(function(){
8098		this.PARAMS.content = '';
8099		this.hideNotify();
8100		this.Show();
8101	}, this)
8102};
8103BX.extend(BX.CDialog, BX.CWindowDialog);
8104
8105BX.CDialog.prototype.defaultParams = {
8106	width: 700,
8107	height: 400,
8108	min_width: 500,
8109	min_height: 300,
8110
8111	resizable: true,
8112	draggable: true,
8113
8114	title: '',
8115	icon: ''
8116};
8117
8118BX.CDialog.prototype.showWait = function(el)
8119{
8120	if (BX.type.isElementNode(el) && (el.type == 'button' || el.type == 'submit'))
8121	{
8122		BX.defer(function(){el.disabled = true})();
8123
8124		var bSave = (BX.hasClass(el, 'adm-btn-save') || BX.hasClass(el, 'adm-btn-save')),
8125			pos = BX.pos(el, true);
8126
8127		el.bxwaiter = this.PARTS.FOOT.appendChild(BX.create('DIV', {
8128			props: {className: 'adm-btn-load-img' + (bSave ? '-green' : '')},
8129			style: {
8130				top: parseInt((pos.bottom + pos.top)/2 - 10) + 'px',
8131				left: parseInt((pos.right + pos.left)/2 - 10) + 'px'
8132			}
8133		}));
8134
8135		BX.addClass(el, 'adm-btn-load');
8136
8137		this.lastWaitElement = el;
8138
8139		return el.bxwaiter;
8140	}
8141	return null;
8142};
8143
8144BX.CDialog.prototype.closeWait = function(el)
8145{
8146	el = el || this.lastWaitElement;
8147
8148	if (BX.type.isElementNode(el))
8149	{
8150		if (el.bxwaiter)
8151		{
8152			if(el.bxwaiter.parentNode)
8153			{
8154				el.bxwaiter.parentNode.removeChild(el.bxwaiter);
8155			}
8156
8157			el.bxwaiter = null;
8158		}
8159
8160		el.disabled = false;
8161		BX.removeClass(el, 'adm-btn-load');
8162
8163		if (this.lastWaitElement == el)
8164			this.lastWaitElement = null;
8165	}
8166};
8167
8168BX.CDialog.prototype.Authorize = function(arAuthResult)
8169{
8170	this.bSkipReplaceContent = true;
8171	this.ShowError(BX.message('JSADM_AUTH_REQ'));
8172
8173	BX.onCustomEvent(this, 'onWindowError', []);
8174
8175	BX.closeWait();
8176
8177	(new BX.CAuthDialog({
8178		content_url: this.PARAMS.content_url,
8179		auth_result: arAuthResult,
8180		callback: BX.delegate(function(){
8181			if (this.auth_callback)
8182				this.auth_callback()
8183		}, this)
8184	})).Show();
8185};
8186
8187BX.CDialog.prototype.ShowError = function(str)
8188{
8189	BX.onCustomEvent(this, 'onWindowError', [str]);
8190
8191	this.closeWait();
8192
8193	if (this._wait)
8194		BX.closeWait(this._wait);
8195
8196	this.Notify(str, true);
8197};
8198
8199
8200BX.CDialog.prototype.__expandGetSize = function()
8201{
8202	var pDocElement = BX.GetDocElement();
8203	pDocElement.style.overflow = 'hidden';
8204
8205	var wndSize = BX.GetWindowInnerSize();
8206
8207	pDocElement.scrollTop = 0;
8208
8209	this.DIV.style.top = '-' + this.dxShadow + 'px';
8210	this.DIV.style.left = '-' + this.dxShadow + 'px';
8211
8212	return {
8213		width: (wndSize.innerWidth - parseInt(BX.style(this.PARTS.CONTENT, 'padding-right')) - parseInt(BX.style(this.PARTS.CONTENT, 'padding-left'))) + this.dxShadow,
8214		height: (wndSize.innerHeight - this.PARTS.TITLEBAR.offsetHeight - this.PARTS.FOOT.offsetHeight - parseInt(BX.style(this.PARTS.CONTENT, 'padding-top')) - parseInt(BX.style(this.PARTS.CONTENT, 'padding-bottom'))) + this.dxShadow
8215	};
8216};
8217
8218BX.CDialog.prototype.__expand = function()
8219{
8220	var pDocElement = BX.GetDocElement();
8221	this.dxShadow = 2;
8222
8223	if (!this.bExpanded)
8224	{
8225		var wndScroll = BX.GetWindowScrollPos();
8226
8227		this.__expand_settings = {
8228			resizable: this.SETTINGS.resizable,
8229			draggable: this.SETTINGS.draggable,
8230			width: this.PARTS.CONTENT_DATA.style.width,
8231			height: this.PARTS.CONTENT_DATA.style.height,
8232			left: this.DIV.style.left,
8233			top: this.DIV.style.top,
8234			scrollTop: wndScroll.scrollTop,
8235			scrollLeft: wndScroll.scrollLeft,
8236			overflow: BX.style(pDocElement, 'overflow')
8237		};
8238
8239		this.SETTINGS.resizable = false;
8240		this.SETTINGS.draggable = false;
8241
8242		var pos = this.__expandGetSize();
8243
8244		this.PARTS.CONTENT_DATA.style.width = pos.width + 'px';
8245		this.PARTS.CONTENT_DATA.style.height = pos.height + 'px';
8246
8247		window.scrollTo(0,0);
8248		pDocElement.style.overflow = 'hidden';
8249
8250		this.bExpanded = true;
8251
8252		BX.onCustomEvent(this, 'onWindowExpand');
8253		BX.onCustomEvent(this, 'onWindowResize');
8254		BX.onCustomEvent(this, 'onWindowResizeExt', [{'width': pos.width, 'height': pos.height}]);
8255
8256		BX.bind(window, 'resize', BX.proxy(this.__expand_onresize, this));
8257	}
8258	else
8259	{
8260		BX.unbind(window, 'resize', BX.proxy(this.__expand_onresize, this));
8261
8262		this.SETTINGS.resizable = this.__expand_settings.resizable;
8263		this.SETTINGS.draggable = this.__expand_settings.draggable;
8264
8265		pDocElement.style.overflow = this.__expand_settings.overflow;
8266
8267		this.DIV.style.top = this.__expand_settings.top;
8268		this.DIV.style.left = this.__expand_settings.left;
8269		this.PARTS.CONTENT_DATA.style.width = this.__expand_settings.width;
8270		this.PARTS.CONTENT_DATA.style.height = this.__expand_settings.height;
8271		window.scrollTo(this.__expand_settings.scrollLeft, this.__expand_settings.scrollTop);
8272		this.bExpanded = false;
8273
8274		BX.onCustomEvent(this, 'onWindowNarrow');
8275		BX.onCustomEvent(this, 'onWindowResize');
8276		BX.onCustomEvent(this, 'onWindowResizeExt', [{'width': parseInt(this.__expand_settings.width), 'height': parseInt(this.__expand_settings.height)}]);
8277	}
8278};
8279
8280BX.CDialog.prototype.__expand_onresize = function()
8281{
8282	var pos = this.__expandGetSize();
8283
8284	this.PARTS.CONTENT_DATA.style.width = pos.width + 'px';
8285	this.PARTS.CONTENT_DATA.style.height = pos.height + 'px';
8286
8287	BX.onCustomEvent(this, 'onWindowResize');
8288	BX.onCustomEvent(this, 'onWindowResizeExt', [pos]);
8289};
8290
8291BX.CDialog.prototype.__onexpand = function()
8292{
8293	var ob = this.PARTS.TITLEBAR_ICONS.firstChild;
8294	ob.className = BX.toggle(ob.className, ['bx-core-adm-icon-expand', 'bx-core-adm-icon-narrow']);
8295	ob.title = BX.toggle(ob.title, [BX.message('JS_CORE_WINDOW_EXPAND'), BX.message('JS_CORE_WINDOW_NARROW')]);
8296
8297	if (this.PARTS.RESIZER)
8298	{
8299		this.PARTS.RESIZER.style.display = this.bExpanded ? 'none' : 'block';
8300	}
8301};
8302
8303
8304BX.CDialog.prototype.__startResize = function(e)
8305{
8306	if (!this.SETTINGS.resizable)
8307		return false;
8308
8309	if(!e) e = window.event;
8310
8311	this.wndSize = BX.GetWindowScrollPos();
8312	this.wndSize.innerWidth = BX.GetWindowInnerSize().innerWidth;
8313
8314	this.pos = BX.pos(this.PARTS.CONTENT_DATA);
8315
8316	this.x = e.clientX + this.wndSize.scrollLeft;
8317	this.y = e.clientY + this.wndSize.scrollTop;
8318
8319	this.dx = this.pos.left + this.pos.width - this.x;
8320	this.dy = this.pos.top + this.pos.height - this.y;
8321
8322
8323	// TODO: suspicious
8324	this.dw = this.pos.width - parseInt(this.PARTS.CONTENT_DATA.style.width) + parseInt(BX.style(this.PARTS.CONTENT, 'padding-right'));
8325
8326	BX.bind(document, "mousemove", BX.proxy(this.__moveResize, this));
8327	BX.bind(document, "mouseup", BX.proxy(this.__stopResize, this));
8328
8329	if(document.body.setCapture)
8330		document.body.setCapture();
8331
8332	document.onmousedown = BX.False;
8333
8334	var b = document.body;
8335	b.ondrag = b.onselectstart = BX.False;
8336	b.style.MozUserSelect = this.DIV.style.MozUserSelect = 'none';
8337	b.style.cursor = 'se-resize';
8338
8339	BX.onCustomEvent(this, 'onWindowResizeStart');
8340
8341	return true;
8342};
8343
8344BX.CDialog.prototype.Resize = function(x, y)
8345{
8346	var new_width = Math.max(x - this.pos.left + this.dx, this.SETTINGS.min_width);
8347	var new_height = Math.max(y - this.pos.top + this.dy, this.SETTINGS.min_height);
8348
8349	if (this.SETTINGS.resize_restrict)
8350	{
8351		var scrollSize = BX.GetWindowScrollSize();
8352
8353		if (this.pos.left + new_width > scrollSize.scrollWidth - this.dw)
8354			new_width = scrollSize.scrollWidth - this.pos.left - this.dw;
8355	}
8356
8357	this.PARTS.CONTENT_DATA.style.width = new_width + 'px';
8358	this.PARTS.CONTENT_DATA.style.height = new_height + 'px';
8359
8360	BX.onCustomEvent(this, 'onWindowResize');
8361	BX.onCustomEvent(this, 'onWindowResizeExt', [{'height': new_height, 'width': new_width}]);
8362};
8363
8364BX.CDialog.prototype.SetSize = function(obSize)
8365{
8366	this.PARTS.CONTENT_DATA.style.width = obSize.width + 'px';
8367	this.PARTS.CONTENT_DATA.style.height = obSize.height + 'px';
8368
8369	BX.onCustomEvent(this, 'onWindowResize');
8370	BX.onCustomEvent(this, 'onWindowResizeExt', [obSize]);
8371};
8372
8373BX.CDialog.prototype.GetParameters = function(form_name)
8374{
8375	var form = this.GetForm();
8376
8377	if(!form)
8378		return "";
8379
8380	var i, s = "";
8381	var n = form.elements.length;
8382
8383	var delim = '';
8384	for(i=0; i<n; i++)
8385	{
8386		if (s != '') delim = '&';
8387		var el = form.elements[i];
8388		if (el.disabled)
8389			continue;
8390
8391		switch(el.type.toLowerCase())
8392		{
8393			case 'text':
8394			case 'textarea':
8395			case 'password':
8396			case 'hidden':
8397				if (null == form_name && el.name.substr(el.name.length-4) == '_alt' && form.elements[el.name.substr(0, el.name.length-4)])
8398					break;
8399				s += delim + el.name + '=' + BX.util.urlencode(el.value);
8400				break;
8401			case 'radio':
8402				if(el.checked)
8403					s += delim + el.name + '=' + BX.util.urlencode(el.value);
8404				break;
8405			case 'checkbox':
8406				s += delim + el.name + '=' + BX.util.urlencode(el.checked ? 'Y':'N');
8407				break;
8408			case 'select-one':
8409				var val = "";
8410				if (null == form_name && form.elements[el.name + '_alt'] && el.selectedIndex == 0)
8411					val = form.elements[el.name+'_alt'].value;
8412				else
8413					val = el.value;
8414				s += delim + el.name + '=' + BX.util.urlencode(val);
8415				break;
8416			case 'select-multiple':
8417				var j, bAdded = false;
8418				var l = el.options.length;
8419				for (j=0; j<l; j++)
8420				{
8421					if (el.options[j].selected)
8422					{
8423						s += delim + el.name + '=' + BX.util.urlencode(el.options[j].value);
8424						bAdded = true;
8425					}
8426				}
8427				if (!bAdded)
8428					s += delim + el.name + '=';
8429				break;
8430			default:
8431				break;
8432		}
8433	}
8434
8435	return s;
8436};
8437
8438BX.CDialog.prototype.PostParameters = function(params)
8439{
8440	var url = this.PARAMS.content_url;
8441
8442	if (null == params)
8443		params = "";
8444
8445	params += (params == "" ? "" : "&") + "bxsender=" + this._sender;
8446
8447	var index = url.indexOf('?');
8448	if (index == -1)
8449		url += '?' + params;
8450	else
8451		url = url.substring(0, index) + '?' + params + "&" + url.substring(index+1);
8452
8453	BX.showWait();
8454
8455	this.auth_callback = BX.delegate(function(){
8456		this.hideNotify();
8457		this.PostParameters(params);
8458	}, this);
8459
8460	BX.ajax.Setup({skipAuthCheck:true},true);
8461	BX.ajax.post(url, this.GetParameters(), BX.delegate(function(result) {
8462		BX.closeWait();
8463		if (!this.bSkipReplaceContent)
8464		{
8465			this.ClearButtons(); // buttons are appended during form reload, so we should clear footer
8466			this.SetContent(result);
8467			this.Show(true);
8468		}
8469
8470		this.bSkipReplaceContent = false;
8471	}, this));
8472};
8473
8474BX.CDialog.prototype.Submit = function(params, url)
8475{
8476	var FORM = this.GetForm();
8477	if (FORM)
8478	{
8479		FORM.onsubmit = null;
8480
8481		FORM.method = 'POST';
8482		if (!FORM.action || url)
8483		{
8484			url = url || this.PARAMS.content_url;
8485			if (null != params)
8486			{
8487				var index = url.indexOf('?');
8488				if (index == -1)
8489					url += '?' + params;
8490				else
8491					url = url.substring(0, index) + '?' + params + "&" + url.substring(index+1);
8492			}
8493
8494			FORM.action = url;
8495		}
8496
8497		if (!FORM._bxsender)
8498		{
8499			FORM._bxsender = FORM.appendChild(BX.create('INPUT', {
8500				attrs: {
8501					type: 'hidden',
8502					name: 'bxsender',
8503					value: this._sender
8504				}
8505			}));
8506		}
8507
8508		this._wait = BX.showWait();
8509
8510		this.auth_callback = BX.delegate(function(){
8511			this.hideNotify();
8512			this.Submit(params);
8513		}, this);
8514
8515		BX.ajax.submit(FORM, BX.delegate(function(){this.closeWait()}, this));
8516	}
8517	else
8518	{
8519		window.alert('no form registered!');
8520	}
8521};
8522
8523BX.CDialog.prototype.GetForm = function()
8524{
8525	if (null == this.__form)
8526	{
8527		var forms = this.PARTS.CONTENT_DATA.getElementsByTagName('FORM');
8528		this.__form = forms[0] ? forms[0] : null;
8529	}
8530
8531	return this.__form;
8532};
8533
8534BX.CDialog.prototype.GetRealForm = function()
8535{
8536	if (null == this.__rform)
8537	{
8538		var forms = this.PARTS.CONTENT_DATA.getElementsByTagName('FORM');
8539		this.__rform = forms[1] ? forms[1] : (forms[0] ? forms[0] : null);
8540	}
8541
8542	return this.__rform;
8543};
8544
8545BX.CDialog.prototype._checkButton = function(btn)
8546{
8547	var arCustomButtons = ['btnSave', 'btnCancel', 'btnClose'];
8548
8549	for (var i = 0; i < arCustomButtons.length; i++)
8550	{
8551		if (this[arCustomButtons[i]] && (btn == this[arCustomButtons[i]]))
8552			return arCustomButtons[i];
8553	}
8554
8555	return false;
8556};
8557
8558BX.CDialog.prototype.ShowButtons = function()
8559{
8560	var result = [];
8561	if (this.PARAMS.buttons)
8562	{
8563		if (this.PARAMS.buttons.title) this.PARAMS.buttons = [this.PARAMS.buttons];
8564
8565		for (var i=0, len=this.PARAMS.buttons.length; i<len; i++)
8566		{
8567			if (BX.type.isNotEmptyString(this.PARAMS.buttons[i]))
8568			{
8569				result.push(this.PARAMS.buttons[i]);
8570			}
8571			else if (this.PARAMS.buttons[i])
8572			{
8573				//if (!(this.PARAMS.buttons[i] instanceof BX.CWindowButton))
8574				if (!BX.is_subclass_of(this.PARAMS.buttons[i], BX.CWindowButton))
8575				{
8576					var b = this._checkButton(this.PARAMS.buttons[i]); // hack to set links to real CWindowButton object in btnSave etc;
8577					this.PARAMS.buttons[i] = new BX.CWindowButton(this.PARAMS.buttons[i]);
8578					if (b) this[b] = this.PARAMS.buttons[i];
8579				}
8580
8581				result.push(this.PARAMS.buttons[i].Button(this));
8582			}
8583		}
8584	}
8585
8586	return result;
8587};
8588
8589BX.CDialog.prototype.setAutosave = function () {
8590	if (!this.bSetAutosaveDelay)
8591	{
8592		this.bSetAutosaveDelay = true;
8593		setTimeout(BX.proxy(this.setAutosave, this), 10);
8594	}
8595};
8596
8597BX.CDialog.prototype.SetTitle = function(title)
8598{
8599	this.PARAMS.title = title;
8600	BX.cleanNode(this.PARTS.TITLE_CONTAINER).appendChild(document.createTextNode(this.PARAMS.title));
8601};
8602
8603BX.CDialog.prototype.SetHead = function(head)
8604{
8605	this.PARAMS.head = BX.util.trim(head);
8606	this.PARTS.HEAD.innerHTML = this.PARAMS.head || "&nbsp;";
8607	this.PARTS.HEAD.style.display = this.PARAMS.head ? 'block' : 'none';
8608	this.adjustSize();
8609};
8610
8611BX.CDialog.prototype.Notify = function(note, bError)
8612{
8613	if (!this.PARTS.NOTIFY)
8614	{
8615		this.PARTS.NOTIFY = this.DIV.insertBefore(BX.create('DIV', {
8616			props: {className: 'adm-warning-block'},
8617			children: [
8618				BX.create('SPAN', {
8619					props: {className: 'adm-warning-text'}
8620				}),
8621				BX.create('SPAN', {
8622					props: {className: 'adm-warning-icon'}
8623				}),
8624				BX.create('SPAN', {
8625					props: {className: 'adm-warning-close'},
8626					events: {click: BX.proxy(this.hideNotify, this)}
8627				})
8628			]
8629		}), this.DIV.firstChild);
8630	}
8631
8632	if (bError)
8633		BX.addClass(this.PARTS.NOTIFY, 'adm-warning-block-red');
8634	else
8635		BX.removeClass(this.PARTS.NOTIFY, 'adm-warning-block-red');
8636
8637	this.PARTS.NOTIFY.firstChild.innerHTML = note || '&nbsp;';
8638	this.PARTS.NOTIFY.firstChild.style.width = (this.PARAMS.width-50) + 'px';
8639	BX.removeClass(this.PARTS.NOTIFY, 'adm-warning-animate');
8640};
8641
8642BX.CDialog.prototype.hideNotify = function()
8643{
8644	BX.addClass(this.PARTS.NOTIFY, 'adm-warning-animate');
8645};
8646
8647BX.CDialog.prototype.__adjustHeadToIcon = function()
8648{
8649	if (!this.PARTS.HEAD.offsetHeight)
8650	{
8651		setTimeout(BX.delegate(this.__adjustHeadToIcon, this), 50);
8652	}
8653	else
8654	{
8655		if (this.icon_image && this.icon_image.height && this.icon_image.height > this.PARTS.HEAD.offsetHeight - 5)
8656		{
8657			this.PARTS.HEAD.style.height = this.icon_image.height + 5 + 'px';
8658			this.adjustSize();
8659		}
8660
8661		this.icon_image.onload = null;
8662		this.icon_image = null;
8663	}
8664};
8665
8666BX.CDialog.prototype.SetIcon = function(icon_class)
8667{
8668	if (this.PARAMS.icon != icon_class)
8669	{
8670		if (this.PARAMS.icon)
8671			BX.removeClass(this.PARTS.HEAD, this.PARAMS.icon);
8672
8673		this.PARAMS.icon = icon_class;
8674
8675		if (this.PARAMS.icon)
8676		{
8677			BX.addClass(this.PARTS.HEAD, this.PARAMS.icon);
8678
8679			var icon_file = (BX.style(this.PARTS.HEAD, 'background-image') || BX.style(this.PARTS.HEAD, 'backgroundImage'));
8680			if (BX.type.isNotEmptyString(icon_file) && icon_file != 'none')
8681			{
8682				var match = icon_file.match(new RegExp('url\\s*\\(\\s*(\'|"|)(.+?)(\\1)\\s*\\)'));
8683				if(match)
8684				{
8685					icon_file = match[2];
8686					if (BX.type.isNotEmptyString(icon_file))
8687					{
8688						this.icon_image = new Image();
8689						this.icon_image.onload = BX.delegate(this.__adjustHeadToIcon, this);
8690						this.icon_image.src = icon_file;
8691					}
8692				}
8693			}
8694		}
8695	}
8696	this.adjustSize();
8697};
8698
8699BX.CDialog.prototype.SetIconFile = function(icon_file)
8700{
8701	this.icon_image = new Image();
8702	this.icon_image.onload = BX.delegate(this.__adjustHeadToIcon, this);
8703	this.icon_image.src = icon_file;
8704
8705	BX.adjust(this.PARTS.HEAD, {style: {backgroundImage: 'url(' + icon_file + ')', backgroundPosition: 'right 9px'/*'99% center'*/}});
8706	this.adjustSize();
8707};
8708
8709/*
8710BUTTON: {
8711	title: 'title',
8712	'action': function executed in window object context
8713}
8714BX.CDialog.btnSave || BX.CDialog.btnCancel - standard buttons
8715*/
8716
8717BX.CDialog.prototype.SetButtons = function(a)
8718{
8719	if (BX.type.isString(a))
8720	{
8721		if (a.length > 0)
8722		{
8723			this.PARTS.BUTTONS_CONTAINER.innerHTML += a;
8724
8725			var btns = this.PARTS.BUTTONS_CONTAINER.getElementsByTagName('INPUT');
8726			if (btns.length > 0)
8727			{
8728				this.PARAMS.buttons = [];
8729				for (var i = 0; i < btns.length; i++)
8730				{
8731					this.PARAMS.buttons.push(new BX.CWindowButton({btn: btns[i], parentWindow: this}));
8732				}
8733			}
8734		}
8735	}
8736	else
8737	{
8738		this.PARAMS.buttons = a;
8739		BX.adjust(this.PARTS.BUTTONS_CONTAINER, {
8740			children: this.ShowButtons()
8741		});
8742	}
8743	this.adjustSize();
8744};
8745
8746BX.CDialog.prototype.ClearButtons = function()
8747{
8748	BX.cleanNode(this.PARTS.BUTTONS_CONTAINER);
8749	this.adjustSize();
8750};
8751
8752BX.CDialog.prototype.SetContent = function(html)
8753{
8754	this.__form = null;
8755
8756	if (BX.type.isElementNode(html))
8757	{
8758		if (html.parentNode)
8759			html.parentNode.removeChild(html);
8760	}
8761	else if (BX.type.isString(html))
8762	{
8763		html = BX.create('DIV', {html: html});
8764	}
8765
8766	this.PARAMS.content = html;
8767	BX.cleanNode(this.PARTS.CONTENT_DATA);
8768
8769	BX.adjust(this.PARTS.CONTENT_DATA, {
8770		children: [
8771			this.PARTS.HEAD,
8772			BX.create('DIV', {
8773				props: {
8774					className: 'bx-core-adm-dialog-content-wrap-inner'
8775				},
8776				children: [this.PARAMS.content]
8777			})
8778		]
8779	});
8780
8781	if (this.PARAMS.content_url && this.GetForm())
8782	{
8783		this.__form.submitbtn = this.__form.appendChild(BX.create('INPUT', {props:{type:'submit'},style:{display:'none'}}));
8784		this.__form.onsubmit = BX.delegate(this.__submit, this);
8785	}
8786};
8787
8788BX.CDialog.prototype.__submit = function(e)
8789{
8790	for (var i=0,len=this.PARAMS.buttons.length; i<len; i++)
8791	{
8792		if (
8793			this.PARAMS.buttons[i]
8794			&& (
8795				this.PARAMS.buttons[i].name && /save|apply/i.test(this.PARAMS.buttons[i].name)
8796				||
8797				this.PARAMS.buttons[i].btn && this.PARAMS.buttons[i].btn.name && /save|apply/i.test(this.PARAMS.buttons[i].btn.name)
8798			)
8799		)
8800		{
8801			this.PARAMS.buttons[i].emulate();
8802			break;
8803		}
8804	}
8805
8806	return BX.PreventDefault(e);
8807};
8808
8809BX.CDialog.prototype.SwapContent = function(cont)
8810{
8811	cont = BX(cont);
8812
8813	BX.cleanNode(this.PARTS.CONTENT_DATA);
8814	cont.parentNode.removeChild(cont);
8815	this.PARTS.CONTENT_DATA.appendChild(cont);
8816	cont.style.display = 'block';
8817	this.SetContent(cont.innerHTML);
8818};
8819
8820// this method deprecated
8821BX.CDialog.prototype.adjustSize = function()
8822{
8823};
8824
8825// this method deprecated
8826BX.CDialog.prototype.__adjustSize = function()
8827{
8828};
8829
8830BX.CDialog.prototype.adjustSizeEx = function()
8831{
8832	BX.defer(this.__adjustSizeEx, this)();
8833};
8834
8835BX.CDialog.prototype.__adjustSizeEx = function()
8836{
8837	var ob = this.PARTS.CONTENT_DATA.firstChild, new_height = 0;
8838	while (ob)
8839	{
8840		new_height += ob.offsetHeight
8841			+ parseInt(BX.style(ob, 'margin-top'))
8842			+ parseInt(BX.style(ob, 'margin-bottom'));
8843
8844		ob = BX.nextSibling(ob);
8845	}
8846
8847	if (new_height)
8848		this.PARTS.CONTENT_DATA.style.height = new_height + 'px';
8849};
8850
8851
8852BX.CDialog.prototype.__onResizeFinished = function()
8853{
8854	BX.WindowManager.saveWindowSize(
8855		this.PARAMS.resize_id || this.PARAMS.content_url, {height: parseInt(this.PARTS.CONTENT_DATA.style.height), width: parseInt(this.PARTS.CONTENT_DATA.style.width)}
8856	);
8857};
8858
8859BX.CDialog.prototype.Show = function(bNotRegister)
8860{
8861	if ((!this.PARAMS.content) && this.PARAMS.content_url && BX.ajax && !bNotRegister)
8862	{
8863		var wait = BX.showWait();
8864
8865		BX.WindowManager.currently_loaded = this;
8866
8867		this.CreateOverlay(parseInt(BX.style(wait, 'z-index'))-1);
8868		this.OVERLAY.style.display = 'block';
8869		this.OVERLAY.className = 'bx-core-dialog-overlay';
8870
8871		var post_data = '', method = 'GET';
8872		if (this.PARAMS.content_post)
8873		{
8874			post_data = this.PARAMS.content_post;
8875			method = 'POST';
8876		}
8877
8878		var url = this.PARAMS.content_url
8879			+ (this.PARAMS.content_url.indexOf('?')<0?'?':'&')+'bxsender=' + this._sender;
8880
8881		this.auth_callback = BX.delegate(function(){
8882			this.PARAMS.content = '';
8883			this.hideNotify();
8884			this.Show();
8885		}, this);
8886
8887		BX.ajax({
8888			method: method,
8889			dataType: 'html',
8890			url: url,
8891			data: post_data,
8892			skipAuthCheck: true,
8893			onsuccess: BX.delegate(function(data) {
8894				BX.closeWait(null, wait);
8895
8896				this.SetContent(data || '&nbsp;');
8897				this.Show();
8898			}, this),
8899			processScriptsConsecutive: true
8900		});
8901	}
8902	else
8903	{
8904		BX.WindowManager.currently_loaded = null;
8905		BX.CDialog.superclass.Show.apply(this, arguments);
8906
8907		this.adjustPos();
8908
8909		this.OVERLAY.className = 'bx-core-dialog-overlay';
8910
8911		this.__adjustSize();
8912
8913		BX.addCustomEvent(this, 'onWindowResize', BX.proxy(this.__adjustSize, this));
8914
8915		if (this.PARAMS.resizable && (this.PARAMS.content_url || this.PARAMS.resize_id))
8916			BX.addCustomEvent(this, 'onWindowResizeFinished', BX.delegate(this.__onResizeFinished, this));
8917	}
8918};
8919
8920BX.CDialog.prototype.GetInnerPos = function()
8921{
8922	return {'width': parseInt(this.PARTS.CONTENT_DATA.style.width), 'height': parseInt(this.PARTS.CONTENT_DATA.style.height)};
8923};
8924
8925BX.CDialog.prototype.adjustPos = function()
8926{
8927	if (!this.bExpanded)
8928	{
8929		var windowSize = BX.GetWindowInnerSize();
8930		var windowScroll = BX.GetWindowScrollPos();
8931
8932		BX.adjust(this.DIV, {
8933			style: {
8934				left: parseInt(windowScroll.scrollLeft + windowSize.innerWidth / 2 - parseInt(this.DIV.offsetWidth) / 2) + 'px',
8935				top: Math.max(parseInt(windowScroll.scrollTop + windowSize.innerHe
8935ight / 2 - parseInt(this.DIV.offsetHeight) / 2), 0) + 'px'
8936			}
8937		});
8938	}
8939};
8940
8941BX.CDialog.prototype.GetContent = function () {return this.PARTS.CONTENT_DATA};
8942
8943BX.CDialog.prototype.btnSave = BX.CDialog.btnSave = {
8944	title: BX.message('JS_CORE_WINDOW_SAVE'),
8945	id: 'savebtn',
8946	name: 'savebtn',
8947	className: BX.browser.IsIE() && BX.browser.IsDoctype() && !BX.browser.IsIE10() ? '' : 'adm-btn-save',
8948	action: function () {
8949		this.disableUntilError();
8950		this.parentWindow.PostParameters();
8951	}
8952};
8953
8954BX.CDialog.prototype.btnCancel = BX.CDialog.btnCancel = {
8955	title: BX.message('JS_CORE_WINDOW_CANCEL'),
8956	id: 'cancel',
8957	name: 'cancel',
8958	action: function () {
8959		this.parentWindow.Close();
8960	}
8961};
8962
8963BX.CDialog.prototype.btnClose = BX.CDialog.btnClose = {
8964	title: BX.message('JS_CORE_WINDOW_CLOSE'),
8965	id: 'close',
8966	name: 'close',
8967	action: function () {
8968		this.parentWindow.Close();
8969	}
8970};
8971
8972/* special child for admin forms loaded into public page */
8973BX.CAdminDialog = function(arParams)
8974{
8975	BX.CAdminDialog.superclass.constructor.apply(this, arguments);
8976
8977	this._sender = 'core_window_cadmindialog';
8978
8979	BX.addClass(this.DIV, 'bx-core-adm-admin-dialog');
8980
8981	this.PARTS.CONTENT.insertBefore(this.PARTS.HEAD, this.PARTS.CONTENT.firstChild);
8982	this.PARTS.HEAD.className = 'bx-core-adm-dialog-tabs';
8983};
8984BX.extend(BX.CAdminDialog, BX.CDialog);
8985
8986BX.CAdminDialog.prototype.SetHead = function()
8987{
8988	BX.CAdminDialog.superclass.SetHead.apply(this, arguments);
8989
8990	if (this.PARTS.HEAD.firstChild && BX.type.isElementNode(this.PARTS.HEAD.firstChild))
8991	{
8992		var ob = this.PARTS.HEAD.firstChild, new_width = 0, marginLeft = 0, marginRight = 0;
8993
8994		while (ob)
8995		{
8996			marginLeft = parseInt(BX.style(ob, 'margin-left'), 10);
8997			if (isNaN(marginLeft))
8998			{
8999				marginLeft = 0;
9000			}
9001			marginRight = parseInt(BX.style(ob, 'margin-right'), 10);
9002			if (isNaN(marginRight))
9003			{
9004				marginRight = 0;
9005			}
9006			new_width += ob.offsetWidth + marginLeft + marginRight;
9007			ob = BX.nextSibling(ob);
9008		}
9009
9010		this.SETTINGS.min_width = Math.max(new_width, this.SETTINGS.min_width) - 2;
9011		if (this.PARAMS.width < this.SETTINGS.min_width)
9012		{
9013			BX.adjust(this.PARTS.CONTENT_DATA, {
9014				style: {
9015					width: this.SETTINGS.min_width + 'px'
9016				}
9017			});
9018		}
9019	}
9020};
9021
9022BX.CAdminDialog.prototype.SetContent = function(html)
9023{
9024	this.__form = null;
9025
9026	if (BX.type.isElementNode(html))
9027	{
9028		if (html.parentNode)
9029			html.parentNode.removeChild(html);
9030	}
9031
9032	this.PARAMS.content = html;
9033	BX.cleanNode(this.PARTS.CONTENT_DATA);
9034
9035	BX.adjust(this.PARTS.CONTENT_DATA, {
9036		children: [
9037			this.PARAMS.content || '&nbsp;'
9038		]
9039	});
9040
9041	if (this.PARAMS.content_url && this.GetForm())
9042	{
9043		this.__form.appendChild(BX.create('INPUT', {props:{type:'submit'},style:{display:'none'}}));
9044		this.__form.onsubmit = BX.delegate(this.__submit, this);
9045	}
9046};
9047
9048BX.CAdminDialog.prototype.__adjustSizeEx = function()
9049{
9050	var new_height = BX.firstChild(this.PARTS.CONTENT_DATA).offsetHeight;
9051	if (new_height)
9052		this.PARTS.CONTENT_DATA.style.height = new_height + 'px';
9053};
9054
9055BX.CAdminDialog.prototype.__expandGetSize = function()
9056{
9057	var res = BX.CAdminDialog.superclass.__expandGetSize.apply(this, arguments);
9058
9059	res.width -= parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-right')) + parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-left'));
9060	res.height -= parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-top')) + parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-bottom'));
9061
9062	res.height -= this.PARTS.HEAD.offsetHeight;
9063
9064	return res;
9065};
9066
9067BX.CAdminDialog.prototype.Submit = function()
9068{
9069	var FORM = this.GetForm();
9070	if (FORM && !FORM['bxpublic'] && !/bxpublic=/.test(FORM.action))
9071	{
9072		FORM.appendChild(BX.create('INPUT', {
9073			props: {
9074				type: 'hidden',
9075				name: 'bxpublic',
9076				value: 'Y'
9077			}
9078		}));
9079	}
9080
9081	return BX.CAdminDialog.superclass.Submit.apply(this, arguments);
9082};
9083
9084BX.CAdminDialog.prototype.btnSave = BX.CAdminDialog.btnSave = {
9085	title: BX.message('JS_CORE_WINDOW_SAVE'),
9086	id: 'savebtn',
9087	name: 'savebtn',
9088	className: 'adm-btn-save',
9089	action: function () {
9090		this.disableUntilError();
9091		this.parentWindow.Submit();
9092	}
9093};
9094
9095BX.CAdminDialog.btnCancel = BX.CAdminDialog.superclass.btnCancel;
9096BX.CAdminDialog.btnClose = BX.CAdminDialog.superclass.btnClose;
9097
9098BX.CDebugDialog = function(arParams)
9099{
9100	BX.CDebugDialog.superclass.constructor.apply(this, arguments);
9101};
9102BX.extend(BX.CDebugDialog, BX.CDialog);
9103
9104BX.CDebugDialog.prototype.ShowDetails = function(div_id)
9105{
9106	var div = BX(div_id);
9107	if (div)
9108	{
9109		if (this.div_detail_current)
9110			this.div_detail_current.style.display = 'none';
9111
9112		div.style.display = 'block';
9113		this.div_detail_current = div;
9114	}
9115};
9116
9117BX.CDebugDialog.prototype.SetContent = function(html)
9118{
9119	if (!html)
9120		return;
9121
9122	var arHtml = html.split('#DIVIDER#');
9123	if (arHtml.length > 1)
9124	{
9125		this.PARAMS.content = arHtml[1];
9126
9127		this.PARTS.CONTENT_DATA.style.overflow = 'hidden';
9128
9129		BX.CDebugDialog.superclass.SetContent.apply(this, [arHtml[1]]);
9130
9131		this.PARTS.CONTENT_INNER = this.PARTS.CONTENT_DATA.firstChild.nextSibling;
9132		this.PARTS.CONTENT_TOP = this.PARTS.CONTENT_DATA.insertBefore(BX.create('DIV', {
9133			props: {
9134				className: 'bx-debug-content-top'
9135			},
9136			html: arHtml[0]
9137		}), this.PARTS.CONTENT_INNER);
9138		this.PARTS.CONTENT_INNER.style.overflow = 'auto';
9139	}
9140	else
9141	{
9142		BX.CDebugDialog.superclass.SetContent.apply(this, arguments);
9143	}
9144};
9145
9146BX.CDebugDialog.prototype.__adjustSize = function()
9147{
9148	BX.CDebugDialog.superclass.__adjustSize.apply(this, arguments);
9149
9150	if (this.PARTS.CONTENT_TOP)
9151	{
9152		var new_height = this.PARTS.CONTENT_DATA.offsetHeight - this.PARTS.HEAD.offsetHeight - this.PARTS.CONTENT_TOP.offsetHeight - 38;
9153
9154		if (new_height > 0)
9155		{
9156			this.PARTS.CONTENT_INNER.style.height = new_height + 'px';
9157		}
9158	}
9159};
9160
9161
9162/* class for dialog window with editors */
9163
9164BX.CEditorDialog = function(arParams)
9165{
9166	BX.CEditorDialog.superclass.constructor.apply(this, arguments);
9167
9168	BX.removeClass(this.PARTS.CONTENT, 'bx-core-adm-dialog-content-wrap');
9169	BX.removeClass(this.PARTS.CONTENT_DATA, 'bx-core-adm-dialog-content');
9170
9171	BX.removeClass(this.PARTS.CONTENT_DATA.lastChild, 'bx-core-adm-dialog-content-wrap-inner');
9172	BX.removeClass(this.PARTS.BUTTONS_CONTAINER, 'bx-core-adm-dialog-buttons');
9173
9174	BX.addClass(this.PARTS.CONTENT, 'bx-core-editor-dialog-content-wrap');
9175	BX.addClass(this.PARTS.CONTENT_DATA, 'bx-core-editor-dialog-content');
9176	BX.addClass(this.PARTS.BUTTONS_CONTAINER, 'bx-core-editor-dialog-buttons');
9177};
9178BX.extend(BX.CEditorDialog, BX.CDialog);
9179
9180BX.CEditorDialog.prototype.SetContent  = function()
9181{
9182	BX.CEditorDialog.superclass.SetContent.apply(this, arguments);
9183
9184	BX.removeClass(this.PARTS.CONTENT_DATA.lastChild, 'bx-core-adm-dialog-content-wrap-inner');
9185};
9186
9187/* class for wizards in admin section */
9188BX.CWizardDialog = function(arParams)
9189{
9190	BX.CWizardDialog.superclass.constructor.apply(this, arguments);
9191
9192	BX.removeClass(this.PARTS.CONTENT, 'bx-core-adm-dialog-content-wrap');
9193	BX.removeClass(this.PARTS.CONTENT_DATA, 'bx-core-adm-dialog-content');
9194	BX.removeClass(this.PARTS.CONTENT_DATA.lastChild, 'bx-core-adm-dialog-content-wrap-inner');
9195	BX.removeClass(this.PARTS.BUTTONS_CONTAINER, 'bx-core-adm-dialog-buttons');
9196
9197	BX.addClass(this.PARTS.CONTENT, 'bx-core-wizard-dialog-content-wrap');
9198};
9199
9200BX.extend(BX.CWizardDialog, BX.CDialog);
9201
9202/* class for auth dialog */
9203BX.CAuthDialog = function(arParams)
9204{
9205	arParams.resizable = false;
9206	arParams.width = 350;
9207	arParams.height = 200;
9208
9209	arParams.buttons = [this.btnSave];
9210
9211	BX.CAuthDialog.superclass.constructor.apply(this, arguments);
9212	this._sender = 'core_window_cauthdialog';
9213
9214	BX.addClass(this.DIV, 'bx-core-auth-dialog');
9215
9216	BX.AUTHAGENT = this;
9217};
9218BX.extend(BX.CAuthDialog, BX.CDialog);
9219
9220BX.CAuthDialog.prototype.btnSave = BX.CAuthDialog.btnSave = {
9221	title: BX.message('JS_CORE_WINDOW_AUTH'),
9222	id: 'savebtn',
9223	name: 'savebtn',
9224	className: 'adm-btn-save',
9225	action: function () {
9226		this.disableUntilError();
9227		this.parentWindow.Submit('', this.parentWindow.PARAMS.content_url);
9228	}
9229};
9230
9231BX.CAuthDialog.prototype.SetError = function(error)
9232{
9233	BX.closeWait();
9234
9235	if (!!error)
9236		this.ShowError(error.MESSAGE || error);
9237};
9238
9239BX.CAuthDialog.prototype.setAuthResult = function(result)
9240{
9241	BX.closeWait();
9242
9243	if (result === false)
9244	{
9245		this.Close();
9246		if (this.PARAMS.callback)
9247			this.PARAMS.callback();
9248	}
9249	else
9250	{
9251		this.SetError(result);
9252	}
9253};
9254
9255/* MENU CLASSES */
9256
9257BX.CWindowFloat = function(node)
9258{
9259	BX.CWindowFloat.superclass.constructor.apply(this, [node, 'float']);
9260
9261	this.SETTINGS.resizable = false;
9262};
9263BX.extend(BX.CWindowFloat, BX.CWindow);
9264
9265BX.CWindowFloat.prototype.adjustPos = function()
9266{
9267	if (this.PARAMS.parent)
9268		this.adjustToNode();
9269	else if (this.PARAMS.x && this.PARAMS.y)
9270		this.adjustToPos([this.PARAMS.x, this.PARAMS.y]);
9271};
9272
9273BX.CWindowFloat.prototype.adjustToPos = function(pos)
9274{
9275	this.DIV.style.left = parseInt(pos[0]) + 'px';
9276	this.DIV.style.top = parseInt(pos[1]) + 'px';
9277};
9278
9279BX.CWindowFloat.prototype.adjustToNodeGetPos = function()
9280{
9281	return BX.pos(this.PARAMS.parent);
9282};
9283
9284BX.CWindowFloat.prototype.adjustToNode = function(el)
9285{
9286	el = el || this.PARAMS.parent;
9287
9288	this.PARAMS.parent = BX(el);
9289
9290	if (this.PARAMS.parent)
9291	{
9292		var pos = this.adjustToNodeGetPos();
9293
9294		this.DIV.style.top = pos.top + 'px';//(pos.top - 26) + 'px';
9295		this.DIV.style.left = pos.left + 'px';
9296
9297		this.PARAMS.parent.OPENER = this;
9298	}
9299};
9300
9301BX.CWindowFloat.prototype.Show = function()
9302{
9303	this.adjustToPos([-1000, -1000]);
9304	BX.CWindowFloat.superclass.Show.apply(this, arguments);
9305	this.adjustPos();
9306};
9307
9308/* menu opener class */
9309/*
9310{
9311	DOMNode DIV,
9312	BX.CMenu or Array MENU,
9313	TYPE = 'hover' | 'click',
9314	TIMEOUT: 1000
9315	ATTACH_MODE: 'top' | 'right'
9316	ACTIVE_CLASS: className for opener element when menu is opened
9317}
9318*/
9319BX.COpener = function(arParams)
9320{
9321	this.PARAMS = arParams || {};
9322
9323	this.MENU = arParams.MENU || [];
9324
9325	this.DIV = arParams.DIV;
9326	this.ATTACH = arParams.ATTACH || arParams.DIV;
9327	this.ATTACH_MODE = arParams.ATTACH_MODE || 'bottom';
9328
9329	this.ACTIVE_CLASS = arParams.ACTIVE_CLASS || '';
9330	this.LEVEL = arParams.LEVEL || 0;
9331
9332	this.CLOSE_ON_CLICK = typeof arParams.CLOSE_ON_CLICK != 'undefined' ? !!arParams.CLOSE_ON_CLICK : true;
9333	this.ADJUST_ON_CLICK = typeof arParams.ADJUST_ON_CLICK != 'undefined' ? !!arParams.ADJUST_ON_CLICK : true;
9334
9335	this.TYPE = this.PARAMS.TYPE == 'hover' ? 'hover' : 'click';
9336
9337	this._openTimeout = null;
9338
9339	if (this.PARAMS.TYPE == 'hover' && arParams.TIMEOUT !== 0)
9340		this.TIMEOUT = arParams.TIMEOUT || 1000;
9341	else
9342		this.TIMEOUT = 0;
9343
9344	if (!!this.PARAMS.MENU_URL)
9345	{
9346		this.bMenuLoaded = false;
9347		this.bMenuLoading = false;
9348
9349		this.MENU = [{
9350			TEXT: BX.message('JS_CORE_LOADING'),
9351			CLOSE_ON_CLICK: false
9352		}];
9353
9354		if (this.PARAMS.MENU_PRELOAD)
9355		{
9356			BX.defer(this.Load, this)();
9357		}
9358	}
9359
9360	BX.ready(BX.defer(this.Init, this));
9361};
9362
9363BX.COpener.prototype.Init = function()
9364{
9365	this.DIV = BX(this.DIV);
9366
9367	switch (this.TYPE)
9368	{
9369		case 'hover':
9370			BX.bind(this.DIV, 'mouseover', BX.proxy(this.Open, this));
9371			BX.bind(this.DIV, 'click', BX.proxy(this.Toggle, this));
9372		break;
9373
9374		case 'click':
9375			BX.bind(this.DIV, 'click', BX.proxy(this.Toggle, this));
9376		break;
9377	}
9378
9379	//BX.bind(window, 'scroll', BX.delegate(this.__close_immediately, this));
9380
9381	this.bMenuInit = false;
9382};
9383
9384BX.COpener.prototype.Load = function()
9385{
9386	if (this.PARAMS.MENU_URL && !this.bMenuLoaded)
9387	{
9388		if (!this.bMenuLoading)
9389		{
9390			var url = this.PARAMS.MENU_URL;
9391			if (url.indexOf('sessid=') <= 0)
9392				url += (url.indexOf('?') > 0 ? '&' : '?') + 'sessid=' + BX.bitrix_sessid();
9393
9394			this.bMenuLoading = true;
9395			BX.ajax.loadJSON(url, BX.proxy(this.SetMenu, this), BX.proxy(this.LoadFailed, this));
9396		}
9397	}
9398};
9399
9400BX.COpener.prototype.SetMenu = function(menu)
9401{
9402	this.bMenuLoaded = true;
9403	this.bMenuLoading = false;
9404	if (this.bMenuInit)
9405	{
9406		this.MENU.setItems(menu);
9407	}
9408	else
9409	{
9410		this.MENU = menu;
9411	}
9412};
9413
9414BX.COpener.prototype.LoadFailed = function(type, error)
9415{
9416	this.bMenuLoading = false;
9417	this.SetMenu([{
9418		TEXT: BX.message('JS_CORE_NO_DATA'),
9419		CLOSE_ON_CLICK: true
9420	}]);
9421	BX.debug(arguments);
9422};
9423
9424BX.COpener.prototype.checkAdminMenu = function()
9425{
9426	if (document.documentElement.id == 'bx-admin-prefix')
9427		return true;
9428
9429	return !!BX.findParent(this.DIV, {property: {id: 'bx-admin-prefix'}});
9430};
9431
9432BX.COpener.prototype.Toggle = function(e)
9433{
9434	this.__clear_timeout();
9435
9436	if (!this.bMenuInit || !this.MENU.visible())
9437	{
9438		var t = this.TIMEOUT;
9439		this.TIMEOUT = 0;
9440		this.Open(e);
9441		this.TIMEOUT = t;
9442	}
9443	else
9444	{
9445		this.MENU.Close();
9446	}
9447
9448	return !!(e||window.event) && BX.PreventDefault(e);
9449};
9450
9451BX.COpener.prototype.GetMenu = function()
9452{
9453	if (!this.bMenuInit)
9454	{
9455		if (BX.type.isArray(this.MENU))
9456		{
9457			this.MENU = new BX.CMenu({
9458				ITEMS: this.MENU,
9459				ATTACH_MODE: this.ATTACH_MODE,
9460				SET_ID: this.checkAdminMenu() ? 'bx-admin-prefix' : '',
9461				CLOSE_ON_CLICK: !!this.CLOSE_ON_CLICK,
9462				ADJUST_ON_CLICK: !!this.ADJUST_ON_CLICK,
9463				LEVEL: this.LEVEL,
9464				parent: BX(this.DIV),
9465				parent_attach: BX(this.ATTACH)
9466			});
9467
9468			if (this.LEVEL > 0)
9469			{
9470				BX.bind(this.MENU.DIV, 'mouseover', BX.proxy(this._on_menu_hover, this));
9471				BX.bind(this.MENU.DIV, 'mouseout', BX.proxy(this._on_menu_hout, this));
9472			}
9473		}
9474
9475		BX.addCustomEvent(this.MENU, 'onMenuOpen', BX.proxy(this.handler_onopen, this));
9476		BX.addCustomEvent(this.MENU, 'onMenuClose', BX.proxy(this.handler_onclose, this));
9477
9478		BX.addCustomEvent('onMenuItemHover', BX.proxy(this.handler_onover, this));
9479
9480		this.bMenuInit = true;
9481	}
9482
9483	return this.MENU;
9484};
9485
9486BX.COpener.prototype.Open = function()
9487{
9488	this.GetMenu();
9489
9490	this.bOpen = true;
9491
9492	this.__clear_timeout();
9493
9494	if (this.TIMEOUT > 0)
9495	{
9496		BX.bind(this.DIV, 'mouseout', BX.proxy(this.__clear_timeout, this));
9497		this._openTimeout = setTimeout(BX.proxy(this.__open, this), this.TIMEOUT);
9498	}
9499	else
9500	{
9501		this.__open();
9502	}
9503
9504	if (!!this.PARAMS.MENU_URL && !this.bMenuLoaded)
9505	{
9506		this._loadTimeout = setTimeout(BX.proxy(this.Load, this), parseInt(this.TIMEOUT/2));
9507	}
9508
9509	return true;
9510};
9511
9512BX.COpener.prototype.__clear_timeout = function()
9513{
9514	if (!!this._openTimeout)
9515		clearTimeout(this._openTimeout);
9516	if (!!this._loadTimeout)
9517		clearTimeout(this._loadTimeout);
9518
9519	BX.unbind(this.DIV, 'mouseout', BX.proxy(this.__clear_timeout, this));
9520};
9521
9522BX.COpener.prototype._on_menu_hover = function()
9523{
9524	this.bMenuHover = true;
9525
9526	this.__clear_timeout();
9527
9528	if (this.ACTIVE_CLASS)
9529		BX.addClass(this.DIV, this.ACTIVE_CLASS);
9530
9531};
9532
9533BX.COpener.prototype._on_menu_hout = function()
9534{
9535	this.bMenuHover = false;
9536};
9537
9538BX.COpener.prototype.handler_onover = function(level, opener)
9539{
9540	if (this.bMenuHover)
9541		return;
9542
9543	if (opener != this && level == this.LEVEL-1 && this.ACTIVE_CLASS)
9544	{
9545		BX.removeClass(this.DIV, this.ACTIVE_CLASS);
9546	}
9547
9548	if (this.bMenuInit && level <= this.LEVEL-1 && this.MENU.visible())
9549	{
9550		if (opener != this)
9551		{
9552			this.__clear_timeout();
9553			this._openTimeout = setTimeout(BX.proxy(this.Close, this), this.TIMEOUT);
9554		}
9555	}
9556};
9557
9558BX.COpener.prototype.handler_onopen = function()
9559{
9560	this.bOpen = true;
9561
9562	if (this.ACTIVE_CLASS)
9563		BX.addClass(this.DIV, this.ACTIVE_CLASS);
9564
9565	BX.defer(function() {
9566		BX.onCustomEvent(this, 'onOpenerMenuOpen');
9567	}, this)();
9568};
9569
9570BX.COpener.prototype.handler_onclose = function()
9571{
9572	this.bOpen = false;
9573	BX.onCustomEvent(this, 'onOpenerMenuClose');
9574
9575	if (this.ACTIVE_CLASS)
9576		BX.removeClass(this.DIV, this.ACTIVE_CLASS);
9577};
9578
9579BX.COpener.prototype.Close = function()
9580{
9581	if (!this.bMenuInit)
9582		return;
9583
9584	if (!!this._openTimeout)
9585		clearTimeout(this._openTimeout);
9586
9587	this.bOpen = false;
9588
9589	this.__close();
9590};
9591
9592BX.COpener.prototype.__open = function()
9593{
9594	this.__clear_timeout();
9595
9596	if (this.bMenuInit && this.bOpen && !this.MENU.visible())
9597		this.MENU.Show();
9598};
9599
9600BX.COpener.prototype.__close = function()
9601{
9602	if (this.bMenuInit && !this.bOpen && this.MENU.visible())
9603		this.MENU.Hide();
9604};
9605
9606BX.COpener.prototype.__close_immediately = function() {
9607	this.bOpen = false; this.__close();
9608};
9609
9610BX.COpener.prototype.isMenuVisible = function() {
9611	return null != this.MENU.visible && this.MENU.visible()
9612};
9613
9614/* common menu class */
9615
9616BX.CMenu = function(arParams)
9617{
9618	BX.CMenu.superclass.constructor.apply(this);
9619
9620	this.DIV.style.width = 'auto';//this.DIV.firstChild.offsetWidth + 'px';
9621	this.DIV.style.height = 'auto';//this.DIV.firstChild.offsetHeight + 'px';
9622
9623	this.PARAMS = arParams || {};
9624	this.PARTS = {};
9625
9626	this.PARAMS.ATTACH_MODE = this.PARAMS.ATTACH_MODE || 'bottom';
9627	this.PARAMS.CLOSE_ON_CLICK = typeof this.PARAMS.CLOSE_ON_CLICK == 'undefined' ? true : this.PARAMS.CLOSE_ON_CLICK;
9628	this.PARAMS.ADJUST_ON_CLICK = typeof this.PARAMS.ADJUST_ON_CLICK == 'undefined' ? true : this.PARAMS.ADJUST_ON_CLICK;
9629	this.PARAMS.LEVEL = this.PARAMS.LEVEL || 0;
9630
9631	this.DIV.className = 'bx-core-popup-menu bx-core-popup-menu-' + this.PARAMS.ATTACH_MODE + ' bx-core-popup-menu-level' + this.PARAMS.LEVEL + (typeof this.PARAMS.ADDITIONAL_CLASS != 'undefined' ? ' ' + this.PARAMS.ADDITIONAL_CLASS : '');
9632	if (!!this.PARAMS.SET_ID)
9633		this.DIV.id = this.PARAMS.SET_ID;
9634
9635	if (this.PARAMS.LEVEL == 0)
9636	{
9637		this.ARROW = this.DIV.appendChild(BX.create('SPAN', {props: {className: 'bx-core-popup-menu-angle'}, style: {left:'15px'}}));
9638	}
9639
9640	if (!!this.PARAMS.CLASS_NAME)
9641		this.DIV.className += ' ' + this.PARAMS.CLASS_NAME;
9642
9643	BX.bind(this.DIV, 'click', BX.eventCancelBubble);
9644
9645	this.ITEMS = [];
9646
9647	this.setItems(this.PARAMS.ITEMS);
9648
9649	BX.addCustomEvent('onMenuOpen', BX.proxy(this._onMenuOpen, this));
9650	BX.addCustomEvent('onMenuItemSelected', BX.proxy(this.Hide, this));
9651};
9652BX.extend(BX.CMenu, BX.CWindowFloat);
9653
9654BX.CMenu.broadcastCloseEvent = function()
9655{
9656	BX.onCustomEvent("onMenuItemSelected");
9657};
9658
9659BX.CMenu._toggleChecked = function()
9660{
9661	BX.toggleClass(this, 'bx-core-popup-menu-item-checked');
9662};
9663
9664BX.CMenu._itemDblClick = function()
9665{
9666	window.location.href = this.href;
9667};
9668
9669BX.CMenu.prototype.toggleArrow = function(v)
9670{
9671	if (!!this.ARROW)
9672	{
9673		if (typeof v == 'undefined')
9674		{
9675			v = this.ARROW.style.visibility == 'hidden';
9676		}
9677
9678		this.ARROW.style.visibility = !!v ? 'visible' : 'hidden';
9679	}
9680};
9681
9682BX.CMenu.prototype.visible = function()
9683{
9684	return this.DIV.style.display !== 'none';
9685};
9686
9687BX.CMenu.prototype._onMenuOpen = function(menu, menu_level)
9688{
9689	if (this.visible())
9690	{
9691		if (menu_level == this.PARAMS.LEVEL && menu != this)
9692		{
9693			this.Hide();
9694		}
9695	}
9696};
9697
9698BX.CMenu.prototype.onUnRegister = function()
9699{
9700	if (!this.visible())
9701		return;
9702
9703	this.Hide();
9704};
9705
9706BX.CMenu.prototype.setItems = function(items)
9707{
9708	this.PARAMS.ITEMS = items;
9709
9710	BX.cleanNode(this.DIV);
9711
9712	if (!!this.ARROW)
9713		this.DIV.appendChild(this.ARROW);
9714
9715	if (this.PARAMS.ITEMS)
9716	{
9717		this.PARAMS.ITEMS = BX.util.array_values(this.PARAMS.ITEMS);
9718
9719		var bIcons = false;
9720		var cnt = 0;
9721		for (var i = 0, len = this.PARAMS.ITEMS.length; i < len; i++)
9722		{
9723			if ((i == 0 || i == len-1) && this.PARAMS.ITEMS[i].SEPARATOR)
9724				continue;
9725
9726			cnt++;
9727
9728			if (!bIcons)
9729				bIcons = !!this.PARAMS.ITEMS[i].GLOBAL_ICON;
9730
9731			this.addItem(this.PARAMS.ITEMS[i], i);
9732		}
9733
9734		// Occam turning in his grave
9735		if (cnt === 1)
9736			BX.addClass(this.DIV, 'bx-core-popup-menu-single-item');
9737		else
9738			BX.removeClass(this.DIV, 'bx-core-popup-menu-single-item');
9739
9740		if (!bIcons)
9741			BX.addClass(this.DIV, 'bx-core-popup-menu-no-icons');
9742		else
9743			BX.removeClass(this.DIV, 'bx-core-popup-menu-no-icons');
9744
9745	}
9746};
9747
9748BX.CMenu.prototype.addItem = function(item)
9749{
9750	this.ITEMS.push(item);
9751
9752	if (item.SEPARATOR)
9753	{
9754		item.NODE = BX.create(
9755			'DIV', {props: {className: 'bx-core-popup-menu-separator'}}
9756		);
9757	}
9758	else
9759	{
9760		var bHasMenu = (!!item.MENU
9761			&& (
9762				(BX.type.isArray(item.MENU) && item.MENU.length > 0)
9763				|| item.MENU instanceof BX.CMenu
9764			) || !!item.MENU_URL
9765		);
9766
9767		if (item.DISABLED)
9768		{
9769			item.CLOSE_ON_CLICK = false;
9770			item.LINK = null;
9771			item.ONCLICK = null;
9772			item.ACTION = null;
9773		}
9774
9775		item.NODE = BX.create(!!item.LINK || BX.browser.IsIE() && !BX.browser.IsDoctype() ? 'A' : 'SPAN', {
9776			props: {
9777				className: 'bx-core-popup-menu-item'
9778					+ (bHasMenu ? ' bx-core-popup-menu-item-opener' : '')
9779					+ (!!item.DEFAULT ? ' bx-core-popup-menu-item-default' : '')
9780					+ (!!item.DISABLED ? ' bx-core-popup-menu-item-disabled' : '')
9781					+ (!!item.CHECKED ? ' bx-core-popup-menu-item-checked' : ''),
9782					title: !!BX.message['MENU_ENABLE_TOOLTIP'] || !!item.SHOW_TITLE ? item.TITLE || '' : '',
9783				BXMENULEVEL: this.PARAMS.LEVEL
9784			},
9785			attrs: !!item.LINK || BX.browser.IsIE() && !BX.browser.IsDoctype() ? {href: item.LINK || 'javascript:void(0)'} : {},
9786			events: {
9787				mouseover: function()
9788				{
9789					BX.onCustomEvent('onMenuItemHover', [this.BXMENULEVEL, this.OPENER])
9790				}
9791			},
9792			html: '<span class="bx-core-popup-menu-item-icon' + (item.GLOBAL_ICON ? ' '+item.GLOBAL_ICON : '') + '"></span><span class="bx-core-popup-menu-item-text">'+item.TEXT+'</span>'
9793		});
9794
9795		if (bHasMenu && !item.DISABLED)
9796		{
9797			item.NODE.OPENER = new BX.COpener({
9798				DIV: item.NODE,
9799				ACTIVE_CLASS: 'bx-core-popup-menu-item-opened',
9800				TYPE: 'hover',
9801				MENU: item.MENU,
9802				MENU_URL: item.MENU_URL,
9803				MENU_PRELOAD: !!item.MENU_PRELOAD,
9804				LEVEL: this.PARAMS.LEVEL + 1,
9805				ATTACH_MODE:'right',
9806				TIMEOUT: 500
9807			});
9808		}
9809		else if (this.PARAMS.CLOSE_ON_CLICK && (typeof item.CLOSE_ON_CLICK == 'undefined' || !!item.CLOSE_ON_CLICK))
9810		{
9811			BX.bind(item.NODE, 'click', BX.CMenu.broadcastCloseEvent);
9812		}
9813		else if (this.PARAMS.ADJUST_ON_CLICK && (typeof item.ADJUST_ON_CLICK == 'undefined' || !!item.ADJUST_ON_CLICK))
9814		{
9815			BX.bind(item.NODE, 'click', BX.defer(this.adjustPos, this));
9816		}
9817
9818		if (bHasMenu && !!item.LINK)
9819		{
9820			BX.bind(item.NODE, 'dblclick', BX.CMenu._itemDblClick);
9821		}
9822
9823		if (typeof item.CHECKED != 'undefined')
9824		{
9825			BX.bind(item.NODE, 'click', BX.CMenu._toggleChecked);
9826		}
9827
9828		item.ONCLICK = item.ACTION || item.ONCLICK;
9829		if (!!item.ONCLICK)
9830		{
9831			if (BX.type.isString(item.ONCLICK))
9832			{
9833				item.ONCLICK = new Function("event", item.ONCLICK);
9834			}
9835
9836			BX.bind(item.NODE, 'click', item.ONCLICK);
9837		}
9838	}
9839
9840	this.DIV.appendChild(item.NODE);
9841};
9842
9843BX.CMenu.prototype._documentClickBind = function()
9844{
9845	this._documentClickUnBind();
9846	BX.bind(document, 'click', BX.proxy(this._documentClick, this));
9847};
9848
9849BX.CMenu.prototype._documentClickUnBind = function()
9850{
9851	BX.unbind(document, 'click', BX.proxy(this._documentClick, this));
9852};
9853
9854BX.CMenu.prototype._documentClick = function(e)
9855{
9856	e = e||window.event;
9857	if(!!e && !(BX.getEventButton(e) & BX.MSLEFT))
9858		return;
9859
9860	this.Close();
9861};
9862
9863BX.CMenu.prototype.Show = function()
9864{
9865	BX.onCustomEvent(this, 'onMenuOpen', [this, this.PARAMS.LEVEL]);
9866	BX.CMenu.superclass.Show.apply(this, []);
9867
9868	this.bCloseEventFired = false;
9869
9870	BX.addCustomEvent(this.PARAMS.parent_attach, 'onChangeNodePosition', BX.proxy(this.adjustToNode, this));
9871
9872	(BX.defer(this._documentClickBind, this))();
9873};
9874
9875BX.CMenu.prototype.Close = // we shouldn't 'Close' window - only hide
9876BX.CMenu.prototype.Hide = function()
9877{
9878	if (!this.visible())
9879		return;
9880
9881	BX.removeCustomEvent(this.PARAMS.parent_attach, 'onChangeNodePosition', BX.proxy(this.adjustToNode, this));
9882
9883	this._documentClickUnBind();
9884
9885	if (!this.bCloseEventFired)
9886	{
9887		BX.onCustomEvent(this, 'onMenuClose', [this, this.PARAMS.LEVEL]);
9888		this.bCloseEventFired = true;
9889	}
9890	BX.CMenu.superclass.Hide.apply(this, arguments);
9891
9892
9893//	this.DIV.onclick = null;
9894	//this.PARAMS.parent.onclick = null;
9895};
9896
9897BX.CMenu.prototype.__adjustMenuToNode = function()
9898{
9899	var pos = BX.pos(this.PARAMS.parent_attach),
9900		bFixed = !!BX.findParent(this.PARAMS.parent_attach, BX.is_fixed);
9901
9902	if (bFixed)
9903		this.DIV.style.position = 'fixed';
9904	else
9905		this.DIV.style.position = 'absolute';
9906
9907	if (!pos.top)
9908	{
9909		this.DIV.style.top = '-1000px';
9910		this.DIV.style.left = '-1000px';
9911	}
9912
9913	if (this.bTimeoutSet) return;
9914
9915	var floatWidth = this.DIV.offsetWidth, floatHeight = this.DIV.offsetHeight;
9916	if (!floatWidth)
9917	{
9918		setTimeout(BX.delegate(function(){
9919			this.bTimeoutSet = false; this.__adjustMenuToNode();
9920		}, this), 100);
9921
9922		this.bTimeoutSet = true;
9923		return;
9924	}
9925
9926	var menu_pos = {},
9927		wndSize = BX.GetWindowSize();
9928
9929/*
9930	if (BX.browser.IsIE() && !BX.browser.IsDoctype())
9931	{
9932		pos.top -= 4; pos.bottom -= 4;
9933		pos.left -= 2; pos.right -= 2;
9934	}
9935*/
9936
9937	switch (this.PARAMS.ATTACH_MODE)
9938	{
9939		case 'bottom':
9940			menu_pos.top = pos.bottom + 9;
9941			menu_pos.left = pos.left;
9942
9943			var arrowPos = 0;
9944			if (!!this.ARROW)
9945			{
9946				if (pos.width > floatWidth)
9947					arrowPos = parseInt(floatWidth/2 - 7);
9948				else
9949					arrowPos = parseInt(Math.min(floatWidth, pos.width)/2 - 7);
9950
9951				if (arrowPos < 7)
9952				{
9953					menu_pos.left -= 15;
9954					arrowPos += 15;
9955				}
9956			}
9957
9958			if (menu_pos.left > wndSize.scrollWidth - floatWidth - 10)
9959			{
9960				var orig_menu_pos = menu_pos.left;
9961				menu_pos.left = wndSize.scrollWidth - floatWidth - 10;
9962
9963				if (!!this.ARROW)
9964					arrowPos += orig_menu_pos - menu_pos.left;
9965			}
9966
9967			if (bFixed)
9968			{
9969				menu_pos.left -= wndSize.scrollLeft;
9970			}
9971
9972			if (!!this.ARROW)
9973				this.ARROW.style.left = arrowPos + 'px';
9974		break;
9975		case 'right':
9976			menu_pos.top = pos.top-1;
9977			menu_pos.left = pos.right;
9978
9979			if (menu_pos.left > wndSize.scrollWidth - floatWidth - 10)
9980			{
9981				menu_pos.left = pos.left - floatWidth - 1;
9982			}
9983		break;
9984	}
9985
9986	if (bFixed)
9987	{
9988		menu_pos.top -= wndSize.scrollTop;
9989	}
9990
9991	if (!!this.ARROW)
9992		this.ARROW.className = 'bx-core-popup-menu-angle';
9993
9994	if((menu_pos.top + floatHeight >
9994 wndSize.scrollTop + wndSize.innerHeight)
9995		|| (menu_pos.top + floatHeight > wndSize.scrollHeight))
9996	{
9997		var new_top = this.PARAMS.ATTACH_MODE == 'bottom'
9998			? pos.top - floatHeight - 9
9999			: pos.bottom - floatHeight + 1;
10000
10001		if((new_top > wndSize.scrollTop)
10002			|| (menu_pos.top + floatHeight > wndSize.scrollHeight))
10003		{
10004			if ((menu_pos.top + floatHeight > wndSize.scrollHeight))
10005			{
10006				menu_pos.top = Math.max(0, wndSize.scrollHeight-floatHeight);
10007				this.toggleArrow(false);
10008			}
10009			else
10010			{
10011				menu_pos.top = new_top;
10012
10013				if (!!this.ARROW)
10014					this.ARROW.className = 'bx-core-popup-menu-angle-bottom';
10015			}
10016		}
10017	}
10018
10019	if (menu_pos.top + menu_pos.left == 0)
10020	{
10021		this.Hide();
10022	}
10023	else
10024	{
10025		this.DIV.style.top = menu_pos.top + 'px';
10026		this.DIV.style.left = menu_pos.left + 'px';
10027	}
10028};
10029
10030BX.CMenu.prototype.adjustToNode = function(el)
10031{
10032	this.PARAMS.parent_attach = BX(el) || this.PARAMS.parent_attach || this.PARAMS.parent;
10033	this.__adjustMenuToNode();
10034};
10035
10036
10037/* components toolbar class */
10038
10039BX.CMenuOpener = function(arParams)
10040{
10041	BX.CMenuOpener.superclass.constructor.apply(this);
10042
10043	this.PARAMS = arParams || {};
10044	this.setParent(this.PARAMS.parent);
10045	this.PARTS = {};
10046
10047	this.SETTINGS.drag_restrict = true;
10048
10049	this.defaultAction = null;
10050
10051	this.timeout = 500;
10052
10053	this.DIV.className = 'bx-component-opener';
10054	this.DIV.ondblclick = BX.PreventDefault;
10055
10056	if (this.PARAMS.component_id)
10057	{
10058		this.PARAMS.transform = !!this.PARAMS.transform;
10059	}
10060
10061	this.OPENERS = [];
10062
10063	this.DIV.appendChild(BX.create('SPAN', {
10064		props: {className: 'bx-context-toolbar' + (this.PARAMS.transform ? ' bx-context-toolbar-vertical-mode' : '')}
10065	}));
10066
10067	//set internal structure and register draggable element
10068	this.PARTS.INNER = this.DIV.firstChild.appendChild(BX.create('SPAN', {
10069		props: {className: 'bx-context-toolbar-inner'},
10070		html: '<span class="bx-context-toolbar-drag-icon"></span><span class="bx-context-toolbar-vertical-line"></span><br>'
10071	}));
10072
10073	this.EXTRA_BUTTONS = {};
10074
10075	var btnCount = 0;
10076	for (var i = 0, len = this.PARAMS.menu.length; i < len; i++)
10077	{
10078		var item = this.addItem(this.PARAMS.menu[i]);
10079		if (null != item)
10080		{
10081			btnCount++;
10082			this.PARTS.INNER.appendChild(item);
10083			this.PARTS.INNER.appendChild(BX.create('BR'));
10084		}
10085	}
10086	var bHasButtons = btnCount > 0;
10087
10088	//menu items will be attached here
10089
10090	this.PARTS.ICONS = this.PARTS.INNER.appendChild(BX.create('SPAN', {
10091		props: {className: 'bx-context-toolbar-icons'}
10092	}));
10093
10094	if (this.PARAMS.component_id)
10095	{
10096		this.PARAMS.pin = !!this.PARAMS.pin;
10097
10098		if (bHasButtons)
10099			this.PARTS.ICONS.appendChild(BX.create('SPAN', {props: {className: 'bx-context-toolbar-separator'}}));
10100
10101		this.PARTS.ICON_PIN = this.PARTS.ICONS.appendChild(BX.create('A', {
10102			attrs: {
10103				href: 'javascript:void(0)'
10104			},
10105			props: {
10106				className: this.PARAMS.pin
10107							? 'bx-context-toolbar-pin-fixed'
10108							: 'bx-context-toolbar-pin'
10109			},
10110			events: {
10111				click: BX.delegate(this.__pin_btn_clicked, this)
10112			}
10113		}));
10114	}
10115
10116
10117	if (this.EXTRA_BUTTONS['components2_props'])
10118	{
10119		var btn = this.EXTRA_BUTTONS['components2_props'] || {URL: 'javascript:void(0)'};
10120		if (null == this.defaultAction)
10121		{
10122			this.defaultAction = btn.ONCLICK;
10123			this.defaultActionTitle = btn.TITLE || btn.TEXT;
10124		}
10125
10126		btn.URL = 'javascript:' + BX.util.urlencode(btn.ONCLICK);
10127
10128		this.ATTACH = this.PARTS.ICONS.appendChild(BX.create('SPAN', {
10129			props: {className: 'bx-context-toolbar-button bx-context-toolbar-button-settings' },
10130			children:
10131			[
10132				BX.create('SPAN',
10133				{
10134					props:{className: 'bx-context-toolbar-button-inner'},
10135					children:
10136					[
10137						BX.create('A', {
10138							attrs: {href: btn.URL},
10139							events: {
10140								mouseover: BX.proxy(this.__msover_text, this),
10141								mouseout: BX.proxy(this.__msout_text, this),
10142								mousedown: BX.proxy(this.__msdown_text, this)
10143							},
10144							html: '<span class="bx-context-toolbar-button-icon bx-context-toolbar-settings-icon"></span>'
10145						}),
10146						BX.create('A', {
10147							attrs: {href: 'javascript: void(0)'},
10148							props: {className: 'bx-context-toolbar-button-arrow'},
10149							events: {
10150								mouseover: BX.proxy(this.__msover_arrow, this),
10151								mouseout: BX.proxy(this.__msout_arrow, this),
10152								mousedown: BX.proxy(this.__msdown_arrow, this)
10153							},
10154							html: '<span class="bx-context-toolbar-button-arrow"></span>'
10155						})
10156					]
10157				})
10158			]
10159		}));
10160
10161		this.OPENER = this.ATTACH.firstChild.lastChild;
10162
10163		var opener = this.attachMenu(this.EXTRA_BUTTONS['components2_submenu']['MENU']);
10164
10165		BX.addCustomEvent(opener, 'onOpenerMenuOpen', BX.proxy(this.__menu_open, this));
10166		BX.addCustomEvent(opener, 'onOpenerMenuClose', BX.proxy(this.__menu_close, this));
10167	}
10168
10169	if (btnCount > 1)
10170	{
10171		this.PARTS.ICONS.appendChild(BX.create('span', { props: {className: 'bx-context-toolbar-separator bx-context-toolbar-separator-switcher'}}));
10172
10173		this.ICON_TRANSFORM = this.PARTS.ICONS.appendChild(BX.create('A', {
10174			attrs: {href: 'javascript: void(0)'},
10175			props: {className: 'bx-context-toolbar-switcher'},
10176			events: {
10177				click: BX.delegate(this.__trf_btn_clicked, this)
10178			}
10179		}));
10180	}
10181
10182	if (this.PARAMS.HINT)
10183	{
10184		this.DIV.BXHINT = this.HINT = new BX.CHint({
10185			parent: this.DIV,
10186			hint:this.PARAMS.HINT.TEXT || '',
10187			title: this.PARAMS.HINT.TITLE || '',
10188			hide_timeout: this.timeout/2,
10189			preventHide: false
10190		});
10191	}
10192
10193	BX.addCustomEvent(this, 'onWindowDragFinished', BX.delegate(this.__onMoveFinished, this));
10194	BX.addCustomEvent('onDynamicModeChange', BX.delegate(this.__onDynamicModeChange, this));
10195	BX.addCustomEvent('onTopPanelCollapse', BX.delegate(this.__onPanelCollapse, this));
10196
10197	BX.addCustomEvent('onMenuOpenerMoved', BX.delegate(this.checkPosition, this));
10198	BX.addCustomEvent('onMenuOpenerUnhide', BX.delegate(this.checkPosition, this));
10199
10200	if (this.OPENERS)
10201	{
10202		for (i=0,len=this.OPENERS.length; i<len; i++)
10203		{
10204			BX.addCustomEvent(this.OPENERS[i], 'onOpenerMenuOpen', BX.proxy(this.__hide_hint, this));
10205		}
10206	}
10207};
10208BX.extend(BX.CMenuOpener, BX.CWindowFloat);
10209
10210BX.CMenuOpener.prototype.setParent = function(new_parent)
10211{
10212	new_parent = BX(new_parent);
10213	if(new_parent.OPENER && new_parent.OPENER != this)
10214	{
10215		new_parent.OPENER.Close();
10216		new_parent.OPENER.clearHoverHoutEvents();
10217	}
10218
10219	if(this.PARAMS.parent && this.PARAMS.parent != new_parent)
10220	{
10221		this.clearHoverHoutEvents();
10222		this.PARAMS.parent.OPENER = null;
10223	}
10224
10225	this.PARAMS.parent = new_parent;
10226	this.PARAMS.parent.OPENER = this;
10227};
10228
10229BX.CMenuOpener.prototype.setHoverHoutEvents = function(hover, hout)
10230{
10231	if(!this.__opener_events_set)
10232	{
10233		BX.bind(this.Get(), 'mouseover', hover);
10234		BX.bind(this.Get(), 'mouseout', hout);
10235		this.__opener_events_set = true;
10236	}
10237};
10238
10239BX.CMenuOpener.prototype.clearHoverHoutEvents = function()
10240{
10241	if(this.Get())
10242	{
10243		BX.unbindAll(this.Get());
10244		this.__opener_events_set = false;
10245	}
10246};
10247
10248
10249BX.CMenuOpener.prototype.unclosable = true;
10250
10251BX.CMenuOpener.prototype.__check_intersection = function(pos_self, pos_other)
10252{
10253	return !(pos_other.right <= pos_self.left || pos_other.left >= pos_self.right
10254			|| pos_other.bottom <= pos_self.top || pos_other.top >= pos_self.bottom);
10255};
10256
10257
10258BX.CMenuOpener.prototype.__msover_text = function() {
10259	this.bx_hover = true;
10260	if (!this._menu_open)
10261		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-text-hover');
10262};
10263
10264BX.CMenuOpener.prototype.__msout_text = function() {
10265	this.bx_hover = false;
10266	if (!this._menu_open)
10267		BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-text-hover bx-context-toolbar-button-text-active');
10268};
10269
10270BX.CMenuOpener.prototype.__msover_arrow = function() {
10271	this.bx_hover = true;
10272	if (!this._menu_open)
10273		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-arrow-hover');
10274};
10275
10276BX.CMenuOpener.prototype.__msout_arrow = function() {
10277	this.bx_hover = false;
10278	if (!this._menu_open)
10279		BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-arrow-hover bx-context-toolbar-button-arrow-active');
10280};
10281
10282BX.CMenuOpener.prototype.__msdown_text = function() {
10283	this.bx_active = true;
10284	if (!this._menu_open)
10285		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-text-active');
10286};
10287
10288BX.CMenuOpener.prototype.__msdown_arrow = function() {
10289	this.bx_active = true;
10290	if (!this._menu_open)
10291		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-arrow-active');
10292};
10293
10294BX.CMenuOpener.prototype.__menu_close = function() {
10295	this._menu_open = false;
10296	this.bx_active = false;
10297	BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-active bx-context-toolbar-button-text-active bx-context-toolbar-button-arrow-active');
10298	if (!this.bx_hover)
10299	{
10300		BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-hover bx-context-toolbar-button-text-hover bx-context-toolbar-button-arrow-hover');
10301		this.bx_hover = false;
10302	}
10303};
10304
10305BX.CMenuOpener.prototype.__menu_open = function() {
10306	this._menu_open = true;
10307};
10308
10309BX.CMenuOpener.prototype.checkPosition = function()
10310{
10311	if (this.isMenuVisible() || this.DIV.style.display == 'none'
10312		|| this == BX.proxy_context || BX.proxy_context.zIndex > this.zIndex)
10313		return;
10314
10315	this.correctPosition(BX.proxy_context);
10316};
10317
10318BX.CMenuOpener.prototype.correctPosition = function(opener)
10319{
10320	var pos_self = BX.pos(this.DIV), pos_other = BX.pos(opener.Get());
10321	if (this.__check_intersection(pos_self, pos_other))
10322	{
10323		var new_top = pos_other.top - pos_self.height;
10324		if (new_top < 0)
10325			new_top = pos_other.bottom;
10326
10327		this.DIV.style.top = new_top + 'px';
10328
10329		BX.addCustomEvent(opener, 'onMenuOpenerHide', BX.proxy(this.restorePosition, this));
10330		BX.onCustomEvent(this, 'onMenuOpenerMoved');
10331	}
10332};
10333
10334BX.CMenuOpener.prototype.restorePosition = function()
10335{
10336	if (!this.MOUSEOVER && !this.isMenuVisible())
10337	{
10338		if (this.originalPos)
10339			this.DIV.style.top = this.originalPos.top + 'px';
10340
10341		BX.removeCustomEvent(BX.proxy_context, 'onMenuOpenerHide', BX.proxy(this.restorePosition, this));
10342		if (this.restore_pos_timeout) clearTimeout(this.restore_pos_timeout);
10343	}
10344	else
10345	{
10346		this.restore_pos_timeout = setTimeout(BX.proxy(this.restorePosition, this), this.timeout);
10347	}
10348};
10349
10350
10351BX.CMenuOpener.prototype.Show = function()
10352{
10353	BX.CMenuOpener.superclass.Show.apply(this, arguments);
10354
10355	this.SetDraggable(this.PARTS.INNER.firstChild);
10356
10357	this.DIV.style.width = 'auto';
10358	this.DIV.style.height = 'auto';
10359
10360	if (!this.PARAMS.pin)
10361	{
10362		this.DIV.style.left = '-1000px';
10363		this.DIV.style.top = '-1000px';
10364
10365		this.Hide();
10366	}
10367	else
10368	{
10369		this.bPosAdjusted = true;
10370		this.bMoved = true;
10371
10372		if (this.PARAMS.top) this.DIV.style.top = this.PARAMS.top + 'px';
10373		if (this.PARAMS.left) this.DIV.style.left = this.PARAMS.left + 'px';
10374
10375		this.DIV.style.display = (!BX.admin.dynamic_mode || BX.admin.dynamic_mode_show_borders) ? 'block' : 'none';
10376
10377		if (this.DIV.style.display == 'block')
10378		{
10379			setTimeout(BX.delegate(function() {BX.onCustomEvent(this, 'onMenuOpenerUnhide')}, this), 50);
10380		}
10381	}
10382};
10383
10384BX.CMenuOpener.prototype.executeDefaultAction = function()
10385{
10386	if (this.defaultAction)
10387	{
10388		if (BX.type.isFunction(this.defaultAction))
10389			this.defaultAction();
10390		else if(BX.type.isString(this.defaultAction))
10391			BX.evalGlobal(this.defaultAction);
10392	}
10393};
10394
10395BX.CMenuOpener.prototype.__onDynamicModeChange = function(val)
10396{
10397	this.DIV.style.display = val ? 'block' : 'none';
10398};
10399
10400BX.CMenuOpener.prototype.__onPanelCollapse = function(bCollapsed, dy)
10401{
10402	this.DIV.style.top = (parseInt(this.DIV.style.top) + dy) + 'px';
10403	if (this.PARAMS.pin)
10404	{
10405		this.__savePosition();
10406	}
10407};
10408
10409BX.CMenuOpener.prototype.__onMoveFinished = function()
10410{
10411	BX.onCustomEvent(this, 'onMenuOpenerMoved');
10412
10413	this.bMoved = true;
10414
10415	if (this.PARAMS.pin)
10416		this.__savePosition();
10417};
10418
10419BX.CMenuOpener.prototype.__savePosition = function()
10420{
10421	var arOpts = {};
10422
10423	arOpts.pin = this.PARAMS.pin;
10424	if (!this.PARAMS.pin)
10425	{
10426		arOpts.top = false; arOpts.left = false; arOpts.transform = false;
10427	}
10428	else
10429	{
10430		arOpts.transform = this.PARAMS.transform;
10431		if (this.bMoved)
10432		{
10433			arOpts.left = parseInt(this.DIV.style.left);
10434			arOpts.top = parseInt(this.DIV.style.top);
10435		}
10436	}
10437
10438	BX.WindowManager.saveWindowOptions(this.PARAMS.component_id, arOpts);
10439};
10440
10441BX.CMenuOpener.prototype.__pin_btn_clicked = function() {this.Pin()};
10442BX.CMenuOpener.prototype.Pin = function(val)
10443{
10444	if (null == val)
10445		this.PARAMS.pin = !this.PARAMS.pin;
10446	else
10447		this.PARAMS.pin = !!val;
10448
10449	this.PARTS.ICON_PIN.className = (this.PARAMS.pin ? 'bx-context-toolbar-pin-fixed' : 'bx-context-toolbar-pin');
10450
10451	this.__savePosition();
10452};
10453
10454BX.CMenuOpener.prototype.__trf_btn_clicked = function() {this.Transform()};
10455BX.CMenuOpener.prototype.Transform = function(val)
10456{
10457	var pos = {};
10458
10459	if (null == val)
10460		this.PARAMS.transform = !this.PARAMS.transform;
10461	else
10462		this.PARAMS.transform = !!val;
10463
10464	if (this.bMoved)
10465	{
10466		pos = BX.pos(this.DIV);
10467	}
10468
10469	if (this.PARAMS.transform)
10470		BX.addClass(this.DIV.firstChild, 'bx-context-toolbar-vertical-mode');
10471	else
10472		BX.removeClass(this.DIV.firstChild, 'bx-context-toolbar-vertical-mode');
10473
10474	if (!this.bMoved)
10475	{
10476		this.adjustPos();
10477	}
10478	else
10479	{
10480		this.DIV.style.left = (pos.right - this.DIV.offsetWidth - (BX.browser.IsIE() && !BX.browser.IsDoctype() ? 2 : 0)) + 'px';
10481	}
10482
10483	this.__savePosition();
10484};
10485
10486BX.CMenuOpener.prototype.adjustToNodeGetPos = function()
10487{
10488	var pos = BX.pos(this.PARAMS.parent/*, true*/);
10489
10490	var scrollSize = BX.GetWindowScrollSize();
10491	var floatWidth = this.DIV.offsetWidth;
10492
10493	pos.left -= BX.admin.__border_dx;
10494	pos.top -= BX.admin.__border_dx;
10495
10496	if (true || !this.PARAMS.transform)
10497	{
10498		pos.top -= 45;
10499	}
10500
10501	if (pos.left > scrollSize.scrollWidth - floatWidth)
10502	{
10503		pos.left = scrollSize.scrollWidth - floatWidth;
10504	}
10505
10506	return pos;
10507};
10508
10509BX.CMenuOpener.prototype.addItem = function(item)
10510{
10511	if (item.TYPE)
10512	{
10513		this.EXTRA_BUTTONS[item.TYPE] = item;
10514		return null;
10515	}
10516	else
10517	{
10518		var q = new BX.CMenuOpenerItem(item);
10519		if (null == this.defaultAction)
10520		{
10521			if (q.item.ONCLICK)
10522			{
10523				this.defaultAction = item.ONCLICK;
10524			}
10525			else if (q.item.MENU)
10526			{
10527				this.defaultAction = BX.delegate(function() {this.Open()}, q.item.OPENER);
10528			}
10529
10530			this.defaultActionTitle = item.TITLE || item.TEXT;
10531
10532			BX.addClass(q.Get(), 'bx-content-toolbar-default');
10533		}
10534		if (q.item.OPENER) this.OPENERS[this.OPENERS.length] = q.item.OPENER;
10535		return q.Get();
10536	}
10537};
10538
10539BX.CMenuOpener.prototype.attachMenu = function(menu)
10540{
10541	var opener = new BX.COpener({
10542		'DIV':  this.OPENER,
10543		'ATTACH': this.ATTACH,
10544		'MENU': menu,
10545		'TYPE': 'click'
10546	});
10547
10548	this.OPENERS[this.OPENERS.length] = opener;
10549
10550	return opener;
10551};
10552
10553BX.CMenuOpener.prototype.__hide_hint = function()
10554{
10555	if (this.HINT) this.HINT.__hide_immediately();
10556};
10557
10558BX.CMenuOpener.prototype.isMenuVisible = function()
10559{
10560	for (var i=0,len=this.OPENERS.length; i<len; i++)
10561	{
10562		if (this.OPENERS[i].isMenuVisible())
10563			return true;
10564	}
10565
10566	return false;
10567};
10568
10569BX.CMenuOpener.prototype.Hide = function()
10570{
10571	if (!this.PARAMS.pin)
10572	{
10573		this.DIV.style.display = 'none';
10574		BX.onCustomEvent(this, 'onMenuOpenerHide');
10575	}
10576};
10577BX.CMenuOpener.prototype.UnHide = function()
10578{
10579	this.DIV.style.display = 'block';
10580	if (!this.bPosAdjusted && !this.PARAMS.pin)
10581	{
10582		this.adjustPos();
10583		this.bPosAdjusted = true;
10584	}
10585
10586	if (null == this.originalPos && !this.bMoved)
10587	{
10588		this.originalPos = BX.pos(this.DIV);
10589	}
10590
10591	BX.onCustomEvent(this, 'onMenuOpenerUnhide');
10592};
10593
10594BX.CMenuOpenerItem = function(item)
10595{
10596	this.item = item;
10597
10598	if (this.item.ACTION && !this.item.ONCLICK)
10599	{
10600		this.item.ONCLICK = this.item.ACTION;
10601	}
10602
10603	this.DIV = BX.create('SPAN');
10604	this.DIV.appendChild(BX.create('SPAN', {props: {className: 'bx-context-toolbar-button-underlay'}}));
10605
10606	this.WRAPPER = this.DIV.appendChild(BX.create('SPAN', {
10607		props: {className: 'bx-context-toolbar-button-wrapper'},
10608		children: [
10609			BX.create('SPAN', {
10610				props: {className: 'bx-context-toolbar-button', title: item.TITLE},
10611				children: [
10612					BX.create('SPAN', {
10613						props: {className: 'bx-context-toolbar-button-inner'}
10614					})
10615				]
10616			})
10617		]
10618	}));
10619
10620	var btn_icon = BX.create('SPAN', {
10621		props: {className: 'bx-context-toolbar-button-icon' + (this.item.ICON || this.item.ICONCLASS ? ' ' + (this.item.ICON || this.item.ICONCLASS) : '')},
10622		attrs: (
10623				!(this.item.ICON || this.item.ICONCLASS)
10624				&&
10625				(this.item.SRC || this.item.IMAGE)
10626			)
10627			? {
10628				style: 'background: scroll transparent url(' + (this.item.SRC || this.item.IMAGE) + ') no-repeat center center !important;'
10629			}
10630			: {}
10631	}), btn_text = BX.create('SPAN', {
10632		props: {className: 'bx-context-toolbar-button-text'},
10633		text: this.item.TEXT
10634	});
10635
10636	if (this.item.ACTION && !this.item.ONCLICK)
10637	{
10638		this.item.ONCLICK = this.item.ACTION;
10639	}
10640
10641	this.bHasMenu = !!this.item.MENU;
10642	this.bHasAction = !!this.item.ONCLICK;
10643
10644	if (this.bHasAction)
10645	{
10646		this.LINK = this.WRAPPER.firstChild.firstChild.appendChild(BX.create('A', {
10647			attrs: {
10648				'href': 'javascript: void(0)'
10649			},
10650			events: {
10651				mouseover: this.bHasMenu ? BX.proxy(this.__msover_text, this) : BX.proxy(this.__msover, this),
10652				mouseout: this.bHasMenu ? BX.proxy(this.__msout_text, this) : BX.proxy(this.__msout, this),
10653				mousedown: this.bHasMenu ? BX.proxy(this.__msdown_text, this) : BX.proxy(this.__msdown, this)
10654			},
10655			children: [btn_icon, btn_text]
10656		}));
10657
10658		if (this.bHasMenu)
10659		{
10660			this.LINK_MENU = this.WRAPPER.firstChild.firstChild.appendChild(BX.create('A', {
10661				props: {className: 'bx-context-toolbar-button-arrow'},
10662				attrs: {
10663					'href': 'javascript: void(0)'
10664				},
10665				events: {
10666					mouseover: BX.proxy(this.__msover_arrow, this),
10667					mouseout: BX.proxy(this.__msout_arrow, this),
10668					mousedown: BX.proxy(this.__msdown_arrow, this)
10669				},
10670				children: [
10671					BX.create('SPAN', {props: {className: 'bx-context-toolbar-button-arrow'}})
10672				]
10673			}));
10674		}
10675
10676	}
10677	else if (this.bHasMenu)
10678	{
10679		this.item.ONCLICK = null;
10680
10681		this.LINK = this.LINK_MENU = this.WRAPPER.firstChild.firstChild.appendChild(BX.create('A', {
10682			attrs: {
10683				'href': 'javascript: void(0)'
10684			},
10685			events: {
10686				mouseover: BX.proxy(this.__msover, this),
10687				mouseout: BX.proxy(this.__msout, this),
10688				mousedown: BX.proxy(this.__msdown, this)
10689			},
10690			children: [
10691				btn_icon,
10692				btn_text
10693			]
10694		}));
10695
10696		this.LINK.appendChild(BX.create('SPAN', {props: {className: 'bx-context-toolbar-single-button-arrow'}}));
10697
10698	}
10699
10700	if (this.bHasMenu)
10701	{
10702		this.item.SUBMENU = new BX.CMenu({
10703			ATTACH_MODE:'bottom',
10704			ITEMS:this.item['MENU'],
10705			//PARENT_MENU:this.parentMenu,
10706			parent: this.LINK_MENU,
10707			parent_attach: this.WRAPPER.firstChild
10708		});
10709
10710		this.item.OPENER = new BX.COpener({
10711			DIV: this.LINK_MENU,
10712			TYPE: 'click',
10713			MENU: this.item.SUBMENU
10714		});
10715
10716		BX.addCustomEvent(this.item.OPENER, 'onOpenerMenuOpen', BX.proxy(this.__menu_open, this));
10717		BX.addCustomEvent(this.item.OPENER, 'onOpenerMenuClose', BX.proxy(this.__menu_close, this));
10718	}
10719
10720	if (this.bHasAction)
10721	{
10722		BX.bind(this.LINK, 'click', BX.delegate(this.__click, this));
10723	}
10724};
10725
10726BX.CMenuOpenerItem.prototype.Get = function() {return this.DIV;};
10727BX.CMenuOpenerItem.prototype.__msover = function() {
10728	this.bx_hover = true;
10729	if (!this._menu_open)
10730		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-hover');
10731};
10732BX.CMenuOpenerItem.prototype.__msout = function() {
10733	this.bx_hover = false;
10734	if (!this._menu_open)
10735		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-hover bx-context-toolbar-button-active');
10736};
10737BX.CMenuOpenerItem.prototype.__msover_text = function() {
10738	this.bx_hover = true;
10739	if (!this._menu_open)
10740		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-text-hover');
10741};
10742BX.CMenuOpenerItem.prototype.__msout_text = function() {
10743	this.bx_hover = false;
10744	if (!this._menu_open)
10745		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-text-hover bx-context-toolbar-button-text-active');
10746};
10747BX.CMenuOpenerItem.prototype.__msover_arrow = function() {
10748	this.bx_hover = true;
10749	if (!this._menu_open)
10750		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-arrow-hover');
10751};
10752BX.CMenuOpenerItem.prototype.__msout_arrow = function() {
10753	this.bx_hover = false;
10754	if (!this._menu_open)
10755		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-arrow-hover bx-context-toolbar-button-arrow-active');
10756};
10757BX.CMenuOpenerItem.prototype.__msdown = function() {
10758	this.bx_active = true;
10759	if (!this._menu_open)
10760		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-active');
10761};
10762BX.CMenuOpenerItem.prototype.__msdown_text = function() {
10763	this.bx_active = true;
10764	if (!this._menu_open)
10765		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-text-active');
10766};
10767BX.CMenuOpenerItem.prototype.__msdown_arrow = function() {
10768	this.bx_active = true;
10769	if (!this._menu_open)
10770		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-arrow-active');
10771};
10772BX.CMenuOpenerItem.prototype.__menu_close = function() {
10773
10774	this._menu_open = false;
10775	this.bx_active = false;
10776	BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-active bx-context-toolbar-button-text-active bx-context-toolbar-button-arrow-active');
10777	if (!this.bx_hover)
10778	{
10779		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-hover bx-context-toolbar-button-text-hover bx-context-toolbar-button-arrow-hover');
10780		this.bx_hover = false;
10781	}
10782};
10783BX.CMenuOpenerItem.prototype.__menu_open = function() {
10784	this._menu_open = true;
10785};
10786
10787BX.CMenuOpenerItem.prototype.__click = function() {BX.evalGlobal(this.item.ONCLICK)};
10788
10789/* global page opener class */
10790BX.CPageOpener = function(arParams)
10791{
10792	//if (null == arParams.pin) arParams.pin = true;
10793	BX.CPageOpener.superclass.constructor.apply(this, arguments);
10794
10795	this.timeout = 505;
10796
10797	window.PAGE_EDIT_CONTROL = this;
10798};
10799BX.extend(BX.CPageOpener, BX.CMenuOpener);
10800
10801BX.CPageOpener.prototype.checkPosition = function()
10802{
10803	if (/*this.isMenuVisible() || this.DIV.style.display == 'none' || */this == BX.proxy_context)
10804		return;
10805
10806	this.correctPosition(BX.proxy_context);
10807};
10808
10809BX.CPageOpener.prototype.correctPosition = function(opener)
10810{
10811	if (this.bPosCorrected) return;
10812	var pos_self;
10813	if (this.DIV.style.display == 'none')
10814	{
10815		pos_self = this.adjustToNodeGetPos();
10816		pos_self.bottom = pos_self.top + 30;
10817		pos_self.right = pos_self.left + 300;
10818	}
10819	else
10820	{
10821		pos_self = BX.pos(this.DIV);
10822	}
10823
10824	var pos_other = BX.pos(opener.Get());
10825	if (this.__check_intersection(pos_self, pos_other))
10826	{
10827		this.DIV.style.display = 'none';
10828		BX.addCustomEvent(opener, 'onMenuOpenerHide', BX.proxy(this.restorePosition, this));
10829
10830		this.bPosCorrected = true;
10831	}
10832};
10833
10834BX.CPageOpener.prototype.restorePosition = function()
10835{
10836	if (BX.proxy_context && BX.proxy_context.Get().style.display == 'none')
10837	{
10838		this.bPosCorrected = false;
10839
10840		if (this.PARAMS.parent.bx_over || this.PARAMS.pin)
10841			this.UnHide();
10842
10843		BX.removeCustomEvent('onMenuOpenerHide', BX.proxy(this.restorePosition, this));
10844	}
10845};
10846
10847BX.CPageOpener.prototype.UnHide = function()
10848{
10849	if (!this.bPosCorrected)
10850		BX.CPageOpener.superclass.UnHide.apply(this, arguments);
10851};
10852
10853BX.CPageOpener.prototype.Remove = function()
10854{
10855	BX.admin.removeComponentBorder(this.PARAMS.parent);
10856	BX.userOptions.save('global', 'settings', 'page_edit_control_enable', 'N');
10857	this.DIV.style.display = 'none';
10858};
10859
10860/******* HINT ***************/
10861BX.CHintSimple = function()
10862{
10863	BX.CHintSimple.superclass.constructor.apply(this, arguments);
10864};
10865BX.extend(BX.CHintSimple, BX.CHint);
10866
10867BX.CHintSimple.prototype.Init = function()
10868{
10869	this.DIV = document.body.appendChild(BX.create('DIV', {props: {className: 'bx-tooltip-simple'}, style: {display: 'none'}, children: [(this.CONTENT = BX.create('DIV'))]}));
10870
10871	if (this.HINT_TITLE)
10872		this.CONTENT.appendChild(BX.create('B', {text: this.HINT_TITLE}));
10873
10874	if (this.HINT)
10875		this.CONTENT_TEXT = this.CONTENT.appendChild(BX.create('DIV')).appendChild(BX.create('SPAN', {html: this.HINT}));
10876
10877	if (this.PARAMS.preventHide)
10878	{
10879		BX.bind(this.DIV, 'mouseout', BX.proxy(this.Hide, this));
10880		BX.bind(this.DIV, 'mouseover', BX.proxy(this.Show, this));
10881	}
10882
10883	this.bInited = true;
10884};
10885
10886/*************************** admin informer **********************************/
10887BX.adminInformer = {
10888
10889	itemsShow: 3,
10890
10891	Init: function (itemsShow)
10892	{
10893		if(itemsShow)
10894			BX.adminInformer.itemsShow = itemsShow;
10895
10896		var informer = BX("admin-informer");
10897
10898		if(informer)
10899			document.body.appendChild(informer);
10900
10901		BX.addCustomEvent("onTopPanelCollapse", BX.proxy(BX.adminInformer.Close, BX.adminInformer));
10902	},
10903
10904	Toggle: function(notifyBlock)
10905	{
10906		var informer = BX("admin-informer");
10907
10908		if(!informer)
10909			return false;
10910
10911		var pos = BX.pos(notifyBlock);
10912
10913		informer.style.top = (parseInt(pos.top)+parseInt(pos.height)+7)+'px';
10914		informer.style.left = pos.left+'px';
10915
10916		if(!BX.hasClass(informer, "adm-informer-active"))
10917			BX.adminInformer.Show(informer);
10918		else
10919			BX.adminInformer.Hide(informer);
10920
10921		return false;
10922	},
10923
10924	Close: function()
10925	{
10926		BX.adminInformer.Hide(BX("admin-informer"));
10927	},
10928
10929	OnInnerClick: function(event)
10930	{
10931		var target = event.target || event.srcElement;
10932
10933		if(target.nodeName.toLowerCase() != 'a' || BX.hasClass(target,"adm-informer-footer"))
10934		{
10935			return BX.PreventDefault(event);
10936		}
10937
10938		return true;
10939	},
10940
10941	ToggleExtra : function()
10942	{
10943		var footerLink = BX("adm-informer-footer");
10944
10945		if (BX.hasClass(footerLink, "adm-informer-footer-collapsed"))
10946			this.ShowAll();
10947		else
10948			this.HideExtra();
10949
10950		return false;
10951	},
10952
10953	ShowAll: function()
10954	{
10955		var informer = BX("admin-informer");
10956		for(var i=0; i<informer.children.length; i++)
10957
10958			if(BX.hasClass(informer.children[i], "adm-informer-item") && informer.children[i].style.display == "none") {
10959				informer.children[i].style.display = "block";
10960			}
10961
10962		var footerLink = BX("adm-informer-footer");
10963
10964		if(footerLink.textContent !== undefined)
10965			footerLink.textContent = BX.message('JSADM_AI_HIDE_EXTRA');
10966		else
10967			footerLink.innerText = BX.message('JSADM_AI_HIDE_EXTRA');
10968
10969		BX.removeClass(footerLink, "adm-informer-footer-collapsed");
10970
10971		return false;
10972	},
10973
10974	HideExtra: function()
10975	{
10976		var informer = BX("admin-informer");
10977		var hided = 0;
10978
10979		for(var i=BX.adminInformer.itemsShow+1; i<informer.children.length; i++)
10980		{
10981			if (BX.hasClass(informer.children[i], "adm-informer-item") && informer.children[i].style.display == "block") {
10982				informer.children[i].style.display = "none";
10983				hided++;
10984			}
10985		}
10986
10987		var footerLink = BX("adm-informer-footer");
10988
10989		var linkText = BX.message('JSADM_AI_ALL_NOTIF')+" ("+(BX.adminInformer.itemsShow+parseInt(hided))+")";
10990
10991		if(footerLink.textContent !== undefined)
10992			footerLink.textContent = linkText;
10993		else
10994			footerLink.innerText = linkText;
10995
10996		BX.addClass(footerLink, "adm-informer-footer-collapsed");
10997
10998		return false;
10999	},
11000
11001	Show: function(informer)
11002	{
11003		var notifButton = BX("adm-header-notif-block");
11004		if (notifButton)
11005			BX.addClass(notifButton, "adm-header-notif-block-active");
11006
11007		BX.onCustomEvent(informer, 'onBeforeAdminInformerShow');
11008		setTimeout(
11009			BX.proxy(function() {
11010					BX.bind(document, "click", BX.proxy(BX.adminInformer.Close, BX.adminInformer));
11011				},
11012				BX.adminInformer
11013			),0
11014		);
11015		BX.addClass(informer, "adm-informer-active");
11016		setTimeout(function() {BX.addClass(informer, "adm-informer-animate");},0);
11017	},
11018
11019	Hide: function(informer)
11020	{
11021		var notifButton = BX("adm-header-notif-block");
11022		if (notifButton)
11023			BX.removeClass(notifButton, "adm-header-notif-block-active");
11024
11025		BX.unbind(document, "click", BX.proxy(BX.adminInformer.Close, BX.adminInformer));
11026
11027		BX.removeClass(informer, "adm-informer-animate");
11028
11029		if (this.IsAnimationSupported())
11030			setTimeout(function() {BX.removeClass(informer, "adm-informer-active");}, 300);
11031		else
11032			BX.removeClass(informer, "adm-informer-active");
11033
11034		BX.onCustomEvent(informer, 'onAdminInformerHide');
11035		//setTimeout(function() {BX.adminInformer.HideExtra();},500);
11036	},
11037
11038	IsAnimationSupported : function()
11039	{
11040		var d = document.body || document.documentElement;
11041		if (typeof(d.style.transition) == "string")
11042			return true;
11043		else if (typeof(d.style.MozTransition) == "string")
11044			return true;
11045		else if (typeof(d.style.OTransition) == "string")
11046			return true;
11047		else if (typeof(d.style.WebkitTransition) == "string")
11048			return true;
11049		else if (typeof(d.style.msTransition) == "string")
11050			return true;
11051
11052		return false;
11053	},
11054
11055
11056	SetItemHtml: function(itemIdx, html)
11057	{
11058		var itemHtmlDiv = BX("adm-informer-item-html-"+itemIdx);
11059
11060		if(!itemHtmlDiv)
11061			return false;
11062
11063		itemHtmlDiv.innerHTML = html;
11064
11065		return true;
11066	},
11067
11068	SetItemFooter: function(itemIdx, html)
11069	{
11070		var itemFooterDiv = BX("adm-informer-item-footer-"+itemIdx);
11071
11072		if(!itemFooterDiv)
11073			return false;
11074
11075		itemFooterDiv.innerHTML = html;
11076
11077		if(html)
11078			itemFooterDiv.style.display = "block";
11079		else
11080			itemFooterDiv.style.display = "none";
11081
11082		return true;
11083	}
11084
11085};
11086
11087}
11087)(window);
11088
11089/* End */
11090;

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.