PageSourceSearch

https://www.fakt-group.ru/bitrix/cache/js/s1/gkfakt/kernel_main/kernel_main_v1.js?1780152584221838

js fakt-group.ru collected 2026-10-02 17:24:43 UTC 221,838 bytes, 8,852 lines download raw bytes

1; /* /bitrix/js/main/session.js?16404489843701*/
2; /* /bitrix/js/main/pageobject/pageobject.js?1608166115864*/
3; /* /bitrix/js/main/core/core_window.js?164085864698768*/
4; /* /bitrix/js/main/date/main.date.js?165838843434555*/
5; /* /bitrix/js/main/core/core_date.js?161472698336080*/
6; /* /bitrix/js/main/utils.js?161472698329279*/
7; /* /bitrix/js/main/core/core_fx.js?160816569716888*/
8
9; /* Start:"a:4:{s:4:"full";s:47:"/bitrix/js/main/core/core_fx.js?160816569716888";s:6:"source";s:31:"/bitrix/js/main/core/core_fx.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
10;(function(window){
11
12var defaultOptions = {
13	time: 1.0,
14	step: 0.05,
15	type: 'linear',
16
17	allowFloat: false
18}
19
20/*
21options: {
22	start: start value or {param: value, param: value}
23	finish: finish value or {param: value, param: value}
24	time: time to transform in seconds
25	type: linear|accelerated|decelerated|custom func name
26	callback,
27	callback_start,
28	callback_complete,
29
30	step: time between steps in seconds
31	allowFloat: false|true
32}
33*/
34BX.fx = function(options)
35{
36	this.options = options;
37
38	if (null != this.options.time)
39		this.options.originalTime = this.options.time;
40	if (null != this.options.step)
41		this.options.originalStep = this.options.step;
42
43	if (!this.__checkOptions())
44		return false;
45
46	this.__go = BX.delegate(this.go, this);
47
48	this.PARAMS = {};
49}
50
51BX.fx.prototype.__checkOptions = function()
52{
53	if (typeof this.options.start != typeof this.options.finish)
54		return false;
55
56	if (null == this.options.time) this.options.time = defaultOptions.time;
57	if (null == this.options.step) this.options.step = defaultOptions.step;
58	if (null == this.options.type) this.options.type = defaultOptions.type;
59	if (null == this.options.allowFloat) this.options.allowFloat = defaultOptions.allowFloat;
60
61	this.options.time *= 1000;
62	this.options.step *= 1000;
63
64	if (typeof this.options.start != 'object')
65	{
66		this.options.start = {_param: this.options.start};
67		this.options.finish = {_param: this.options.finish};
68	}
69
70	var i;
71	for (i in this.options.start)
72	{
73		if (null == this.options.finish[i])
74		{
75			this.options.start[i] = null;
76			delete this.options.start[i];
77		}
78	}
79
80	if (!BX.type.isFunction(this.options.type))
81	{
82		if (BX.type.isFunction(window[this.options.type]))
83			this.options.type = window[this.options.type];
84		else if (BX.type.isFunction(BX.fx.RULES[this.options.type]))
85			this.options.type = BX.fx.RULES[this.options.type];
86		else
87			this.options.type = BX.fx.RULES[defaultOptions.type];
88	}
89
90	return true;
91}
92
93BX.fx.prototype.go = function()
94{
95	var timeCurrent = new Date().valueOf();
96	if (timeCurrent < this.PARAMS.timeFinish)
97	{
98		for (var i in this.PARAMS.current)
99		{
100			this.PARAMS.current[i][0] = this.options.type.apply(this, [{
101				start_value: this.PARAMS.start[i][0],
102				finish_value: this.PARAMS.finish[i][0],
103				current_value: this.PARAMS.current[i][0],
104				current_time: timeCurrent - this.PARAMS.timeStart,
105				total_time: this.options.time
106			}]);
107		}
108
109		this._callback(this.options.callback);
110
111		if (!this.paused)
112			this.PARAMS.timer = setTimeout(this.__go, this.options.step);
113	}
114	else
115	{
116		this.stop();
117	}
118}
119
120BX.fx.prototype._callback = function(cb)
121{
122	var tmp = {};
123
124	cb = cb || this.options.callback;
125
126	for (var i in this.PARAMS.current)
127	{
128		tmp[i] = (this.options.allowFloat ? this.PARAMS.current[i][0] : Math.round(this.PARAMS.current[i][0])) + this.PARAMS.current[i][1];
129	}
130
131	return cb.apply(this, [null != tmp['_param'] ? tmp._param : tmp]);
132}
133
134BX.fx.prototype.start = function()
135{
136	var i,value, unit;
137
138	this.PARAMS.start = {};
139	this.PARAMS.current = {};
140	this.PARAMS.finish = {};
141
142	for (i in this.options.start)
143	{
144		value = +this.options.start[i];
145		unit = (this.options.start[i]+'').substring((value+'').length);
146		this.PARAMS.start[i] = [value, unit];
147		this.PARAMS.current[i] = [value, unit];
148		this.PARAMS.finish[i] = [+this.options.finish[i], unit];
149	}
150
151	this._callback(this.options.callback_start);
152	this._callback(this.options.callback);
153
154	this.PARAMS.timeStart = new Date().valueOf();
155	this.PARAMS.timeFinish = this.PARAMS.timeStart + this.options.time;
156	this.PARAMS.timer = setTimeout(BX.delegate(this.go, this), this.options.step);
157
158	return this;
159}
160
161BX.fx.prototype.pause = function()
162{
163	if (this.paused)
164	{
165		this.PARAMS.timer = setTimeout(this.__go, this.options.step);
166		this.paused = false;
167	}
168	else
169	{
170		clearTimeout(this.PARAMS.timer);
171		this.paused = true;
172	}
173}
174
175BX.fx.prototype.stop = function(silent)
176{
177	silent = !!silent;
178	if (this.PARAMS.timer)
179		clearTimeout(this.PARAMS.timer);
180
181	if (null != this.options.originalTime)
182		this.options.time = this.options.originalTime;
183	if (null != this.options.originalStep)
184		this.options.step = this.options.originalStep;
185
186	this.PARAMS.current = this.PARAMS.finish;
187	if (!silent) {
188		this._callback(this.options.callback);
189		this._callback(this.options.callback_complete);
190	}
191}
192
193/*
194type rules of animation
195 - linear - simple linear animation
196 - accelerated
197 - decelerated
198*/
199
200/*
201	params: {
202		start_value, finish_value, current_time, total_time
203	}
204*/
205BX.fx.RULES =
206{
207	linear: function(params)
208	{
209		return params.start_value + (params.current_time/params.total_time) * (params.finish_value - params.start_value);
210	},
211
212	decelerated: function(params)
213	{
214		return params.start_value + Math.sqrt(params.current_time/params.total_time) * (params.finish_value - params.start_value);
215	},
216
217	accelerated: function(params)
218	{
219		var q = params.current_time/params.total_time;
220		return params.start_value + q * q * (params.finish_value - params.start_value);
221	}
222}
223
224/****************** effects realizaion ************************/
225
226/*
227	type = 'fade' || 'scroll' || 'scale' || 'fold'
228*/
229
230BX.fx.hide = function(el, type, opts)
231{
232	el = BX(el);
233
234	if (typeof type == 'object' && null == opts)
235	{
236		opts = type;
237		type = opts.type
238	}
239
240	if (!opts) opts = {};
241
242	if (!BX.type.isNotEmptyString(type))
243	{
244		el.style.display = 'none';
245		return;
246	}
247
248	var fxOptions = BX.fx.EFFECTS[type](el, opts, 0);
249	fxOptions.callback_complete = function () {
250		if (opts.hide !== false)
251			el.style.display = 'none';
252
253		if (opts.callback_complete)
254			opts.callback_complete.apply(this, arguments);
255	}
256
257	return (new BX.fx(fxOptions)).start();
258}
259
260BX.fx.show = function(el, type, opts)
261{
262	el = BX(el);
263
264	if (typeof type == 'object' && null == opts)
265	{
266		opts = type;
267		type = opts.type
268	}
269
270	if (!opts) opts = {};
271
272	if (!BX.type.isNotEmptyString(type))
273	{
274		el.style.display = 'block';
275		return;
276	}
277
278	var fxOptions = BX.fx.EFFECTS[type](el, opts, 1);
279
280	fxOptions.callback_complete = function () {
281		if (opts.show !== false)
282			el.style.display = 'block';
283
284		if (opts.callback_complete)
285			opts.callback_complete.apply(this, arguments);
286	}
287
288	return (new BX.fx(fxOptions)).start();
289}
290
291BX.fx.EFFECTS = {
292	scroll: function(el, opts, action)
293	{
294		if (!opts.direction) opts.direction = 'vertical';
295
296		var param = opts.direction == 'horizontal' ? 'width' : 'height';
297
298		var val = parseInt(BX.style(el, param));
299		if (isNaN(val))
300		{
301			val = BX.pos(el)[param];
302		}
303
304		if (action == 0)
305			var start = val, finish = opts.min_height ? parseInt(opts.min_height) : 0;
306		else
307			var finish = val, start = opts.min_height ? parseInt(opts.min_height) : 0;
308
309		return {
310			'start': start,
311			'finish': finish,
312			'time': opts.time || defaultOptions.time,
313			'type': 'linear',
314			callback_start: function () {
315				if (BX.style(el, 'position') == 'static')
316					el.style.position = 'relative';
317
318				el.style.overflow = 'hidden';
319				el.style[param] = start + 'px';
320				el.style.display = 'block';
321			},
322			callback: function (val) {el.style[param] = val + 'px';}
323		}
324	},
325
326	fade: function(el, opts, action)
327	{
328		var fadeOpts = {
329			'time': opts.time || defaultOptions.time,
330			'type': action == 0 ? 'decelerated' : 'linear',
331			'start': action == 0 ? 1 : 0,
332			'finish': action == 0 ? 0 : 1,
333			'allowFloat': true
334		};
335
336		if (BX.browser.IsIE() && !BX.browser.IsIE9())
337		{
338			fadeOpts.start *= 100; fadeOpts.finish *= 100; fadeOpts.allowFloat = false;
339
340			fadeOpts.callback_start = function() {
341				el.style.display = 'block';
342				el.style.filter += "progid:DXImageTransform.Microsoft.Alpha(opacity=" + fadeOpts.start + ")";
343			};
344
345			fadeOpts.callback = function (val) {
346				(el.filters['DXImageTransform.Microsoft.alpha']||el.filters.alpha).opacity = val;
347			}
348		}
349		else
350		{
351			fadeOpts.callback_start = function () {
352				el.style.display = 'block';
353			}
354
355			fadeOpts.callback = function (val) {
356				el.style.opacity = el.style.KhtmlOpacity = el.style.MozOpacity = val;
357			};
358		}
359
360		return fadeOpts;
361	},
362
363	fold: function (el, opts, action) // 'fold' is a combination of two consequential 'scroll' hidings.
364	{
365		if (action != 0) return;
366
367		var pos = BX.pos(el);
368		var coef = pos.height / (pos.width + pos.height);
369		var old_opts = {time: opts.time || defaultOptions.time, callback_complete: opts.callback_complete, hide: opts.hide};
370
371		opts.type = 'scroll';
372		opts.direction = 'vertical';
373		opts.min_height = opts.min_height || 10;
374		opts.hide = false;
375		opts.time = coef * old_opts.time;
376		opts.callback_complete = function()
377		{
378			el.style.whiteSpace = 'nowrap';
379
380			opts.direction = 'horizontal';
381			opts.min_height = null;
382
383			opts.time = old_opts.time - opts.time;
384			opts.hide = old_opts.hide;
385			opts.callback_complete = old_opts.callback_complete;
386
387			BX.fx.hide(el, opts);
388		}
389
390		return BX.fx.EFFECTS.scroll(el, opts, action);
391	},
392
393	scale: function (el, opts, action)
394	{
395		var val = {width: parseInt(BX.style(el, 'width')), height: parseInt(BX.style(el, 'height'))};
396		if (isNaN(val.width) || isNaN(val.height))
397		{
398			var pos = BX.pos(el)
399			val = {width: pos.width, height: pos.height};
400		}
401
402		if (action == 0)
403			var start = val, finish = {width: 0, height: 0};
404		else
405			var finish = val, start = {width: 0, height: 0};
406
407		return {
408			'start': start,
409			'finish': finish,
410			'time': opts.time || defaultOptions.time,
411			'type': 'linear',
412			callback_start: function () {
413				el.style.position = 'relative';
414				el.style.overflow = 'hidden';
415				el.style.display = 'block';
416				el.style.height = start.height + 'px';
417				el.style.width = start.width + 'px';
418			},
419			callback: function (val) {
420				el.style.height = val.height + 'px';
421				el.style.width = val.width + 'px';
422			}
423		}
424	}
425}
426
427// Color animation
428//
429// Set animation rule
430// BX.fx.colorAnimate.addRule('animationRule1',"#FFF","#faeeb4", "background-color", 100, 1, true);
431// BX.fx.colorAnimate.addRule('animationRule2',"#fc8282","#ff0000", "color", 100, 1, true);
432// Params: 1 - animation name, 2 - start color, 3 - end color, 4 - count step, 5 - delay each step, 6 - return color on end animation
433//
434// Animate color for element
435// BX.fx.colorAnimate(BX('element'), 'animationRule1,animationRule2');
436
437var defaultOptionsColorAnimation = {
438	arStack: {},
439	arRules: {},
440	globalAnimationId: 0
441}
442
443BX.fx.colorAnimate = function(element, rule, back)
444{
445	if (element == null)
446		return;
447
448	animationId = element.getAttribute('data-animation-id');
449	if (animationId == null)
450	{
451		animationId = defaultOptionsColorAnimation.globalAnimationId;
452		element.setAttribute('data-animation-id', defaultOptionsColorAnimation.globalAnimationId++);
453	}
454	var aRuleList = rule.split(/\s*,\s*/);
455
456	for (var j	= 0; j < aRuleList.length; j++)
457	{
458		rule = aRuleList[j];
459
460		if (!defaultOptionsColorAnimation.arRules[rule]) continue;
461
462		var i=0;
463
464		if (!defaultOptionsColorAnimation.arStack[animationId])
465		{
466			defaultOptionsColorAnimation.arStack[animationId] = {};
467		}
468		else if (defaultOptionsColorAnimation.arStack[animationId][rule])
469		{
470			i = defaultOptionsColorAnimation.arStack[animationId][rule].i;
471			clearInterval(defaultOptionsColorAnimation.arStack[animationId][rule].tId);
472		}
473
474		if ((i==0 && back) || (i==defaultOptionsColorAnimation.arRules[rule][3] && !back)) continue;
475
476		defaultOptionsColorAnimation.arStack[animationId][rule] = {'i':i, 'element': element, 'tId':setInterval('BX.fx.colorAnimate.run("'+animationId+'","'+rule+'")', defaultOptionsColorAnimation.arRules[rule][4]),'back':Boolean(back)};
477	}
478}
479
480BX.fx.colorAnimate.addRule = function (rule, startColor, finishColor, cssProp, step, delay, back)
481{
482	defaultOptionsColorAnimation.arRules[rule] = [
483		BX.util.hex2rgb(startColor),
484		BX.util.hex2rgb(finishColor),
485		cssProp.replace(/\-(.)/g,function(){return arguments[1].toUpperCase();}),
486		step,
487		delay || 1,
488		back || false
489	];
490};
491
492BX.fx.colorAnimate.run = function(animationId, rule)
493{
494	element = defaultOptionsColorAnimation.arStack[animationId][rule].element;
495
496    defaultOptionsColorAnimation.arStack[animationId][rule].i += defaultOptionsColorAnimation.arStack[animationId][rule].back?-1:1;
497 	var finishPercent = defaultOptionsColorAnimation.arStack[animationId][rule].i/defaultOptionsColorAnimation.arRules[rule][3];
498	var startPercent = 1 - finishPercent;
499
500	var aRGBStart = defaultOptionsColorAnimation.arRules[rule][0];
501	var aRGBFinish = defaultOptionsColorAnimation.arRules[rule][1];
502
503	element.style[defaultOptionsColorAnimation.arRules[rule][2]] = 'rgb('+
504	Math.floor( aRGBStart['r'] * startPercent + aRGBFinish['r'] * finishPercent ) + ','+
505	Math.floor( aRGBStart['g'] * startPercent + aRGBFinish['g'] * finishPercent ) + ','+
506	Math.floor( aRGBStart['b'] * startPercent + aRGBFinish['b'] * finishPercent ) +')';
507
508	if ( defaultOptionsColorAnimation.arStack[animationId][rule].i == defaultOptionsColorAnimation.arRules[rule][3] || defaultOptionsColorAnimation.arStack[animationId][rule].i ==0)
509	{
510		clearInterval(defaultOptionsColorAnimation.arStack[animationId][rule].tId);
511		if (defaultOptionsColorAnimation.arRules[rule][5])
512			BX.fx.colorAnimate(defaultOptionsColorAnimation.arStack[animationId][rule].element, rule, true);
513	}
514}
515
516
517/*
518options = {
519	delay: 100,
520	duration : 3000,
521	start : { scroll : document.body.scrollTop, left : 0, opacity :  100 },
522	finish : { scroll : document.body.scrollHeight, left : 500, opacity : 10 },
523	transition : BitrixAnimation.makeEaseOut(BitrixAnimation.transitions.quart),
524
525	step : function(state)
526	{
527		document.body.scrollTop = state.scroll;
528		button.style.left =  state.left + "px";
529		button.style.opacity =  state.opacity / 100;
530	},
531	complete : function()
532	{
533		button.style.background = "green";
534	}
535}
536
537options =
538{
539	delay : 20,
540	duration : 4000,
541	transition : BXAnimation.makeEaseOut(BXAnimation.transitions.quart),
542	progress : function(progress)
543	{
544		document.body.scrollTop = Math.round(topMax * progress);
545		button.style.left =  Math.round(leftMax * progress) + "px";
546		button.style.opacity =  (100 + Math.round((opacityMin - 100) * progress)) / 100;
547
548	},
549	complete : function()
550	{
551		button.style.background = "green";
552	}
553}
554*/
555
556BX.easing = function(options)
557{
558	this.options = options;
559	this.timer = null;
560};
561
562BX.easing.prototype.animate = function()
563{
564	if (!this.options || !this.options.start || !this.options.finish ||
565		typeof(this.options.start) != "object" || typeof(this.options.finish) != "object"
566		)
567		return null;
568
569	for (var propName in this.options.start)
570	{
571		if (typeof(this.options.finish[propName]) == "undefined")
572		{
573			delete this.options.start[propName];
574		}
575	}
576
577	this.options.progress = function(progress) {
578		var state = {};
579		for (var propName in this.start)
580			state[propName] = Math.round(this.start[propName] + (this.finish[propName] - this.start[propName]) * progress);
581
582		if (this.step)
583		{
584			this.step(state);
585		}
586	};
587
588	this.animateProgress();
589};
590
591BX.easing.prototype.stop = function(completed)
592{
593	if (this.timer)
594	{
595		cancelAnimationFrame(this.timer);
596		this.timer = null;
597		if (completed)
598		{
599			this.options.complete && this.options.complete();
600		}
601	}
602};
603
604BX.easing.prototype.animateProgress = function()
605{
606	if (!window.requestAnimationFrame)
607	{
608		//For old browsers we skip animation
609		this.options.progress(1);
610		this.options.complete && this.options.complete();
611		return;
612	}
613
614	var start = null;
615	var delta = this.options.transition || BX.easing.transitions.linear;
616	var duration = this.options.duration || 1000;
617	var animation = BX.proxy(function(time) {
618
619		if (start === null)
620		{
621			start = time;
622		}
623
624		var progress = (time - start) / duration;
625		if (progress > 1)
626		{
627			progress = 1;
628		}
629
630		this.options.progress(delta(progress));
631
632		if (progress == 1)
633		{
634			this.stop(true);
635		}
636		else
637		{
638			this.timer = requestAnimationFrame(animation);
639		}
640
641	}, this);
642
643	this.timer = requestAnimationFrame(animation);
644};
645
646BX.easing.makeEaseInOut = function(delta)
647{
648	return function(progress) {
649		if (progress < 0.5)
650			return delta( 2 * progress ) / 2;
651		else
652			return (2 - delta( 2 * (1-progress) ) ) / 2;
653	}
654};
655
656BX.easing.makeEaseOut = function(delta)
657{
658	return function(progress) {
659		return 1 - delta(1 - progress);
660	};
661};
662
663BX.easing.transitions = {
664
665	linear : function(progress)
666	{
667		return progress;
668	},
669
670	quad : function(progress)
671	{
672		return Math.pow(progress, 2);
673	},
674
675	cubic : function(progress) {
676		return Math.pow(progress, 3);
677	},
678
679	quart : function(progress)
680	{
681		return Math.pow(progress, 4);
682	},
683
684	quint : function(progress)
685	{
686		return Math.pow(progress, 5);
687	},
688
689	circ : function(progress)
690	{
691		return 1 - Math.sin(Math.acos(progress));
692	},
693
694	back : function(progress)
695	{
696		return Math.pow(progress, 2) * ((1.5 + 1) * progress - 1.5);
697	},
698
699	elastic: function(progress)
700	{
701		return Math.pow(2, 10 * (progress-1)) * Math.cos(20 * Math.PI * 1.5/3 * progress);
702	},
703
704	bounce : function(progress)
705	{
706		for(var a = 0, b = 1; 1; a += b, b /= 2) {
707			if (progress >= (7 - 4 * a) / 11) {
708				return -Math.pow((11 - 6 * a - 11 * progress) / 4, 2) + Math.pow(b, 2);
709			}
710		}
711	}};
712
713
714})(window);
715
716
717/* End */
718;
719; /* Start:"a:4:{s:4:"full";s:41:"/bitrix/js/main/session.js?16404489843701";s:6:"source";s:26:"/bitrix/js/main/session.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
720function CBXSession()
721{
722	var _this = this;
723	this.dateInput = new Date();
724	this.dateCheck = new Date();
725	this.dateHit = new Date();
726	this.notifier = null;
727	this.checkInterval = 60;
728	this.checkImmediately = false;
729
730	this.Expand = function(key)
731	{
732		this.key = key;
733
734		BX.ready(function(){
735			BX.bind(document, "keypress", _this.OnUserInput);
736			BX.bind(document.body, "mousemove", _this.OnUserInput);
737			BX.bind(document.body, "click", _this.OnUserInput);
738
739			//check the state once in a minute
740			setInterval(_this.CheckSession, _this.checkInterval*1000);
741		})
742	};
743
744	this.OnUserInput = function()
745	{
746		var currentDate = new Date();
747		_this.dateInput.setTime(currentDate.valueOf());
748
749		if ((currentDate - _this.dateHit)/1000 > (_this.checkInterval + 5) && _this.checkImmediately === false)
750		{
751			// last hit was long time ago, need to recheck immediately
752			_this.checkImmediately = true;
753			_this.CheckSession();
754		}
755	};
756
757	this.CheckSession = function()
758	{
759		var currentDate = new Date();
760
761		if((currentDate - _this.dateCheck)/1000 < (_this.checkInterval - 1) && _this.checkImmediately === false)
762		{
763			//storm protection, e.g. after PC wake-up
764			return;
765		}
766
767		_this.dateCheck.setTime(currentDate.valueOf());
768
769		if(_this.dateInput > _this.dateHit)
770		{
771			//there was input after the last hit, expand/check the session
772			var config = {
773				'method': 'GET',
774				'headers': [
775					{'name': 'X-Bitrix-Csrf-Token', 'value': BX.bitrix_sessid()}
776				],
777				'dataType': 'html',
778				'url': '/bitrix/tools/public_session.php?k='+_this.key,
779				'data':  '',
780				'onsuccess': function(data){_this.CheckResult(data)},
781				'lsId': 'sess_expand', //caching the result in the local storage for multiple tabs
782				'lsTimeout': _this.checkInterval - 5 //some delta for response time
783			};
784			BX.ajax(config);
785		}
786	};
787
788	this.CheckResult = function(data)
789	{
790		var currentDate = new Date();
791		_this.dateHit.setTime(currentDate.valueOf());
792		_this.checkImmediately = false;
793
794		if(data == 'SESSION_EXPIRED')
795		{
796			if(BX.message("SessExpired"))
797			{
798				if(!_this.notifier)
799				{
800					_this.notifier = document.body.appendChild(BX.create('DIV', {
801						props: {className: 'bx-session-message'},
802						style: {
803							top: '0',
804							backgroundColor: '#FFEB41',
805							border: '1px solid #EDDA3C',
806							width: '630px',
807							fontFamily: 'Arial,Helvetica,sans-serif',
808							fontSize: '13px',
809							fontWeight: 'bold',
810							textAlign: 'center',
811							color: 'black',
812							position: 'absolute',
813							zIndex: '10000',
814							padding: '10px'
815						},
816						html: '<a class="bx-session-message-close" ' +
817							'style="display:block; width:12px; height:12px; background:url(/bitrix/js/main/core/images/close.gif) center no-repeat; float:right;" ' +
818							'href="javascript:bxSession.Close()"></a>' +
819							BX.message("SessExpired")
820					}));
821
822					BX.ZIndexManager.register(_this.notifier);
823					BX.ZIndexManager.bringToFront(_this.notifier);
824
825					var windowScroll = BX.GetWindowScrollPos();
826					var windowSize = BX.GetWindowInnerSize();
827
828					_this.notifier.style.left = parseInt(windowScroll.scrollLeft + (windowSize.innerWidth / 2) - (parseInt(_this.notifier.clientWidth) / 2)) + 'px';
829
830					if(BX.browser.IsIE())
831					{
832						_this.notifier.style.top = windowScroll.scrollTop + 'px';
833
834						BX.bind(window, 'scroll', function()
835						{
836							var windowScroll = BX.GetWindowScrollPos();
837							_this.notifier.style.top = windowScroll.scrollTop + 'px';
838						});
839					}
840					else
841					{
842						_this.notifier.style.position='fixed';
843					}
844				}
845
846				_this.notifier.style.display = '';
847			}
848		}
849	};
850
851	this.Close = function()
852	{
853		this.notifier.style.display = 'none';
854	}
855}
856
857var bxSession = new CBXSession();
858
859/* End */
860;
861; /* Start:"a:4:{s:4:"full";s:54:"/bitrix/js/main/pageobject/pageobject.js?1608166115864";s:6:"source";s:40:"/bitrix/js/main/pageobject/pageobject.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
862window.BX = BX || {};
863
864BX.PageObject = {
865	getRootWindow: function()
866	{
867		return BX.PageObject.getTopWindowOfCurrentHost(window);
868	},
869
870	isCrossOriginObject: function(currentWindow)
871	{
872		try
873		{
874			void currentWindow.location.host;
875		}
876		catch (e)
877		{
878			// cross-origin object
879			return true;
880		}
881
882		return false;
883	},
884
885	getTopWindowOfCurrentHost: function(currentWindow)
886	{
887		if (
888			!BX.PageObject.isCrossOriginObject(currentWindow.parent)
889			&& currentWindow.parent !== currentWindow
890			&& currentWindow.parent.location.host === currentWindow.location.host
891		)
892		{
893			return BX.PageObject.getTopWindowOfCurrentHost(currentWindow.parent);
894		}
895
896		return currentWindow;
897	},
898
899	getParentWindowOfCurrentHost: function(currentWindow)
900	{
901		if (BX.PageObject.isCrossOriginObject(currentWindow.parent))
902		{
903			return currentWindow;
904		}
905
906		return currentWindow.parent;
907	}
908};
909/* End */
910;
911; /* Start:"a:4:{s:4:"full";s:51:"/bitrix/js/main/core/core_window.js?164085864698768";s:6:"source";s:35:"/bitrix/js/main/core/core_window.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
912;(function(window) {
913if (BX.WindowManager) return;
914
915/* windows manager */
916BX.WindowManager = {
917	_stack: [],
918	_runtime_resize: {},
919	_delta: 2,
920	_delta_start: 1000,
921	currently_loaded: null,
922
923	settings_category: 'BX.WindowManager.9.5',
924
925	register: function (w)
926	{
927		this.currently_loaded = null;
928
929		w.WM_REG_INDEX = this._stack.length;
930		this._stack.push(w);
931
932		if (this._stack.length < 2)
933		{
934			BX.bind(document, 'keyup', BX.proxy(this.__checkKeyPress, this));
935		}
936	},
937
938	unregister: function (w)
939	{
940		if (null == w.WM_REG_INDEX)
941			return null;
942
943		var _current;
944		if (this._stack.length > 0)
945		{
946			while ((_current = this.__pop_stack()) != w)
947			{
948				if (!_current)
949				{
950					_current = null;
951					break;
952				}
953			}
954
955			if (this._stack.length <= 0)
956			{
957				this.enableKeyCheck();
958			}
959
960			return _current;
961		}
962		else
963		{
964			return null;
965		}
966	},
967
968	__pop_stack: function(clean)
969	{
970		if (this._stack.length > 0)
971		{
972			var _current = this._stack.pop();
973			_current.WM_REG_INDEX = null;
974			BX.onCustomEvent(_current, 'onWindowUnRegister', [clean === true]);
975
976			return _current;
977		}
978		else
979			return null;
980	},
981
982	clean: function()
983	{
984		while (this.__pop_stack(true)){}
985		this._stack = null;
986		this.disableKeyCheck();
987	},
988
989	Get: function()
990	{
991		if (this.currently_loaded)
992			return this.currently_loaded;
993		else if (this._stack.length > 0)
994			return this._stack[this._stack.length-1];
995		else
996			return null;
997	},
998
999	setStartZIndex: function(value)
1000	{
1001		this._delta_start = value;
1002	},
1003
1004	restoreStartZIndex: function()
1005	{
1006		this._delta_start = 1000;
1007	},
1008
1009	GetZIndex: function()
1010	{
1011		var _current;
1012		return (null != (_current = this._stack[this._stack.length-1])
1013			? parseInt(_current.Get().style.zIndex) + this._delta
1014			: this._delta_start
1015		);
1016	},
1017
1018	__get_check_url: function(url)
1019	{
1020		var pos = url.indexOf('?');
1021		return pos == -1 ? url : url.substring(0, pos);
1022	},
1023
1024	saveWindowSize: function(url, params)
1025	{
1026		var check_url = this.__get_check_url(url);
1027		if (BX.userOptions)
1028		{
1029			BX.userOptions.save(this.settings_category, 'size_' + check_url, 'width', params.width);
1030			BX.userOptions.save(this.settings_category, 'size_' + check_url, 'height', params.height);
1031		}
1032
1033		this._runtime_resize[check_url] = params;
1034	},
1035
1036	saveWindowOptions: function(wnd_id, opts)
1037	{
1038		if (BX.userOptions)
1039		{
1040			for (var i in opts)
1041			{
1042				if(opts.hasOwnProperty(i))
1043				{
1044					BX.userOptions.save(this.settings_category, 'options_' + wnd_id, i, opts[i]);
1045				}
1046			}
1047		}
1048	},
1049
1050	getRuntimeWindowSize: function(url)
1051	{
1052		return this._runtime_resize[this.__get_check_url(url)];
1053	},
1054
1055	disableKeyCheck: function()
1056	{
1057		BX.unbind(document, 'keyup', BX.proxy(this.__checkKeyPress, this));
1058	},
1059
1060	enableKeyCheck: function()
1061	{
1062		BX.bind(document, 'keyup', BX.proxy(this.__checkKeyPress, this));
1063	},
1064
1065	__checkKeyPress: function(e)
1066	{
1067		if (null == e)
1068			e = window.event;
1069
1070		if (e.keyCode == 27)
1071		{
1072			var wnd = BX.WindowManager.Get();
1073			if (wnd && !wnd.unclosable) wnd.Close();
1074		}
1075	}
1076};
1077
1078BX.garbage(BX.WindowManager.clean, BX.WindowManager);
1079
1080/* base button class */
1081BX.CWindowButton = function(params)
1082{
1083	if (params.btn)
1084	{
1085		this.btn = params.btn;
1086		this.parentWindow = params.parentWindow;
1087
1088		if (/save|apply/i.test(this.btn.name))
1089		{
1090			BX.bind(this.btn, 'click', BX.delegate(this.disableUntilError, this));
1091		}
1092	}
1093	else
1094	{
1095		this.title = params.title; // html value attr
1096		this.hint = params.hint; // html title attr
1097		this.id = params.id; // html name and id attrs
1098		this.name = params.name; // html name or value attrs when id and title 're absent
1099		this.className = params.className; // className for button input
1100
1101		this.action = params.action;
1102		this.onclick = params.onclick;
1103
1104		// you can override button creation method
1105		if (params.Button && BX.type.isFunction(params.Button))
1106			this.Button = params.Button;
1107
1108		this.btn = null;
1109	}
1110};
1111
1112BX.CWindowButton.prototype.disable = function()
1113{
1114	if (this.btn)
1115		this.parentWindow.showWait(this.btn);
1116};
1117BX.CWindowButton.prototype.enable = function(){
1118	if (this.btn)
1119		this.parentWindow.closeWait(this.btn);
1120};
1121
1122BX.CWindowButton.prototype.emulate = function()
1123{
1124	if (this.btn && this.btn.disabled)
1125		return;
1126
1127	var act =
1128		this.action
1129		? BX.delegate(this.action, this)
1130		: (
1131			this.onclick
1132			? this.onclick
1133			: (
1134				this.btn
1135				? this.btn.getAttribute('onclick')
1136				: ''
1137			)
1138		);
1139
1140	if (act)
1141	{
1142		setTimeout(act, 50);
1143		if (this.btn && /save|apply/i.test(this.btn.name) && !this.action)
1144		{
1145			this.disableUntilError();
1146		}
1147	}
1148};
1149
1150BX.CWindowButton.prototype.Button = function(parentWindow)
1151{
1152	this.parentWindow = parentWindow;
1153
1154	var btn = {
1155		props: {
1156			'type': 'button',
1157			'name': this.id ? this.id : this.name,
1158			'value': this.title ? this.title : this.name,
1159			'id': this.id
1160		}
1161	};
1162
1163	if (this.hint)
1164		btn.props.title = this.hint;
1165	if (!!this.className)
1166		btn.props.className = this.className;
1167
1168	if (this.action)
1169	{
1170		btn.events = {
1171			'click': BX.delegate(this.action, this)
1172		};
1173	}
1174	else if (this.onclick)
1175	{
1176		if (BX.browser.IsIE())
1177		{
1178			btn.events = {
1179				'click': BX.delegate(function() {eval(this.onclick)}, this)
1180			};
1181		}
1182		else
1183		{
1184			btn.attrs = {
1185				'onclick': this.onclick
1186			};
1187		}
1188	}
1189
1190	this.btn = BX.create('INPUT', btn);
1191
1192	return this.btn;
1193};
1194
1195BX.CWindowButton.prototype.disableUntilError = function() {
1196	this.disable();
1197	if (!this.__window_error_handler_set)
1198	{
1199		BX.addCustomEvent(this.parentWindow, 'onWindowError', BX.delegate(this.enable, this));
1200		this.__window_error_handler_set = true;
1201	}
1202};
1203
1204/* base window class */
1205BX.CWindow = function(div, type)
1206{
1207	this.DIV = div || document.createElement('DIV');
1208
1209	this.SETTINGS = {
1210		resizable: false,
1211		min_height: 0,
1212		min_width: 0,
1213		top: 0,
1214		left: 0,
1215		draggable: false,
1216		drag_restrict: true,
1217		resize_restrict: true
1218	};
1219
1220	this.ELEMENTS = {
1221		draggable: [],
1222		resizer: [],
1223		close: []
1224	};
1225
1226	this.type = type == 'float' ? 'float' : 'dialog';
1227
1228	BX.adjust(this.DIV, {
1229		props: {
1230			className: 'bx-core-window'
1231		},
1232		style: {
1233			'zIndex': 0,
1234			'position': 'absolute',
1235			'display': 'none',
1236			'top': this.SETTINGS.top + 'px',
1237			'left': this.SETTINGS.left + 'px',
1238			'height': '100px',
1239			'width': '100px'
1240		}
1241	});
1242
1243	this.isOpen = false;
1244
1245	BX.addCustomEvent(this, 'onWindowRegister', BX.delegate(this.onRegister, this));
1246	BX.addCustomEvent(this, 'onWindowUnRegister', BX.delegate(this.onUnRegister, this));
1247
1248	this.MOUSEOVER = null;
1249	BX.bind(this.DIV, 'mouseover', BX.delegate(this.__set_msover, this));
1250	BX.bind(this.DIV, 'mouseout', BX.delegate(this.__unset_msover, this));
1251
1252	BX.ready(BX.delegate(function() {
1253		document.body.appendChild(this.DIV);
1254		BX.ZIndexManager.register(this.DIV);
1255	}, this));
1256};
1257
1258BX.CWindow.prototype.Get = function () {return this.DIV};
1259BX.CWindow.prototype.visible = function() {return this.isOpen;};
1260
1261BX.CWindow.prototype.Show = function(bNotRegister)
1262{
1263	this.DIV.style.display = 'block';
1264
1265	if (!bNotRegister)
1266	{
1267		BX.WindowManager.register(this);
1268		BX.onCustomEvent(this, 'onWindowRegister');
1269	}
1270
1271	BX.ZIndexManager.bringToFront(this.DIV);
1272};
1273
1274BX.CWindow.prototype.Hide = function()
1275{
1276	BX.WindowManager.unregister(this);
1277	this.DIV.style.display = 'none';
1278};
1279
1280BX.CWindow.prototype.onRegister = function()
1281{
1282	this.isOpen = true;
1283};
1284
1285BX.CWindow.prototype.onUnRegister = function(clean)
1286{
1287	this.isOpen = false;
1288
1289	if (clean || (this.PARAMS && this.PARAMS.content_url))
1290	{
1291		if (clean) {BX.onCustomEvent(this, 'onWindowClose', [this, true]);}
1292
1293		if (this.DIV.parentNode)
1294			this.DIV.parentNode.removeChild(this.DIV);
1295	}
1296	else
1297	{
1298		this.DIV.style.display = 'none';
1299	}
1300};
1301
1302BX.CWindow.prototype.CloseDialog = // compatibility
1303BX.CWindow.prototype.Close = function(bImmediately)
1304{
1305	BX.onCustomEvent(this, 'onBeforeWindowClose', [this]);
1306	if (bImmediately !== true)
1307	{
1308		if (this.denyClose)
1309			return false;
1310	}
1311
1312	BX.onCustomEvent(this, 'onWindowClose', [this]);
1313
1314	//this crashes vis editor in ie via onWindowResizeExt event handler
1315	//if (this.bExpanded) this.__expand();
1316	// alternative version:
1317	if (this.bExpanded)
1318	{
1319		var pDocElement = BX.GetDocElement();
1320		BX.unbind(window, 'resize', BX.proxy(this.__expand_onresize, this));
1321		pDocElement.style.overflow = this.__expand_settings.overflow;
1322	}
1323
1324	BX.WindowManager.unregister(this);
1325
1326	return true;
1327};
1328
1329BX.CWindow.prototype.SetResize = function(elem)
1330{
1331	elem.style.cursor = 'se-resize';
1332	BX.bind(elem, 'mousedown', BX.proxy(this.__startResize, this));
1333
1334	this.ELEMENTS.resizer.push(elem);
1335	this.SETTINGS.resizable = true;
1336};
1337
1338BX.CWindow.prototype.SetExpand = function(elem, event_name)
1339{
1340	event_name = event_name || 'click';
1341	BX.bind(elem, event_name, BX.proxy(this.__expand, this));
1342};
1343
1344BX.CWindow.prototype.__expand_onresize = function()
1345{
1346	var windowSize = BX.GetWindowInnerSize();
1347	this.DIV.style.width = windowSize.innerWidth + "px";
1348	this.DIV.style.height = windowSize.innerHeight + "px";
1349
1350	BX.onCustomEvent(this, 'onWindowResize');
1351};
1352
1353BX.CWindow.prototype.__expand = function()
1354{
1355	var pDocElement = BX.GetDocElement();
1356
1357	if (!this.bExpanded)
1358	{
1359		var wndScroll = BX.GetWindowScrollPos(),
1360			wndSize = BX.GetWindowInnerSize();
1361
1362		this.__expand_settings = {
1363			resizable: this.SETTINGS.resizable,
1364			draggable: this.SETTINGS.draggable,
1365			width: this.DIV.style.width,
1366			height: this.DIV.style.height,
1367			left: this.DIV.style.left,
1368			top: this.DIV.style.top,
1369			scrollTop: wndScroll.scrollTop,
1370			scrollLeft: wndScroll.scrollLeft,
1371			overflow: BX.style(pDocElement, 'overflow')
1372		};
1373
1374		this.SETTINGS.resizable = false;
1375		this.SETTINGS.draggable = false;
1376
1377		window.scrollTo(0,0);
1378		pDocElement.style.overflow = 'hidden';
1379
1380		this.DIV.style.top = '0px';
1381		this.DIV.style.left = '0px';
1382
1383		this.DIV.style.width = wndSize.innerWidth + 'px';
1384		this.DIV.style.height = wndSize.innerHeight + 'px';
1385
1386		this.bExpanded = true;
1387
1388		BX.onCustomEvent(this, 'onWindowExpand');
1389		BX.onCustomEvent(this, 'onWindowResize');
1390
1391		BX.bind(window, 'resize', BX.proxy(this.__expand_onresize, this));
1392	}
1393	else
1394	{
1395		BX.unbind(window, 'resize', BX.proxy(this.__expand_onresize, this));
1396
1397		this.SETTINGS.resizable = this.__expand_settings.resizable;
1398		this.SETTINGS.draggable = this.__expand_settings.draggable;
1399
1400		pDocElement.style.overflow = this.__expand_settings.overflow;
1401
1402		this.DIV.style.top = this.__expand_settings.top;
1403		this.DIV.style.left = this.__expand_settings.left;
1404		this.DIV.style.width = this.__expand_settings.width;
1405		this.DIV.style.height = this.__expand_settings.height;
1406
1407		window.scrollTo(this.__expand_settings.scrollLeft, this.__expand_settings.scrollTop);
1408
1409		this.bExpanded = false;
1410
1411		BX.onCustomEvent(this, 'onWindowNarrow');
1412		BX.onCustomEvent(this, 'onWindowResize');
1413
1414	}
1415};
1416
1417BX.CWindow.prototype.Resize = function(x, y)
1418{
1419	var new_width = Math.max(x - this.pos.left + this.dx, this.SETTINGS.min_width);
1420	var new_height = Math.max(y - this.pos.top + this.dy, this.SETTINGS.min_height);
1421
1422	if (this.SETTINGS.resize_restrict)
1423	{
1424		var scrollSize = BX.GetWindowScrollSize();
1425
1426		if (this.pos.left + new_width > scrollSize.scrollWidth - this.dw)
1427			new_width = scrollSize.scrollWidth - this.pos.left - this.dw;
1428	}
1429
1430	this.DIV.style.width = new_width + 'px';
1431	this.DIV.style.height = new_height + 'px';
1432
1433	BX.onCustomEvent(this, 'onWindowResize');
1434};
1435
1436BX.CWindow.prototype.__startResize = function(e)
1437{
1438	if (!this.SETTINGS.resizable)
1439		return false;
1440
1441	if(!e) e = window.event;
1442
1443	this.wndSize = BX.GetWindowScrollPos();
1444	this.wndSize.innerWidth = BX.GetWindowInnerSize().innerWidth;
1445
1446	this.pos = BX.pos(this.DIV);
1447
1448	this.x = e.clientX + this.wndSize.scrollLeft;
1449	this.y = e.clientY + this.wndSize.scrollTop;
1450
1451	this.dx = this.pos.left + this.pos.width - this.x;
1452	this.dy = this.pos.top + this.pos.height - this.y;
1453	this.dw = this.pos.width - parseInt(this.DIV.style.width);
1454
1455	BX.bind(document, "mousemove", BX.proxy(this.__moveResize, this));
1456	BX.bind(document, "mouseup", BX.proxy(this.__stopResize, this));
1457
1458	if(document.body.setCapture)
1459		document.body.setCapture();
1460
1461	document.onmousedown = BX.False;
1462
1463	var b = document.body;
1464	b.ondrag = b.onselectstart = BX.False;
1465	b.style.MozUserSelect = this.DIV.style.MozUserSelect = 'none';
1466	b.style.cursor = 'se-resize';
1467
1468	BX.onCustomEvent(this, 'onWindowResizeStart');
1469
1470	return true;
1471};
1472
1473BX.CWindow.prototype.__moveResize = function(e)
1474{
1475	if(!e) e = window.event;
1476
1477	var windowScroll = BX.GetWindowScrollPos();
1478
1479	var x = e.clientX + windowScroll.scrollLeft;
1480	var y = e.clientY + windowScroll.scrollTop;
1481
1482	if(this.x == x && this.y == y)
1483		return;
1484
1485	this.Resize(x, y);
1486
1487	this.x = x;
1488	this.y = y;
1489};
1490
1491BX.CWindow.prototype.__stopResize = function()
1492{
1493	if(document.body.releaseCapture)
1494		document.body.releaseCapture();
1495
1496	BX.unbind(document, "mousemove", BX.proxy(this.__moveResize, this));
1497	BX.unbind(document, "mouseup", BX.proxy(this.__stopResize, this));
1498
1499	document.onmousedown = null;
1500
1501	var b = document.body;
1502	b.ondrag = b.onselectstart = null;
1503	b.style.MozUserSelect = this.DIV.style.MozUserSelect = '';
1504	b.style.cursor = '';
1505
1506	BX.onCustomEvent(this, 'onWindowResizeFinished')
1507};
1508
1509BX.CWindow.prototype.SetClose = function(elem)
1510{
1511	BX.bind(elem, 'click', BX.proxy(this.Close, this));
1512	this.ELEMENTS.close.push(elem);
1513};
1514
1515BX.CWindow.prototype.SetDraggable = function(elem)
1516{
1517	BX.bind(elem, 'mousedown', BX.proxy(this.__startDrag, this));
1518
1519	elem.style.cursor = 'move';
1520
1521	this.ELEMENTS.draggable.push(elem);
1522	this.SETTINGS.draggable = true;
1523};
1524
1525BX.CWindow.prototype.Move = function(x, y)
1526{
1527	var dxShadow = 1; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1528
1529	var left = parseInt(this.DIV.style.left)+x;
1530	var top = parseInt(this.DIV.style.top)+y;
1531
1532	if (this.SETTINGS.drag_restrict)
1533	{
1534		//Left side
1535		if (left < 0)
1536			left = 0;
1537
1538		//Right side
1539		var scrollSize = BX.GetWindowScrollSize();
1540		var floatWidth = this.DIV.offsetWidth;
1541		var floatHeight = this.DIV.offsetHeight;
1542
1543		if (left > (scrollSize.scrollWidth - floatWidth - dxShadow))
1544			left = scrollSize.scrollWidth - floatWidth - dxShadow;
1545
1546		var scrollHeight = Math.max(
1547			document.body.scrollHeight, document.documentElement.scrollHeight,
1548			document.body.offsetHeight, document.documentElement.offsetHeight,
1549			document.body.clientHeight, document.documentElement.clientHeight,
1550			scrollSize.scrollHeight
1551		);
1552
1553		if (top > (scrollHeight - floatHeight - dxShadow))
1554			top = scrollHeight - floatHeight - dxShadow;
1555
1556		//Top side
1557		if (top < 0)
1558			top = 0;
1559	}
1560
1561	this.DIV.style.left = left+'px';
1562	this.DIV.style.top = top+'px';
1563
1564	//this.AdjustShadow(div);
1565};
1566
1567BX.CWindow.prototype.__startDrag = function(e)
1568{
1569	if (!this.SETTINGS.draggable)
1570		return false;
1571
1572	if(!e) e = window.event;
1573
1574	this.x = e.clientX + document.body.scrollLeft;
1575	this.y = e.clientY + document.body.scrollTop;
1576
1577	this.__bWasDragged = false;
1578	BX.bind(document, "mousemove", BX.proxy(this.__moveDrag, this));
1579	BX.bind(document, "mouseup", BX.proxy(this.__stopDrag, this));
1580
1581	if(document.body.setCapture)
1582		document.body.setCapture();
1583
1584	document.onmousedown = BX.False;
1585
1586	var b = document.body;
1587	b.ondrag = b.onselectstart = BX.False;
1588	b.style.MozUserSelect = this.DIV.style.MozUserSelect = 'none';
1589	b.style.cursor = 'move';
1590	return BX.PreventDefault(e);
1591};
1592
1593BX.CWindow.prototype.__moveDrag = function(e)
1594{
1595	if(!e) e = window.event;
1596
1597	var x = e.clientX + document.body.scrollLeft;
1598	var y = e.clientY + document.body.scrollTop;
1599
1600	if(this.x == x && this.y == y)
1601		return;
1602
1603	this.Move((x - this.x), (y - this.y));
1604	this.x = x;
1605	this.y = y;
1606
1607	if (!this.__bWasDragged)
1608	{
1609		BX.onCustomEvent(this, 'onWindowDragStart');
1610		this.__bWasDragged = true;
1611		BX.bind(BX.proxy_context, "click", BX.PreventDefault);
1612	}
1613
1614	BX.onCustomEvent(this, 'onWindowDrag');
1615};
1616
1617BX.CWindow.prototype.__stopDrag = function(e)
1618{
1619	if(document.body.releaseCapture)
1620		document.body.releaseCapture();
1621
1622	BX.unbind(document, "mousemove", BX.proxy(this.__moveDrag, this));
1623	BX.unbind(document, "mouseup", BX.proxy(this.__stopDrag, this));
1624
1625	document.onmousedown = null;
1626
1627	var b = document.body;
1628	b.ondrag = b.onselectstart = null;
1629	b.style.MozUserSelect = this.DIV.style.MozUserSelect = '';
1630	b.style.cursor = '';
1631
1632	if (this.__bWasDragged)
1633	{
1634		BX.onCustomEvent(this, 'onWindowDragFinished');
1635		var _proxy_context = BX.proxy_context;
1636		setTimeout(function(){BX.unbind(_proxy_context, "click", BX.PreventDefault)}, 100);
1637		this.__bWasDragged = false;
1638	}
1639	return BX.PreventDefault(e);
1640};
1641
1642BX.CWindow.prototype.DenyClose = function()
1643{
1644	this.denyClose = true;
1645};
1646
1647BX.CWindow.prototype.AllowClose = function()
1648{
1649	this.denyClose = false;
1650};
1651
1652BX.CWindow.prototype.ShowError = function(str)
1653{
1654	BX.onCustomEvent(this, 'onWindowError', [str]);
1655
1656	if (this._wait)
1657		BX.closeWait(this._wait);
1658
1659	window.alert(str);
1660};
1661
1662BX.CWindow.prototype.__set_msover = function() {this.MOUSEOVER = true;};
1663BX.CWindow.prototype.__unset_msover = function() {this.MOUSEOVER = false;};
1664
1665/* dialog window class extends window class */
1666BX.CWindowDialog = function() {
1667	var a = arguments;
1668	a[1] = 'dialog';
1669	BX.CWindowDialog.superclass.constructor.apply(this, a);
1670
1671	this.DIV.style.top = '10px';
1672	this.OVERLAY = null;
1673};
1674BX.extend(BX.CWindowDialog, BX.CWindow);
1675
1676BX.CWindowDialog.prototype.__resizeOverlay = function()
1677{
1678	var windowSize = BX.GetWindowScrollSize();
1679	this.OVERLAY.style.width = windowSize.scrollWidth + "px";
1680};
1681
1682BX.CWindowDialog.prototype.CreateOverlay = function(zIndex)
1683{
1684	if (null == this.OVERLAY)
1685	{
1686		var windowSize = BX.GetWindowScrollSize();
1687
1688		// scrollHeight in BX.GetWindowScrollSize may be incorrect
1689		var scrollHeight = Math.max(
1690			document.body.scrollHeight, document.documentElement.scrollHeight,
1691			document.body.offsetHeight, document.documentElement.offsetHeight,
1692			document.body.clientHeight, document.documentElement.clientHeight,
1693			windowSize.scrollHeight
1694		);
1695
1696		this.OVERLAY = document.body.appendChild(BX.create("DIV", {
1697			style: {
1698				position: 'absolute',
1699				top: '0px',
1700				left: '0px',
1701				zIndex: zIndex || (parseInt(this.DIV.style.zIndex)-2),
1702				width: windowSize.scrollWidth + "px",
1703				height: scrollHeight + "px"
1704			}
1705		}));
1706
1707		var component = BX.ZIndexManager.getComponent(this.DIV);
1708		if (component)
1709		{
1710			component.setOverlay(this.OVERLAY);
1711		}
1712	}
1713
1714	return this.OVERLAY;
1715};
1716
1717BX.CWindowDialog.prototype.Show = function()
1718{
1719	BX.CWindowDialog.superclass.Show.apply(this, arguments);
1720
1721	this.CreateOverlay();
1722
1723	this.OVERLAY.style.display = 'block';
1724
1725	BX.unbind(window, 'resize', BX.proxy(this.__resizeOverlay, this));
1726	BX.bind(window, 'resize', BX.proxy(this.__resizeOverlay, this));
1727};
1728
1729BX.CWindowDialog.prototype.onUnRegister = function(clean)
1730{
1731	BX.CWindowDialog.superclass.onUnRegister.apply(this, arguments);
1732
1733	if (this.clean)
1734	{
1735		if (this.OVERLAY.parentNode)
1736			this.OVERLAY.parentNode.removeChild(this.OVERLAY);
1737	}
1738	else
1739	{
1740		this.OVERLAY.style.display = 'none';
1741	}
1742
1743	BX.unbind(window, 'resize', BX.proxy(this.__resizeOverlay, this));
1744};
1745
1746/* standard bitrix dialog extends BX.CWindowDialog */
1747/*
1748	arParams = {
1749		(
1750			title: 'dialog title',
1751			head: 'head block html',
1752			content: 'dialog content',
1753			icon: 'head icon classname or filename',
1754
1755			resize_id: 'some id to save resize information'// useless if resizable = false
1756		)
1757		or
1758		(
1759			content_url: url to content load
1760				loaded content scripts can use BX.WindowManager.Get() to get access to the current window object
1761		)
1762
1763		height: window_height_in_pixels,
1764		width: window_width_in_pixels,
1765
1766		draggable: true|false,
1767		resizable: true|false,
1768
1769		min_height: min_window_height_in_pixels, // useless if resizable = false
1770		min_width: min_window_width_in_pixels, // useless if resizable = false
1771
1772		buttons: [
1773			'html_code',
1774			BX.CDialog.btnSave, BX.CDialog.btnCancel, BX.CDialog.btnClose
1775		]
1776	}
1777*/
1778BX.CDialog = function(arParams)
1779{
1780	BX.CDialog.superclass.constructor.apply(this);
1781
1782	this._sender = 'core_window_cdialog';
1783
1784	this.PARAMS = arParams || {};
1785
1786	for (var i in this.defaultParams)
1787	{
1788		if (typeof this.PARAMS[i] == 'undefined')
1789			this.PARAMS[i] = this.defaultParams[i];
1790	}
1791
1792	this.PARAMS.width = (!isNaN(parseInt(this.PARAMS.width)))
1793		? this.PARAMS.width
1794		: this.defaultParams['width'];
1795	this.PARAMS.height = (!isNaN(parseInt(this.PARAMS.height)))
1796		? this.PARAMS.height
1797		: this.defaultParams['height'];
1798
1799	if (this.PARAMS.resize_id || this.PARAMS.content_url)
1800	{
1801		var arSize = BX.WindowManager.getRuntimeWindowSize(this.PARAMS.resize_id || this.PARAMS.content_url);
1802		if (arSize)
1803		{
1804			this.PARAMS.width = arSize.width;
1805			this.PARAMS.height = arSize.height;
1806		}
1807	}
1808
1809	BX.addClass(this.DIV, 'bx-core-adm-dialog');
1810	this.DIV.id = 'bx-admin-prefix';
1811
1812	this.PARTS = {};
1813
1814	this.DIV.style.height = null;
1815	this.DIV.style.width = null;
1816
1817	this.PARTS.TITLEBAR = this.DIV.appendChild(BX.create('DIV', {props: {
1818			className: 'bx-core-adm-dialog-head'
1819		}
1820	}));
1821
1822	this.PARTS.TITLE_CONTAINER = this.PARTS.TITLEBAR.appendChild(BX.create('SPAN', {
1823		props: {className: 'bx-core-adm-dialog-head-inner'},
1824		text: this.PARAMS.title
1825	}));
1826
1827	this.PARTS.TITLEBAR_ICONS = this.PARTS.TITLEBAR.appendChild(BX.create('DIV', {
1828		props: {
1829			className: 'bx-core-adm-dialog-head-icons'
1830		},
1831		children: (this.PARAMS.resizable ? [
1832			BX.create('SPAN', {props: {className: 'bx-core-adm-icon-expand', title: BX.message('JS_CORE_WINDOW_EXPAND')}}),
1833			BX.create('SPAN', {props: {className: 'bx-core-adm-icon-close', title: BX.message('JS_CORE_WINDOW_CLOSE')}})
1834		] : [
1835			BX.create('SPAN', {props: {className: 'bx-core-adm-icon-close', title: BX.message('JS_CORE_WINDOW_CLOSE')}})
1836		])
1837	}));
1838
1839
1840	this.PARTS.CONTENT = this.DIV.appendChild(BX.create('DIV', {
1841		props: {className: 'bx-core-adm-dialog-content-wrap adm-workarea'}
1842	}));
1843
1844	this.PARTS.CONTENT_DATA = this.PARTS.CONTENT.appendChild(BX.create('DIV', {
1845		props: {className: 'bx-core-adm-dialog-content'},
1846		style: {
1847			height: this.PARAMS.height + 'px',
1848			width: this.PARAMS.width + 'px'
1849		}
1850	}));
1851
1852	this.PARTS.HEAD = this.PARTS.CONTENT_DATA.appendChild(BX.create('DIV', {
1853		props: {
1854			className: 'bx-core-adm-dialog-head-block' + (this.PARAMS.icon ? ' ' + this.PARAMS.icon : '')
1855		}
1856	}));
1857
1858	this.SetHead(this.PARAMS.head);
1859	this.SetContent(this.PARAMS.content);
1860	this.SetTitle(this.PARAMS.title);
1861	this.SetClose(this.PARTS.TITLEBAR_ICONS.lastChild);
1862
1863	if (this.PARAMS.resizable)
1864	{
1865		this.SetExpand(this.PARTS.TITLEBAR_ICONS.firstChild);
1866		this.SetExpand(this.PARTS.TITLEBAR, 'dblclick');
1867
1868		BX.addCustomEvent(this, 'onWindowExpand', BX.proxy(this.__onexpand, this));
1869		BX.addCustomEvent(this, 'onWindowNarrow', BX.proxy(this.__onexpand, this));
1870	}
1871
1872	this.PARTS.FOOT = this.PARTS.BUTTONS_CONTAINER = this.PARTS.CONTENT.appendChild(BX.create('DIV', {
1873			props: {
1874				className: 'bx-core-adm-dialog-buttons'
1875			},
1876			//events: {
1877			//	'click': BX.delegateEvent({property:{type: /button|submit/}}, BX.delegate(function() {this.showWait(BX.proxy_context)}, this))
1878			//},
1879			children: this.ShowButtons()
1880		}
1881	));
1882
1883	if (this.PARAMS.draggable)
1884		this.SetDraggable(this.PARTS.TITLEBAR);
1885
1886	if (this.PARAMS.resizable)
1887	{
1888		this.PARTS.RESIZER = this.DIV.appendChild(BX.create('DIV', {
1889			props: {className: 'bx-core-resizer'}
1890		}));
1891
1892		this.SetResize(this.PARTS.RESIZER);
1893
1894		this.SETTINGS.min_width = this.PARAMS.min_width;
1895		this.SETTINGS.min_height = this.PARAMS.min_height;
1896	}
1897
1898	this.auth_callback = BX.delegate(function(){
1899		this.PARAMS.content = '';
1900		this.hideNotify();
1901		this.Show();
1902	}, this)
1903};
1904BX.extend(BX.CDialog, BX.CWindowDialog);
1905
1906BX.CDialog.prototype.defaultParams = {
1907	width: 700,
1908	height: 400,
1909	min_width: 500,
1910	min_height: 300,
1911
1912	resizable: true,
1913	draggable: true,
1914
1915	title: '',
1916	icon: ''
1917};
1918
1919BX.CDialog.prototype.showWait = function(el)
1920{
1921	if (BX.type.isElementNode(el) && (el.type == 'button' || el.type == 'submit'))
1922	{
1923		BX.defer(function(){el.disabled = true})();
1924
1925		var bSave = (BX.hasClass(el, 'adm-btn-save') || BX.hasClass(el, 'adm-btn-save')),
1926			pos = BX.pos(el, true);
1927
1928		el.bxwaiter = this.PARTS.FOOT.appendChild(BX.create('DIV', {
1929			props: {className: 'adm-btn-load-img' + (bSave ? '-green' : '')},
1930			style: {
1931				top: parseInt((pos.bottom + pos.top)/2 - 10) + 'px',
1932				left: parseInt((pos.right + pos.left)/2 - 10) + 'px'
1933			}
1934		}));
1935
1936		BX.addClass(el, 'adm-btn-load');
1937
1938		this.lastWaitElement = el;
1939
1940		return el.bxwaiter;
1941	}
1942	return null;
1943};
1944
1945BX.CDialog.prototype.closeWait = function(el)
1946{
1947	el = el || this.lastWaitElement;
1948
1949	if (BX.type.isElementNode(el))
1950	{
1951		if (el.bxwaiter)
1952		{
1953			if(el.bxwaiter.parentNode)
1954			{
1955				el.bxwaiter.parentNode.removeChild(el.bxwaiter);
1956			}
1957
1958			el.bxwaiter = null;
1959		}
1960
1961		el.disabled = false;
1962		BX.removeClass(el, 'adm-btn-load');
1963
1964		if (this.lastWaitElement == el)
1965			this.lastWaitElement = null;
1966	}
1967};
1968
1969BX.CDialog.prototype.Authorize = function(arAuthResult)
1970{
1971	this.bSkipReplaceContent = true;
1972	this.ShowError(BX.message('JSADM_AUTH_REQ'));
1973
1974	BX.onCustomEvent(this, 'onWindowError', []);
1975
1976	BX.closeWait();
1977
1978	(new BX.CAuthDialog({
1979		content_url: this.PARAMS.content_url,
1980		auth_result: arAuthResult,
1981		callback: BX.delegate(function(){
1982			if (this.auth_callback)
1983				this.auth_callback()
1984		}, this)
1985	})).Show();
1986};
1987
1988BX.CDialog.prototype.ShowError = function(str)
1989{
1990	BX.onCustomEvent(this, 'onWindowError', [str]);
1991
1992	this.closeWait();
1993
1994	if (this._wait)
1995		BX.closeWait(this._wait);
1996
1997	this.Notify(str, true);
1998};
1999
2000
2001BX.CDialog.prototype.__expandGetSize = function()
2002{
2003	var pDocElement = BX.GetDocElement();
2004	pDocElement.style.overflow = 'hidden';
2005
2006	var wndSize = BX.GetWindowInnerSize();
2007
2008	pDocElement.scrollTop = 0;
2009
2010	this.DIV.style.top = '-' + this.dxShadow + 'px';
2011	this.DIV.style.left = '-' + this.dxShadow + 'px';
2012
2013	return {
2014		width: (wndSize.innerWidth - parseInt(BX.style(this.PARTS.CONTENT, 'padding-right')) - parseInt(BX.style(this.PARTS.CONTENT, 'padding-left'))) + this.dxShadow,
2015		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
2016	};
2017};
2018
2019BX.CDialog.prototype.__expand = function()
2020{
2021	var pDocElement = BX.GetDocElement();
2022	this.dxShadow = 2;
2023
2024	if (!this.bExpanded)
2025	{
2026		var wndScroll = BX.GetWindowScrollPos();
2027
2028		this.__expand_settings = {
2029			resizable: this.SETTINGS.resizable,
2030			draggable: this.SETTINGS.draggable,
2031			width: this.PARTS.CONTENT_DATA.style.width,
2032			height: this.PARTS.CONTENT_DATA.style.height,
2033			left: this.DIV.style.left,
2034			top: this.DIV.style.top,
2035			scrollTop: wndScroll.scrollTop,
2036			scrollLeft: wndScroll.scrollLeft,
2037			overflow: BX.style(pDocElement, 'overflow')
2038		};
2039
2040		this.SETTINGS.resizable = false;
2041		this.SETTINGS.draggable = false;
2042
2043		var pos = this.__expandGetSize();
2044
2045		this.PARTS.CONTENT_DATA.style.width = pos.width + 'px';
2046		this.PARTS.CONTENT_DATA.style.height = pos.height + 'px';
2047
2048		window.scrollTo(0,0);
2049		pDocElement.style.overflow = 'hidden';
2050
2051		this.bExpanded = true;
2052
2053		BX.onCustomEvent(this, 'onWindowExpand');
2054		BX.onCustomEvent(this, 'onWindowResize');
2055		BX.onCustomEvent(this, 'onWindowResizeExt', [{'width': pos.width, 'height': pos.height}]);
2056
2057		BX.bind(window, 'resize', BX.proxy(this.__expand_onresize, this));
2058	}
2059	else
2060	{
2061		BX.unbind(window, 'resize', BX.proxy(this.__expand_onresize, this));
2062
2063		this.SETTINGS.resizable = this.__expand_settings.resizable;
2064		this.SETTINGS.draggable = this.__expand_settings.draggable;
2065
2066		pDocElement.style.overflow = this.__expand_settings.overflow;
2067
2068		this.DIV.style.top = this.__expand_settings.top;
2069		this.DIV.style.left = this.__expand_settings.left;
2070		this.PARTS.CONTENT_DATA.style.width = this.__expand_settings.width;
2071		this.PARTS.CONTENT_DATA.style.height = this.__expand_settings.height;
2072		window.scrollTo(this.__expand_settings.scrollLeft, this.__expand_settings.scrollTop);
2073		this.bExpanded = false;
2074
2075		BX.onCustomEvent(this, 'onWindowNarrow');
2076		BX.onCustomEvent(this, 'onWindowResize');
2077		BX.onCustomEvent(this, 'onWindowResizeExt', [{'width': parseInt(this.__expand_settings.width), 'height': parseInt(this.__expand_settings.height)}]);
2078	}
2079};
2080
2081BX.CDialog.prototype.__expand_onresize = function()
2082{
2083	var pos = this.__expandGetSize();
2084
2085	this.PARTS.CONTENT_DATA.style.width = pos.width + 'px';
2086	this.PARTS.CONTENT_DATA.style.height = pos.height + 'px';
2087
2088	BX.onCustomEvent(this, 'onWindowResize');
2089	BX.onCustomEvent(this, 'onWindowResizeExt', [pos]);
2090};
2091
2092BX.CDialog.prototype.__onexpand = function()
2093{
2094	var ob = this.PARTS.TITLEBAR_ICONS.firstChild;
2095	ob.className = BX.toggle(ob.className, ['bx-core-adm-icon-expand', 'bx-core-adm-icon-narrow']);
2096	ob.title = BX.toggle(ob.title, [BX.message('JS_CORE_WINDOW_EXPAND'), BX.message('JS_CORE_WINDOW_NARROW')]);
2097
2098	if (this.PARTS.RESIZER)
2099	{
2100		this.PARTS.RESIZER.style.display = this.bExpanded ? 'none' : 'block';
2101	}
2102};
2103
2104
2105BX.CDialog.prototype.__startResize = function(e)
2106{
2107	if (!this.SETTINGS.resizable)
2108		return false;
2109
2110	if(!e) e = window.event;
2111
2112	this.wndSize = BX.GetWindowScrollPos();
2113	this.wndSize.innerWidth = BX.GetWindowInnerSize().innerWidth;
2114
2115	this.pos = BX.pos(this.PARTS.CONTENT_DATA);
2116
2117	this.x = e.clientX + this.wndSize.scrollLeft;
2118	this.y = e.clientY + this.wndSize.scrollTop;
2119
2120	this.dx = this.pos.left + this.pos.width - this.x;
2121	this.dy = this.pos.top + this.pos.height - this.y;
2122
2123
2124	// TODO: suspicious
2125	this.dw = this.pos.width - parseInt(this.PARTS.CONTENT_DATA.style.width) + parseInt(BX.style(this.PARTS.CONTENT, 'padding-right'));
2126
2127	BX.bind(document, "mousemove", BX.proxy(this.__moveResize, this));
2128	BX.bind(document, "mouseup", BX.proxy(this.__stopResize, this));
2129
2130	if(document.body.setCapture)
2131		document.body.setCapture();
2132
2133	document.onmousedown = BX.False;
2134
2135	var b = document.body;
2136	b.ondrag = b.onselectstart = BX.False;
2137	b.style.MozUserSelect = this.DIV.style.MozUserSelect = 'none';
2138	b.style.cursor = 'se-resize';
2139
2140	BX.onCustomEvent(this, 'onWindowResizeStart');
2141
2142	return true;
2143};
2144
2145BX.CDialog.prototype.Resize = function(x, y)
2146{
2147	var new_width = Math.max(x - this.pos.left + this.dx, this.SETTINGS.min_width);
2148	var new_height = Math.max(y - this.pos.top + this.dy, this.SETTINGS.min_height);
2149
2150	if (this.SETTINGS.resize_restrict)
2151	{
2152		var scrollSize = BX.GetWindowScrollSize();
2153
2154		if (this.pos.left + new_width > scrollSize.scrollWidth - this.dw)
2155			new_width = scrollSize.scrollWidth - this.pos.left - this.dw;
2156	}
2157
2158	this.PARTS.CONTENT_DATA.style.width = new_width + 'px';
2159	this.PARTS.CONTENT_DATA.style.height = new_height + 'px';
2160
2161	BX.onCustomEvent(this, 'onWindowResize');
2162	BX.onCustomEvent(this, 'onWindowResizeExt', [{'height': new_height, 'width': new_width}]);
2163};
2164
2165BX.CDialog.prototype.SetSize = function(obSize)
2166{
2167	this.PARTS.CONTENT_DATA.style.width = obSize.width + 'px';
2168	this.PARTS.CONTENT_DATA.style.height = obSize.height + 'px';
2169
2170	BX.onCustomEvent(this, 'onWindowResize');
2171	BX.onCustomEvent(this, 'onWindowResizeExt', [obSize]);
2172};
2173
2174BX.CDialog.prototype.GetParameters = function(form_name)
2175{
2176	var form = this.GetForm();
2177
2178	if(!form)
2179		return "";
2180
2181	var i, s = "";
2182	var n = form.elements.length;
2183
2184	var delim = '';
2185	for(i=0; i<n; i++)
2186	{
2187		if (s != '') delim = '&';
2188		var el = form.elements[i];
2189		if (el.disabled)
2190			continue;
2191
2192		switch(el.type.toLowerCase())
2193		{
2194			case 'text':
2195			case 'textarea':
2196			case 'password':
2197			case 'hidden':
2198				if (null == form_name && el.name.substr(el.name.length-4) == '_alt' && form.elements[el.name.substr(0, el.name.length-4)])
2199					break;
2200				s += delim + el.name + '=' + BX.util.urlencode(el.value);
2201				break;
2202			case 'radio':
2203				if(el.checked)
2204					s += delim + el.name + '=' + BX.util.urlencode(el.value);
2205				break;
2206			case 'checkbox':
2207				s += delim + el.name + '=' + BX.util.urlencode(el.checked ? 'Y':'N');
2208				break;
2209			case 'select-one':
2210				var val = "";
2211				if (null == form_name && form.elements[el.name + '_alt'] && el.selectedIndex == 0)
2212					val = form.elements[el.name+'_alt'].value;
2213				else
2214					val = el.value;
2215				s += delim + el.name + '=' + BX.util.urlencode(val);
2216				break;
2217			case 'select-multiple':
2218				var j, bAdded = false;
2219				var l = el.options.length;
2220				for (j=0; j<l; j++)
2221				{
2222					if (el.options[j].selected)
2223					{
2224						s += delim + el.name + '=' + BX.util.urlencode(el.options[j].value);
2225						bAdded = true;
2226					}
2227				}
2228				if (!bAdded)
2229					s += delim + el.name + '=';
2230				break;
2231			default:
2232				break;
2233		}
2234	}
2235
2236	return s;
2237};
2238
2239BX.CDialog.prototype.PostParameters = function(params)
2240{
2241	var url = this.PARAMS.content_url;
2242
2243	if (null == params)
2244		params = "";
2245
2246	params += (params == "" ? "" : "&") + "bxsender=" + this._sender;
2247
2248	var index = url.indexOf('?');
2249	if (index == -1)
2250		url += '?' + params;
2251	else
2252		url = url.substring(0, index) + '?' + params + "&" + url.substring(index+1);
2253
2254	BX.showWait();
2255
2256	this.auth_callback = BX.delegate(function(){
2257		this.hideNotify();
2258		this.PostParameters(params);
2259	}, this);
2260
2261	BX.ajax.Setup({skipAuthCheck:true},true);
2262	BX.ajax.post(url, this.GetParameters(), BX.delegate(function(result) {
2263		BX.closeWait();
2264		if (!this.bSkipReplaceContent)
2265		{
2266			this.ClearButtons(); // buttons are appended during form reload, so we should clear footer
2267			this.SetContent(result);
2268			this.Show(true);
2269		}
2270
2271		this.bSkipReplaceContent = false;
2272	}, this));
2273};
2274
2275BX.CDialog.prototype.Submit = function(params, url)
2276{
2277	var FORM = this.GetForm();
2278	if (FORM)
2279	{
2280		FORM.onsubmit = null;
2281
2282		FORM.method = 'POST';
2283		if (!FORM.action || url)
2284		{
2285			url = url || this.PARAMS.content_url;
2286			if (null != params)
2287			{
2288				var index = url.indexOf('?');
2289				if (index == -1)
2290					url += '?' + params;
2291				else
2292					url = url.substring(0, index) + '?' + params + "&" + url.substring(index+1);
2293			}
2294
2295			FORM.action = url;
2296		}
2297
2298		if (!FORM._bxsender)
2299		{
2300			FORM._bxsender = FORM.appendChild(BX.create('INPUT', {
2301				attrs: {
2302					type: 'hidden',
2303					name: 'bxsender',
2304					value: this._sender
2305				}
2306			}));
2307		}
2308
2309		this._wait = BX.showWait();
2310
2311		this.auth_callback = BX.delegate(function(){
2312			this.hideNotify();
2313			this.Submit(params);
2314		}, this);
2315
2316		BX.ajax.submit(FORM, BX.delegate(function(){this.closeWait()}, this));
2317	}
2318	else
2319	{
2320		window.alert('no form registered!');
2321	}
2322};
2323
2324BX.CDialog.prototype.GetForm = function()
2325{
2326	if (null == this.__form)
2327	{
2328		var forms = this.PARTS.CONTENT_DATA.getElementsByTagName('FORM');
2329		this.__form = forms[0] ? forms[0] : null;
2330	}
2331
2332	return this.__form;
2333};
2334
2335BX.CDialog.prototype.GetRealForm = function()
2336{
2337	if (null == this.__rform)
2338	{
2339		var forms = this.PARTS.CONTENT_DATA.getElementsByTagName('FORM');
2340		this.__rform = forms[1] ? forms[1] : (forms[0] ? forms[0] : null);
2341	}
2342
2343	return this.__rform;
2344};
2345
2346BX.CDialog.prototype._checkButton = function(btn)
2347{
2348	var arCustomButtons = ['btnSave', 'btnCancel', 'btnClose'];
2349
2350	for (var i = 0; i < arCustomButtons.length; i++)
2351	{
2352		if (this[arCustomButtons[i]] && (btn == this[arCustomButtons[i]]))
2353			return arCustomButtons[i];
2354	}
2355
2356	return false;
2357};
2358
2359BX.CDialog.prototype.ShowButtons = function()
2360{
2361	var result = [];
2362	if (this.PARAMS.buttons)
2363	{
2364		if (this.PARAMS.buttons.title) this.PARAMS.buttons = [this.PARAMS.buttons];
2365
2366		for (var i=0, len=this.PARAMS.buttons.length; i<len; i++)
2367		{
2368			if (BX.type.isNotEmptyString(this.PARAMS.buttons[i]))
2369			{
2370				result.push(this.PARAMS.buttons[i]);
2371			}
2372			else if (BX.type.isElementNode(this.PARAMS.buttons[i]))
2373			{
2374				result.push(this.PARAMS.buttons[i]);
2375			}
2376			else if (this.PARAMS.buttons[i])
2377			{
2378				//if (!(this.PARAMS.buttons[i] instanceof BX.CWindowButton))
2379				if (!BX.is_subclass_of(this.PARAMS.buttons[i], BX.CWindowButton))
2380				{
2381					var b = this._checkButton(this.PARAMS.buttons[i]); // hack to set links to real CWindowButton object in btnSave etc;
2382					this.PARAMS.buttons[i] = new BX.CWindowButton(this.PARAMS.buttons[i]);
2383					if (b) this[b] = this.PARAMS.buttons[i];
2384				}
2385
2386				result.push(this.PARAMS.buttons[i].Button(this));
2387			}
2388		}
2389	}
2390
2391	return result;
2392};
2393
2394BX.CDialog.prototype.setAutosave = function () {
2395	if (!this.bSetAutosaveDelay)
2396	{
2397		this.bSetAutosaveDelay = true;
2398		setTimeout(BX.proxy(this.setAutosave, this), 10);
2399	}
2400};
2401
2402BX.CDialog.prototype.SetTitle = function(title)
2403{
2404	this.PARAMS.title = title;
2405	BX.cleanNode(this.PARTS.TITLE_CONTAINER).appendChild(document.createTextNode(this.PARAMS.title));
2406};
2407
2408BX.CDialog.prototype.SetHead = function(head)
2409{
2410	this.PARAMS.head = BX.util.trim(head);
2411	this.PARTS.HEAD.innerHTML = this.PARAMS.head || "&nbsp;";
2412	this.PARTS.HEAD.style.display = this.PARAMS.head ? 'block' : 'none';
2413	this.adjustSize();
2414};
2415
2416BX.CDialog.prototype.Notify = function(note, bError, html)
2417{
2418	if (!this.PARTS.NOTIFY)
2419	{
2420		this.PARTS.NOTIFY = this.DIV.insertBefore(BX.create('DIV', {
2421			props: {className: 'adm-warning-block'},
2422			children: [
2423				BX.create('SPAN', {
2424					props: {className: 'adm-warning-text'}
2425				}),
2426				BX.create('SPAN', {
2427					props: {className: 'adm-warning-icon'}
2428				}),
2429				BX.create('SPAN', {
2430					props: {className: 'adm-warning-close'},
2431					events: {click: BX.proxy(this.hideNotify, this)}
2432				})
2433			]
2434		}), this.DIV.firstChild);
2435	}
2436
2437	if (bError)
2438		BX.addClass(this.PARTS.NOTIFY, 'adm-warning-block-red');
2439	else
2440		BX.removeClass(this.PARTS.NOTIFY, 'adm-warning-block-red');
2441
2442	if(html !== true)
2443	{
2444		note = BX.util.htmlspecialchars(note);
2445	}
2446
2447	this.PARTS.NOTIFY.firstChild.innerHTML = note || '&nbsp;';
2448	this.PARTS.NOTIFY.firstChild.style.width = (this.PARAMS.width-50) + 'px';
2449	BX.removeClass(this.PARTS.NOTIFY, 'adm-warning-animate');
2450};
2451
2452BX.CDialog.prototype.hideNotify = function()
2453{
2454	BX.addClass(this.PARTS.NOTIFY, 'adm-warning-animate');
2455};
2456
2457BX.CDialog.prototype.__adjustHeadToIcon = function()
2458{
2459	if (!this.PARTS.HEAD.offsetHeight)
2460	{
2461		setTimeout(BX.delegate(this.__adjustHeadToIcon, this), 50);
2462	}
2463	else
2464	{
2465		if (this.icon_image && this.icon_image.height && this.icon_image.height > this.PARTS.HEAD.offsetHeight - 5)
2466		{
2467			this.PARTS.HEAD.style.height = this.icon_image.height + 5 + 'px';
2468			this.adjustSize();
2469		}
2470
2471		this.icon_image.onload = null;
2472		this.icon_image = null;
2473	}
2474};
2475
2476BX.CDialog.prototype.SetIcon = function(icon_class)
2477{
2478	if (this.PARAMS.icon != icon_class)
2479	{
2480		if (this.PARAMS.icon)
2481			BX.removeClass(this.PARTS.HEAD, this.PARAMS.icon);
2482
2483		this.PARAMS.icon = icon_class;
2484
2485		if (this.PARAMS.icon)
2486		{
2487			BX.addClass(this.PARTS.HEAD, this.PARAMS.icon);
2488
2489			var icon_file = (BX.style(this.PARTS.HEAD, 'background-image') || BX.style(this.PARTS.HEAD, 'backgroundImage'));
2490			if (BX.type.isNotEmptyString(icon_file) && icon_file != 'none')
2491			{
2492				var match = icon_file.match(new RegExp('url\\s*\\(\\s*(\'|"|)(.+?)(\\1)\\s*\\)'));
2493				if(match)
2494				{
2495					icon_file = match[2];
2496					if (BX.type.isNotEmptyString(icon_file))
2497					{
2498						this.icon_image = new Image();
2499						this.icon_image.onload = BX.delegate(this.__adjustHeadToIcon, this);
2500						this.icon_image.src = icon_file;
2501					}
2502				}
2503			}
2504		}
2505	}
2506	this.adjustSize();
2507};
2508
2509BX.CDialog.prototype.SetIconFile = function(icon_file)
2510{
2511	this.icon_image = new Image();
2512	this.icon_image.onload = BX.delegate(this.__adjustHeadToIcon, this);
2513	this.icon_image.src = icon_file;
2514
2515	BX.adjust(this.PARTS.HEAD, {style: {backgroundImage: 'url(' + icon_file + ')', backgroundPosition: 'right 9px'/*'99% center'*/}});
2516	this.adjustSize();
2517};
2518
2519/*
2520BUTTON: {
2521	title: 'title',
2522	'action': function executed in window object context
2523}
2524BX.CDialog.btnSave || BX.CDialog.btnCancel - standard buttons
2525*/
2526
2527BX.CDialog.prototype.SetButtons = function(a)
2528{
2529	if (BX.type.isString(a))
2530	{
2531		if (a.length > 0)
2532		{
2533			this.PARTS.BUTTONS_CONTAINER.innerHTML += a;
2534
2535			var btns = this.PARTS.BUTTONS_CONTAINER.getElementsByTagName('INPUT');
2536			if (btns.length > 0)
2537			{
2538				this.PARAMS.buttons = [];
2539				for (var i = 0; i < btns.length; i++)
2540				{
2541					this.PARAMS.buttons.push(new BX.CWindowButton({btn: btns[i], parentWindow: this}));
2542				}
2543			}
2544		}
2545	}
2546	else
2547	{
2548		this.PARAMS.buttons = a;
2549		BX.adjust(this.PARTS.BUTTONS_CONTAINER, {
2550			children: this.ShowButtons()
2551		});
2552	}
2553	this.adjustSize();
2554};
2555
2556BX.CDialog.prototype.ClearButtons = function()
2557{
2558	BX.cleanNode(this.PARTS.BUTTONS_CONTAINER);
2559	this.adjustSize();
2560};
2561
2562BX.CDialog.prototype.SetContent = function(html)
2563{
2564	this.__form = null;
2565
2566	if (BX.type.isElementNode(html))
2567	{
2568		if (html.parentNode)
2569			html.parentNode.removeChild(html);
2570	}
2571	else if (BX.type.isString(html))
2572	{
2573		html = BX.create('DIV', {html: html});
2574	}
2575
2576	this.PARAMS.content = html;
2577	BX.cleanNode(this.PARTS.CONTENT_DATA);
2578
2579	BX.adjust(this.PARTS.CONTENT_DATA, {
2580		children: [
2581			this.PARTS.HEAD,
2582			BX.create('DIV', {
2583				props: {
2584					className: 'bx-core-adm-dialog-content-wrap-inner'
2585				},
2586				children: [this.PARAMS.content]
2587			})
2588		]
2589	});
2590
2591	if (this.PARAMS.content_url && this.GetForm())
2592	{
2593		this.__form.submitbtn = this.__form.appendChild(BX.create('INPUT', {props:{type:'submit'},style:{display:'none'}}));
2594		this.__form.onsubmit = BX.delegate(this.__submit, this);
2595	}
2596};
2597
2598BX.CDialog.prototype.__submit = function(e)
2599{
2600	for (var i=0,len=this.PARAMS.buttons.length; i<len; i++)
2601	{
2602		if (
2603			this.PARAMS.buttons[i]
2604			&& (
2605				this.PARAMS.buttons[i].name && /save|apply/i.test(this.PARAMS.buttons[i].name)
2606				||
2607				this.PARAMS.buttons[i].btn && this.PARAMS.buttons[i].btn.name && /save|apply/i.test(this.PARAMS.buttons[i].btn.name)
2608			)
2609		)
2610		{
2611			this.PARAMS.buttons[i].emulate();
2612			break;
2613		}
2614	}
2615
2616	return BX.PreventDefault(e);
2617};
2618
2619BX.CDialog.prototype.SwapContent = function(cont)
2620{
2621	cont = BX(cont);
2622
2623	BX.cleanNode(this.PARTS.CONTENT_DATA);
2624	cont.parentNode.removeChild(cont);
2625	this.PARTS.CONTENT_DATA.appendChild(cont);
2626	cont.style.display = 'block';
2627	this.SetContent(cont.innerHTML);
2628};
2629
2630// this method deprecated
2631BX.CDialog.prototype.adjustSize = function()
2632{
2633};
2634
2635// this method deprecated
2636BX.CDialog.prototype.__adjustSize = function()
2637{
2638};
2639
2640BX.CDialog.prototype.adjustSizeEx = function()
2641{
2642	BX.defer(this.__adjustSizeEx, this)();
2643};
2644
2645BX.CDialog.prototype.__adjustSizeEx = function()
2646{
2647	var ob = this.PARTS.CONTENT_DATA.firstChild,
2648		new_height = 0,
2649		marginTop,
2650		marginBottom;
2651
2652	while (ob)
2653	{
2654		if (BX.type.isElementNode(ob))
2655		{
2656			marginTop = parseInt(BX.style(ob, 'margin-top'), 10);
2657			if (isNaN(marginTop))
2658				marginTop = 0;
2659			marginBottom = parseInt(BX.style(ob, 'margin-bottom'), 10);
2660			if (isNaN(marginBottom))
2661				marginBottom = 0;
2662			new_height += ob.offsetHeight + marginTop + marginBottom;
2663		}
2664		ob = BX.nextSibling(ob);
2665	}
2666
2667	if (new_height)
2668		this.PARTS.CONTENT_DATA.style.height = new_height + 'px';
2669};
2670
2671
2672BX.CDialog.prototype.__onResizeFinished = function()
2673{
2674	BX.WindowManager.saveWindowSize(
2675		this.PARAMS.resize_id || this.PARAMS.content_url, {height: parseInt(this.PARTS.CONTENT_DATA.style.height), width: parseInt(this.PARTS.CONTENT_DATA.style.width)}
2676	);
2677};
2678
2679BX.CDialog.prototype.Show = function(bNotRegister)
2680{
2681	if ((!this.PARAMS.content) && this.PARAMS.content_url && BX.ajax && !bNotRegister)
2682	{
2683		var wait = BX.showWait();
2684
2685		BX.WindowManager.currently_loaded = this;
2686
2687		this.CreateOverlay();
2688		this.OVERLAY.style.display = 'block';
2689		this.OVERLAY.className = 'bx-core-dialog-overlay';
2690
2691		var post_data = '', method = 'GET';
2692		if (this.PARAMS.content_post)
2693		{
2694			post_data = this.PARAMS.content_post;
2695			method = 'POST';
2696		}
2697
2698		var url = this.PARAMS.content_url
2699			+ (this.PARAMS.content_url.indexOf('?')<0?'?':'&')+'bxsender=' + this._sender;
2700
2701		this.auth_callback = BX.delegate(function(){
2702			this.PARAMS.content = '';
2703			this.hideNotify();
2704			this.Show();
2705		}, this);
2706
2707		BX.ajax({
2708			method: method,
2709			dataType: 'html',
2710			url: url,
2711			data: post_data,
2712			skipAuthCheck: true,
2713			onsuccess: BX.delegate(function(data) {
2714				BX.closeWait(null, wait);
2715
2716				this.SetContent(data || '&nbsp;');
2717				this.Show();
2718			}, this)
2719		});
2720	}
2721	else
2722	{
2723		BX.WindowManager.currently_loaded = null;
2724		BX.CDialog.superclass.Show.apply(this, arguments);
2725
2726		this.adjustPos();
2727
2728		this.OVERLAY.className = 'bx-core-dialog-overlay';
2729
2730		this.__adjustSize();
2731
2732		BX.removeCustomEvent(this, 'onWindowResize', BX.proxy(this.__adjustSize, this));
2733		BX.addCustomEvent(this, 'onWindowResize', BX.proxy(this.__adjustSize, this));
2734
2735		if (this.PARAMS.resizable && (this.PARAMS.content_url || this.PARAMS.resize_id))
2736		{
2737			BX.removeCustomEvent(this, 'onWindowResizeFinished', BX.proxy(this.__onResizeFinished, this));
2738			BX.addCustomEvent(this, 'onWindowResizeFinished', BX.proxy(this.__onResizeFinished, this));
2739		}
2740	}
2741};
2742
2743BX.CDialog.prototype.GetInnerPos = function()
2744{
2745	return {'width': parseInt(this.PARTS.CONTENT_DATA.style.width), 'height': parseInt(this.PARTS.CONTENT_DATA.style.height)};
2746};
2747
2748BX.CDialog.prototype.adjustPos = function()
2749{
2750	if (!this.bExpanded)
2751	{
2752		var currentWindow = window;
2753		var topWindow = BX.PageObject.getRootWindow();
2754		if (topWindow.BX.SidePanel && topWindow.BX.SidePanel.Instance && topWindow.BX.SidePanel.Instance.getTopSlider())
2755		{
2756			currentWindow = topWindow.BX.SidePanel.Instance.getTopSlider().getWindow();
2757		}
2758		var windowSize = currentWindow.BX.GetWindowInnerSize();
2759		var windowScroll = currentWindow.BX.GetWindowScrollPos();
2760
2761		var style = {
2762			left: parseInt(windowScroll.scrollLeft + windowSize.innerWidth / 2 - parseInt(this.DIV.offsetWidth) / 2) + 'px',
2763			top: Math.max(parseInt(windowScroll.scrollTop + windowSize.innerHe
2763ight / 2 - parseInt(this.DIV.offsetHeight) / 2), 0) + 'px'
2764		};
2765
2766		BX.adjust(this.DIV, {
2767			style: style
2768		});
2769	}
2770};
2771
2772BX.CDialog.prototype.GetContent = function () {return this.PARTS.CONTENT_DATA};
2773
2774BX.CDialog.prototype.btnSave = BX.CDialog.btnSave = {
2775	title: BX.message('JS_CORE_WINDOW_SAVE'),
2776	id: 'savebtn',
2777	name: 'savebtn',
2778	className: BX.browser.IsIE() && BX.browser.IsDoctype() && !BX.browser.IsIE10() ? '' : 'adm-btn-save',
2779	action: function () {
2780		this.disableUntilError();
2781		this.parentWindow.PostParameters();
2782	}
2783};
2784
2785BX.CDialog.prototype.btnCancel = BX.CDialog.btnCancel = {
2786	title: BX.message('JS_CORE_WINDOW_CANCEL'),
2787	id: 'cancel',
2788	name: 'cancel',
2789	action: function () {
2790		this.parentWindow.Close();
2791	}
2792};
2793
2794BX.CDialog.prototype.btnClose = BX.CDialog.btnClose = {
2795	title: BX.message('JS_CORE_WINDOW_CLOSE'),
2796	id: 'close',
2797	name: 'close',
2798	action: function () {
2799		this.parentWindow.Close();
2800	}
2801};
2802
2803/* special child for admin forms loaded into public page */
2804BX.CAdminDialog = function(arParams)
2805{
2806	BX.CAdminDialog.superclass.constructor.apply(this, arguments);
2807
2808	this._sender = 'core_window_cadmindialog';
2809
2810	BX.addClass(this.DIV, 'bx-core-adm-admin-dialog');
2811
2812	this.PARTS.CONTENT.insertBefore(this.PARTS.HEAD, this.PARTS.CONTENT.firstChild);
2813	this.PARTS.HEAD.className = 'bx-core-adm-dialog-tabs';
2814};
2815BX.extend(BX.CAdminDialog, BX.CDialog);
2816
2817BX.CAdminDialog.prototype.SetHead = function()
2818{
2819	BX.CAdminDialog.superclass.SetHead.apply(this, arguments);
2820
2821	if (this.PARTS.HEAD.firstChild && BX.type.isElementNode(this.PARTS.HEAD.firstChild))
2822	{
2823		var ob = this.PARTS.HEAD.firstChild, new_width = 0, marginLeft = 0, marginRight = 0;
2824
2825		while (ob)
2826		{
2827			if (BX.type.isElementNode(ob))
2828			{
2829				marginLeft = parseInt(BX.style(ob, 'margin-left'), 10);
2830				if (isNaN(marginLeft))
2831					marginLeft = 0;
2832				marginRight = parseInt(BX.style(ob, 'margin-right'), 10);
2833				if (isNaN(marginRight))
2834					marginRight = 0;
2835				new_width += ob.offsetWidth + marginLeft + marginRight;
2836			}
2837			ob = BX.nextSibling(ob);
2838		}
2839
2840		this.SETTINGS.min_width = Math.max(new_width, this.SETTINGS.min_width) - 2;
2841		if (this.PARAMS.width < this.SETTINGS.min_width)
2842		{
2843			BX.adjust(this.PARTS.CONTENT_DATA, {
2844				style: {
2845					width: this.SETTINGS.min_width + 'px'
2846				}
2847			});
2848		}
2849	}
2850};
2851
2852BX.CAdminDialog.prototype.SetContent = function(html)
2853{
2854	this.__form = null;
2855
2856	if (BX.type.isElementNode(html))
2857	{
2858		if (html.parentNode)
2859			html.parentNode.removeChild(html);
2860	}
2861
2862	this.PARAMS.content = html;
2863	BX.cleanNode(this.PARTS.CONTENT_DATA);
2864
2865	BX.adjust(this.PARTS.CONTENT_DATA, {
2866		children: [
2867			this.PARAMS.content || '&nbsp;'
2868		]
2869	});
2870
2871	if (this.PARAMS.content_url && this.GetForm())
2872	{
2873		this.__form.appendChild(BX.create('INPUT', {props:{type:'submit'},style:{display:'none'}}));
2874		this.__form.onsubmit = BX.delegate(this.__submit, this);
2875	}
2876};
2877
2878BX.CAdminDialog.prototype.__expandGetSize = function()
2879{
2880	var res = BX.CAdminDialog.superclass.__expandGetSize.apply(this, arguments);
2881
2882	res.width -= parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-right')) + parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-left'));
2883	res.height -= parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-top')) + parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-bottom'));
2884
2885	res.height -= this.PARTS.HEAD.offsetHeight;
2886
2887	return res;
2888};
2889
2890BX.CAdminDialog.prototype.Submit = function()
2891{
2892	var FORM = this.GetForm();
2893	if (FORM && !FORM['bxpublic'] && !/bxpublic=/.test(FORM.action))
2894	{
2895		FORM.appendChild(BX.create('INPUT', {
2896			props: {
2897				type: 'hidden',
2898				name: 'bxpublic',
2899				value: 'Y'
2900			}
2901		}));
2902	}
2903
2904	return BX.CAdminDialog.superclass.Submit.apply(this, arguments);
2905};
2906
2907BX.CAdminDialog.prototype.btnSave = BX.CAdminDialog.btnSave = {
2908	title: BX.message('JS_CORE_WINDOW_SAVE'),
2909	id: 'savebtn',
2910	name: 'savebtn',
2911	className: 'adm-btn-save',
2912	action: function () {
2913		this.disableUntilError();
2914		this.parentWindow.Submit();
2915	}
2916};
2917
2918BX.CAdminDialog.btnCancel = BX.CAdminDialog.superclass.btnCancel;
2919BX.CAdminDialog.btnClose = BX.CAdminDialog.superclass.btnClose;
2920
2921BX.CDebugDialog = function(arParams)
2922{
2923	BX.CDebugDialog.superclass.constructor.apply(this, arguments);
2924};
2925BX.extend(BX.CDebugDialog, BX.CDialog);
2926
2927BX.CDebugDialog.prototype.ShowDetails = function(div_id)
2928{
2929	var div = BX(div_id);
2930	if (div)
2931	{
2932		if (this.div_detail_current)
2933			this.div_detail_current.style.display = 'none';
2934
2935		div.style.display = 'block';
2936		this.div_detail_current = div;
2937	}
2938};
2939
2940BX.CDebugDialog.prototype.SetContent = function(html)
2941{
2942	if (!html)
2943		return;
2944
2945	var arHtml = html.split('#DIVIDER#');
2946	if (arHtml.length > 1)
2947	{
2948		this.PARAMS.content = arHtml[1];
2949
2950		this.PARTS.CONTENT_DATA.style.overflow = 'hidden';
2951
2952		BX.CDebugDialog.superclass.SetContent.apply(this, [arHtml[1]]);
2953
2954		this.PARTS.CONTENT_INNER = this.PARTS.CONTENT_DATA.firstChild.nextSibling;
2955		this.PARTS.CONTENT_TOP = this.PARTS.CONTENT_DATA.insertBefore(BX.create('DIV', {
2956			props: {
2957				className: 'bx-debug-content-top'
2958			},
2959			html: arHtml[0]
2960		}), this.PARTS.CONTENT_INNER);
2961		this.PARTS.CONTENT_INNER.style.overflow = 'auto';
2962	}
2963	else
2964	{
2965		BX.CDebugDialog.superclass.SetContent.apply(this, arguments);
2966	}
2967};
2968
2969BX.CDebugDialog.prototype.__adjustSize = function()
2970{
2971	BX.CDebugDialog.superclass.__adjustSize.apply(this, arguments);
2972
2973	if (this.PARTS.CONTENT_TOP)
2974	{
2975		var new_height = this.PARTS.CONTENT_DATA.offsetHeight - this.PARTS.HEAD.offsetHeight - this.PARTS.CONTENT_TOP.offsetHeight - 38;
2976
2977		if (new_height > 0)
2978		{
2979			this.PARTS.CONTENT_INNER.style.height = new_height + 'px';
2980		}
2981	}
2982};
2983
2984
2985/* class for dialog window with editors */
2986
2987BX.CEditorDialog = function(arParams)
2988{
2989	BX.CEditorDialog.superclass.constructor.apply(this, arguments);
2990
2991	BX.removeClass(this.PARTS.CONTENT, 'bx-core-adm-dialog-content-wrap');
2992	BX.removeClass(this.PARTS.CONTENT_DATA, 'bx-core-adm-dialog-content');
2993
2994	BX.removeClass(this.PARTS.CONTENT_DATA.lastChild, 'bx-core-adm-dialog-content-wrap-inner');
2995	BX.removeClass(this.PARTS.BUTTONS_CONTAINER, 'bx-core-adm-dialog-buttons');
2996
2997	BX.addClass(this.PARTS.CONTENT, 'bx-core-editor-dialog-content-wrap');
2998	BX.addClass(this.PARTS.CONTENT_DATA, 'bx-core-editor-dialog-content');
2999	BX.addClass(this.PARTS.BUTTONS_CONTAINER, 'bx-core-editor-dialog-buttons');
3000};
3001BX.extend(BX.CEditorDialog, BX.CDialog);
3002
3003BX.CEditorDialog.prototype.SetContent  = function()
3004{
3005	BX.CEditorDialog.superclass.SetContent.apply(this, arguments);
3006
3007	BX.removeClass(this.PARTS.CONTENT_DATA.lastChild, 'bx-core-adm-dialog-content-wrap-inner');
3008};
3009
3010/* class for wizards in admin section */
3011BX.CWizardDialog = function(arParams)
3012{
3013	BX.CWizardDialog.superclass.constructor.apply(this, arguments);
3014
3015	BX.removeClass(this.PARTS.CONTENT, 'bx-core-adm-dialog-content-wrap');
3016	BX.removeClass(this.PARTS.CONTENT_DATA, 'bx-core-adm-dialog-content');
3017	BX.removeClass(this.PARTS.CONTENT_DATA.lastChild, 'bx-core-adm-dialog-content-wrap-inner');
3018	BX.removeClass(this.PARTS.BUTTONS_CONTAINER, 'bx-core-adm-dialog-buttons');
3019
3020	BX.addClass(this.PARTS.CONTENT, 'bx-core-wizard-dialog-content-wrap');
3021};
3022
3023BX.extend(BX.CWizardDialog, BX.CDialog);
3024
3025/* class for auth dialog */
3026BX.CAuthDialog = function(arParams)
3027{
3028	arParams.resizable = false;
3029	arParams.width = 350;
3030	arParams.height = 200;
3031
3032	arParams.buttons = [this.btnSave];
3033
3034	BX.CAuthDialog.superclass.constructor.apply(this, arguments);
3035	this._sender = 'core_window_cauthdialog';
3036
3037	BX.addClass(this.DIV, 'bx-core-auth-dialog');
3038
3039	BX.AUTHAGENT = this;
3040};
3041BX.extend(BX.CAuthDialog, BX.CDialog);
3042
3043BX.CAuthDialog.prototype.btnSave = BX.CAuthDialog.btnSave = {
3044	title: BX.message('JS_CORE_WINDOW_AUTH'),
3045	id: 'savebtn',
3046	name: 'savebtn',
3047	className: 'adm-btn-save',
3048	action: function () {
3049		this.disableUntilError();
3050		this.parentWindow.Submit('', this.parentWindow.PARAMS.content_url);
3051	}
3052};
3053
3054BX.CAuthDialog.prototype.SetError = function(error)
3055{
3056	BX.closeWait();
3057
3058	if (!!error)
3059		this.ShowError(error.MESSAGE || error);
3060};
3061
3062BX.CAuthDialog.prototype.setAuthResult = function(result)
3063{
3064	BX.closeWait();
3065
3066	if (result === false)
3067	{
3068		this.Close();
3069		if (this.PARAMS.callback)
3070			this.PARAMS.callback();
3071	}
3072	else
3073	{
3074		this.SetError(result);
3075	}
3076};
3077
3078/* MENU CLASSES */
3079
3080BX.CWindowFloat = function(node)
3081{
3082	BX.CWindowFloat.superclass.constructor.apply(this, [node, 'float']);
3083
3084	this.SETTINGS.resizable = false;
3085};
3086BX.extend(BX.CWindowFloat, BX.CWindow);
3087
3088BX.CWindowFloat.prototype.adjustPos = function()
3089{
3090	if (this.PARAMS.parent)
3091		this.adjustToNode();
3092	else if (this.PARAMS.x && this.PARAMS.y)
3093		this.adjustToPos([this.PARAMS.x, this.PARAMS.y]);
3094};
3095
3096BX.CWindowFloat.prototype.adjustToPos = function(pos)
3097{
3098	this.DIV.style.left = parseInt(pos[0]) + 'px';
3099	this.DIV.style.top = parseInt(pos[1]) + 'px';
3100};
3101
3102BX.CWindowFloat.prototype.adjustToNodeGetPos = function()
3103{
3104	return BX.pos(this.PARAMS.parent);
3105};
3106
3107BX.CWindowFloat.prototype.adjustToNode = function(el)
3108{
3109	el = el || this.PARAMS.parent;
3110
3111	this.PARAMS.parent = BX(el);
3112
3113	if (this.PARAMS.parent)
3114	{
3115		var pos = this.adjustToNodeGetPos();
3116
3117		this.DIV.style.top = pos.top + 'px';//(pos.top - 26) + 'px';
3118		this.DIV.style.left = pos.left + 'px';
3119
3120		this.PARAMS.parent.OPENER = this;
3121	}
3122};
3123
3124BX.CWindowFloat.prototype.Show = function()
3125{
3126	this.adjustToPos([-1000, -1000]);
3127	BX.CWindowFloat.superclass.Show.apply(this, arguments);
3128	this.adjustPos();
3129};
3130
3131/* menu opener class */
3132/*
3133{
3134	DOMNode DIV,
3135	BX.CMenu or Array MENU,
3136	TYPE = 'hover' | 'click',
3137	TIMEOUT: 1000
3138	ATTACH_MODE: 'top' | 'right'
3139	ACTIVE_CLASS: className for opener element when menu is opened
3140}
3141*/
3142BX.COpener = function(arParams)
3143{
3144	this.PARAMS = arParams || {};
3145
3146	this.MENU = arParams.MENU || [];
3147
3148	this.DIV = arParams.DIV;
3149	this.ATTACH = arParams.ATTACH || arParams.DIV;
3150	this.ATTACH_MODE = arParams.ATTACH_MODE || 'bottom';
3151
3152	this.ACTIVE_CLASS = arParams.ACTIVE_CLASS || '';
3153	this.PUBLIC_FRAME = arParams.PUBLIC_FRAME || 0;
3154	this.LEVEL = arParams.LEVEL || 0;
3155
3156	this.CLOSE_ON_CLICK = typeof arParams.CLOSE_ON_CLICK != 'undefined' ? !!arParams.CLOSE_ON_CLICK : true;
3157	this.ADJUST_ON_CLICK = typeof arParams.ADJUST_ON_CLICK != 'undefined' ? !!arParams.ADJUST_ON_CLICK : true;
3158
3159	this.TYPE = this.PARAMS.TYPE == 'hover' ? 'hover' : 'click';
3160
3161	this._openTimeout = null;
3162
3163	if (this.PARAMS.TYPE == 'hover' && arParams.TIMEOUT !== 0)
3164		this.TIMEOUT = arParams.TIMEOUT || 1000;
3165	else
3166		this.TIMEOUT = 0;
3167
3168	this.bMenuInit = false;
3169
3170	if (!!this.PARAMS.MENU_URL)
3171	{
3172		this.bMenuLoaded = false;
3173		this.bMenuLoading = false;
3174
3175		this.MENU = [{
3176			TEXT: BX.message('JS_CORE_LOADING'),
3177			CLOSE_ON_CLICK: false
3178		}];
3179
3180		if (this.PARAMS.MENU_PRELOAD)
3181		{
3182			BX.defer(this.Load, this)();
3183		}
3184	}
3185
3186	BX.ready(BX.defer(this.Init, this));
3187};
3188
3189BX.COpener.prototype.Init = function()
3190{
3191	this.DIV = BX(this.DIV);
3192
3193	switch (this.TYPE)
3194	{
3195		case 'hover':
3196			BX.bind(this.DIV, 'mouseover', BX.proxy(this.Open, this));
3197			BX.bind(this.DIV, 'click', BX.proxy(this.Toggle, this));
3198		break;
3199
3200		case 'click':
3201			BX.bind(this.DIV, 'click', BX.proxy(this.Toggle, this));
3202		break;
3203	}
3204
3205	//BX.bind(window, 'scroll', BX.delegate(this.__close_immediately, this));
3206
3207	//this.bMenuInit = false;
3208};
3209
3210BX.COpener.prototype.Load = function()
3211{
3212	if (this.PARAMS.MENU_URL && !this.bMenuLoaded)
3213	{
3214		if (!this.bMenuLoading)
3215		{
3216			var url = this.PARAMS.MENU_URL;
3217			if (url.indexOf('sessid=') <= 0)
3218				url += (url.indexOf('?') > 0 ? '&' : '?') + 'sessid=' + BX.bitrix_sessid();
3219
3220			this.bMenuLoading = true;
3221			BX.ajax.loadJSON(url, BX.proxy(this.SetMenu, this), BX.proxy(this.LoadFailed, this));
3222		}
3223	}
3224};
3225
3226BX.COpener.prototype.SetMenu = function(menu)
3227{
3228	this.bMenuLoaded = true;
3229	this.bMenuLoading = false;
3230	if (this.bMenuInit)
3231	{
3232		this.MENU.setItems(menu);
3233	}
3234	else
3235	{
3236		this.MENU = menu;
3237	}
3238};
3239
3240BX.COpener.prototype.LoadFailed = function(type, error)
3241{
3242	this.bMenuLoading = false;
3243	this.SetMenu([{
3244		TEXT: BX.message('JS_CORE_NO_DATA'),
3245		CLOSE_ON_CLICK: true
3246	}]);
3247	BX.debug(arguments);
3248};
3249
3250BX.COpener.prototype.checkAdminMenu = function()
3251{
3252	if (document.documentElement.id == 'bx-admin-prefix')
3253		return true;
3254
3255	return !!BX.findParent(this.DIV, {property: {id: 'bx-admin-prefix'}});
3256};
3257
3258BX.COpener.prototype.Toggle = function(e)
3259{
3260	this.__clear_timeout();
3261
3262	if (!this.bMenuInit || !this.MENU.visible())
3263	{
3264		var t = this.TIMEOUT;
3265		this.TIMEOUT = 0;
3266		this.Open(e);
3267		this.TIMEOUT = t;
3268	}
3269	else
3270	{
3271		this.MENU.Close();
3272	}
3273
3274	return !!(e||window.event) && BX.PreventDefault(e);
3275};
3276
3277BX.COpener.prototype.GetMenu = function()
3278{
3279	if (!this.bMenuInit)
3280	{
3281		if (BX.type.isArray(this.MENU))
3282		{
3283			this.MENU = new BX.CMenu({
3284				ITEMS: this.MENU,
3285				ATTACH_MODE: this.ATTACH_MODE,
3286				SET_ID: this.checkAdminMenu() ? 'bx-admin-prefix' : '',
3287				CLOSE_ON_CLICK: !!this.CLOSE_ON_CLICK,
3288				ADJUST_ON_CLICK: !!this.ADJUST_ON_CLICK,
3289				PUBLIC_FRAME: !!this.PUBLIC_FRAME,
3290				LEVEL: this.LEVEL,
3291				parent: BX(this.DIV),
3292				parent_attach: BX(this.ATTACH)
3293			});
3294
3295			if (this.LEVEL > 0)
3296			{
3297				BX.bind(this.MENU.DIV, 'mouseover', BX.proxy(this._on_menu_hover, this));
3298				BX.bind(this.MENU.DIV, 'mouseout', BX.proxy(this._on_menu_hout, this));
3299			}
3300		}
3301
3302		BX.addCustomEvent(this.MENU, 'onMenuOpen', BX.proxy(this.handler_onopen, this));
3303		BX.addCustomEvent(this.MENU, 'onMenuClose', BX.proxy(this.handler_onclose, this));
3304
3305		BX.addCustomEvent('onMenuItemHover', BX.proxy(this.handler_onover, this));
3306
3307		this.bMenuInit = true;
3308	}
3309
3310	return this.MENU;
3311};
3312
3313BX.COpener.prototype.Open = function()
3314{
3315	this.GetMenu();
3316
3317	this.bOpen = true;
3318
3319	this.__clear_timeout();
3320
3321	if (this.TIMEOUT > 0)
3322	{
3323		BX.bind(this.DIV, 'mouseout', BX.proxy(this.__clear_timeout, this));
3324		this._openTimeout = setTimeout(BX.proxy(this.__open, this), this.TIMEOUT);
3325	}
3326	else
3327	{
3328		this.__open();
3329	}
3330
3331	if (!!this.PARAMS.MENU_URL && !this.bMenuLoaded)
3332	{
3333		this._loadTimeout = setTimeout(BX.proxy(this.Load, this), parseInt(this.TIMEOUT/2));
3334	}
3335
3336	return true;
3337};
3338
3339BX.COpener.prototype.__clear_timeout = function()
3340{
3341	if (!!this._openTimeout)
3342		clearTimeout(this._openTimeout);
3343	if (!!this._loadTimeout)
3344		clearTimeout(this._loadTimeout);
3345
3346	BX.unbind(this.DIV, 'mouseout', BX.proxy(this.__clear_timeout, this));
3347};
3348
3349BX.COpener.prototype._on_menu_hover = function()
3350{
3351	this.bMenuHover = true;
3352
3353	this.__clear_timeout();
3354
3355	if (this.ACTIVE_CLASS)
3356		BX.addClass(this.DIV, this.ACTIVE_CLASS);
3357
3358};
3359
3360BX.COpener.prototype._on_menu_hout = function()
3361{
3362	this.bMenuHover = false;
3363};
3364
3365BX.COpener.prototype.handler_onover = function(level, opener)
3366{
3367	if (this.bMenuHover)
3368		return;
3369
3370	if (opener != this && level == this.LEVEL-1 && this.ACTIVE_CLASS)
3371	{
3372		BX.removeClass(this.DIV, this.ACTIVE_CLASS);
3373	}
3374
3375	if (this.bMenuInit && level <= this.LEVEL-1 && this.MENU.visible())
3376	{
3377		if (opener != this)
3378		{
3379			this.__clear_timeout();
3380			this._openTimeout = setTimeout(BX.proxy(this.Close, this), this.TIMEOUT);
3381		}
3382	}
3383};
3384
3385BX.COpener.prototype.handler_onopen = function()
3386{
3387	this.bOpen = true;
3388
3389	if (this.ACTIVE_CLASS)
3390		BX.addClass(this.DIV, this.ACTIVE_CLASS);
3391
3392	BX.defer(function() {
3393		BX.onCustomEvent(this, 'onOpenerMenuOpen');
3394	}, this)();
3395};
3396
3397BX.COpener.prototype.handler_onclose = function()
3398{
3399	this.bOpen = false;
3400	BX.onCustomEvent(this, 'onOpenerMenuClose');
3401
3402	if (this.ACTIVE_CLASS)
3403		BX.removeClass(this.DIV, this.ACTIVE_CLASS);
3404};
3405
3406BX.COpener.prototype.Close = function()
3407{
3408	if (!this.bMenuInit)
3409		return;
3410
3411	if (!!this._openTimeout)
3412		clearTimeout(this._openTimeout);
3413
3414	this.bOpen = false;
3415
3416	this.__close();
3417};
3418
3419BX.COpener.prototype.__open = function()
3420{
3421	this.__clear_timeout();
3422
3423	if (this.bMenuInit && this.bOpen && !this.MENU.visible())
3424		this.MENU.Show();
3425};
3426
3427BX.COpener.prototype.__close = function()
3428{
3429	if (this.bMenuInit && !this.bOpen && this.MENU.visible())
3430		this.MENU.Hide();
3431};
3432
3433BX.COpener.prototype.__close_immediately = function() {
3434	this.bOpen = false; this.__close();
3435};
3436
3437BX.COpener.prototype.isMenuVisible = function() {
3438	return null != this.MENU.visible && this.MENU.visible()
3439};
3440
3441/* common menu class */
3442
3443BX.CMenu = function(arParams)
3444{
3445	BX.CMenu.superclass.constructor.apply(this);
3446
3447	this.DIV.style.width = 'auto';//this.DIV.firstChild.offsetWidth + 'px';
3448	this.DIV.style.height = 'auto';//this.DIV.firstChild.offsetHeight + 'px';
3449
3450	this.PARAMS = arParams || {};
3451	this.PARTS = {};
3452
3453	this.PARAMS.ATTACH_MODE = this.PARAMS.ATTACH_MODE || 'bottom';
3454	this.PARAMS.CLOSE_ON_CLICK = typeof this.PARAMS.CLOSE_ON_CLICK == 'undefined' ? true : this.PARAMS.CLOSE_ON_CLICK;
3455	this.PARAMS.ADJUST_ON_CLICK = typeof this.PARAMS.ADJUST_ON_CLICK == 'undefined' ? true : this.PARAMS.ADJUST_ON_CLICK;
3456	this.PARAMS.PUBLIC_FRAME = typeof this.PARAMS.PUBLIC_FRAME == 'undefined' ? false : this.PARAMS.PUBLIC_FRAME;
3457	this.PARAMS.LEVEL = this.PARAMS.LEVEL || 0;
3458
3459	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 : '');
3460	if (!!this.PARAMS.SET_ID)
3461		this.DIV.id = this.PARAMS.SET_ID;
3462
3463	if (this.PARAMS.LEVEL == 0)
3464	{
3465		this.ARROW = this.DIV.appendChild(BX.create('SPAN', {props: {className: 'bx-core-popup-menu-angle'}, style: {left:'15px'}}));
3466	}
3467
3468	if (!!this.PARAMS.CLASS_NAME)
3469		this.DIV.className += ' ' + this.PARAMS.CLASS_NAME;
3470
3471	BX.bind(this.DIV, 'click', BX.eventCancelBubble);
3472
3473	this.ITEMS = [];
3474
3475	this.setItems(this.PARAMS.ITEMS);
3476
3477	BX.addCustomEvent('onMenuOpen', BX.proxy(this._onMenuOpen, this));
3478	BX.addCustomEvent('onMenuItemSelected', BX.proxy(this.Hide, this));
3479};
3480BX.extend(BX.CMenu, BX.CWindowFloat);
3481
3482BX.CMenu.broadcastCloseEvent = function()
3483{
3484	BX.onCustomEvent("onMenuItemSelected");
3485};
3486
3487BX.CMenu._toggleChecked = function()
3488{
3489	BX.toggleClass(this, 'bx-core-popup-menu-item-checked');
3490};
3491
3492BX.CMenu._itemDblClick = function()
3493{
3494	window.location.href = this.href;
3495};
3496
3497BX.CMenu.prototype.toggleArrow = function(v)
3498{
3499	if (!!this.ARROW)
3500	{
3501		if (typeof v == 'undefined')
3502		{
3503			v = this.ARROW.style.visibility == 'hidden';
3504		}
3505
3506		this.ARROW.style.visibility = !!v ? 'visible' : 'hidden';
3507	}
3508};
3509
3510BX.CMenu.prototype.visible = function()
3511{
3512	return this.DIV.style.display !== 'none';
3513};
3514
3515BX.CMenu.prototype._onMenuOpen = function(menu, menu_level)
3516{
3517	if (this.visible())
3518	{
3519		if (menu_level == this.PARAMS.LEVEL && menu != this)
3520		{
3521			this.Hide();
3522		}
3523	}
3524};
3525
3526BX.CMenu.prototype.onUnRegister = function()
3527{
3528	if (!this.visible())
3529		return;
3530
3531	this.Hide();
3532};
3533
3534BX.CMenu.prototype.setItems = function(items)
3535{
3536	this.PARAMS.ITEMS = items;
3537
3538	BX.cleanNode(this.DIV);
3539
3540	if (!!this.ARROW)
3541		this.DIV.appendChild(this.ARROW);
3542
3543	if (this.PARAMS.ITEMS)
3544	{
3545		this.PARAMS.ITEMS = BX.util.array_values(this.PARAMS.ITEMS);
3546
3547		var bIcons = false;
3548		var cnt = 0;
3549		for (var i = 0, len = this.PARAMS.ITEMS.length; i < len; i++)
3550		{
3551			if ((i == 0 || i == len-1) && this.PARAMS.ITEMS[i].SEPARATOR)
3552				continue;
3553
3554			cnt++;
3555
3556			if (!bIcons)
3557				bIcons = !!this.PARAMS.ITEMS[i].GLOBAL_ICON;
3558
3559			this.addItem(this.PARAMS.ITEMS[i], i);
3560		}
3561
3562		// Occam turning in his grave
3563		if (cnt === 1)
3564			BX.addClass(this.DIV, 'bx-core-popup-menu-single-item');
3565		else
3566			BX.removeClass(this.DIV, 'bx-core-popup-menu-single-item');
3567
3568		if (!bIcons)
3569			BX.addClass(this.DIV, 'bx-core-popup-menu-no-icons');
3570		else
3571			BX.removeClass(this.DIV, 'bx-core-popup-menu-no-icons');
3572
3573	}
3574};
3575
3576BX.CMenu.prototype.addItem = function(item)
3577{
3578	this.ITEMS.push(item);
3579
3580	if (item.SEPARATOR)
3581	{
3582		item.NODE = BX.create(
3583			'DIV', {props: {className: 'bx-core-popup-menu-separator'}}
3584		);
3585	}
3586	else
3587	{
3588		var bHasMenu = (!!item.MENU
3589			&& (
3590				(BX.type.isArray(item.MENU) && item.MENU.length > 0)
3591				|| item.MENU instanceof BX.CMenu
3592			) || !!item.MENU_URL
3593		);
3594
3595		if (item.DISABLED)
3596		{
3597			item.CLOSE_ON_CLICK = false;
3598			item.LINK = null;
3599			item.ONCLICK = null;
3600			item.ACTION = null;
3601		}
3602
3603		var attrs = {};
3604		if (!!item.LINK || BX.browser.IsIE() && !BX.browser.IsDoctype())
3605		{
3606			attrs.href = item.LINK || 'javascript:void(0)';
3607		}
3608		if (this.PARAMS.PUBLIC_FRAME)
3609		{
3610			attrs.target = '_top';
3611		}
3612
3613		item.NODE = BX.create(!!item.LINK || BX.browser.IsIE() && !BX.browser.IsDoctype() ? 'A' : 'SPAN', {
3614			props: {
3615				className: 'bx-core-popup-menu-item'
3616					+ (bHasMenu ? ' bx-core-popup-menu-item-opener' : '')
3617					+ (!!item.DEFAULT ? ' bx-core-popup-menu-item-default' : '')
3618					+ (!!item.DISABLED ? ' bx-core-popup-menu-item-disabled' : '')
3619					+ (!!item.CHECKED ? ' bx-core-popup-menu-item-checked' : ''),
3620					title: !!BX.message['MENU_ENABLE_TOOLTIP'] || !!item.SHOW_TITLE ? item.TITLE || '' : '',
3621				BXMENULEVEL: this.PARAMS.LEVEL
3622			},
3623			attrs: attrs,
3624			events: {
3625				mouseover: function()
3626				{
3627					BX.onCustomEvent('onMenuItemHover', [this.BXMENULEVEL, this.OPENER])
3628				}
3629			},
3630			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>'
3631		});
3632
3633		if (bHasMenu && !item.DISABLED)
3634		{
3635			item.NODE.OPENER = new BX.COpener({
3636				DIV: item.NODE,
3637				ACTIVE_CLASS: 'bx-core-popup-menu-item-opened',
3638				TYPE: 'hover',
3639				MENU: item.MENU,
3640				MENU_URL: item.MENU_URL,
3641				MENU_PRELOAD: !!item.MENU_PRELOAD,
3642				LEVEL: this.PARAMS.LEVEL + 1,
3643				ATTACH_MODE:'right',
3644				TIMEOUT: 500
3645			});
3646		}
3647		else if (this.PARAMS.CLOSE_ON_CLICK && (typeof item.CLOSE_ON_CLICK == 'undefined' || !!item.CLOSE_ON_CLICK))
3648		{
3649			BX.bind(item.NODE, 'click', BX.CMenu.broadcastCloseEvent);
3650		}
3651		else if (this.PARAMS.ADJUST_ON_CLICK && (typeof item.ADJUST_ON_CLICK == 'undefined' || !!item.ADJUST_ON_CLICK))
3652		{
3653			BX.bind(item.NODE, 'click', BX.defer(this.adjustPos, this));
3654		}
3655
3656		if (bHasMenu && !!item.LINK)
3657		{
3658			BX.bind(item.NODE, 'dblclick', BX.CMenu._itemDblClick);
3659		}
3660
3661		if (typeof item.CHECKED != 'undefined')
3662		{
3663			BX.bind(item.NODE, 'click', BX.CMenu._toggleChecked);
3664		}
3665
3666		item.ONCLICK = item.ACTION || item.ONCLICK;
3667		if (!!item.ONCLICK)
3668		{
3669			if (BX.type.isString(item.ONCLICK))
3670			{
3671				item.ONCLICK = new Function("event", item.ONCLICK);
3672			}
3673
3674			BX.bind(item.NODE, 'click', item.ONCLICK);
3675		}
3676	}
3677
3678	this.DIV.appendChild(item.NODE);
3679};
3680
3681BX.CMenu.prototype._documentClickBind = function()
3682{
3683	this._documentClickUnBind();
3684	BX.bind(document, 'click', BX.proxy(this._documentClick, this));
3685};
3686
3687BX.CMenu.prototype._documentClickUnBind = function()
3688{
3689	BX.unbind(document, 'click', BX.proxy(this._documentClick, this));
3690};
3691
3692BX.CMenu.prototype._documentClick = function(e)
3693{
3694	e = e||window.event;
3695	if(!!e && !(BX.getEventButton(e) & BX.MSLEFT))
3696		return;
3697
3698	this.Close();
3699};
3700
3701BX.CMenu.prototype.Show = function()
3702{
3703	BX.onCustomEvent(this, 'onMenuOpen', [this, this.PARAMS.LEVEL]);
3704	BX.CMenu.superclass.Show.apply(this, []);
3705
3706	this.bCloseEventFired = false;
3707
3708	BX.addCustomEvent(this.PARAMS.parent_attach, 'onChangeNodePosition', BX.proxy(this.adjustToNode, this));
3709
3710	(BX.defer(this._documentClickBind, this))();
3711};
3712
3713BX.CMenu.prototype.Close = // we shouldn't 'Close' window - only hide
3714BX.CMenu.prototype.Hide = function()
3715{
3716	if (!this.visible())
3717		return;
3718
3719	BX.removeCustomEvent(this.PARAMS.parent_attach, 'onChangeNodePosition', BX.proxy(this.adjustToNode, this));
3720
3721	this._documentClickUnBind();
3722
3723	if (!this.bCloseEventFired)
3724	{
3725		BX.onCustomEvent(this, 'onMenuClose', [this, this.PARAMS.LEVEL]);
3726		this.bCloseEventFired = true;
3727	}
3728	BX.CMenu.superclass.Hide.apply(this, arguments);
3729
3730
3731//	this.DIV.onclick = null;
3732	//this.PARAMS.parent.onclick = null;
3733};
3734
3735BX.CMenu.prototype.__adjustMenuToNode = function()
3736{
3737	var pos = BX.pos(this.PARAMS.parent_attach),
3738		bFixed = !!BX.findParent(this.PARAMS.parent_attach, BX.is_fixed);
3739
3740	if (bFixed)
3741		this.DIV.style.position = 'fixed';
3742	else
3743		this.DIV.style.position = 'absolute';
3744
3745	if (!pos.top)
3746	{
3747		this.DIV.style.top = '-1000px';
3748		this.DIV.style.left = '-1000px';
3749	}
3750
3751	if (this.bTimeoutSet) return;
3752
3753	var floatWidth = this.DIV.offsetWidth, floatHeight = this.DIV.offsetHeight;
3754	if (!floatWidth)
3755	{
3756		setTimeout(BX.delegate(function(){
3757			this.bTimeoutSet = false; this.__adjustMenuToNode();
3758		}, this), 100);
3759
3760		this.bTimeoutSet = true;
3761		return;
3762	}
3763
3764	var menu_pos = {},
3765		wndSize = BX.GetWindowSize();
3766
3767/*
3768	if (BX.browser.IsIE() && !BX.browser.IsDoctype())
3769	{
3770		pos.top -= 4; pos.bottom -= 4;
3771		pos.left -= 2; pos.right -= 2;
3772	}
3773*/
3774
3775	switch (this.PARAMS.ATTACH_MODE)
3776	{
3777		case 'bottom':
3778			menu_pos.top = pos.bottom + 9;
3779			menu_pos.left = pos.left;
3780
3781			var arrowPos = 0;
3782			if (!!this.ARROW)
3783			{
3784				if (pos.width > floatWidth)
3785					arrowPos = parseInt(floatWidth/2 - 7);
3786				else
3787					arrowPos = parseInt(Math.min(floatWidth, pos.width)/2 - 7);
3788
3789				if (arrowPos < 7)
3790				{
3791					menu_pos.left -= 15;
3792					arrowPos += 15;
3793				}
3794			}
3795
3796			if (menu_pos.left > wndSize.scrollWidth - floatWidth - 10)
3797			{
3798				var orig_menu_pos = menu_pos.left;
3799				menu_pos.left = wndSize.scrollWidth - floatWidth - 10;
3800
3801				if (!!this.ARROW)
3802					arrowPos += orig_menu_pos - menu_pos.left;
3803			}
3804
3805			if (bFixed)
3806			{
3807				menu_pos.left -= wndSize.scrollLeft;
3808			}
3809
3810			if (!!this.ARROW)
3811				this.ARROW.style.left = arrowPos + 'px';
3812		break;
3813		case 'right':
3814			menu_pos.top = pos.top-1;
3815			menu_pos.left = pos.right;
3816
3817			if (menu_pos.left > wndSize.scrollWidth - floatWidth - 10)
3818			{
3819				menu_pos.left = pos.left - floatWidth - 1;
3820			}
3821		break;
3822	}
3823
3824	if (bFixed)
3825	{
3826		menu_pos.top -= wndSize.scrollTop;
3827	}
3828
3829	if (!!this.ARROW)
3830		this.ARROW.className = 'bx-core-popup-menu-angle';
3831
3832	if((menu_pos.top + floatHeight >
3832 wndSize.scrollTop + wndSize.innerHeight)
3833		|| (menu_pos.top + floatHeight > wndSize.scrollHeight))
3834	{
3835		var new_top = this.PARAMS.ATTACH_MODE == 'bottom'
3836			? pos.top - floatHeight - 9
3837			: pos.bottom - floatHeight + 1;
3838
3839		if((new_top > wndSize.scrollTop)
3840			|| (menu_pos.top + floatHeight > wndSize.scrollHeight))
3841		{
3842			if ((menu_pos.top + floatHeight > wndSize.scrollHeight))
3843			{
3844				menu_pos.top = Math.max(0, wndSize.scrollHeight-floatHeight);
3845				this.toggleArrow(false);
3846			}
3847			else
3848			{
3849				menu_pos.top = new_top;
3850
3851				if (!!this.ARROW)
3852					this.ARROW.className = 'bx-core-popup-menu-angle-bottom';
3853			}
3854		}
3855	}
3856
3857	if (menu_pos.top + menu_pos.left == 0)
3858	{
3859		this.Hide();
3860	}
3861	else
3862	{
3863		this.DIV.style.top = menu_pos.top + 'px';
3864		this.DIV.style.left = menu_pos.left + 'px';
3865	}
3866};
3867
3868BX.CMenu.prototype.adjustToNode = function(el)
3869{
3870	this.PARAMS.parent_attach = BX(el) || this.PARAMS.parent_attach || this.PARAMS.parent;
3871	this.__adjustMenuToNode();
3872};
3873
3874
3875/* components toolbar class */
3876
3877BX.CMenuOpener = function(arParams)
3878{
3879	BX.CMenuOpener.superclass.constructor.apply(this);
3880
3881	this.PARAMS = arParams || {};
3882	this.setParent(this.PARAMS.parent);
3883	this.PARTS = {};
3884
3885	this.SETTINGS.drag_restrict = true;
3886
3887	this.defaultAction = null;
3888
3889	this.timeout = 500;
3890
3891	this.DIV.className = 'bx-component-opener';
3892	this.DIV.ondblclick = BX.PreventDefault;
3893
3894	if (this.PARAMS.component_id)
3895	{
3896		this.PARAMS.transform = !!this.PARAMS.transform;
3897	}
3898
3899	this.OPENERS = [];
3900
3901	this.DIV.appendChild(BX.create('SPAN', {
3902		props: {className: 'bx-context-toolbar' + (this.PARAMS.transform ? ' bx-context-toolbar-vertical-mode' : '')}
3903	}));
3904
3905	//set internal structure and register draggable element
3906	this.PARTS.INNER = this.DIV.firstChild.appendChild(BX.create('SPAN', {
3907		props: {className: 'bx-context-toolbar-inner'},
3908		html: '<span class="bx-context-toolbar-drag-icon"></span><span class="bx-context-toolbar-vertical-line"></span><br>'
3909	}));
3910
3911	this.EXTRA_BUTTONS = {};
3912
3913	var btnCount = 0;
3914	for (var i = 0, len = this.PARAMS.menu.length; i < len; i++)
3915	{
3916		var item = this.addItem(this.PARAMS.menu[i]);
3917		if (null != item)
3918		{
3919			btnCount++;
3920			this.PARTS.INNER.appendChild(item);
3921			this.PARTS.INNER.appendChild(BX.create('BR'));
3922		}
3923	}
3924	var bHasButtons = btnCount > 0;
3925
3926	//menu items will be attached here
3927
3928	this.PARTS.ICONS = this.PARTS.INNER.appendChild(BX.create('SPAN', {
3929		props: {className: 'bx-context-toolbar-icons'}
3930	}));
3931
3932	if (this.PARAMS.component_id)
3933	{
3934		this.PARAMS.pin = !!this.PARAMS.pin;
3935
3936		if (bHasButtons)
3937			this.PARTS.ICONS.appendChild(BX.create('SPAN', {props: {className: 'bx-context-toolbar-separator'}}));
3938
3939		this.PARTS.ICON_PIN = this.PARTS.ICONS.appendChild(BX.create('A', {
3940			attrs: {
3941				href: 'javascript:void(0)'
3942			},
3943			props: {
3944				className: this.PARAMS.pin
3945							? 'bx-context-toolbar-pin-fixed'
3946							: 'bx-context-toolbar-pin'
3947			},
3948			events: {
3949				click: BX.delegate(this.__pin_btn_clicked, this)
3950			}
3951		}));
3952	}
3953
3954
3955	if (this.EXTRA_BUTTONS['components2_props'])
3956	{
3957		var btn = this.EXTRA_BUTTONS['components2_props'] || {URL: 'javascript:void(0)'};
3958		if (null == this.defaultAction)
3959		{
3960			this.defaultAction = btn.ONCLICK;
3961			this.defaultActionTitle = btn.TITLE || btn.TEXT;
3962		}
3963
3964		btn.URL = 'javascript:' + BX.util.urlencode(btn.ONCLICK);
3965
3966		this.ATTACH = this.PARTS.ICONS.appendChild(BX.create('SPAN', {
3967			props: {className: 'bx-context-toolbar-button bx-context-toolbar-button-settings' },
3968			children:
3969			[
3970				BX.create('SPAN',
3971				{
3972					props:{className: 'bx-context-toolbar-button-inner'},
3973					children:
3974					[
3975						BX.create('A', {
3976							attrs: {href: btn.URL},
3977							events: {
3978								mouseover: BX.proxy(this.__msover_text, this),
3979								mouseout: BX.proxy(this.__msout_text, this),
3980								mousedown: BX.proxy(this.__msdown_text, this)
3981							},
3982							html: '<span class="bx-context-toolbar-button-icon bx-context-toolbar-settings-icon"></span>'
3983						}),
3984						BX.create('A', {
3985							attrs: {href: 'javascript: void(0)'},
3986							props: {className: 'bx-context-toolbar-button-arrow'},
3987							events: {
3988								mouseover: BX.proxy(this.__msover_arrow, this),
3989								mouseout: BX.proxy(this.__msout_arrow, this),
3990								mousedown: BX.proxy(this.__msdown_arrow, this)
3991							},
3992							html: '<span class="bx-context-toolbar-button-arrow"></span>'
3993						})
3994					]
3995				})
3996			]
3997		}));
3998
3999		this.OPENER = this.ATTACH.firstChild.lastChild;
4000
4001		var opener = this.attachMenu(this.EXTRA_BUTTONS['components2_submenu']['MENU']);
4002
4003		BX.addCustomEvent(opener, 'onOpenerMenuOpen', BX.proxy(this.__menu_open, this));
4004		BX.addCustomEvent(opener, 'onOpenerMenuClose', BX.proxy(this.__menu_close, this));
4005	}
4006
4007	if (btnCount > 1)
4008	{
4009		this.PARTS.ICONS.appendChild(BX.create('span', { props: {className: 'bx-context-toolbar-separator bx-context-toolbar-separator-switcher'}}));
4010
4011		this.ICON_TRANSFORM = this.PARTS.ICONS.appendChild(BX.create('A', {
4012			attrs: {href: 'javascript: void(0)'},
4013			props: {className: 'bx-context-toolbar-switcher'},
4014			events: {
4015				click: BX.delegate(this.__trf_btn_clicked, this)
4016			}
4017		}));
4018	}
4019
4020	if (this.PARAMS.HINT)
4021	{
4022		this.DIV.BXHINT = this.HINT = new BX.CHint({
4023			parent: this.DIV,
4024			hint:this.PARAMS.HINT.TEXT || '',
4025			title: this.PARAMS.HINT.TITLE || '',
4026			hide_timeout: this.timeout/2,
4027			preventHide: false
4028		});
4029	}
4030
4031	BX.addCustomEvent(this, 'onWindowDragFinished', BX.delegate(this.__onMoveFinished, this));
4032	BX.addCustomEvent('onDynamicModeChange', BX.delegate(this.__onDynamicModeChange, this));
4033	BX.addCustomEvent('onTopPanelCollapse', BX.delegate(this.__onPanelCollapse, this));
4034
4035	BX.addCustomEvent('onMenuOpenerMoved', BX.delegate(this.checkPosition, this));
4036	BX.addCustomEvent('onMenuOpenerUnhide', BX.delegate(this.checkPosition, this));
4037
4038	BX.Event.EventEmitter.incrementMaxListeners('onDynamicModeChange');
4039	BX.Event.EventEmitter.incrementMaxListeners('onTopPanelCollapse');
4040	BX.Event.EventEmitter.incrementMaxListeners('onMenuOpenerMoved');
4041	BX.Event.EventEmitter.incrementMaxListeners('onMenuOpenerUnhide');
4042
4043	if (this.OPENERS)
4044	{
4045		for (i=0,len=this.OPENERS.length; i<len; i++)
4046		{
4047			BX.addCustomEvent(this.OPENERS[i], 'onOpenerMenuOpen', BX.proxy(this.__hide_hint, this));
4048		}
4049	}
4050};
4051BX.extend(BX.CMenuOpener, BX.CWindowFloat);
4052
4053BX.CMenuOpener.prototype.setParent = function(new_parent)
4054{
4055	new_parent = BX(new_parent);
4056
4057	if (!new_parent)
4058	{
4059		return;
4060	}
4061
4062	if(new_parent.OPENER && new_parent.OPENER != this)
4063	{
4064		new_parent.OPENER.Close();
4065		new_parent.OPENER.clearHoverHoutEvents();
4066	}
4067
4068	if(this.PARAMS.parent && this.PARAMS.parent != new_parent)
4069	{
4070		this.clearHoverHoutEvents();
4071		this.PARAMS.parent.OPENER = null;
4072	}
4073
4074	this.PARAMS.parent = new_parent;
4075	this.PARAMS.parent.OPENER = this;
4076};
4077
4078BX.CMenuOpener.prototype.setHoverHoutEvents = function(hover, hout)
4079{
4080	if(!this.__opener_events_set)
4081	{
4082		BX.bind(this.Get(), 'mouseover', hover);
4083		BX.bind(this.Get(), 'mouseout', hout);
4084		this.__opener_events_set = true;
4085	}
4086};
4087
4088BX.CMenuOpener.prototype.clearHoverHoutEvents = function()
4089{
4090	if(this.Get())
4091	{
4092		BX.unbindAll(this.Get());
4093		this.__opener_events_set = false;
4094	}
4095};
4096
4097
4098BX.CMenuOpener.prototype.unclosable = true;
4099
4100BX.CMenuOpener.prototype.__check_intersection = function(pos_self, pos_other)
4101{
4102	return !(pos_other.right <= pos_self.left || pos_other.left >= pos_self.right
4103			|| pos_other.bottom <= pos_self.top || pos_other.top >= pos_self.bottom);
4104};
4105
4106
4107BX.CMenuOpener.prototype.__msover_text = function() {
4108	this.bx_hover = true;
4109	if (!this._menu_open)
4110		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-text-hover');
4111};
4112
4113BX.CMenuOpener.prototype.__msout_text = function() {
4114	this.bx_hover = false;
4115	if (!this._menu_open)
4116		BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-text-hover bx-context-toolbar-button-text-active');
4117};
4118
4119BX.CMenuOpener.prototype.__msover_arrow = function() {
4120	this.bx_hover = true;
4121	if (!this._menu_open)
4122		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-arrow-hover');
4123};
4124
4125BX.CMenuOpener.prototype.__msout_arrow = function() {
4126	this.bx_hover = false;
4127	if (!this._menu_open)
4128		BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-arrow-hover bx-context-toolbar-button-arrow-active');
4129};
4130
4131BX.CMenuOpener.prototype.__msdown_text = function() {
4132	this.bx_active = true;
4133	if (!this._menu_open)
4134		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-text-active');
4135};
4136
4137BX.CMenuOpener.prototype.__msdown_arrow = function() {
4138	this.bx_active = true;
4139	if (!this._menu_open)
4140		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-arrow-active');
4141};
4142
4143BX.CMenuOpener.prototype.__menu_close = function() {
4144	this._menu_open = false;
4145	this.bx_active = false;
4146	BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-active bx-context-toolbar-button-text-active bx-context-toolbar-button-arrow-active');
4147	if (!this.bx_hover)
4148	{
4149		BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-hover bx-context-toolbar-button-text-hover bx-context-toolbar-button-arrow-hover');
4150		this.bx_hover = false;
4151	}
4152};
4153
4154BX.CMenuOpener.prototype.__menu_open = function() {
4155	this._menu_open = true;
4156};
4157
4158BX.CMenuOpener.prototype.checkPosition = function()
4159{
4160	if (this.isMenuVisible() || this.DIV.style.display == 'none'
4161		|| this == BX.proxy_context || BX.proxy_context.zIndex > this.zIndex)
4162		return;
4163
4164	this.correctPosition(BX.proxy_context);
4165};
4166
4167BX.CMenuOpener.prototype.correctPosition = function(opener)
4168{
4169	var pos_self = BX.pos(this.DIV), pos_other = BX.pos(opener.Get());
4170	if (this.__check_intersection(pos_self, pos_other))
4171	{
4172		var new_top = pos_other.top - pos_self.height;
4173		if (new_top < 0)
4174			new_top = pos_other.bottom;
4175
4176		this.DIV.style.top = new_top + 'px';
4177
4178		BX.addCustomEvent(opener, 'onMenuOpenerHide', BX.proxy(this.restorePosition, this));
4179		BX.onCustomEvent(this, 'onMenuOpenerMoved');
4180	}
4181};
4182
4183BX.CMenuOpener.prototype.restorePosition = function()
4184{
4185	if (!this.MOUSEOVER && !this.isMenuVisible())
4186	{
4187		if (this.originalPos)
4188			this.DIV.style.top = this.originalPos.top + 'px';
4189
4190		BX.removeCustomEvent(BX.proxy_context, 'onMenuOpenerHide', BX.proxy(this.restorePosition, this));
4191		if (this.restore_pos_timeout) clearTimeout(this.restore_pos_timeout);
4192	}
4193	else
4194	{
4195		this.restore_pos_timeout = setTimeout(BX.proxy(this.restorePosition, this), this.timeout);
4196	}
4197};
4198
4199
4200BX.CMenuOpener.prototype.Show = function()
4201{
4202	BX.CMenuOpener.superclass.Show.apply(this, arguments);
4203
4204	this.SetDraggable(this.PARTS.INNER.firstChild);
4205
4206	this.DIV.style.width = 'auto';
4207	this.DIV.style.height = 'auto';
4208
4209	if (!this.PARAMS.pin)
4210	{
4211		this.DIV.style.left = '-1000px';
4212		this.DIV.style.top = '-1000px';
4213
4214		this.Hide();
4215	}
4216	else
4217	{
4218		this.bPosAdjusted = true;
4219		this.bMoved = true;
4220
4221		if (this.PARAMS.top) this.DIV.style.top = this.PARAMS.top + 'px';
4222		if (this.PARAMS.left) this.DIV.style.left = this.PARAMS.left + 'px';
4223
4224		this.DIV.style.display = (!BX.admin.dynamic_mode || BX.admin.dynamic_mode_show_borders) ? 'block' : 'none';
4225
4226		if (this.DIV.style.display == 'block')
4227		{
4228			setTimeout(BX.delegate(function() {BX.onCustomEvent(this, 'onMenuOpenerUnhide')}, this), 50);
4229		}
4230	}
4231};
4232
4233BX.CMenuOpener.prototype.executeDefaultAction = function()
4234{
4235	if (this.defaultAction)
4236	{
4237		if (BX.type.isFunction(this.defaultAction))
4238			this.defaultAction();
4239		else if(BX.type.isString(this.defaultAction))
4240			BX.evalGlobal(this.defaultAction);
4241	}
4242};
4243
4244BX.CMenuOpener.prototype.__onDynamicModeChange = function(val)
4245{
4246	this.DIV.style.display = val ? 'block' : 'none';
4247};
4248
4249BX.CMenuOpener.prototype.__onPanelCollapse = function(bCollapsed, dy)
4250{
4251	this.DIV.style.top = (parseInt(this.DIV.style.top) + dy) + 'px';
4252	if (this.PARAMS.pin)
4253	{
4254		this.__savePosition();
4255	}
4256};
4257
4258BX.CMenuOpener.prototype.__onMoveFinished = function()
4259{
4260	BX.onCustomEvent(this, 'onMenuOpenerMoved');
4261
4262	this.bMoved = true;
4263
4264	if (this.PARAMS.pin)
4265		this.__savePosition();
4266};
4267
4268BX.CMenuOpener.prototype.__savePosition = function()
4269{
4270	var arOpts = {};
4271
4272	arOpts.pin = this.PARAMS.pin;
4273	if (!this.PARAMS.pin)
4274	{
4275		arOpts.top = false; arOpts.left = false; arOpts.transform = false;
4276	}
4277	else
4278	{
4279		arOpts.transform = this.PARAMS.transform;
4280		if (this.bMoved)
4281		{
4282			arOpts.left = parseInt(this.DIV.style.left);
4283			arOpts.top = parseInt(this.DIV.style.top);
4284		}
4285	}
4286
4287	BX.WindowManager.saveWindowOptions(this.PARAMS.component_id, arOpts);
4288};
4289
4290BX.CMenuOpener.prototype.__pin_btn_clicked = function() {this.Pin()};
4291BX.CMenuOpener.prototype.Pin = function(val)
4292{
4293	if (null == val)
4294		this.PARAMS.pin = !this.PARAMS.pin;
4295	else
4296		this.PARAMS.pin = !!val;
4297
4298	this.PARTS.ICON_PIN.className = (this.PARAMS.pin ? 'bx-context-toolbar-pin-fixed' : 'bx-context-toolbar-pin');
4299
4300	this.__savePosition();
4301};
4302
4303BX.CMenuOpener.prototype.__trf_btn_clicked = function() {this.Transform()};
4304BX.CMenuOpener.prototype.Transform = function(val)
4305{
4306	var pos = {};
4307
4308	if (null == val)
4309		this.PARAMS.transform = !this.PARAMS.transform;
4310	else
4311		this.PARAMS.transform = !!val;
4312
4313	if (this.bMoved)
4314	{
4315		pos = BX.pos(this.DIV);
4316	}
4317
4318	if (this.PARAMS.transform)
4319		BX.addClass(this.DIV.firstChild, 'bx-context-toolbar-vertical-mode');
4320	else
4321		BX.removeClass(this.DIV.firstChild, 'bx-context-toolbar-vertical-mode');
4322
4323	if (!this.bMoved)
4324	{
4325		this.adjustPos();
4326	}
4327	else
4328	{
4329		this.DIV.style.left = (pos.right - this.DIV.offsetWidth - (BX.browser.IsIE() && !BX.browser.IsDoctype() ? 2 : 0)) + 'px';
4330	}
4331
4332	this.__savePosition();
4333};
4334
4335BX.CMenuOpener.prototype.adjustToNodeGetPos = function()
4336{
4337	var pos = BX.pos(this.PARAMS.parent/*, true*/);
4338
4339	var scrollSize = BX.GetWindowScrollSize();
4340	var floatWidth = this.DIV.offsetWidth;
4341
4342	pos.left -= BX.admin.__border_dx;
4343	pos.top -= BX.admin.__border_dx;
4344
4345	if (true || !this.PARAMS.transform)
4346	{
4347		pos.top -= 45;
4348	}
4349
4350	if (pos.left > scrollSize.scrollWidth - floatWidth)
4351	{
4352		pos.left = scrollSize.scrollWidth - floatWidth;
4353	}
4354
4355	return pos;
4356};
4357
4358BX.CMenuOpener.prototype.addItem = function(item)
4359{
4360	if (item.TYPE)
4361	{
4362		this.EXTRA_BUTTONS[item.TYPE] = item;
4363		return null;
4364	}
4365	else
4366	{
4367		var q = new BX.CMenuOpenerItem(item);
4368		if (null == this.defaultAction)
4369		{
4370			if (q.item.ONCLICK)
4371			{
4372				this.defaultAction = item.ONCLICK;
4373			}
4374			else if (q.item.MENU)
4375			{
4376				this.defaultAction = BX.delegate(function() {this.Open()}, q.item.OPENER);
4377			}
4378
4379			this.defaultActionTitle = item.TITLE || item.TEXT;
4380
4381			BX.addClass(q.Get(), 'bx-content-toolbar-default');
4382		}
4383		if (q.item.OPENER) this.OPENERS[this.OPENERS.length] = q.item.OPENER;
4384		return q.Get();
4385	}
4386};
4387
4388BX.CMenuOpener.prototype.attachMenu = function(menu)
4389{
4390	var opener = new BX.COpener({
4391		'DIV':  this.OPENER,
4392		'ATTACH': this.ATTACH,
4393		'MENU': menu,
4394		'TYPE': 'click'
4395	});
4396
4397	this.OPENERS[this.OPENERS.length] = opener;
4398
4399	return opener;
4400};
4401
4402BX.CMenuOpener.prototype.__hide_hint = function()
4403{
4404	if (this.HINT) this.HINT.__hide_immediately();
4405};
4406
4407BX.CMenuOpener.prototype.isMenuVisible = function()
4408{
4409	for (var i=0,len=this.OPENERS.length; i<len; i++)
4410	{
4411		if (this.OPENERS[i].isMenuVisible())
4412			return true;
4413	}
4414
4415	return false;
4416};
4417
4418BX.CMenuOpener.prototype.Hide = function()
4419{
4420	if (!this.PARAMS.pin)
4421	{
4422		this.DIV.style.display = 'none';
4423		BX.onCustomEvent(this, 'onMenuOpenerHide');
4424	}
4425};
4426BX.CMenuOpener.prototype.UnHide = function()
4427{
4428	this.DIV.style.display = 'block';
4429	if (!this.bPosAdjusted && !this.PARAMS.pin)
4430	{
4431		this.adjustPos();
4432		this.bPosAdjusted = true;
4433	}
4434
4435	if (null == this.originalPos && !this.bMoved)
4436	{
4437		this.originalPos = BX.pos(this.DIV);
4438	}
4439
4440	BX.onCustomEvent(this, 'onMenuOpenerUnhide');
4441};
4442
4443BX.CMenuOpenerItem = function(item)
4444{
4445	this.item = item;
4446
4447	if (this.item.ACTION && !this.item.ONCLICK)
4448	{
4449		this.item.ONCLICK = this.item.ACTION;
4450	}
4451
4452	this.DIV = BX.create('SPAN');
4453	this.DIV.appendChild(BX.create('SPAN', {props: {className: 'bx-context-toolbar-button-underlay'}}));
4454
4455	this.WRAPPER = this.DIV.appendChild(BX.create('SPAN', {
4456		props: {className: 'bx-context-toolbar-button-wrapper'},
4457		children: [
4458			BX.create('SPAN', {
4459				props: {className: 'bx-context-toolbar-button', title: item.TITLE},
4460				children: [
4461					BX.create('SPAN', {
4462						props: {className: 'bx-context-toolbar-button-inner'}
4463					})
4464				]
4465			})
4466		]
4467	}));
4468
4469	var btn_icon = BX.create('SPAN', {
4470		props: {className: 'bx-context-toolbar-button-icon' + (this.item.ICON || this.item.ICONCLASS ? ' ' + (this.item.ICON || this.item.ICONCLASS) : '')},
4471		attrs: (
4472				!(this.item.ICON || this.item.ICONCLASS)
4473				&&
4474				(this.item.SRC || this.item.IMAGE)
4475			)
4476			? {
4477				style: 'background: scroll transparent url(' + (this.item.SRC || this.item.IMAGE) + ') no-repeat center center !important;'
4478			}
4479			: {}
4480	}), btn_text = BX.create('SPAN', {
4481		props: {className: 'bx-context-toolbar-button-text'},
4482		text: this.item.TEXT
4483	});
4484
4485	if (this.item.ACTION && !this.item.ONCLICK)
4486	{
4487		this.item.ONCLICK = this.item.ACTION;
4488	}
4489
4490	this.bHasMenu = !!this.item.MENU;
4491	this.bHasAction = !!this.item.ONCLICK;
4492
4493	if (this.bHasAction)
4494	{
4495		this.LINK = this.WRAPPER.firstChild.firstChild.appendChild(BX.create('A', {
4496			attrs: {
4497				'href': 'javascript: void(0)'
4498			},
4499			events: {
4500				mouseover: this.bHasMenu ? BX.proxy(this.__msover_text, this) : BX.proxy(this.__msover, this),
4501				mouseout: this.bHasMenu ? BX.proxy(this.__msout_text, this) : BX.proxy(this.__msout, this),
4502				mousedown: this.bHasMenu ? BX.proxy(this.__msdown_text, this) : BX.proxy(this.__msdown, this)
4503			},
4504			children: [btn_icon, btn_text]
4505		}));
4506
4507		if (this.bHasMenu)
4508		{
4509			this.LINK_MENU = this.WRAPPER.firstChild.firstChild.appendChild(BX.create('A', {
4510				props: {className: 'bx-context-toolbar-button-arrow'},
4511				attrs: {
4512					'href': 'javascript: void(0)'
4513				},
4514				events: {
4515					mouseover: BX.proxy(this.__msover_arrow, this),
4516					mouseout: BX.proxy(this.__msout_arrow, this),
4517					mousedown: BX.proxy(this.__msdown_arrow, this)
4518				},
4519				children: [
4520					BX.create('SPAN', {props: {className: 'bx-context-toolbar-button-arrow'}})
4521				]
4522			}));
4523		}
4524
4525	}
4526	else if (this.bHasMenu)
4527	{
4528		this.item.ONCLICK = null;
4529
4530		this.LINK = this.LINK_MENU = this.WRAPPER.firstChild.firstChild.appendChild(BX.create('A', {
4531			attrs: {
4532				'href': 'javascript: void(0)'
4533			},
4534			events: {
4535				mouseover: BX.proxy(this.__msover, this),
4536				mouseout: BX.proxy(this.__msout, this),
4537				mousedown: BX.proxy(this.__msdown, this)
4538			},
4539			children: [
4540				btn_icon,
4541				btn_text
4542			]
4543		}));
4544
4545		this.LINK.appendChild(BX.create('SPAN', {props: {className: 'bx-context-toolbar-single-button-arrow'}}));
4546
4547	}
4548
4549	if (this.bHasMenu)
4550	{
4551		this.item.SUBMENU = new BX.CMenu({
4552			ATTACH_MODE:'bottom',
4553			ITEMS:this.item['MENU'],
4554			//PARENT_MENU:this.parentMenu,
4555			parent: this.LINK_MENU,
4556			parent_attach: this.WRAPPER.firstChild
4557		});
4558
4559		this.item.OPENER = new BX.COpener({
4560			DIV: this.LINK_MENU,
4561			TYPE: 'click',
4562			MENU: this.item.SUBMENU
4563		});
4564
4565		BX.addCustomEvent(this.item.OPENER, 'onOpenerMenuOpen', BX.proxy(this.__menu_open, this));
4566		BX.addCustomEvent(this.item.OPENER, 'onOpenerMenuClose', BX.proxy(this.__menu_close, this));
4567	}
4568
4569	if (this.bHasAction)
4570	{
4571		BX.bind(this.LINK, 'click', BX.delegate(this.__click, this));
4572	}
4573};
4574
4575BX.CMenuOpenerItem.prototype.Get = function() {return this.DIV;};
4576BX.CMenuOpenerItem.prototype.__msover = function() {
4577	this.bx_hover = true;
4578	if (!this._menu_open)
4579		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-hover');
4580};
4581BX.CMenuOpenerItem.prototype.__msout = function() {
4582	this.bx_hover = false;
4583	if (!this._menu_open)
4584		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-hover bx-context-toolbar-button-active');
4585};
4586BX.CMenuOpenerItem.prototype.__msover_text = function() {
4587	this.bx_hover = true;
4588	if (!this._menu_open)
4589		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-text-hover');
4590};
4591BX.CMenuOpenerItem.prototype.__msout_text = function() {
4592	this.bx_hover = false;
4593	if (!this._menu_open)
4594		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-text-hover bx-context-toolbar-button-text-active');
4595};
4596BX.CMenuOpenerItem.prototype.__msover_arrow = function() {
4597	this.bx_hover = true;
4598	if (!this._menu_open)
4599		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-arrow-hover');
4600};
4601BX.CMenuOpenerItem.prototype.__msout_arrow = function() {
4602	this.bx_hover = false;
4603	if (!this._menu_open)
4604		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-arrow-hover bx-context-toolbar-button-arrow-active');
4605};
4606BX.CMenuOpenerItem.prototype.__msdown = function() {
4607	this.bx_active = true;
4608	if (!this._menu_open)
4609		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-active');
4610};
4611BX.CMenuOpenerItem.prototype.__msdown_text = function() {
4612	this.bx_active = true;
4613	if (!this._menu_open)
4614		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-text-active');
4615};
4616BX.CMenuOpenerItem.prototype.__msdown_arrow = function() {
4617	this.bx_active = true;
4618	if (!this._menu_open)
4619		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-arrow-active');
4620};
4621BX.CMenuOpenerItem.prototype.__menu_close = function() {
4622
4623	this._menu_open = false;
4624	this.bx_active = false;
4625	BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-active bx-context-toolbar-button-text-active bx-context-toolbar-button-arrow-active');
4626	if (!this.bx_hover)
4627	{
4628		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-hover bx-context-toolbar-button-text-hover bx-context-toolbar-button-arrow-hover');
4629		this.bx_hover = false;
4630	}
4631};
4632BX.CMenuOpenerItem.prototype.__menu_open = function() {
4633	this._menu_open = true;
4634};
4635
4636BX.CMenuOpenerItem.prototype.__click = function() {BX.evalGlobal(this.item.ONCLICK)};
4637
4638/* global page opener class */
4639BX.CPageOpener = function(arParams)
4640{
4641	//if (null == arParams.pin) arParams.pin = true;
4642	BX.CPageOpener.superclass.constructor.apply(this, arguments);
4643
4644	this.timeout = 505;
4645
4646	window.PAGE_EDIT_CONTROL = this;
4647};
4648BX.extend(BX.CPageOpener, BX.CMenuOpener);
4649
4650BX.CPageOpener.prototype.checkPosition = function()
4651{
4652	if (/*this.isMenuVisible() || this.DIV.style.display == 'none' || */this == BX.proxy_context)
4653		return;
4654
4655	this.correctPosition(BX.proxy_context);
4656};
4657
4658BX.CPageOpener.prototype.correctPosition = function(opener)
4659{
4660	if (this.bPosCorrected) return;
4661	var pos_self;
4662	if (this.DIV.style.display == 'none')
4663	{
4664		pos_self = this.adjustToNodeGetPos();
4665		pos_self.bottom = pos_self.top + 30;
4666		pos_self.right = pos_self.left + 300;
4667	}
4668	else
4669	{
4670		pos_self = BX.pos(this.DIV);
4671	}
4672
4673	var pos_other = BX.pos(opener.Get());
4674	if (this.__check_intersection(pos_self, pos_other))
4675	{
4676		this.DIV.style.display = 'none';
4677
4678		var handler = BX.proxy(this.restorePosition, this);
4679
4680		BX.removeCustomEvent(opener, 'onMenuOpenerHide', handler);
4681		BX.addCustomEvent(opener, 'onMenuOpenerHide', handler);
4682
4683		this.bPosCorrected = true;
4684	}
4685};
4686
4687BX.CPageOpener.prototype.restorePosition = function()
4688{
4689	if (BX.proxy_context && BX.proxy_context.Get().style.display == 'none')
4690	{
4691		this.bPosCorrected = false;
4692
4693		if (this.PARAMS.parent.bx_over || this.PARAMS.pin)
4694			this.UnHide();
4695
4696		BX.removeCustomEvent('onMenuOpenerHide', BX.proxy(this.restorePosition, this));
4697	}
4698};
4699
4700BX.CPageOpener.prototype.UnHide = function()
4701{
4702	if (!this.bPosCorrected)
4703		BX.CPageOpener.superclass.UnHide.apply(this, arguments);
4704};
4705
4706BX.CPageOpener.prototype.Remove = function()
4707{
4708	BX.admin.removeComponentBorder(this.PARAMS.parent);
4709	BX.userOptions.save('global', 'settings', 'page_edit_control_enable', 'N');
4710	this.DIV.style.display = 'none';
4711};
4712
4713/******* HINT ***************/
4714BX.CHintSimple = function()
4715{
4716	BX.CHintSimple.superclass.constructor.apply(this, arguments);
4717};
4718BX.extend(BX.CHintSimple, BX.CHint);
4719
4720BX.CHintSimple.prototype.Init = function()
4721{
4722	this.DIV = document.body.appendChild(BX.create('DIV', {props: {className: 'bx-tooltip-simple'}, style: {display: 'none'}, children: [(this.CONTENT = BX.create('DIV'))]}));
4723
4724	BX.ZIndexManager.register(this.DIV);
4725
4726	if (this.HINT_TITLE)
4727		this.CONTENT.appendChild(BX.create('B', {text: this.HINT_TITLE}));
4728
4729	if (this.HINT)
4730		this.CONTENT_TEXT = this.CONTENT.appendChild(BX.create('DIV')).appendChild(BX.create('SPAN', {html: this.HINT}));
4731
4732	if (this.PARAMS.preventHide)
4733	{
4734		BX.bind(this.DIV, 'mouseout', BX.proxy(this.Hide, this));
4735		BX.bind(this.DIV, 'mouseover', BX.proxy(this.Show, this));
4736	}
4737
4738	this.bInited = true;
4739};
4740
4741/*************************** admin informer **********************************/
4742BX.adminInformer = {
4743
4744	itemsShow: 3,
4745
4746	Init: function (itemsShow)
4747	{
4748		if(itemsShow)
4749			BX.adminInformer.itemsShow = itemsShow;
4750
4751		var informer = BX("admin-informer");
4752
4753		if(informer)
4754		{
4755			document.body.appendChild(informer);
4756			BX.ZIndexManager.register(informer);
4757		}
4758
4759		BX.addCustomEvent("onTopPanelCollapse", BX.proxy(BX.adminInformer.Close, BX.adminInformer));
4760	},
4761
4762	Toggle: function(notifyBlock)
4763	{
4764		var informer = BX("admin-informer");
4765
4766		if(!informer)
4767			return false;
4768
4769		var pos = BX.pos(notifyBlock);
4770
4771		informer.style.top = (parseInt(pos.top)+parseInt(pos.height)+7)+'px';
4772		informer.style.left = pos.left+'px';
4773
4774		if(!BX.hasClass(informer, "adm-informer-active"))
4775			BX.adminInformer.Show(informer);
4776		else
4777			BX.adminInformer.Hide(informer);
4778
4779		return false;
4780	},
4781
4782	Close: function()
4783	{
4784		BX.adminInformer.Hide(BX("admin-informer"));
4785	},
4786
4787	OnInnerClick: function(event)
4788	{
4789		var target = event.target || event.srcElement;
4790
4791		if(target.nodeName.toLowerCase() != 'a' || BX.hasClass(target,"adm-informer-footer"))
4792		{
4793			return BX.PreventDefault(event);
4794		}
4795
4796		return true;
4797	},
4798
4799	ToggleExtra : function()
4800	{
4801		var footerLink = BX("adm-informer-footer");
4802
4803		if (BX.hasClass(footerLink, "adm-informer-footer-collapsed"))
4804			this.ShowAll();
4805		else
4806			this.HideExtra();
4807
4808		return false;
4809	},
4810
4811	ShowAll: function()
4812	{
4813		var informer = BX("admin-informer");
4814		for(var i=0; i<informer.children.length; i++)
4815
4816			if(BX.hasClass(informer.children[i], "adm-informer-item") && informer.children[i].style.display == "none") {
4817				informer.children[i].style.display = "block";
4818			}
4819
4820		var footerLink = BX("adm-informer-footer");
4821
4822		if(footerLink.textContent !== undefined)
4823			footerLink.textContent = BX.message('JSADM_AI_HIDE_EXTRA');
4824		else
4825			footerLink.innerText = BX.message('JSADM_AI_HIDE_EXTRA');
4826
4827		BX.removeClass(footerLink, "adm-informer-footer-collapsed");
4828
4829		return false;
4830	},
4831
4832	HideExtra: function()
4833	{
4834		var informer = BX("admin-informer");
4835		var hided = 0;
4836
4837		for(var i=BX.adminInformer.itemsShow+1; i<informer.children.length; i++)
4838		{
4839			if (BX.hasClass(informer.children[i], "adm-informer-item") && informer.children[i].style.display == "block") {
4840				informer.children[i].style.display = "none";
4841				hided++;
4842			}
4843		}
4844
4845		var footerLink = BX("adm-informer-footer");
4846
4847		var linkText = BX.message('JSADM_AI_ALL_NOTIF')+" ("+(BX.adminInformer.itemsShow+parseInt(hided))+")";
4848
4849		if(footerLink.textContent !== undefined)
4850			footerLink.textContent = linkText;
4851		else
4852			footerLink.innerText = linkText;
4853
4854		BX.addClass(footerLink, "adm-informer-footer-collapsed");
4855
4856		return false;
4857	},
4858
4859	Show: function(informer)
4860	{
4861		var notifButton = BX("adm-header-notif-block");
4862		if (notifButton)
4863			BX.addClass(notifButton, "adm-header-notif-block-active");
4864
4865		BX.onCustomEvent(informer, 'onBeforeAdminInformerShow');
4866		setTimeout(
4867			BX.proxy(function() {
4868					BX.bind(document, "click", BX.proxy(BX.adminInformer.Close, BX.adminInformer));
4869				},
4870				BX.adminInformer
4871			),0
4872		);
4873		BX.addClass(informer, "adm-informer-active");
4874
4875		BX.ZIndexManager.bringToFront(informer);
4876
4877		setTimeout(function() {BX.addClass(informer, "adm-informer-animate");},0);
4878	},
4879
4880	Hide: function(informer)
4881	{
4882		var notifButton = BX("adm-header-notif-block");
4883		if (notifButton)
4884			BX.removeClass(notifButton, "adm-header-notif-block-active");
4885
4886		BX.unbind(document, "click", BX.proxy(BX.adminInformer.Close, BX.adminInformer));
4887
4888		BX.removeClass(informer, "adm-informer-animate");
4889
4890		if (this.IsAnimationSupported())
4891			setTimeout(function() {BX.removeClass(informer, "adm-informer-active");}, 300);
4892		else
4893			BX.removeClass(informer, "adm-informer-active");
4894
4895		BX.onCustomEvent(informer, 'onAdminInformerHide');
4896		//setTimeout(function() {BX.adminInformer.HideExtra();},500);
4897	},
4898
4899	IsAnimationSupported : function()
4900	{
4901		var d = document.body || document.documentElement;
4902		if (typeof(d.style.transition) == "string")
4903			return true;
4904		else if (typeof(d.style.MozTransition) == "string")
4905			return true;
4906		else if (typeof(d.style.OTransition) == "string")
4907			return true;
4908		else if (typeof(d.style.WebkitTransition) == "string")
4909			return true;
4910		else if (typeof(d.style.msTransition) == "string")
4911			return true;
4912
4913		return false;
4914	},
4915
4916
4917	SetItemHtml: function(itemIdx, html)
4918	{
4919		var itemHtmlDiv = BX("adm-informer-item-html-"+itemIdx);
4920
4921		if(!itemHtmlDiv)
4922			return false;
4923
4924		itemHtmlDiv.innerHTML = html;
4925
4926		return true;
4927	},
4928
4929	SetItemFooter: function(itemIdx, html)
4930	{
4931		var itemFooterDiv = BX("adm-informer-item-footer-"+itemIdx);
4932
4933		if(!itemFooterDiv)
4934			return false;
4935
4936		itemFooterDiv.innerHTML = html;
4937
4938		if(html)
4939			itemFooterDiv.style.display = "block";
4940		else
4941			itemFooterDiv.style.display = "none";
4942
4943		return true;
4944	}
4945
4946};
4947
4948}
4948)(window);
4949
4950
4951/* End */
4952;
4953; /* Start:"a:4:{s:4:"full";s:49:"/bitrix/js/main/date/main.date.js?165838843434555";s:6:"source";s:33:"/bitrix/js/main/date/main.date.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
4954;(function(window)
4955{
4956	/****************** ATTENTION *******************************
4957	 * Please do not use Bitrix CoreJS in this class.
4958	 * This class can be called on page without Bitrix Framework
4959	*************************************************************/
4960
4961	if (!window.BX)
4962	{
4963		window.BX = {};
4964	}
4965
4966	if (!window.BX.Main)
4967	{
4968		window.BX.Main = {};
4969	}
4970	else if (window.BX.Main.Date)
4971	{
4972		return;
4973	}
4974
4975	var BX = window.BX;
4976
4977	BX.Main.Date = BX.Main.DateTimeFormat = {
4978
4979		AM_PM_MODE: {
4980			UPPER: 1,
4981			LOWER: 2,
4982			NONE: false
4983		},
4984
4985		format: function(format, timestamp, now, utc)
4986		{
4987			var _this = this;
4988
4989			/*
4990			PHP to Javascript:
4991				time() = new Date()
4992				mktime(...) = new Date(...)
4993				gmmktime(...) = new Date(Date.UTC(...))
4994				mktime(0,0,0, 1, 1, 1970) != 0          new Date(1970,0,1).getTime() != 0
4995				gmmktime(0,0,0, 1, 1, 1970) == 0        new Date(Date.UTC(1970,0,1)).getTime() == 0
4996				date("d.m.Y H:i:s") = BX.Main.Date.format("d.m.Y H:i:s")
4997				gmdate("d.m.Y H:i:s") = BX.Main.Date.format("d.m.Y H:i:s", null, null, true);
4998			*/
4999			var date = Utils.isDate(timestamp) ? new Date(timestamp.getTime()) : Utils.isNumber(timestamp) ? new Date(timestamp * 1000) : new Date();
5000			var nowDate = Utils.isDate(now) ? new Date(now.getTime()) : Utils.isNumber(now) ? new Date(now * 1000) : new Date();
5001			var isUTC = !!utc;
5002
5003			if (Utils.isArray(format))
5004				return _formatDateInterval(format, date, nowDate, isUTC);
5005			else if (!Utils.isNotEmptyString(format))
5006				return "";
5007
5008			var replaceMap = (format.match(/{{([^{}]*)}}/g) || []).map(function(x) { return (x.match(/[^{}]+/) || [''])[0]; });
5009			if (replaceMap.length > 0)
5010			{
5011				replaceMap.forEach(function(element, index) {
5012					format = format.replace("{{"+element+"}}", "{{"+index+"}}");
5013				});
5014			}
5015
5016			var 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;
5017
5018			var dateFormats = {
5019				d : function() {
5020					// Day of the month 01 to 31
5021					return Utils.strPadLeft(getDate(date).toString(), 2, "0");
5022				},
5023
5024				D : function() {
5025					//Mon through Sun
5026					return _this._getMessage("DOW_" + getDay(date));
5027				},
5028
5029				j : function() {
5030					//Day of the month 1 to 31
5031					return getDate(date);
5032				},
5033
5034				l : function() {
5035					//Sunday through Saturday
5036					return _this._getMessage("DAY_OF_WEEK_" + getDay(date));
5037				},
5038
5039				N : function() {
5040					//1 (for Monday) through 7 (for Sunday)
5041					return getDay(date) || 7;
5042				},
5043
5044				S : function() {
5045					//st, nd, rd or th. Works well with j
5046					if (getDate(date) % 10 == 1 && getDate(date) != 11)
5047						return "st";
5048					else if (getDate(date) % 10 == 2 && getDate(date) != 12)
5049						return "nd";
5050					else if (getDate(date) % 10 == 3 && getDate(date) != 13)
5051						return "rd";
5052					else
5053						return "th";
5054				},
5055
5056				w : function() {
5057					//0 (for Sunday) through 6 (for Saturday)
5058					return getDay(date);
5059				},
5060
5061				z : function() {
5062					//0 through 365
5063					var firstDay = new Date(getFullYear(date), 0, 1);
5064					var currentDay = new Date(getFullYear(date), getMonth(date), getDate(date));
5065					return Math.ceil( (currentDay - firstDay) / (24 * 3600 * 1000) );
5066				},
5067
5068				W : function() {
5069					//ISO-8601 week number of year
5070					var newDate  = new Date(date.getTime());
5071					var dayNumber   = (getDay(date) + 6) % 7;
5072					setDate(newDate, getDate(newDate) - dayNumber + 3);
5073					var firstThursday = newDate.getTime();
5074					setMonth(newDate, 0, 1);
5075					if (getDay(newDate) != 4)
5076						setMonth(newDate, 0, 1 + ((4 - getDay(newDate)) + 7) % 7);
5077					var weekNumber = 1 + Math.ceil((firstThursday - newDate) / (7 * 24 * 3600 * 1000));
5078					return Utils.strPadLeft(weekNumber.toString(), 2, "0");
5079				},
5080
5081				F : function() {
5082					//January through December
5083					return _this._getMessage("MONTH_" + (getMonth(date) + 1) + "_S");
5084				},
5085
5086				f : function() {
5087					//January through December
5088					return _this._getMessage("MONTH_" + (getMonth(date) + 1));
5089				},
5090
5091				m : function() {
5092					//Numeric representation of a month 01 through 12
5093					return Utils.strPadLeft((getMonth(date) + 1).toString(), 2, "0");
5094				},
5095
5096				M : function() {
5097					//A short textual representation of a month, three letters Jan through Dec
5098					return _this._getMessage("MON_" + (getMonth(date) + 1));
5099				},
5100
5101				n : function() {
5102					//Numeric representation of a month 1 through 12
5103					return getMonth(date) + 1;
5104				},
5105
5106				t : function() {
5107					//Number of days in the given month 28 through 31
5108					var lastMonthDay = isUTC ? new Date(Date.UTC(getFullYear(date), getMonth(date) + 1, 0)) : new Date(getFullYear(date), getMonth(date) + 1, 0);
5109					return getDate(lastMonthDay);
5110				},
5111
5112				L : function() {
5113					//1 if it is a leap year, 0 otherwise.
5114					var year = getFullYear(date);
5115					return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0 ? 1 : 0);
5116				},
5117
5118				o : function() {
5119					//ISO-8601 year number
5120					var correctDate  = new Date(date.getTime());
5121					setDate(correctDate, getDate(correctDate) - ((getDay(date) + 6) % 7) + 3);
5122					return getFullYear(correctDate);
5123				},
5124
5125				Y : function() {
5126					//A full numeric representation of a year, 4 digits
5127					return getFullYear(date);
5128				},
5129
5130				y : function() {
5131					//A two digit representation of a year
5132					return getFullYear(date).toString().slice(2);
5133				},
5134
5135				a : function() {
5136					//am or pm
5137					return getHours(date) > 11 ? "pm" : "am";
5138				},
5139
5140				A : function() {
5141					//AM or PM
5142					return getHours(date) > 11 ? "PM" : "AM";
5143				},
5144
5145				B : function() {
5146					//000 through 999
5147					var swatch = ((date.getUTCHours() + 1) % 24) + date.getUTCMinutes() / 60 + date.getUTCSeconds() / 3600;
5148					return Utils.strPadLeft(Math.floor(swatch * 1000 / 24).toString(), 3, "0");
5149				},
5150
5151				g : function() {
5152					//12-hour format of an hour without leading zeros 1 through 12
5153					return getHours(date) % 12 || 12;
5154				},
5155
5156				G : function() {
5157					//24-hour format of an hour without leading zeros 0 through 23
5158					return getHours(date);
5159				},
5160
5161				h : function() {
5162					//12-hour format of an hour with leading zeros 01 through 12
5163					return Utils.strPadLeft((getHours(date) % 12 || 12).toString(), 2, "0");
5164				},
5165
5166				H : function() {
5167					//24-hour format of an hour with leading zeros 00 through 23
5168					return Utils.strPadLeft(getHours(date).toString(), 2, "0");
5169				},
5170
5171				i : function() {
5172					//Minutes with leading zeros 00 to 59
5173					return Utils.strPadLeft(getMinutes(date).toString(), 2, "0");
5174				},
5175
5176				s : function() {
5177					//Seconds, with leading zeros 00 through 59
5178					return Utils.strPadLeft(getSeconds(date).toString(), 2, "0");
5179				},
5180
5181				u : function() {
5182					//Microseconds
5183					return Utils.strPadLeft((getMilliseconds(date) * 1000).toString(), 6, "0");
5184				},
5185
5186				e : function() {
5187					if (isUTC)
5188						return "UTC";
5189					return "";
5190				},
5191
5192				I : function() {
5193					if (isUTC)
5194						return 0;
5195
5196					//Whether or not the date is in daylight saving time 1 if Daylight Saving Time, 0 otherwise
5197					var firstJanuary = new Date(getFullYear(date), 0, 1);
5198					var firstJanuaryUTC = Date.UTC(getFullYear(date), 0, 1);
5199					var firstJuly = new Date(getFullYear(date), 6, 0);
5200					var firstJulyUTC = Date.UTC(getFullYear(date), 6, 0);
5201					return 0 + ((firstJanuary - firstJanuaryUTC) !== (firstJuly - firstJulyUTC));
5202				},
5203
5204				O : function() {
5205					if (isUTC)
5206						return "+0000";
5207
5208					//Difference to Greenwich time (GMT) in hours +0200
5209					var timezoneOffset = date.getTimezoneOffset();
5210					var timezoneOffsetAbs = Math.abs(timezoneOffset);
5211					return (timezoneOffset > 0 ? "-" : "+") + Utils.strPadLeft((Math.floor(timezoneOffsetAbs / 60) * 100 + timezoneOffsetAbs % 60).toString(), 4, "0");
5212				},
5213
5214				P : function() {
5215					if (isUTC)
5216						return "+00:00";
5217
5218					//Difference to Greenwich time (GMT) with colon between hours and minutes +02:00
5219					var difference = this.O();
5220					return difference.substr(0, 3) + ":" + difference.substr(3);
5221				},
5222
5223				Z : function() {
5224					if (isUTC)
5225						return 0;
5226					//Timezone offset in seconds. The offset for timezones west of UTC is always negative,
5227					//and for those east of UTC is always positive.
5228					return -date.getTimezoneOffset() * 60;
5229				},
5230
5231				c : function() {
5232					//ISO 8601 date
5233					return "Y-m-d\\TH:i:sP".replace(formatRegex, _replaceDateFormat);
5234				},
5235
5236				r : function() {
5237					//RFC 2822 formatted date
5238					return "D, d M Y H:i:s O".replace(formatRegex, _replaceDateFormat);
5239				},
5240
5241				U : function() {
5242					//Seconds since the Unix Epoch
5243					return Math.floor(date.getTime() / 1000);
5244				},
5245
5246				sago : function() {
5247					return _formatDateMessage(intval((nowDate - date) / 1000), {
5248						"0" : "FD_SECOND_AGO_0",
5249						"1" : "FD_SECOND_AGO_1",
5250						"10_20" : "FD_SECOND_AGO_10_20",
5251						"MOD_1" : "FD_SECOND_AGO_MOD_1",
5252						"MOD_2_4" : "FD_SECOND_AGO_MOD_2_4",
5253						"MOD_OTHER" : "FD_SECOND_AGO_MOD_OTHER"
5254					});
5255				},
5256
5257				sdiff : function() {
5258					return _formatDateMessage(intval((nowDate - date) / 1000), {
5259						"0" : "FD_SECOND_DIFF_0",
5260						"1" : "FD_SECOND_DIFF_1",
5261						"10_20" : "FD_SECOND_DIFF_10_20",
5262						"MOD_1" : "FD_SECOND_DIFF_MOD_1",
5263						"MOD_2_4" : "FD_SECOND_DIFF_MOD_2_4",
5264						"MOD_OTHER" : "FD_SECOND_DIFF_MOD_OTHER"
5265					});
5266				},
5267
5268				sshort : function() {
5269					return _this._getMessage("FD_SECOND_SHORT").replace(/#VALUE#/g, intval((nowDate - date) / 1000));
5270				},
5271
5272				iago : function() {
5273					return _formatDateMessage(intval((nowDate - date) / 60 / 1000), {
5274						"0" : "FD_MINUTE_AGO_0",
5275						"1" : "FD_MINUTE_AGO_1",
5276						"10_20" : "FD_MINUTE_AGO_10_20",
5277						"MOD_1" : "FD_MINUTE_AGO_MOD_1",
5278						"MOD_2_4" : "FD_MINUTE_AGO_MOD_2_4",
5279						"MOD_OTHER" : "FD_MINUTE_AGO_MOD_OTHER"
5280					});
5281				},
5282
5283				idiff : function() {
5284					return _formatDateMessage(intval((nowDate - date) / 60 / 1000), {
5285						"0" : "FD_MINUTE_DIFF_0",
5286						"1" : "FD_MINUTE_DIFF_1",
5287						"10_20" : "FD_MINUTE_DIFF_10_20",
5288						"MOD_1" : "FD_MINUTE_DIFF_MOD_1",
5289						"MOD_2_4" : "FD_MINUTE_DIFF_MOD_2_4",
5290						"MOD_OTHER" : "FD_MINUTE_DIFF_MOD_OTHER"
5291					});
5292				},
5293
5294				isago : function() {
5295					var minutesAgo = intval((nowDate - date) / 60 / 1000);
5296					var result = _formatDateMessage(minutesAgo, {
5297						"0" : "FD_MINUTE_0",
5298						"1" : "FD_MINUTE_1",
5299						"10_20" : "FD_MINUTE_10_20",
5300						"MOD_1" : "FD_MINUTE_MOD_1",
5301						"MOD_2_4" : "FD_MINUTE_MOD_2_4",
5302						"MOD_OTHER" : "FD_MINUTE_MOD_OTHER"
5303					});
5304
5305					result += " ";
5306
5307					var secondsAgo = intval((nowDate - date) / 1000) - (minutesAgo * 60);
5308					result += _formatDateMessage(secondsAgo, {
5309						"0" : "FD_SECOND_AGO_0",
5310						"1" : "FD_SECOND_AGO_1",
5311						"10_20" : "FD_SECOND_AGO_10_20",
5312						"MOD_1" : "FD_SECOND_AGO_MOD_1",
5313						"MOD_2_4" : "FD_SECOND_AGO_MOD_2_4",
5314						"MOD_OTHER" : "FD_SECOND_AGO_MOD_OTHER"
5315					});
5316					return result;
5317				},
5318
5319				ishort : function() {
5320					return _this._getMessage("FD_MINUTE_SHORT").replace(/#VALUE#/g, intval((nowDate - date) / 60 / 1000));
5321				},
5322
5323				Hago : function() {
5324					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 1000), {
5325						"0" : "FD_HOUR_AGO_0",
5326						"1" : "FD_HOUR_AGO_1",
5327						"10_20" : "FD_HOUR_AGO_10_20",
5328						"MOD_1" : "FD_HOUR_AGO_MOD_1",
5329						"MOD_2_4" : "FD_HOUR_AGO_MOD_2_4",
5330						"MOD_OTHER" : "FD_HOUR_AGO_MOD_OTHER"
5331					});
5332				},
5333
5334				Hdiff : function() {
5335					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 1000), {
5336						"0" : "FD_HOUR_DIFF_0",
5337						"1" : "FD_HOUR_DIFF_1",
5338						"10_20" : "FD_HOUR_DIFF_10_20",
5339						"MOD_1" : "FD_HOUR_DIFF_MOD_1",
5340						"MOD_2_4" : "FD_HOUR_DIFF_MOD_2_4",
5341						"MOD_OTHER" : "FD_HOUR_DIFF_MOD_OTHER"
5342					});
5343				},
5344
5345				Hshort : function() {
5346					return _this._getMessage("FD_HOUR_SHORT").replace(/#VALUE#/g, intval((nowDate - date) / 60 / 60 / 1000));
5347				},
5348
5349				yesterday : function() {
5350					return _this._getMessage("FD_YESTERDAY");
5351				},
5352
5353				today : function() {
5354					return _this._getMessage("FD_TODAY");
5355				},
5356
5357				tommorow : function() {
5358					return _this._getMessage("FD_TOMORROW");
5359				},
5360
5361				tomorrow : function() {
5362					return _this._getMessage("FD_TOMORROW");
5363				},
5364
5365				dago : function() {
5366					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 1000), {
5367						"0" : "FD_DAY_AGO_0",
5368						"1" : "FD_DAY_AGO_1",
5369						"10_20" : "FD_DAY_AGO_10_20",
5370						"MOD_1" : "FD_DAY_AGO_MOD_1",
5371						"MOD_2_4" : "FD_DAY_AGO_MOD_2_4",
5372						"MOD_OTHER" : "FD_DAY_AGO_MOD_OTHER"
5373					});
5374				},
5375
5376				ddiff : function() {
5377					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 1000), {
5378						"0" : "FD_DAY_DIFF_0",
5379						"1" : "FD_DAY_DIFF_1",
5380						"10_20" : "FD_DAY_DIFF_10_20",
5381						"MOD_1" : "FD_DAY_DIFF_MOD_1",
5382						"MOD_2_4" : "FD_DAY_DIFF_MOD_2_4",
5383						"MOD_OTHER" : "FD_DAY_DIFF_MOD_OTHER"
5384					});
5385				},
5386
5387				dshort : function() {
5388					return _this._getMessage("FD_DAY_SHORT").replace(/#VALUE#/g, intval((nowDate - date) / 60 / 60 / 24 / 1000));
5389				},
5390
5391				mago : function() {
5392					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 31 / 1000), {
5393						"0" : "FD_MONTH_AGO_0",
5394						"1" : "FD_MONTH_AGO_1",
5395						"10_20" : "FD_MONTH_AGO_10_20",
5396						"MOD_1" : "FD_MONTH_AGO_MOD_1",
5397						"MOD_2_4" : "FD_MONTH_AGO_MOD_2_4",
5398						"MOD_OTHER" : "FD_MONTH_AGO_MOD_OTHER"
5399					});
5400				},
5401
5402				mdiff : function() {
5403					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 31 / 1000), {
5404						"0" : "FD_MONTH_DIFF_0",
5405						"1" : "FD_MONTH_DIFF_1",
5406						"10_20" : "FD_MONTH_DIFF_10_20",
5407						"MOD_1" : "FD_MONTH_DIFF_MOD_1",
5408						"MOD_2_4" : "FD_MONTH_DIFF_MOD_2_4",
5409						"MOD_OTHER" : "FD_MONTH_DIFF_MOD_OTHER"
5410					});
5411				},
5412
5413				mshort : function() {
5414					return _this._getMessage("FD_MONTH_SHORT").replace(/#VALUE#/g, intval((nowDate - date) / 60 / 60 / 24 / 31 / 1000));
5415				},
5416
5417				Yago : function() {
5418					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 365 / 1000), {
5419						"0" : "FD_YEARS_AGO_0",
5420						"1" : "FD_YEARS_AGO_1",
5421						"10_20" : "FD_YEARS_AGO_10_20",
5422						"MOD_1" : "FD_YEARS_AGO_MOD_1",
5423						"MOD_2_4" : "FD_YEARS_AGO_MOD_2_4",
5424						"MOD_OTHER" : "FD_YEARS_AGO_MOD_OTHER"
5425					});
5426				},
5427
5428				Ydiff : function() {
5429					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 365 / 1000), {
5430						"0" : "FD_YEARS_DIFF_0",
5431						"1" : "FD_YEARS_DIFF_1",
5432						"10_20" : "FD_YEARS_DIFF_10_20",
5433						"MOD_1" : "FD_YEARS_DIFF_MOD_1",
5434						"MOD_2_4" : "FD_YEARS_DIFF_MOD_2_4",
5435						"MOD_OTHER" : "FD_YEARS_DIFF_MOD_OTHER"
5436					});
5437				},
5438
5439				Yshort : function() {
5440					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 365 / 1000), {
5441						"0" : "FD_YEARS_SHORT_0",
5442						"1" : "FD_YEARS_SHORT_1",
5443						"10_20" : "FD_YEARS_SHORT_10_20",
5444						"MOD_1" : "FD_YEARS_SHORT_MOD_1",
5445						"MOD_2_4" : "FD_YEARS_SHORT_MOD_2_4",
5446						"MOD_OTHER" : "FD_YEARS_SHORT_MOD_OTHER"
5447					});
5448				},
5449
5450				x : function() {
5451					var ampm = _this.isAmPmMode(true);
5452					var timeFormat = (ampm === _this.AM_PM_MODE.LOWER? "g:i a" : (ampm === _this.AM_PM_MODE.UPPER? "g:i A" : "H:i"));
5453
5454					return _this.format([
5455						["tomorrow", "tomorrow, "+timeFormat],
5456						["-", _this.convertBitrixFormat(_this._getMessage("FORMAT_DATETIME")).replace(/:s/g, "")],
5457						["s", "sago"],
5458						["i", "iago"],
5459						["today", "today, "+timeFormat],
5460						["yesterday", "yesterday, "+timeFormat],
5461						["", _this.convertBitrixFormat(_this._getMessage("FORMAT_DATETIME")).replace(/:s/g, "")]
5462					], date, nowDate, isUTC);
5463				},
5464
5465				X : function() {
5466
5467					var ampm = _this.isAmPmMode(true);
5468					var timeFormat = (ampm === _this.AM_PM_MODE.LOWER? "g:i a" : (ampm === _this.AM_PM_MODE.UPPER? "g:i A" : "H:i"));
5469
5470					var day = _this.format([
5471						["tomorrow", "tomorrow"],
5472						["-", _this.convertBitrixFormat(_this._getMessage("FORMAT_DATE"))],
5473						["today", "today"],
5474						["yesterday", "yesterday"],
5475						["", _this.convertBitrixFormat(_this._getMessage("FORMAT_DATE"))]
5476					], date, nowDate, isUTC);
5477
5478					var time = _this.format([
5479						["tomorrow", timeFormat],
5480						["today", timeFormat],
5481						["yesterday", timeFormat],
5482						["", ""]
5483					], date, nowDate, isUTC);
5484
5485					if (time.length > 0)
5486						return _this._getMessage("FD_DAY_AT_TIME").replace(/#DAY#/g, day).replace(/#TIME#/g, time);
5487					else
5488						return day;
5489				},
5490
5491				Q : function() {
5492					var daysAgo = intval((nowDate - date) / 60 / 60 / 24 / 1000);
5493					if(daysAgo == 0)
5494						return _this._getMessage("FD_DAY_DIFF_1").replace(/#VALUE#/g, 1);
5495					else
5496						return _this.format([ ["d", "ddiff"], ["m", "mdiff"], ["", "Ydiff"] ], date, nowDate);
5497				}
5498			};
5499
5500			var cutZeroTime = false;
5501			if (format[0] && format[0] == "^")
5502			{
5503				cutZeroTime = true;
5504				format = format.substr(1);
5505			}
5506
5507			var result = format.replace(formatRegex, _replaceDateFormat);
5508
5509			if (cutZeroTime)
5510			{
5511				/* 	15.04.12 13:00:00 => 15.04.12 13:00
5512					00:01:00 => 00:01
5513					4 may 00:00:00 => 4 may
5514					01-01-12 00:00 => 01-01-12
5515				*/
5516
5517				result = result.replace(/\s*00:00:00\s*/g, "").
5518								replace(/(\d\d:\d\d)(:00)/g, "$1").
5519								replace(/(\s*00:00\s*)(?!:)/g, "");
5520			}
5521
5522			if (replaceMap.length > 0)
5523			{
5524				replaceMap.forEach(function(element, index) {
5525					result = result.replace("{{"+index+"}}", element);
5526				});
5527			}
5528
5529			return result;
5530
5531			function _formatDateInterval(formats, date, nowDate, isUTC)
5532			{
5533				var secondsAgo = intval((nowDate - date) / 1000);
5534				for (var i = 0; i < formats.length; i++)
5535				{
5536					var formatInterval = formats[i][0];
5537					var formatValue = formats[i][1];
5538					var match = null;
5539					if (formatInterval == "s")
5540					{
5541						if (secondsAgo < 60)
5542							return _this.format(formatValue, date, nowDate, isUTC);
5543					}
5544					else if ((match = /^s(\d+)\>?(\d+)?/.exec(formatInterval)) != null)
5545					{
5546						if (match[1] && match[2])
5547						{
5548							if (
5549								secondsAgo < match[1]
5550								&& secondsAgo > match[2]
5551							)
5552							{
5553								return _this.format(formatValue, date, nowDate, isUTC);
5554							}
5555						}
5556						else if (secondsAgo < match[1])
5557						{
5558							return _this.format(formatValue, date, nowDate, isUTC);
5559						}
5560					}
5561					else if (formatInterval == "i")
5562					{
5563						if (secondsAgo < 60 * 60)
5564							return _this.format(formatValue, date, nowDate, isUTC);
5565					}
5566					else if ((match = /^i(\d+)\>?(\d+)?/.exec(formatInterval)) != null)
5567					{
5568						if (match[1] && match[2])
5569						{
5570							if (
5571								secondsAgo < match[1] * 60
5572								&& secondsAgo > match[2] * 60
5573							)
5574							{
5575								return _this.format(formatValue, date, nowDate, isUTC);
5576							}
5577						}
5578						else if (secondsAgo < match[1] * 60)
5579						{
5580							return _this.format(formatValue, date, nowDate, isUTC);
5581						}
5582					}
5583					else if (formatInterval == "H")
5584					{
5585						if (secondsAgo < 24 * 60 * 60)
5586							return _this.format(formatValue, date, nowDate, isUTC);
5587					}
5588					else if ((match = /^H(\d+)\>?(\d+)?/.exec(formatInterval)) != null)
5589					{
5590						if (match[1] && match[2])
5591						{
5592							if (
5593								secondsAgo < match[1] * 60 * 60
5594								&& secondsAgo > match[2] * 60 * 60
5595							)
5596							{
5597								return _this.format(formatValue, date, nowDate, isUTC);
5598							}
5599						}
5600						else if (secondsAgo < match[1] * 60 * 60)
5601						{
5602							return _this.format(formatValue, date, nowDate, isUTC);
5603						}
5604					}
5605					else if (formatInterval == "d")
5606					{
5607						if (secondsAgo < 31 *24 * 60 * 60)
5608							return _this.format(formatValue, date, nowDate, isUTC);
5609					}
5610					else if ((match = /^d(\d+)\>?(\d+)?/.exec(formatInterval)) != null)
5611					{
5612						if (match[1] && match[2])
5613						{
5614							if (
5615								secondsAgo < match[1] * 24 * 60 * 60
5616								&& secondsAgo > match[2] * 24 * 60 * 60
5617							)
5618							{
5619								return _this.format(formatValue, date, nowDate, isUTC);
5620							}
5621						}
5622						else if (secondsAgo < match[1] * 24 * 60 * 60)
5623						{
5624							return _this.format(formatValue, date, nowDate, isUTC);
5625						}
5626					}
5627					else if (formatInterval == "m")
5628					{
5629						if (secondsAgo < 365 * 24 * 60 * 60)
5630							return _this.format(formatValue, date, nowDate, isUTC);
5631					}
5632					else if ((match = /^m(\d+)\>?(\d+)?/.exec(formatInterval)) != null)
5633					{
5634						if (match[1] && match[2])
5635						{
5636							if (
5637								secondsAgo < match[1] * 31 * 24 * 60 * 60
5638								&& secondsAgo > match[2] * 31 * 24 * 60 * 60
5639							)
5640							{
5641								return _this.format(formatValue, date, nowDate, isUTC);
5642							}
5643						}
5644						else if (secondsAgo < match[1] * 31 * 24 * 60 * 60)
5645						{
5646							return _this.format(formatValue, date, nowDate, isUTC);
5647						}
5648					}
5649					else if (formatInterval == "now")
5650					{
5651						if (date.getTime() == nowDate.getTime())
5652						{
5653							return _this.format(formatValue, date, nowDate, isUTC);
5654						}
5655					}
5656					else if (formatInterval == "today")
5657					{
5658						var year = getFullYear(nowDate), month = getMonth(nowDate), day = getDate(nowDate);
5659						var todayStart = isUTC ? new Date(Date.UTC(year, month, day, 0, 0, 0, 0)) : new Date(year, month, day, 0, 0, 0, 0);
5660						var todayEnd = isUTC ? new Date(Date.UTC(year, month, day+1, 0, 0, 0, 0)) : new Date(year, month, day+1, 0, 0, 0, 0);
5661						if (date >= todayStart && date < todayEnd)
5662							return _this.format(formatValue, date, nowDate, isUTC);
5663					}
5664					else if (formatInterval == "todayFuture")
5665					{
5666						var year = getFullYear(nowDate), month = getMonth(nowDate), day = getDate(nowDate);
5667						var todayStart = nowDate.getTime();
5668						var todayEnd = isUTC ? new Date(Date.UTC(year, month, day+1, 0, 0, 0, 0)) : new Date(year, month, day+1, 0, 0, 0, 0);
5669						if (date >= todayStart && date < todayEnd)
5670							return _this.format(formatValue, date, nowDate, isUTC);
5671					}
5672					else if (formatInterval == "yesterday")
5673					{
5674						year = getFullYear(nowDate); month = getMonth(nowDate); day = getDate(nowDate);
5675						var yesterdayStart = isUTC ? new Date(Date.UTC(year, month, day-1, 0, 0, 0, 0)) : new Date(year, month, day-1, 0, 0, 0, 0);
5676						var yesterdayEnd = isUTC ? new Date(Date.UTC(year, month, day, 0, 0, 0, 0)) : new Date(year, month, day, 0, 0, 0, 0);
5677						if (date >= yesterdayStart && date < yesterdayEnd)
5678							return _this.format(formatValue, date, nowDate, isUTC);
5679					}
5680					else if (formatInterval == "tommorow" || formatInterval == "tomorrow")
5681					{
5682						year = getFullYear(nowDate); month = getMonth(nowDate); day = getDate(nowDate);
5683						var tomorrowStart = isUTC ? new Date(Date.UTC(year, month, day+1, 0, 0, 0, 0)) : new Date(year, month, day+1, 0, 0, 0, 0);
5684						var tomorrowEnd = isUTC ? new Date(Date.UTC(year, month, day+2, 0, 0, 0, 0)) : new Date(year, month, day+2, 0, 0, 0, 0);
5685						if (date >= tomorrowStart && date < tomorrowEnd)
5686							return _this.format(formatValue, date, nowDate, isUTC);
5687					}
5688					else if (formatInterval == "-")
5689					{
5690						if (secondsAgo < 0)
5691							return _this.format(formatValue, date, nowDate, isUTC);
5692					}
5693				}
5694
5695				//return formats.length > 0 ? _this.format(formats.pop()[1], date, nowDate, isUTC) : "";
5696				return formats.length > 0 ? _this.format(formats[formats.length - 1][1], date, nowDate, isUTC) : "";
5697			}
5698
5699			function getFullYear(date) { return isUTC ? date.getUTCFullYear() : date.getFullYear(); }
5700			function getDate(date) { return isUTC ? date.getUTCDate() : date.getDate(); }
5701			function getMonth(date) { return isUTC ? date.getUTCMonth() : date.getMonth(); }
5702			function getHours(date) { return isUTC ? date.getUTCHours() : date.getHours(); }
5703			function getMinutes(date) { return isUTC ? date.getUTCMinutes() : date.getMinutes(); }
5704			function getSeconds(date) { return isUTC ? date.getUTCSeconds() : date.getSeconds(); }
5705			function getMilliseconds(date) { return isUTC ? date.getUTCMilliseconds() : date.getMilliseconds(); }
5706			function getDay(date) { return isUTC ? date.getUTCDay() : date.getDay(); }
5707			function setDate(date, dayValue) { return isUTC ? date.setUTCDate(dayValue) : date.setDate(dayValue); }
5708			function setMonth(date, monthValue, dayValue) { return isUTC ? date.setUTCMonth(monthValue, dayValue) : date.setMonth(monthValue, dayValue); }
5709
5710			function _formatDateMessage(value, messages)
5711			{
5712				var val = value < 100 ? Math.abs(value) : Math.abs(value % 100);
5713				var dec = val % 10;
5714				var message = "";
5715
5716				if(val == 0)
5717					message = _this._getMessage(messages["0"]);
5718				else if (val == 1)
5719					message = _this._getMessage(messages["1"]);
5720				else if (val >= 10 && val <= 20)
5721					message = _this._getMessage(messages["10_20"]);
5722				else if (dec == 1)
5723					message = _this._getMessage(messages["MOD_1"]);
5724				else if (2 <= dec && dec <= 4)
5725					message = _this._getMessage(messages["MOD_2_4"]);
5726				else
5727					message = _this._getMessage(messages["MOD_OTHER"]);
5728
5729				return message.replace(/#VALUE#/g, value);
5730			}
5731
5732			function _replaceDateFormat(match, matchFull)
5733			{
5734				if (dateFormats[match])
5735					return dateFormats[match]();
5736				else
5737					return matchFull;
5738			}
5739
5740			function intval(number)
5741			{
5742				return number >= 0 ? Math.floor(number) : Math.ceil(number);
5743			}
5744		},
5745
5746		convertBitrixFormat: function(format)
5747		{
5748			if (!Utils.isNotEmptyString(format))
5749				return "";
5750
5751			return format.replace("YYYY", "Y")	// 1999
5752						 .replace("MMMM", "F")	// January - December
5753						 .replace("MM", "m")	// 01 - 12
5754						 .replace("M", "M")	// Jan - Dec
5755						 .replace("DD", "d")	// 01 - 31
5756						 .replace("G", "g")	//  1 - 12
5757						 .replace(/GG/i, "G")	//  0 - 23
5758						 .replace("H", "h")	// 01 - 12
5759						 .replace(/HH/i, "H")	// 00 - 24
5760						 .replace("MI", "i")	// 00 - 59
5761						 .replace("SS", "s")	// 00 - 59
5762						 .replace("TT", "A")	// AM - PM
5763						 .replace("T", "a");	// am - pm
5764		},
5765
5766		convertToUTC: function(date)
5767		{
5768			if (!Utils.isDate(date))
5769				return null;
5770
5771			return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));
5772		},
5773
5774		/**
5775		 * Function creates and returns Javascript Date() object from server timestamp regardless of local browser (system) timezone.
5776		 * For example can be used to convert timestamp from some exact date on server to the JS Date object with the same value.
5777		 *
5778		 * @param timestamp - timestamp in seconds
5779		 * @returns {Date}
5780		 */
5781		getNewDate: function(timestamp)
5782		{
5783			return new Date(this.getBrowserTimestamp(timestamp));
5784		},
5785
5786		/**
5787		 * Function transforms server timestamp (in sec) to javascript timestamp (calculated depend on local browser timezone offset). Returns timestamp in milliseconds.
5788		 * Also see BX.Main.Date.getNewDate description.
5789		 *
5790		 * @param timestamp - timestamp in seconds
5791		 * @returns {number}
5792		 */
5793		getBrowserTimestamp: function(timestamp)
5794		{
5795			timestamp = parseInt(timestamp, 10);
5796			var browserOffset = new Date(timestamp * 1000).getTimezoneOffset() * 60;
5797			return (parseInt(timestamp, 10) + parseInt(this._getMessage('SERVER_TZ_OFFSET')) + browserOffset) * 1000;
5798		},
5799
5800		/**
5801		 * Function transforms local browser timestamp (in ms) to server timestamp (calculated depend on local browser timezone offset). Returns timestamp in seconds.
5802		 *
5803		 * @param timestamp - timestamp in milliseconds
5804		 * @returns {number}
5805		 */
5806		getServerTimestamp: function(timestamp)
5807		{
5808			timestamp = parseInt(timestamp, 10);
5809			var browserOffset = new Date(timestamp).getTimezoneOffset() * 60;
5810			return Math.round(timestamp / 1000 - (parseInt(this._getMessage('SERVER_TZ_OFFSET'), 10) + parseInt(browserOffset, 10)));
5811		},
5812
5813		formatLastActivityDate: function(timestamp, now, utc)
5814		{
5815			var ampm = this.isAmPmMode(true);
5816			var timeFormat = (ampm === this.AM_PM_MODE.LOWER? "g:i a" : (ampm === this.AM_PM_MODE.UPPER? "g:i A" : "H:i"));
5817
5818			var format = [
5819			   ["tomorrow", "#01#"+timeFormat],
5820			   ["now" , "#02#"],
5821			   ["todayFuture", "#03#"+timeFormat],
5822			   ["yesterday", "#04#"+timeFormat],
5823			   ["-", this.convertBitrixFormat(this._getMessage("FORMAT_DATETIME")).replace(/:s/g, "")],
5824			   ["s60", "sago"],
5825			   ["i60", "iago"],
5826			   ["H5", "Hago"],
5827			   ["H24", "#03#"+timeFormat],
5828			   ["d31", "dago"],
5829			   ["m12>1", "mago"],
5830			   ["m12>0", "dago"],
5831			   ["", "#05#"]
5832			];
5833			var formattedDate = this.format(format, timestamp, now, utc);
5834			var match = null;
5835			if ((match = /^#(\d+)#(.*)/.exec(formattedDate)) != null)
5836			{
5837				switch (match[1])
5838				{
5839					case "01":
5840						formattedDate = this._getMessage('FD_LAST_SEEN_TOMORROW').replace("#TIME#", match[2]);
5841					break;
5842					case "02":
5843						formattedDate = this._getMessage('FD_LAST_SEEN_NOW');
5844					break;
5845					case "03":
5846						formattedDate = this._getMessage('FD_LAST_SEEN_TODAY').replace("#TIME#", match[2]);
5847					break;
5848					case "04":
5849						formattedDate = this._getMessage('FD_LAST_SEEN_YESTERDAY').replace("#TIME#", match[2]);
5850					break;
5851					case "05":
5852						formattedDate = this._getMessage('FD_LAST_SEEN_MORE_YEAR');
5853					break;
5854					default:
5855						formattedDate = match[2];
5856					break;
5857				}
5858			}
5859
5860			return formattedDate;
5861		},
5862
5863		isAmPmMode: function(returnConst)
5864		{
5865			if (returnConst === true)
5866			{
5867				return this._getMessage('AMPM_MODE');
5868			}
5869
5870			return this._getMessage('AMPM_MODE') !== false;
5871		},
5872
5873		/**
5874		 * The method is designed to replace the localization storage on sites without Bitrix Framework.
5875		 *
5876		 * @param message
5877		 * @returns {*}
5878		 * @private
5879		 */
5880		_getMessage: function(message)
5881		{
5882			return BX.message(message);
5883		},
5884
5885		/**
5886		 * The method used to parse date from string by given format.
5887		 *
5888		 * @param {string} str - date in given format
5889		 * @param {boolean} isUTC - is date in UTC
5890		 * @param {string} formatDate - format of the date without time
5891		 * @param {string} formatDatetime - format of the date with time
5892		 * @returns {Date|null} - returns Date object if string was parsed or null
5893		 */
5894		parse: function(str, isUTC, formatDate, formatDatetime)
5895		{
5896			if (Utils.isNotEmptyString(str))
5897			{
5898				if (!formatDate)
5899					formatDate = this._getMessage('FORMAT_DATE');
5900				if (!formatDatetime)
5901					formatDatetime = this._getMessage('FORMAT_DATETIME');
5902
5903				var regMonths = '';
5904				for (i = 1; i <= 12; i++)
5905				{
5906					regMonths = regMonths + '|' + this._getMessage('MON_'+i);
5907				}
5908
5909				var
5910					expr = new RegExp('([0-9]+|[a-z]+' + regMonths + ')', 'ig'),
5911					aDate = str.match(expr),
5912					aFormat = formatDate.match(/(DD|MI|MMMM|MM|M|YYYY)/ig),
5913					i, cnt,
5914					aDateArgs=[], aFormatArgs=[],
5915					aResult={};
5916
5917				if (!aDate)
5918				{
5919					return null;
5920				}
5921
5922				if(aDate.length > aFormat.length)
5923				{
5924					aFormat = formatDatetime.match(/(DD|MI|MMMM|MM|M|YYYY|HH|H|SS|TT|T|GG|G)/ig);
5925				}
5926
5927				for(i = 0, cnt = aDate.length; i < cnt; i++)
5928				{
5929					if(aDate[i].trim() !== '')
5930					{
5931						aDateArgs[aDateArgs.length] = aDate[i];
5932					}
5933				}
5934
5935				for(i = 0, cnt = aFormat.length; i < cnt; i++)
5936				{
5937					if(aFormat[i].trim() !== '')
5938					{
5939						aFormatArgs[aFormatArgs.length] = aFormat[i];
5940					}
5941				}
5942
5943				var m = Utils.array_search('MMMM', aFormatArgs);
5944				if (m > 0)
5945				{
5946					aDateArgs[m] = this.getMonthIndex(aDateArgs[m]);
5947					aFormatArgs[m] = "MM";
5948				}
5949				else
5950				{
5951					m = Utils.array_search('M', aFormatArgs);
5952					if (m > 0)
5953					{
5954						aDateArgs[m] = this.getMonthIndex(aDateArgs[m]);
5955						aFormatArgs[m] = "MM";
5956					}
5957				}
5958
5959				for(i = 0, cnt = aFormatArgs.length; i < cnt; i++)
5960				{
5961					var k = aFormatArgs[i].toUpperCase();
5962					aResult[k] = k === 'T' || k === 'TT' ? aDateArgs[i] : parseInt(aDateArgs[i], 10);
5963				}
5964
5965				if(aResult['DD'] > 0 && aResult['MM'] > 0 && aResult['YYYY'] > 0)
5966				{
5967					var d = new Date();
5968
5969					if(isUTC)
5970					{
5971						d.setUTCDate(1);
5972						d.setUTCFullYear(aResult['YYYY']);
5973						d.setUTCMonth(aResult['MM'] - 1);
5974						d.setUTCDate(aResult['DD']);
5975						d.setUTCHours(0, 0, 0, 0);
5976					}
5977					else
5978					{
5979						d.setDate(1);
5980						d.setFullYear(aResult['YYYY']);
5981						d.setMonth(aResult['MM'] - 1);
5982						d.setDate(aResult['DD']);
5983						d.setHours(0, 0, 0, 0);
5984					}
5985
5986					if(
5987						(!isNaN(aResult['HH']) || !isNaN(aResult['GG']) || !isNaN(aResult['H']) || !isNaN(aResult['G']))
5988						&& !isNaN(aResult['MI'])
5989					)
5990					{
5991						if (!isNaN(aResult['H']) || !isNaN(aResult['G']))
5992						{
5993							var
5994								bPM = (aResult['T']||aResult['TT']||'am').toUpperCase() === 'PM',
5995								h = parseInt(aResult['H']||aResult['G']||0, 10);
5996
5997							if(bPM)
5998							{
5999								aResult['HH'] = h + (h === 12 ? 0 : 12);
6000							}
6001							else
6002							{
6003								aResult['HH'] = h < 12 ? h : 0;
6004							}
6005						}
6006						else
6007						{
6008							aResult['HH'] = parseInt(aResult['HH']||aResult['GG']||0, 10);
6009						}
6010
6011						if (isNaN(aResult['SS']))
6012							aResult['SS'] = 0;
6013
6014						if(isUTC)
6015						{
6016							d.setUTCHours(aResult['HH'], aResult['MI'], aResult['SS']);
6017						}
6018						else
6019						{
6020							d.setHours(aResult['HH'], aResult['MI'], aResult['SS']);
6021						}
6022					}
6023
6024					return d;
6025				}
6026			}
6027
6028			return null;
6029		},
6030
6031		getMonthIndex: function(month)
6032		{
6033			var
6034				i,
6035				q = month.toUpperCase(),
6036				wordMonthCut = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'],
6037				wordMonth = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
6038
6039			for (i = 1; i <= 12; i++)
6040			{
6041				if (q === this._getMessage('MON_'+i).toUpperCase()
6042					|| q === this._getMessage('MONTH_'+i).toUpperCase()
6043					|| q === wordMonthCut[i-1].toUpperCase()
6044					|| q === wordMonth[i-1].toUpperCase())
6045				{
6046					return i;
6047				}
6048			}
6049			return month;
6050		}
6051	};
6052
6053	/**
6054	 * @private
6055	 */
6056	var Utils = {
6057		isDate: function(item) {
6058			return item && Object.prototype.toString.call(item) == "[object Date]";
6059		},
6060		isNumber: function(item) {
6061			return item === 0 ? true : (item ? (typeof (item) == "number" || item instanceof Number) : false);
6062		},
6063		isArray: function(item) {
6064			return item && Object.prototype.toString.call(item) == "[object Array]";
6065		},
6066		isString: function(item) {
6067			return item === '' ? true : (item ? (typeof (item) == "string" || item instanceof String) : false);
6068		},
6069		isNotEmptyString: function(item) {
6070			return this.isString(item) ? item.length > 0 : false;
6071		},
6072		strPadLeft: function(input, padLength, padString)
6073		{
6074			var i = input.length, q=padString.length;
6075			if (i >= padLength) return input;
6076
6077			for(;i<padLength;i+=q)
6078				input = padString + input;
6079
6080			return input;
6081		},
6082		/**
6083		 * @deprecated
6084		 * @use myArr.findIndex(item => item === needle);
6085		 */
6086		array_search: function(needle, haystack)
6087		{
6088			for(var i = 0; i < haystack.length; i++)
6089			{
6090				if(haystack[i] == needle)
6091					return i;
6092			}
6093			return -1;
6094		},
6095	};
6096
6097})(window);
6098
6099/* End */
6100;
6101; /* Start:"a:4:{s:4:"full";s:49:"/bitrix/js/main/core/core_date.js?161472698336080";s:6:"source";s:33:"/bitrix/js/main/core/core_date.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
6102;(function(){
6103
6104if (BX.date)
6105	return;
6106
6107BX.date = BX.Main.Date;
6108
6109/************************************** calendar class **********************************/
6110
6111var obCalendarSingleton = null;
6112
6113/*
6114params: {
6115	node: bind element || document.body
6116
6117	value - start value in site format (using 'field' param if 'value' does not exist)
6118	callback - date check handler. can return false to prevent calendar closing.
6119	callback_after - another handler, called after date picking
6120
6121	field - field to read/write data
6122
6123	bTime = true - whether to enable time control
6124	bHideTime = false - whether to hide time control by default
6125
6126	currentTime - current UTC time()
6127
6128}
6129*/
6130
6131
6132BX.calendar = function(params)
6133{
6134	return BX.calendar.get().Show(params);
6135};
6136
6137BX.calendar.get = function()
6138{
6139	if (!obCalendarSingleton)
6140		obCalendarSingleton = new BX.JCCalendar();
6141
6142	return obCalendarSingleton;
6143};
6144
6145// simple func for compatibility with the oldies
6146BX.calendar.InsertDaysBack = function(input, days)
6147{
6148	if (days != '')
6149	{
6150		var d = new Date();
6151		if(days > 0)
6152		{
6153			d.setTime(d.valueOf() - days*86400000);
6154		}
6155
6156		input.value = BX.date.format(BX.date.convertBitrixFormat(BX.message('FORMAT_DATE')), d, null);
6157	}
6158	else
6159	{
6160		input.value = '';
6161	}
6162};
6163
6164BX.calendar.ValueToString = function(value, bTime, bUTC)
6165{
6166	return BX.date.format(
6167		BX.date.convertBitrixFormat(BX.message(bTime ? 'FORMAT_DATETIME' : 'FORMAT_DATE')),
6168		value,
6169		null,
6170		!!bUTC
6171	);
6172};
6173
6174BX.calendar.ValueToStringFormat = function(value, bitrixFormat, bUTC)
6175{
6176	return BX.date.format(
6177		BX.date.convertBitrixFormat(bitrixFormat),
6178		value,
6179		null,
6180		!!bUTC
6181	);
6182};
6183
6184
6185BX.CalendarPeriod =
6186{
6187	Init: function(inputFrom, inputTo, selPeriod)
6188	{
6189		if((inputFrom.value != "" || inputTo.value != "") && selPeriod.value == "")
6190			selPeriod.value = "interval";
6191
6192		selPeriod.onchange();
6193	},
6194
6195	ChangeDirectOpts: function(peroidValue, selPParent) // "week" || "others"
6196	{
6197		var selDirect = BX.findChild(selPParent, {'className':'adm-select adm-calendar-direction'}, true);
6198
6199		if(peroidValue == "week")
6200		{
6201			selDirect.options[0].text = BX.message('JSADM_CALEND_PREV_WEEK');
6202			selDirect.options[1].text = BX.message('JSADM_CALEND_CURR_WEEK');
6203			selDirect.options[2].text = BX.message('JSADM_CALEND_NEXT_WEEK');
6204		}
6205		else
6206		{
6207			selDirect.options[0].text = BX.message('JSADM_CALEND_PREV');
6208			selDirect.options[1].text = BX.message('JSADM_CALEND_CURR');
6209			selDirect.options[2].text = BX.message('JSADM_CALEND_NEXT');
6210		}
6211	},
6212
6213	SaveAndClearInput: function(oInput)
6214	{
6215		if(!window.SavedPeriodValues)
6216			window.SavedPeriodValues = {};
6217
6218		window.SavedPeriodValues[oInput.id] = oInput.value;
6219		oInput.value="";
6220	},
6221
6222	RestoreInput: function(oInput)
6223	{
6224		if(!window.SavedPeriodValues || !window.SavedPeriodValues[oInput.id])
6225			return;
6226
6227		oInput.value = window.SavedPeriodValues[oInput.id];
6228		delete(window.SavedPeriodValues[oInput.id]);
6229	},
6230
6231	OnChangeP: function(sel)
6232	{
6233		var selPParent = sel.parentNode.parentNode;
6234		var bShowFrom, bShowTo, bShowDirect, bShowSeparate;
6235		bShowFrom = bShowTo = bShowDirect = bShowSeparate = false;
6236
6237		var inputFromWrap = BX.findChild(selPParent, {'className':'adm-input-wrap adm-calendar-inp adm-calendar-first'});
6238		var inputToWrap = BX.findChild(selPParent, {'className':'adm-input-wrap adm-calendar-second'});
6239		var selDirectWrap = BX.findChild(selPParent, {'className':'adm-select-wrap adm-calendar-direction'});
6240		var separator = BX.findChild(selPParent, {'className':'adm-calendar-separate'});
6241		var inputFrom = BX.findChild(selPParent, {'className':'adm-input adm-calendar-from'},true);
6242		var inputTo = BX.findChild(selPParent, {'className':'adm-input adm-calendar-to'},true);
6243
6244		// define who must be shown
6245		switch (sel.value)
6246		{
6247			case "day":
6248			case "week":
6249			case "month":
6250			case "quarter":
6251			case "year":
6252				bShowDirect=true;
6253				BX.CalendarPeriod.OnChangeD(selDirectWrap.children[0]);
6254				break;
6255
6256			case "before":
6257				bShowTo = true;
6258				break;
6259
6260			case "after":
6261				bShowFrom = true;
6262				break;
6263
6264			case "exact":
6265				bShowFrom= true;
6266				break;
6267
6268			case "interval":
6269				bShowFrom = bShowTo = bShowSeparate = true;
6270				BX.CalendarPeriod.RestoreInput(inputFrom);
6271				BX.CalendarPeriod.RestoreInput(inputTo);
6272
6273				break;
6274
6275			case "":
6276				BX.CalendarPeriod.SaveAndClearInput(inputFrom);
6277				BX.CalendarPeriod.SaveAndClearInput(inputTo);
6278				break;
6279
6280			default:
6281				break;
6282
6283		}
6284
6285		BX.CalendarPeriod.ChangeDirectOpts(sel.value, selPParent);
6286
6287		inputFromWrap.style.display = (bShowFrom? 'inline-block':'none');
6288		inputToWrap.style.display = (bShowTo? 'inline-block':'none');
6289		selDirectWrap.style.display = (bShowDirect? 'inline-block':'none');
6290		separator.style.display = (bShowSeparate? 'inline-block':'none');
6291	},
6292
6293
6294	OnChangeD: function(sel)
6295	{
6296		var selPParent = sel.parentNode.parentNode;
6297		var inputFrom = BX.findChild(selPParent, {'className':'adm-input adm-calendar-from'},true);
6298		var inputTo = BX.findChild(selPParent, {'className':'adm-input adm-calendar-to'},true);
6299		var selPeriod = BX.findChild(selPParent, {'className':'adm-select adm-calendar-period'},true);
6300
6301		var offset=0;
6302
6303		switch (sel.value)
6304		{
6305			case "previous":
6306				offset = -1;
6307				break;
6308
6309			case "next":
6310				offset = 1;
6311				break;
6312
6313			case "current":
6314			default:
6315				break;
6316
6317		}
6318
6319		var from = false;
6320		var to = false;
6321
6322		var today = new Date();
6323		var year = today.getFullYear();
6324		var month = today.getMonth();
6325		var day = today.getDate();
6326		var dayW = today.getDay();
6327
6328		if (dayW == 0)
6329				dayW = 7;
6330
6331		switch (selPeriod.value)
6332		{
6333			case "day":
6334				from = new Date(year, month, day+offset, 0, 0, 0);
6335				to = new Date(year, month, day+offset, 23, 59, 59);
6336				break;
6337
6338			case "week":
6339				from = new Date(year, month, day-dayW+1+offset*7, 0, 0, 0);
6340				to = new Date(year, month, day+(7-dayW)+offset*7, 23, 59, 59);
6341				break;
6342
6343			case "month":
6344				from = new Date(year, month+offset, 1, 0, 0, 0);
6345				to = new Date(year, month+1+offset, 0, 23, 59, 59);
6346				break;
6347
6348			case "quarter":
6349				var quarterNum = Math.floor((month/3))+offset;
6350				from = new Date(year, 3*(quarterNum), 1, 0, 0, 0);
6351				to = new Date(year, 3*(quarterNum+1), 0, 23, 59, 59);
6352				break;
6353
6354			case "year":
6355				from = new Date(year+offset, 0, 1, 0, 0, 0);
6356				to = new Date(year+1+offset, 0, 0, 23, 59, 59);
6357				break;
6358
6359			default:
6360				break;
6361		}
6362
6363		var format = window[inputFrom.name+"_bTime"] ? BX.message('FORMAT_DATETIME') : BX.message('FORMAT_DATE');
6364
6365		if(from)
6366		{
6367			inputFrom.value = BX.formatDate(from, format);
6368			BX.addClass(inputFrom,"adm-calendar-inp-setted");
6369		}
6370
6371		if(to)
6372		{
6373			inputTo.value = BX.formatDate(to, format);
6374			BX.addClass(inputTo,"adm-calendar-inp-setted");
6375		}
6376	}
6377};
6378
6379
6380BX.JCCalendar = function()
6381{
6382	this.params = {};
6383
6384	this.bAmPm = BX.isAmPmMode();
6385
6386	this.popup = null;
6387	this.popup_month = null;
6388	this.popup_year = null;
6389	this.month_popup_classname = '';
6390	this.year_popup_classname = '';
6391	this.value = null;
6392	this._layers = {};
6393	this._current_layer = null;
6394
6395	this.DIV = null;
6396	this.PARTS = {};
6397
6398	this.weekStart = 0;
6399	this.numRows = 6;
6400
6401	this._create = function(params)
6402	{
6403		this.popup = new BX.PopupWindow('calendar_popup_' + Math.random(), params.node, {
6404			closeByEsc: true,
6405			autoHide: false,
6406			content: this._get_content(),
6407			bindOptions: {forceBindPosition: true}
6408		});
6409
6410		BX.bind(this.popup.popupContainer, 'click', function(event) {
6411			event.stopPropagation();
6412		});
6413	};
6414
6415	this._auto_hide_disable = function()
6416	{
6417		BX.unbind(document, 'click', BX.proxy(this._auto_hide, this));
6418	};
6419
6420	this._auto_hide_enable = function()
6421	{
6422		BX.bind(document, 'click', BX.proxy(this._auto_hide, this));
6423	};
6424
6425	this._auto_hide = function(e)
6426	{
6427		this._auto_hide_disable();
6428		this.popup.close();
6429	};
6430
6431	this._get_content = function()
6432	{
6433		var _layer_onclick = BX.delegate(function(e) {
6434			e = e||window.event;
6435			this.SetDate(
6436				new Date(parseInt(BX.proxy_context.getAttribute('data-date'))),
6437				(e.type === 'dblclick' || (this.params.bCompatibility && !this.params.bTimeVisibility))
6438			)
6439		}, this);
6440
6441		this.DIV = BX.create('DIV', {
6442			props: {className: 'bx-calendar'},
6443			children: [
6444				BX.create('DIV', {
6445					props: {
6446						className: 'bx-calendar-header'
6447					},
6448					children: [
6449						BX.create('A', {
6450							attrs: {href: 'javascript:void(0)'},
6451							props: {className: 'bx-calendar-left-arrow'},
6452							events: {click: BX.proxy(this._prev, this)}
6453						}),
6454
6455						BX.create('SPAN', {
6456							props: {className: 'bx-calendar-header-content'},
6457							children: [
6458								(this.PARTS.MONTH = BX.create('A', {
6459									attrs: {href: 'javascript:void(0)'},
6460									props: {className: 'bx-calendar-top-month'},
6461									events: {click: BX.proxy(this._menu_month, this)}
6462								})),
6463
6464								(this.PARTS.YEAR = BX.create('A', {
6465									attrs: {href: 'javascript:void(0)'},
6466									props: {className: 'bx-calendar-top-year'},
6467									events: {click: BX.proxy(this._menu_year, this)}
6468								}))
6469							]
6470						}),
6471
6472						BX.create('A', {
6473							attrs: {href: 'javascript:void(0)'},
6474							props: {className: 'bx-calendar-right-arrow'},
6475							events: {click: BX.proxy(this._next, this)}
6476						})
6477					]
6478				}),
6479
6480				(this.PARTS.WEEK = BX.create('DIV', {
6481					props: {
6482						className: 'bx-calendar-name-day-wrap'
6483					}
6484				})),
6485
6486				(this.PARTS.LAYERS = BX.create('DIV', {
6487					props: {
6488						className: 'bx-calendar-cell-block'
6489					},
6490					events: {
6491						click: BX.delegateEvent({className: 'bx-calendar-cell'}, _layer_onclick),
6492						dblclick: BX.delegateEvent({className: 'bx-calendar-cell'}, _layer_onclick)
6493					}
6494				})),
6495
6496				(this.PARTS.TIME = BX.create('DIV', {
6497					props: {
6498						className: 'bx-calendar-set-time-wrap'
6499					},
6500					events: {
6501						click: BX.delegateEvent(
6502							{attr: 'data-action'},
6503							BX.delegate(this._time_actions, this)
6504						)
6505					},
6506					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>'
6507				})),
6508
6509				(this.PARTS.BUTTONS = BX.create('DIV', {
6510					props: {className: 'bx-calendar-button-block'},
6511					events: {
6512						click: BX.delegateEvent(
6513							{attr: 'data-action'},
6514							BX.delegate(this._button_actions, this)
6515						)
6516					},
6517					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>'
6518				}))
6519			]
6520		});
6521
6522		this.PARTS.TIME_INPUT_H = BX.findChild(this.PARTS.TIME, {tag: 'INPUT'}, true);
6523		this.PARTS.TIME_INPUT_M = this.PARTS.TIME_INPUT_H.nextSibling.nextSibling;
6524
6525		if (this.bAmPm)
6526			this.PARTS.TIME_AMPM = this.PARTS.TIME_INPUT_M.nextSibling.firstChild;
6527
6528		var spinner = (new BX.JCSpinner({
6529			input: this.PARTS.TIME_INPUT_H,
6530			callback_change: BX.proxy(this._check_time, this),
6531			bSaveValue: false
6532		})).Show();
6533		spinner.className = 'bx-calendar-form-arrow-l';
6534		this.PARTS.TIME_INPUT_H.parentNode.insertBefore(spinner, this.PARTS.TIME_INPUT_H);
6535
6536		spinner = (new BX.JCSpinner({
6537			input: this.PARTS.TIME_INPUT_M,
6538			callback_change: BX.proxy(this._check_time, this),
6539			bSaveValue: true
6540		})).Show();
6541		spinner.className = 'bx-calendar-form-arrow-r';
6542		if (!this.PARTS.TIME_INPUT_M.nextSibling)
6543			this.PARTS.TIME_INPUT_M.parentNode.appendChild(spinner);
6544		else
6545			this.PARTS.TIME_INPUT_M.parentNode.insertBefore(spinner, this.PARTS.TIME_INPUT_M.nextSibling);
6546
6547		for (var i = 0; i < 7; i++)
6548		{
6549			this.PARTS.WEEK.appendChild(BX.create('SPAN', {
6550				props: {
6551					className: 'bx-calendar-name-day'
6552				},
6553				text: BX.message('DOW_' + ((i + this.weekStart) % 7))
6554			}));
6555		}
6556
6557		return this.DIV;
6558	};
6559
6560	this._time_actions = function()
6561	{
6562		switch (BX.proxy_context.getAttribute('data-action'))
6563		{
6564			case 'time_show':
6565				BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
6566				if (this.params.bCompatibility)
6567				{
6568					BX.removeClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled');
6569				}
6570				this.popup.adjustPosition();
6571			break;
6572			case 'time_hide':
6573				BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
6574				if (this.params.bCompatibility)
6575				{
6576					this._saveChoice('hide');
6577					BX.addClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled');
6578				}
6579				this.popup.adjustPosition();
6580			break;
6581			case 'time_ampm':
6582				this.PARTS.TIME_AMPM.innerHTML = this.PARTS.TIME_AMPM.innerHTML == 'AM' ? 'PM' : 'AM';
6583			break;
6584			case 'time_ampm_up':
6585				this._check_time({bSaveValue: false}, null, 12);
6586				return;
6587			break;
6588			case 'time_ampm_down':
6589				this._check_time({bSaveValue: false}, null, -12);
6590				return;
6591			break;
6592		}
6593
6594		this._check_time();
6595	};
6596
6597	this._button_actions = function()
6598	{
6599		switch (BX.proxy_context.getAttribute('data-action'))
6600		{
6601			case 'submit':
6602				if (this.params.bCompatibility)
6603				{
6604					this._saveChoice('show');
6605				}
6606				this.SaveValue();
6607			break;
6608			case 'cancel':
6609				this.Close();
6610			break;
6611		}
6612	};
6613
6614	this._saveChoice = function(state)
6615	{
6616		if (this.params.bCategoryTimeVisibilityOption)
6617		{
6618			BX.userOptions.save(
6619				this.params.bCategoryTimeVisibilityOption,
6620				this.params.bNameTimeVisibilityOption,
6621				'visibility',
6622				(state === 'show' ? 'Y' : 'N')
6623			);
6624		}
6625
6626		this._bTimeVisibility = (state === 'show');
6627		this.params.bTimeVisibility = this._bTimeVisibility;
6628	};
6629
6630	this._check_time = function(params, value, direction)
6631	{
6632		var h = parseInt(this.PARTS.TIME_INPUT_H.value.substring(0,5),10)||0,
6633			m = parseInt(this.PARTS.TIME_INPUT_M.value.substring(0,5),10)||0,
6634			bChanged = false;
6635
6636		if (!!params && !params.bSaveValue)
6637		{
6638			this.value.setUTCHours(this.value.getUTCHours() + direction);
6639		}
6640		else if (!isNaN(h))
6641		{
6642			if (this.bAmPm)
6643			{
6644				if (h != 12 && this.PARTS.TIME_AMPM.innerHTML == 'PM')
6645				{
6646					h += 12;
6647				}
6648			}
6649
6650			bChanged = true;
6651			this.value.setUTCHours(h % 24);
6652		}
6653
6654		if (!isNaN(m))
6655		{
6656			bChanged = true;
6657			this.value.setUTCMinutes(m % 60);
6658		}
6659
6660		if (bChanged)
6661		{
6662			this.SetValue(this.value);
6663		}
6664	};
6665
6666	this._set_layer = function()
6667	{
6668		var layerId = parseInt(this.value.getUTCFullYear() + '' + BX.util.str_pad_left(this.value.getUTCMonth()+'', 2, "0"));
6669
6670		if (!this._layers[layerId])
6671		{
6672			this._layers[layerId] = this._create_layer();
6673			this._layers[layerId].BXLAYERID = layerId;
6674		}
6675
6676		if (this._current_layer)
6677		{
6678			var v = new Date(this.value.valueOf());
6679			v.setUTCHours(0); v.setUTCMinutes(0);
6680
6681			var cur_value = BX.findChild(this._layers[layerId], {
6682					tag: 'A',
6683					className: 'bx-calendar-active'
6684				}, true),
6685				new_value = BX.findChild(this._layers[layerId], {
6686					tag: 'A',
6687					attr: {
6688						'data-date' : v.valueOf() + ''
6689					}
6690				}, true);
6691
6692			if (cur_value)
6693			{
6694				BX.removeClass(cur_value, 'bx-calendar-active');
6695			}
6696
6697			if (new_value)
6698			{
6699				BX.addClass(new_value, 'bx-calendar-active');
6700			}
6701
6702			this._replace_layer(this._current_layer, this._layers[layerId]);
6703		}
6704		else
6705		{
6706			this.PARTS.LAYERS.appendChild(this._layers[layerId]);
6707		}
6708
6709		this._current_layer = this._layers[layerId];
6710	};
6711
6712	this._replace_layer = function(old_layer, new_layer)
6713	{
6714		if (old_layer != new_layer)
6715		{
6716			if (!BX.browser.IsIE() || BX.browser.IsDoctype())
6717			{
6718				var dir = old_layer.BXLAYERID > new_layer.BXLAYERID ? 1 : -1;
6719
6720				var old_top = 0;
6721				var new_top = -dir * old_layer.offsetHeight;
6722
6723				old_layer.style.position = 'relative';
6724				old_layer.style.top = "0px";
6725				old_layer.style.zIndex = 5;
6726
6727				new_layer.style.position = 'absolute';
6728				new_layer.style.top = new_top + 'px';
6729				new_layer.style.zIndex = 6;
6730
6731				this.PARTS.LAYERS.appendChild(new_layer);
6732
6733				var delta = 15;
6734
6735				var f;
6736				(f = function() {
6737					new_top += dir * delta;
6738					old_top += dir * delta;
6739
6740					if (dir * new_top < 0)
6741					{
6742						old_layer.style.top = old_top + 'px';
6743						new_layer.style.top = new_top + 'px';
6744						setTimeout(f, 10);
6745					}
6746					else
6747					{
6748						old_layer.parentNode.removeChild(old_layer);
6749
6750						new_layer.style.top = "0px";
6751						new_layer.style.position = 'static';
6752						new_layer.style.zIndex = 0;
6753					}
6754				})();
6755			}
6756			else
6757			{
6758				this.PARTS.LAYERS.replaceChild(new_layer, old_layer);
6759			}
6760		}
6761	};
6762
6763	this._create_layer = function()
6764	{
6765		var l = BX.create('DIV', {
6766			props: {
6767				className: 'bx-calendar-layer'
6768			}
6769		});
6770
6771		var month_start = new Date(this.value);
6772		month_start.setUTCHours(0);
6773		month_start.setUTCMinutes(0);
6774
6775		month_start.setUTCDate(1);
6776
6777		if (month_start.getUTCDay() != this.weekStart)
6778		{
6779			var d = month_start.getUTCDay() - this.weekStart;
6780			d += d < 0 ? 7 : 0;
6781			month_start.setUTCDate(month_start.getUTCDate()-d);
6782		}
6783
6784		var cur_month = this.value.getUTCMonth(),
6785			cur_day = this.value.getUTCDate(),
6786			s = '';
6787		for (var i = 0; i < this.numRows; i++)
6788		{
6789			s += '<div class="bx-calendar-range'
6790				+(i == this.numRows-1 ? ' bx-calendar-range-noline' : '')
6791				+'">';
6792
6793			for (var j = 0; j < 7; j++)
6794			{
6795				d = month_start.getUTCDate();
6796				var wd = month_start.getUTCDay();
6797				var className = 'bx-calendar-cell';
6798
6799				if (cur_month != month_start.getUTCMonth())
6800					className += ' bx-calendar-date-hidden';
6801				else if (cur_day == d)
6802					className += ' bx-calendar-active';
6803
6804
6805				if (wd == 0 || wd == 6)
6806					className += ' bx-calendar-weekend';
6807
6808				s += '<a href="javascript:void(0)" class="'+className+'" data-date="' + month_start.valueOf() + '">' + d + '</a>';
6809
6810				month_start.setUTCDate(month_start.getUTCDate()+1);
6811			}
6812			s += '</div>';
6813		}
6814
6815		l.innerHTML = s;
6816
6817		return l;
6818	};
6819
6820	this._prev = function()
6821	{
6822		this.SetMonth(this.value.getUTCMonth()-1);
6823	};
6824
6825	this._next = function()
6826	{
6827		this.SetMonth(this.value.getUTCMonth()+1);
6828	};
6829
6830	this._menu_month_content = function()
6831	{
6832		var months = '', cur_month = this.value.getMonth(), i;
6833		for (i = 0; i < 12; i++)
6834		{
6835			months += '<span class="bx-calendar-month'+(i == cur_month ? ' bx-calendar-month-active' : '')+'" data-bx-month="' + i + '">' + BX.message('MONTH_' + (i + 1)) + '</span>';
6836		}
6837
6838		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>';
6839	};
6840
6841	this._menu_month = function()
6842	{
6843		if (!this.popup_month)
6844		{
6845			this.popup_month = new BX.PopupWindow(
6846				'calendar_popup_month_' + Math.random(), this.PARTS.MONTH,
6847				{
6848					content: this._menu_month_content(),
6849					closeByEsc: true,
6850					autoHide: true,
6851					offsetTop: -29,
6852					offsetLeft: -1,
6853					className: this.month_popup_classname,
6854					events: {
6855						onPopupShow: BX.delegate(function() {
6856							if (this.popup_year)
6857							{
6858								this.popup_year.close();
6859							}
6860						}, this)
6861					}
6862				}
6863			);
6864
6865			BX.bind(this.popup_month.popupContainer, 'click', BX.proxy(this.month_popup_click, this));
6866			this.popup_month.BXMONTH = this.value.getUTCMonth();
6867		}
6868		else if (this.popup_month.BXMONTH != this.value.getUTCMonth())
6869		{
6870			this.popup_month.setContent(this._menu_month_content());
6871			this.popup_month.BXMONTH = this.value.getUTCMonth();
6872		}
6873
6874		this.popup_month.show();
6875	};
6876
6877	this.month_popup_click = function(e)
6878	{
6879		var target = e.target || e.srcElement;
6880		if (target && target.getAttribute && target.getAttribute('data-bx-month'))
6881		{
6882			this.SetMonth(parseInt(target.getAttribute('data-bx-month')));
6883			this.popup_month.close();
6884		}
6885	};
6886
6887	this._menu_year_content = function()
6888	{
6889		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">';
6890
6891		for (var i=-3; i <= 3; i++)
6892		{
6893			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>';
6894		}
6895
6896		s += '</div><input data-bx-year-input="Y" type="text" class="bx-calendar-year-input" maxlength="4" /></div>';
6897
6898		return s;
6899	};
6900
6901	this._menu_year = function()
6902	{
6903		if (!this.popup_year)
6904		{
6905			this.popup_year = new BX.PopupWindow(
6906				'calendar_popup_year_' + Math.random(), this.PARTS.YEAR,
6907				{
6908					content: this._menu_year_content(),
6909					closeByEsc: true,
6910					autoHide: true,
6911					offsetTop: -29,
6912					offsetLeft: -1,
6913					className: this.year_popup_classname,
6914					events: {
6915						onPopupShow: BX.delegate(function() {
6916							if (this.popup_month)
6917							{
6918								this.popup_month.close();
6919							}
6920						}, this)
6921					}
6922				}
6923			);
6924
6925			BX.bind(this.popup_year.popupContainer, 'click', BX.proxy(this.year_popup_click, this));
6926			BX.bind(this.popup_year.popupContainer, 'keyup', BX.proxy(this.year_popup_keyup, this));
6927			this.popup_year.BXYEAR = this.value.getUTCFullYear();
6928		}
6929		else if (this.popup_year.BXYEAR != this.value.getUTCFullYear())
6930		{
6931			this.popup_year.setContent(this._menu_year_content());
6932			this.popup_year.BXYEAR = this.value.getUTCFullYear();
6933		}
6934
6935		this.popup_year.show();
6936	};
6937
6938	this.year_popup_click = function(e)
6939	{
6940		var target = e.target || e.srcElement;
6941		if (target && target.getAttribute && target.getAttribute('data-bx-year'))
6942		{
6943			this.SetYear(parseInt(target.getAttribute('data-bx-year')));
6944			this.popup_year.close();
6945		}
6946	};
6947	this.year_popup_keyup = function(e)
6948	{
6949		var target = e.target || e.srcElement;
6950		if (target && target.getAttribute && target.getAttribute('data-bx-year-input') == 'Y')
6951		{
6952			var value = parseInt(target.value);
6953			if(value >= 1900 && value <= 2100)
6954			{
6955				this.SetYear(value);
6956				this.popup_year.close();
6957			}
6958		}
6959	};
6960
6961	this._check_date = function(v)
6962	{
6963		var res = v;
6964
6965		if (BX.type.isString(v))
6966		{
6967			res = BX.parseDate(v, true);
6968		}
6969
6970		if (!BX.type.isDate(res) || isNaN(res.valueOf()))
6971		{
6972			res = BX.date.convertToUTC(new Date());
6973			if (this.params.bHideTime)
6974			{
6975				res.setUTCHours(0);
6976				res.setUTCMinutes(0);
6977			}
6978		}
6979
6980		res.setUTCMilliseconds(0);
6981		res.setUTCSeconds(0);
6982
6983		res.BXCHECKED = true;
6984
6985		return res;
6986	};
6987};
6988
6989BX.JCCalendar.prototype.Show = function(params)
6990{
6991	if (!BX.isReady)
6992	{
6993		BX.ready(BX.delegate(function() {this.Show(params)}, this));
6994		return;
6995	}
6996
6997	params.node = params.node||document.body;
6998
6999	if (BX.type.isNotEmptyString(params.node))
7000	{
7001		var n = BX(params.node);
7002		if (!n)
7003		{
7004			n = document.getElementsByName(params.node);
7005			if (n && n.length > 0)
7006			{
7007				n = n[0]
7008			}
7009		}
7010		params.node = n;
7011	}
7012
7013	if (!params.node)
7014		return;
7015
7016	if (!!params.field)
7017	{
7018		if (BX.type.isString(params.field))
7019		{
7020			n = BX(params.field);
7021			if (!!n)
7022			{
7023				params.field = n;
7024			}
7025			else
7026			{
7027				if (params.form)
7028				{
7029					if (BX.type.isString(params.form))
7030					{
7031						params.form = document.forms[params.form];
7032					}
7033				}
7034
7035				if (BX.type.isDomNode(params.form) && !!params.form[params.field])
7036				{
7037					params.field = params.form[params.field];
7038				}
7039				else
7040				{
7041					n = document.getElementsByName(params.field);
7042					if (n && n.length > 0)
7043					{
7044						n = n[0];
7045						params.field = n;
7046					}
7047				}
7048			}
7049
7050			if (BX.type.isString(params.field))
7051			{
7052				params.field = BX(params.field);
7053			}
7054		}
7055	}
7056
7057	var bShow = !this.popup || !this.popup.isShown() || this.params.node != params.node;
7058
7059	this.params = params;
7060
7061	this.params.bCompatibility = (typeof this.params.bCompatibility == 'undefined' ? false : this.params.bCompatibility);
7062	this.params.bTimeVisibility = (typeof this.params.bTimeVisibility == 'undefined' ? !this.params.bCompatibility : this.params.bTimeVisibility);
7063	if (this.params.bCompatibility)
7064	{
7065		this.params.bCategoryTimeVisibilityOption = (
7066			this.params.bCategoryTimeVisibilityOption ? this.params.bCategoryTimeVisibilityOption : ''
7067		);
7068		this.params.bNameTimeVisibilityOption = (
7069			this.params.bNameTimeVisibilityOption ? this.params.bNameTimeVisibilityOption : 'time_visibility'
7070		);
7071
7072		if (typeof this._bTimeVisibility !== 'undefined')
7073		{
7074			this.params.bTimeVisibility = this._bTimeVisibility;
7075		}
7076	}
7077
7078	this.params.bTime = typeof this.params.bTime == 'undefined' ? true : !!this.params.bTime;
7079	this.params.bHideTime = typeof this.params.bHideTime == 'undefined' ? true : !!this.params.bHideTime;
7080	this.params.bUseSecond = typeof this.params.bUseSecond == 'undefined' ? true : !!this.params.bUseSecond;
7081
7082	this.weekStart = parseInt(this.params.weekStart || this.params.weekStart || BX.message('WEEK_START'));
7083	if (isNaN(this.weekStart))
7084		this.weekStart = 1;
7085
7086	if (!this.popup)
7087	{
7088		this._create(this.params);
7089	}
7090	else
7091	{
7092		this.popup.setBindElement(this.params.node);
7093	}
7094
7095	var bHideTime = !!this.params.bHideTime;
7096	if (this.params.value)
7097	{
7098		this.SetValue(this.params.value);
7099		bHideTime = this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0;
7100	}
7101	else if (this.params.field)
7102	{
7103		this.SetValue(this.params.field.value);
7104		bHideTime = this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0;
7105	}
7106	else if (!!this.params.currentTime)
7107	{
7108		this.SetValue(this.params.currentTime);
7109	}
7110	else
7111	{
7112		this.SetValue();
7113	}
7114
7115	if (!!this.params.bTime)
7116	{
7117		this.activateTimeStyle(bHideTime);
7118	}
7119	else
7120	{
7121		this.activateDateStyle(bHideTime);
7122	}
7123
7124	if (bShow)
7125	{
7126		this._auto_hide_disable();
7127		this.popup.show();
7128		setTimeout(BX.proxy(this._auto_hide_enable, this), 0);
7129	}
7130
7131	this.params.bSetFocus = typeof this.params.bSetFocus == 'undefined' ? true : !!this.params.bSetFocus;
7132	if(this.params.bSetFocus)
7133	{
7134		params.node.blur();
7135	}
7136	else
7137	{
7138		BX.bind(params.node, 'keyup', BX.defer(function(){
7139			this.SetValue(params.node.value);
7140			if(!!this.params.bTime)
7141			{
7142				if(this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0)
7143					BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7144				else
7145					BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7146			}
7147		}, this));
7148	}
7149
7150	return this;
7151};
7152
7153BX.JCCalendar.prototype.activateDateStyle = function(bHideTime)
7154{
7155	BX.addClass(this.DIV, 'bx-calendar-time-disabled');
7156
7157	if (!!bHideTime)
7158		BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7159	else
7160		BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7161};
7162
7163BX.JCCalendar.prototype.activateTimeStyle = function(bHideTime)
7164{
7165	if (this.params.bCompatibility && !this.params.bTimeVisibility)
7166	{
7167		BX.addClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled');
7168		BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-wrap-simple');
7169		BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7170	}
7171	else
7172	{
7173		BX.removeClass(this.DIV, 'bx-calendar-time-disabled');
7174
7175		if (!!bHideTime)
7176			BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7177		else
7178			BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7179	}
7180};
7181
7182BX.JCCalendar.prototype.SetDay = function(d)
7183{
7184	this.value.setUTCDate(d);
7185	return this.SetValue(this.value);
7186};
7187
7188BX.JCCalendar.prototype.SetMonth = function(m)
7189{
7190	if (this.popup_month)
7191		this.popup_month.close();
7192
7193	this.value.setUTCMonth(m);
7194
7195	if(m < 0)
7196		m += 12;
7197	else if (m >= 12)
7198		m -= 12;
7199
7200	while(this.value.getUTCMonth() > m)
7201	{
7202		this.value.setUTCDate(this.value.getUTCDate()-1);
7203	}
7204
7205	return this.SetValue(this.value);
7206};
7207
7208BX.JCCalendar.prototype.SetYear = function(y)
7209{
7210	if (this.popup_year)
7211		this.popup_year.close();
7212	this.value.setUTCFullYear(y);
7213	return this.SetValue(this.value);
7214};
7215
7216BX.JCCalendar.prototype.SetDate = function(v, bSet)
7217{
7218	v = this._check_date(v);
7219	v.setUTCHours(this.value.getUTCHours());
7220	v.setUTCMinutes(this.value.getUTCMinutes());
7221	v.setUTCSeconds(this.value.getUTCSeconds());
7222
7223	if (this.params.bTime && !bSet)
7224	{
7225		return this.SetValue(v);
7226	}
7227	else
7228	{
7229		this.SetValue(v);
7230		this.SaveValue();
7231	}
7232};
7233
7234BX.JCCalendar.prototype.SetValue = function(v)
7235{
7236	this.value = (v && v.BXCHECKED) ? v : this._check_date(v);
7237
7238	this.PARTS.MONTH.innerHTML = BX.message('MONTH_' + (this.value.getUTCMonth()+1));
7239	this.PARTS.YEAR.innerHTML = this.value.getUTCFullYear();
7240
7241	if (!!this.params.bTime)
7242	{
7243		var h = this.value.getUTCHours();
7244		if (this.bAmPm)
7245		{
7246			if (h >= 12)
7247			{
7248				this.PARTS.TIME_AMPM.innerHTML = 'PM';
7249
7250				if (h != 12)
7251					h -= 12;
7252			}
7253			else
7254			{
7255				this.PARTS.TIME_AMPM.innerHTML = 'AM';
7256
7257				if (h == 0)
7258					h = 12;
7259			}
7260		}
7261
7262		this.PARTS.TIME_INPUT_H.value = BX.util.str_pad_left(h.toString(), 2, "0");
7263		this.PARTS.TIME_INPUT_M.value = BX.util.str_pad_left(this.value.getUTCMinutes().toString(), 2, "0");
7264	}
7265
7266	this._set_layer();
7267
7268	return this;
7269};
7270
7271BX.JCCalendar.prototype.SaveValue = function()
7272{
7273	if (this.popup_month)
7274		this.popup_month.close();
7275	if (this.popup_year)
7276		this.popup_year.close();
7277
7278	var bSetValue = true;
7279	if (!!this.params.callback)
7280	{
7281		var res = this.params.callback.apply(this, [new Date(this.value.valueOf()+this.value.getTimezoneOffset()*60000)]);
7282		if (res === false)
7283			bSetValue = false;
7284	}
7285
7286	if (bSetValue)
7287	{
7288		var bTime = !!this.params.bTime && BX.hasClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7289
7290		if (this.params.field)
7291		{
7292			var format = BX.message(bTime ? 'FORMAT_DATETIME' : 'FORMAT_DATE');
7293
7294			if(bTime && !this.params.bUseSecond)
7295			{
7296				format = format.replace(':SS', '');
7297			}
7298
7299			this.params.field.value = BX.calendar.ValueToStringFormat(this.value, format, true);
7300			BX.fireEvent(this.params.field, 'change');
7301		}
7302
7303		this.popup.close();
7304
7305		if (!!this.params.callback_after)
7306		{
7307			this.params.callback_after.apply(this, [new Date(this.value.valueOf()+this.value.getTimezoneOffset()*60000), bTime]);
7308		}
7309	}
7310
7311	return this;
7312};
7313
7314BX.JCCalendar.prototype.Close = function()
7315{
7316	if (!!this.popup)
7317		this.popup.close();
7318
7319	return this;
7320};
7321
7322BX.JCSpinner = function(params)
7323{
7324	params = params || {};
7325	this.params = {
7326		input: params.input || null,
7327
7328		delta: params.delta || 1,
7329
7330		timeout_start: params.timeout_start || 1000,
7331		timeout_cont: params.timeout_cont || 150,
7332
7333		callback_start: params.callback_start || null,
7334		callback_change: params.callback_change || null,
7335		callback_finish: params.callback_finish || null,
7336
7337		bSaveValue: typeof params.bSaveValue == 'undefined' ? !!params.input : !!params.bSaveValue
7338	};
7339
7340	this.mousedown = false;
7341	this.direction = 1;
7342};
7343
7344BX.JCSpinner.prototype.Show = function()
7345{
7346	this.node = BX.create('span', {
7347		events: {
7348			mousedown: BX.delegateEvent(
7349				{attr: 'data-dir'},
7350				BX.delegate(this.Start, this)
7351			)
7352		},
7353		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>'
7354	});
7355	return this.node;
7356};
7357
7358BX.JCSpinner.prototype.Start = function()
7359{
7360	this.mousedown = true;
7361	this.direction = BX.proxy_context.getAttribute('data-dir') > 0 ? 1 : -1;
7362	BX.bind(document, "mouseup", BX.proxy(this.MouseUp, this));
7363	this.ChangeValue(true);
7364};
7365
7366BX.JCSpinner.prototype.ChangeValue = function(bFirst)
7367{
7368	if(!this.mousedown)
7369		return;
7370
7371	if (this.params.input)
7372	{
7373		var v = parseInt(this.params.input.value, 10) + this.params.delta * this.direction;
7374
7375		if (this.params.bSaveValue)
7376			this.params.input.value = v;
7377
7378		if (!!bFirst && this.params.callback_start)
7379			this.params.callback_start(this.params, v, this.direction);
7380
7381		if (this.params.callback_change)
7382			this.params.callback_change(this.params, v, this.direction);
7383
7384		setTimeout(
7385			BX.proxy(this.ChangeValue, this),
7386			!!bFirst ? this.params.timeout_start : this.params.timeout_cont
7387		);
7388	}
7389};
7390
7391BX.JCSpinner.prototype.MouseUp = function()
7392{
7393	this.mousedown = false;
7394	BX.unbind(document, "mouseup", BX.proxy(this.MouseUp, this));
7395
7396	if (this.params.callback_finish)
7397		this.params.callback_finish(this.params, this.params.input.value);
7398};
7399
7400/**************** compatibility hacks ***************************/
7401
7402window.jsCalendar = {
7403	Show: function(obj, field, fieldFrom, fieldTo, bTime, serverTime, form_name, bHideTimebar)
7404	{
7405		return BX.calendar({
7406			node: obj, field: field, form: form_name, bTime: !!bTime, currentTime: serverTime, bHideTimebar: !!bHideTimebar
7407		});
7408	},
7409
7410	ValueToString: BX.calendar.ValueToString
7411};
7412
7413
7414/************ clock popup transferred from timeman **************/
7415
7416BX.CClockSelector = function(params)
7417{
7418	this.params = params;
7419
7420	this.params.popup_buttons = this.params.popup_buttons || [
7421		new BX.PopupWindowButton({
7422			text : BX.message('CAL_BUTTON'),
7423			className : "popup-window-button-create",
7424			events : {click : BX.proxy(this.setValue, this)}
7425		})
7426	];
7427
7428	this.isReady = false;
7429
7430	this.WND = new BX.PopupWindow(
7431		this.params.popup_id || 'clock_selector_popup',
7432		this.params.node,
7433		this.params.popup_config || {
7434			titleBar: BX.message('CAL_TIME'),
7435			offsetLeft: -45,
7436			offsetTop: -135,
7437			autoHide: true,
7438			closeIcon: true,
7439			closeByEsc: true
7440		}
7441	);
7442
7443	this.SHOW = false;
7444	BX.addCustomEvent(this.WND, "onPopupClose", BX.delegate(this.onPopupClose, this));
7445
7446	this.obClocks = {};
7447	this.CLOCK_ID = this.params.clock_id || 'clock_selector';
7448};
7449
7450BX.CClockSelector.prototype.Show = function()
7451{
7452	if (!this.isReady)
7453	{
7454		//BX.timeman.showWait(this.parent.DIV);
7455
7456		BX.addCustomEvent('onClockRegister', BX.proxy(this.onClockRegister, this));
7457		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));
7458	}
7459
7460	this.WND.setButtons(this.params.popup_buttons);
7461	this.WND.show();
7462
7463	this.SHOW = true;
7464
7465	if (window['bxClock_' + this.obClocks[this.CLOCK_ID]])
7466	{
7467		setTimeout("window['bxClock_" + this.obClocks[this.CLOCK_ID] + "'].CalculateCoordinates()", 40);
7468	}
7469
7470	return true;
7471};
7472
7473BX.CClockSelector.prototype.onClockRegister = function(obClocks)
7474{
7475	if (obClocks[this.CLOCK_ID])
7476	{
7477		this.obClocks[this.CLOCK_ID] = obClocks[this.CLOCK_ID];
7478		BX.removeCustomEvent('onClockRegister', BX.proxy(this.onClockRegister, this));
7479	}
7480};
7481
7482BX.CClockSelector.prototype.Ready = function(data)
7483{
7484	this.content = this.CreateContent(data);
7485	this.WND.setContent(this.content);
7486
7487	this.isReady = true;
7488	//BX.timeman.closeWait();
7489
7490	setTimeout(BX.proxy(this.Show, this), 30);
7491};
7492
7493BX.CClockSelector.prototype.CreateContent = function(data)
7494{
7495	return BX.create('DIV', {
7496		events: {click: BX.PreventDefault},
7497		html:
7498			'<div class="bx-tm-popup-clock">' + data + '</div>'
7499	});
7500};
7501
7502BX.CClockSelector.prototype.setValue = function(e)
7503{
7504	if (this.params.callback)
7505	{
7506		var input = BX.findChild(this.content, {tagName: 'INPUT'}, true);
7507		this.params.callback.apply(this.params.node, [input.value]);
7508	}
7509
7510	return BX.PreventDefault(e);
7511};
7512
7513BX.CClockSelector.prototype.closeWnd = function(e)
7514{
7515	this.WND.close();
7516	return (e || window.event) ? BX.PreventDefault(e) : true;
7517};
7518
7519BX.CClockSelector.prototype.setNode = function(node)
7520{
7521	this.WND.setBindElement(node);
7522};
7523
7524BX.CClockSelector.prototype.setTime = function(timestamp)
7525{
7526	this.params.start_time = timestamp;
7527	if (window['bxClock_' + this.obClocks[this.CLOCK_ID]])
7528	{
7529		window['bxClock_' +  this.obClocks[this.CLOCK_ID]].SetTime(parseInt(timestamp/3600), parseInt((timestamp%3600)/60));
7530	}
7531};
7532
7533BX.CClockSelector.prototype.setCallback = function(cb)
7534{
7535	this.params.callback = cb;
7536};
7537
7538BX.CClockSelector.prototype.onPopupClose = function()
7539{
7540	this.SHOW = false;
7541};
7542
7543})();
7544
7545/* End */
7546;
7547; /* Start:"a:4:{s:4:"full";s:40:"/bitrix/js/main/utils.js?161472698329279";s:6:"source";s:24:"/bitrix/js/main/utils.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
7548var phpVars;
7549if(!phpVars)
7550{
7551	phpVars = {
7552		ADMIN_THEME_ID: '.default',
7553		LANGUAGE_ID: 'en',
7554		FORMAT_DATE: 'DD.MM.YYYY',
7555		FORMAT_DATETIME: 'DD.MM.YYYY HH:MI:SS',
7556		opt_context_ctrl: false,
7557		cookiePrefix: 'BITRIX_SM',
7558		titlePrefix: '',
7559		bitrix_sessid: '',
7560		messHideMenu: '',
7561		messShowMenu: '',
7562		messHideButtons: '',
7563		messShowButtons: '',
7564		messFilterInactive: '',
7565		messFilterActive: '',
7566		messFilterLess: '',
7567		messLoading: 'Loading...',
7568		messMenuLoading: '',
7569		messMenuLoadingTitle: '',
7570		messNoData: '',
7571		messExpandTabs: '',
7572		messCollapseTabs: '',
7573		messPanelFixOn: '',
7574		messPanelFixOff: '',
7575		messPanelCollapse: '',
7576		messPanelExpand: ''
7577	};
7578}
7579
7580var jsUtils =
7581{
7582	arEvents: Array(),
7583
7584	addEvent: function(el, evname, func, capture)
7585	{
7586		if(el.attachEvent) // IE
7587			el.attachEvent("on" + evname, func);
7588		else if(el.addEventListener) // Gecko / W3C
7589			el.addEventListener(evname, func, false);
7590		else
7591			el["on" + evname] = func;
7592		this.arEvents[this.arEvents.length] = {'element': el, 'event': evname, 'fn': func};
7593	},
7594
7595	removeEvent: function(el, evname, func)
7596	{
7597		if(el.detachEvent) // IE
7598			el.detachEvent("on" + evname, func);
7599		else if(el.removeEventListener) // Gecko / W3C
7600			el.removeEventListener(evname, func, false);
7601		else
7602			el["on" + evname] = null;
7603	},
7604
7605	removeAllEvents: function(el)
7606	{
7607		var i;
7608		for(i=0; i<this.arEvents.length; i++)
7609		{
7610			if(this.arEvents[i] && (el==false || el==this.arEvents[i].element))
7611			{
7612				jsUtils.removeEvent(this.arEvents[i].element, this.arEvents[i].event, this.arEvents[i].fn);
7613				this.arEvents[i] = null;
7614			}
7615		}
7616		if(el==false)
7617			this.arEvents.length = 0;
7618	},
7619
7620	IsDoctype: function()
7621	{
7622		if (document.compatMode)
7623			return (document.compatMode == "CSS1Compat");
7624
7625		if (document.documentElement && document.documentElement.clientHeight)
7626			return true;
7627
7628		return false;
7629	},
7630
7631	GetRealPos: function(el)
7632	{
7633		if(window.BX)
7634			return BX.pos(el);
7635
7636		if(!el || !el.offsetParent)
7637			return false;
7638
7639		var res = Array();
7640		res["left"] = el.offsetLeft;
7641		res["top"] = el.offsetTop;
7642		var objParent = el.offsetParent;
7643
7644		while(objParent && objParent.tagName != "BODY")
7645		{
7646			res["left"] += objParent.offsetLeft;
7647			res["top"] += objParent.offsetTop;
7648			objParent = objParent.offsetParent;
7649		}
7650		res["right"] = res["left"] + el.offsetWidth;
7651		res["bottom"] = res["top"] + el.offsetHeight;
7652
7653		return res;
7654	},
7655
7656	FindChildObject: function(obj, tag_name, class_name, recursive)
7657	{
7658		if(!obj)
7659			return null;
7660		var tag = tag_name.toUpperCase();
7661		var cl = (class_name? class_name.toLowerCase() : null);
7662		var n = obj.childNodes.length;
7663		for(var j=0; j<n; j++)
7664		{
7665			var child = obj.childNodes[j];
7666			if(child.tagName && child.tagName.toUpperCase() == tag)
7667				if(!class_name || child.className.toLowerCase() == cl)
7668					return child;
7669			if(recursive == true)
7670			{
7671				var deepChild;
7672				if((deepChild = jsUtils.FindChildObject(child, tag_name, class_name, true)))
7673					return deepChild;
7674			}
7675		}
7676		return null;
7677	},
7678
7679	FindParentObject: function(obj, tag_name, class_name)
7680	{
7681		if(!obj)
7682			return null;
7683		var o = obj;
7684		var tag = tag_name.toUpperCase();
7685		var cl = (class_name? class_name.toLowerCase() : null);
7686		while(o.parentNode)
7687		{
7688			var parent = o.parentNode;
7689			if(parent.tagName && parent.tagName.toUpperCase() == tag)
7690				if(!class_name || parent.className.toLowerCase() == cl)
7691					return parent;
7692			o = parent;
7693		}
7694		return null;
7695	},
7696
7697	FindNextSibling: function(obj, tag_name)
7698	{
7699		if(!obj)
7700			return null;
7701		var o = obj;
7702		var tag = tag_name.toUpperCase();
7703		while(o.nextSibling)
7704		{
7705			var sibling = o.nextSibling;
7706			if(sibling.tagName && sibling.tagName.toUpperCase() == tag)
7707				return sibling;
7708			o = sibling;
7709		}
7710		return null;
7711	},
7712
7713	FindPreviousSibling: function(obj, tag_name)
7714	{
7715		if(!obj)
7716			return null;
7717		var o = obj;
7718		var tag = tag_name.toUpperCase();
7719		while(o.previousSibling)
7720		{
7721			var sibling = o.previousSibling;
7722			if(sibling.tagName && sibling.tagName.toUpperCase() == tag)
7723				return sibling;
7724			o = sibling;
7725		}
7726		return null;
7727	},
7728
7729	bOpera : navigator.userAgent.toLowerCase().indexOf('opera') != -1,
7730	bIsIE : document.attachEvent && navigator.userAgent.toLowerCase().indexOf('opera') == -1,
7731
7732	IsIE: function()
7733	{
7734		return this.bIsIE;
7735	},
7736
7737	IsOpera: function()
7738	{
7739		return this.bOpera;
7740	},
7741
7742	IsSafari: function()
7743	{
7744		var userAgent = navigator.userAgent.toLowerCase();
7745		return (/webkit/.test(userAgent));
7746	},
7747
7748	IsEditor: function()
7749	{
7750		var userAgent = navigator.userAgent.toLowerCase();
7751		var version = (userAgent.match( /.+(msie)[\/: ]([\d.]+)/ ) || [])[2];
7752		var safari = /webkit/.test(userAgent);
7753
7754		if (this.IsOpera() || (document.all && !document.compatMode && version < 6) || safari)
7755			return false;
7756
7757		return true;
7758	},
7759
7760	ToggleDiv: function(div)
7761	{
7762		var style = document.getElementById(div).style;
7763		if(style.display!="none")
7764			style.display = "none";
7765		else
7766			style.display = "block";
7767		return (style.display != "none");
7768	},
7769
7770	urlencode: function(s)
7771	{
7772		return escape(s).replace(new RegExp('\\+','g'), '%2B');
7773	},
7774
7775	OpenWindow: function(url, width, height)
7776	{
7777		var w = screen.width, h = screen.height;
7778		if(this.IsOpera())
7779		{
7780			w = document.body.offsetWidth;
7781			h = document.body.offsetHeight;
7782		}
7783		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));
7784	},
7785
7786	SetPageTitle: function(s)
7787	{
7788		document.title = phpVars.titlePrefix+s;
7789		var h1 = document.getElementsByTagName("H1");
7790		if(h1)
7791			h1[0].innerHTML = s;
7792	},
7793
7794	LoadPageToDiv: function(url, div_id)
7795	{
7796		var div = document.getElementById(div_id);
7797		if(!div)
7798			return;
7799		CHttpRequest.Action = function(result)
7800		{
7801			CloseWaitWindow();
7802			document.getElementById(div_id).innerHTML = result;
7803		}
7804		ShowWaitWindow();
7805		CHttpRequest.Send(url);
7806	},
7807
7808	trim: function(s)
7809	{
7810		if (typeof s == 'string' || typeof s == 'object' && s.constructor == String)
7811		{
7812			var r, re;
7813
7814			re = /^[\s\r\n]+/g;
7815			r = s.replace(re, "");
7816			re = /[\s\r\n]+$/g;
7817			r = r.replace(re, "");
7818			return r;
7819		}
7820		else
7821			return s;
7822	},
7823
7824	Redirect: function(args, url)
7825	{
7826		var e = null, bShift = false;
7827		if(args && args.length > 0)
7828			e = args[0];
7829		if(!e)
7830			e = window.event;
7831		if(e)
7832			bShift = e.shiftKey;
7833
7834		if(bShift)
7835			window.open(url);
7836		else
7837		{
7838			window.location.href=url;
7839		}
7840	},
7841
7842	False: function(){return false;},
7843
7844	AlignToPos: function(pos, w, h)
7845	{
7846		var x = pos["left"], y = pos["bottom"];
7847
7848		var scroll = jsUtils.GetWindowScrollPos();
7849		var size = jsUtils.GetWindowInnerSize();
7850
7851		if((size.innerWidth + scroll.scrollLeft) - (pos["left"] + w) < 0)
7852		{
7853			if(pos["right"] - w >= 0 )
7854				x = pos["right"] - w;
7855			else
7856				x = scroll.scrollLeft;
7857		}
7858
7859		if((size.innerHeight + scroll.scrollTop) - (pos["bottom"] + h) < 0)
7860		{
7861			if(pos["top"] - h >= 0)
7862				y = pos["top"] - h;
7863			else
7864				y = scroll.scrollTop;
7865		}
7866
7867		return {'left':x, 'top':y};
7868	},
7869
7870	// evaluate js string in window scope
7871	EvalGlobal: function(script)
7872	{
7873		try {
7874		if (window.execScript)
7875			window.execScript(script, 'javascript');
7876		else if (jsUtils.IsSafari())
7877			window.setTimeout(script, 0);
7878		else
7879			window.eval(script);
7880		} catch (e) {/*alert("Error! jsUtils.EvalGlobal");*/}
7881	},
7882
7883	GetStyleValue: function(el, styleProp)
7884	{
7885		var res;
7886		if(el.currentStyle)
7887			res = el.currentStyle[styleProp];
7888		else if(window.getComputedStyle)
7889			res = document.defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
7890		if(!res)
7891			res = '';
7892		return res;
7893	},
7894
7895	GetWindowInnerSize: function(pDoc)
7896	{
7897		var width, height;
7898		if (!pDoc)
7899			pDoc = document;
7900
7901		if (self.innerHeight) // all except Explorer
7902		{
7903			width = self.innerWidth;
7904			height = self.innerHeight;
7905		}
7906		else if (pDoc.documentElement && (pDoc.documentElement.clientHeight || pDoc.documentElement.clientWidth)) // Explorer 6 Strict Mode
7907		{
7908			width = pDoc.documentElement.clientWidth;
7909			height = pDoc.documentElement.clientHeight;
7910		}
7911		else if (pDoc.body) // other Explorers
7912		{
7913			width = pDoc.body.clientWidth;
7914			height = pDoc.body.clientHeight;
7915		}
7916		return {innerWidth : width, innerHeight : height};
7917	},
7918
7919	GetWindowScrollPos: function(pDoc)
7920	{
7921		var left, top;
7922		if (!pDoc)
7923			pDoc = document;
7924
7925		if (self.pageYOffset) // all except Explorer
7926		{
7927			left = self.pageXOffset;
7928			top = self.pageYOffset;
7929		}
7930		else if (pDoc.documentElement && (pDoc.documentElement.scrollTop || pDoc.documentElement.scrollLeft)) // Explorer 6 Strict
7931		{
7932			left = document.documentElement.scrollLeft;
7933			top = document.documentElement.scrollTop;
7934		}
7935		else if (pDoc.body) // all other Explorers
7936		{
7937			left = pDoc.body.scrollLeft;
7938			top = pDoc.body.scrollTop;
7939		}
7940		return {scrollLeft : left, scrollTop : top};
7941	},
7942
7943	GetWindowScrollSize: function(pDoc)
7944	{
7945		var width, height;
7946		if (!pDoc)
7947			pDoc = document;
7948
7949		if ( (pDoc.compatMode && pDoc.compatMode == "CSS1Compat"))
7950		{
7951			width = pDoc.documentElement.scrollWidth;
7952			height = pDoc.documentElement.scrollHeight;
7953		}
7954		else
7955		{
7956			if (pDoc.body.scrollHeight > pDoc.body.offsetHeight)
7957				height = pDoc.body.scrollHeight;
7958			else
7959				height = pDoc.body.offsetHeight;
7960
7961			if (pDoc.body.scrollWidth > pDoc.body.offsetWidth ||
7962				(pDoc.compatMode && pDoc.compatMode == "BackCompat") ||
7963				(pDoc.documentElement && !pDoc.documentElement.clientWidth)
7964			)
7965				width = pDoc.body.scrollWidth;
7966			else
7967				width = pDoc.body.offsetWidth;
7968		}
7969		return {scrollWidth : width, scrollHeight : height};
7970	},
7971
7972	GetWindowSize: function()
7973	{
7974		var innerSize = jsUtils.GetWindowInnerSize();
7975		var scrollPos = jsUtils.GetWindowScrollPos();
7976		var scrollSize = jsUtils.GetWindowScrollSize();
7977
7978		return  {
7979			innerWidth : innerSize.innerWidth, innerHeight : innerSize.innerHeight,
7980			scrollLeft : scrollPos.scrollLeft, scrollTop : scrollPos.scrollTop,
7981			scrollWidth : scrollSize.scrollWidth, scrollHeight : scrollSize.scrollHeight
7982		};
7983	},
7984
7985
7986	arCustomEvents: {},
7987
7988	addCustomEvent: function(eventName, eventHandler, arParams, handlerContextObject)
7989	{
7990		if (!this.arCustomEvents[eventName])
7991			this.arCustomEvents[eventName] = [];
7992
7993		if (!arParams)
7994			arParams = [];
7995		if (!handlerContextObject)
7996			handlerContextObject = false;
7997
7998		this.arCustomEvents[eventName].push(
7999			{
8000				handler: eventHandler,
8001				arParams: arParams,
8002				obj: handlerContextObject
8003			}
8004		);
8005	},
8006
8007	removeCustomEvent: function(eventName, eventHandler)
8008	{
8009		if (!this.arCustomEvents[eventName])
8010			return;
8011
8012		var l = this.arCustomEvents[eventName].length;
8013		if (l == 1)
8014		{
8015			delete this.arCustomEvents[eventName];
8016			return;
8017		}
8018
8019		for (var i = 0; i < l; i++)
8020		{
8021			if (!this.arCustomEvents[eventName][i])
8022				continue;
8023			if (this.arCustomEvents[eventName][i].handler == eventHandler)
8024			{
8025				delete this.arCustomEvents[eventName][i];
8026				return;
8027			}
8028		}
8029	},
8030
8031	onCustomEvent: function(eventName, arEventParams)
8032	{
8033		if (!this.arCustomEvents[eventName])
8034			return;
8035
8036		if (!arEventParams)
8037			arEventParams = [];
8038
8039		var h;
8040		for (var i = 0, l = this.arCustomEvents[eventName].length; i < l; i++)
8041		{
8042			h = this.arCustomEvents[eventName][i];
8043			if (!h || !h.handler)
8044				continue;
8045
8046			if (h.obj)
8047				h.handler.call(h.obj, h.arParams, arEventParams);
8048			else
8049				h.handler(h.arParams, arEventParams);
8050		}
8051	},
8052
8053	loadJSFile: function(arJs, oCallBack, pDoc)
8054	{
8055		if (!pDoc)
8056			pDoc = document;
8057		if (typeof arJs == 'string')
8058			arJs = [arJs];
8059		var callback = function()
8060		{
8061			if (!oCallBack)
8062				return;
8063			if (typeof oCallBack == 'function')
8064				return oCallBack();
8065			if (typeof oCallBack != 'object' || !oCallBack.func)
8066				return;
8067			var p = oCallBack.params || {};
8068			if (oCallBack.obj)
8069				oCallBack.func.apply(oCallBack.obj, p);
8070			else
8071				oCallBack.func(p);
8072		};
8073		var load_js = function(ind)
8074		{
8075			if (ind >= arJs.length)
8076				return callback();
8077			var oSript = pDoc.body.appendChild(pDoc.createElement('script'));
8078			oSript.src = arJs[ind];
8079			var bLoaded = false;
8080			oSript.onload = oSript.onreadystatechange = function()
8081			{
8082				if (!bLoaded && (!oSript.readyState || oSript.readyState == "loaded" || oSript.readyState == "complete"))
8083				{
8084					bLoaded = true;
8085					setTimeout(function (){load_js(++ind);}, 50);
8086				}
8087			};
8088		};
8089		load_js(0);
8090	},
8091
8092	loadCSSFile: function(arCSS, pDoc, pWin)
8093	{
8094		if (typeof arCSS == 'string')
8095		{
8096			var bSingle = true;
8097			arCSS = [arCSS];
8098		}
8099		var i, l = arCSS.length, pLnk = [];
8100		if (l == 0)
8101			return;
8102		if (!pDoc)
8103			pDoc = document;
8104		if (!pWin)
8105			pWin = window;
8106		if (!pWin.bxhead)
8107		{
8108			var heads = pDoc.getElementsByTagName('HEAD');
8109			pWin.bxhead = heads[0];
8110		}
8111		if (!pWin.bxhead)
8112			return;
8113		for (i = 0; i < l; i++)
8114		{
8115			var lnk = document.createElement('LINK');
8116			lnk.href = arCSS[i];
8117			lnk.rel = 'stylesheet';
8118			lnk.type = 'text/css';
8119			pWin.bxhead.appendChild(lnk);
8120			pLnk.push(lnk);
8121		}
8122		if (bSingle)
8123			return lnk;
8124		return pLnk;
8125	},
8126
8127	appendBXHint : function(node, html)
8128	{
8129		if (!node || !node.parentNode || !html)
8130			return;
8131		var oBXHint = new BXHint(html);
8132		node.parentNode.insertBefore(oBXHint.oIcon, node);
8133		node.parentNode.removeChild(node);
8134		oBXHint.oIcon.style.marginLeft = "5px";
8135	},
8136
8137	PreventDefault : function(e)
8138	{
8139		if(!e) e = window.event;
8140		if(e.stopPropagation)
8141		{
8142			e.preventDefault();
8143			e.stopPropagation();
8144		}
8145		else
8146		{
8147			e.cancelBubble = true;
8148			e.returnValue = false;
8149		}
8150		return false;
8151	},
8152
8153	CreateElement: function(tag, arAttr, arStyles, pDoc)
8154	{
8155		if (!pDoc)
8156			pDoc = document;
8157		var pEl = pDoc.createElement(tag), p;
8158		if(arAttr)
8159		{
8160			for(p in arAttr)
8161			{
8162				if(p == 'className' || p == 'class')
8163				{
8164					pEl.setAttribute('class', arAttr[p]);
8165					if (jsUtils.IsIE())
8166						pEl.setAttribute('className', arAttr[p]);
8167					continue;
8168				}
8169
8170				if (arAttr[p] != undefined && arAttr[p] != null)
8171					pEl.setAttribute(p, arAttr[p]);
8172			}
8173		}
8174		if(arStyles)
8175		{
8176			for(p in arStyles)
8177				pEl.style[p] = arStyles[p];
8178		}
8179		return pEl;
8180	},
8181
8182	in_array: function(needle, haystack)
8183	{
8184		for(var i=0; i<haystack.length; i++)
8185		{
8186			if(haystack[i] == needle)
8187				return true;
8188		}
8189		return false;
8190	},
8191
8192	htmlspecialchars: function(str)
8193	{
8194		if(!str.replace)
8195			return str;
8196
8197		return str.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
8198	}
8199}
8200
8201/************************************************/
8202
8203function JCFloatDiv()
8204{
8205	var _this = this;
8206	this.floatDiv = null;
8207	this.x = this.y = 0;
8208
8209	this.Create = function(arParams)
8210	{
8211		var div = document.body.appendChild(document.createElement("DIV"));
8212		div.id = arParams.id;
8213		div.style.position = 'absolute';
8214		div.style.left = '-10000px';
8215		div.style.top = '-10000px';
8216		if(arParams.className)
8217			div.className = arParams.className;
8218		if(arParams.zIndex)
8219			div.style.zIndex = arParams.zIndex;
8220		if(arParams.width)
8221			div.style.width = arParams.width+'px';
8222		if(arParams.height)
8223			div.style.height = arParams.height+'px';
8224		return div;
8225	}
8226
8227	this.Show = function(div, left, top, dxShadow, restrictDrag)
8228	{
8229		var component = BX.ZIndexManager.getComponent(div);
8230		if (!component)
8231		{
8232			BX.ZIndexManager.register(div);
8233		}
8234
8235		BX.ZIndexManager.bringToFront(div);
8236
8237		if (left < 0)
8238			left = 0;
8239
8240		if (top < 0)
8241			top = 0;
8242
8243		div.style.left = parseInt(left) + "px";
8244		div.style.top = parseInt(top) + "px";
8245
8246		/*Restrict drag*/
8247		div.restrictDrag = restrictDrag || false;
8248
8249		/*shadow*/
8250		if(isNaN(dxShadow))
8251			dxShadow = 5;
8252
8253		div.dxShadow = dxShadow;
8254	}
8255
8256	this.Close = function(div)
8257	{
8258		if(!div)
8259			return;
8260		var sh = document.getElementById(div.id+"_shadow");
8261		if(sh)
8262			sh.style.visibility = 'hidden';
8263
8264		var frame = document.getElementById(div.id+"_frame");
8265		if(frame)
8266			frame.style.visibility = 'hidden';
8267	}
8268
8269	this.Move = function(div, x, y)
8270	{
8271		if(!div)
8272			return;
8273
8274		var dxShadow = div.dxShadow;
8275		var left = parseInt(div.style.left)+x;
8276		var top = parseInt(div.style.top)+y;
8277
8278		if (div.restrictDrag)
8279		{
8280			//Left side
8281			if (left < 0)
8282				left = 0;
8283
8284			//Right side
8285			if ( (document.compatMode && document.compatMode == "CSS1Compat"))
8286				windowWidth = document.documentElement.scrollWidth;
8287			else
8288			{
8289				if (document.body.scrollWidth > document.body.offsetWidth ||
8290					(document.compatMode && document.compatMode == "BackCompat") ||
8291					(document.documentElement && !document.documentElement.clientWidth)
8292				)
8293					windowWidth = document.body.scrollWidth;
8294				else
8295					windowWidth = document.body.offsetWidth;
8296			}
8297
8298			var floatWidth = div.offsetWidth;
8299			if (left > (windowWidth - floatWidth - dxShadow))
8300				left = windowWidth - floatWidth - dxShadow;
8301
8302			//Top side
8303			if (top < 0)
8304				top = 0;
8305		}
8306
8307		div.style.left = left+'px';
8308		div.style.top = top+'px';
8309
8310		this.AdjustShadow(div);
8311	}
8312
8313	this.HideShadow = function(div)
8314	{
8315		var sh = document.getElementById(div.id + "_shadow");
8316		sh.style.visibility = 'hidden';
8317	}
8318
8319	this.UnhideShadow = function(div)
8320	{
8321		var sh = document.getElementById(div.id + "_shadow");
8322		sh.style.visibility = 'visible';
8323	}
8324
8325	this.AdjustShadow = function(div)
8326	{
8327		var sh = document.getElementById(div.id + "_shadow");
8328		if(sh && sh.style.visibility != 'hidden')
8329		{
8330			var dxShadow = div.dxShadow;
8331
8332			sh.style.width = div.offsetWidth+'px';
8333			sh.style.height = div.offsetHeight+'px';
8334			sh.style.left = parseInt(div.style.left)+dxShadow+'px';
8335			sh.style.top = parseInt(div.style.top)+dxShadow+'px';
8336		}
8337
8338		var frame = document.getElementById(div.id+"_frame");
8339		if(frame)
8340		{
8341			frame.style.width = div.offsetWidth + "px";
8342			frame.style.height = div.offsetHeight + "px";
8343			frame.style.left = div.style.left;
8344			frame.style.top = div.style.top;
8345		}
8346	}
8347
8348	this.StartDrag = function(e, div)
8349	{
8350		if(!e)
8351			e = window.event;
8352		this.x = e.clientX + document.body.scrollLeft;
8353		this.y = e.clientY + document.body.scrollTop;
8354		this.floatDiv = div;
8355
8356		jsUtils.addEvent(document, "mousemove", this.MoveDrag);
8357		document.onmouseup = this.StopDrag;
8358		if(document.body.setCapture)
8359			document.body.setCapture();
8360
8361		document.onmousedown = jsUtils.False;
8362		var b = document.body;
8363		b.ondrag = jsUtils.False;
8364		b.onselectstart = jsUtils.False;
8365		b.style.MozUserSelect = _this.floatDiv.style.MozUserSelect = 'none';
8366		b.style.cursor = 'move';
8367	}
8368
8369	this.StopDrag = function(e)
8370	{
8371		if(document.body.releaseCapture)
8372			document.body.releaseCapture();
8373
8374		jsUtils.removeEvent(document, "mousemove", _this.MoveDrag);
8375		document.onmouseup = null;
8376
8377		this.floatDiv = null;
8378
8379		document.onmousedown = null;
8380		var b = document.body;
8381		b.ondrag = null;
8382		b.onselectstart = null;
8383		b.style.MozUserSelect = _this.floatDiv.style.MozUserSelect = '';
8384		b.style.cursor = '';
8385	}
8386
8387	this.MoveDrag = function(e)
8388	{
8389		var x = e.clientX + document.body.scrollLeft;
8390		var y = e.clientY + document.body.scrollTop;
8391
8392		if(_this.x == x && _this.y == y)
8393			return;
8394
8395		_this.Move(_this.floatDiv, (x - _this.x), (y - _this.y));
8396		_this.x = x;
8397		_this.y = y;
8398	}
8399}
8400var jsFloatDiv = new JCFloatDiv();
8401
8402/************************************************/
8403
8404var BXHint = function(innerHTML, element, addParams)
8405{
8406	this.oDivOver = false;
8407	this.timeOutID = null;
8408	this.oIcon = null;
8409	this.freeze = false;
8410	this.x = 0;
8411	this.y = 0;
8412	this.time = 700;
8413
8414	if (!innerHTML)
8415		innerHTML = "";
8416	this.Create(innerHTML, element, addParams);
8417}
8418
8419BXHint.prototype.Create = function(innerHTML, element, addParams)
8420{
8421	var
8422		_this = this,
8423		width = 0,
8424		height = 0,
8425		className = null,
8426		type = "icon";
8427	this.bWidth = true;
8428
8429	if (addParams)
8430	{
8431		if (addParams.width === false)
8432			this.bWidth = false;
8433		else if (addParams.width)
8434			width = addParams.width;
8435
8436		if (addParams.height)
8437			height = addParams.height;
8438
8439		if (addParams.className)
8440			className = addParams.className;
8441
8442		if (addParams.type && (addParams.type == "link" || addParams.type == "icon"))
8443			type = addParams.type;
8444		if (addParams.time > 0)
8445			this.time = addParams.time;
8446	}
8447
8448	if (element)
8449		type = "element";
8450
8451	if (type == "icon")
8452	{
8453		var element = document.createElement("IMG");
8454		element.src = (addParams && addParams.iconSrc) ? addParams.iconSrc : "/bitrix/themes/"+phpVars.ADMIN_THEME_ID+"/public/popup/hint.gif";
8455		element.ondrag = jsUtils.False;
8456	}
8457	else if (type == "link")
8458	{
8459		var element = document.createElement("A");
8460		element.href = "";
8461		element.onclick = function(e){return false;}
8462		element.innerHTML = "[?]";
8463	}
8464
8465	this.element = element;
8466	if (type == "element")
8467	{
8468		if(addParams && addParams.show_on_click)
8469		{
8470			jsUtils.addEvent(
8471				element,
8472				"click",
8473				function (event)
8474				{
8475					if (!event)
8476						event = window.event;
8477					_this.GetMouseXY(event);
8478					_this.timeOutID = setTimeout(function () {_this.Show(innerHTML,width,height,className) }, 10);
8479				}
8480			);
8481		}
8482		else
8483		{
8484			jsUtils.addEvent(
8485				element,
8486				"mouseover",
8487				function (event)
8488				{
8489					if (!event)
8490						event = window.event;
8491					_this.GetMouseXY(event);
8492					_this.timeOutID = setTimeout(function () {_this.Show(innerHTML,width,height,className) }, 750);
8493				}
8494			);
8495		}
8496
8497		jsUtils.addEvent(
8498			element,
8499			"mouseout",
8500			function(event)
8501			{
8502				if (_this.timeOutID)
8503					clearTimeout(_this.timeOutID);
8504				_this.SmartHide(_this);
8505			}
8506		);
8507	}
8508	else
8509	{
8510		this.oIcon = element;
8511		element.onmouseover = function(event) {if (!event) event = window.event; _this.GetMouseXY(event); _this.Show(innerHTML,width,height,className)};
8512		element.onmouseout = function() {_this.SmartHide(_this);};
8513	}
8514}
8515
8516BXHint.prototype.IsFrozen = function()
8517{
8518	return this.freeze;
8519}
8520
8521BXHint.prototype.Freeze = function()
8522{
8523	this.freeze = true;
8524	this.Hide();
8525}
8526
8527BXHint.prototype.UnFreeze = function()
8528{
8529	this.freeze = false;
8530}
8531
8532BXHint.prototype.GetMouseXY = function(event)
8533{
8534	if (event.pageX || event.pageY)
8535	{
8536		this.x = event.pageX;
8537		this.y = event.pageY;
8538	}
8539	else if (event.clientX || event.clientY)
8540	{
8541		this.x = event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft;
8542		this.y = event.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop;
8543	}
8544}
8545
8546BXHint.prototype.Show = function(innerHTML, width, height, className)
8547{
8548	//Delete previous hint
8549	var old = document.getElementById("__BXHint_div");
8550	if (old)
8551		this.Hide();
8552
8553	if (this.freeze)
8554		return;
8555
8556	var _this = this;
8557	var oDiv = document.body.appendChild(document.createElement("DIV"));
8558	oDiv.onmouseover = function(){_this.oDivOver = true};
8559	oDiv.onmouseout = function(){_this.oDivOver = false; _this.SmartHide(_this);}
8560	oDiv.id = "__BXHint_div";
8561	oDiv.className = (className) ? className : "bxhint";
8562	oDiv.style.position = 'absolute';
8563	if (width && this.bWidth)
8564		oDiv.style.width = width + "px";
8565
8566	if (height)
8567		oDiv.style.height = height + "px";
8568	oDiv.innerHTML = innerHTML;
8569
8570	var w = oDiv.offsetWidth;
8571	var h = oDiv.offsetHeight;
8572	if (this.bWidth)
8573	{
8574		if (!width && w>200)
8575			w = Math.round(Math.sqrt(1.618*w*h));
8576		oDiv.style.width = w + "px";
8577		h = oDiv.offsetHeight;
8578	}
8579
8580	var pos = {left : this.x + 10, right : this.x + w, top : this.y, bottom : this.y + h};
8581
8582	pos = this.AlignToPos(pos, w, h);
8583
8584	jsFloatDiv.Show(oDiv, pos.left, pos.top,3);
8585
8586//	oDiv.ondrag = jsUtils.False;
8587//	oDiv.onselectstart = jsUtils.False;
8588//	oDiv.style.MozUserSelect = 'none';
8589	oDiv = null;
8590}
8591
8592BXHint.prototype.AlignToPos = function(pos, w, h)
8593{
8594	var body = document.body;
8595	if((body.clientWidth + body.scrollLeft) < (pos.left + w))
8596		pos.left = (pos.left - w >= 0) ? (pos.left - w) : body.scrollLeft;
8597
8598	if((body.clientHeight + body.scrollTop) - (pos["bottom"]) < 0)
8599		pos.top = (pos.top - h >= 0) ? (pos.top - h) : body.scrollTop;
8600
8601	return pos;
8602}
8603
8604BXHint.prototype.Hide = function()
8605{
8606	var oDiv = document.getElementById("__BXHint_div");
8607
8608	if (!oDiv)
8609		return;
8610
8611	BX.ZIndexManager.unregister(oDiv);
8612
8613	jsFloatDiv.Close(oDiv);
8614	oDiv.parentNode.removeChild(oDiv);
8615	oDiv = null;
8616}
8617
8618BXHint.prototype.SmartHide = function(_this)
8619{
8620	setTimeout(function ()
8621		{
8622			if (!_this.oDivOver)
8623				_this.Hide();
8624		}, 100
8625	);
8626}
8627
8628/************************************************/
8629
8630function WaitOnKeyPress(e)
8631{
8632	if(!e) e = window.event
8633	if(!e) return;
8634	if(e.keyCode == 27)
8635		CloseWaitWindow();
8636}
8637
8638function ShowWaitWindow()
8639{
8640	CloseWaitWindow();
8641
8642	var obWndSize = jsUtils.GetWindowSize();
8643
8644	var div = document.body.appendChild(document.createElement("DIV"));
8645	div.id = "wait_window_div";
8646	div.innerHTML = phpVars.messLoading;
8647	div.className = "waitwindow";
8648	//div.style.left = obWndSize.scrollLeft + (obWndSize.innerWidth - div.offsetWidth) - (jsUtils.IsIE() ? 5 : 20) + "px";
8649	div.style.right = (5 - obWndSize.scrollLeft) + 'px';
8650	div.style.top = obWndSize.scrollTop + 5 + "px";
8651
8652	if(jsUtils.IsIE())
8653	{
8654		var frame = document.createElement("IFRAME");
8655		frame.src = "javascript:''";
8656		frame.id = "wait_window_frame";
8657		frame.className = "waitwindow";
8658		frame.style.width = div.offsetWidth + "px";
8659		frame.style.height = div.offsetHeight + "px";
8660		frame.style.right = div.style.right;
8661		frame.style.top = div.style.top;
8662		document.body.appendChild(frame);
8663	}
8664	jsUtils.addEvent(document, "keypress", WaitOnKeyPress);
8665}
8666
8667function CloseWaitWindow()
8668{
8669	jsUtils.removeEvent(document, "keypress", WaitOnKeyPress);
8670
8671	var frame = document.getElementById("wait_window_frame");
8672	if(frame)
8673		frame.parentNode.removeChild(frame);
8674
8675	var div = document.getElementById("wait_window_div");
8676	if(div)
8677		div.parentNode.removeChild(div);
8678}
8679
8680/************************************************/
8681
8682var jsSelectUtils =
8683{
8684	addNewOption: function(select_id, opt_value, opt_name, do_sort, check_unique)
8685	{
8686		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
8687		if(oSelect)
8688		{
8689			var n = oSelect.length;
8690			if(check_unique !== false)
8691			{
8692				for(var i=0;i<n;i++)
8693					if(oSelect[i].value==opt_value)
8694						return;
8695			}
8696			var newoption = new Option(opt_name, opt_value, false, false);
8697			oSelect.options[n]=newoption;
8698		}
8699		if(do_sort === true)
8700			this.sortSelect(select_id);
8701	},
8702
8703	deleteOption: function(select_id, opt_value)
8704	{
8705		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
8706		if(oSelect)
8707		{
8708			for(var i=0;i<oSelect.length;i++)
8709				if(oSelect[i].value==opt_value)
8710				{
8711					oSelect.remove(i);
8712					break;
8713				}
8714		}
8715	},
8716
8717	deleteSelectedOptions: function(select_id)
8718	{
8719		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
8720		if(oSelect)
8721		{
8722			var i=0;
8723			while(i<oSelect.length)
8724				if(oSelect[i].selected)
8725				{
8726					oSelect[i].selected=false;
8727					oSelect.remove(i);
8728				}
8729				else
8730					i++;
8731		}
8732	},
8733
8734	deleteAllOptions: function(oSelect)
8735	{
8736		if(oSelect)
8737		{
8738			for(var i=oSelect.length-1; i>=0; i--)
8739				oSelect.remove(i);
8740		}
8741	},
8742
8743	optionCompare: function(record1, record2)
8744	{
8745		var value1 = record1.optText.toLowerCase();
8746		var value2 = record2.optText.toLowerCase();
8747		if (value1 > value2) return(1);
8748		if (value1 < value2) return(-1);
8749		return(0);
8750	},
8751
8752	sortSelect: function(select_id)
8753	{
8754		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
8755		if(oSelect)
8756		{
8757			var myOptions = [];
8758			var n = oSelect.options.length;
8759			for (var i=0;i<n;i++)
8760			{
8761				myOptions[i] = {
8762					optText:oSelect[i].text,
8763					optValue:oSelect[i].value
8764				};
8765			}
8766			myOptions.sort(this.optionCompare);
8767			oSelect.length=0;
8768			n = myOptions.length;
8769			for(var i=0;i<n;i++)
8770			{
8771				var newoption = new Option(myOptions[i].optText, myOptions[i].optValue, false, false);
8772				oSelect[i]=newoption;
8773			}
8774		}
8775	},
8776
8777	selectAllOptions: function(select_id)
8778	{
8779		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
8780		if(oSelect)
8781		{
8782			var n = oSelect.length;
8783			for(var i=0;i<n;i++)
8784				oSelect[i].selected=true;
8785		}
8786	},
8787
8788	selectOption: function(select_id, opt_value)
8789	{
8790		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
8791		if(oSelect)
8792		{
8793			var n = oSelect.length;
8794			for(var i=0;i<n;i++)
8795				oSelect[i].selected = (oSelect[i].value == opt_value);
8796		}
8797	},
8798
8799	addSelectedOptions: function(oSelect, to_select_id, check_unique, do_sort)
8800	{
8801		if(!oSelect)
8802			return;
8803		var n = oSelect.length;
8804		for(var i=0; i<n; i++)
8805			if(oSelect[i].selected)
8806				this.addNewOption(to_select_id, oSelect[i].value, oSelect[i].text, do_sort, check_unique);
8807	},
8808
8809	moveOptionsUp: function(oSelect)
8810	{
8811		if(!oSelect)
8812			return;
8813		var n = oSelect.length;
8814		for(var i=0; i<n; i++)
8815		{
8816			if(oSelect[i].selected && i>0 && oSelect[i-1].selected == false)
8817			{
8818				var option1 = new Option(oSelect[i].text, oSelect[i].value);
8819				var option2 = new Option(oSelect[i-1].text, oSelect[i-1].value);
8820				oSelect[i] = option2;
8821				oSelect[i].selected = false;
8822				oSelect[i-1] = option1;
8823				oSelect[i-1].selected = true;
8824			}
8825		}
8826	},
8827
8828	moveOptionsDown: function(oSelect)
8829	{
8830		if(!oSelect)
8831			return;
8832		var n = oSelect.length;
8833		for(var i=n-1; i>=0; i--)
8834		{
8835			if(oSelect[i].selected && i<n-1 && oSelect[i+1].selected == false)
8836			{
8837				var option1 = new Option(oSelect[i].text, oSelect[i].value);
8838				var option2 = new Option(oSelect[i+1].text, oSelect[i+1].value);
8839				oSelect[i] = option2;
8840				oSelect[i].selected = false;
8841				oSelect[i+1] = option1;
8842				oSelect[i+1].selected = true;
8843			}
8844		}
8845	}
8846
8847}
8848
8849/************************************************/
8850
8851/* End */
8852;

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.