PageSourceSearch

https://altaytms.ru/bitrix/cache/js/s1/aspro-allcorp3/kernel_main/kernel_main_v1.js?1752218214249964

js altaytms.ru collected 2026-10-08 08:21:51 UTC 249,964 bytes, 9,185 lines download raw bytes

1; /* /bitrix/js/main/session.js?16969173103701*/
2; /* /bitrix/js/main/pageobject/pageobject.js?1696917310864*/
3; /* /bitrix/js/main/core/core_window.js?171075048198766*/
4; /* /bitrix/js/main/date/main.date.js?175075493762683*/
5; /* /bitrix/js/main/core/core_date.js?169691731036080*/
6; /* /bitrix/js/main/utils.js?169691731029279*/
7; /* /bitrix/js/main/core/core_fx.js?169691731016888*/
8
9; /* Start:"a:4:{s:4:"full";s:47:"/bitrix/js/main/core/core_fx.js?169691731016888";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?16969173103701";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?1696917310864";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?171075048198766";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 = [];
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?175075493762683";s:6:"source";s:33:"/bitrix/js/main/date/main.date.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
4954/* eslint-disable */
4955this.BX = this.BX || {};
4956(function (exports,main_core) {
4957	'use strict';
4958
4959	function convertBitrixFormat(format) {
4960	  if (!main_core.Type.isStringFilled(format)) {
4961	    return '';
4962	  }
4963	  return format.replace('YYYY', 'Y') // 1999
4964	  .replace('MMMM', 'F') // January - December
4965	  .replace('MM', 'm') // 01 - 12
4966	  .replace('M', 'M') // Jan - Dec
4967	  .replace('DD', 'd') // 01 - 31
4968	  .replace('G', 'g') //  1 - 12
4969	  .replace(/GG/i, 'G') //  0 - 23
4970	  .replace('H', 'h') // 01 - 12
4971	  .replace(/HH/i, 'H') // 00 - 24
4972	  .replace('MI', 'i') // 00 - 59
4973	  .replace('SS', 's') // 00 - 59
4974	  .replace('TT', 'A') // AM - PM
4975	  .replace('T', 'a'); // am - pm
4976	}
4977
4978	const formatsCache = new main_core.Cache.MemoryCache();
4979
4980	/**
4981	 * Returns culture-specific datetime format by code.
4982	 * The full list with examples can be found in config.php of this extension in ['settings']['formats'].
4983	 * All formats are compatible with this.format() without any additional transformations.
4984	 *
4985	 * @param code
4986	 * @returns {string|null}
4987	 */
4988	function getFormat(code) {
4989	  return formatsCache.remember(`main.date.format.${code}`, () => {
4990	    let format = main_core.Extension.getSettings('main.date').get(`formats.${code}`);
4991	    if (main_core.Type.isStringFilled(format) && (code === 'FORMAT_DATE' || code === 'FORMAT_DATETIME')) {
4992	      format = convertBitrixFormat(format);
4993	    }
4994	    return format;
4995	  });
4996	}
4997
4998	/**
4999	 * @memberOf BX.Main
5000	 * @alias Date
5001	 */
5002	let DateTimeFormat = /*#__PURE__*/function () {
5003	  function DateTimeFormat() {
5004	    babelHelpers.classCallCheck(this, DateTimeFormat);
5005	  }
5006	  babelHelpers.createClass(DateTimeFormat, null, [{
5007	    key: "isAmPmMode",
5008	    value: function isAmPmMode(returnConst) {
5009	      if (returnConst === true) {
5010	        return this._getMessage('AMPM_MODE');
5011	      }
5012	      return this._getMessage('AMPM_MODE') !== false;
5013	    }
5014	  }, {
5015	    key: "convertToUTC",
5016	    value: function convertToUTC(date) {
5017	      if (!main_core.Type.isDate(date)) {
5018	        return null;
5019	      }
5020	      return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));
5021	    }
5022	    /**
5023	     * Function creates and returns Javascript Date() object from server timestamp regardless of local browser (system) timezone.
5024	     * For example can be used to convert timestamp from some exact date on server to the JS Date object with the same value.
5025	     *
5026	     * @param timestamp - timestamp in seconds
5027	     * @returns {Date}
5028	     */
5029	  }, {
5030	    key: "getNewDate",
5031	    value: function getNewDate(timestamp) {
5032	      return new Date(this.getBrowserTimestamp(timestamp));
5033	    }
5034	    /**
5035	     * Function transforms server timestamp (in sec) to javascript timestamp (calculated depend on local browser timezone offset). Returns timestamp in milliseconds.
5036	     * Also see BX.Main.Date.getNewDate description.
5037	     *
5038	     * @param timestamp - timestamp in seconds
5039	     * @returns {number}
5040	     */
5041	  }, {
5042	    key: "getBrowserTimestamp",
5043	    value: function getBrowserTimestamp(timestamp) {
5044	      timestamp = parseInt(timestamp, 10);
5045	      const browserOffset = new Date(timestamp * 1000).getTimezoneOffset() * 60;
5046	      return (parseInt(timestamp, 10) + parseInt(this._getMessage('SERVER_TZ_OFFSET')) + browserOffset) * 1000;
5047	    }
5048	    /**
5049	     * Function transforms local browser timestamp (in ms) to server timestamp (calculated depend on local browser timezone offset). Returns timestamp in seconds.
5050	     *
5051	     * @param timestamp - timestamp in milliseconds
5052	     * @returns {number}
5053	     */
5054	  }, {
5055	    key: "getServerTimestamp",
5056	    value: function getServerTimestamp(timestamp) {
5057	      timestamp = parseInt(timestamp, 10);
5058	      const browserOffset = new Date(timestamp).getTimezoneOffset() * 60;
5059	      return Math.round(timestamp / 1000 - (parseInt(this._getMessage('SERVER_TZ_OFFSET'), 10) + parseInt(browserOffset, 10)));
5060	    }
5061	  }, {
5062	    key: "formatLastActivityDate",
5063	    value: function formatLastActivityDate(timestamp, now, utc) {
5064	      const ampm = this.isAmPmMode(true);
5065	      const timeFormat = ampm === this.AM_PM_MODE.LOWER ? 'g:i a' : ampm === this.AM_PM_MODE.UPPER ? 'g:i A' : 'H:i';
5066	      const format = [['tomorrow', '#01#' + timeFormat], ['now', '#02#'], ['todayFuture', '#03#' + timeFormat], ['yesterday', '#04#' + timeFormat], ['-', this.convertBitrixFormat(this._getMessage('FORMAT_DATETIME')).replace(/:s/g, '')], ['
5066s60', 'sago'], ['i60', 'iago'], ['H5', 'Hago'], ['H24', '#03#' + timeFormat], ['d31', 'dago'], ['m12>1', 'mago'], ['m12>0', 'dago'], ['', '#05#']];
5067	      let formattedDate = this.format(format, timestamp, now, utc);
5068	      let match = null;
5069	      if ((match = /^#(\d+)#(.*)/.exec(formattedDate)) != null) {
5070	        switch (match[1]) {
5071	          case '01':
5072	            formattedDate = this._getMessage('FD_LAST_SEEN_TOMORROW').replace('#TIME#', match[2]);
5073	            break;
5074	          case '02':
5075	            formattedDate = this._getMessage('FD_LAST_SEEN_NOW');
5076	            break;
5077	          case '03':
5078	            formattedDate = this._getMessage('FD_LAST_SEEN_TODAY').replace('#TIME#', match[2]);
5079	            break;
5080	          case '04':
5081	            formattedDate = this._getMessage('FD_LAST_SEEN_YESTERDAY').replace('#TIME#', match[2]);
5082	            break;
5083	          case '05':
5084	            formattedDate = this._getMessage('FD_LAST_SEEN_MORE_YEAR');
5085	            break;
5086	          default:
5087	            formattedDate = match[2];
5088	            break;
5089	        }
5090	      }
5091	      return formattedDate;
5092	    }
5093	    /**
5094	     * The method is designed to replace the localization storage on sites without Bitrix Framework.
5095	     * It gets overloaded with custom implementation:
5096	     *
5097	     * const CustomDate = Object.create(BX.Main.Date);
5098	     * CustomDate._getMessage = () => ...new implementation...;
5099	     *
5100	     * This class should get messages only via this method.
5101	     * Otherwise, the class won't work on sites without Bitrix Framework.
5102	     *
5103	     * @param message
5104	     * @returns {*}
5105	     * @private
5106	     */
5107	  }, {
5108	    key: "_getMessage",
5109	    value: function _getMessage(message) {
5110	      return main_core.Loc.getMessage(message);
5111	    }
5112	    /**
5113	     * The method used to parse date from string by given format.
5114	     *
5115	     * @param {string} str - date in given format
5116	     * @param {boolean} isUTC - is date in UTC
5117	     * @param {string} formatDate - format of the date without time
5118	     * @param {string} formatDatetime - format of the date with time
5119	     * @returns {Date|null} - returns Date object if string was parsed or null
5120	     */
5121	  }, {
5122	    key: "parse",
5123	    value: function parse(str, isUTC, formatDate, formatDatetime) {
5124	      if (main_core.Type.isStringFilled(str)) {
5125	        if (!formatDate) {
5126	          formatDate = this._getMessage('FORMAT_DATE');
5127	        }
5128	        if (!formatDatetime) {
5129	          formatDatetime = this._getMessage('FORMAT_DATETIME');
5130	        }
5131	        let regMonths = '';
5132	        for (let i = 1; i <= 12; i++) {
5133	          regMonths = regMonths + '|' + this._getMessage('MON_' + i);
5134	        }
5135	        const expr = new RegExp('([0-9]+|[a-z]+' + regMonths + ')', 'ig');
5136	        const aDate = str.match(expr);
5137	        let aFormat = formatDate.match(/(DD|MI|MMMM|MM|M|YYYY)/ig);
5138	        const aDateArgs = [];
5139	        const aFormatArgs = [];
5140	        const aResult = {};
5141	        if (!aDate) {
5142	          return null;
5143	        }
5144	        if (aDate.length > aFormat.length) {
5145	          aFormat = formatDatetime.match(/(DD|MI|MMMM|MM|M|YYYY|HH|H|SS|TT|T|GG|G)/ig);
5146	        }
5147	        for (let i = 0, cnt = aDate.length; i < cnt; i++) {
5148	          if (aDate[i].trim() !== '') {
5149	            aDateArgs[aDateArgs.length] = aDate[i];
5150	          }
5151	        }
5152	        for (let i = 0, cnt = aFormat.length; i < cnt; i++) {
5153	          if (aFormat[i].trim() !== '') {
5154	            aFormatArgs[aFormatArgs.length] = aFormat[i];
5155	          }
5156	        }
5157	        let m = aFormatArgs.findIndex(item => item === 'MMMM');
5158	        if (m > 0) {
5159	          aDateArgs[m] = this.getMonthIndex(aDateArgs[m]);
5160	          aFormatArgs[m] = 'MM';
5161	        } else {
5162	          m = aFormatArgs.findIndex(item => item === 'M');
5163	          if (m > 0) {
5164	            aDateArgs[m] = this.getMonthIndex(aDateArgs[m]);
5165	            aFormatArgs[m] = 'MM';
5166	          }
5167	        }
5168	        for (let i = 0, cnt = aFormatArgs.length; i < cnt; i++) {
5169	          const k = aFormatArgs[i].toUpperCase();
5170	          aResult[k] = k === 'T' || k === 'TT' ? aDateArgs[i] : parseInt(aDateArgs[i], 10);
5171	        }
5172	        if (aResult['DD'] > 0 && aResult['MM'] > 0 && aResult['YYYY'] > 0) {
5173	          const d = new Date();
5174	          if (isUTC) {
5175	            d.setUTCDate(1);
5176	            d.setUTCFullYear(aResult['YYYY']);
5177	            d.setUTCMonth(aResult['MM'] - 1);
5178	            d.setUTCDate(aResult['DD']);
5179	            d.setUTCHours(0, 0, 0, 0);
5180	          } else {
5181	            d.setDate(1);
5182	            d.setFullYear(aResult['YYYY']);
5183	            d.setMonth(aResult['MM'] - 1);
5184	            d.setDate(aResult['DD']);
5185	            d.setHours(0, 0, 0, 0);
5186	          }
5187	          if ((!isNaN(aResult['HH']) || !isNaN(aResult['GG']) || !isNaN(aResult['H']) || !isNaN(aResult['G'])) && !isNaN(aResult['MI'])) {
5188	            if (!isNaN(aResult['H']) || !isNaN(aResult['G'])) {
5189	              const bPM = (aResult['T'] || aResult['TT'] || 'am').toUpperCase() === 'PM',
5190	                h = parseInt(aResult['H'] || aResult['G'] || 0, 10);
5191	              if (bPM) {
5192	                aResult['HH'] = h + (h === 12 ? 0 : 12);
5193	              } else {
5194	                aResult['HH'] = h < 12 ? h : 0;
5195	              }
5196	            } else {
5197	              aResult['HH'] = parseInt(aResult['HH'] || aResult['GG'] || 0, 10);
5198	            }
5199	            if (isNaN(aResult['SS'])) {
5200	              aResult['SS'] = 0;
5201	            }
5202	            if (isUTC) {
5203	              d.setUTCHours(aResult['HH'], aResult['MI'], aResult['SS']);
5204	            } else {
5205	              d.setHours(aResult['HH'], aResult['MI'], aResult['SS']);
5206	            }
5207	          }
5208	          return d;
5209	        }
5210	      }
5211	      return null;
5212	    }
5213	  }, {
5214	    key: "getMonthIndex",
5215	    value: function getMonthIndex(month) {
5216	      const q = month.toUpperCase();
5217	      const wordMonthCut = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
5218	      const wordMonth = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
5219	      for (let i = 1; i <= 12; i++) {
5220	        if (q === this._getMessage('MON_' + i).toUpperCase() || q === this._getMessage('MONTH_' + i).toUpperCase() || q === this._getMessage('MONTH_' + i + '_S').toUpperCase() || q === wordMonthCut[i - 1].toUpperCase() || q === wordMonth[i - 1].toUpperCase()) {
5221	          return i;
5222	        }
5223	      }
5224	      return month;
5225	    }
5226	  }, {
5227	    key: "format",
5228	    value: function format(_format, timestamp, now, utc) {
5229	      /*
5230	      PHP to Javascript:
5231	      	time() = new Date()
5232	      	mktime(...) = new Date(...)
5233	      	gmmktime(...) = new Date(Date.UTC(...))
5234	      	mktime(0,0,0, 1, 1, 1970) != 0          new Date(1970,0,1).getTime() != 0
5235	      	gmmktime(0,0,0, 1, 1, 1970) == 0        new Date(Date.UTC(1970,0,1)).getTime() == 0
5236	      	date('d.m.Y H:i:s') = BX.Main.Date.format('d.m.Y H:i:s')
5237	      	gmdate('d.m.Y H:i:s') = BX.Main.Date.format('d.m.Y H:i:s', null, null, true);
5238	      */
5239	      const date = main_core.Type.isDate(timestamp) ? new Date(timestamp.getTime()) : main_core.Type.isNumber(timestamp) ? new Date(timestamp * 1000) : new Date();
5240	      const nowDate = main_core.Type.isDate(now) ? new Date(now.getTime()) : main_core.Type.isNumber(now) ? new Date(now * 1000) : new Date();
5241	      const isUTC = !!utc;
5242	      // used in hoisting inner functions, like _formatDateInterval
5243	      const thisDateTimeFormat = this;
5244	      if (main_core.Type.isArray(_format)) {
5245	        return _formatDateInterval(_format, date, nowDate, isUTC);
5246	      } else {
5247	        if (!main_core.Type.isStringFilled(_format)) {
5248	          return '';
5249	        }
5250	      }
5251	      const replaceMap = (_format.match(/{{([^{}]*)}}/g) || []).map(x => {
5252	        return (x.match(/[^{}]+/) || [''])[0];
5253	      });
5254	      if (replaceMap.length > 0) {
5255	        replaceMap.forEach((element, index) => {
5256	          _format = _format.replace('{{' + element + '}}', '{{' + index + '}}');
5257	        });
5258	      }
5259	      const formatRegex = /\\?(sago|iago|isago|Hago|dago|mago|Yago|sdiff|idiff|Hdiff|ddiff|mdiff|Ydiff|sshort|ishort|Hshort|dshort|mshort|Yshort|yesterday|today|tommorow|tomorrow|.)/gi;
5260	      const dateFormats = {
5261	        d: () => {
5262	          // Day of the month 01 to 31
5263	          return getDate(date).toString().padStart(2, '0');
5264	        },
5265	        D: () => {
5266	          //Mon through Sun
5267	          return this._getMessage('DOW_' + getDay(date));
5268	        },
5269	        j: () => {
5270	          //Day of the month 1 to 31
5271	          return getDate(date);
5272	        },
5273	        l: () => {
5274	          //Sunday through Saturday
5275	          return this._getMessage('DAY_OF_WEEK_' + getDay(date));
5276	        },
5277	        N: () => {
5278	          //1 (for Monday) through 7 (for Sunday)
5279	          return getDay(date) || 7;
5280	        },
5281	        S: () => {
5282	          //st, nd, rd or th. Works well with j
5283	          if (getDate(date) % 10 == 1 && getDate(date) != 11) {
5284	            return 'st';
5285	          } else if (getDate(date) % 10 == 2 && getDate(date) != 12) {
5286	            return 'nd';
5287	          } else if (getDate(date) % 10 == 3 && getDate(date) != 13) {
5288	            return 'rd';
5289	          } else {
5290	            return 'th';
5291	          }
5292	        },
5293	        w: () => {
5294	          //0 (for Sunday) through 6 (for Saturday)
5295	          return getDay(date);
5296	        },
5297	        z: () => {
5298	          //0 through 365
5299	          const firstDay = new Date(getFullYear(date), 0, 1);
5300	          const currentDay = new Date(getFullYear(date), getMonth(date), getDate(date));
5301	          return Math.ceil((currentDay - firstDay) / (24 * 3600 * 1000));
5302	        },
5303	        W: () => {
5304	          //ISO-8601 week number of year
5305	          const newDate = new Date(date.getTime());
5306	          const dayNumber = (getDay(date) + 6) % 7;
5307	          setDate(newDate, getDate(newDate) - dayNumber + 3);
5308	          const firstThursday = newDate.getTime();
5309	          setMonth(newDate, 0, 1);
5310	          if (getDay(newDate) != 4) {
5311	            setMonth(newDate, 0, 1 + (4 - getDay(newDate) + 7) % 7);
5312	          }
5313	          const weekNumber = 1 + Math.ceil((firstThursday - newDate) / (7 * 24 * 3600 * 1000));
5314	          return weekNumber.toString().padStart(2, '0');
5315	        },
5316	        F: () => {
5317	          //January through December
5318	          return this._getMessage('MONTH_' + (getMonth(date) + 1) + '_S');
5319	        },
5320	        f: () => {
5321	          //January through December
5322	          return this._getMessage('MONTH_' + (getMonth(date) + 1));
5323	        },
5324	        m: () => {
5325	          //Numeric representation of a month 01 through 12
5326	          return (getMonth(date) + 1).toString().padStart(2, '0');
5327	        },
5328	        M: () => {
5329	          //A short textual representation of a month, three letters Jan through Dec
5330	          return this._getMessage('MON_' + (getMonth(date) + 1));
5331	        },
5332	        n: () => {
5333	          //Numeric representation of a month 1 through 12
5334	          return getMonth(date) + 1;
5335	        },
5336	        t: () => {
5337	          //Number of days in the given month 28 through 31
5338	          const lastMonthDay = isUTC ? new Date(Date.UTC(getFullYear(date), getMonth(date) + 1, 0)) : new Date(getFullYear(date), getMonth(date) + 1, 0);
5339	          return getDate(lastMonthDay);
5340	        },
5341	        L: () => {
5342	          //1 if it is a leap year, 0 otherwise.
5343	          const year = getFullYear(date);
5344	          return year % 4 == 0 && year % 100 != 0 || year % 400 == 0 ? 1 : 0;
5345	        },
5346	        o: () => {
5347	          //ISO-8601 year number
5348	          const correctDate = new Date(date.getTime());
5349	          setDate(correctDate, getDate(correctDate) - (getDay(date) + 6) % 7 + 3);
5350	          return getFullYear(correctDate);
5351	        },
5352	        Y: () => {
5353	          //A full numeric representation of a year, 4 digits
5354	          return getFullYear(date);
5355	        },
5356	        y: () => {
5357	          //A two digit representation of a year
5358	          return getFullYear(date).toString().slice(2);
5359	        },
5360	        a: () => {
5361	          //am or pm
5362	          return getHours(date) > 11 ? 'pm' : 'am';
5363	        },
5364	        A: () => {
5365	          //AM or PM
5366	          return getHours(date) > 11 ? 'PM' : 'AM';
5367	        },
5368	        B: () => {
5369	          //000 through 999
5370	          const swatch = (date.getUTCHours() + 1) % 24 + date.getUTCMinutes() / 60 + date.getUTCSeconds() / 3600;
5371	          return Math.floor(swatch * 1000 / 24).toString().padStart(3, '0');
5372	        },
5373	        g: () => {
5374	          //12-hour format of an hour without leading zeros 1 through 12
5375	          return getHours(date) % 12 || 12;
5376	        },
5377	        G: () => {
5378	          //24-hour format of an hour without leading zeros 0 through 23
5379	          return getHours(date);
5380	        },
5381	        h: () => {
5382	          //12-hour format of an hour with leading zeros 01 through 12
5383	          return (getHours(date) % 12 || 12).toString().padStart(2, '0');
5384	        },
5385	        H: () => {
5386	          //24-hour format of an hour with leading zeros 00 through 23
5387	          return getHours(date).toString().padStart(2, '0');
5388	        },
5389	        i: () => {
5390	          //Minutes with leading zeros 00 to 59
5391	          return getMinutes(date).toString().padStart(2, '0');
5392	        },
5393	        s: () => {
5394	          //Seconds, with leading zeros 00 through 59
5395	          return getSeconds(date).toString().padStart(2, '0');
5396	        },
5397	        u: () => {
5398	          //Microseconds
5399	          return (getMilliseconds(date) * 1000).toString().padStart(6, '0');
5400	        },
5401	        e: () => {
5402	          if (isUTC) {
5403	            return 'UTC';
5404	          }
5405	          return '';
5406	        },
5407	        I: () => {
5408	          if (isUTC) {
5409	            return 0;
5410	          }
5411
5412	          //Whether or not the date is in daylight saving time 1 if Daylight Saving Time, 0 otherwise
5413	          const firstJanuary = new Date(getFullYear(date), 0, 1);
5414	          const firstJanuaryUTC = Date.UTC(getFullYear(date), 0, 1);
5415	          const firstJuly = new Date(getFullYear(date), 6, 0);
5416	          const firstJulyUTC = Date.UTC(getFullYear(date), 6, 0);
5417	          return 0 + (firstJanuary - firstJanuaryUTC !== firstJuly - firstJulyUTC);
5418	        },
5419	        O: () => {
5420	          if (isUTC) {
5421	            return '+0000';
5422	          }
5423
5424	          //Difference to Greenwich time (GMT) in hours +0200
5425	          const timezoneOffset = date.getTimezoneOffset();
5426	          const timezoneOffsetAbs = Math.abs(timezoneOffset);
5427	          return (timezoneOffset > 0 ? '-' : '+') + (Math.floor(timezoneOffsetAbs / 60) * 100 + timezoneOffsetAbs % 60).toString().padStart(4, '0');
5428	        },
5429	        //this method references 'O' method of the same object, arrow function is not suitable here
5430	        P: function () {
5431	          if (isUTC) {
5432	            return '+00:00';
5433	          }
5434
5435	          //Difference to Greenwich time (GMT) with colon between hours and minutes +02:00
5436	          const difference = this.O();
5437	          return difference.substr(0, 3) + ':' + difference.substr(3);
5438	        },
5439	        Z: () => {
5440	          if (isUTC) {
5441	            return 0;
5442	          }
5443	          //Timezone offset in seconds. The offset for timezones west of UTC is always negative,
5444	          //and for those east of UTC is always positive.
5445	          return -date.getTimezoneOffset() * 60;
5446	        },
5447	        c: () => {
5448	          //ISO 8601 date
5449	          return 'Y-m-d\\TH:i:sP'.replace(formatRegex, _replaceDateFormat);
5450	        },
5451	        r: () => {
5452	          //RFC 2822 formatted date
5453	          return 'D, d M Y H:i:s O'.replace(formatRegex, _replaceDateFormat);
5454	        },
5455	        U: () => {
5456	          //Seconds since the Unix Epoch
5457	          return Math.floor(date.getTime() / 1000);
5458	        },
5459	        sago: () => {
5460	          return _formatDateMessage(intval((nowDate - date) / 1000), {
5461	            '0': 'FD_SECOND_AGO_0',
5462	            '1': 'FD_SECOND_AGO_1',
5463	            '10_20': 'FD_SECOND_AGO_10_20',
5464	            'MOD_1': 'FD_SECOND_AGO_MOD_1',
5465	            'MOD_2_4': 'FD_SECOND_AGO_MOD_2_4',
5466	            'MOD_OTHER': 'FD_SECOND_AGO_MOD_OTHER'
5467	          });
5468	        },
5469	        sdiff: () => {
5470	          return _formatDateMessage(intval((nowDate - date) / 1000), {
5471	            '0': 'FD_SECOND_DIFF_0',
5472	            '1': 'FD_SECOND_DIFF_1',
5473	            '10_20': 'FD_SECOND_DIFF_10_20',
5474	            'MOD_1': 'FD_SECOND_DIFF_MOD_1',
5475	            'MOD_2_4': 'FD_SECOND_DIFF_MOD_2_4',
5476	            'MOD_OTHER': 'FD_SECOND_DIFF_MOD_OTHER'
5477	          });
5478	        },
5479	        sshort: () => {
5480	          return this._getMessage('FD_SECOND_SHORT').replace(/#VALUE#/g, intval((nowDate - date) / 1000));
5481	        },
5482	        iago: () => {
5483	          return _formatDateMessage(intval((nowDate - date) / 60 / 1000), {
5484	            '0': 'FD_MINUTE_AGO_0',
5485	            '1': 'FD_MINUTE_AGO_1',
5486	            '10_20': 'FD_MINUTE_AGO_10_20',
5487	            'MOD_1': 'FD_MINUTE_AGO_MOD_1',
5488	            'MOD_2_4': 'FD_MINUTE_AGO_MOD_2_4',
5489	            'MOD_OTHER': 'FD_MINUTE_AGO_MOD_OTHER'
5490	          });
5491	        },
5492	        idiff: () => {
5493	          return _formatDateMessage(intval((nowDate - date) / 60 / 1000), {
5494	            '0': 'FD_MINUTE_DIFF_0',
5495	            '1': 'FD_MINUTE_DIFF_1',
5496	            '10_20': 'FD_MINUTE_DIFF_10_20',
5497	            'MOD_1': 'FD_MINUTE_DIFF_MOD_1',
5498	            'MOD_2_4': 'FD_MINUTE_DIFF_MOD_2_4',
5499	            'MOD_OTHER': 'FD_MINUTE_DIFF_MOD_OTHER'
5500	          });
5501	        },
5502	        isago: () => {
5503	          const minutesAgo = intval((nowDate - date) / 60 / 1000);
5504	          let result = _formatDateMessage(minutesAgo, {
5505	            '0': 'FD_MINUTE_0',
5506	            '1': 'FD_MINUTE_1',
5507	            '10_20': 'FD_MINUTE_10_20',
5508	            'MOD_1': 'FD_MINUTE_MOD_1',
5509	            'MOD_2_4': 'FD_MINUTE_MOD_2_4',
5510	            'MOD_OTHER': 'FD_MINUTE_MOD_OTHER'
5511	          });
5512	          result += ' ';
5513	          const secondsAgo = intval((nowDate - date) / 1000) - minutesAgo * 60;
5514	          result += _formatDateMessage(secondsAgo, {
5515	            '0': 'FD_SECOND_AGO_0',
5516	            '1': 'FD_SECOND_AGO_1',
5517	            '10_20': 'FD_SECOND_AGO_10_20',
5518	            'MOD_1': 'FD_SECOND_AGO_MOD_1',
5519	            'MOD_2_4': 'FD_SECOND_AGO_MOD_2_4',
5520	            'MOD_OTHER': 'FD_SECOND_AGO_MOD_OTHER'
5521	          });
5522	          return result;
5523	        },
5524	        ishort: () => {
5525	          return this._getMessage('FD_MINUTE_SHORT').replace(/#VALUE#/g, intval((nowDate - date) / 60 / 1000));
5526	        },
5527	        Hago: () => {
5528	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 1000), {
5529	            '0': 'FD_HOUR_AGO_0',
5530	            '1': 'FD_HOUR_AGO_1',
5531	            '10_20': 'FD_HOUR_AGO_10_20',
5532	            'MOD_1': 'FD_HOUR_AGO_MOD_1',
5533	            'MOD_2_4': 'FD_HOUR_AGO_MOD_2_4',
5534	            'MOD_OTHER': 'FD_HOUR_AGO_MOD_OTHER'
5535	          });
5536	        },
5537	        Hdiff: () => {
5538	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 1000), {
5539	            '0': 'FD_HOUR_DIFF_0',
5540	            '1': 'FD_HOUR_DIFF_1',
5541	            '10_20': 'FD_HOUR_DIFF_10_20',
5542	            'MOD_1': 'FD_HOUR_DIFF_MOD_1',
5543	            'MOD_2_4': 'FD_HOUR_DIFF_MOD_2_4',
5544	            'MOD_OTHER': 'FD_HOUR_DIFF_MOD_OTHER'
5545	          });
5546	        },
5547	        Hshort: () => {
5548	          return this._getMessage('FD_HOUR_SHORT').replace(/#VALUE#/g, intval((nowDate - date) / 60 / 60 / 1000));
5549	        },
5550	        yesterday: () => {
5551	          return this._getMessage('FD_YESTERDAY');
5552	        },
5553	        today: () => {
5554	          return this._getMessage('FD_TODAY');
5555	        },
5556	        tommorow: () => {
5557	          return this._getMessage('FD_TOMORROW');
5558	        },
5559	        tomorrow: () => {
5560	          return this._getMessage('FD_TOMORROW');
5561	        },
5562	        dago: () => {
5563	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 1000), {
5564	            '0': 'FD_DAY_AGO_0',
5565	            '1': 'FD_DAY_AGO_1',
5566	            '10_20': 'FD_DAY_AGO_10_20',
5567	            'MOD_1': 'FD_DAY_AGO_MOD_1',
5568	            'MOD_2_4': 'FD_DAY_AGO_MOD_2_4',
5569	            'MOD_OTHER': 'FD_DAY_AGO_MOD_OTHER'
5570	          });
5571	        },
5572	        ddiff: () => {
5573	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 1000), {
5574	            '0': 'FD_DAY_DIFF_0',
5575	            '1': 'FD_DAY_DIFF_1',
5576	            '10_20': 'FD_DAY_DIFF_10_20',
5577	            'MOD_1': 'FD_DAY_DIFF_MOD_1',
5578	            'MOD_2_4': 'FD_DAY_DIFF_MOD_2_4',
5579	            'MOD_OTHER': 'FD_DAY_DIFF_MOD_OTHER'
5580	          });
5581	        },
5582	        dshort: () => {
5583	          return this._getMessage('FD_DAY_SHORT').replace(/#VALUE#/g, intval((nowDate - date) / 60 / 60 / 24 / 1000));
5584	        },
5585	        mago: () => {
5586	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 31 / 1000), {
5587	            '0': 'FD_MONTH_AGO_0',
5588	            '1': 'FD_MONTH_AGO_1',
5589	            '10_20': 'FD_MONTH_AGO_10_20',
5590	            'MOD_1': 'FD_MONTH_AGO_MOD_1',
5591	            'MOD_2_4': 'FD_MONTH_AGO_MOD_2_4',
5592	            'MOD_OTHER': 'FD_MONTH_AGO_MOD_OTHER'
5593	          });
5594	        },
5595	        mdiff: () => {
5596	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 31 / 1000), {
5597	            '0': 'FD_MONTH_DIFF_0',
5598	            '1': 'FD_MONTH_DIFF_1',
5599	            '10_20': 'FD_MONTH_DIFF_10_20',
5600	            'MOD_1': 'FD_MONTH_DIFF_MOD_1',
5601	            'MOD_2_4': 'FD_MONTH_DIFF_MOD_2_4',
5602	            'MOD_OTHER': 'FD_MONTH_DIFF_MOD_OTHER'
5603	          });
5604	        },
5605	        mshort: () => {
5606	          return this._getMessage('FD_MONTH_SHORT').replace(/#VALUE#/g, intval((nowDate - date) / 60 / 60 / 24 / 31 / 1000));
5607	        },
5608	        Yago: () => {
5609	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 365 / 1000), {
5610	            '0': 'FD_YEARS_AGO_0',
5611	            '1': 'FD_YEARS_AGO_1',
5612	            '10_20': 'FD_YEARS_AGO_10_20',
5613	            'MOD_1': 'FD_YEARS_AGO_MOD_1',
5614	            'MOD_2_4': 'FD_YEARS_AGO_MOD_2_4',
5615	            'MOD_OTHER': 'FD_YEARS_AGO_MOD_OTHER'
5616	          });
5617	        },
5618	        Ydiff: () => {
5619	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 365 / 1000), {
5620	            '0': 'FD_YEARS_DIFF_0',
5621	            '1': 'FD_YEARS_DIFF_1',
5622	            '10_20': 'FD_YEARS_DIFF_10_20',
5623	            'MOD_1': 'FD_YEARS_DIFF_MOD_1',
5624	            'MOD_2_4': 'FD_YEARS_DIFF_MOD_2_4',
5625	            'MOD_OTHER': 'FD_YEARS_DIFF_MOD_OTHER'
5626	          });
5627	        },
5628	        Yshort: () => {
5629	          return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 365 / 1000), {
5630	            '0': 'FD_YEARS_SHORT_0',
5631	            '1': 'FD_YEARS_SHORT_1',
5632	            '10_20': 'FD_YEARS_SHORT_10_20',
5633	            'MOD_1': 'FD_YEARS_SHORT_MOD_1',
5634	            'MOD_2_4': 'FD_YEARS_SHORT_MOD_2_4',
5635	            'MOD_OTHER': 'FD_YEARS_SHORT_MOD_OTHER'
5636	          });
5637	        },
5638	        x: () => {
5639	          const ampm = this.isAmPmMode(true);
5640	          const timeFormat = ampm === this.AM_PM_MODE.LOWER ? 'g:i a' : ampm === this.AM_PM_MODE.UPPER ? 'g:i A' : 'H:i';
5641	          return this.format([['tomorrow', 'tomorrow, ' + timeFormat], ['-', this.convertBitrixFormat(this._getMessage('FORMAT_DATETIME')).replace(/:s/g, '')], ['
5641s', 'sago'], ['i', 'iago'], ['today', 'today, ' + timeFormat], ['yesterday', 'yesterday, ' + timeFormat], ['', this.convertBitrixFormat(this._getMessage('FORMAT_DATETIME')).replace(/:s/g, '')]], date, nowDate, isUTC);
5642	        },
5643	        X: () => {
5644	          const ampm = this.isAmPmMode(true);
5645	          const timeFormat = ampm === this.AM_PM_MODE.LOWER ? 'g:i a' : ampm === this.AM_PM_MODE.UPPER ? 'g:i A' : 'H:i';
5646	          const day = this.format([['tomorrow', 'tomorrow'], ['-', this.convertBitrixFormat(this._getMessage('FORMAT_DATE'))], ['today', 'today'], ['yesterday', 'yesterday'], ['', this.convertBitrixFormat(this._getMessage('FORMAT_DATE'))]], date, nowDate, isUTC);
5647	          const time = this.format([['tomorrow', timeFormat], ['today', timeFormat], ['yesterday', timeFormat], ['', '']], date, nowDate, isUTC);
5648	          if (time.length > 0) {
5649	            return this._getMessage('FD_DAY_AT_TIME').replace(/#DAY#/g, day).replace(/#TIME#/g, time);
5650	          } else {
5651	            return day;
5652	          }
5653	        },
5654	        Q: () => {
5655	          const daysAgo = intval((nowDate - date) / 60 / 60 / 24 / 1000);
5656	          if (daysAgo == 0) {
5657	            return this._getMessage('FD_DAY_DIFF_1').replace(/#VALUE#/g, 1);
5658	          } else {
5659	            return this.format([['d', 'ddiff'], ['m', 'mdiff'], ['', 'Ydiff']], date, nowDate);
5660	          }
5661	        }
5662	      };
5663	      let cutZeroTime = false;
5664	      if (_format[0] && _format[0] == '^') {
5665	        cutZeroTime = true;
5666	        _format = _format.substr(1);
5667	      }
5668	      let result = _format.replace(formatRegex, _replaceDateFormat);
5669	      if (cutZeroTime) {
5670	        /* 	15.04.12 13:00:00 => 15.04.12 13:00
5671	        	00:01:00 => 00:01
5672	        	4 may 00:00:00 => 4 may
5673	        	01-01-12 00:00 => 01-01-12
5674	        */
5675
5676	        result = result.replace(/\s*00:00:00\s*/g, '').replace(/(\d\d:\d\d)(:00)/g, '$1').replace(/(\s*00:00\s*)(?!:)/g, '');
5677	      }
5678	      if (replaceMap.length > 0) {
5679	        replaceMap.forEach(function (element, index) {
5680	          result = result.replace('{{' + index + '}}', element);
5681	        });
5682	      }
5683	      return result;
5684	      function _formatDateInterval(formats, date, nowDate, isUTC) {
5685	        const secondsAgo = intval((nowDate - date) / 1000);
5686	        for (let i = 0; i < formats.length; i++) {
5687	          const formatInterval = formats[i][0];
5688	          const formatValue = formats[i][1];
5689	          let match = null;
5690	          if (formatInterval == 's') {
5691	            if (secondsAgo < 60) {
5692	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5693	            }
5694	          } else if ((match = /^s(\d+)\>?(\d+)?/.exec(formatInterval)) != null) {
5695	            if (match[1] && match[2]) {
5696	              if (secondsAgo < match[1] && secondsAgo > match[2]) {
5697	                return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5698	              }
5699	            } else if (secondsAgo < match[1]) {
5700	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5701	            }
5702	          } else if (formatInterval == 'i') {
5703	            if (secondsAgo < 60 * 60) {
5704	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5705	            }
5706	          } else if ((match = /^i(\d+)\>?(\d+)?/.exec(formatInterval)) != null) {
5707	            if (match[1] && match[2]) {
5708	              if (secondsAgo < match[1] * 60 && secondsAgo > match[2] * 60) {
5709	                return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5710	              }
5711	            } else if (secondsAgo < match[1] * 60) {
5712	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5713	            }
5714	          } else if (formatInterval == 'H') {
5715	            if (secondsAgo < 24 * 60 * 60) {
5716	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5717	            }
5718	          } else if ((match = /^H(\d+)\>?(\d+)?/.exec(formatInterval)) != null) {
5719	            if (match[1] && match[2]) {
5720	              if (secondsAgo < match[1] * 60 * 60 && secondsAgo > match[2] * 60 * 60) {
5721	                return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5722	              }
5723	            } else if (secondsAgo < match[1] * 60 * 60) {
5724	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5725	            }
5726	          } else if (formatInterval == 'd') {
5727	            if (secondsAgo < 31 * 24 * 60 * 60) {
5728	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5729	            }
5730	          } else if ((match = /^d(\d+)\>?(\d+)?/.exec(formatInterval)) != null) {
5731	            if (match[1] && match[2]) {
5732	              if (secondsAgo < match[1] * 24 * 60 * 60 && secondsAgo > match[2] * 24 * 60 * 60) {
5733	                return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5734	              }
5735	            } else if (secondsAgo < match[1] * 24 * 60 * 60) {
5736	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5737	            }
5738	          } else if (formatInterval == 'm') {
5739	            if (secondsAgo < 365 * 24 * 60 * 60) {
5740	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5741	            }
5742	          } else if ((match = /^m(\d+)\>?(\d+)?/.exec(formatInterval)) != null) {
5743	            if (match[1] && match[2]) {
5744	              if (secondsAgo < match[1] * 31 * 24 * 60 * 60 && secondsAgo > match[2] * 31 * 24 * 60 * 60) {
5745	                return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5746	              }
5747	            } else if (secondsAgo < match[1] * 31 * 24 * 60 * 60) {
5748	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5749	            }
5750	          } else if (formatInterval == 'now') {
5751	            if (date.getTime() == nowDate.getTime()) {
5752	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5753	            }
5754	          } else if (formatInterval == 'today') {
5755	            const year = getFullYear(nowDate);
5756	            const month = getMonth(nowDate);
5757	            const day = getDate(nowDate);
5758	            const todayStart = isUTC ? new Date(Date.UTC(year, month, day, 0, 0, 0, 0)) : new Date(year, month, day, 0, 0, 0, 0);
5759	            const todayEnd = isUTC ? new Date(Date.UTC(year, month, day + 1, 0, 0, 0, 0)) : new Date(year, month, day + 1, 0, 0, 0, 0);
5760	            if (date >= todayStart && date < todayEnd) {
5761	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5762	            }
5763	          } else if (formatInterval == 'todayFuture') {
5764	            const year = getFullYear(nowDate);
5765	            const month = getMonth(nowDate);
5766	            const day = getDate(nowDate);
5767	            const todayStart = nowDate.getTime();
5768	            const todayEnd = isUTC ? new Date(Date.UTC(year, month, day + 1, 0, 0, 0, 0)) : new Date(year, month, day + 1, 0, 0, 0, 0);
5769	            if (date >= todayStart && date < todayEnd) {
5770	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5771	            }
5772	          } else if (formatInterval == 'yesterday') {
5773	            const year = getFullYear(nowDate);
5774	            const month = getMonth(nowDate);
5775	            const day = getDate(nowDate);
5776	            const yesterdayStart = isUTC ? new Date(Date.UTC(year, month, day - 1, 0, 0, 0, 0)) : new Date(year, month, day - 1, 0, 0, 0, 0);
5777	            const yesterdayEnd = isUTC ? new Date(Date.UTC(year, month, day, 0, 0, 0, 0)) : new Date(year, month, day, 0, 0, 0, 0);
5778	            if (date >= yesterdayStart && date < yesterdayEnd) {
5779	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5780	            }
5781	          } else if (formatInterval == 'tommorow' || formatInterval == 'tomorrow') {
5782	            const year = getFullYear(nowDate);
5783	            const month = getMonth(nowDate);
5784	            const day = getDate(nowDate);
5785	            const tomorrowStart = isUTC ? new Date(Date.UTC(year, month, day + 1, 0, 0, 0, 0)) : new Date(year, month, day + 1, 0, 0, 0, 0);
5786	            const tomorrowEnd = isUTC ? new Date(Date.UTC(year, month, day + 2, 0, 0, 0, 0)) : new Date(year, month, day + 2, 0, 0, 0, 0);
5787	            if (date >= tomorrowStart && date < tomorrowEnd) {
5788	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5789	            }
5790	          } else if (formatInterval == '-') {
5791	            if (secondsAgo < 0) {
5792	              return thisDateTimeFormat.format(formatValue, date, nowDate, isUTC);
5793	            }
5794	          }
5795	        }
5796
5797	        //return formats.length > 0 ? thisDateTimeFormat.format(formats.pop()[1], date, nowDate, isUTC) : '';
5798	        return formats.length > 0 ? thisDateTimeFormat.format(formats[formats.length - 1][1], date, nowDate, isUTC) : '';
5799	      }
5800	      function getFullYear(date) {
5801	        return isUTC ? date.getUTCFullYear() : date.getFullYear();
5802	      }
5803	      function getDate(date) {
5804	        return isUTC ? date.getUTCDate() : date.getDate();
5805	      }
5806	      function getMonth(date) {
5807	        return isUTC ? date.getUTCMonth() : date.getMonth();
5808	      }
5809	      function getHours(date) {
5810	        return isUTC ? date.getUTCHours() : date.getHours();
5811	      }
5812	      function getMinutes(date) {
5813	        return isUTC ? date.getUTCMinutes() : date.getMinutes();
5814	      }
5815	      function getSeconds(date) {
5816	        return isUTC ? date.getUTCSeconds() : date.getSeconds();
5817	      }
5818	      function getMilliseconds(date) {
5819	        return isUTC ? date.getUTCMilliseconds() : date.getMilliseconds();
5820	      }
5821	      function getDay(date) {
5822	        return isUTC ? date.getUTCDay() : date.getDay();
5823	      }
5824	      function setDate(date, dayValue) {
5825	        return isUTC ? date.setUTCDate(dayValue) : date.setDate(dayValue);
5826	      }
5827	      function setMonth(date, monthValue, dayValue) {
5828	        return isUTC ? date.setUTCMonth(monthValue, dayValue) : date.setMonth(monthValue, dayValue);
5829	      }
5830	      function _formatDateMessage(value, messages) {
5831	        const val = value < 100 ? Math.abs(value) : Math.abs(value % 100);
5832	        const dec = val % 10;
5833	        let message = '';
5834	        if (val == 0) {
5835	          message = thisDateTimeFormat._getMessage(messages['0']);
5836	        } else if (val == 1) {
5837	          message = thisDateTimeFormat._getMessage(messages['1']);
5838	        } else if (val >= 10 && val <= 20) {
5839	          message = thisDateTimeFormat._getMessage(messages['10_20']);
5840	        } else if (dec == 1) {
5841	          message = thisDateTimeFormat._getMessage(messages['MOD_1']);
5842	        } else if (2 <= dec && dec <= 4) {
5843	          message = thisDateTimeFormat._getMessage(messages['MOD_2_4']);
5844	        } else {
5845	          message = thisDateTimeFormat._getMessage(messages['MOD_OTHER']);
5846	        }
5847	        return message.replace(/#VALUE#/g, value);
5848	      }
5849	      function _replaceDateFormat(match, matchFull) {
5850	        if (dateFormats[match]) {
5851	          return dateFormats[match]();
5852	        } else {
5853	          return matchFull;
5854	        }
5855	      }
5856	      function intval(number) {
5857	        return number >= 0 ? Math.floor(number) : Math.ceil(number);
5858	      }
5859	    }
5860	  }]);
5861	  return DateTimeFormat;
5862	}();
5863	babelHelpers.defineProperty(DateTimeFormat, "AM_PM_MODE", {
5864	  UPPER: 1,
5865	  LOWER: 2,
5866	  NONE: false
5867	});
5868	babelHelpers.defineProperty(DateTimeFormat, "convertBitrixFormat", convertBitrixFormat);
5869	babelHelpers.defineProperty(DateTimeFormat, "getFormat", getFormat);
5870
5871	function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
5872	function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
5873	function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
5874
5875	/**
5876	 * Available units: `Y` - years, `m` - months, `d` - days, `H` - hours, `i` - minutes, `s` - seconds.
5877	 */
5878
5879	const defaultOptions = {
5880	  format: 'Y m d H i s',
5881	  style: 'long'
5882	};
5883	var _getSeparator = /*#__PURE__*/new WeakSet();
5884	var _getMaxUnit = /*#__PURE__*/new WeakSet();
5885	var _formatUnit = /*#__PURE__*/new WeakSet();
5886	var _getUnitPropertyModByFormat = /*#__PURE__*/new WeakSet();
5887	var _getUnitPropertyByFormat = /*#__PURE__*/new WeakSet();
5888	var _getUnitDuration = /*#__PURE__*/new WeakSet();
5889	let DurationFormat = /*#__PURE__*/function () {
5890	  function DurationFormat(milliseconds) {
5891	    babelHelpers.classCallCheck(this, DurationFormat);
5892	    _classPrivateMethodInitSpec(this, _getUnitDuration);
5893	    _classPrivateMethodInitSpec(this, _getUnitPropertyByFormat);
5894	    _classPrivateMethodInitSpec(this, _getUnitPropertyModByFormat);
5895	    _classPrivateMethodInitSpec(this, _formatUnit);
5896	    _classPrivateMethodInitSpec(this, _getMaxUnit);
5897	    _classPrivateMethodInitSpec(this, _getSeparator);
5898	    this.milliseconds = Math.abs(milliseconds);
5899	  }
5900	  babelHelpers.createClass(DurationFormat, [{
5901	    key: "format",
5902	    /**
5903	     * @example new DurationFormat(5070000).format() // 1 hour, 24 minutes, 30 seconds
5904	     * @example new DurationFormat(5070000).format({ style: 'short' }) // 1 h 24 m 30 s
5905	     * @example new DurationFormat(5070000).format({ format: 'd H i' }) // 1 hour, 24 minutes
5906	     * @example new DurationFormat(5070000).format({ format: 'i s' }) // 84 minutes, 30 seconds
5907	     */
5908	    value: function format(formatOptions = defaultOptions) {
5909	      const options = {
5910	        ...defaultOptions,
5911	        ...formatOptions
5912	      };
5913	      const orderedUnits = main_core.Loc.getMessage('FD_UNIT_ORDER').split(' ');
5914	      const separator = _classPrivateMethodGet(this, _getSeparator, _getSeparator2).
5914call(this, options.style);
5915	      const formatUnits = new Set(options.format.split(' '));
5916	      const maxUnit = _classPrivateMethodGet(this, _getMaxUnit, _getMaxUnit2).call(this, options.format);
5917	      return orderedUnits.filter(unit => formatUnits.has(unit)).map(unit => _classPrivateMethodGet(this, _formatUnit, _formatUnit2).call(this, unit, unit !== maxUnit, options.style)).filter(unit => unit !== '').join(separator);
5918	    }
5919	    /**
5920	     * @example new DurationFormat(5070000).formatClosest() // 1 hour
5921	     * @example new DurationFormat(5070000).formatClosest({ format: 'i s' }) // 84 minutes
5922	     */
5923	  }, {
5924	    key: "formatClosest",
5925	    value: function formatClosest(formatOptions = defaultOptions) {
5926	      const options = {
5927	        ...defaultOptions,
5928	        ...formatOptions
5929	      };
5930	      const maxUnit = _classPrivateMethodGet(this, _getMaxUnit, _getMaxUnit2).call(this, options.format);
5931	      return _classPrivateMethodGet(this, _formatUnit, _formatUnit2).call(this, maxUnit, false, options.style);
5932	    }
5933	  }, {
5934	    key: "seconds",
5935	    get: function () {
5936	      return Math.floor(this.milliseconds / DurationFormat.getUnitDurations().s);
5937	    }
5938	  }, {
5939	    key: "minutes",
5940	    get: function () {
5941	      return Math.floor(this.milliseconds / DurationFormat.getUnitDurations().i);
5942	    }
5943	  }, {
5944	    key: "hours",
5945	    get: function () {
5946	      return Math.floor(this.milliseconds / DurationFormat.getUnitDurations().H);
5947	    }
5948	  }, {
5949	    key: "days",
5950	    get: function () {
5951	      return Math.floor(this.milliseconds / DurationFormat.getUnitDurations().d);
5952	    }
5953	    /**
5954	     * Considering month is 31 days
5955	     */
5956	  }, {
5957	    key: "months",
5958	    get: function () {
5959	      return Math.floor(this.milliseconds / DurationFormat.getUnitDurations().m);
5960	    }
5961	    /**
5962	     * Considering year is 365 days
5963	     */
5964	  }, {
5965	    key: "years",
5966	    get: function () {
5967	      return Math.floor(this.milliseconds / DurationFormat.getUnitDurations().Y);
5968	    }
5969	  }], [{
5970	    key: "createFromSeconds",
5971	    value: function createFromSeconds(seconds) {
5972	      return new DurationFormat(seconds * DurationFormat.getUnitDurations().s);
5973	    }
5974	  }, {
5975	    key: "createFromMinutes",
5976	    value: function createFromMinutes(minutes) {
5977	      return new DurationFormat(minutes * DurationFormat.getUnitDurations().i);
5978	    }
5979	  }, {
5980	    key: "getUnitDurations",
5981	    value: function getUnitDurations() {
5982	      return {
5983	        s: 1000,
5984	        i: 60000,
5985	        H: 3600000,
5986	        d: 86400000,
5987	        m: 2678400000,
5988	        Y: 31536000000
5989	      };
5990	    }
5991	  }]);
5992	  return DurationFormat;
5993	}();
5994	function _getSeparator2(style) {
5995	  if (style === 'short') {
5996	    return main_core.Loc.getMessage('FD_SEPARATOR_SHORT').replaceAll('&#32;', ' ');
5997	  }
5998	  return main_core.Loc.getMessage('FD_SEPARATOR').replaceAll('&#32;', ' ');
5999	}
6000	function _getMaxUnit2(format) {
6001	  const formatUnits = new Set(format.split(' '));
6002	  const units = Object.entries(DurationFormat.getUnitDurations()).filter(([unit]) => formatUnits.has(unit));
6003	  return units.reduce((closestDuration, unitDuration) => {
6004	    const whole = Math.floor(this.milliseconds / unitDuration[1]) >= 1;
6005	    const max = unitDuration[1] > closestDuration[1];
6006	    return whole && max ? unitDuration : closestDuration;
6007	  }, units[0])[0];
6008	}
6009	function _formatUnit2(unitStr, mod, style) {
6010	  const value = mod ? _classPrivateMethodGet(this, _getUnitPropertyModByFormat, _getUnitPropertyModByFormat2).call(this, unitStr) : _classPrivateMethodGet(this, _getUnitPropertyByFormat, _getUnitPropertyByFormat2).call(this, unitStr);
6011	  if (mod && value === 0) {
6012	    return '';
6013	  }
6014	  const now = Date.now() / 1000;
6015	  const unitDuration = value * _classPrivateMethodGet(this, _getUnitDuration, _getUnitDuration2).call(this, unitStr) / 1000;
6016	  const format = style === 'short' ? `${unitStr}short` : `${unitStr}diff`;
6017	  return DateTimeFormat.format(format, now - unitDuration, now);
6018	}
6019	function _getUnitPropertyModByFormat2(unitStr) {
6020	  const propsMod = {
6021	    s: this.seconds % 60,
6022	    i: this.minutes % 60,
6023	    H: this.hours % 24,
6024	    d: this.days % 31,
6025	    m: this.months % 12,
6026	    Y: this.years
6027	  };
6028	  return propsMod[unitStr];
6029	}
6030	function _getUnitPropertyByFormat2(unitStr) {
6031	  const props = {
6032	    s: this.seconds,
6033	    i: this.minutes,
6034	    H: this.hours,
6035	    d: this.days,
6036	    m: this.months,
6037	    Y: this.years
6038	  };
6039	  return props[unitStr];
6040	}
6041	function _getUnitDuration2(unitStr) {
6042	  return DurationFormat.getUnitDurations()[unitStr];
6043	}
6044
6045	const cache = new main_core.Cache.MemoryCache();
6046	/**
6047	 * @memberOf BX.Main.Timezone
6048	 *
6049	 * WARNING! Don't use this class or any classes from Timezone namespace on sites without Bitrix Framework.
6050	 * It is not designed to handle this case and will definitely break.
6051	 */
6052	const Offset = {
6053	  get SERVER_TO_UTC() {
6054	    return cache.remember('SERVER_TO_UTC', () => {
6055	      return main_core.Text.toInteger(main_core.Loc.getMessage('SERVER_TZ_OFFSET'));
6056	    });
6057	  },
6058	  get USER_TO_SERVER() {
6059	    return cache.remember('USER_TO_SERVER', () => {
6060	      return main_core.Text.toInteger(main_core.Loc.getMessage('USER_TZ_OFFSET'));
6061	    });
6062	  },
6063	  // Date returns timezone offset in minutes by default, change it to seconds
6064	  // Also offset is negative in UTC+ timezones and positive in UTC- timezones.
6065	  // By convention Bitrix uses the opposite approach, so change offset sign.
6066	  get BROWSER_TO_UTC() {
6067	    return cache.remember('BROWSER_TO_UTC', () => {
6068	      const offset = main_core.Text.toInteger(new Date().getTimezoneOffset() * 60);
6069	      return -offset;
6070	    });
6071	  }
6072	};
6073	Object.freeze(Offset);
6074
6075	function normalizeTimeValue(timeValue) {
6076	  if (main_core.Type.isDate(timeValue)) {
6077	    return getTimestampFromDate(timeValue);
6078	  }
6079	  return main_core.Text.toInteger(timeValue);
6080	}
6081	function createDateFromTimestamp(timestampInSeconds) {
6082	  return new Date(timestampInSeconds * 1000);
6083	}
6084	function getTimestampFromDate(date) {
6085	  return Math.floor(date.getTime() / 1000);
6086	}
6087
6088	let offset = Offset;
6089	let now = null;
6090	function getOffset() {
6091	  return offset;
6092	}
6093	function getNowTimestamp() {
6094	  var _now;
6095	  return (_now = now) !== null && _now !== void 0 ? _now : getTimestampFromDate(new Date());
6096	}
6097
6098	/**
6099	 * @memberOf BX.Main.Timezone
6100	 *
6101	 * WARNING! Don't use this class or any classes from Timezone namespace on sites without Bitrix Framework.
6102	 * It is not designed to handle this case and will definitely break.
6103	 */
6104	let BrowserTime = /*#__PURE__*/function () {
6105	  function BrowserTime() {
6106	    babelHelpers.classCallCheck(this, BrowserTime);
6107	  }
6108	  babelHelpers.createClass(BrowserTime, null, [{
6109	    key: "getDate",
6110	    /**
6111	     * Returns a Date object with time and date that represent a specific moment in Browser (device) timezone.
6112	     *
6113	     * @param utcTimestamp - normal utc timestamp in seconds. 'now' by default
6114	     * @returns {Date}
6115	     */
6116	    value: function getDate(utcTimestamp = null) {
6117	      const timestamp = main_core.Type.isNumber(utcTimestamp) ? utcTimestamp : this.getTimestamp();
6118	      return createDateFromTimestamp(timestamp);
6119	    }
6120	    /**
6121	     * Transforms a moment in Browser (device) timezone to a moment in User timezone.
6122	     *
6123	     * ATTENTION! Date.getTime() and Date.getTimezoneOffset() will return inaccurate data. Since a native Date object
6124	     * doesn't support timezone other that device timezone, we have to manually change timestamp to shift time value in
6125	     * a Date object.
6126	     *
6127	     * @param browserTime - a moment in Browser (device) timezone. Either a Date object (recommended way). Or timestamp
6128	     * in seconds in Browser timezone (see this.getTimestamp for details).
6129	     * @returns {Date}
6130	     */
6131	  }, {
6132	    key: "toUserDate",
6133	    value: function toUserDate(browserTime) {
6134	      return createDateFromTimestamp(this.toUser(browserTime));
6135	    }
6136	    /**
6137	     * Transforms a moment in Browser (device) timezone to a moment in Server timezone.
6138	     *
6139	     * ATTENTION! Date.getTime() and Date.getTimezoneOffset() will return inaccurate data. Since a native Date object
6140	     * doesn't support timezone other that device timezone, we have to manually change timestamp to shift time value in
6141	     * a Date object.
6142	     *
6143	     * @param browserTime - a moment in Browser (device) timezone. Either a Date object (recommended way). Or timestamp
6144	     * in seconds in Browser timezone (see this.getTimestamp for details).
6145	     * @returns {Date}
6146	     */
6147	  }, {
6148	    key: "toServerDate",
6149	    value: function toServerDate(browserTime) {
6150	      return createDateFromTimestamp(this.toServer(browserTime));
6151	    }
6152	    /**
6153	     * Transforms a moment in Browser (device) timezone to a timestamp in User timezone.
6154	     * It's recommended to use this.toUserDate for more clear code.
6155	     *
6156	     * @param browserTime - a moment in Browser timezone. Either a Date object (recommended way). Or timestamp in seconds
6157	     * in Browser timezone (see this.getTimestamp for details).
6158	     * @returns {number} - timestamp that when passed to 'new Date' will create an object with absolute time matching
6159	     * the time in User timezone
6160	     */
6161	  }, {
6162	    key: "toUser",
6163	    value: function toUser(browserTime) {
6164	      return this.toServer(browserTime) + getOffset().USER_TO_SERVER;
6165	    }
6166	    /**
6167	     * Transforms a moment in Browser (device) timezone to a timestamp in Server timezone.
6168	     * It's recommended to use this.toServerDate for more clear code.
6169	     *
6170	     * @param browserTime - a moment in Browser timezone. Either a Date object (recommended way). Or timestamp in seconds
6171	     * in Browser timezone (see this.getTimestamp for details).
6172	     * @returns {number} - timestamp that when passed to 'new Date' will create an object with absolute time matching
6173	     * the time in Server timezone
6174	     */
6175	  }, {
6176	    key: "toServer",
6177	    value: function toServer(browserTime) {
6178	      return normalizeTimeValue(browserTime) - getOffset().BROWSER_TO_UTC + getOffset().SERVER_TO_UTC;
6179	    }
6180	    /**
6181	     * Returns 'now' timestamp in Browser (device) timezone - when it's passed to a 'new Date', it will create an object
6182	     * with absolute time matching the time as if it was in Browser (device) timezone.
6183	     *
6184	     * @returns {number}
6185	     */
6186	  }, {
6187	    key: "getTimestamp",
6188	    value: function getTimestamp() {
6189	      // since 'Date' class in JS is hardcoded to use device timezone, 'browser timestamp' is just normal UTC timestamp :)
6190
6191	      return getNowTimestamp();
6192	    }
6193	  }]);
6194	  return BrowserTime;
6195	}();
6196
6197	/**
6198	 * @memberOf BX.Main.Timezone
6199	 *
6200	 * WARNING! Don't use this class or any classes from Timezone namespace on sites without Bitrix Framework.
6201	 * It is not designed to handle this case and will definitely break.
6202	 */
6203	let ServerTime = /*#__PURE__*/function () {
6204	  function ServerTime() {
6205	    babelHelpers.classCallCheck(this, ServerTime);
6206	  }
6207	  babelHelpers.createClass(ServerTime, null, [{
6208	    key: "getDate",
6209	    /**
6210	     * Returns a Date object with time and date that represent a specific moment in Server timezone.
6211	     *
6212	     * ATTENTION! Date.getTime() and Date.getTimezoneOffset() will return inaccurate data. Since a native Date object
6213	     * doesn't support timezone other that device timezone, we have to manually change timestamp to shift time value in
6214	     * a Date object.
6215	     *
6216	     * @param utcTimestamp - normal utc timestamp in seconds. 'now' by default
6217	     * @returns {Date}
6218	     */
6219	    value: function getDate(utcTimestamp = null) {
6220	      if (main_core.Type.isNumber(utcTimestamp)) {
6221	        const browserToServerOffset = getOffset().SERVER_TO_UTC - getOffset().BROWSER_TO_UTC;
6222	        return createDateFromTimestamp(utcTimestamp + browserToServerOffset);
6223	      }
6224	      return BrowserTime.toServerDate(BrowserTime.getDate());
6225	    }
6226	    /**
6227	     * Transforms a moment in Server timezone to a moment in User timezone.
6228	     *
6229	     * ATTENTION! Date.getTime() and Date.getTimezoneOffset() will return inaccurate data. Since a native Date object
6230	     * doesn't support timezone other that device timezone, we have to manually change timestamp to shift time value in
6231	     * a Date object.
6232	     *
6233	     * @param serverTime - a moment in Server timezone. Either a Date object (recommended way). Or timestamp in seconds 
6233in
6234	     * Server timezone (see this.getTimestamp for details).
6235	     * @returns {Date}
6236	     */
6237	  }, {
6238	    key: "toUserDate",
6239	    value: function toUserDate(serverTime) {
6240	      return createDateFromTimestamp(this.toUser(serverTime));
6241	    }
6242	    /**
6243	     * Transforms a moment in Server timezone to a moment in Browser (device) timezone.
6244	     *
6245	     * @param serverTime - a moment in Server timezone. Either a Date object (recommended way). Or timestamp in seconds in
6246	     * Server timezone (see this.getTimestamp for details).
6247	     * @returns {Date}
6248	     */
6249	  }, {
6250	    key: "toBrowserDate",
6251	    value: function toBrowserDate(serverTime) {
6252	      return createDateFromTimestamp(this.toBrowser(serverTime));
6253	    }
6254	    /**
6255	     * Transforms a moment in Server timezone to a timestamp in User timezone.
6256	     * It's recommended to use this.toServerDate for more clear code.
6257	     *
6258	     * @param serverTime - a moment in Server timezone. Either a Date object (recommended way). Or timestamp in seconds in
6259	     * Server timezone (see this.getTimestamp for details).
6260	     * @returns {number} - timestamp that when passed to 'new Date' will create an object with absolute time matching
6261	     * the time in User timezone
6262	     */
6263	  }, {
6264	    key: "toUser",
6265	    value: function toUser(serverTime) {
6266	      return normalizeTimeValue(serverTime) + getOffset().USER_TO_SERVER;
6267	    }
6268	    /**
6269	     * Transforms a moment in Server timezone to a timestamp in Browser (device) timezone.
6270	     * It's recommended to use this.toBrowserDate for more clear code.
6271	     *
6272	     * @param serverTime - a moment in Server timezone. Either a Date object (recommended way). Or timestamp in seconds in
6273	     * Server timezone (see this.getTimestamp for details).
6274	     * @returns {number} - timestamp that when passed to 'new Date' will create an object with absolute time matching
6275	     * the time in Browser (device) timezone
6276	     */
6277	  }, {
6278	    key: "toBrowser",
6279	    value: function toBrowser(serverTime) {
6280	      return normalizeTimeValue(serverTime) + getOffset().BROWSER_TO_UTC - getOffset().SERVER_TO_UTC;
6281	    }
6282	    /**
6283	     * Returns 'now' timestamp in Server timezone - when it's passed to a 'new Date', it will create an object with
6284	     * absolute time matching the time as if it was in Server timezone.
6285	     *
6286	     * @returns {number}
6287	     */
6288	  }, {
6289	    key: "getTimestamp",
6290	    value: function getTimestamp() {
6291	      return BrowserTime.toServer(BrowserTime.getTimestamp());
6292	    }
6293	  }]);
6294	  return ServerTime;
6295	}();
6296
6297	function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) { _classCheckPrivateStaticAccess(receiver, classConstructor); _classCheckPrivateStaticFieldDescriptor(descriptor, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
6298	function _classCheckPrivateStaticFieldDescriptor(descriptor, action) { if (descriptor === undefined) { throw new TypeError("attempted to " + action + " private static field before its declaration"); } }
6299	function _classCheckPrivateStaticAccess(receiver, classConstructor) { if (receiver !== classConstructor) { throw new TypeError("Private static access of wrong provenance"); } }
6300	function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
6301
6302	/**
6303	 * @memberOf BX.Main.Timezone
6304	 *
6305	 * WARNING! Don't use this class or any classes from Timezone namespace on sites without Bitrix Framework.
6306	 * It is not designed to handle this case and will definitely break.
6307	 *
6308	 * ATTENTION! In Bitrix user timezone !== browser timezone. Users can change their timezone from their profile settings
6309	 * and the timezone will be different from browser timezone.
6310	 */
6311	let UserTime = /*#__PURE__*/function () {
6312	  function UserTime() {
6313	    babelHelpers.classCallCheck(this, UserTime);
6314	  }
6315	  babelHelpers.createClass(UserTime, null, [{
6316	    key: "getDate",
6317	    /**
6318	     * Returns a Date object with time and date that represent a specific moment in User timezone.
6319	     *
6320	     * ATTENTION! Date.getTime() and Date.getTimezoneOffset() will return inaccurate data. Since a native Date object
6321	     * doesn't support timezone other that device timezone, we have to manually change timestamp to shift time value in
6322	     * a Date object.
6323	     *
6324	     * @param utcTimestamp - normal utc timestamp in seconds. 'now' by default
6325	     * @returns {Date}
6326	     */
6327	    value: function getDate(utcTimestamp = null) {
6328	      if (main_core.Type.isNumber(utcTimestamp)) {
6329	        return createDateFromTimestamp(utcTimestamp + _classStaticPrivateFieldSpecGet(this, UserTime, _userToBrowserOffset));
6330	      }
6331	      return createDateFromTimestamp(this.getTimestamp());
6332	    }
6333	  }, {
6334	    key: "toBrowserDate",
6335	    /**
6336	     * Transforms a moment in User timezone to a moment in Browser (device) timezone.
6337	     *
6338	     * @param userTime - a moment in User timezone. Either a Date object (recommended way). Or timestamp in seconds 
6338in
6339	     * User timezone (see this.getTimestamp for details).
6340	     * @returns {Date}
6341	     */
6342	    value: function toBrowserDate(userTime) {
6343	      return createDateFromTimestamp(this.toBrowser(userTime));
6344	    }
6345	    /**
6346	     * Transforms a moment in User timezone to a moment in Server timezone.
6347	     *
6348	     * ATTENTION! Date.getTime() and Date.getTimezoneOffset() will return inaccurate data. Since a native Date object
6349	     * doesn't support timezone other that device timezone, we have to manually change timestamp to shift time value in
6350	     * a Date object.
6351	     *
6352	     * @param userTime - a moment in User timezone. Either a Date object (recommended way). Or timestamp in seconds in
6353	     * User timezone (see this.getTimestamp for details).
6354	     * @returns {Date}
6355	     */
6356	  }, {
6357	    key: "toServerDate",
6358	    value: function toServerDate(userTime) {
6359	      return createDateFromTimestamp(this.toServer(userTime));
6360	    }
6361	  }, {
6362	    key: "toUTCTimestamp",
6363	    value: function toUTCTimestamp(userTime) {
6364	      return normalizeTimeValue(userTime) - _classStaticPrivateFieldSpecGet(this, UserTime, _userToBrowserOffset);
6365	    }
6366	    /**
6367	     * Transforms a moment in User timezone to a timestamp in Browser timezone.
6368	     * It's recommended to use this.toBrowserDate for more clear code.
6369	     *
6370	     * @param userTime - a moment in User timezone. Either a Date object (recommended way). Or timestamp in seconds in
6371	     * User timezone (see this.getTimestamp for details).
6372	     * @returns {number} - timestamp that when passed to 'new Date' will create an object with absolute time matching
6373	     * the time in Browser (device) timezone
6374	     */
6375	  }, {
6376	    key: "toBrowser",
6377	    value: function toBrowser(userTime) {
6378	      return normalizeTimeValue(userTime) + getOffset().BROWSER_TO_UTC - getOffset().SERVER_TO_UTC - getOffset().USER_TO_SERVER;
6379	    }
6380	    /**
6381	     * Transforms a moment in User timezone to a timestamp in Server timezone.
6382	     * It's recommended to use this.toServerDate for more clear code.
6383	     *
6384	     * @param userTime - a moment in User timezone. Either a Date object (recommended way). Or timestamp in seconds in
6385	     * User timezone (see this.getTimestamp for details).
6386	     * @returns {number} - timestamp that when passed to 'new Date' will create an object with absolute time matching
6387	     * the time in Server timezone
6388	     */
6389	  }, {
6390	    key: "toServer",
6391	    value: function toServer(userTime) {
6392	      return normalizeTimeValue(userTime) - getOffset().USER_TO_SERVER;
6393	    }
6394	    /**
6395	     * Returns 'now' timestamp in User timezone - when it's passed to a 'new Date', it will create an object with absolute
6396	     * time matching the time as if it was in User timezone.
6397	     *
6398	     * @returns {number}
6399	     */
6400	  }, {
6401	    key: "getTimestamp",
6402	    value: function getTimestamp() {
6403	      return BrowserTime.toUser(BrowserTime.getTimestamp());
6404	    }
6405	  }]);
6406	  return UserTime;
6407	}();
6408	function _get_userToBrowserOffset() {
6409	  const userToUTCOffset = getOffset().SERVER_TO_UTC + getOffset().USER_TO_SERVER;
6410	  return userToUTCOffset - getOffset().BROWSER_TO_UTC;
6411	}
6412	var _userToBrowserOffset = {
6413	  get: _get_userToBrowserOffset,
6414	  set: void 0
6415	};
6416
6417	const Timezone = Object.freeze({
6418	  BrowserTime,
6419	  Offset,
6420	  ServerTime,
6421	  UserTime
6422	});
6423
6424	exports.Timezone = Timezone;
6425	exports.Date = DateTimeFormat;
6426	exports.DateTimeFormat = DateTimeFormat;
6427	exports.DurationFormat = DurationFormat;
6428
6429}((this.BX.Main = this.BX.Main || {}),BX));
6430//# sourceMappingURL=main.date.js.map
6431
6432/* End */
6433;
6434; /* Start:"a:4:{s:4:"full";s:49:"/bitrix/js/main/core/core_date.js?169691731036080";s:6:"source";s:33:"/bitrix/js/main/core/core_date.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
6435;(function(){
6436
6437if (BX.date)
6438	return;
6439
6440BX.date = BX.Main.Date;
6441
6442/************************************** calendar class **********************************/
6443
6444var obCalendarSingleton = null;
6445
6446/*
6447params: {
6448	node: bind element || document.body
6449
6450	value - start value in site format (using 'field' param if 'value' does not exist)
6451	callback - date check handler. can return false to prevent calendar closing.
6452	callback_after - another handler, called after date picking
6453
6454	field - field to read/write data
6455
6456	bTime = true - whether to enable time control
6457	bHideTime = false - whether to hide time control by default
6458
6459	currentTime - current UTC time()
6460
6461}
6462*/
6463
6464
6465BX.calendar = function(params)
6466{
6467	return BX.calendar.get().Show(params);
6468};
6469
6470BX.calendar.get = function()
6471{
6472	if (!obCalendarSingleton)
6473		obCalendarSingleton = new BX.JCCalendar();
6474
6475	return obCalendarSingleton;
6476};
6477
6478// simple func for compatibility with the oldies
6479BX.calendar.InsertDaysBack = function(input, days)
6480{
6481	if (days != '')
6482	{
6483		var d = new Date();
6484		if(days > 0)
6485		{
6486			d.setTime(d.valueOf() - days*86400000);
6487		}
6488
6489		input.value = BX.date.format(BX.date.convertBitrixFormat(BX.message('FORMAT_DATE')), d, null);
6490	}
6491	else
6492	{
6493		input.value = '';
6494	}
6495};
6496
6497BX.calendar.ValueToString = function(value, bTime, bUTC)
6498{
6499	return BX.date.format(
6500		BX.date.convertBitrixFormat(BX.message(bTime ? 'FORMAT_DATETIME' : 'FORMAT_DATE')),
6501		value,
6502		null,
6503		!!bUTC
6504	);
6505};
6506
6507BX.calendar.ValueToStringFormat = function(value, bitrixFormat, bUTC)
6508{
6509	return BX.date.format(
6510		BX.date.convertBitrixFormat(bitrixFormat),
6511		value,
6512		null,
6513		!!bUTC
6514	);
6515};
6516
6517
6518BX.CalendarPeriod =
6519{
6520	Init: function(inputFrom, inputTo, selPeriod)
6521	{
6522		if((inputFrom.value != "" || inputTo.value != "") && selPeriod.value == "")
6523			selPeriod.value = "interval";
6524
6525		selPeriod.onchange();
6526	},
6527
6528	ChangeDirectOpts: function(peroidValue, selPParent) // "week" || "others"
6529	{
6530		var selDirect = BX.findChild(selPParent, {'className':'adm-select adm-calendar-direction'}, true);
6531
6532		if(peroidValue == "week")
6533		{
6534			selDirect.options[0].text = BX.message('JSADM_CALEND_PREV_WEEK');
6535			selDirect.options[1].text = BX.message('JSADM_CALEND_CURR_WEEK');
6536			selDirect.options[2].text = BX.message('JSADM_CALEND_NEXT_WEEK');
6537		}
6538		else
6539		{
6540			selDirect.options[0].text = BX.message('JSADM_CALEND_PREV');
6541			selDirect.options[1].text = BX.message('JSADM_CALEND_CURR');
6542			selDirect.options[2].text = BX.message('JSADM_CALEND_NEXT');
6543		}
6544	},
6545
6546	SaveAndClearInput: function(oInput)
6547	{
6548		if(!window.SavedPeriodValues)
6549			window.SavedPeriodValues = {};
6550
6551		window.SavedPeriodValues[oInput.id] = oInput.value;
6552		oInput.value="";
6553	},
6554
6555	RestoreInput: function(oInput)
6556	{
6557		if(!window.SavedPeriodValues || !window.SavedPeriodValues[oInput.id])
6558			return;
6559
6560		oInput.value = window.SavedPeriodValues[oInput.id];
6561		delete(window.SavedPeriodValues[oInput.id]);
6562	},
6563
6564	OnChangeP: function(sel)
6565	{
6566		var selPParent = sel.parentNode.parentNode;
6567		var bShowFrom, bShowTo, bShowDirect, bShowSeparate;
6568		bShowFrom = bShowTo = bShowDirect = bShowSeparate = false;
6569
6570		var inputFromWrap = BX.findChild(selPParent, {'className':'adm-input-wrap adm-calendar-inp adm-calendar-first'});
6571		var inputToWrap = BX.findChild(selPParent, {'className':'adm-input-wrap adm-calendar-second'});
6572		var selDirectWrap = BX.findChild(selPParent, {'className':'adm-select-wrap adm-calendar-direction'});
6573		var separator = BX.findChild(selPParent, {'className':'adm-calendar-separate'});
6574		var inputFrom = BX.findChild(selPParent, {'className':'adm-input adm-calendar-from'},true);
6575		var inputTo = BX.findChild(selPParent, {'className':'adm-input adm-calendar-to'},true);
6576
6577		// define who must be shown
6578		switch (sel.value)
6579		{
6580			case "day":
6581			case "week":
6582			case "month":
6583			case "quarter":
6584			case "year":
6585				bShowDirect=true;
6586				BX.CalendarPeriod.OnChangeD(selDirectWrap.children[0]);
6587				break;
6588
6589			case "before":
6590				bShowTo = true;
6591				break;
6592
6593			case "after":
6594				bShowFrom = true;
6595				break;
6596
6597			case "exact":
6598				bShowFrom= true;
6599				break;
6600
6601			case "interval":
6602				bShowFrom = bShowTo = bShowSeparate = true;
6603				BX.CalendarPeriod.RestoreInput(inputFrom);
6604				BX.CalendarPeriod.RestoreInput(inputTo);
6605
6606				break;
6607
6608			case "":
6609				BX.CalendarPeriod.SaveAndClearInput(inputFrom);
6610				BX.CalendarPeriod.SaveAndClearInput(inputTo);
6611				break;
6612
6613			default:
6614				break;
6615
6616		}
6617
6618		BX.CalendarPeriod.ChangeDirectOpts(sel.value, selPParent);
6619
6620		inputFromWrap.style.display = (bShowFrom? 'inline-block':'none');
6621		inputToWrap.style.display = (bShowTo? 'inline-block':'none');
6622		selDirectWrap.style.display = (bShowDirect? 'inline-block':'none');
6623		separator.style.display = (bShowSeparate? 'inline-block':'none');
6624	},
6625
6626
6627	OnChangeD: function(sel)
6628	{
6629		var selPParent = sel.parentNode.parentNode;
6630		var inputFrom = BX.findChild(selPParent, {'className':'adm-input adm-calendar-from'},true);
6631		var inputTo = BX.findChild(selPParent, {'className':'adm-input adm-calendar-to'},true);
6632		var selPeriod = BX.findChild(selPParent, {'className':'adm-select adm-calendar-period'},true);
6633
6634		var offset=0;
6635
6636		switch (sel.value)
6637		{
6638			case "previous":
6639				offset = -1;
6640				break;
6641
6642			case "next":
6643				offset = 1;
6644				break;
6645
6646			case "current":
6647			default:
6648				break;
6649
6650		}
6651
6652		var from = false;
6653		var to = false;
6654
6655		var today = new Date();
6656		var year = today.getFullYear();
6657		var month = today.getMonth();
6658		var day = today.getDate();
6659		var dayW = today.getDay();
6660
6661		if (dayW == 0)
6662				dayW = 7;
6663
6664		switch (selPeriod.value)
6665		{
6666			case "day":
6667				from = new Date(year, month, day+offset, 0, 0, 0);
6668				to = new Date(year, month, day+offset, 23, 59, 59);
6669				break;
6670
6671			case "week":
6672				from = new Date(year, month, day-dayW+1+offset*7, 0, 0, 0);
6673				to = new Date(year, month, day+(7-dayW)+offset*7, 23, 59, 59);
6674				break;
6675
6676			case "month":
6677				from = new Date(year, month+offset, 1, 0, 0, 0);
6678				to = new Date(year, month+1+offset, 0, 23, 59, 59);
6679				break;
6680
6681			case "quarter":
6682				var quarterNum = Math.floor((month/3))+offset;
6683				from = new Date(year, 3*(quarterNum), 1, 0, 0, 0);
6684				to = new Date(year, 3*(quarterNum+1), 0, 23, 59, 59);
6685				break;
6686
6687			case "year":
6688				from = new Date(year+offset, 0, 1, 0, 0, 0);
6689				to = new Date(year+1+offset, 0, 0, 23, 59, 59);
6690				break;
6691
6692			default:
6693				break;
6694		}
6695
6696		var format = window[inputFrom.name+"_bTime"] ? BX.message('FORMAT_DATETIME') : BX.message('FORMAT_DATE');
6697
6698		if(from)
6699		{
6700			inputFrom.value = BX.formatDate(from, format);
6701			BX.addClass(inputFrom,"adm-calendar-inp-setted");
6702		}
6703
6704		if(to)
6705		{
6706			inputTo.value = BX.formatDate(to, format);
6707			BX.addClass(inputTo,"adm-calendar-inp-setted");
6708		}
6709	}
6710};
6711
6712
6713BX.JCCalendar = function()
6714{
6715	this.params = {};
6716
6717	this.bAmPm = BX.isAmPmMode();
6718
6719	this.popup = null;
6720	this.popup_month = null;
6721	this.popup_year = null;
6722	this.month_popup_classname = '';
6723	this.year_popup_classname = '';
6724	this.value = null;
6725	this._layers = {};
6726	this._current_layer = null;
6727
6728	this.DIV = null;
6729	this.PARTS = {};
6730
6731	this.weekStart = 0;
6732	this.numRows = 6;
6733
6734	this._create = function(params)
6735	{
6736		this.popup = new BX.PopupWindow('calendar_popup_' + Math.random(), params.node, {
6737			closeByEsc: true,
6738			autoHide: false,
6739			content: this._get_content(),
6740			bindOptions: {forceBindPosition: true}
6741		});
6742
6743		BX.bind(this.popup.popupContainer, 'click', function(event) {
6744			event.stopPropagation();
6745		});
6746	};
6747
6748	this._auto_hide_disable = function()
6749	{
6750		BX.unbind(document, 'click', BX.proxy(this._auto_hide, this));
6751	};
6752
6753	this._auto_hide_enable = function()
6754	{
6755		BX.bind(document, 'click', BX.proxy(this._auto_hide, this));
6756	};
6757
6758	this._auto_hide = function(e)
6759	{
6760		this._auto_hide_disable();
6761		this.popup.close();
6762	};
6763
6764	this._get_content = function()
6765	{
6766		var _layer_onclick = BX.delegate(function(e) {
6767			e = e||window.event;
6768			this.SetDate(
6769				new Date(parseInt(BX.proxy_context.getAttribute('data-date'))),
6770				(e.type === 'dblclick' || (this.params.bCompatibility && !this.params.bTimeVisibility))
6771			)
6772		}, this);
6773
6774		this.DIV = BX.create('DIV', {
6775			props: {className: 'bx-calendar'},
6776			children: [
6777				BX.create('DIV', {
6778					props: {
6779						className: 'bx-calendar-header'
6780					},
6781					children: [
6782						BX.create('A', {
6783							attrs: {href: 'javascript:void(0)'},
6784							props: {className: 'bx-calendar-left-arrow'},
6785							events: {click: BX.proxy(this._prev, this)}
6786						}),
6787
6788						BX.create('SPAN', {
6789							props: {className: 'bx-calendar-header-content'},
6790							children: [
6791								(this.PARTS.MONTH = BX.create('A', {
6792									attrs: {href: 'javascript:void(0)'},
6793									props: {className: 'bx-calendar-top-month'},
6794									events: {click: BX.proxy(this._menu_month, this)}
6795								})),
6796
6797								(this.PARTS.YEAR = BX.create('A', {
6798									attrs: {href: 'javascript:void(0)'},
6799									props: {className: 'bx-calendar-top-year'},
6800									events: {click: BX.proxy(this._menu_year, this)}
6801								}))
6802							]
6803						}),
6804
6805						BX.create('A', {
6806							attrs: {href: 'javascript:void(0)'},
6807							props: {className: 'bx-calendar-right-arrow'},
6808							events: {click: BX.proxy(this._next, this)}
6809						})
6810					]
6811				}),
6812
6813				(this.PARTS.WEEK = BX.create('DIV', {
6814					props: {
6815						className: 'bx-calendar-name-day-wrap'
6816					}
6817				})),
6818
6819				(this.PARTS.LAYERS = BX.create('DIV', {
6820					props: {
6821						className: 'bx-calendar-cell-block'
6822					},
6823					events: {
6824						click: BX.delegateEvent({className: 'bx-calendar-cell'}, _layer_onclick),
6825						dblclick: BX.delegateEvent({className: 'bx-calendar-cell'}, _layer_onclick)
6826					}
6827				})),
6828
6829				(this.PARTS.TIME = BX.create('DIV', {
6830					props: {
6831						className: 'bx-calendar-set-time-wrap'
6832					},
6833					events: {
6834						click: BX.delegateEvent(
6835							{attr: 'data-action'},
6836							BX.delegate(this._time_actions, this)
6837						)
6838					},
6839					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>'
6840				})),
6841
6842				(this.PARTS.BUTTONS = BX.create('DIV', {
6843					props: {className: 'bx-calendar-button-block'},
6844					events: {
6845						click: BX.delegateEvent(
6846							{attr: 'data-action'},
6847							BX.delegate(this._button_actions, this)
6848						)
6849					},
6850					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>'
6851				}))
6852			]
6853		});
6854
6855		this.PARTS.TIME_INPUT_H = BX.findChild(this.PARTS.TIME, {tag: 'INPUT'}, true);
6856		this.PARTS.TIME_INPUT_M = this.PARTS.TIME_INPUT_H.nextSibling.nextSibling;
6857
6858		if (this.bAmPm)
6859			this.PARTS.TIME_AMPM = this.PARTS.TIME_INPUT_M.nextSibling.firstChild;
6860
6861		var spinner = (new BX.JCSpinner({
6862			input: this.PARTS.TIME_INPUT_H,
6863			callback_change: BX.proxy(this._check_time, this),
6864			bSaveValue: false
6865		})).Show();
6866		spinner.className = 'bx-calendar-form-arrow-l';
6867		this.PARTS.TIME_INPUT_H.parentNode.insertBefore(spinner, this.PARTS.TIME_INPUT_H);
6868
6869		spinner = (new BX.JCSpinner({
6870			input: this.PARTS.TIME_INPUT_M,
6871			callback_change: BX.proxy(this._check_time, this),
6872			bSaveValue: true
6873		})).Show();
6874		spinner.className = 'bx-calendar-form-arrow-r';
6875		if (!this.PARTS.TIME_INPUT_M.nextSibling)
6876			this.PARTS.TIME_INPUT_M.parentNode.appendChild(spinner);
6877		else
6878			this.PARTS.TIME_INPUT_M.parentNode.insertBefore(spinner, this.PARTS.TIME_INPUT_M.nextSibling);
6879
6880		for (var i = 0; i < 7; i++)
6881		{
6882			this.PARTS.WEEK.appendChild(BX.create('SPAN', {
6883				props: {
6884					className: 'bx-calendar-name-day'
6885				},
6886				text: BX.message('DOW_' + ((i + this.weekStart) % 7))
6887			}));
6888		}
6889
6890		return this.DIV;
6891	};
6892
6893	this._time_actions = function()
6894	{
6895		switch (BX.proxy_context.getAttribute('data-action'))
6896		{
6897			case 'time_show':
6898				BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
6899				if (this.params.bCompatibility)
6900				{
6901					BX.removeClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled');
6902				}
6903				this.popup.adjustPosition();
6904			break;
6905			case 'time_hide':
6906				BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
6907				if (this.params.bCompatibility)
6908				{
6909					this._saveChoice('hide');
6910					BX.addClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled');
6911				}
6912				this.popup.adjustPosition();
6913			break;
6914			case 'time_ampm':
6915				this.PARTS.TIME_AMPM.innerHTML = this.PARTS.TIME_AMPM.innerHTML == 'AM' ? 'PM' : 'AM';
6916			break;
6917			case 'time_ampm_up':
6918				this._check_time({bSaveValue: false}, null, 12);
6919				return;
6920			break;
6921			case 'time_ampm_down':
6922				this._check_time({bSaveValue: false}, null, -12);
6923				return;
6924			break;
6925		}
6926
6927		this._check_time();
6928	};
6929
6930	this._button_actions = function()
6931	{
6932		switch (BX.proxy_context.getAttribute('data-action'))
6933		{
6934			case 'submit':
6935				if (this.params.bCompatibility)
6936				{
6937					this._saveChoice('show');
6938				}
6939				this.SaveValue();
6940			break;
6941			case 'cancel':
6942				this.Close();
6943			break;
6944		}
6945	};
6946
6947	this._saveChoice = function(state)
6948	{
6949		if (this.params.bCategoryTimeVisibilityOption)
6950		{
6951			BX.userOptions.save(
6952				this.params.bCategoryTimeVisibilityOption,
6953				this.params.bNameTimeVisibilityOption,
6954				'visibility',
6955				(state === 'show' ? 'Y' : 'N')
6956			);
6957		}
6958
6959		this._bTimeVisibility = (state === 'show');
6960		this.params.bTimeVisibility = this._bTimeVisibility;
6961	};
6962
6963	this._check_time = function(params, value, direction)
6964	{
6965		var h = parseInt(this.PARTS.TIME_INPUT_H.value.substring(0,5),10)||0,
6966			m = parseInt(this.PARTS.TIME_INPUT_M.value.substring(0,5),10)||0,
6967			bChanged = false;
6968
6969		if (!!params && !params.bSaveValue)
6970		{
6971			this.value.setUTCHours(this.value.getUTCHours() + direction);
6972		}
6973		else if (!isNaN(h))
6974		{
6975			if (this.bAmPm)
6976			{
6977				if (h != 12 && this.PARTS.TIME_AMPM.innerHTML == 'PM')
6978				{
6979					h += 12;
6980				}
6981			}
6982
6983			bChanged = true;
6984			this.value.setUTCHours(h % 24);
6985		}
6986
6987		if (!isNaN(m))
6988		{
6989			bChanged = true;
6990			this.value.setUTCMinutes(m % 60);
6991		}
6992
6993		if (bChanged)
6994		{
6995			this.SetValue(this.value);
6996		}
6997	};
6998
6999	this._set_layer = function()
7000	{
7001		var layerId = parseInt(this.value.getUTCFullYear() + '' + BX.util.str_pad_left(this.value.getUTCMonth()+'', 2, "0"));
7002
7003		if (!this._layers[layerId])
7004		{
7005			this._layers[layerId] = this._create_layer();
7006			this._layers[layerId].BXLAYERID = layerId;
7007		}
7008
7009		if (this._current_layer)
7010		{
7011			var v = new Date(this.value.valueOf());
7012			v.setUTCHours(0); v.setUTCMinutes(0);
7013
7014			var cur_value = BX.findChild(this._layers[layerId], {
7015					tag: 'A',
7016					className: 'bx-calendar-active'
7017				}, true),
7018				new_value = BX.findChild(this._layers[layerId], {
7019					tag: 'A',
7020					attr: {
7021						'data-date' : v.valueOf() + ''
7022					}
7023				}, true);
7024
7025			if (cur_value)
7026			{
7027				BX.removeClass(cur_value, 'bx-calendar-active');
7028			}
7029
7030			if (new_value)
7031			{
7032				BX.addClass(new_value, 'bx-calendar-active');
7033			}
7034
7035			this._replace_layer(this._current_layer, this._layers[layerId]);
7036		}
7037		else
7038		{
7039			this.PARTS.LAYERS.appendChild(this._layers[layerId]);
7040		}
7041
7042		this._current_layer = this._layers[layerId];
7043	};
7044
7045	this._replace_layer = function(old_layer, new_layer)
7046	{
7047		if (old_layer != new_layer)
7048		{
7049			if (!BX.browser.IsIE() || BX.browser.IsDoctype())
7050			{
7051				var dir = old_layer.BXLAYERID > new_layer.BXLAYERID ? 1 : -1;
7052
7053				var old_top = 0;
7054				var new_top = -dir * old_layer.offsetHeight;
7055
7056				old_layer.style.position = 'relative';
7057				old_layer.style.top = "0px";
7058				old_layer.style.zIndex = 5;
7059
7060				new_layer.style.position = 'absolute';
7061				new_layer.style.top = new_top + 'px';
7062				new_layer.style.zIndex = 6;
7063
7064				this.PARTS.LAYERS.appendChild(new_layer);
7065
7066				var delta = 15;
7067
7068				var f;
7069				(f = function() {
7070					new_top += dir * delta;
7071					old_top += dir * delta;
7072
7073					if (dir * new_top < 0)
7074					{
7075						old_layer.style.top = old_top + 'px';
7076						new_layer.style.top = new_top + 'px';
7077						setTimeout(f, 10);
7078					}
7079					else
7080					{
7081						old_layer.parentNode.removeChild(old_layer);
7082
7083						new_layer.style.top = "0px";
7084						new_layer.style.position = 'static';
7085						new_layer.style.zIndex = 0;
7086					}
7087				})();
7088			}
7089			else
7090			{
7091				this.PARTS.LAYERS.replaceChild(new_layer, old_layer);
7092			}
7093		}
7094	};
7095
7096	this._create_layer = function()
7097	{
7098		var l = BX.create('DIV', {
7099			props: {
7100				className: 'bx-calendar-layer'
7101			}
7102		});
7103
7104		var month_start = new Date(this.value);
7105		month_start.setUTCHours(0);
7106		month_start.setUTCMinutes(0);
7107
7108		month_start.setUTCDate(1);
7109
7110		if (month_start.getUTCDay() != this.weekStart)
7111		{
7112			var d = month_start.getUTCDay() - this.weekStart;
7113			d += d < 0 ? 7 : 0;
7114			month_start.setUTCDate(month_start.getUTCDate()-d);
7115		}
7116
7117		var cur_month = this.value.getUTCMonth(),
7118			cur_day = this.value.getUTCDate(),
7119			s = '';
7120		for (var i = 0; i < this.numRows; i++)
7121		{
7122			s += '<div class="bx-calendar-range'
7123				+(i == this.numRows-1 ? ' bx-calendar-range-noline' : '')
7124				+'">';
7125
7126			for (var j = 0; j < 7; j++)
7127			{
7128				d = month_start.getUTCDate();
7129				var wd = month_start.getUTCDay();
7130				var className = 'bx-calendar-cell';
7131
7132				if (cur_month != month_start.getUTCMonth())
7133					className += ' bx-calendar-date-hidden';
7134				else if (cur_day == d)
7135					className += ' bx-calendar-active';
7136
7137
7138				if (wd == 0 || wd == 6)
7139					className += ' bx-calendar-weekend';
7140
7141				s += '<a href="javascript:void(0)" class="'+className+'" data-date="' + month_start.valueOf() + '">' + d + '</a>';
7142
7143				month_start.setUTCDate(month_start.getUTCDate()+1);
7144			}
7145			s += '</div>';
7146		}
7147
7148		l.innerHTML = s;
7149
7150		return l;
7151	};
7152
7153	this._prev = function()
7154	{
7155		this.SetMonth(this.value.getUTCMonth()-1);
7156	};
7157
7158	this._next = function()
7159	{
7160		this.SetMonth(this.value.getUTCMonth()+1);
7161	};
7162
7163	this._menu_month_content = function()
7164	{
7165		var months = '', cur_month = this.value.getMonth(), i;
7166		for (i = 0; i < 12; i++)
7167		{
7168			months += '<span class="bx-calendar-month'+(i == cur_month ? ' bx-calendar-month-active' : '')+'" data-bx-month="' + i + '">' + BX.message('MONTH_' + (i + 1)) + '</span>';
7169		}
7170
7171		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>';
7172	};
7173
7174	this._menu_month = function()
7175	{
7176		if (!this.popup_month)
7177		{
7178			this.popup_month = new BX.PopupWindow(
7179				'calendar_popup_month_' + Math.random(), this.PARTS.MONTH,
7180				{
7181					content: this._menu_month_content(),
7182					closeByEsc: true,
7183					autoHide: true,
7184					offsetTop: -29,
7185					offsetLeft: -1,
7186					className: this.month_popup_classname,
7187					events: {
7188						onPopupShow: BX.delegate(function() {
7189							if (this.popup_year)
7190							{
7191								this.popup_year.close();
7192							}
7193						}, this)
7194					}
7195				}
7196			);
7197
7198			BX.bind(this.popup_month.popupContainer, 'click', BX.proxy(this.month_popup_click, this));
7199			this.popup_month.BXMONTH = this.value.getUTCMonth();
7200		}
7201		else if (this.popup_month.BXMONTH != this.value.getUTCMonth())
7202		{
7203			this.popup_month.setContent(this._menu_month_content());
7204			this.popup_month.BXMONTH = this.value.getUTCMonth();
7205		}
7206
7207		this.popup_month.show();
7208	};
7209
7210	this.month_popup_click = function(e)
7211	{
7212		var target = e.target || e.srcElement;
7213		if (target && target.getAttribute && target.getAttribute('data-bx-month'))
7214		{
7215			this.SetMonth(parseInt(target.getAttribute('data-bx-month')));
7216			this.popup_month.close();
7217		}
7218	};
7219
7220	this._menu_year_content = function()
7221	{
7222		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">';
7223
7224		for (var i=-3; i <= 3; i++)
7225		{
7226			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>';
7227		}
7228
7229		s += '</div><input data-bx-year-input="Y" type="text" class="bx-calendar-year-input" maxlength="4" /></div>';
7230
7231		return s;
7232	};
7233
7234	this._menu_year = function()
7235	{
7236		if (!this.popup_year)
7237		{
7238			this.popup_year = new BX.PopupWindow(
7239				'calendar_popup_year_' + Math.random(), this.PARTS.YEAR,
7240				{
7241					content: this._menu_year_content(),
7242					closeByEsc: true,
7243					autoHide: true,
7244					offsetTop: -29,
7245					offsetLeft: -1,
7246					className: this.year_popup_classname,
7247					events: {
7248						onPopupShow: BX.delegate(function() {
7249							if (this.popup_month)
7250							{
7251								this.popup_month.close();
7252							}
7253						}, this)
7254					}
7255				}
7256			);
7257
7258			BX.bind(this.popup_year.popupContainer, 'click', BX.proxy(this.year_popup_click, this));
7259			BX.bind(this.popup_year.popupContainer, 'keyup', BX.proxy(this.year_popup_keyup, this));
7260			this.popup_year.BXYEAR = this.value.getUTCFullYear();
7261		}
7262		else if (this.popup_year.BXYEAR != this.value.getUTCFullYear())
7263		{
7264			this.popup_year.setContent(this._menu_year_content());
7265			this.popup_year.BXYEAR = this.value.getUTCFullYear();
7266		}
7267
7268		this.popup_year.show();
7269	};
7270
7271	this.year_popup_click = function(e)
7272	{
7273		var target = e.target || e.srcElement;
7274		if (target && target.getAttribute && target.getAttribute('data-bx-year'))
7275		{
7276			this.SetYear(parseInt(target.getAttribute('data-bx-year')));
7277			this.popup_year.close();
7278		}
7279	};
7280	this.year_popup_keyup = function(e)
7281	{
7282		var target = e.target || e.srcElement;
7283		if (target && target.getAttribute && target.getAttribute('data-bx-year-input') == 'Y')
7284		{
7285			var value = parseInt(target.value);
7286			if(value >= 1900 && value <= 2100)
7287			{
7288				this.SetYear(value);
7289				this.popup_year.close();
7290			}
7291		}
7292	};
7293
7294	this._check_date = function(v)
7295	{
7296		var res = v;
7297
7298		if (BX.type.isString(v))
7299		{
7300			res = BX.parseDate(v, true);
7301		}
7302
7303		if (!BX.type.isDate(res) || isNaN(res.valueOf()))
7304		{
7305			res = BX.date.convertToUTC(new Date());
7306			if (this.params.bHideTime)
7307			{
7308				res.setUTCHours(0);
7309				res.setUTCMinutes(0);
7310			}
7311		}
7312
7313		res.setUTCMilliseconds(0);
7314		res.setUTCSeconds(0);
7315
7316		res.BXCHECKED = true;
7317
7318		return res;
7319	};
7320};
7321
7322BX.JCCalendar.prototype.Show = function(params)
7323{
7324	if (!BX.isReady)
7325	{
7326		BX.ready(BX.delegate(function() {this.Show(params)}, this));
7327		return;
7328	}
7329
7330	params.node = params.node||document.body;
7331
7332	if (BX.type.isNotEmptyString(params.node))
7333	{
7334		var n = BX(params.node);
7335		if (!n)
7336		{
7337			n = document.getElementsByName(params.node);
7338			if (n && n.length > 0)
7339			{
7340				n = n[0]
7341			}
7342		}
7343		params.node = n;
7344	}
7345
7346	if (!params.node)
7347		return;
7348
7349	if (!!params.field)
7350	{
7351		if (BX.type.isString(params.field))
7352		{
7353			n = BX(params.field);
7354			if (!!n)
7355			{
7356				params.field = n;
7357			}
7358			else
7359			{
7360				if (params.form)
7361				{
7362					if (BX.type.isString(params.form))
7363					{
7364						params.form = document.forms[params.form];
7365					}
7366				}
7367
7368				if (BX.type.isDomNode(params.form) && !!params.form[params.field])
7369				{
7370					params.field = params.form[params.field];
7371				}
7372				else
7373				{
7374					n = document.getElementsByName(params.field);
7375					if (n && n.length > 0)
7376					{
7377						n = n[0];
7378						params.field = n;
7379					}
7380				}
7381			}
7382
7383			if (BX.type.isString(params.field))
7384			{
7385				params.field = BX(params.field);
7386			}
7387		}
7388	}
7389
7390	var bShow = !this.popup || !this.popup.isShown() || this.params.node != params.node;
7391
7392	this.params = params;
7393
7394	this.params.bCompatibility = (typeof this.params.bCompatibility == 'undefined' ? false : this.params.bCompatibility);
7395	this.params.bTimeVisibility = (typeof this.params.bTimeVisibility == 'undefined' ? !this.params.bCompatibility : this.params.bTimeVisibility);
7396	if (this.params.bCompatibility)
7397	{
7398		this.params.bCategoryTimeVisibilityOption = (
7399			this.params.bCategoryTimeVisibilityOption ? this.params.bCategoryTimeVisibilityOption : ''
7400		);
7401		this.params.bNameTimeVisibilityOption = (
7402			this.params.bNameTimeVisibilityOption ? this.params.bNameTimeVisibilityOption : 'time_visibility'
7403		);
7404
7405		if (typeof this._bTimeVisibility !== 'undefined')
7406		{
7407			this.params.bTimeVisibility = this._bTimeVisibility;
7408		}
7409	}
7410
7411	this.params.bTime = typeof this.params.bTime == 'undefined' ? true : !!this.params.bTime;
7412	this.params.bHideTime = typeof this.params.bHideTime == 'undefined' ? true : !!this.params.bHideTime;
7413	this.params.bUseSecond = typeof this.params.bUseSecond == 'undefined' ? true : !!this.params.bUseSecond;
7414
7415	this.weekStart = parseInt(this.params.weekStart || this.params.weekStart || BX.message('WEEK_START'));
7416	if (isNaN(this.weekStart))
7417		this.weekStart = 1;
7418
7419	if (!this.popup)
7420	{
7421		this._create(this.params);
7422	}
7423	else
7424	{
7425		this.popup.setBindElement(this.params.node);
7426	}
7427
7428	var bHideTime = !!this.params.bHideTime;
7429	if (this.params.value)
7430	{
7431		this.SetValue(this.params.value);
7432		bHideTime = this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0;
7433	}
7434	else if (this.params.field)
7435	{
7436		this.SetValue(this.params.field.value);
7437		bHideTime = this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0;
7438	}
7439	else if (!!this.params.currentTime)
7440	{
7441		this.SetValue(this.params.currentTime);
7442	}
7443	else
7444	{
7445		this.SetValue();
7446	}
7447
7448	if (!!this.params.bTime)
7449	{
7450		this.activateTimeStyle(bHideTime);
7451	}
7452	else
7453	{
7454		this.activateDateStyle(bHideTime);
7455	}
7456
7457	if (bShow)
7458	{
7459		this._auto_hide_disable();
7460		this.popup.show();
7461		setTimeout(BX.proxy(this._auto_hide_enable, this), 0);
7462	}
7463
7464	this.params.bSetFocus = typeof this.params.bSetFocus == 'undefined' ? true : !!this.params.bSetFocus;
7465	if(this.params.bSetFocus)
7466	{
7467		params.node.blur();
7468	}
7469	else
7470	{
7471		BX.bind(params.node, 'keyup', BX.defer(function(){
7472			this.SetValue(params.node.value);
7473			if(!!this.params.bTime)
7474			{
7475				if(this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0)
7476					BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7477				else
7478					BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7479			}
7480		}, this));
7481	}
7482
7483	return this;
7484};
7485
7486BX.JCCalendar.prototype.activateDateStyle = function(bHideTime)
7487{
7488	BX.addClass(this.DIV, 'bx-calendar-time-disabled');
7489
7490	if (!!bHideTime)
7491		BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7492	else
7493		BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7494};
7495
7496BX.JCCalendar.prototype.activateTimeStyle = function(bHideTime)
7497{
7498	if (this.params.bCompatibility && !this.params.bTimeVisibility)
7499	{
7500		BX.addClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled');
7501		BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-wrap-simple');
7502		BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7503	}
7504	else
7505	{
7506		BX.removeClass(this.DIV, 'bx-calendar-time-disabled');
7507
7508		if (!!bHideTime)
7509			BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7510		else
7511			BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7512	}
7513};
7514
7515BX.JCCalendar.prototype.SetDay = function(d)
7516{
7517	this.value.setUTCDate(d);
7518	return this.SetValue(this.value);
7519};
7520
7521BX.JCCalendar.prototype.SetMonth = function(m)
7522{
7523	if (this.popup_month)
7524		this.popup_month.close();
7525
7526	this.value.setUTCMonth(m);
7527
7528	if(m < 0)
7529		m += 12;
7530	else if (m >= 12)
7531		m -= 12;
7532
7533	while(this.value.getUTCMonth() > m)
7534	{
7535		this.value.setUTCDate(this.value.getUTCDate()-1);
7536	}
7537
7538	return this.SetValue(this.value);
7539};
7540
7541BX.JCCalendar.prototype.SetYear = function(y)
7542{
7543	if (this.popup_year)
7544		this.popup_year.close();
7545	this.value.setUTCFullYear(y);
7546	return this.SetValue(this.value);
7547};
7548
7549BX.JCCalendar.prototype.SetDate = function(v, bSet)
7550{
7551	v = this._check_date(v);
7552	v.setUTCHours(this.value.getUTCHours());
7553	v.setUTCMinutes(this.value.getUTCMinutes());
7554	v.setUTCSeconds(this.value.getUTCSeconds());
7555
7556	if (this.params.bTime && !bSet)
7557	{
7558		return this.SetValue(v);
7559	}
7560	else
7561	{
7562		this.SetValue(v);
7563		this.SaveValue();
7564	}
7565};
7566
7567BX.JCCalendar.prototype.SetValue = function(v)
7568{
7569	this.value = (v && v.BXCHECKED) ? v : this._check_date(v);
7570
7571	this.PARTS.MONTH.innerHTML = BX.message('MONTH_' + (this.value.getUTCMonth()+1));
7572	this.PARTS.YEAR.innerHTML = this.value.getUTCFullYear();
7573
7574	if (!!this.params.bTime)
7575	{
7576		var h = this.value.getUTCHours();
7577		if (this.bAmPm)
7578		{
7579			if (h >= 12)
7580			{
7581				this.PARTS.TIME_AMPM.innerHTML = 'PM';
7582
7583				if (h != 12)
7584					h -= 12;
7585			}
7586			else
7587			{
7588				this.PARTS.TIME_AMPM.innerHTML = 'AM';
7589
7590				if (h == 0)
7591					h = 12;
7592			}
7593		}
7594
7595		this.PARTS.TIME_INPUT_H.value = BX.util.str_pad_left(h.toString(), 2, "0");
7596		this.PARTS.TIME_INPUT_M.value = BX.util.str_pad_left(this.value.getUTCMinutes().toString(), 2, "0");
7597	}
7598
7599	this._set_layer();
7600
7601	return this;
7602};
7603
7604BX.JCCalendar.prototype.SaveValue = function()
7605{
7606	if (this.popup_month)
7607		this.popup_month.close();
7608	if (this.popup_year)
7609		this.popup_year.close();
7610
7611	var bSetValue = true;
7612	if (!!this.params.callback)
7613	{
7614		var res = this.params.callback.apply(this, [new Date(this.value.valueOf()+this.value.getTimezoneOffset()*60000)]);
7615		if (res === false)
7616			bSetValue = false;
7617	}
7618
7619	if (bSetValue)
7620	{
7621		var bTime = !!this.params.bTime && BX.hasClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
7622
7623		if (this.params.field)
7624		{
7625			var format = BX.message(bTime ? 'FORMAT_DATETIME' : 'FORMAT_DATE');
7626
7627			if(bTime && !this.params.bUseSecond)
7628			{
7629				format = format.replace(':SS', '');
7630			}
7631
7632			this.params.field.value = BX.calendar.ValueToStringFormat(this.value, format, true);
7633			BX.fireEvent(this.params.field, 'change');
7634		}
7635
7636		this.popup.close();
7637
7638		if (!!this.params.callback_after)
7639		{
7640			this.params.callback_after.apply(this, [new Date(this.value.valueOf()+this.value.getTimezoneOffset()*60000), bTime]);
7641		}
7642	}
7643
7644	return this;
7645};
7646
7647BX.JCCalendar.prototype.Close = function()
7648{
7649	if (!!this.popup)
7650		this.popup.close();
7651
7652	return this;
7653};
7654
7655BX.JCSpinner = function(params)
7656{
7657	params = params || {};
7658	this.params = {
7659		input: params.input || null,
7660
7661		delta: params.delta || 1,
7662
7663		timeout_start: params.timeout_start || 1000,
7664		timeout_cont: params.timeout_cont || 150,
7665
7666		callback_start: params.callback_start || null,
7667		callback_change: params.callback_change || null,
7668		callback_finish: params.callback_finish || null,
7669
7670		bSaveValue: typeof params.bSaveValue == 'undefined' ? !!params.input : !!params.bSaveValue
7671	};
7672
7673	this.mousedown = false;
7674	this.direction = 1;
7675};
7676
7677BX.JCSpinner.prototype.Show = function()
7678{
7679	this.node = BX.create('span', {
7680		events: {
7681			mousedown: BX.delegateEvent(
7682				{attr: 'data-dir'},
7683				BX.delegate(this.Start, this)
7684			)
7685		},
7686		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>'
7687	});
7688	return this.node;
7689};
7690
7691BX.JCSpinner.prototype.Start = function()
7692{
7693	this.mousedown = true;
7694	this.direction = BX.proxy_context.getAttribute('data-dir') > 0 ? 1 : -1;
7695	BX.bind(document, "mouseup", BX.proxy(this.MouseUp, this));
7696	this.ChangeValue(true);
7697};
7698
7699BX.JCSpinner.prototype.ChangeValue = function(bFirst)
7700{
7701	if(!this.mousedown)
7702		return;
7703
7704	if (this.params.input)
7705	{
7706		var v = parseInt(this.params.input.value, 10) + this.params.delta * this.direction;
7707
7708		if (this.params.bSaveValue)
7709			this.params.input.value = v;
7710
7711		if (!!bFirst && this.params.callback_start)
7712			this.params.callback_start(this.params, v, this.direction);
7713
7714		if (this.params.callback_change)
7715			this.params.callback_change(this.params, v, this.direction);
7716
7717		setTimeout(
7718			BX.proxy(this.ChangeValue, this),
7719			!!bFirst ? this.params.timeout_start : this.params.timeout_cont
7720		);
7721	}
7722};
7723
7724BX.JCSpinner.prototype.MouseUp = function()
7725{
7726	this.mousedown = false;
7727	BX.unbind(document, "mouseup", BX.proxy(this.MouseUp, this));
7728
7729	if (this.params.callback_finish)
7730		this.params.callback_finish(this.params, this.params.input.value);
7731};
7732
7733/**************** compatibility hacks ***************************/
7734
7735window.jsCalendar = {
7736	Show: function(obj, field, fieldFrom, fieldTo, bTime, serverTime, form_name, bHideTimebar)
7737	{
7738		return BX.calendar({
7739			node: obj, field: field, form: form_name, bTime: !!bTime, currentTime: serverTime, bHideTimebar: !!bHideTimebar
7740		});
7741	},
7742
7743	ValueToString: BX.calendar.ValueToString
7744};
7745
7746
7747/************ clock popup transferred from timeman **************/
7748
7749BX.CClockSelector = function(params)
7750{
7751	this.params = params;
7752
7753	this.params.popup_buttons = this.params.popup_buttons || [
7754		new BX.PopupWindowButton({
7755			text : BX.message('CAL_BUTTON'),
7756			className : "popup-window-button-create",
7757			events : {click : BX.proxy(this.setValue, this)}
7758		})
7759	];
7760
7761	this.isReady = false;
7762
7763	this.WND = new BX.PopupWindow(
7764		this.params.popup_id || 'clock_selector_popup',
7765		this.params.node,
7766		this.params.popup_config || {
7767			titleBar: BX.message('CAL_TIME'),
7768			offsetLeft: -45,
7769			offsetTop: -135,
7770			autoHide: true,
7771			closeIcon: true,
7772			closeByEsc: true
7773		}
7774	);
7775
7776	this.SHOW = false;
7777	BX.addCustomEvent(this.WND, "onPopupClose", BX.delegate(this.onPopupClose, this));
7778
7779	this.obClocks = {};
7780	this.CLOCK_ID = this.params.clock_id || 'clock_selector';
7781};
7782
7783BX.CClockSelector.prototype.Show = function()
7784{
7785	if (!this.isReady)
7786	{
7787		//BX.timeman.showWait(this.parent.DIV);
7788
7789		BX.addCustomEvent('onClockRegister', BX.proxy(this.onClockRegister, this));
7790		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));
7791	}
7792
7793	this.WND.setButtons(this.params.popup_buttons);
7794	this.WND.show();
7795
7796	this.SHOW = true;
7797
7798	if (window['bxClock_' + this.obClocks[this.CLOCK_ID]])
7799	{
7800		setTimeout("window['bxClock_" + this.obClocks[this.CLOCK_ID] + "'].CalculateCoordinates()", 40);
7801	}
7802
7803	return true;
7804};
7805
7806BX.CClockSelector.prototype.onClockRegister = function(obClocks)
7807{
7808	if (obClocks[this.CLOCK_ID])
7809	{
7810		this.obClocks[this.CLOCK_ID] = obClocks[this.CLOCK_ID];
7811		BX.removeCustomEvent('onClockRegister', BX.proxy(this.onClockRegister, this));
7812	}
7813};
7814
7815BX.CClockSelector.prototype.Ready = function(data)
7816{
7817	this.content = this.CreateContent(data);
7818	this.WND.setContent(this.content);
7819
7820	this.isReady = true;
7821	//BX.timeman.closeWait();
7822
7823	setTimeout(BX.proxy(this.Show, this), 30);
7824};
7825
7826BX.CClockSelector.prototype.CreateContent = function(data)
7827{
7828	return BX.create('DIV', {
7829		events: {click: BX.PreventDefault},
7830		html:
7831			'<div class="bx-tm-popup-clock">' + data + '</div>'
7832	});
7833};
7834
7835BX.CClockSelector.prototype.setValue = function(e)
7836{
7837	if (this.params.callback)
7838	{
7839		var input = BX.findChild(this.content, {tagName: 'INPUT'}, true);
7840		this.params.callback.apply(this.params.node, [input.value]);
7841	}
7842
7843	return BX.PreventDefault(e);
7844};
7845
7846BX.CClockSelector.prototype.closeWnd = function(e)
7847{
7848	this.WND.close();
7849	return (e || window.event) ? BX.PreventDefault(e) : true;
7850};
7851
7852BX.CClockSelector.prototype.setNode = function(node)
7853{
7854	this.WND.setBindElement(node);
7855};
7856
7857BX.CClockSelector.prototype.setTime = function(timestamp)
7858{
7859	this.params.start_time = timestamp;
7860	if (window['bxClock_' + this.obClocks[this.CLOCK_ID]])
7861	{
7862		window['bxClock_' +  this.obClocks[this.CLOCK_ID]].SetTime(parseInt(timestamp/3600), parseInt((timestamp%3600)/60));
7863	}
7864};
7865
7866BX.CClockSelector.prototype.setCallback = function(cb)
7867{
7868	this.params.callback = cb;
7869};
7870
7871BX.CClockSelector.prototype.onPopupClose = function()
7872{
7873	this.SHOW = false;
7874};
7875
7876})();
7877
7878/* End */
7879;
7880; /* Start:"a:4:{s:4:"full";s:40:"/bitrix/js/main/utils.js?169691731029279";s:6:"source";s:24:"/bitrix/js/main/utils.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
7881var phpVars;
7882if(!phpVars)
7883{
7884	phpVars = {
7885		ADMIN_THEME_ID: '.default',
7886		LANGUAGE_ID: 'en',
7887		FORMAT_DATE: 'DD.MM.YYYY',
7888		FORMAT_DATETIME: 'DD.MM.YYYY HH:MI:SS',
7889		opt_context_ctrl: false,
7890		cookiePrefix: 'BITRIX_SM',
7891		titlePrefix: '',
7892		bitrix_sessid: '',
7893		messHideMenu: '',
7894		messShowMenu: '',
7895		messHideButtons: '',
7896		messShowButtons: '',
7897		messFilterInactive: '',
7898		messFilterActive: '',
7899		messFilterLess: '',
7900		messLoading: 'Loading...',
7901		messMenuLoading: '',
7902		messMenuLoadingTitle: '',
7903		messNoData: '',
7904		messExpandTabs: '',
7905		messCollapseTabs: '',
7906		messPanelFixOn: '',
7907		messPanelFixOff: '',
7908		messPanelCollapse: '',
7909		messPanelExpand: ''
7910	};
7911}
7912
7913var jsUtils =
7914{
7915	arEvents: Array(),
7916
7917	addEvent: function(el, evname, func, capture)
7918	{
7919		if(el.attachEvent) // IE
7920			el.attachEvent("on" + evname, func);
7921		else if(el.addEventListener) // Gecko / W3C
7922			el.addEventListener(evname, func, false);
7923		else
7924			el["on" + evname] = func;
7925		this.arEvents[this.arEvents.length] = {'element': el, 'event': evname, 'fn': func};
7926	},
7927
7928	removeEvent: function(el, evname, func)
7929	{
7930		if(el.detachEvent) // IE
7931			el.detachEvent("on" + evname, func);
7932		else if(el.removeEventListener) // Gecko / W3C
7933			el.removeEventListener(evname, func, false);
7934		else
7935			el["on" + evname] = null;
7936	},
7937
7938	removeAllEvents: function(el)
7939	{
7940		var i;
7941		for(i=0; i<this.arEvents.length; i++)
7942		{
7943			if(this.arEvents[i] && (el==false || el==this.arEvents[i].element))
7944			{
7945				jsUtils.removeEvent(this.arEvents[i].element, this.arEvents[i].event, this.arEvents[i].fn);
7946				this.arEvents[i] = null;
7947			}
7948		}
7949		if(el==false)
7950			this.arEvents.length = 0;
7951	},
7952
7953	IsDoctype: function()
7954	{
7955		if (document.compatMode)
7956			return (document.compatMode == "CSS1Compat");
7957
7958		if (document.documentElement && document.documentElement.clientHeight)
7959			return true;
7960
7961		return false;
7962	},
7963
7964	GetRealPos: function(el)
7965	{
7966		if(window.BX)
7967			return BX.pos(el);
7968
7969		if(!el || !el.offsetParent)
7970			return false;
7971
7972		var res = Array();
7973		res["left"] = el.offsetLeft;
7974		res["top"] = el.offsetTop;
7975		var objParent = el.offsetParent;
7976
7977		while(objParent && objParent.tagName != "BODY")
7978		{
7979			res["left"] += objParent.offsetLeft;
7980			res["top"] += objParent.offsetTop;
7981			objParent = objParent.offsetParent;
7982		}
7983		res["right"] = res["left"] + el.offsetWidth;
7984		res["bottom"] = res["top"] + el.offsetHeight;
7985
7986		return res;
7987	},
7988
7989	FindChildObject: function(obj, tag_name, class_name, recursive)
7990	{
7991		if(!obj)
7992			return null;
7993		var tag = tag_name.toUpperCase();
7994		var cl = (class_name? class_name.toLowerCase() : null);
7995		var n = obj.childNodes.length;
7996		for(var j=0; j<n; j++)
7997		{
7998			var child = obj.childNodes[j];
7999			if(child.tagName && child.tagName.toUpperCase() == tag)
8000				if(!class_name || child.className.toLowerCase() == cl)
8001					return child;
8002			if(recursive == true)
8003			{
8004				var deepChild;
8005				if((deepChild = jsUtils.FindChildObject(child, tag_name, class_name, true)))
8006					return deepChild;
8007			}
8008		}
8009		return null;
8010	},
8011
8012	FindParentObject: function(obj, tag_name, class_name)
8013	{
8014		if(!obj)
8015			return null;
8016		var o = obj;
8017		var tag = tag_name.toUpperCase();
8018		var cl = (class_name? class_name.toLowerCase() : null);
8019		while(o.parentNode)
8020		{
8021			var parent = o.parentNode;
8022			if(parent.tagName && parent.tagName.toUpperCase() == tag)
8023				if(!class_name || parent.className.toLowerCase() == cl)
8024					return parent;
8025			o = parent;
8026		}
8027		return null;
8028	},
8029
8030	FindNextSibling: function(obj, tag_name)
8031	{
8032		if(!obj)
8033			return null;
8034		var o = obj;
8035		var tag = tag_name.toUpperCase();
8036		while(o.nextSibling)
8037		{
8038			var sibling = o.nextSibling;
8039			if(sibling.tagName && sibling.tagName.toUpperCase() == tag)
8040				return sibling;
8041			o = sibling;
8042		}
8043		return null;
8044	},
8045
8046	FindPreviousSibling: function(obj, tag_name)
8047	{
8048		if(!obj)
8049			return null;
8050		var o = obj;
8051		var tag = tag_name.toUpperCase();
8052		while(o.previousSibling)
8053		{
8054			var sibling = o.previousSibling;
8055			if(sibling.tagName && sibling.tagName.toUpperCase() == tag)
8056				return sibling;
8057			o = sibling;
8058		}
8059		return null;
8060	},
8061
8062	bOpera : navigator.userAgent.toLowerCase().indexOf('opera') != -1,
8063	bIsIE : document.attachEvent && navigator.userAgent.toLowerCase().indexOf('opera') == -1,
8064
8065	IsIE: function()
8066	{
8067		return this.bIsIE;
8068	},
8069
8070	IsOpera: function()
8071	{
8072		return this.bOpera;
8073	},
8074
8075	IsSafari: function()
8076	{
8077		var userAgent = navigator.userAgent.toLowerCase();
8078		return (/webkit/.test(userAgent));
8079	},
8080
8081	IsEditor: function()
8082	{
8083		var userAgent = navigator.userAgent.toLowerCase();
8084		var version = (userAgent.match( /.+(msie)[\/: ]([\d.]+)/ ) || [])[2];
8085		var safari = /webkit/.test(userAgent);
8086
8087		if (this.IsOpera() || (document.all && !document.compatMode && version < 6) || safari)
8088			return false;
8089
8090		return true;
8091	},
8092
8093	ToggleDiv: function(div)
8094	{
8095		var style = document.getElementById(div).style;
8096		if(style.display!="none")
8097			style.display = "none";
8098		else
8099			style.display = "block";
8100		return (style.display != "none");
8101	},
8102
8103	urlencode: function(s)
8104	{
8105		return escape(s).replace(new RegExp('\\+','g'), '%2B');
8106	},
8107
8108	OpenWindow: function(url, width, height)
8109	{
8110		var w = screen.width, h = screen.height;
8111		if(this.IsOpera())
8112		{
8113			w = document.body.offsetWidth;
8114			h = document.body.offsetHeight;
8115		}
8116		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));
8117	},
8118
8119	SetPageTitle: function(s)
8120	{
8121		document.title = phpVars.titlePrefix+s;
8122		var h1 = document.getElementsByTagName("H1");
8123		if(h1)
8124			h1[0].innerHTML = s;
8125	},
8126
8127	LoadPageToDiv: function(url, div_id)
8128	{
8129		var div = document.getElementById(div_id);
8130		if(!div)
8131			return;
8132		CHttpRequest.Action = function(result)
8133		{
8134			CloseWaitWindow();
8135			document.getElementById(div_id).innerHTML = result;
8136		}
8137		ShowWaitWindow();
8138		CHttpRequest.Send(url);
8139	},
8140
8141	trim: function(s)
8142	{
8143		if (typeof s == 'string' || typeof s == 'object' && s.constructor == String)
8144		{
8145			var r, re;
8146
8147			re = /^[\s\r\n]+/g;
8148			r = s.replace(re, "");
8149			re = /[\s\r\n]+$/g;
8150			r = r.replace(re, "");
8151			return r;
8152		}
8153		else
8154			return s;
8155	},
8156
8157	Redirect: function(args, url)
8158	{
8159		var e = null, bShift = false;
8160		if(args && args.length > 0)
8161			e = args[0];
8162		if(!e)
8163			e = window.event;
8164		if(e)
8165			bShift = e.shiftKey;
8166
8167		if(bShift)
8168			window.open(url);
8169		else
8170		{
8171			window.location.href=url;
8172		}
8173	},
8174
8175	False: function(){return false;},
8176
8177	AlignToPos: function(pos, w, h)
8178	{
8179		var x = pos["left"], y = pos["bottom"];
8180
8181		var scroll = jsUtils.GetWindowScrollPos();
8182		var size = jsUtils.GetWindowInnerSize();
8183
8184		if((size.innerWidth + scroll.scrollLeft) - (pos["left"] + w) < 0)
8185		{
8186			if(pos["right"] - w >= 0 )
8187				x = pos["right"] - w;
8188			else
8189				x = scroll.scrollLeft;
8190		}
8191
8192		if((size.innerHeight + scroll.scrollTop) - (pos["bottom"] + h) < 0)
8193		{
8194			if(pos["top"] - h >= 0)
8195				y = pos["top"] - h;
8196			else
8197				y = scroll.scrollTop;
8198		}
8199
8200		return {'left':x, 'top':y};
8201	},
8202
8203	// evaluate js string in window scope
8204	EvalGlobal: function(script)
8205	{
8206		try {
8207		if (window.execScript)
8208			window.execScript(script, 'javascript');
8209		else if (jsUtils.IsSafari())
8210			window.setTimeout(script, 0);
8211		else
8212			window.eval(script);
8213		} catch (e) {/*alert("Error! jsUtils.EvalGlobal");*/}
8214	},
8215
8216	GetStyleValue: function(el, styleProp)
8217	{
8218		var res;
8219		if(el.currentStyle)
8220			res = el.currentStyle[styleProp];
8221		else if(window.getComputedStyle)
8222			res = document.defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
8223		if(!res)
8224			res = '';
8225		return res;
8226	},
8227
8228	GetWindowInnerSize: function(pDoc)
8229	{
8230		var width, height;
8231		if (!pDoc)
8232			pDoc = document;
8233
8234		if (self.innerHeight) // all except Explorer
8235		{
8236			width = self.innerWidth;
8237			height = self.innerHeight;
8238		}
8239		else if (pDoc.documentElement && (pDoc.documentElement.clientHeight || pDoc.documentElement.clientWidth)) // Explorer 6 Strict Mode
8240		{
8241			width = pDoc.documentElement.clientWidth;
8242			height = pDoc.documentElement.clientHeight;
8243		}
8244		else if (pDoc.body) // other Explorers
8245		{
8246			width = pDoc.body.clientWidth;
8247			height = pDoc.body.clientHeight;
8248		}
8249		return {innerWidth : width, innerHeight : height};
8250	},
8251
8252	GetWindowScrollPos: function(pDoc)
8253	{
8254		var left, top;
8255		if (!pDoc)
8256			pDoc = document;
8257
8258		if (self.pageYOffset) // all except Explorer
8259		{
8260			left = self.pageXOffset;
8261			top = self.pageYOffset;
8262		}
8263		else if (pDoc.documentElement && (pDoc.documentElement.scrollTop || pDoc.documentElement.scrollLeft)) // Explorer 6 Strict
8264		{
8265			left = document.documentElement.scrollLeft;
8266			top = document.documentElement.scrollTop;
8267		}
8268		else if (pDoc.body) // all other Explorers
8269		{
8270			left = pDoc.body.scrollLeft;
8271			top = pDoc.body.scrollTop;
8272		}
8273		return {scrollLeft : left, scrollTop : top};
8274	},
8275
8276	GetWindowScrollSize: function(pDoc)
8277	{
8278		var width, height;
8279		if (!pDoc)
8280			pDoc = document;
8281
8282		if ( (pDoc.compatMode && pDoc.compatMode == "CSS1Compat"))
8283		{
8284			width = pDoc.documentElement.scrollWidth;
8285			height = pDoc.documentElement.scrollHeight;
8286		}
8287		else
8288		{
8289			if (pDoc.body.scrollHeight > pDoc.body.offsetHeight)
8290				height = pDoc.body.scrollHeight;
8291			else
8292				height = pDoc.body.offsetHeight;
8293
8294			if (pDoc.body.scrollWidth > pDoc.body.offsetWidth ||
8295				(pDoc.compatMode && pDoc.compatMode == "BackCompat") ||
8296				(pDoc.documentElement && !pDoc.documentElement.clientWidth)
8297			)
8298				width = pDoc.body.scrollWidth;
8299			else
8300				width = pDoc.body.offsetWidth;
8301		}
8302		return {scrollWidth : width, scrollHeight : height};
8303	},
8304
8305	GetWindowSize: function()
8306	{
8307		var innerSize = jsUtils.GetWindowInnerSize();
8308		var scrollPos = jsUtils.GetWindowScrollPos();
8309		var scrollSize = jsUtils.GetWindowScrollSize();
8310
8311		return  {
8312			innerWidth : innerSize.innerWidth, innerHeight : innerSize.innerHeight,
8313			scrollLeft : scrollPos.scrollLeft, scrollTop : scrollPos.scrollTop,
8314			scrollWidth : scrollSize.scrollWidth, scrollHeight : scrollSize.scrollHeight
8315		};
8316	},
8317
8318
8319	arCustomEvents: {},
8320
8321	addCustomEvent: function(eventName, eventHandler, arParams, handlerContextObject)
8322	{
8323		if (!this.arCustomEvents[eventName])
8324			this.arCustomEvents[eventName] = [];
8325
8326		if (!arParams)
8327			arParams = [];
8328		if (!handlerContextObject)
8329			handlerContextObject = false;
8330
8331		this.arCustomEvents[eventName].push(
8332			{
8333				handler: eventHandler,
8334				arParams: arParams,
8335				obj: handlerContextObject
8336			}
8337		);
8338	},
8339
8340	removeCustomEvent: function(eventName, eventHandler)
8341	{
8342		if (!this.arCustomEvents[eventName])
8343			return;
8344
8345		var l = this.arCustomEvents[eventName].length;
8346		if (l == 1)
8347		{
8348			delete this.arCustomEvents[eventName];
8349			return;
8350		}
8351
8352		for (var i = 0; i < l; i++)
8353		{
8354			if (!this.arCustomEvents[eventName][i])
8355				continue;
8356			if (this.arCustomEvents[eventName][i].handler == eventHandler)
8357			{
8358				delete this.arCustomEvents[eventName][i];
8359				return;
8360			}
8361		}
8362	},
8363
8364	onCustomEvent: function(eventName, arEventParams)
8365	{
8366		if (!this.arCustomEvents[eventName])
8367			return;
8368
8369		if (!arEventParams)
8370			arEventParams = [];
8371
8372		var h;
8373		for (var i = 0, l = this.arCustomEvents[eventName].length; i < l; i++)
8374		{
8375			h = this.arCustomEvents[eventName][i];
8376			if (!h || !h.handler)
8377				continue;
8378
8379			if (h.obj)
8380				h.handler.call(h.obj, h.arParams, arEventParams);
8381			else
8382				h.handler(h.arParams, arEventParams);
8383		}
8384	},
8385
8386	loadJSFile: function(arJs, oCallBack, pDoc)
8387	{
8388		if (!pDoc)
8389			pDoc = document;
8390		if (typeof arJs == 'string')
8391			arJs = [arJs];
8392		var callback = function()
8393		{
8394			if (!oCallBack)
8395				return;
8396			if (typeof oCallBack == 'function')
8397				return oCallBack();
8398			if (typeof oCallBack != 'object' || !oCallBack.func)
8399				return;
8400			var p = oCallBack.params || {};
8401			if (oCallBack.obj)
8402				oCallBack.func.apply(oCallBack.obj, p);
8403			else
8404				oCallBack.func(p);
8405		};
8406		var load_js = function(ind)
8407		{
8408			if (ind >= arJs.length)
8409				return callback();
8410			var oSript = pDoc.body.appendChild(pDoc.createElement('script'));
8411			oSript.src = arJs[ind];
8412			var bLoaded = false;
8413			oSript.onload = oSript.onreadystatechange = function()
8414			{
8415				if (!bLoaded && (!oSript.readyState || oSript.readyState == "loaded" || oSript.readyState == "complete"))
8416				{
8417					bLoaded = true;
8418					setTimeout(function (){load_js(++ind);}, 50);
8419				}
8420			};
8421		};
8422		load_js(0);
8423	},
8424
8425	loadCSSFile: function(arCSS, pDoc, pWin)
8426	{
8427		if (typeof arCSS == 'string')
8428		{
8429			var bSingle = true;
8430			arCSS = [arCSS];
8431		}
8432		var i, l = arCSS.length, pLnk = [];
8433		if (l == 0)
8434			return;
8435		if (!pDoc)
8436			pDoc = document;
8437		if (!pWin)
8438			pWin = window;
8439		if (!pWin.bxhead)
8440		{
8441			var heads = pDoc.getElementsByTagName('HEAD');
8442			pWin.bxhead = heads[0];
8443		}
8444		if (!pWin.bxhead)
8445			return;
8446		for (i = 0; i < l; i++)
8447		{
8448			var lnk = document.createElement('LINK');
8449			lnk.href = arCSS[i];
8450			lnk.rel = 'stylesheet';
8451			lnk.type = 'text/css';
8452			pWin.bxhead.appendChild(lnk);
8453			pLnk.push(lnk);
8454		}
8455		if (bSingle)
8456			return lnk;
8457		return pLnk;
8458	},
8459
8460	appendBXHint : function(node, html)
8461	{
8462		if (!node || !node.parentNode || !html)
8463			return;
8464		var oBXHint = new BXHint(html);
8465		node.parentNode.insertBefore(oBXHint.oIcon, node);
8466		node.parentNode.removeChild(node);
8467		oBXHint.oIcon.style.marginLeft = "5px";
8468	},
8469
8470	PreventDefault : function(e)
8471	{
8472		if(!e) e = window.event;
8473		if(e.stopPropagation)
8474		{
8475			e.preventDefault();
8476			e.stopPropagation();
8477		}
8478		else
8479		{
8480			e.cancelBubble = true;
8481			e.returnValue = false;
8482		}
8483		return false;
8484	},
8485
8486	CreateElement: function(tag, arAttr, arStyles, pDoc)
8487	{
8488		if (!pDoc)
8489			pDoc = document;
8490		var pEl = pDoc.createElement(tag), p;
8491		if(arAttr)
8492		{
8493			for(p in arAttr)
8494			{
8495				if(p == 'className' || p == 'class')
8496				{
8497					pEl.setAttribute('class', arAttr[p]);
8498					if (jsUtils.IsIE())
8499						pEl.setAttribute('className', arAttr[p]);
8500					continue;
8501				}
8502
8503				if (arAttr[p] != undefined && arAttr[p] != null)
8504					pEl.setAttribute(p, arAttr[p]);
8505			}
8506		}
8507		if(arStyles)
8508		{
8509			for(p in arStyles)
8510				pEl.style[p] = arStyles[p];
8511		}
8512		return pEl;
8513	},
8514
8515	in_array: function(needle, haystack)
8516	{
8517		for(var i=0; i<haystack.length; i++)
8518		{
8519			if(haystack[i] == needle)
8520				return true;
8521		}
8522		return false;
8523	},
8524
8525	htmlspecialchars: function(str)
8526	{
8527		if(!str.replace)
8528			return str;
8529
8530		return str.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
8531	}
8532}
8533
8534/************************************************/
8535
8536function JCFloatDiv()
8537{
8538	var _this = this;
8539	this.floatDiv = null;
8540	this.x = this.y = 0;
8541
8542	this.Create = function(arParams)
8543	{
8544		var div = document.body.appendChild(document.createElement("DIV"));
8545		div.id = arParams.id;
8546		div.style.position = 'absolute';
8547		div.style.left = '-10000px';
8548		div.style.top = '-10000px';
8549		if(arParams.className)
8550			div.className = arParams.className;
8551		if(arParams.zIndex)
8552			div.style.zIndex = arParams.zIndex;
8553		if(arParams.width)
8554			div.style.width = arParams.width+'px';
8555		if(arParams.height)
8556			div.style.height = arParams.height+'px';
8557		return div;
8558	}
8559
8560	this.Show = function(div, left, top, dxShadow, restrictDrag)
8561	{
8562		var component = BX.ZIndexManager.getComponent(div);
8563		if (!component)
8564		{
8565			BX.ZIndexManager.register(div);
8566		}
8567
8568		BX.ZIndexManager.bringToFront(div);
8569
8570		if (left < 0)
8571			left = 0;
8572
8573		if (top < 0)
8574			top = 0;
8575
8576		div.style.left = parseInt(left) + "px";
8577		div.style.top = parseInt(top) + "px";
8578
8579		/*Restrict drag*/
8580		div.restrictDrag = restrictDrag || false;
8581
8582		/*shadow*/
8583		if(isNaN(dxShadow))
8584			dxShadow = 5;
8585
8586		div.dxShadow = dxShadow;
8587	}
8588
8589	this.Close = function(div)
8590	{
8591		if(!div)
8592			return;
8593		var sh = document.getElementById(div.id+"_shadow");
8594		if(sh)
8595			sh.style.visibility = 'hidden';
8596
8597		var frame = document.getElementById(div.id+"_frame");
8598		if(frame)
8599			frame.style.visibility = 'hidden';
8600	}
8601
8602	this.Move = function(div, x, y)
8603	{
8604		if(!div)
8605			return;
8606
8607		var dxShadow = div.dxShadow;
8608		var left = parseInt(div.style.left)+x;
8609		var top = parseInt(div.style.top)+y;
8610
8611		if (div.restrictDrag)
8612		{
8613			//Left side
8614			if (left < 0)
8615				left = 0;
8616
8617			//Right side
8618			if ( (document.compatMode && document.compatMode == "CSS1Compat"))
8619				windowWidth = document.documentElement.scrollWidth;
8620			else
8621			{
8622				if (document.body.scrollWidth > document.body.offsetWidth ||
8623					(document.compatMode && document.compatMode == "BackCompat") ||
8624					(document.documentElement && !document.documentElement.clientWidth)
8625				)
8626					windowWidth = document.body.scrollWidth;
8627				else
8628					windowWidth = document.body.offsetWidth;
8629			}
8630
8631			var floatWidth = div.offsetWidth;
8632			if (left > (windowWidth - floatWidth - dxShadow))
8633				left = windowWidth - floatWidth - dxShadow;
8634
8635			//Top side
8636			if (top < 0)
8637				top = 0;
8638		}
8639
8640		div.style.left = left+'px';
8641		div.style.top = top+'px';
8642
8643		this.AdjustShadow(div);
8644	}
8645
8646	this.HideShadow = function(div)
8647	{
8648		var sh = document.getElementById(div.id + "_shadow");
8649		sh.style.visibility = 'hidden';
8650	}
8651
8652	this.UnhideShadow = function(div)
8653	{
8654		var sh = document.getElementById(div.id + "_shadow");
8655		sh.style.visibility = 'visible';
8656	}
8657
8658	this.AdjustShadow = function(div)
8659	{
8660		var sh = document.getElementById(div.id + "_shadow");
8661		if(sh && sh.style.visibility != 'hidden')
8662		{
8663			var dxShadow = div.dxShadow;
8664
8665			sh.style.width = div.offsetWidth+'px';
8666			sh.style.height = div.offsetHeight+'px';
8667			sh.style.left = parseInt(div.style.left)+dxShadow+'px';
8668			sh.style.top = parseInt(div.style.top)+dxShadow+'px';
8669		}
8670
8671		var frame = document.getElementById(div.id+"_frame");
8672		if(frame)
8673		{
8674			frame.style.width = div.offsetWidth + "px";
8675			frame.style.height = div.offsetHeight + "px";
8676			frame.style.left = div.style.left;
8677			frame.style.top = div.style.top;
8678		}
8679	}
8680
8681	this.StartDrag = function(e, div)
8682	{
8683		if(!e)
8684			e = window.event;
8685		this.x = e.clientX + document.body.scrollLeft;
8686		this.y = e.clientY + document.body.scrollTop;
8687		this.floatDiv = div;
8688
8689		jsUtils.addEvent(document, "mousemove", this.MoveDrag);
8690		document.onmouseup = this.StopDrag;
8691		if(document.body.setCapture)
8692			document.body.setCapture();
8693
8694		document.onmousedown = jsUtils.False;
8695		var b = document.body;
8696		b.ondrag = jsUtils.False;
8697		b.onselectstart = jsUtils.False;
8698		b.style.MozUserSelect = _this.floatDiv.style.MozUserSelect = 'none';
8699		b.style.cursor = 'move';
8700	}
8701
8702	this.StopDrag = function(e)
8703	{
8704		if(document.body.releaseCapture)
8705			document.body.releaseCapture();
8706
8707		jsUtils.removeEvent(document, "mousemove", _this.MoveDrag);
8708		document.onmouseup = null;
8709
8710		this.floatDiv = null;
8711
8712		document.onmousedown = null;
8713		var b = document.body;
8714		b.ondrag = null;
8715		b.onselectstart = null;
8716		b.style.MozUserSelect = _this.floatDiv.style.MozUserSelect = '';
8717		b.style.cursor = '';
8718	}
8719
8720	this.MoveDrag = function(e)
8721	{
8722		var x = e.clientX + document.body.scrollLeft;
8723		var y = e.clientY + document.body.scrollTop;
8724
8725		if(_this.x == x && _this.y == y)
8726			return;
8727
8728		_this.Move(_this.floatDiv, (x - _this.x), (y - _this.y));
8729		_this.x = x;
8730		_this.y = y;
8731	}
8732}
8733var jsFloatDiv = new JCFloatDiv();
8734
8735/************************************************/
8736
8737var BXHint = function(innerHTML, element, addParams)
8738{
8739	this.oDivOver = false;
8740	this.timeOutID = null;
8741	this.oIcon = null;
8742	this.freeze = false;
8743	this.x = 0;
8744	this.y = 0;
8745	this.time = 700;
8746
8747	if (!innerHTML)
8748		innerHTML = "";
8749	this.Create(innerHTML, element, addParams);
8750}
8751
8752BXHint.prototype.Create = function(innerHTML, element, addParams)
8753{
8754	var
8755		_this = this,
8756		width = 0,
8757		height = 0,
8758		className = null,
8759		type = "icon";
8760	this.bWidth = true;
8761
8762	if (addParams)
8763	{
8764		if (addParams.width === false)
8765			this.bWidth = false;
8766		else if (addParams.width)
8767			width = addParams.width;
8768
8769		if (addParams.height)
8770			height = addParams.height;
8771
8772		if (addParams.className)
8773			className = addParams.className;
8774
8775		if (addParams.type && (addParams.type == "link" || addParams.type == "icon"))
8776			type = addParams.type;
8777		if (addParams.time > 0)
8778			this.time = addParams.time;
8779	}
8780
8781	if (element)
8782		type = "element";
8783
8784	if (type == "icon")
8785	{
8786		var element = document.createElement("IMG");
8787		element.src = (addParams && addParams.iconSrc) ? addParams.iconSrc : "/bitrix/themes/"+phpVars.ADMIN_THEME_ID+"/public/popup/hint.gif";
8788		element.ondrag = jsUtils.False;
8789	}
8790	else if (type == "link")
8791	{
8792		var element = document.createElement("A");
8793		element.href = "";
8794		element.onclick = function(e){return false;}
8795		element.innerHTML = "[?]";
8796	}
8797
8798	this.element = element;
8799	if (type == "element")
8800	{
8801		if(addParams && addParams.show_on_click)
8802		{
8803			jsUtils.addEvent(
8804				element,
8805				"click",
8806				function (event)
8807				{
8808					if (!event)
8809						event = window.event;
8810					_this.GetMouseXY(event);
8811					_this.timeOutID = setTimeout(function () {_this.Show(innerHTML,width,height,className) }, 10);
8812				}
8813			);
8814		}
8815		else
8816		{
8817			jsUtils.addEvent(
8818				element,
8819				"mouseover",
8820				function (event)
8821				{
8822					if (!event)
8823						event = window.event;
8824					_this.GetMouseXY(event);
8825					_this.timeOutID = setTimeout(function () {_this.Show(innerHTML,width,height,className) }, 750);
8826				}
8827			);
8828		}
8829
8830		jsUtils.addEvent(
8831			element,
8832			"mouseout",
8833			function(event)
8834			{
8835				if (_this.timeOutID)
8836					clearTimeout(_this.timeOutID);
8837				_this.SmartHide(_this);
8838			}
8839		);
8840	}
8841	else
8842	{
8843		this.oIcon = element;
8844		element.onmouseover = function(event) {if (!event) event = window.event; _this.GetMouseXY(event); _this.Show(innerHTML,width,height,className)};
8845		element.onmouseout = function() {_this.SmartHide(_this);};
8846	}
8847}
8848
8849BXHint.prototype.IsFrozen = function()
8850{
8851	return this.freeze;
8852}
8853
8854BXHint.prototype.Freeze = function()
8855{
8856	this.freeze = true;
8857	this.Hide();
8858}
8859
8860BXHint.prototype.UnFreeze = function()
8861{
8862	this.freeze = false;
8863}
8864
8865BXHint.prototype.GetMouseXY = function(event)
8866{
8867	if (event.pageX || event.pageY)
8868	{
8869		this.x = event.pageX;
8870		this.y = event.pageY;
8871	}
8872	else if (event.clientX || event.clientY)
8873	{
8874		this.x = event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft;
8875		this.y = event.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop;
8876	}
8877}
8878
8879BXHint.prototype.Show = function(innerHTML, width, height, className)
8880{
8881	//Delete previous hint
8882	var old = document.getElementById("__BXHint_div");
8883	if (old)
8884		this.Hide();
8885
8886	if (this.freeze)
8887		return;
8888
8889	var _this = this;
8890	var oDiv = document.body.appendChild(document.createElement("DIV"));
8891	oDiv.onmouseover = function(){_this.oDivOver = true};
8892	oDiv.onmouseout = function(){_this.oDivOver = false; _this.SmartHide(_this);}
8893	oDiv.id = "__BXHint_div";
8894	oDiv.className = (className) ? className : "bxhint";
8895	oDiv.style.position = 'absolute';
8896	if (width && this.bWidth)
8897		oDiv.style.width = width + "px";
8898
8899	if (height)
8900		oDiv.style.height = height + "px";
8901	oDiv.innerHTML = innerHTML;
8902
8903	var w = oDiv.offsetWidth;
8904	var h = oDiv.offsetHeight;
8905	if (this.bWidth)
8906	{
8907		if (!width && w>200)
8908			w = Math.round(Math.sqrt(1.618*w*h));
8909		oDiv.style.width = w + "px";
8910		h = oDiv.offsetHeight;
8911	}
8912
8913	var pos = {left : this.x + 10, right : this.x + w, top : this.y, bottom : this.y + h};
8914
8915	pos = this.AlignToPos(pos, w, h);
8916
8917	jsFloatDiv.Show(oDiv, pos.left, pos.top,3);
8918
8919//	oDiv.ondrag = jsUtils.False;
8920//	oDiv.onselectstart = jsUtils.False;
8921//	oDiv.style.MozUserSelect = 'none';
8922	oDiv = null;
8923}
8924
8925BXHint.prototype.AlignToPos = function(pos, w, h)
8926{
8927	var body = document.body;
8928	if((body.clientWidth + body.scrollLeft) < (pos.left + w))
8929		pos.left = (pos.left - w >= 0) ? (pos.left - w) : body.scrollLeft;
8930
8931	if((body.clientHeight + body.scrollTop) - (pos["bottom"]) < 0)
8932		pos.top = (pos.top - h >= 0) ? (pos.top - h) : body.scrollTop;
8933
8934	return pos;
8935}
8936
8937BXHint.prototype.Hide = function()
8938{
8939	var oDiv = document.getElementById("__BXHint_div");
8940
8941	if (!oDiv)
8942		return;
8943
8944	BX.ZIndexManager.unregister(oDiv);
8945
8946	jsFloatDiv.Close(oDiv);
8947	oDiv.parentNode.removeChild(oDiv);
8948	oDiv = null;
8949}
8950
8951BXHint.prototype.SmartHide = function(_this)
8952{
8953	setTimeout(function ()
8954		{
8955			if (!_this.oDivOver)
8956				_this.Hide();
8957		}, 100
8958	);
8959}
8960
8961/************************************************/
8962
8963function WaitOnKeyPress(e)
8964{
8965	if(!e) e = window.event
8966	if(!e) return;
8967	if(e.keyCode == 27)
8968		CloseWaitWindow();
8969}
8970
8971function ShowWaitWindow()
8972{
8973	CloseWaitWindow();
8974
8975	var obWndSize = jsUtils.GetWindowSize();
8976
8977	var div = document.body.appendChild(document.createElement("DIV"));
8978	div.id = "wait_window_div";
8979	div.innerHTML = phpVars.messLoading;
8980	div.className = "waitwindow";
8981	//div.style.left = obWndSize.scrollLeft + (obWndSize.innerWidth - div.offsetWidth) - (jsUtils.IsIE() ? 5 : 20) + "px";
8982	div.style.right = (5 - obWndSize.scrollLeft) + 'px';
8983	div.style.top = obWndSize.scrollTop + 5 + "px";
8984
8985	if(jsUtils.IsIE())
8986	{
8987		var frame = document.createElement("IFRAME");
8988		frame.src = "javascript:''";
8989		frame.id = "wait_window_frame";
8990		frame.className = "waitwindow";
8991		frame.style.width = div.offsetWidth + "px";
8992		frame.style.height = div.offsetHeight + "px";
8993		frame.style.right = div.style.right;
8994		frame.style.top = div.style.top;
8995		document.body.appendChild(frame);
8996	}
8997	jsUtils.addEvent(document, "keypress", WaitOnKeyPress);
8998}
8999
9000function CloseWaitWindow()
9001{
9002	jsUtils.removeEvent(document, "keypress", WaitOnKeyPress);
9003
9004	var frame = document.getElementById("wait_window_frame");
9005	if(frame)
9006		frame.parentNode.removeChild(frame);
9007
9008	var div = document.getElementById("wait_window_div");
9009	if(div)
9010		div.parentNode.removeChild(div);
9011}
9012
9013/************************************************/
9014
9015var jsSelectUtils =
9016{
9017	addNewOption: function(select_id, opt_value, opt_name, do_sort, check_unique)
9018	{
9019		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
9020		if(oSelect)
9021		{
9022			var n = oSelect.length;
9023			if(check_unique !== false)
9024			{
9025				for(var i=0;i<n;i++)
9026					if(oSelect[i].value==opt_value)
9027						return;
9028			}
9029			var newoption = new Option(opt_name, opt_value, false, false);
9030			oSelect.options[n]=newoption;
9031		}
9032		if(do_sort === true)
9033			this.sortSelect(select_id);
9034	},
9035
9036	deleteOption: function(select_id, opt_value)
9037	{
9038		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
9039		if(oSelect)
9040		{
9041			for(var i=0;i<oSelect.length;i++)
9042				if(oSelect[i].value==opt_value)
9043				{
9044					oSelect.remove(i);
9045					break;
9046				}
9047		}
9048	},
9049
9050	deleteSelectedOptions: function(select_id)
9051	{
9052		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
9053		if(oSelect)
9054		{
9055			var i=0;
9056			while(i<oSelect.length)
9057				if(oSelect[i].selected)
9058				{
9059					oSelect[i].selected=false;
9060					oSelect.remove(i);
9061				}
9062				else
9063					i++;
9064		}
9065	},
9066
9067	deleteAllOptions: function(oSelect)
9068	{
9069		if(oSelect)
9070		{
9071			for(var i=oSelect.length-1; i>=0; i--)
9072				oSelect.remove(i);
9073		}
9074	},
9075
9076	optionCompare: function(record1, record2)
9077	{
9078		var value1 = record1.optText.toLowerCase();
9079		var value2 = record2.optText.toLowerCase();
9080		if (value1 > value2) return(1);
9081		if (value1 < value2) return(-1);
9082		return(0);
9083	},
9084
9085	sortSelect: function(select_id)
9086	{
9087		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
9088		if(oSelect)
9089		{
9090			var myOptions = [];
9091			var n = oSelect.options.length;
9092			for (var i=0;i<n;i++)
9093			{
9094				myOptions[i] = {
9095					optText:oSelect[i].text,
9096					optValue:oSelect[i].value
9097				};
9098			}
9099			myOptions.sort(this.optionCompare);
9100			oSelect.length=0;
9101			n = myOptions.length;
9102			for(var i=0;i<n;i++)
9103			{
9104				var newoption = new Option(myOptions[i].optText, myOptions[i].optValue, false, false);
9105				oSelect[i]=newoption;
9106			}
9107		}
9108	},
9109
9110	selectAllOptions: function(select_id)
9111	{
9112		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
9113		if(oSelect)
9114		{
9115			var n = oSelect.length;
9116			for(var i=0;i<n;i++)
9117				oSelect[i].selected=true;
9118		}
9119	},
9120
9121	selectOption: function(select_id, opt_value)
9122	{
9123		var oSelect = (typeof(select_id) == 'string' || select_id instanceof String? document.getElementById(select_id) : select_id);
9124		if(oSelect)
9125		{
9126			var n = oSelect.length;
9127			for(var i=0;i<n;i++)
9128				oSelect[i].selected = (oSelect[i].value == opt_value);
9129		}
9130	},
9131
9132	addSelectedOptions: function(oSelect, to_select_id, check_unique, do_sort)
9133	{
9134		if(!oSelect)
9135			return;
9136		var n = oSelect.length;
9137		for(var i=0; i<n; i++)
9138			if(oSelect[i].selected)
9139				this.addNewOption(to_select_id, oSelect[i].value, oSelect[i].text, do_sort, check_unique);
9140	},
9141
9142	moveOptionsUp: function(oSelect)
9143	{
9144		if(!oSelect)
9145			return;
9146		var n = oSelect.length;
9147		for(var i=0; i<n; i++)
9148		{
9149			if(oSelect[i].selected && i>0 && oSelect[i-1].selected == false)
9150			{
9151				var option1 = new Option(oSelect[i].text, oSelect[i].value);
9152				var option2 = new Option(oSelect[i-1].text, oSelect[i-1].value);
9153				oSelect[i] = option2;
9154				oSelect[i].selected = false;
9155				oSelect[i-1] = option1;
9156				oSelect[i-1].selected = true;
9157			}
9158		}
9159	},
9160
9161	moveOptionsDown: function(oSelect)
9162	{
9163		if(!oSelect)
9164			return;
9165		var n = oSelect.length;
9166		for(var i=n-1; i>=0; i--)
9167		{
9168			if(oSelect[i].selected && i<n-1 && oSelect[i+1].selected == false)
9169			{
9170				var option1 = new Option(oSelect[i].text, oSelect[i].value);
9171				var option2 = new Option(oSelect[i+1].text, oSelect[i+1].value);
9172				oSelect[i] = option2;
9173				oSelect[i].selected = false;
9174				oSelect[i+1] = option1;
9175				oSelect[i+1].selected = true;
9176			}
9177		}
9178	}
9179
9180}
9181
9182/************************************************/
9183
9184/* End */
9185;

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.