PageSourceSearch

https://i-gifts.su/bitrix/js/main/core/core.js?1343538524

js i-gifts.su collected 2026-10-05 11:26:18 UTC 57,305 bytes, 2,768 lines download raw bytes

1/**********************************************************************/
2/*********** Bitrix JS Core library ver 0.9.0 beta ********************/
3/**********************************************************************/
4
5;(function(window){
6if (window.BX) return;
7
8
9var BX = function(node, bCache)
10{
11	if (BX.type.isNotEmptyString(node))
12	{
13		var ob;
14
15		if (!!bCache && null != NODECACHE[node]) ob = NODECACHE[node];
16		ob = ob || document.getElementById(node);
17		if (!!bCache) NODECACHE[node] = ob;
18
19		return ob;
20	}
21	else if (BX.type.isDomNode(node))
22		return node;
23	else if (BX.type.isFunction(node))
24		return BX.ready(node);
25
26	return null;
27},
28
29/* ready */
30__readyHandler = null,
31readyBound = false,
32readyList = [],
33
34/* list of registered proxy functions */
35proxyId = 1,
36proxyList = [],
37
38/* getElementById cache */
39NODECACHE = {},
40
41/* List of denied event handlers */
42deniedEvents = [],
43
44/* list of registered event handlers */
45eventsList = [],
46
47/* list of registered custom events */
48customEvents = {},
49
50/* list of external garbage collectors */
51garbageCollectors = [],
52
53/* browser detection */
54bOpera = navigator.userAgent.toLowerCase().indexOf('opera') != -1,
55bSafari = navigator.userAgent.toLowerCase().indexOf('webkit') != -1,
56bIE = document.attachEvent && !bOpera,
57
58/* regexps */
59r = {
60	script: /<script([^>]*)>/i,
61	script_src: /src=["\']([^"\']+)["\']/i,
62	space: /\s+/,
63	ltrim: /^[\s\r\n]+/g,
64	rtrim: /[\s\r\n]+$/g,
65	style: /<link.*?(rel="stylesheet"|type="text\/css")[^>]*/i,
66	style_href: /href=["\']([^"\']+)["\']/i
67},
68
69eventTypes = {
70	click: 'MouseEvent',
71	dblclick: 'MouseEvent',
72	mousedown: 'MouseEvent',
73	mousemove: 'MouseEvent',
74	mouseout: 'MouseEvent',
75	mouseover: 'MouseEvent',
76	mouseup: 'MouseEvent'
77},
78
79lastWait = [];
80
81BX.ext = function(ob) {for (var i in ob) this[i] = ob[i];}
82
83/* OO emulation utility */
84BX.extend = function(child, parent)
85{
86	var f = function() {};
87	f.prototype = parent.prototype;
88
89	child.prototype = new f();
90	child.prototype.constructor = child;
91
92	child.superclass = parent.prototype;
93	if(parent.prototype.constructor == Object.prototype.constructor)
94	{
95		parent.prototype.constructor = parent;
96	}
97}
98
99BX.debug = function(mess)
100{
101	if (window.BXDEBUG)
102	{
103		if (console && console.log)
104			console.log(mess);
105	}
106}
107
108BX.is_subclass_of = function(ob, parent_class)
109{
110	if (ob instanceof parent_class)
111		return true;
112
113	if (parent_class.superclass)
114		return BX.is_subclass_of(ob, parent_class.superclass);
115
116	return false;
117}
118
119// language utility
120BX.message = function(mess)
121{
122	if (BX.type.isString(mess))
123	{
124		if (typeof BX.message[mess] == 'undefined')
125			BX.debug('message undefined: ' + mess);
126		return BX.message[mess];
127	}
128	else
129	{
130		for (var i in mess)
131		{
132			BX.message[i] = mess[i];
133		}
134		return true;
135	}
136};
137
138BX.bitrix_sessid = function() {return BX.message.bitrix_sessid;}
139
140/* DOM manipulation */
141BX.create = function(tag, data, context)
142{
143	context = context || document;
144
145	if (null == data && typeof tag == 'object' && tag.constructor !== String)
146	{
147		data = tag; tag = tag.tag;
148	}
149
150	var elem;
151	if (BX.browser.IsIE() && !BX.browser.IsIE9() && null != data && null != data.props && (data.props.name || data.props.id))
152	{
153		elem = context.createElement('<' + tag + (data.props.name ? ' name="' + data.props.name + '"' : '') + (data.props.id ? ' id="' + data.props.id + '"' : '') + '>');
154	}
155	else
156	{
157		elem = context.createElement(tag);
158	}
159
160	return data ? BX.adjust(elem, data) : elem;
161}
162
163BX.adjust = function(elem, data)
164{
165	var j,len;
166
167	if (!elem.nodeType)
168		return null;
169
170	if (elem.nodeType == 9)
171		elem = elem.body;
172
173	if (data.attrs)
174	{
175		for (j in data.attrs)
176		{
177			if (j == 'class' || j == 'className')
178				elem.className = data.attrs[j];
179			else if(data.attrs[j] == "")
180				elem.removeAttribute(j);
181			else
182				elem.setAttribute(j, data.attrs[j]);
183		}
184	}
185
186	if (data.style)
187	{
188		for (j in data.style)
189			elem.style[j] = data.style[j];
190	}
191
192	if (data.props)
193	{
194		for (j in data.props)
195			elem[j] = data.props[j];
196	}
197
198	if (data.events)
199	{
200		for (j in data.events)
201			BX.bind(elem, j, data.events[j]);
202	}
203
204	if (data.children && data.children.length > 0)
205	{
206		for (j=0,len=data.children.length; j<len; j++)
207		{
208			if (BX.type.isNotEmptyString(data.children[j]))
209				elem.innerHTML += data.children[j];
210			else if (BX.type.isElementNode(data.children[j]))
211				elem.appendChild(data.children[j]);
212		}
213	}
214	else if (data.text)
215	{
216		BX.cleanNode(elem);
217		elem.appendChild((elem.ownerDocument || document).createTextNode(data.text));
218	}
219	else if (data.html)
220	{
221		elem.innerHTML = data.html;
222	}
223
224	return elem;
225}
226
227BX.remove = function(ob)
228{
229	if (null != ob.parentNode)
230		ob.parentNode.removeChild(ob);
231	ob = null;
232	return null;
233}
234
235BX.cleanNode = function(node, bSuicide)
236{
237	node = BX(node);
238	bSuicide = !!bSuicide;
239
240	if (node && node.childNodes)
241	{
242		while(node.childNodes.length > 0)
243			node.removeChild(node.firstChild);
244	}
245
246	if (node && bSuicide)
247	{
248		node = BX.remove(node);
249	}
250
251	return node;
252}
253
254BX.addClass = function(ob, value)
255{
256	var classNames;
257	ob = BX(ob)
258
259	if (ob)
260	{
261		if (!ob.className)
262		{
263			ob.className = value
264		}
265		else
266		{
267			classNames = (value || "").split(r.space);
268
269			var className = " " + ob.className + " ";
270			for (var j = 0, cl = classNames.length; j < cl; j++)
271			{
272				if (className.indexOf(" " + classNames[j] + " ") < 0)
273				{
274					ob.className += " " + classNames[j];
275				}
276			}
277		}
278	}
279
280	return ob;
281}
282
283BX.removeClass = function(ob, value)
284{
285	ob = BX(ob);
286	if (ob)
287	{
288		if (ob.className)
289		{
290			if (BX.type.isString(value))
291			{
292				var classNames = value.split(r.space), className = " " + ob.className + " ";
293				for (var j = 0, cl = classNames.length; j < cl; j++)
294				{
295					className = className.replace(" " + classNames[j] + " ", " ");
296				}
297
298				ob.className = BX.util.trim(className);
299			}
300			else
301			{
302				ob.className = "";
303			}
304		}
305	}
306
307	return ob;
308}
309
310BX.toggleClass = function(ob, value)
311{
312	var className;
313	if (BX.type.isArray(value))
314	{
315		className = ' ' + ob.className + ' ';
316		for (var j = 0, len = value.length; j < len; j++)
317		{
318			if (BX.hasClass(ob, value[j]))
319			{
320				className = (' ' + className + ' ').replace(' ' + value[j] + ' ', ' ');
321				className += ' ' + value[j >= len-1 ? 0 : j+1];
322
323				j--;
324				break;
325			}
326		}
327
328		if (j == len)
329			ob.className += ' ' + value[0];
330		else
331			ob.className = className;
332
333		ob.className = BX.util.trim(ob.className);
334	}
335	else if (BX.type.isNotEmptyString(value))
336	{
337		className = ob.className;
338		if (BX.hasClass(ob, value))
339		{
340			className = (' ' + className + ' ').replace(' ' + value + ' ', ' ');
341		}
342		else
343		{
344			className += ' ' + value;
345		}
346
347		ob.className = BX.util.trim(className);
348	}
349
350	return ob;
351}
352
353BX.hasClass = function(el, className)
354{
355	if (!el.className)
356		return false;
357	return ((" " + el.className + " ").indexOf(" " + className + " ")) >= 0;
358}
359
360BX.hoverEvents = function(el)
361{
362	if (el)
363		return BX.adjust(el, {events: BX.hoverEvents()});
364	else
365		return {mouseover: BX.hoverEventsHover, mouseout: BX.hoverEventsHout};
366}
367
368BX.hoverEventsHover = function(){BX.addClass(this,'bx-hover');this.BXHOVER=true;}
369BX.hoverEventsHout = function(){BX.removeClass(this,'bx-hover');this.BXHOVER=false;}
370
371BX.focusEvents = function(el)
372{
373	if (el)
374		return BX.adjust(el, {events: BX.focusEvents()});
375	else
376		return {mouseover: BX.focusEventsFocus, mouseout: BX.focusEventsBlur};
377}
378
379BX.focusEventsFocus = function(){BX.addClass(this,'bx-focus');this.BXFOCUS=true;}
380BX.focusEventsBlur = function(){BX.removeClass(this,'bx-focus');this.BXFOCUS=false;}
381
382BX.setUnselectable = function(node)
383{
384	BX.addClass(node, 'bx-unselectable');
385	node.setAttribute('unSelectable', 'on');
386}
387
388BX.setSelectable = function(node)
389{
390	BX.removeClass(node, 'bx-unselectable');
391	node.removeAttribute('unSelectable');
392}
393
394BX.styleIEPropertyName = function(name)
395{
396	if (name == 'float')
397		name = BX.browser.IsIE() ? 'styleFloat' : 'cssFloat';
398	else
399	{
400		var reg = /(\-([a-z]){1})/g;
401		if (reg.test(name))
402		{
403			name = name.replace(reg, function () {return arguments[2].toUpperCase();});
404		}
405	}
406	return name;
407}
408
409/* CSS-notation should be used here */
410BX.style = function(el, property, value)
411{
412	if (!BX.type.isElementNode(el))
413		return null;
414
415	if (value == null)
416	{
417		var res;
418		if(el.currentStyle)
419			res = el.currentStyle[BX.styleIEPropertyName(property)];
420		else if(window.getComputedStyle)
421			res = BX.GetContext(el).getComputedStyle(el, null).getPropertyValue(property);
422
423		if(!res)
424			res = '';
425		return res;
426	}
427	else
428	{
429		el.style[BX.styleIEPropertyName(property)] = value;
430		return el;
431	}
432}
433
434BX.focus = function(el)
435{
436	try
437	{
438		el.focus();
439		return true;
440	}
441	catch (e)
442	{
443		return false;
444	}
445}
446
447/*
448	params: {
449		tagName|tag : 'tagName',
450		className|class : 'className',
451		attribute : {attribute : value, attribute : value} | attribute | [attribute, attribute....],
452		property : {prop: value, prop: value} | prop | [prop, prop]
453	}
454
455	all values can be RegExps or strings
456*/
457BX.findChildren = function(obj, params, recursive)
458{
459	return BX.findChild(obj, params, recursive, true);
460}
461
462BX.findChild = function(obj, params, recursive, get_all)
463{
464	if(!obj || !obj.childNodes) return null;
465
466	recursive = !!recursive; get_all = !!get_all;
467
468	var n = obj.childNodes.length, result = [];
469
470	for (var j=0; j<n; j++)
471	{
472		var child = obj.childNodes[j];
473
474		if (_checkNode(child, params))
475		{
476			if (get_all)
477				result.push(child)
478			else
479				return child;
480		}
481
482		if(recursive == true)
483		{
484			var res = BX.findChild(child, params, recursive, get_all);
485			if (res)
486			{
487				if (get_all)
488					result = BX.util.array_merge(result, res);
489				else
490					return res;
491			}
492		}
493	}
494
495	if (get_all && result.length > 0)
496		return result;
497	else
498		return null;
499}
500
501BX.findParent = function(obj, params)
502{
503	if(!obj)
504		return null;
505
506	var o = obj;
507	while(o.parentNode)
508	{
509		var parent = o.parentNode;
510
511		if (_checkNode(parent, params))
512			return parent;
513
514		o = parent;
515	}
516	return null;
517}
518
519BX.findNextSibling = function(obj, params)
520{
521	if(!obj)
522		return null;
523	var o = obj;
524	while(o.nextSibling)
525	{
526		var sibling = o.nextSibling;
527		if (_checkNode(sibling, params))
528			return sibling;
529		o = sibling;
530	}
531	return null;
532}
533
534BX.findPreviousSibling = function(obj, params)
535{
536	if(!obj)
537		return null;
538
539	var o = obj;
540	while(o.previousSibling)
541	{
542		var sibling = o.previousSibling;
543		if(_checkNode(sibling, params))
544			return sibling;
545		o = sibling;
546	}
547	return null;
548}
549
550BX.clone = function(obj, bCopyObj)
551{
552	var _obj, i, l;
553	if (bCopyObj !== false)
554		bCopyObj = true;
555
556	if (obj === null)
557		return null;
558
559	if (BX.type.isDomNode(obj))
560	{
561		_obj = obj.cloneNode(bCopyObj);
562	}
563	else if (typeof obj == 'object')
564	{
565		if (BX.type.isArray(obj))
566		{
567			_obj = [];
568			for (i=0,l=obj.length;i<l;i++)
569			{
570				if (typeof obj[i] == "object" && bCopyObj)
571					_obj[i] = BX.clone(obj[i], bCopyObj);
572				else
573					_obj[i] = obj[i];
574			}
575		}
576		else
577		{
578			_obj =  {};
579			if (obj.constructor)
580			{
581				if (obj.constructor === Date)
582					_obj = new Date(obj);
583				else
584					_obj = new obj.constructor();
585			}
586
587			for (i in obj)
588			{
589				if (typeof obj[i] == "object" && bCopyObj)
590					_obj[i] = BX.clone(obj[i], bCopyObj);
591				else
592					_obj[i] = obj[i];
593			}
594		}
595
596	}
597	else
598	{
599		_obj = obj;
600	}
601
602	return _obj;
603}
604
605/* events */
606BX.bind = function(el, evname, func)
607{
608	if (!el)
609		return;
610
611	if (evname === 'mousewheel')
612		BX.bind(el, 'DOMMouseScroll', func);
613
614	if (el.addEventListener)
615		el.addEventListener(evname, func, false);
616	else if(el.attachEvent) // IE
617		el.attachEvent("on" + evname, BX.proxy(func, el));
618	else
619		el["on" + evname] = func;
620
621	eventsList[eventsList.length] = {'element': el, 'event': evname, 'fn': func};
622}
623
624BX.unbind = function(el, evname, func)
625{
626	if (!el)
627		return;
628
629	if (evname === 'mousewheel')
630		BX.unbind(el, 'DOMMouseScroll', func);
631
632	if(el.removeEventListener) // Gecko / W3C
633		el.removeEventListener(evname, func, false);
634	else if(el.detachEvent) // IE
635		el.detachEvent("on" + evname, BX.proxy(func, el));
636	else
637		el["on" + evname] = null;
638}
639
640BX.unbindAll = function(el)
641{
642	if (!el)
643		return;
644
645	for (var i=0,len=eventsList.length; i<len; i++)
646	{
647		try
648		{
649			if (eventsList[i] && (null==el || el==eventsList[i].element))
650			{
651				BX.unbind(eventsList[i].element, eventsList[i].event, eventsList[i].fn);
652				eventsList[i] = null;
653			}
654		}
655		catch(e){}
656	}
657
658	if (null==el)
659	{
660		eventsList = [];
661	}
662}
663
664var captured_events = null, _bind = null;
665BX.CaptureEvents = function(el_c, evname_c)
666{
667	if (_bind)
668		return false;
669
670	_bind = BX.bind; captured_events = [];
671
672	BX.bind = function(el, evname, func)
673	{
674		if (el === el_c && evname === evname_c)
675			captured_events.push(func);
676
677		_bind.apply(this, arguments);
678	}
679}
680
681BX.CaptureEventsGet = function()
682{
683	if (_bind)
684	{
685		BX.bind = _bind;
686
687		var captured = captured_events;
688
689		_bind = null; captured_events = null;
690		return captured;
691	}
692}
693
694BX.fireEvent = function(ob,ev)
695{
696	var result = true;
697	if (document.createEventObject)
698	{
699		// IE
700		var e = document.createEventObject();
701		result = ob.fireEvent('on' + ev, e);
702		if (ob[ev])
703			ob[ev]();
704	}
705	else
706	{
707		// non-IE
708		var e = null;
709
710		switch (eventTypes[ev])
711		{
712			case 'MouseEvent':
713				e = document.createEvent('MouseEvent');
714				e.initMouseEvent(ev, true, true, top, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, null);
715			break;
716			default:
717				e = document.createEvent('Event');
718				e.initEvent(ev, true, true);
719		}
720
721		result = ob.dispatchEvent(e);
722    }
723	return result;
724}
725
726BX.getWheelData = function(e)
727{
728	e = e || window.event;
729	return wheelData = e.detail ? e.detail * -1 : e.wheelDelta / 40;
730}
731
732BX.proxy_context = null;
733
734BX.delegate = function (func, thisObject)
735{
736	if (!func || !thisObject)
737		return func;
738
739	return function() {
740		var cur = BX.proxy_context;
741		BX.proxy_context = this;
742		var res = func.apply(thisObject, arguments);
743		BX.proxy_context = cur;
744		return res;
745	}
746}
747
748BX.delegateLater = function (func_name, thisObject, contextObject)
749{
750	return function()
751	{
752		if (thisObject[func_name])
753		{
754			var cur = BX.proxy_context;
755			BX.proxy_context = this;
756			var res = thisObject[func_name].apply(contextObject||thisObject, arguments);
757			BX.proxy_context = cur;
758			return res;
759		}
760	}
761}
762
763BX.proxy = function(func, thisObject)
764{
765	if (!func || !thisObject)
766		return func;
767
768	if (null == thisObject.__proxy_id)
769	{
770		proxyList[thisObject.__proxy_id = proxyList.length] = {};
771	}
772
773	if (null == func.__proxy_id)
774		func.__proxy_id = proxyId++;
775
776	if (null == proxyList[thisObject.__proxy_id][func.__proxy_id])
777		proxyList[thisObject.__proxy_id][func.__proxy_id] = BX.delegate(func, thisObject);
778
779	return proxyList[thisObject.__proxy_id][func.__proxy_id];
780}
781
782BX.bindDelegate = function (elem, eventName, isTarget, handler)
783{
784	var h = BX.delegateEvent(elem, isTarget, handler);
785	BX.bind(elem, eventName, h);
786	return h;
787}
788
789BX.delegateEvent = function(el, isTarget, handler)
790{
791	return function(e)
792	{
793		e = e || window.event;
794		var target = e.target || e.srcElement;
795
796		while (target != this)
797		{
798			if (_checkNode(target, isTarget))
799			{
800				return handler.call(target, e);
801			}
802
803			target = target.parentNode;
804		}
805	}
806}
807
808BX.False = function() {return false;}
809BX.DoNothing = function() {}
810
811// TODO: also check event handlers set via BX.bind()
812BX.denyEvent = function(el, ev)
813{
814	deniedEvents.push([el, ev, el['on' + ev]]);
815	el['on' + ev] = BX.DoNothing;
816}
817
818BX.allowEvent = function(el, ev)
819{
820	for(var i=0, len=deniedEvents.length; i<len; i++)
821	{
822		if (deniedEvents[i][0] == el && deniedEvents[i][1] == ev)
823		{
824			el['on' + ev] = deniedEvents[i][2];
825			BX.util.deleteFromArray(deniedEvents, i);
826			return;
827		}
828	}
829}
830
831BX.fixEventPageXY = function(event)
832{
833	BX.fixEventPageX(event);
834	BX.fixEventPageY(event);
835	return event;
836};
837
838BX.fixEventPageX = function(event)
839{
840	if (event.pageX == null && event.clientX != null)
841	{
842		event.pageX =
843			event.clientX +
844			(document.documentElement && document.documentElement.scrollLeft || document.body && document.body.scrollLeft || 0) -
845			(document.documentElement.clientLeft || 0);
846	}
847
848	return event;
849};
850
851BX.fixEventPageY = function(event)
852{
853	if (event.pageY == null && event.clientY != null)
854	{
855		event.pageY =
856			event.clientY +
857			(document.documentElement && document.documentElement.scrollTop || document.body && document.body.scrollTop || 0) -
858			(document.documentElement.clientTop || 0);
859	}
860
861	return event;
862};
863
864BX.PreventDefault = function(e)
865{
866	if(!e) e = window.event;
867	if(e.stopPropagation)
868	{
869		e.preventDefault();
870		e.stopPropagation();
871	}
872	else
873	{
874		e.cancelBubble = true;
875		e.returnValue = false;
876	}
877	return false;
878}
879
880BX.eventReturnFalse = function(e)
881{
882	e=e||window.event;
883	if (e && e.preventDefault) e.preventDefault();
884	else e.returnValue = false;
885	return false;
886}
887
888BX.eventCancelBubble = function(e)
889{
890	e=e||window.event;
891	if(e && e.stopPropagation)
892		e.stopPropagation();
893	else
894		e.cancelBubble = true;
895}
896
897/* custom events */
898/*
899	BX.addCustomEvent(eventObject, eventName, eventHandler) - set custom event handler for particular object
900	BX.addCustomEvent(eventName, eventHandler) - set custom event handler for all objects
901*/
902BX.addCustomEvent = function(eventObject, eventName, eventHandler)
903{
904	/* shift parameters for short version */
905	if (BX.type.isString(eventObject))
906	{
907		eventHandler = eventName;
908		eventName = eventObject;
909		eventObject = window;
910	}
911
912	eventName = eventName.toUpperCase();
913
914	if (!customEvents[eventName])
915		customEvents[eventName] = [];
916
917	customEvents[eventName].push(
918		{
919			handler: eventHandler,
920			obj: eventObject
921		}
922	);
923}
924
925BX.removeCustomEvent = function(eventObject, eventName, eventHandler)
926{
927	/* shift parameters for short version */
928	if (BX.type.isString(eventObject))
929	{
930		eventHandler = eventName;
931		eventName = eventObject;
932		eventObject = window;
933	}
934
935	eventName = eventName.toUpperCase();
936
937	if (!customEvents[eventName])
938		return;
939
940	for (var i = 0, l = customEvents[eventName].length; i < l; i++)
941	{
942		if (!customEvents[eventName][i])
943			continue;
944		if (customEvents[eventName][i].handler == eventHandler && customEvents[eventName][i].obj == eventObject)
945		{
946			delete customEvents[eventName][i];
947			return;
948		}
949	}
950}
951
952BX.onCustomEvent = function(eventObject, eventName, arEventParams)
953{
954	/* shift parameters for short version */
955	if (BX.type.isString(eventObject))
956	{
957		arEventParams = eventName;
958		eventName = eventObject;
959		eventObject = window;
960	}
961
962	eventName = eventName.toUpperCase();
963
964	if (!customEvents[eventName])
965		return;
966
967	if (!arEventParams)
968		arEventParams = [];
969
970	var h;
971	for (var i = 0, l = customEvents[eventName].length; i < l; i++)
972	{
973		h = customEvents[eventName][i];
974		if (!h || !h.handler)
975			continue;
976
977		if (h.obj == window || /*eventObject == window || */h.obj == eventObject) //- only global event handlers will be called
978		{
979			h.handler.apply(eventObject, arEventParams);
980		}
981	}
982}
983
984BX.parseJSON = function(data)
985{
986	var result = null;
987	if (BX.type.isString(data))
988	{
989		try {
990			if (data.indexOf("\n") >= 0)
991				eval('result = ' + data);
992			else
993				result = (new Function("return " + data))();
994		}catch(e){}
995	}
996
997	return result;
998}
999
1000/* ready */
1001BX.isReady = false;
1002BX.ready = function(handler)
1003{
1004	bindReady();
1005
1006	if (BX.isReady)
1007		handler.call(document);
1008	else if (readyList)
1009		readyList.push(handler);
1010}
1011
1012BX.submit = function(obForm, action_name, action_value)
1013{
1014	action_name = action_name || 'save';
1015	if (!obForm['BXFormSubmit_' + action_name])
1016	{
1017		obForm['BXFormSubmit_' + action_name] = obForm.appendChild(BX.create('INPUT', {
1018			'props': {
1019				'type': 'submit',
1020				'name': action_name,
1021				'value': action_value || 'Y'
1022			},
1023			'style': {
1024				'display': 'none'
1025			}
1026		}));
1027	}
1028
1029	BX.fireEvent(obForm['BXFormSubmit_' + action_name], 'click');
1030}
1031
1032
1033/* browser detection */
1034BX.browser = {
1035
1036	IsIE: function()
1037	{
1038		return bIE;
1039	},
1040
1041	IsIE6: function()
1042	{
1043		return (/MSIE 6/i.test(navigator.userAgent));
1044	},
1045
1046	IsIE9: function()
1047	{
1048		return !!document.documentMode && document.documentMode >= 9;
1049	},
1050
1051	IsOpera: function()
1052	{
1053		return bOpera;
1054	},
1055
1056	IsSafari: function()
1057	{
1058		return bSafari;
1059	},
1060
1061	IsMac: function()
1062	{
1063		return (/Macintosh/i.test(navigator.userAgent));
1064	},
1065
1066	IsAndroid: function()
1067	{
1068		return (/Android/i.test(navigator.userAgent));
1069	},
1070
1071	IsIOS: function()
1072	{
1073		return (/(iPad;)|(iPhone;)/i.test(navigator.userAgent));
1074	},
1075
1076	IsDoctype: function(pDoc)
1077	{
1078		pDoc = pDoc || document;
1079
1080		if (pDoc.compatMode)
1081			return (pDoc.compatMode == "CSS1Compat");
1082
1083		if (pDoc.documentElement && pDoc.documentElement.clientHeight)
1084			return true;
1085
1086		return false;
1087	},
1088
1089	SupportLocalStorage: function() {
1090		return !!BX.localStorage && !!BX.localStorage.checkBrowser()
1091	}
1092}
1093
1094/* low-level fx funcitons*/
1095BX.show = function(ob, displayType)
1096{
1097	if (ob.BXDISPLAY || !_checkDisplay(ob, displayType))
1098	{
1099		ob.style.display = ob.BXDISPLAY;
1100	}
1101}
1102
1103BX.hide = function(ob, displayType)
1104{
1105	if (!ob.BXDISPLAY)
1106		_checkDisplay(ob, displayType);
1107
1108	ob.style.display = 'none';
1109}
1110
1111BX.toggle = function(ob, values)
1112{
1113	if (!values && BX.type.isElementNode(ob))
1114	{
1115		var bShow = true;
1116		if (ob.BXDISPLAY)
1117			bShow = !_checkDisplay(ob);
1118		else
1119			bShow = ob.style.display == 'none';
1120
1121		if (bShow)
1122			BX.show(ob);
1123		else
1124			BX.hide(ob);
1125	}
1126	else if (BX.type.isArray(values))
1127	{
1128		for (var i=0,len=values.length; i<len; i++)
1129		{
1130			if (ob == values[i])
1131			{
1132				ob = values[i==len-1 ? 0 : i+1]
1133				break;
1134			}
1135		}
1136		if (i==len)
1137			ob = values[0];
1138	}
1139
1140	return ob;
1141}
1142
1143/* some useful util functions */
1144
1145BX.util = {
1146	array_values: function(ar)
1147	{
1148		if (!BX.type.isArray(ar))
1149			return BX.util._array_values_ob(ar);
1150		var arv = [];
1151		for(var i=0,l=ar.length;i<l;i++)
1152			if (ar[i] !== null && typeof ar[i] != 'undefined')
1153				arv.push(ar[i]);
1154		return arv;
1155	},
1156
1157	_array_values_ob: function(ar)
1158	{
1159		var arv = [];
1160		for(var i in ar)
1161			if (ar[i] !== null && typeof ar[i] != 'undefined')
1162				arv.push(ar[i]);
1163		return arv;
1164	},
1165
1166	array_keys: function(ar)
1167	{
1168		if (!BX.type.isArray(ar))
1169			return BX.util._array_keys_ob(ar);
1170		var arv = [];
1171		for(var i=0,l=ar.length;i<l;i++)
1172			if (ar[i] !== null && typeof ar[i] != 'undefined')
1173				arv.push(i);
1174		return arv;
1175	},
1176
1177	_array_keys_ob: function(ar)
1178	{
1179		var arv = [];
1180		for(var i in ar)
1181			if (ar[i] !== null && typeof ar[i] != 'undefined')
1182				arv.push(i);
1183		return arv;
1184	},
1185
1186	array_merge: function(first, second)
1187	{
1188		if (!BX.type.isArray(first)) first = [];
1189		if (!BX.type.isArray(second)) second = [];
1190
1191		var i = first.length, j = 0;
1192
1193		if (typeof second.length === "number")
1194		{
1195			for (var l = second.length; j < l; j++)
1196			{
1197				first[i++] = second[j];
1198			}
1199		}
1200		else
1201		{
1202			while (second[j] !== undefined)
1203			{
1204				first[i++] = second[j++];
1205			}
1206		}
1207
1208		first.length = i;
1209
1210		return first;
1211	},
1212
1213	array_unique: function(ar)
1214	{
1215		var i=0,j,len=ar.length;
1216		if(len<2) return ar;
1217
1218		for (; i<len-1;i++)
1219		{
1220			for (j=i+1; j<len;j++)
1221			{
1222				if (ar[i]==ar[j])
1223				{
1224					ar.splice(j--,1); len--;
1225				}
1226			}
1227		}
1228
1229		return ar;
1230	},
1231
1232	in_array: function(needle, haystack)
1233	{
1234		for(var i=0; i<haystack.length; i++)
1235		{
1236			if(haystack[i] == needle)
1237				return true;
1238		}
1239		return false;
1240	},
1241
1242	array_search: function(needle, haystack)
1243	{
1244		for(var i=0; i<haystack.length; i++)
1245		{
1246			if(haystack[i] == needle)
1247				return i;
1248		}
1249		return -1;
1250	},
1251
1252	object_search_key: function(needle, haystack)
1253	{
1254		if (haystack[needle])
1255			return haystack[needle];
1256
1257		for(var i in haystack)
1258		{
1259			if (typeof haystack[i] == "object")
1260			{
1261				var result = BX.util.object_search_key(needle, haystack[i]);
1262				if (result !== false)
1263					return result;
1264			}
1265		}
1266		return false;
1267	},
1268
1269	trim: function(s)
1270	{
1271		if (BX.type.isString(s))
1272			return s.replace(r.ltrim, '').replace(r.rtrim, '');
1273		else
1274			return s;
1275	},
1276
1277	urlencode: function(s){return encodeURIComponent(s);},
1278
1279	// it may also be useful. via sVD.
1280	deleteFromArray: function(ar, ind) {return ar.slice(0, ind).concat(ar.slice(ind + 1));},
1281	insertIntoArray: function(ar, ind, el) {return ar.slice(0, ind).concat([el]).concat(ar.slice(ind));},
1282
1283	htmlspecialchars: function(str)
1284	{
1285		if(!str.replace) return str;
1286
1287		return str.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
1288	},
1289
1290	htmlspecialcharsback: function(str)
1291	{
1292		if(!str.replace) return str;
1293
1294		return str.replace(/\&quot;/g, '"').replace(/&#39;/g, "'").replace(/\&lt;/g, '<').replace(/\&gt;/g, '>').replace(/\&amp;/g, '&');
1295	},
1296
1297	// Quote regular expression characters plus an optional character
1298	preg_quote: function(str, delimiter)
1299	{
1300		if(!str.replace)
1301			return str;
1302		return str.replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
1303	},
1304
1305	jsencode: function(str)
1306	{
1307		if (!str || !str.replace)
1308			return str;
1309
1310		var escapes =
1311		[
1312			{ c: "\\\\", r: "\\\\" }, // should be first
1313			{ c: "\\t", r: "\\t" },
1314			{ c: "\\n", r: "\\n" },
1315			{ c: "\\r", r: "\\r" },
1316			{ c: "\"", r: "\\\"" },
1317			{ c: "'", r: "\\'" },
1318			{ c: "<", r: "\\x3C" },
1319			{ c: ">", r: "\\x3E" },
1320			{ c: "\\u2028", r: "\\u2028" },
1321			{ c: "\\u2029", r: "\\u2029" }
1322		];
1323		for (var i = 0; i < escapes.length; i++)
1324			str = str.replace(new RegExp(escapes[i].c, 'g'), escapes[i].r);
1325		return str;
1326	},
1327
1328	str_pad: function(input, pad_length, pad_string, pad_type)
1329	{
1330		pad_string = pad_string || ' ';
1331		pad_type = pad_type || 'right';
1332		input = input.toString();
1333
1334		if (pad_type == 'left')
1335			return BX.util.str_pad_left(input, pad_length, pad_string);
1336		else
1337			return BX.util.str_pad_right(input, pad_length, pad_string);
1338
1339	},
1340
1341	str_pad_left: function(input, pad_length, pad_string)
1342	{
1343		var i = input.length, q=pad_string.length;
1344		if (i >= pad_length) return input;
1345
1346		for(;i<pad_length;i+=q)
1347			input = pad_string + input;
1348
1349		return input;
1350	},
1351
1352	str_pad_right: function(input, pad_length, pad_string)
1353	{
1354		var i = input.length, q=pad_string.length;
1355		if (i >= pad_length) return input;
1356
1357		for(;i<pad_length;i+=q)
1358			input += pad_string;
1359
1360		return input;
1361	},
1362
1363	popup: function(url, width, height)
1364	{
1365		var w, h;
1366		if(BX.browser.IsOpera())
1367		{
1368			w = document.body.offsetWidth;
1369			h = document.body.offsetHeight;
1370		}
1371		else
1372		{
1373			w = screen.width;
1374			h = screen.height;
1375		}
1376		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));
1377	},
1378
1379
1380	// BX.util.objectSort(object, sortBy, sortDir) - Sort object by property
1381	// function params: 1 - object for sort, 2 - sort by property, 3 - sort direction (asc/desc)
1382	// return: sort array [[objectElement], [objectElement]] in sortDir direction
1383
1384	// example: BX.util.objectSortBy({'L1': {'name': 'Last'}, 'F1': {'name': 'First'}}, 'name', 'asc');
1385	// return: [{'name' : 'First'}, {'name' : 'Last'}]
1386	objectSort: function(object, sortBy, sortDir)
1387	{
1388		sortDir = sortDir == 'asc'? 'asc': 'desc';
1389
1390		var arItems = Array();
1391		for (var i in object)
1392			if (object[i][sortBy])
1393				arItems.push([i, object[i][sortBy]]);
1394
1395		if (sortDir == 'asc')
1396		{
1397			arItems.sort(function(i, ii) {
1398				if (!isNaN(i[1]) && !isNaN(ii[1]))
1399				{
1400					var s1 = parseInt(i[1]); var s2 = parseInt(ii[1]);
1401				}
1402				else
1403				{
1404					var s1 = i[1].toString().toLowerCase(); var s2 = ii[1].toString().toLowerCase();
1405				}
1406				if (s1 > s2) return 1; else if (s1 < s2) return -1; else return 0;
1407			});
1408		}
1409		else
1410		{
1411			arItems.sort(function(i, ii) {
1412				if (!isNaN(i[1]) && !isNaN(ii[1]))
1413				{
1414					var s1 = parseInt(i[1]);
1415					var s2 = parseInt(ii[1]);
1416				}
1417				else
1418				{
1419					var s1 = i[1].toString().toLowerCase();
1420					var s2 = ii[1].toString().toLowerCase();
1421				}
1422				if (s1 < s2) return 1; else if (s1 > s2) return -1; else return 0;
1423			});
1424		}
1425
1426		var arReturnArray = Array();
1427		for (var i = 0; i < arItems.length; i++)
1428			arReturnArray.push(object[arItems[i][0]]);
1429
1430		return arReturnArray;
1431	},
1432
1433	// #fdf9e5 => {r=253, g=249, b=229}
1434	hex2rgb: function(color)
1435	{
1436		var rgb = color.replace(/[# ]/g,"").replace(/^(.)(.)(.)$/,'$1$1$2$2$3$3').match(/.{2}/g);
1437		for (var i=0;  i<3; i++)
1438		{
1439			rgb[i] = parseInt(rgb[i], 16);
1440		}
1441		return {'r':rgb[0],'g':rgb[1],'b':rgb[2]};
1442	}
1443}
1444
1445BX.type = {
1446	isString: function(item) {
1447		return item === '' ? true : (item ? (typeof (item) == "string" || item instanceof String) : false);
1448	},
1449	isNotEmptyString: function(item) {
1450		return BX.type.isString(item) ? item.length > 0 : false;
1451	},
1452	isBoolean: function(item) {
1453		return item === false || item === false;
1454	},
1455	isNumber: function(item) {
1456		return item === 0 ? true : (item ? (typeof (item) == "number" || item instanceof Number) : false);
1457	},
1458	isFunction: function(item) {
1459		return item === null ? false : (typeof (item) == "function" || item instanceof Function);
1460	},
1461	isElementNode: function(item) {
1462		return item && typeof (item) == "object" && "nodeType" in item && item.nodeType == 1; //document.body.ELEMENT_NODE;
1463	},
1464	isDomNode: function(item) {
1465		return item && typeof (item) == "object" && "nodeType" in item;
1466	},
1467	isArray: function(item) {
1468		return item && Object.prototype.toString.call(item) == "[object Array]";
1469	},
1470	isDate : function(item) {
1471		return item && Object.prototype.toString.call(item) == "[object Date]";
1472	}
1473}
1474
1475BX.isNodeInDom = function(node)
1476{
1477	return node === document ? true :
1478		(node.parentNode ? BX.isNodeInDom(node.parentNode) : false);
1479}
1480
1481BX.evalPack = function(code)
1482{
1483	while (code.length > 0)
1484	{
1485		var c = code.shift();
1486
1487		if (c.TYPE == 'SCRIPT_EXT' || c.TYPE == 'SCRIPT_SRC')
1488		{
1489			BX.loadScript(c.DATA, function() {BX.evalPack(code)});
1490		}
1491		else if (c.TYPE == 'SCRIPT')
1492			BX.evalGlobal(c.DATA);
1493	}
1494}
1495
1496BX.evalGlobal = function(data)
1497{
1498	if (data)
1499	{
1500		var head = document.getElementsByTagName("head")[0] || document.documentElement,
1501			script = document.createElement("script");
1502
1503		script.type = "text/javascript";
1504
1505		if (!BX.browser.IsIE())
1506		{
1507			script.appendChild(document.createTextNode(data));
1508		}
1509		else
1510		{
1511			script.text = data;
1512		}
1513
1514		head.insertBefore(script, head.firstChild);
1515		head.removeChild(script);
1516	}
1517}
1518
1519BX.processHTML = function(HTML, scriptsRunFirst)
1520{
1521	var matchScript, scripts = [], data = HTML;
1522
1523	while ((matchScript = data.match(r.script)) !== null)
1524	{
1525		var end = data.search('<\/script>', 'i');
1526		if (end == -1)
1527			break;
1528
1529		var bRunFirst = scriptsRunFirst || (matchScript[1].indexOf('bxrunfirst') != '-1');
1530
1531		var matchSrc;
1532		if ((matchSrc = matchScript[1].match(r.script_src)) !== null)
1533			scripts.push({"bRunFirst": bRunFirst, "isInternal": false, "JS": matchSrc[1]});
1534		else
1535		{
1536			var start = matchScript.index + matchScript[0].length;
1537			var js = data.substr(start, end-start);
1538
1539			scripts.push({"bRunFirst": bRunFirst, "isInternal": true, "JS": js});
1540		}
1541
1542		data = data.substr(0, matchScript.index) + data.substr(end+9);
1543	}
1544
1545	var res = {'HTML': data, 'SCRIPT': scripts, 'STYLE': []};
1546
1547	if (BX.browser.IsIE()/* && !BX.browser.IsIE9()*/)
1548	{
1549		while ((matchStyle = data.match(r.style)) !== null)
1550		{
1551			var matchHref;
1552			if ((matchHref = matchStyle[0].match(r.style_href)) !== null)
1553			{
1554				res.STYLE.push(matchHref[1]);
1555			}
1556			data = data.replace(matchStyle[0], '');
1557		}
1558	}
1559
1560	return res;
1561}
1562
1563BX.garbage = function(call, thisObject)
1564{
1565	garbageCollectors.push({callback: call, context: thisObject});
1566}
1567
1568/* window pos functions */
1569
1570BX.GetDocElement = function (pDoc)
1571{
1572	pDoc = pDoc || document;
1573	return (BX.browser.IsDoctype(pDoc) ? pDoc.documentElement : pDoc.body);
1574}
1575
1576BX.GetContext = function(node)
1577{
1578	if (BX.type.isElementNode(node))
1579		return node.ownerDocument.parentWindow || node.ownerDocument.defaultView || window;
1580	else if (BX.type.isDomNode(node))
1581		return node.parentWindow || node.defaultView || window;
1582	else
1583		return window;
1584}
1585
1586BX.GetWindowInnerSize = function(pDoc)
1587{
1588	var width, height;
1589
1590	pDoc = pDoc || document;
1591
1592	if (self.innerHeight) // all except Explorer
1593	{
1594		width = BX.GetContext(pDoc).innerWidth;
1595		height = BX.GetContext(pDoc).innerHeight;
1596	}
1597	else if (pDoc.documentElement && (pDoc.documentElement.clientHeight || pDoc.documentElement.clientWidth)) // Explorer 6 Strict Mode
1598	{
1599		width = pDoc.documentElement.clientWidth;
1600		height = pDoc.documentElement.clientHeight;
1601	}
1602	else if (pDoc.body) // other Explorers
1603	{
1604		width = pDoc.body.clientWidth;
1605		height = pDoc.body.clientHeight;
1606	}
1607	return {innerWidth : width, innerHeight : height};
1608}
1609
1610BX.GetWindowScrollPos = function(pDoc)
1611{
1612	var left, top;
1613
1614	pDoc = pDoc || document;
1615
1616	if (self.pageYOffset) // all except Explorer
1617	{
1618		left = BX.GetContext(pDoc).pageXOffset;
1619		top = BX.GetContext(pDoc).pageYOffset;
1620	}
1621	else if (pDoc.documentElement && (pDoc.documentElement.scrollTop || pDoc.documentElement.scrollLeft)) // Explorer 6 Strict
1622	{
1623		left = pDoc.documentElement.scrollLeft;
1624		top = pDoc.documentElement.scrollTop;
1625	}
1626	else if (pDoc.body) // all other Explorers
1627	{
1628		left = pDoc.body.scrollLeft;
1629		top = pDoc.body.scrollTop;
1630	}
1631	return {scrollLeft : left, scrollTop : top};
1632}
1633
1634BX.GetWindowScrollSize = function(pDoc)
1635{
1636	var width, height;
1637	if (!pDoc)
1638		pDoc = document;
1639
1640	if ( (pDoc.compatMode && pDoc.compatMode == "CSS1Compat"))
1641	{
1642		width = pDoc.documentElement.scrollWidth;
1643		height = pDoc.documentElement.scrollHeight;
1644	}
1645	else
1646	{
1647		if (pDoc.body.scrollHeight > pDoc.body.offsetHeight)
1648			height = pDoc.body.scrollHeight;
1649		else
1650			height = pDoc.body.offsetHeight;
1651
1652		if (pDoc.body.scrollWidth > pDoc.body.offsetWidth ||
1653			(pDoc.compatMode && pDoc.compatMode == "BackCompat") ||
1654			(pDoc.documentElement && !pDoc.documentElement.clientWidth)
1655		)
1656			width = pDoc.body.scrollWidth;
1657		else
1658			width = pDoc.body.offsetWidth;
1659	}
1660	return {scrollWidth : width, scrollHeight : height};
1661}
1662
1663BX.GetWindowSize = function(pDoc)
1664{
1665	var innerSize = this.GetWindowInnerSize(pDoc);
1666	var scrollPos = this.GetWindowScrollPos(pDoc);
1667	var scrollSize = this.GetWindowScrollSize(pDoc);
1668
1669	return  {
1670		innerWidth : innerSize.innerWidth, innerHeight : innerSize.innerHeight,
1671		scrollLeft : scrollPos.scrollLeft, scrollTop : scrollPos.scrollTop,
1672		scrollWidth : scrollSize.scrollWidth, scrollHeight : scrollSize.scrollHeight
1673	};
1674}
1675
1676BX.hide_object = function(ob)
1677{
1678	ob = BX(ob);
1679	ob.style.position = 'absolute';
1680	ob.style.top = '-1000px';
1681	ob.style.left = '-1000px';
1682	ob.style.height = '10px';
1683	ob.style.width = '10px';
1684};
1685
1686BX.is_relative = function(el)
1687{
1688	var p = BX.style(el, 'position');
1689	return p == 'relative' || p == 'absolute';
1690}
1691
1692BX.is_float = function(el)
1693{
1694	var p = BX.style(el, 'float');
1695	return p == 'right' || p == 'left';
1696}
1697
1698BX.pos = function(el, bRelative)
1699{
1700	var r = { top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 };
1701	bRelative = !!bRelative;
1702	if (!el)
1703		return r;
1704	if (typeof (el.getBoundingClientRect) != "undefined" && el.ownerDocument == document && !bRelative)
1705	{
1706		var clientRect = el.getBoundingClientRect();
1707		var root = document.documentElement;
1708		var body = document.body;
1709
1710		r.top = clientRect.top + root.scrollTop + body.scrollTop;
1711		r.left = clientRect.left + root.scrollLeft + body.scrollLeft;
1712		r.width = clientRect.right - clientRect.left;
1713		r.height = clientRect.bottom - clientRect.top;
1714		r.right = clientRect.right + root.scrollLeft + body.scrollLeft;
1715		r.bottom = clientRect.bottom + root.scrollTop + body.scrollTop;
1716	}
1717	else
1718	{
1719		var x = 0, y = 0, w = el.offsetWidth, h = el.offsetHeight;
1720		var first = true;
1721		for (; el != null; el = el.offsetParent)
1722		{
1723			if (!first && bRelative && BX.is_relative(el))
1724				break;
1725
1726			x += el.offsetLeft;
1727			y += el.offsetTop;
1728			if (first)
1729			{
1730				first = false;
1731				continue;
1732			}
1733
1734			var elBorderLeftWidth = parseInt(BX.style(el, 'border-left-width')),
1735				elBorderTopWidth = parseInt(BX.style(el, 'border-top-width'));
1736
1737			if (!isNaN(elBorderLeftWidth) && elBorderLeftWidth > 0)
1738				x += elBorderLeftWidth;
1739			if (!isNaN(elBorderTopWidth) && elBorderTopWidth > 0)
1740				y += elBorderTopWidth;
1741		}
1742
1743		r.top = y;
1744		r.left = x;
1745		r.width = w;
1746		r.height = h;
1747		r.right = r.left + w;
1748		r.bottom = r.top + h;
1749	}
1750
1751	for (var i in r) r[i] = parseInt(r[i]);
1752
1753	return r;
1754}
1755
1756
1757BX.align = function(pos, w, h, type)
1758{
1759	if (type)
1760		type = type.toLowerCase();
1761	else
1762		type = '';
1763
1764	var pDoc = document;
1765	if (BX.type.isElementNode(pos))
1766	{
1767		pDoc = pos.ownerDocument;
1768		pos = BX.pos(pos);
1769	}
1770
1771	var x = pos["left"], y = pos["bottom"];
1772
1773	var scroll = BX.GetWindowScrollPos(pDoc);
1774	var size = BX.GetWindowInnerSize(pDoc);
1775
1776	if((size.innerWidth + scroll.scrollLeft) - (pos["left"] + w) < 0)
1777	{
1778		if(pos["right"] - w >= 0 )
1779			x = pos["right"] - w;
1780		else
1781			x = scroll.scrollLeft;
1782	}
1783
1784	if(((size.innerHeight + scroll.scrollTop) - (pos["bottom"] + h) < 0) || ~type.indexOf('top'))
1785	{
1786		if(pos["top"] - h >= 0 || ~type.indexOf('top'))
1787			y = pos["top"] - h;
1788		else
1789			y = scroll.scrollTop;
1790	}
1791
1792	return {'left':x, 'top':y};
1793}
1794
1795BX.scrollToNode = function(node)
1796{
1797	var obNode = BX(node);
1798
1799	if (obNode.scrollIntoView)
1800		obNode.scrollIntoView(true);
1801	else
1802	{
1803		var arNodePos = BX.pos(obNode);
1804		window.scrollTo(arNodePos.left, arNodePos.top);
1805	}
1806}
1807
1808/* non-xhr loadings */
1809BX.showWait = function(node, msg)
1810{
1811	node = BX(node) || document.body || document.documentElement;
1812	msg = msg || BX.message('JS_CORE_LOADING');
1813
1814	var container_id = node.id || Math.random();
1815
1816	var obMsg = node.bxmsg = document.body.appendChild(BX.create('DIV', {
1817		props: {
1818			id: 'wait_' + container_id,
1819			className: 'bx-core-waitwindow'
1820		},
1821		text: msg
1822	}));
1823
1824	setTimeout(BX.delegate(_adjustWait, node), 10);
1825
1826	lastWait[lastWait.length] = obMsg;
1827	return obMsg;
1828}
1829
1830BX.closeWait = function(node, obMsg)
1831{
1832	obMsg = obMsg || node && (node.bxmsg || BX('wait_' + node.id)) || lastWait.pop();
1833	if (obMsg && obMsg.parentNode)
1834	{
1835		for (var i=0,len=lastWait.length;i<len;i++)
1836		{
1837			if (obMsg == lastWait[i])
1838			{
1839				lastWait = BX.util.deleteFromArray(lastWait, i);
1840				break;
1841			}
1842		}
1843
1844		obMsg.parentNode.removeChild(obMsg);
1845		if (node) node.bxmsg = null;
1846		BX.cleanNode(obMsg, true);
1847	}
1848}
1849
1850BX.loadScript = function(script, callback, doc)
1851{
1852	if (!BX.isReady)
1853	{
1854		var _args = arguments;
1855		BX.ready(function() {
1856			BX.loadScript.apply(this, _args);
1857		});
1858		return;
1859	}
1860
1861	doc = doc || document;
1862
1863	if (BX.type.isString(script))
1864		script = [script];
1865	var _callback = function()
1866	{
1867		return (callback && BX.type.isFunction(callback)) ? callback() : null
1868	}
1869	var load_js = function(ind)
1870	{
1871		if (ind >= script.length)
1872			return _callback();
1873
1874		var oHead = doc.getElementsByTagName("head")[0] || doc.documentElement;
1875		var oScript = doc.createElement('script');
1876		oScript.src = script[ind];
1877
1878		var bLoaded = false;
1879		oScript.onload = oScript.onreadystatechange = function()
1880		{
1881			if (!bLoaded && (!oScript.readyState || oScript.readyState == "loaded" || oScript.readyState == "complete"))
1882			{
1883				bLoaded = true;
1884				setTimeout(function (){load_js(++ind);}, 50);
1885
1886				oScript.onload = oScript.onreadystatechange = null;
1887				if (oHead && oScript.parentNode)
1888				{
1889					oHead.removeChild(oScript);
1890				}
1891			}
1892		}
1893
1894		return oHead.insertBefore(oScript, oHead.firstChild);
1895	}
1896
1897	load_js(0);
1898}
1899
1900BX.loadCSS = function(arCSS, doc, win)
1901{
1902	if (!BX.isReady)
1903	{
1904		var _args = arguments;
1905		BX.ready(function() {
1906			BX.loadCSS.apply(this, _args);
1907		});
1908		return null;
1909	}
1910
1911	if (BX.type.isString(arCSS))
1912	{
1913		var bSingle = true;
1914		arCSS = [arCSS];
1915	}
1916	var i, l = arCSS.length, pLnk = [];
1917
1918	if (l == 0)
1919		return null;
1920
1921	doc = doc || document;
1922	win = win ||window;
1923
1924	if (!win.bxhead)
1925	{
1926		var heads = doc.getElementsByTagName('HEAD');
1927		win.bxhead = heads[0];
1928	}
1929
1930	if (!win.bxhead)
1931		return null;
1932
1933	for (i = 0; i < l; i++)
1934	{
1935		var lnk = document.createElement('LINK');
1936		lnk.href = arCSS[i];
1937		lnk.rel = 'stylesheet';
1938		lnk.type = 'text/css';
1939		win.bxhead.appendChild(lnk);
1940		pLnk.push(lnk);
1941	}
1942
1943	if (bSingle)
1944		return lnk;
1945
1946	return pLnk;
1947}
1948
1949BX.reload = function(back_url, bAddClearCache)
1950{
1951	if (back_url === true)
1952	{
1953		bAddClearCache = true;
1954		back_url = null;
1955	}
1956
1957	var new_href = back_url || top.location.href;
1958
1959	var hashpos = new_href.indexOf('#'), hash = '';
1960
1961	if (hashpos != -1)
1962	{
1963		hash = new_href.substr(hashpos);
1964		new_href = new_href.substr(0, hashpos);
1965	}
1966
1967	if (bAddClearCache && new_href.indexOf('clear_cache=Y') < 0)
1968		new_href += (new_href.indexOf('?') == -1 ? '?' : '&') + 'clear_cache=Y';
1969
1970	if (hash)
1971	{
1972		// hack for clearing cache in ajax mode components with history emulation
1973		if (bAddClearCache && (hash.substr(0, 5) == 'view/' || hash.substr(0, 6) == '#view/') && hash.indexOf('clear_cache%3DY') < 0)
1974			hash += (hash.indexOf('%3F') == -1 ? '%3F' : '%26') + 'clear_cache%3DY'
1975
1976		new_href = new_href.replace(/(\?|\&)_r=[\d]*/, '');
1977		new_href += (new_href.indexOf('?') == -1 ? '?' : '&') + '_r='+Math.round(Math.random()*10000) + hash;
1978	}
1979
1980	top.location.href = new_href;
1981}
1982
1983BX.clearCache = function()
1984{
1985	BX.showWait();
1986	BX.reload(true);
1987}
1988
1989BX.template = function(tpl, callback, bKillTpl)
1990{
1991	BX.ready(function() {
1992		_processTpl(BX(tpl), callback, bKillTpl);
1993	});
1994}
1995
1996BX.formatDate = function(date, format)
1997{
1998	date = date || new Date();
1999
2000	var bTime = date.getHours() || date.getMinutes() || date.getSeconds(),
2001		str = !!format
2002			? format :
2003			(bTime ? BX.message('FORMAT_DATETIME') : BX.message('FORMAT_DATE')
2004		);
2005
2006	return str.replace(/YYYY/ig, date.getFullYear())
2007		.replace(/MM/ig, BX.util.str_pad_left((date.getMonth()+1).toString(), 2, '0'))
2008		.replace(/DD/ig, BX.util.str_pad_left(date.getDate().toString(), 2, '0'))
2009		.replace(/HH/ig, BX.util.str_pad_left(date.getHours().toString(), 2, '0'))
2010		.replace(/MI/ig, BX.util.str_pad_left(date.getMinutes().toString(), 2, '0'))
2011		.replace(/SS/ig, BX.util.str_pad_left(date.getSeconds().toString(), 2, '0'));
2012}
2013
2014BX.parseDate = function(str)
2015{
2016	var aDate = str.split(/\D/ig);
2017	var aFormat = BX.message('FORMAT_DATE').split(/\W/ig);
2018	if(aDate.length > aFormat.length)
2019		aFormat = BX.message('FORMAT_DATETIME').split(/\W/ig);
2020
2021	var i, cnt;
2022	var aDateArgs=[], aFormatArgs=[];
2023	for(i = 0, cnt = aDate.length; i < cnt; i++)
2024		if(BX.util.trim(aDate[i]) != '')
2025			aDateArgs[aDateArgs.length] = aDate[i];
2026	for(i = 0, cnt = aFormat.length; i < cnt; i++)
2027		if(BX.util.trim(aFormat[i]) != '')
2028			aFormatArgs[aFormatArgs.length] = aFormat[i];
2029
2030	var aResult={};
2031	for(i = 0, cnt = aFormatArgs.length; i < cnt; i++)
2032		aResult[aFormatArgs[i].toUpperCase()] = parseInt(aDateArgs[i], 10);
2033
2034	if(aResult['DD'] > 0 && aResult['MM'] > 0 && aResult['YYYY'] > 0)
2035	{
2036		var d = new Date();
2037		d.setDate(1);
2038		d.setFullYear(aResult['YYYY']);
2039		d.setMonth(aResult['MM']-1);
2040		d.setDate(aResult['DD']);
2041		d.setHours(0, 0, 0);
2042		if(!isNaN(aResult['HH']) && !isNaN(aResult['MI']) && !isNaN(aResult['SS']))
2043		{
2044			d.setHours(aResult['HH'], aResult['MI'], aResult['SS']);
2045		}
2046		return d;
2047	}
2048	return null;
2049}
2050
2051/******* HINT ***************/
2052// if function has 2 params - the 2nd one is hint html. otherwise hint_html is third and hint_title - 2nd;
2053// '<div onmouseover="BX.hint(this, 'This is &lt;b&gt;Hint&lt;/b&gt;')"'>;
2054// BX.hint(el, 'This is <b>Hint</b>') - this won't work, use constructor
2055BX.hint = function(el, hint_title, hint_html, hint_id)
2056{
2057	if (null == hint_html)
2058	{
2059		hint_html = hint_title;
2060		hint_title = '';
2061	}
2062
2063	if (null == el.BXHINT)
2064	{
2065		el.BXHINT = new BX.CHint({
2066			parent: el, hint: hint_html, title: hint_title, id: hint_id
2067		});
2068		el.BXHINT.Show();
2069	}
2070}
2071
2072BX.hint_replace = function(el, hint_title, hint_html)
2073{
2074	if (null == hint_html)
2075	{
2076		hint_html = hint_title;
2077		hint_title = '';
2078	}
2079
2080	if (!el || !el.parentNode || !hint_html)
2081			return null;
2082
2083	var obHint = new BX.CHint({
2084		hint: hint_html,
2085		title: hint_title
2086	});
2087
2088	obHint.CreateParent();
2089
2090	el.parentNode.insertBefore(obHint.PARENT, el);
2091	el.parentNode.removeChild(el);
2092
2093	obHint.PARENT.style.marginLeft = '5px';
2094
2095	return el;
2096}
2097
2098BX.CHint = function(params)
2099{
2100	this.PARENT = BX(params.parent);
2101
2102	this.HINT = params.hint;
2103	this.HINT_TITLE = params.title;
2104
2105	this.PARAMS = {}
2106	for (var i in this.defaultSettings)
2107	{
2108		if (null == params[i])
2109			this.PARAMS[i] = this.defaultSettings[i];
2110		else
2111			this.PARAMS[i] = params[i];
2112	}
2113
2114	if (null != params.id)
2115		this.ID = params.id;
2116
2117	this.timer = null;
2118	this.bInited = false;
2119	this.msover = true;
2120
2121	if (this.PARAMS.showOnce)
2122	{
2123		this.__show();
2124		this.msover = false;
2125		this.timer = setTimeout(BX.proxy(this.__hide, this), this.PARAMS.hide_timeout);
2126	}
2127	else if (this.PARENT)
2128	{
2129		BX.bind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
2130		BX.bind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
2131	}
2132
2133	BX.addCustomEvent('onMenuOpen', BX.delegate(this.disable, this));
2134	BX.addCustomEvent('onMenuClose', BX.delegate(this.enable, this));
2135}
2136
2137BX.CHint.prototype.defaultSettings = {
2138	show_timeout: 1000,
2139	hide_timeout: 500,
2140	dx: 2,
2141	showOnce: false,
2142	preventHide: true,
2143	min_width: 250
2144}
2145
2146BX.CHint.prototype.CreateParent = function(element, params)
2147{
2148	if (this.PARENT)
2149	{
2150		BX.unbind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
2151		BX.unbind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
2152	}
2153
2154	if (!params) params = {}
2155	var type = 'icon';
2156
2157	if (params.type && (params.type == "link" || params.type == "icon"))
2158		type = params.type;
2159
2160	if (element)
2161		type = "element";
2162
2163	if (type == "icon")
2164	{
2165		element = BX.create('IMG', {
2166			props: {
2167				src: params.iconSrc
2168					? params.iconSrc
2169					: "/bitrix/js/main/core/images/hint.gif"
2170			}
2171		});
2172	}
2173	else if (type == "link")
2174	{
2175		element = BX.create("A", {
2176			props: {href: 'javascript:void(0)'},
2177			html: '[?]'
2178		});
2179	}
2180
2181	this.PARENT = element;
2182
2183	BX.bind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
2184	BX.bind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
2185
2186	return this.PARENT;
2187}
2188
2189BX.CHint.prototype.Show = function()
2190{
2191	this.msover = true;
2192
2193	if (null != this.timer)
2194		clearTimeout(this.timer);
2195
2196	this.timer = setTimeout(BX.proxy(this.__show, this), this.PARAMS.show_timeout);
2197}
2198
2199BX.CHint.prototype.Hide = function()
2200{
2201	this.msover = false;
2202
2203	if (null != this.timer)
2204		clearTimeout(this.timer);
2205
2206	this.timer = setTimeout(BX.proxy(this.__hide, this), this.PARAMS.hide_timeout);
2207}
2208
2209BX.CHint.prototype.__show = function()
2210{
2211	if (!this.msover || this.disabled) return;
2212	if (!this.bInited) this.Init();
2213
2214	if (this.prepareAdjustPos())
2215	{
2216		this.DIV.style.display = 'block';
2217		this.adjustPos();
2218
2219		BX.bind(window, 'scroll', BX.proxy(this.__onscroll, this));
2220
2221		if (this.PARAMS.showOnce)
2222		{
2223			this.timer = setTimeout(BX.proxy(this.__hide, this), this.PARAMS.hide_timeout);
2224		}
2225	}
2226}
2227
2228BX.CHint.prototype.__onscroll = function()
2229{
2230	if (!BX.admin || !BX.admin.panel || !BX.admin.panel.isFixed()) return;
2231
2232	if (this.scrollTimer) clearTimeout(this.scrollTimer);
2233
2234	this.DIV.style.display = 'none';
2235	this.scrollTimer = setTimeout(BX.proxy(this.Reopen, this), this.PARAMS.show_timeout);
2236}
2237
2238BX.CHint.prototype.Reopen = function()
2239{
2240	if (null != this.timer) clearTimeout(this.timer);
2241	this.timer = setTimeout(BX.proxy(this.__show, this), 50);
2242}
2243
2244BX.CHint.prototype.__hide = function()
2245{
2246	if (this.msover) return;
2247	if (!this.bInited) return;
2248
2249	BX.unbind(window, 'scroll', BX.proxy(this.Reopen, this));
2250
2251	if (this.PARAMS.showOnce)
2252	{
2253		this.Destroy();
2254	}
2255	else
2256	{
2257		this.DIV.style.display = 'none';
2258	}
2259}
2260
2261BX.CHint.prototype.__hide_immediately = function()
2262{
2263	this.msover = false;
2264	this.__hide();
2265}
2266
2267BX.CHint.prototype.Init = function()
2268{
2269	this.DIV = document.body.appendChild(BX.create('DIV', {
2270		props: {className: 'bx-panel-tooltip'},
2271		style: {display: 'none'},
2272		children: [
2273			BX.create('DIV', {
2274				props: {className: 'bx-panel-tooltip-top-border'},
2275				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>'
2276			}),
2277			(this.CONTENT = BX.create('DIV', {
2278				props: {className: 'bx-panel-tooltip-content'},
2279				children: [
2280					BX.create('DIV', {
2281						props: {className: 'bx-panel-tooltip-underlay'},
2282						children: [
2283							BX.create('DIV', {props: {className: 'bx-panel-tooltip-underlay-bg'}})
2284						]
2285					})
2286				]
2287			})),
2288
2289			BX.create('DIV', {
2290				props: {className: 'bx-panel-tooltip-bottom-border'},
2291				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>'
2292			})
2293		]
2294	}));
2295
2296	if (this.ID)
2297	{
2298		this.CONTENT.insertBefore(BX.create('A', {
2299			attrs: {href: 'javascript:void(0)'},
2300			props: {className: 'bx-panel-tooltip-close'},
2301			events: {click: BX.delegate(this.Close, this)}
2302		}), this.CONTENT.firstChild)
2303	}
2304
2305	if (this.HINT_TITLE)
2306	{
2307		this.CONTENT.appendChild(
2308			BX.create('DIV', {
2309				props: {className: 'bx-panel-tooltip-title'},
2310				text: this.HINT_TITLE
2311			})
2312		)
2313	}
2314
2315	if (this.HINT)
2316	{
2317		this.CONTENT_TEXT = this.CONTENT.appendChild(BX.create('DIV', {props: {className: 'bx-panel-tooltip-text'}})).appendChild(BX.create('SPAN', {html: this.HINT}));
2318	}
2319
2320	if (this.PARAMS.preventHide)
2321	{
2322		BX.bind(this.DIV, 'mouseout', BX.proxy(this.Hide, this));
2323		BX.bind(this.DIV, 'mouseover', BX.proxy(this.Show, this));
2324	}
2325
2326	this.bInited = true;
2327}
2328
2329BX.CHint.prototype.setContent = function(content)
2330{
2331	this.HINT = content;
2332
2333	if (this.CONTENT_TEXT)
2334		this.CONTENT_TEXT.innerHTML = this.HINT;
2335	else
2336		this.CONTENT_TEXT = this.CONTENT.appendChild(BX.create('DIV', {props: {className: 'bx-panel-tooltip-text'}})).appendChild(BX.create('SPAN', {html: this.HINT}));
2337}
2338
2339BX.CHint.prototype.prepareAdjustPos = function()
2340{
2341	this._wnd = {scrollPos: BX.GetWindowScrollPos(),scrollSize:BX.GetWindowScrollSize()};
2342	return BX.style(this.PARENT, 'display') != 'none';
2343}
2344
2345BX.CHint.prototype.getAdjustPos = function()
2346{
2347	var res = {}, pos = BX.pos(this.PARENT);
2348
2349	res.top = pos.bottom + this.PARAMS.dx;
2350
2351	if (BX.admin && BX.admin.panel.DIV)
2352	{
2353		var min_top = BX.admin.panel.DIV.offsetHeight + this.PARAMS.dx;
2354
2355		if (BX.admin.panel.isFixed())
2356		{
2357			min_top += this._wnd.scrollPos.scrollTop;
2358		}
2359	}
2360
2361	if (res.top < min_top)
2362		res.top = min_top;
2363	else
2364	{
2365		if (res.top + this.DIV.offsetHeight > this._wnd.scrollSize.scrollHeight)
2366			res.top = pos.top - this.PARAMS.dx - this.DIV.offsetHeight;
2367	}
2368
2369	res.left = pos.left;
2370	if (pos.left < this.PARAMS.dx) pos.left = this.PARAMS.dx;
2371	else
2372	{
2373		floatWidth = this.DIV.offsetWidth;
2374
2375		var max_left = this._wnd.scrollSize.scrollWidth - floatWidth - this.PARAMS.dx;
2376
2377		if (res.left > max_left)
2378			res.left = max_left;
2379	}
2380
2381	return res;
2382}
2383
2384BX.CHint.prototype.adjustWidth = function()
2385{
2386	if (this.bWidthAdjusted) return;
2387
2388	var w = this.DIV.offsetWidth, h = this.DIV.offsetHeight;
2389
2390	if (w > this.PARAMS.min_width)
2391		w = Math.round(Math.sqrt(1.618*w*h));
2392
2393	if (w < this.PARAMS.min_width)
2394		w = this.PARAMS.min_width;
2395
2396	this.DIV.style.width = w + "px";
2397
2398	if (this._adjustWidthInt)
2399		clearInterval(this._adjustWidthInt);
2400	this._adjustWidthInt = setInterval(BX.delegate(this._adjustWidthInterval, this), 5);
2401
2402	this.bWidthAdjusted = true;
2403}
2404
2405BX.CHint.prototype._adjustWidthInterval = function()
2406{
2407	if (!this.DIV || this.DIV.style.display == 'none')
2408		clearInterval(this._adjustWidthInt);
2409
2410	var
2411		dW = 20,
2412		maxWidth = 1500,
2413		w = this.DIV.offsetWidth,
2414		w1 = this.CONTENT_TEXT.offsetWidth;
2415
2416	if (w > 0 && w1 > 0 && w - w1 < dW && w < maxWidth)
2417	{
2418		this.DIV.style.width = (w + dW) + "px";
2419		return;
2420	}
2421
2422	clearInterval(this._adjustWidthInt);
2423}
2424
2425BX.CHint.prototype.adjustPos = function()
2426{
2427	this.adjustWidth();
2428
2429	var pos = this.getAdjustPos();
2430
2431	this.DIV.style.top = pos.top + 'px';
2432	this.DIV.style.left = pos.left + 'px';
2433}
2434
2435BX.CHint.prototype.Close = function()
2436{
2437	if (this.ID && BX.WindowManager)
2438		BX.WindowManager.saveWindowOptions(this.ID, {display: 'off'});
2439	this.__hide_immediately();
2440	this.Destroy();
2441}
2442
2443BX.CHint.prototype.Destroy = function()
2444{
2445	if (this.PARENT)
2446	{
2447		BX.unbind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
2448		BX.unbind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
2449	}
2450
2451	if (this.DIV)
2452	{
2453		BX.unbind(this.DIV, 'mouseover', BX.proxy(this.Show, this));
2454		BX.unbind(this.DIV, 'mouseout', BX.proxy(this.Hide, this));
2455
2456		BX.cleanNode(this.DIV, true);
2457	}
2458}
2459
2460BX.CHint.prototype.enable = function(){this.disabled = false;}
2461BX.CHint.prototype.disable = function(){this.__hide_immediately(); this.disabled = true;}
2462
2463/* ready */
2464if (document.addEventListener)
2465{
2466	__readyHandler = function()
2467	{
2468		document.removeEventListener("DOMContentLoaded", __readyHandler, false);
2469		runReady();
2470	}
2471}
2472else if (document.attachEvent)
2473{
2474	__readyHandler = function()
2475	{
2476		if (document.readyState === "complete")
2477		{
2478			document.detachEvent("onreadystatechange", __readyHandler);
2479			runReady();
2480		}
2481	}
2482}
2483
2484function bindReady()
2485{
2486	if (!readyBound)
2487	{
2488		readyBound = true;
2489
2490		if (document.readyState === "complete")
2491		{
2492			return runReady();
2493		}
2494
2495		if (document.addEventListener)
2496		{
2497			document.addEventListener("DOMContentLoaded", __readyHandler, false);
2498			window.addEventListener("load", runReady, false);
2499		}
2500		else if (document.attachEvent) // IE
2501		{
2502			document.attachEvent("onreadystatechange", __readyHandler);
2503			window.attachEvent("onload", runReady);
2504
2505			var toplevel = false;
2506			try {toplevel = (window.frameElement == null);} catch(e) {}
2507
2508			if (document.documentElement.doScroll && toplevel)
2509				doScrollCheck();
2510		}
2511	}
2512
2513	return null;
2514}
2515
2516
2517function runReady()
2518{
2519	if (!BX.isReady)
2520	{
2521		if (!document.body)
2522			return setTimeout(runReady, 15);
2523
2524		BX.isReady = true;
2525
2526
2527		if (readyList && readyList.length > 0)
2528		{
2529			var fn, i = 0;
2530			while (readyList && (fn = readyList[i++]))
2531			{
2532				fn.call(document);
2533			}
2534
2535			readyList = null;
2536		}
2537		// TODO: check ready handlers binded some other way;
2538	}
2539	return null;
2540}
2541
2542// hack for IE
2543function doScrollCheck()
2544{
2545	if (BX.isReady)
2546		return;
2547
2548	try {document.documentElement.doScroll("left");} catch( error ) {setTimeout(doScrollCheck, 1); return;}
2549
2550	runReady();
2551}
2552/* \ready */
2553
2554function _adjustWait()
2555{
2556	if (!this.bxmsg) return;
2557
2558	var arContainerPos = BX.pos(this),
2559		div_top = arContainerPos.top;
2560
2561	if (div_top < BX.GetDocElement().scrollTop)
2562		div_top = BX.GetDocElement().scrollTop + 5;
2563
2564	this.bxmsg.style.top = (div_top + 5) + 'px';
2565
2566	if (this == BX.GetDocElement())
2567	{
2568		this.bxmsg.style.right = '5px';
2569	}
2570	else
2571	{
2572		this.bxmsg.style.left = (arContainerPos.right - this.bxmsg.offsetWidth - 5) + 'px';
2573	}
2574}
2575
2576function _checkDisplay(ob, displayType)
2577{
2578	if (typeof displayType != 'undefined')
2579		ob.BXDISPLAY = displayType;
2580
2581	var d = ob.style.display || BX.style(ob, 'display');
2582	if (d != 'none')
2583	{
2584		ob.BXDISPLAY = ob.BXDISPLAY || d;
2585		return true;
2586	}
2587	else
2588	{
2589		ob.BXDISPLAY = ob.BXDISPLAY || 'block';
2590		return false;
2591	}
2592}
2593
2594function _processTpl(tplNode, cb, bKillTpl)
2595{
2596	if (tplNode)
2597	{
2598		if (bKillTpl)
2599			tplNode.parentNode.removeChild(tplNode);
2600
2601		var res = {}, nodes = BX.findChildren(tplNode, {attribute: 'data-role'}, true);
2602
2603		for (var i = 0, l = nodes.length; i < l; i++)
2604		{
2605			res[nodes[i].getAttribute('data-role')] = nodes[i];
2606		}
2607
2608		cb.apply(tplNode, [res]);
2609	}
2610}
2611
2612function _checkNode(obj, params)
2613{
2614	params = params || {};
2615
2616	if (BX.type.isFunction(params))
2617		return params.call(window, obj);
2618
2619	if (!params.allowTextNodes && !BX.type.isElementNode(obj))
2620		return false;
2621	var i,j,len;
2622	for (i in params)
2623	{
2624		switch(i)
2625		{
2626			case 'tag':
2627			case 'tagName':
2628				if (BX.type.isString(params[i]))
2629				{
2630					if (obj.tagName.toUpperCase() != params[i].toUpperCase())
2631						return false;
2632				}
2633				else if (params[i] instanceof RegExp)
2634				{
2635					if (!params[i].test(obj.tagName))
2636						return false;
2637				}
2638			break;
2639
2640			case 'class':
2641			case 'className':
2642				if (BX.type.isString(params[i]))
2643				{
2644					if (!BX.hasClass(obj, params[i]))
2645						return false;
2646				}
2647				else if (params[i] instanceof RegExp)
2648				{
2649					if (!BX.type.isString(obj.className) || !params[i].test(obj.className))
2650						return false;
2651				}
2652			break;
2653
2654			case 'attr':
2655			case 'attribute':
2656				if (BX.type.isString(params[i]))
2657				{
2658					if (!obj.getAttribute(params[i]))
2659						return false;
2660				}
2661				else if (BX.type.isArray(params[i]))
2662				{
2663					for (j = 0, len = params[i].length; j < len; j++)
2664					{
2665						if (params[i] && !obj.getAttribute(params[i]))
2666							return false;
2667					}
2668				}
2669				else
2670				{
2671					for (j in params[i])
2672					{
2673						var q = obj.getAttribute(j);
2674						if (params[i][j] instanceof RegExp)
2675						{
2676							if (!BX.type.isString(q) || !params[i][j].test(q))
2677								return false;
2678						}
2679						else
2680						{
2681							if (q != '' + params[i][j])
2682								return false;
2683						}
2684					}
2685				}
2686			break;
2687
2688			case 'property':
2689				if (BX.type.isString(params[i]))
2690				{
2691					if (!obj[params[i]])
2692						return false;
2693				}
2694				else if (BX.type.isArray(params[i]))
2695				{
2696					for (j = 0, len = params[i].length; j < len; j++)
2697					{
2698						if (params[i] && !obj[params[i]])
2699							return false;
2700					}
2701				}
2702				else
2703				{
2704					for (j in params[i])
2705					{
2706						if (BX.type.isString(params[i][j]))
2707						{
2708							if (obj[j] != params[i][j])
2709								return false;
2710						}
2711						else if (params[i][j] instanceof RegExp)
2712						{
2713							if (!BX.type.isString(obj[j]) || !params[i][j].test(obj[j]))
2714								return false;
2715						}
2716					}
2717				}
2718			break;
2719
2720			case 'callback':
2721				return params[i](obj);
2722			break;
2723		}
2724	}
2725
2726	return true;
2727}
2728
2729/* garbage collector */
2730function Trash()
2731{
2732	var i,len;
2733
2734	for (i = 0, len = garbageCollectors.length; i<len; i++)
2735	{
2736		garbageCollectors[i].callback.apply(garbageCollectors[i].context || window);
2737
2738		try {
2739			delete garbageCollectors[i];
2740			garbageCollectors[i] = null;
2741		} catch (e) {}
2742	}
2743
2744	try {BX.unbindAll();} catch(e) {}
2745/*
2746	for (i = 0, len = proxyList.length; i < len; i++)
2747	{
2748		try {
2749			delete proxyList[i];
2750			proxyList[i] = null;
2751		} catch (e) {}
2752	}
2753*/
2754}
2755
2756if(window.attachEvent) // IE
2757	window.attachEvent("onunload", Trash);
2758else if(window.addEventListener) // Gecko / W3C
2759	window.addEventListener('unload', Trash, false);
2760else
2761	window.onunload = Trash;
2762/* \garbage collector */
2763
2764// set empty ready handler
2765BX(BX.DoNothing);
2766
2767window.BX = BX;
2768})(window)

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.