PageSourceSearch

https://labburo.ru/bitrix/cache/js/s1/alpha_s1/kernel_main/kernel_main_v1.js?1789733656288123

js labburo.ru collected 2026-10-06 11:20:40 UTC 288,123 bytes, 11,098 lines download raw bytes

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

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.