PageSourceSearch

https://sharspb.ru/bitrix/js/main/core/core.js?1787308376333925

js sharspb.ru collected 2026-10-08 06:11:21 UTC 333,925 bytes, 13,451 lines download raw bytes

1/* eslint-disable */
2;(function() {
3
4	if (typeof window.BX === 'function')
5	{
6		return;
7	}
8
9/**
10 * Babel external helpers
11 * (c) 2018 Babel
12 * @license MIT
13 */
14(function (global) {
15	var babelHelpers = global.babelHelpers = {};
16
17	function _typeof(obj) {
18		if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
19			babelHelpers.typeof = _typeof = function (obj) {
20				return typeof obj;
21			};
22		} else {
23			babelHelpers.typeof = _typeof = function (obj) {
24				return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
25			};
26		}
27
28		return _typeof(obj);
29	}
30
31	babelHelpers.typeof = _typeof;
32	var REACT_ELEMENT_TYPE;
33
34	function _createRawReactElement(type, props, key, children) {
35		if (!REACT_ELEMENT_TYPE) {
36			REACT_ELEMENT_TYPE = typeof Symbol === "function" && Symbol.for && Symbol.for("react.element") || 0xeac7;
37		}
38
39		var defaultProps = type && type.defaultProps;
40		var childrenLength = arguments.length - 3;
41
42		if (!props && childrenLength !== 0) {
43			props = {
44				children: void 0
45			};
46		}
47
48		if (props && defaultProps) {
49			for (var propName in defaultProps) {
50				if (props[propName] === void 0) {
51					props[propName] = defaultProps[propName];
52				}
53			}
54		} else if (!props) {
55			props = defaultProps || {};
56		}
57
58		if (childrenLength === 1) {
59			props.children = children;
60		} else if (childrenLength > 1) {
61			var childArray = new Array(childrenLength);
62
63			for (var i = 0; i < childrenLength; i++) {
64				childArray[i] = arguments[i + 3];
65			}
66
67			props.children = childArray;
68		}
69
70		return {
71			$$typeof: REACT_ELEMENT_TYPE,
72			type: type,
73			key: key === undefined ? null : '' + key,
74			ref: null,
75			props: props,
76			_owner: null
77		};
78	}
79
80	babelHelpers.jsx = _createRawReactElement;
81
82	function _asyncIterator(iterable) {
83		var method;
84
85		if (typeof Symbol === "function") {
86			if (Symbol.asyncIterator) {
87				method = iterable[Symbol.asyncIterator];
88				if (method != null) return method.call(iterable);
89			}
90
91			if (Symbol.iterator) {
92				method = iterable[Symbol.iterator];
93				if (method != null) return method.call(iterable);
94			}
95		}
96
97		throw new TypeError("Object is not async iterable");
98	}
99
100	babelHelpers.asyncIterator = _asyncIterator;
101
102	function _AwaitValue(value) {
103		this.wrapped = value;
104	}
105
106	babelHelpers.AwaitValue = _AwaitValue;
107
108	function AsyncGenerator(gen) {
109		var front, back;
110
111		function send(key, arg) {
112			return new Promise(function (resolve, reject) {
113				var request = {
114					key: key,
115					arg: arg,
116					resolve: resolve,
117					reject: reject,
118					next: null
119				};
120
121				if (back) {
122					back = back.next = request;
123				} else {
124					front = back = request;
125					resume(key, arg);
126				}
127			});
128		}
129
130		function resume(key, arg) {
131			try {
132				var result = gen[key](arg);
133				var value = result.value;
134				var wrappedAwait = value instanceof babelHelpers.AwaitValue;
135				Promise.resolve(wrappedAwait ? value.wrapped : value).then(function (arg) {
136					if (wrappedAwait) {
137						resume("next", arg);
138						return;
139					}
140
141					settle(result.done ? "return" : "normal", arg);
142				}, function (err) {
143					resume("throw", err);
144				});
145			} catch (err) {
146				settle("throw", err);
147			}
148		}
149
150		function settle(type, value) {
151			switch (type) {
152				case "return":
153					front.resolve({
154						value: value,
155						done: true
156					});
157					break;
158
159				case "throw":
160					front.reject(value);
161					break;
162
163				default:
164					front.resolve({
165						value: value,
166						done: false
167					});
168					break;
169			}
170
171			front = front.next;
172
173			if (front) {
174				resume(front.key, front.arg);
175			} else {
176				back = null;
177			}
178		}
179
180		this._invoke = send;
181
182		if (typeof gen.return !== "function") {
183			this.return = undefined;
184		}
185	}
186
187	if (typeof Symbol === "function" && Symbol.asyncIterator) {
188		AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
189			return this;
190		};
191	}
192
193	AsyncGenerator.prototype.next = function (arg) {
194		return this._invoke("next", arg);
195	};
196
197	AsyncGenerator.prototype.throw = function (arg) {
198		return this._invoke("throw", arg);
199	};
200
201	AsyncGenerator.prototype.return = function (arg) {
202		return this._invoke("return", arg);
203	};
204
205	babelHelpers.AsyncGenerator = AsyncGenerator;
206
207	function _wrapAsyncGenerator(fn) {
208		return function () {
209			return new babelHelpers.AsyncGenerator(fn.apply(this, arguments));
210		};
211	}
212
213	babelHelpers.wrapAsyncGenerator = _wrapAsyncGenerator;
214
215	function _awaitAsyncGenerator(value) {
216		return new babelHelpers.AwaitValue(value);
217	}
218
219	babelHelpers.awaitAsyncGenerator = _awaitAsyncGenerator;
220
221	function _asyncGeneratorDelegate(inner, awaitWrap) {
222		var iter = {},
223				waiting = false;
224
225		function pump(key, value) {
226			waiting = true;
227			value = new Promise(function (resolve) {
228				resolve(inner[key](value));
229			});
230			return {
231				done: false,
232				value: awaitWrap(value)
233			};
234		}
235
236		;
237
238		if (typeof Symbol === "function" && Symbol.iterator) {
239			iter[Symbol.iterator] = function () {
240				return this;
241			};
242		}
243
244		iter.next = function (value) {
245			if (waiting) {
246				waiting = false;
247				return value;
248			}
249
250			return pump("next", value);
251		};
252
253		if (typeof inner.throw === "function") {
254			iter.throw = function (value) {
255				if (waiting) {
256					waiting = false;
257					throw value;
258				}
259
260				return pump("throw", value);
261			};
262		}
263
264		if (typeof inner.return === "function") {
265			iter.return = function (value) {
266				return pump("return", value);
267			};
268		}
269
270		return iter;
271	}
272
273	babelHelpers.asyncGeneratorDelegate = _asyncGeneratorDelegate;
274
275	function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
276		try {
277			var info = gen[key](arg);
278			var value = info.value;
279		} catch (error) {
280			reject(error);
281			return;
282		}
283
284		if (info.done) {
285			resolve(value);
286		} else {
287			Promise.resolve(value).then(_next, _throw);
288		}
289	}
290
291	function _asyncToGenerator(fn) {
292		return function () {
293			var self = this,
294					args = arguments;
295			return new Promise(function (resolve, reject) {
296				var gen = fn.apply(self, args);
297
298				function _next(value) {
299					asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
300				}
301
302				function _throw(err) {
303					asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
304				}
305
306				_next(undefined);
307			});
308		};
309	}
310
311	babelHelpers.asyncToGenerator = _asyncToGenerator;
312
313	function _classCallCheck(instance, Constructor) {
314		if (!(instance instanceof Constructor)) {
315			throw new TypeError("Cannot call a class as a function");
316		}
317	}
318
319	babelHelpers.classCallCheck = _classCallCheck;
320
321	function _defineProperties(target, props) {
322		for (var i = 0; i < props.length; i++) {
323			var descriptor = props[i];
324			descriptor.enumerable = descriptor.enumerable || false;
325			descriptor.configurable = true;
326			if ("value" in descriptor) descriptor.writable = true;
327			Object.defineProperty(target, descriptor.key, descriptor);
328		}
329	}
330
331	function _createClass(Constructor, protoProps, staticProps) {
332		if (protoProps) _defineProperties(Constructor.prototype, protoProps);
333		if (staticProps) _defineProperties(Constructor, staticProps);
334		return Constructor;
335	}
336
337	babelHelpers.createClass = _createClass;
338
339	function _defineEnumerableProperties(obj, descs) {
340		for (var key in descs) {
341			var desc = descs[key];
342			desc.configurable = desc.enumerable = true;
343			if ("value" in desc) desc.writable = true;
344			Object.defineProperty(obj, key, desc);
345		}
346
347		if (Object.getOwnPropertySymbols) {
348			var objectSymbols = Object.getOwnPropertySymbols(descs);
349
350			for (var i = 0; i < objectSymbols.length; i++) {
351				var sym = objectSymbols[i];
352				var desc = descs[sym];
353				desc.configurable = desc.enumerable = true;
354				if ("value" in desc) desc.writable = true;
355				Object.defineProperty(obj, sym, desc);
356			}
357		}
358
359		return obj;
360	}
361
362	babelHelpers.defineEnumerableProperties = _defineEnumerableProperties;
363
364	function _defaults(obj, defaults) {
365		var keys = Object.getOwnPropertyNames(defaults);
366
367		for (var i = 0; i < keys.length; i++) {
368			var key = keys[i];
369			var value = Object.getOwnPropertyDescriptor(defaults, key);
370
371			if (value && value.configurable && obj[key] === undefined) {
372				Object.defineProperty(obj, key, value);
373			}
374		}
375
376		return obj;
377	}
378
379	babelHelpers.defaults = _defaults;
380
381	function _defineProperty(obj, key, value) {
382		if (key in obj) {
383			Object.defineProperty(obj, key, {
384				value: value,
385				enumerable: true,
386				configurable: true,
387				writable: true
388			});
389		} else {
390			obj[key] = value;
391		}
392
393		return obj;
394	}
395
396	babelHelpers.defineProperty = _defineProperty;
397
398	function _extends() {
399		babelHelpers.extends = _extends = Object.assign || function (target) {
400			for (var i = 1; i < arguments.length; i++) {
401				var source = arguments[i];
402
403				for (var key in source) {
404					if (Object.prototype.hasOwnProperty.call(source, key)) {
405						target[key] = source[key];
406					}
407				}
408			}
409
410			return target;
411		};
412
413		return _extends.apply(this, arguments);
414	}
415
416	babelHelpers.extends = _extends;
417
418	function _objectSpread(target) {
419		for (var i = 1; i < arguments.length; i++) {
420			var source = arguments[i] != null ? arguments[i] : {};
421			var ownKeys = Object.keys(source);
422
423			if (typeof Object.getOwnPropertySymbols === 'function') {
424				ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
425					return Object.getOwnPropertyDescriptor(source, sym).enumerable;
426				}));
427			}
428
429			ownKeys.forEach(function (key) {
430				babelHelpers.defineProperty(target, key, source[key]);
431			});
432		}
433
434		return target;
435	}
436
437	babelHelpers.objectSpread = _objectSpread;
438
439	function _inherits(subClass, superClass) {
440		if (typeof superClass !== "function" && superClass !== null) {
441			throw new TypeError("Super expression must either be null or a function");
442		}
443
444		subClass.prototype = Object.create(superClass && superClass.prototype, {
445			constructor: {
446				value: subClass,
447				writable: true,
448				configurable: true
449			}
450		});
451		if (superClass) babelHelpers.setPrototypeOf(subClass, superClass);
452	}
453
454	babelHelpers.inherits = _inherits;
455
456	function _inheritsLoose(subClass, superClass) {
457		subClass.prototype = Object.create(superClass.prototype);
458		subClass.prototype.constructor = subClass;
459		subClass.__proto__ = superClass;
460	}
461
462	babelHelpers.inheritsLoose = _inheritsLoose;
463
464	function _getPrototypeOf(o) {
465		babelHelpers.getPrototypeOf = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
466			return o.__proto__ || Object.getPrototypeOf(o);
467		};
468		return _getPrototypeOf(o);
469	}
470
471	babelHelpers.getPrototypeOf = _getPrototypeOf;
472
473	function _setPrototypeOf(o, p) {
474		babelHelpers.setPrototypeOf = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
475			o.__proto__ = p;
476			return o;
477		};
478
479		return _setPrototypeOf(o, p);
480	}
481
482	babelHelpers.setPrototypeOf = _setPrototypeOf;
483
484	function isNativeReflectConstruct() {
485		if (typeof Reflect === "undefined" || !Reflect.construct) return false;
486		if (Reflect.construct.sham) return false;
487		if (typeof Proxy === "function") return true;
488
489		try {
490			Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
491			return true;
492		} catch (e) {
493			return false;
494		}
495	}
496
497	function _construct(Parent, args, Class) {
498		if (isNativeReflectConstruct()) {
499			babelHelpers.construct = _construct = Reflect.construct;
500		} else {
501			babelHelpers.construct = _construct = function _construct(Parent, args, Class) {
502				var a = [null];
503				a.push.apply(a, args);
504				var Constructor = Function.bind.apply(Parent, a);
505				var instance = new Constructor();
506				if (Class) babelHelpers.setPrototypeOf(instance, Class.prototype);
507				return instance;
508			};
509		}
510
511		return _construct.apply(null, arguments);
512	}
513
514	babelHelpers.construct = _construct;
515
516	function _isNativeFunction(fn) {
517		return Function.toString.call(fn).indexOf("[native code]") !== -1;
518	}
519
520	babelHelpers.isNativeFunction = _isNativeFunction;
521
522	function _wrapNativeSuper(Class) {
523		var _cache = typeof Map === "function" ? new Map() : undefined;
524
525		babelHelpers.wrapNativeSuper = _wrapNativeSuper = function _wrapNativeSuper(Class) {
526			if (Class === null || !babelHelpers.isNativeFunction(Class)) return Class;
527
528			if (typeof Class !== "function") {
529				throw new TypeError("Super expression must either be null or a function");
530			}
531
532			if (typeof _cache !== "undefined") {
533				if (_cache.has(Class)) return _cache.get(Class);
534
535				_cache.set(Class, Wrapper);
536			}
537
538			function Wrapper() {
539				return babelHelpers.construct(Class, arguments, babelHelpers.getPrototypeOf(this).constructor);
540			}
541
542			Wrapper.prototype = Object.create(Class.prototype, {
543				constructor: {
544					value: Wrapper,
545					enumerable: false,
546					writable: true,
547					configurable: true
548				}
549			});
550			return babelHelpers.setPrototypeOf(Wrapper, Class);
551		};
552
553		return _wrapNativeSuper(Class);
554	}
555
556	babelHelpers.wrapNativeSuper = _wrapNativeSuper;
557
558	function _instanceof(left, right) {
559		if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
560			return right[Symbol.hasInstance](left);
561		} else {
562			return left instanceof right;
563		}
564	}
565
566	babelHelpers.instanceof = _instanceof;
567
568	function _interopRequireDefault(obj) {
569		return obj && obj.__esModule ? obj : {
570			default: obj
571		};
572	}
573
574	babelHelpers.interopRequireDefault = _interopRequireDefault;
575
576	function _interopRequireWildcard(obj) {
577		if (obj && obj.__esModule) {
578			return obj;
579		} else {
580			var newObj = {};
581
582			if (obj != null) {
583				for (var key in obj) {
584					if (Object.prototype.hasOwnProperty.call(obj, key)) {
585						var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};
586
587						if (desc.get || desc.set) {
588							Object.defineProperty(newObj, key, desc);
589						} else {
590							newObj[key] = obj[key];
591						}
592					}
593				}
594			}
595
596			newObj.default = obj;
597			return newObj;
598		}
599	}
600
601	babelHelpers.interopRequireWildcard = _interopRequireWildcard;
602
603	function _newArrowCheck(innerThis, boundThis) {
604		if (innerThis !== boundThis) {
605			throw new TypeError("Cannot instantiate an arrow function");
606		}
607	}
608
609	babelHelpers.newArrowCheck = _newArrowCheck;
610
611	function _objectDestructuringEmpty(obj) {
612		if (obj == null) throw new TypeError("Cannot destructure undefined");
613	}
614
615	babelHelpers.objectDestructuringEmpty = _objectDestructuringEmpty;
616
617	function _objectWithoutPropertiesLoose(source, excluded) {
618		if (source == null) return {};
619		var target = {};
620		var sourceKeys = Object.keys(source);
621		var key, i;
622
623		for (i = 0; i < sourceKeys.length; i++) {
624			key = sourceKeys[i];
625			if (excluded.indexOf(key) >= 0) continue;
626			target[key] = source[key];
627		}
628
629		return target;
630	}
631
632	babelHelpers.objectWithoutPropertiesLoose = _objectWithoutPropertiesLoose;
633
634	function _objectWithoutProperties(source, excluded) {
635		if (source == null) return {};
636		var target = babelHelpers.objectWithoutPropertiesLoose(source, excluded);
637		var key, i;
638
639		if (Object.getOwnPropertySymbols) {
640			var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
641
642			for (i = 0; i < sourceSymbolKeys.length; i++) {
643				key = sourceSymbolKeys[i];
644				if (excluded.indexOf(key) >= 0) continue;
645				if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
646				target[key] = source[key];
647			}
648		}
649
650		return target;
651	}
652
653	babelHelpers.objectWithoutProperties = _objectWithoutProperties;
654
655	function _assertThisInitialized(self) {
656		if (self === void 0) {
657			throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
658		}
659
660		return self;
661	}
662
663	babelHelpers.assertThisInitialized = _assertThisInitialized;
664
665	function _possibleConstructorReturn(self, call) {
666		if (call && (typeof call === "object" || typeof call === "function")) {
667			return call;
668		}
669
670		return babelHelpers.assertThisInitialized(self);
671	}
672
673	babelHelpers.possibleConstructorReturn = _possibleConstructorReturn;
674
675	function _superPropBase(object, property) {
676		while (!Object.prototype.hasOwnProperty.call(object, property)) {
677			object = babelHelpers.getPrototypeOf(object);
678			if (object === null) break;
679		}
680
681		return object;
682	}
683
684	babelHelpers.superPropBase = _superPropBase;
685
686	function _get(target, property, receiver) {
687		if (typeof Reflect !== "undefined" && Reflect.get) {
688			babelHelpers.get = _get = Reflect.get;
689		} else {
690			babelHelpers.get = _get = function _get(target, property, receiver) {
691				var base = babelHelpers.superPropBase(target, property);
692				if (!base) return;
693				var desc = Object.getOwnPropertyDescriptor(base, property);
694
695				if (desc.get) {
696					return desc.get.call(receiver);
697				}
698
699				return desc.value;
700			};
701		}
702
703		return _get(target, property, receiver || target);
704	}
705
706	babelHelpers.get = _get;
707
708	function set(target, property, value, receiver) {
709		if (typeof Reflect !== "undefined" && Reflect.set) {
710			set = Reflect.set;
711		} else {
712			set = function set(target, property, value, receiver) {
713				var base = babelHelpers.superPropBase(target, property);
714				var desc;
715
716				if (base) {
717					desc = Object.getOwnPropertyDescriptor(base, property);
718
719					if (desc.set) {
720						desc.set.call(receiver, value);
721						return true;
722					} else if (!desc.writable) {
723						return false;
724					}
725				}
726
727				desc = Object.getOwnPropertyDescriptor(receiver, property);
728
729				if (desc) {
730					if (!desc.writable) {
731						return false;
732					}
733
734					desc.value = value;
735					Object.defineProperty(receiver, property, desc);
736				} else {
737					babelHelpers.defineProperty(receiver, property, value);
738				}
739
740				return true;
741			};
742		}
743
744		return set(target, property, value, receiver);
745	}
746
747	function _set(target, property, value, receiver, isStrict) {
748		var s = set(target, property, value, receiver || target);
749
750		if (!s && isStrict) {
751			throw new Error('failed to set property');
752		}
753
754		return value;
755	}
756
757	babelHelpers.set = _set;
758
759	function _taggedTemplateLiteral(strings, raw) {
760		if (!raw) {
761			raw = strings.slice(0);
762		}
763
764		return Object.freeze(Object.defineProperties(strings, {
765			raw: {
766				value: Object.freeze(raw)
767			}
768		}));
769	}
770
771	babelHelpers.taggedTemplateLiteral = _taggedTemplateLiteral;
772
773	function _taggedTemplateLiteralLoose(strings, raw) {
774		if (!raw) {
775			raw = strings.slice(0);
776		}
777
778		strings.raw = raw;
779		return strings;
780	}
781
782	babelHelpers.taggedTemplateLiteralLoose = _taggedTemplateLiteralLoose;
783
784	function _temporalRef(val, name) {
785		if (val === babelHelpers.temporalUndefined) {
786			throw new ReferenceError(name + " is not defined - temporal dead zone");
787		} else {
788			return val;
789		}
790	}
791
792	babelHelpers.temporalRef = _temporalRef;
793
794	function _readOnlyError(name) {
795		throw new Error("\"" + name + "\" is read-only");
796	}
797
798	babelHelpers.readOnlyError = _readOnlyError;
799
800	function _classNameTDZError(name) {
801		throw new Error("Class \"" + name + "\" cannot be referenced in computed property keys.");
802	}
803
804	babelHelpers.classNameTDZError = _classNameTDZError;
805	babelHelpers.temporalUndefined = {};
806
807	function _slicedToArray(arr, i) {
808		return babelHelpers.arrayWithHoles(arr) || babelHelpers.iterableToArrayLimit(arr, i) || babelHelpers.nonIterableRest();
809	}
810
811	babelHelpers.slicedToArray = _slicedToArray;
812
813	function _slicedToArrayLoose(arr, i) {
814		return babelHelpers.arrayWithHoles(arr) || babelHelpers.iterableToArrayLimitLoose(arr, i) || babelHelpers.nonIterableRest();
815	}
816
817	babelHelpers.slicedToArrayLoose = _slicedToArrayLoose;
818
819	function _toArray(arr) {
820		return babelHelpers.arrayWithHoles(arr) || babelHelpers.iterableToArray(arr) || babelHelpers.nonIterableRest();
821	}
822
823	babelHelpers.toArray = _toArray;
824
825	function _toConsumableArray(arr) {
826		return babelHelpers.arrayWithoutHoles(arr) || babelHelpers.iterableToArray(arr) || babelHelpers.nonIterableSpread();
827	}
828
829	babelHelpers.toConsumableArray = _toConsumableArray;
830
831	function _arrayWithoutHoles(arr) {
832		if (Array.isArray(arr)) {
833			for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
834
835			return arr2;
836		}
837	}
838
839	babelHelpers.arrayWithoutHoles = _arrayWithoutHoles;
840
841	function _arrayWithHoles(arr) {
842		if (Array.isArray(arr)) return arr;
843	}
844
845	babelHelpers.arrayWithHoles = _arrayWithHoles;
846
847	function _iterableToArray(iter) {
848		if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
849	}
850
851	babelHelpers.iterableToArray = _iterableToArray;
852
853	function _iterableToArrayLimit(arr, i) {
854		var _arr = [];
855		var _n = true;
856		var _d = false;
857		var _e = undefined;
858
859		try {
860			for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
861				_arr.push(_s.value);
862
863				if (i && _arr.length === i) break;
864			}
865		} catch (err) {
866			_d = true;
867			_e = err;
868		} finally {
869			try {
870				if (!_n && _i["return"] != null) _i["return"]();
871			} finally {
872				if (_d) throw _e;
873			}
874		}
875
876		return _arr;
877	}
878
879	babelHelpers.iterableToArrayLimit = _iterableToArrayLimit;
880
881	function _iterableToArrayLimitLoose(arr, i) {
882		var _arr = [];
883
884		for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) {
885			_arr.push(_step.value);
886
887			if (i && _arr.length === i) break;
888		}
889
890		return _arr;
891	}
892
893	babelHelpers.iterableToArrayLimitLoose = _iterableToArrayLimitLoose;
894
895	function _nonIterableSpread() {
896		throw new TypeError("Invalid attempt to spread non-iterable instance");
897	}
898
899	babelHelpers.nonIterableSpread = _nonIterableSpread;
900
901	function _nonIterableRest() {
902		throw new TypeError("Invalid attempt to destructure non-iterable instance");
903	}
904
905	babelHelpers.nonIterableRest = _nonIterableRest;
906
907	function _skipFirstGeneratorNext(fn) {
908		return function () {
909			var it = fn.apply(this, arguments);
910			it.next();
911			return it;
912		};
913	}
914
915	babelHelpers.skipFirstGeneratorNext = _skipFirstGeneratorNext;
916
917	function _toPropertyKey(key) {
918		if (typeof key === "symbol") {
919			return key;
920		} else {
921			return String(key);
922		}
923	}
924
925	babelHelpers.toPropertyKey = _toPropertyKey;
926
927	function _initializerWarningHelper(descriptor, context) {
928		throw new Error('Decorating class property failed. Please ensure that ' + 'proposal-class-properties is enabled and set to use loose mode. ' + 'To use proposal-class-properties in spec mode with decorators, wait for ' + 'the next major version of decorators in stage 2.');
929	}
930
931	babelHelpers.initializerWarningHelper = _initializerWarningHelper;
932
933	function _initializerDefineProperty(target, property, descriptor, context) {
934		if (!descriptor) return;
935		Object.defineProperty(target, property, {
936			enumerable: descriptor.enumerable,
937			configurable: descriptor.configurable,
938			writable: descriptor.writable,
939			value: descriptor.initializer ? descriptor.initializer.call(context) : void 0
940		});
941	}
942
943	babelHelpers.initializerDefineProperty = _initializerDefineProperty;
944
945	function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
946		var desc = {};
947		Object['ke' + 'ys'](descriptor).forEach(function (key) {
948			desc[key] = descriptor[key];
949		});
950		desc.enumerable = !!desc.enumerable;
951		desc.configurable = !!desc.configurable;
952
953		if ('value' in desc || desc.initializer) {
954			desc.writable = true;
955		}
956
957		desc = decorators.slice().reverse().reduce(function (desc, decorator) {
958			return decorator(target, property, desc) || desc;
959		}, desc);
960
961		if (context && desc.initializer !== void 0) {
962			desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
963			desc.initializer = undefined;
964		}
965
966		if (desc.initializer === void 0) {
967			Object['define' + 'Property'](target, property, desc);
968			desc = null;
969		}
970
971		return desc;
972	}
973
974	babelHelpers.applyDecoratedDescriptor = _applyDecoratedDescriptor;
975	var id = 0;
976
977	function _classPrivateFieldKey(name) {
978		return "__private_" + id++ + "_" + name;
979	}
980
981	babelHelpers.classPrivateFieldLooseKey = _classPrivateFieldKey;
982
983	function _classPrivateFieldBase(receiver, privateKey) {
984		if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
985			throw new TypeError("attempted to use private field on non-instance");
986		}
987
988		return receiver;
989	}
990
991	babelHelpers.classPrivateFieldLooseBase = _classPrivateFieldBase;
992
993	function _classPrivateFieldGet(receiver, privateMap) {
994		if (!privateMap.has(receiver)) {
995			throw new TypeError("attempted to get private field on non-instance");
996		}
997
998		return privateMap.get(receiver).value;
999	}
1000
1001	babelHelpers.classPrivateFieldGet = _classPrivateFieldGet;
1002
1003	function _classPrivateFieldSet(receiver, privateMap, value) {
1004		if (!privateMap.has(receiver)) {
1005			throw new TypeError("attempted to set private field on non-instance");
1006		}
1007
1008		var descriptor = privateMap.get(receiver);
1009
1010		if (!descriptor.writable) {
1011			throw new TypeError("attempted to set read only private field");
1012		}
1013
1014		descriptor.value = value;
1015		return value;
1016	}
1017
1018	babelHelpers.classPrivateFieldSet = _classPrivateFieldSet;
1019})(typeof global === "undefined" ? window : global);
1020
1021/**
1022 * Copyright (c) 2014-present, Facebook, Inc.
1023 *
1024 * This source code is licensed under the MIT license found in the
1025 * LICENSE file in the root directory of this source tree.
1026 */
1027
1028!(function(global) {
1029	"use strict";
1030
1031	var Op = Object.prototype;
1032	var hasOwn = Op.hasOwnProperty;
1033	var undefined; // More compressible than void 0.
1034	var $Symbol = typeof Symbol === "function" ? Symbol : {};
1035	var iteratorSymbol = $Symbol.iterator || "@@iterator";
1036	var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
1037	var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
1038
1039	// Define the runtime globally (as expected by generated code) as either
1040	// module.exports (if we're in a module) or a new, empty object.
1041	var runtime = global.regeneratorRuntime = {};
1042
1043	function wrap(innerFn, outerFn, self, tryLocsList) {
1044		// If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
1045		var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
1046		var generator = Object.create(protoGenerator.prototype);
1047		var context = new Context(tryLocsList || []);
1048
1049		// The ._invoke method unifies the implementations of the .next,
1050		// .throw, and .return methods.
1051		generator._invoke = makeInvokeMethod(innerFn, self, context);
1052
1053		return generator;
1054	}
1055	runtime.wrap = wrap;
1056
1057	// Try/catch helper to minimize deoptimizations. Returns a completion
1058	// record like context.tryEntries[i].completion. This interface could
vendor: 10,591 bytes, lines 1059-1352
1059	// have been (and was previously) designed to take a closure to be
1060	// invoked without arguments, but in all the cases we care about we
1061	// already have an existing method we want to call, so there's no need
1062	// to create a new function object. We can even get away with assuming
1063	// the method takes exactly one argument, since that happens to be true
1064	// in every case, so we don't have to touch the arguments object. The
1065	// only additional allocation required is the completion record, which
1066	// has a stable shape and so hopefully should be cheap to allocate.
1067	function tryCatch(fn, obj, arg) {
1068		try {
1069			return { type: "normal", arg: fn.call(obj, arg) };
1070		} catch (err) {
1071			return { type: "throw", arg: err };
1072		}
1073	}
1074
1075	var GenStateSuspendedStart = "suspendedStart";
1076	var GenStateSuspendedYield = "suspendedYield";
1077	var GenStateExecuting = "executing";
1078	var GenStateCompleted = "completed";
1079
1080	// Returning this object from the innerFn has the same effect as
1081	// breaking out of the dispatch switch statement.
1082	var ContinueSentinel = {};
1083
1084	// Dummy constructor functions that we use as the .constructor and
1085	// .constructor.prototype properties for functions that return Generator
1086	// objects. For full spec compliance, you may wish to configure your
1087	// minifier not to mangle the names of these two functions.
1088	function Generator() {}
1089	function GeneratorFunction() {}
1090	function GeneratorFunctionPrototype() {}
1091
1092	// This is a polyfill for %IteratorPrototype% for environments that
1093	// don't natively support it.
1094	var IteratorPrototype = {};
1095	IteratorPrototype[iteratorSymbol] = function () {
1096		return this;
1097	};
1098
1099	var getProto = Object.getPrototypeOf;
1100	var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
1101	if (NativeIteratorPrototype &&
1102		NativeIteratorPrototype !== Op &&
1103		hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
1104		// This environment has a native %IteratorPrototype%; use it instead
1105		// of the polyfill.
1106		IteratorPrototype = NativeIteratorPrototype;
1107	}
1108
1109	var Gp = GeneratorFunctionPrototype.prototype =
1110		Generator.prototype = Object.create(IteratorPrototype);
1111	GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
1112	GeneratorFunctionPrototype.constructor = GeneratorFunction;
1113	GeneratorFunctionPrototype[toStringTagSymbol] =
1114		GeneratorFunction.displayName = "GeneratorFunction";
1115
1116	// Helper for defining the .next, .throw, and .return methods of the
1117	// Iterator interface in terms of a single ._invoke method.
1118	function defineIteratorMethods(prototype) {
1119		["next", "throw", "return"].forEach(function(method) {
1120			prototype[method] = function(arg) {
1121				return this._invoke(method, arg);
1122			};
1123		});
1124	}
1125
1126	runtime.isGeneratorFunction = function(genFun) {
1127		var ctor = typeof genFun === "function" && genFun.constructor;
1128		return ctor
1129			? ctor === GeneratorFunction ||
1130			// For the native GeneratorFunction constructor, the best we can
1131			// do is to check its .name property.
1132			(ctor.displayName || ctor.name) === "GeneratorFunction"
1133			: false;
1134	};
1135
1136	runtime.mark = function(genFun) {
1137		if (Object.setPrototypeOf) {
1138			Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
1139		} else {
1140			genFun.__proto__ = GeneratorFunctionPrototype;
1141			if (!(toStringTagSymbol in genFun)) {
1142				genFun[toStringTagSymbol] = "GeneratorFunction";
1143			}
1144		}
1145		genFun.prototype = Object.create(Gp);
1146		return genFun;
1147	};
1148
1149	// Within the body of any async function, `await x` is transformed to
1150	// `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
1151	// `hasOwn.call(value, "__await")` to determine if the yielded value is
1152	// meant to be awaited.
1153	runtime.awrap = function(arg) {
1154		return { __await: arg };
1155	};
1156
1157	function AsyncIterator(generator) {
1158		function invoke(method, arg, resolve, reject) {
1159			var record = tryCatch(generator[method], generator, arg);
1160			if (record.type === "throw") {
1161				reject(record.arg);
1162			} else {
1163				var result = record.arg;
1164				var value = result.value;
1165				if (value &&
1166					typeof value === "object" &&
1167					hasOwn.call(value, "__await")) {
1168					return Promise.resolve(value.__await).then(function(value) {
1169						invoke("next", value, resolve, reject);
1170					}, function(err) {
1171						invoke("throw", err, resolve, reject);
1172					});
1173				}
1174
1175				return Promise.resolve(value).then(function(unwrapped) {
1176					// When a yielded Promise is resolved, its final value becomes
1177					// the .value of the Promise<{value,done}> result for the
1178					// current iteration. If the Promise is rejected, however, the
1179					// result for this iteration will be rejected with the same
1180					// reason. Note that rejections of yielded Promises are not
1181					// thrown back into the generator function, as is the case
1182					// when an awaited Promise is rejected. This difference in
1183					// behavior between yield and await is important, because it
1184					// allows the consumer to decide what to do with the yielded
1185					// rejection (swallow it and continue, manually .throw it back
1186					// into the generator, abandon iteration, whatever). With
1187					// await, by contrast, there is no opportunity to examine the
1188					// rejection reason outside the generator function, so the
1189					// only option is to throw it from the await expression, and
1190					// let the generator function handle the exception.
1191					result.value = unwrapped;
1192					resolve(result);
1193				}, reject);
1194			}
1195		}
1196
1197		var previousPromise;
1198
1199		function enqueue(method, arg) {
1200			function callInvokeWithMethodAndArg() {
1201				return new Promise(function(resolve, reject) {
1202					invoke(method, arg, resolve, reject);
1203				});
1204			}
1205
1206			return previousPromise =
1207				// If enqueue has been called before, then we want to wait until
1208				// all previous Promises have been resolved before calling invoke,
1209				// so that results are always delivered in the correct order. If
1210				// enqueue has not been called before, then it is important to
1211				// call invoke immediately, without waiting on a callback to fire,
1212				// so that the async generator function has the opportunity to do
1213				// any necessary setup in a predictable way. This predictability
1214				// is why the Promise constructor synchronously invokes its
1215				// executor callback, and why async functions synchronously
1216				// execute code before the first await. Since we implement simple
1217				// async functions in terms of async generators, it is especially
1218				// important to get this right, even though it requires care.
1219				previousPromise ? previousPromise.then(
1220					callInvokeWithMethodAndArg,
1221					// Avoid propagating failures to Promises returned by later
1222					// invocations of the iterator.
1223					callInvokeWithMethodAndArg
1224				) : callInvokeWithMethodAndArg();
1225		}
1226
1227		// Define the unified helper method that is used to implement .next,
1228		// .throw, and .return (see defineIteratorMethods).
1229		this._invoke = enqueue;
1230	}
1231
1232	defineIteratorMethods(AsyncIterator.prototype);
1233	AsyncIterator.prototype[asyncIteratorSymbol] = function () {
1234		return this;
1235	};
1236	runtime.AsyncIterator = AsyncIterator;
1237
1238	// Note that simple async functions are implemented on top of
1239	// AsyncIterator objects; they just return a Promise for the value of
1240	// the final result produced by the iterator.
1241	runtime.async = function(innerFn, outerFn, self, tryLocsList) {
1242		var iter = new AsyncIterator(
1243			wrap(innerFn, outerFn, self, tryLocsList)
1244		);
1245
1246		return runtime.isGeneratorFunction(outerFn)
1247			? iter // If outerFn is a generator, return the full iterator.
1248			: iter.next().then(function(result) {
1249				return result.done ? result.value : iter.next();
1250			});
1251	};
1252
1253	function makeInvokeMethod(innerFn, self, context) {
1254		var state = GenStateSuspendedStart;
1255
1256		return function invoke(method, arg) {
1257			if (state === GenStateExecuting) {
1258				throw new Error("Generator is already running");
1259			}
1260
1261			if (state === GenStateCompleted) {
1262				if (method === "throw") {
1263					throw arg;
1264				}
1265
1266				// Be forgiving, per 25.3.3.3.3 of the spec:
1267				// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
1268				return doneResult();
1269			}
1270
1271			context.method = method;
1272			context.arg = arg;
1273
1274			while (true) {
1275				var delegate = context.delegate;
1276				if (delegate) {
1277					var delegateResult = maybeInvokeDelegate(delegate, context);
1278					if (delegateResult) {
1279						if (delegateResult === ContinueSentinel) continue;
1280						return delegateResult;
1281					}
1282				}
1283
1284				if (context.method === "next") {
1285					// Setting context._sent for legacy support of Babel's
1286					// function.sent implementation.
1287					context.sent = context._sent = context.arg;
1288
1289				} else if (context.method === "throw") {
1290					if (state === GenStateSuspendedStart) {
1291						state = GenStateCompleted;
1292						throw context.arg;
1293					}
1294
1295					context.dispatchException(context.arg);
1296
1297				} else if (context.method === "return") {
1298					context.abrupt("return", context.arg);
1299				}
1300
1301				state = GenStateExecuting;
1302
1303				var record = tryCatch(innerFn, self, context);
1304				if (record.type === "normal") {
1305					// If an exception is thrown from innerFn, we leave state ===
1306					// GenStateExecuting and loop back for another invocation.
1307					state = context.done
1308						? GenStateCompleted
1309						: GenStateSuspendedYield;
1310
1311					if (record.arg === ContinueSentinel) {
1312						continue;
1313					}
1314
1315					return {
1316						value: record.arg,
1317						done: context.done
1318					};
1319
1320				} else if (record.type === "throw") {
1321					state = GenStateCompleted;
1322					// Dispatch the exception by looping back around to the
1323					// context.dispatchException(context.arg) call above.
1324					context.method = "throw";
1325					context.arg = record.arg;
1326				}
1327			}
1328		};
1329	}
1330
1331	// Call delegate.iterator[context.method](context.arg) and handle the
1332	// result, either by returning a { value, done } result from the
1333	// delegate iterator, or by modifying context.method and context.arg,
1334	// setting context.delegate to null, and returning the ContinueSentinel.
1335	function maybeInvokeDelegate(delegate, context) {
1336		var method = delegate.iterator[context.method];
1337		if (method === undefined) {
1338			// A .throw or .return when the delegate iterator has no .throw
1339			// method always terminates the yield* loop.
1340			context.delegate = null;
1341
1342			if (context.method === "throw") {
1343				if (delegate.iterator.return) {
1344					// If the delegate iterator has a return method, give it a
1345					// chance to clean up.
1346					context.method = "return";
1347					context.arg = undefined;
1348					maybeInvokeDelegate(delegate, context);
1349
1350					if (context.method === "throw") {
1351						// If maybeInvokeDelegate(context) changed context.method from
1352						// "return" to "throw", let that override the TypeError below.
vendor: 4,172 bytes, lines 1353-1506
1353						return ContinueSentinel;
1354					}
1355				}
1356
1357				context.method = "throw";
1358				context.arg = new TypeError(
1359					"The iterator does not provide a 'throw' method");
1360			}
1361
1362			return ContinueSentinel;
1363		}
1364
1365		var record = tryCatch(method, delegate.iterator, context.arg);
1366
1367		if (record.type === "throw") {
1368			context.method = "throw";
1369			context.arg = record.arg;
1370			context.delegate = null;
1371			return ContinueSentinel;
1372		}
1373
1374		var info = record.arg;
1375
1376		if (! info) {
1377			context.method = "throw";
1378			context.arg = new TypeError("iterator result is not an object");
1379			context.delegate = null;
1380			return ContinueSentinel;
1381		}
1382
1383		if (info.done) {
1384			// Assign the result of the finished delegate to the temporary
1385			// variable specified by delegate.resultName (see delegateYield).
1386			context[delegate.resultName] = info.value;
1387
1388			// Resume execution at the desired location (see delegateYield).
1389			context.next = delegate.nextLoc;
1390
1391			// If context.method was "throw" but the delegate handled the
1392			// exception, let the outer generator proceed normally. If
1393			// context.method was "next", forget context.arg since it has been
1394			// "consumed" by the delegate iterator. If context.method was
1395			// "return", allow the original .return call to continue in the
1396			// outer generator.
1397			if (context.method !== "return") {
1398				context.method = "next";
1399				context.arg = undefined;
1400			}
1401
1402		} else {
1403			// Re-yield the result returned by the delegate method.
1404			return info;
1405		}
1406
1407		// The delegate iterator is finished, so forget it and continue with
1408		// the outer generator.
1409		context.delegate = null;
1410		return ContinueSentinel;
1411	}
1412
1413	// Define Generator.prototype.{next,throw,return} in terms of the
1414	// unified ._invoke helper method.
1415	defineIteratorMethods(Gp);
1416
1417	Gp[toStringTagSymbol] = "Generator";
1418
1419	// A Generator should always return itself as the iterator object when the
1420	// @@iterator function is called on it. Some browsers' implementations of the
1421	// iterator prototype chain incorrectly implement this, causing the Generator
1422	// object to not be returned from this call. This ensures that doesn't happen.
1423	// See https://github.com/facebook/regenerator/issues/274 for more details.
1424	Gp[iteratorSymbol] = function() {
1425		return this;
1426	};
1427
1428	Gp.toString = function() {
1429		return "[object Generator]";
1430	};
1431
1432	function pushTryEntry(locs) {
1433		var entry = { tryLoc: locs[0] };
1434
1435		if (1 in locs) {
1436			entry.catchLoc = locs[1];
1437		}
1438
1439		if (2 in locs) {
1440			entry.finallyLoc = locs[2];
1441			entry.afterLoc = locs[3];
1442		}
1443
1444		this.tryEntries.push(entry);
1445	}
1446
1447	function resetTryEntry(entry) {
1448		var record = entry.completion || {};
1449		record.type = "normal";
1450		delete record.arg;
1451		entry.completion = record;
1452	}
1453
1454	function Context(tryLocsList) {
1455		// The root entry object (effectively a try statement without a catch
1456		// or a finally block) gives us a place to store values thrown from
1457		// locations where there is no enclosing try statement.
1458		this.tryEntries = [{ tryLoc: "root" }];
1459		tryLocsList.forEach(pushTryEntry, this);
1460		this.reset(true);
1461	}
1462
1463	runtime.keys = function(object) {
1464		var keys = [];
1465		for (var key in object) {
1466			keys.push(key);
1467		}
1468		keys.reverse();
1469
1470		// Rather than returning an object with a next method, we keep
1471		// things simple and return the next function itself.
1472		return function next() {
1473			while (keys.length) {
1474				var key = keys.pop();
1475				if (key in object) {
1476					next.value = key;
1477					next.done = false;
1478					return next;
1479				}
1480			}
1481
1482			// To avoid creating an additional object, we just hang the .value
1483			// and .done properties off the next function object itself. This
1484			// also ensures that the minifier will not anonymize the function.
1485			next.done = true;
1486			return next;
1487		};
1488	};
1489
1490	function values(iterable) {
1491		if (iterable) {
1492			var iteratorMethod = iterable[iteratorSymbol];
1493			if (iteratorMethod) {
1494				return iteratorMethod.call(iterable);
1495			}
1496
1497			if (typeof iterable.next === "function") {
1498				return iterable;
1499			}
1500
1501			if (!isNaN(iterable.length)) {
1502				var i = -1, next = function next() {
1503					while (++i < iterable.length) {
1504						if (hasOwn.call(iterable, i)) {
1505							next.value = iterable[i];
1506							next.done = false;
vendor: 6,037 bytes, lines 1507-1760
1507							return next;
1508						}
1509					}
1510
1511					next.value = undefined;
1512					next.done = true;
1513
1514					return next;
1515				};
1516
1517				return next.next = next;
1518			}
1519		}
1520
1521		// Return an iterator with no values.
1522		return { next: doneResult };
1523	}
1524	runtime.values = values;
1525
1526	function doneResult() {
1527		return { value: undefined, done: true };
1528	}
1529
1530	Context.prototype = {
1531		constructor: Context,
1532
1533		reset: function(skipTempReset) {
1534			this.prev = 0;
1535			this.next = 0;
1536			// Resetting context._sent for legacy support of Babel's
1537			// function.sent implementation.
1538			this.sent = this._sent = undefined;
1539			this.done = false;
1540			this.delegate = null;
1541
1542			this.method = "next";
1543			this.arg = undefined;
1544
1545			this.tryEntries.forEach(resetTryEntry);
1546
1547			if (!skipTempReset) {
1548				for (var name in this) {
1549					// Not sure about the optimal order of these conditions:
1550					if (name.charAt(0) === "t" &&
1551						hasOwn.call(this, name) &&
1552						!isNaN(+name.slice(1))) {
1553						this[name] = undefined;
1554					}
1555				}
1556			}
1557		},
1558
1559		stop: function() {
1560			this.done = true;
1561
1562			var rootEntry = this.tryEntries[0];
1563			var rootRecord = rootEntry.completion;
1564			if (rootRecord.type === "throw") {
1565				throw rootRecord.arg;
1566			}
1567
1568			return this.rval;
1569		},
1570
1571		dispatchException: function(exception) {
1572			if (this.done) {
1573				throw exception;
1574			}
1575
1576			var context = this;
1577			function handle(loc, caught) {
1578				record.type = "throw";
1579				record.arg = exception;
1580				context.next = loc;
1581
1582				if (caught) {
1583					// If the dispatched exception was caught by a catch block,
1584					// then let that catch block handle the exception normally.
1585					context.method = "next";
1586					context.arg = undefined;
1587				}
1588
1589				return !! caught;
1590			}
1591
1592			for (var i = this.tryEntries.length - 1; i >= 0; --i) {
1593				var entry = this.tryEntries[i];
1594				var record = entry.completion;
1595
1596				if (entry.tryLoc === "root") {
1597					// Exception thrown outside of any try block that could handle
1598					// it, so set the completion value of the entire function to
1599					// throw the exception.
1600					return handle("end");
1601				}
1602
1603				if (entry.tryLoc <= this.prev) {
1604					var hasCatch = hasOwn.call(entry, "catchLoc");
1605					var hasFinally = hasOwn.call(entry, "finallyLoc");
1606
1607					if (hasCatch && hasFinally) {
1608						if (this.prev < entry.catchLoc) {
1609							return handle(entry.catchLoc, true);
1610						} else if (this.prev < entry.finallyLoc) {
1611							return handle(entry.finallyLoc);
1612						}
1613
1614					} else if (hasCatch) {
1615						if (this.prev < entry.catchLoc) {
1616							return handle(entry.catchLoc, true);
1617						}
1618
1619					} else if (hasFinally) {
1620						if (this.prev < entry.finallyLoc) {
1621							return handle(entry.finallyLoc);
1622						}
1623
1624					} else {
1625						throw new Error("try statement without catch or finally");
1626					}
1627				}
1628			}
1629		},
1630
1631		abrupt: function(type, arg) {
1632			for (var i = this.tryEntries.length - 1; i >= 0; --i) {
1633				var entry = this.tryEntries[i];
1634				if (entry.tryLoc <= this.prev &&
1635					hasOwn.call(entry, "finallyLoc") &&
1636					this.prev < entry.finallyLoc) {
1637					var finallyEntry = entry;
1638					break;
1639				}
1640			}
1641
1642			if (finallyEntry &&
1643				(type === "break" ||
1644					type === "continue") &&
1645				finallyEntry.tryLoc <= arg &&
1646				arg <= finallyEntry.finallyLoc) {
1647				// Ignore the finally entry if control is not jumping to a
1648				// location outside the try/catch block.
1649				finallyEntry = null;
1650			}
1651
1652			var record = finallyEntry ? finallyEntry.completion : {};
1653			record.type = type;
1654			record.arg = arg;
1655
1656			if (finallyEntry) {
1657				this.method = "next";
1658				this.next = finallyEntry.finallyLoc;
1659				return ContinueSentinel;
1660			}
1661
1662			return this.complete(record);
1663		},
1664
1665		complete: function(record, afterLoc) {
1666			if (record.type === "throw") {
1667				throw record.arg;
1668			}
1669
1670			if (record.type === "break" ||
1671				record.type === "continue") {
1672				this.next = record.arg;
1673			} else if (record.type === "return") {
1674				this.rval = this.arg = record.arg;
1675				this.method = "return";
1676				this.next = "end";
1677			} else if (record.type === "normal" && afterLoc) {
1678				this.next = afterLoc;
1679			}
1680
1681			return ContinueSentinel;
1682		},
1683
1684		finish: function(finallyLoc) {
1685			for (var i = this.tryEntries.length - 1; i >= 0; --i) {
1686				var entry = this.tryEntries[i];
1687				if (entry.finallyLoc === finallyLoc) {
1688					this.complete(entry.completion, entry.afterLoc);
1689					resetTryEntry(entry);
1690					return ContinueSentinel;
1691				}
1692			}
1693		},
1694
1695		"catch": function(tryLoc) {
1696			for (var i = this.tryEntries.length - 1; i >= 0; --i) {
1697				var entry = this.tryEntries[i];
1698				if (entry.tryLoc === tryLoc) {
1699					var record = entry.completion;
1700					if (record.type === "throw") {
1701						var thrown = record.arg;
1702						resetTryEntry(entry);
1703					}
1704					return thrown;
1705				}
1706			}
1707
1708			// The context.catch method must only be called with a location
1709			// argument that corresponds to a known catch block.
1710			throw new Error("illegal catch attempt");
1711		},
1712
1713		delegateYield: function(iterable, resultName, nextLoc) {
1714			this.delegate = {
1715				iterator: values(iterable),
1716				resultName: resultName,
1717				nextLoc: nextLoc
1718			};
1719
1720			if (this.method === "next") {
1721				// Deliberately forget the last sent value so that we don't
1722				// accidentally pass it on to the delegate.
1723				this.arg = undefined;
1724			}
1725
1726			return ContinueSentinel;
1727		}
1728	};
1729})(
1730	// In sloppy mode, unbound `this` refers to the global object, fallback to
1731	// Function constructor if we're in global strict mode. That is sadly a form
1732	// of indirect eval which violates Content Security Policy.
1733	(function() { return this })() || Function("return this")()
1734);
1735
1736if (window._main_polyfill_core)
1737{
1738	console.warn('main.polyfill.core is loaded more than once on this page');
1739}
1740
1741window._main_polyfill_core = true;
1742
1743
1744(function (exports) {
1745	'use strict';
1746
1747	const bxTmp = window.BX;
1748	window.BX = function (node) {
1749		if (window.BX.type.isNotEmptyString(node)) {
1750			return document.getElementById(node);
1751		}
1752		if (window.BX.type.isDomNode(node)) {
1753			return node;
1754		}
1755		if (window.BX.type.isFunction(node)) {
1756			return window.BX.ready(node);
1757		}
1758		return null;
1759	};
1760	if (bxTmp) {
1761		Object.keys(bxTmp).forEach(key => {
1762			window.BX[key] = bxTmp[key];
1763		});
1764	}
1765	exports = window.BX;
1766
1767	function getTag(value) {
1768		return Object.prototype.toString.call(value);
1769	}
1770
1771	const objectCtorString = Function.prototype.toString.call(Object);
1772	class Type {
1773		static isString(value) {
1774			return typeof value === 'string';
1775		}
1776		static isStringFilled(value) {
1777			return Type.isString(value) && value !== '';
1778		}
1779		static isFunction(value) {
1780			return typeof value === 'function';
1781		}
1782		static isObject(value) {
1783			return Boolean(value) && (typeof value === 'object' || typeof value === 'function');
1784		}
1785		static isObjectLike(value) {
1786			return Boolean(value) && typeof value === 'object';
1787		}
1788		static isPlainObject(value) {
1789			if (!Type.isObjectLike(value) || getTag(value) !== '[object Object]') {
1790				return false;
1791			}
1792			const proto = Object.getPrototypeOf(value);
1793			if (proto === null) {
1794				return true;
1795			}
1796			const ctor = proto.hasOwnProperty('constructor') && proto.constructor;
1797			return typeof ctor === 'function' && Function.prototype.toString.call(ctor) === objectCtorString;
1798		}
1799		static isBoolean(value) {
1800			return value === true || value === false;
1801		}
1802		static isNumber(value) {
1803			return !Number.isNaN(value) && typeof value === 'number';
1804		}
1805		static isInteger(value) {
1806			return Type.isNumber(value) && value % 1 === 0;
1807		}
1808		static isFloat(value) {
1809			return Type.isNumber(value) && !Type.isInteger(value);
1810		}
1811		static isNil(value) {
1812			return value === null || value === undefined;
1813		}
1814		static isArray(value) {
1815			return !Type.isNil(value) && Array.isArray(value);
1816		}
1817		static isArrayFilled(value) {
1818			return Type.isArray(value) && value.length > 0;
1819		}
1820		static isArrayLike(value) {
1821			if (Type.isNil(value) || Type.isFunction(value) || !('length' in value)) {
1822				return false;
1823			}
1824			const {
1825				length
1826			} = value;
1827			return Type.isNumber(length) && length > -1 && length <= Number.MAX_SAFE_INTEGER;
1828		}
1829		static isDate(value) {
1830			return Type.isObjectLike(value) && getTag(value) === '[object Date]';
1831		}
1832		static isDomNode(value) {
1833			return Type.isObjectLike(value) && !Type.isPlainObject(value) && 'nodeType' in value;
1834		}
1835		static isElementNode(value) {
1836			return Type.isDomNode(value) && value.nodeType === Node.ELEMENT_NODE;
1837		}
1838		static isEventTargetLike(value) {
1839			return Type.isObjectLike(value) && Type.isFunction(value.addEventListener) && Type.isFunction(value.removeEventListener) && Type.isFunction(value.dispatchEvent);
1840		}
1841		static isTextNode(value) {
1842			return Type.isDomNode(value) && value.nodeType === Node.TEXT_NODE;
1843		}
1844		static isMap(value) {
1845			return Type.isObjectLike(value) && getTag(value) === '[object Map]';
1846		}
1847		static isSet(value) {
1848			return Type.isObjectLike(value) && getTag(value) === '[object Set]';
1849		}
1850		static isWeakMap(value) {
1851			return Type.isObjectLike(value) && getTag(value) === '[object WeakMap]';
1852		}
1853		static isWeakSet(value) {
1854			return Type.isObjectLike(value) && getTag(value) === '[object WeakSet]';
1855		}
1856		static isPrototype(value) {
1857			if (!Type.isObjectLike(value)) {
1858				return false;
1859			}
1860			const ctor = value.constructor;
1861			const proto = Type.isFunction(ctor) ? ctor.prototype : Object.prototype;
1862			return proto === value;
1863		}
1864		static isRegExp(value) {
1865			return Type.isObjectLike(value) && getTag(value) === '[object RegExp]';
1866		}
1867		static isNull(value) {
1868			return value === null;
1869		}
1870		static isUndefined(value) {
1871			return typeof value === 'undefined';
1872		}
1873		static isArrayBuffer(value) {
1874			return Type.isObjectLike(value) && getTag(value) === '[object ArrayBuffer]';
1875		}
1876		static isTypedArray(value) {
1877			const regExpTypedTag = /^\[object (?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)]$/;
1878			return Type.isObjectLike(value) && regExpTypedTag.test(getTag(value));
1879		}
1880		static isBlob(value) {
1881			return Type.isObjectLike(value) && Type.isNumber(value.size) && Type.isString(value.type) && Type.isFunction(value.slice);
1882		}
1883		static isFile(value) {
1884			if (!Type.isBlob(value) || !('name' in value) || !Type.isString(value.name)) {
1885				return false;
1886			}
1887			if ('lastModified' in value && Type.isNumber(value.lastModified)) {
1888				return true;
1889			}
1890			return 'lastModifiedDate' in value && Type.isObjectLike(value.lastModifiedDate);
1891		}
1892		static isFormData(value) {
1893			return value instanceof FormData;
1894		}
1895		static isJsonValue(value) {
1896			return Type.isPlainObject(value) || Type.isString(value) || Type.isNumber(value) || Type.isBoolean(value) || Type.isNull(value) || Type.isArray(value);
1897		}
1898	}
1899
1900	class Reflection {
1901		static getClass(className) {
1902			if (Type.isString(className) && Boolean(className)) {
1903				let classFn = null;
1904				let currentNamespace = window;
1905				const namespaces = className.split('.');
1906				for (const namespace of namespaces) {
1907					if (!currentNamespace[namespace]) {
1908						return null;
1909					}
1910					currentNamespace = currentNamespace[namespace];
1911					classFn = currentNamespace;
1912				}
1913				return classFn;
1914			}
1915			if (Type.isFunction(className)) {
1916				return className;
1917			}
1918			return null;
1919		}
1920		static namespace(namespaceName) {
1921			let parts = namespaceName.split('.');
1922			let parent = window.BX;
1923			if (parts[0] === 'BX') {
1924				parts = parts.slice(1);
1925			}
1926			for (const part of parts) {
1927				if (Type.isUndefined(parent[part])) {
1928					parent[part] = {};
1929				}
1930				parent = parent[part];
1931			}
1932			return parent;
1933		}
1934	}
1935
1936	const reEscape = /["&'<>]/g;
1937	const reUnescape = /&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34);/g;
1938	const escapeEntities = {
1939		'&': '&amp;',
1940		'<': '&lt;',
1941		'>': '&gt;',
1942		"'": '&#39;',
1943		'"': '&quot;'
1944	};
1945	const unescapeEntities = {
1946		'&amp;': '&',
1947		'&#38;': '&',
1948		'&lt;': '<',
1949		'&#60;': '<',
1950		'&gt;': '>',
1951		'&#62;': '>',
1952		'&apos;': "'",
1953		'&#39;': "'",
1954		'&quot;': '"',
1955		'&#34;': '"'
1956	};
1957	class Text {
1958		static encode(value) {
1959			if (Type.isString(value)) {
1960				return value.replaceAll(reEscape, item => escapeEntities[item]);
1961			}
1962			return value;
1963		}
1964		static decode(value) {
1965			if (Type.isString(value)) {
1966				return value.replaceAll(reUnescape, item => unescapeEntities[item]);
1967			}
1968			return value;
1969		}
1970		static getRandom(length = 8) {
1971			return Array.from({
1972				length
1973			}, () => Math.trunc(Math.random() * 36).toString(36)).join('');
1974		}
1975		static toNumber(value) {
1976			const parsedValue = Number.parseFloat(String(value));
1977			if (Type.isNumber(parsedValue)) {
1978				return parsedValue;
1979			}
1980			return 0;
1981		}
1982		static toInteger(value) {
1983			return Text.toNumber(Number.parseInt(String(value), 10));
1984		}
1985		static toBoolean(value, trueValues = []) {
1986			const transformedValue = Type.isString(value) ? value.toLowerCase() : value;
1987			const truthyValues = ['true', 'y', '1', 1, true, ...trueValues];
1988			return truthyValues.includes(transformedValue);
1989		}
1990		static toCamelCase(str) {
1991			if (!Type.isStringFilled(str)) {
1992				return str;
1993			}
1994			const regex = /[\s_-]+(.)?/g;
1995			if (!regex.test(str)) {
1996				return /^[A-Z]+$/.test(str) ? str.toLowerCase() : str[0].toLowerCase() + str.slice(1);
1997			}
1998			const result = str.toLowerCase().replaceAll(regex, (match, letter) => {
1999				return letter ? letter.toUpperCase() : '';
2000			});
2001			return result[0].toLowerCase() + result.slice(1);
2002		}
2003		static toPascalCase(str) {
2004			if (!Type.isStringFilled(str)) {
2005				return str;
2006			}
2007			return this.capitalize(this.toCamelCase(str));
2008		}
2009		static toKebabCase(str) {
2010			if (!Type.isStringFilled(str)) {
2011				return str;
2012			}
2013			const matches = str.match(/[A-Z]{2,}(?=[A-Z][a-z]+\d*|\b)|[A-Z]?[a-z]+\d*|[A-Z]|\d+/g);
2014			if (!matches) {
2015				return str;
2016			}
2017			return matches.map(x => x.toLowerCase()).join('-');
2018		}
2019		static capitalize(str) {
2020			if (!Type.isStringFilled(str)) {
2021				return str;
2022			}
2023			return str[0].toUpperCase() + str.slice(1);
2024		}
2025	}
2026
2027	const aliases = {
2028		mousewheel: ['DOMMouseScroll'],
2029		bxchange: ['change', 'cut', 'paste', 'drop', 'keyup'],
2030		animationend: ['animationend', 'oAnimationEnd', 'webkitAnimationEnd', 'MSAnimationEnd'],
2031		transitionend: ['webkitTransitionEnd', 'otransitionend', 'oTransitionEnd', 'msTransitionEnd', 'transitionend'],
2032		fullscreenchange: ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange', 'MSFullscreenChange'],
2033		fullscreenerror: ['fullscreenerror', 'webkitfullscreenerror', 'mozfullscreenerror', 'MSFullscreenError']
2034	};
2035
2036	class Registry {
2037		registry = new WeakMap();
2038		set(target, event, listener) {
2039			if (!Type.isEventTargetLike(target)) {
2040				return;
2041			}
2042			const events = this.get(target);
2043			if (!Type.isSet(events[event])) {
2044				events[event] = new Set();
2045			}
2046			events[event].add(listener);
2047			this.registry.set(target, events);
2048		}
2049		get(target) {
2050			return this.registry.get(target) || {};
2051		}
2052		has(target, event, listener) {
2053			if (event && listener) {
2054				const events = this.registry.get(target);
2055				return this.registry.has(target) && Boolean(events && events[event]?.has(listener));
2056			}
2057			return this.registry.has(target);
2058		}
2059		delete(target, event, listener) {
2060			if (!Type.isEventTargetLike(target)) {
2061				return;
2062			}
2063			if (Type.isString(event) && Type.isFunction(listener)) {
2064				const events = this.registry.get(target);
2065				if (Type.isPlainObject(events) && Type.isSet(events[event])) {
2066					events[event].delete(listener);
2067				}
2068				return;
2069			}
2070			if (Type.isString(event)) {
2071				const events = this.registry.get(target);
2072				if (Type.isPlainObject(events) && Type.isSet(events[event])) {
2073					events[event] = new Set();
2074				}
2075				return;
2076			}
2077			this.registry.delete(target);
2078		}
2079	}
2080	var registry = new Registry();
2081
2082	function isOptionSupported(name) {
2083		let isSupported = false;
2084		try {
2085			const options = Object.defineProperty({}, name, {
2086				get() {
2087					isSupported = true;
2088				}
2089			});
2090			window.addEventListener('test', null, options);
2091		} catch {
2092		}
2093		return isSupported;
2094	}
2095	function fetchSupportedListenerOptions(options) {
2096		if (!Type.isPlainObject(options)) {
2097			return options;
2098		}
2099		return Object.keys(options).reduce((acc, name) => {
2100			if (isOptionSupported(name)) {
2101				acc[name] = options[name];
2102			}
2103			return acc;
2104		}, {});
2105	}
2106
2107	function bind$1(target, eventName, handler, options) {
2108		if (!Type.isEventTargetLike(target) || handler === null) {
2109			return;
2110		}
2111		const listenerOptions = fetchSupportedListenerOptions(options);
2112		if (eventName in aliases) {
2113			aliases[eventName].forEach(key => {
2114				target.addEventListener(key, handler, listenerOptions);
2115				registry.set(target, eventName, handler);
2116			});
2117			return;
2118		}
2119		target.addEventListener(eventName, handler, listenerOptions);
2120		registry.set(target, eventName, handler);
2121	}
2122
2123	function unbind$1(target, eventName, handler, options) {
2124		if (!Type.isEventTargetLike(target) || handler === null) {
2125			return;
2126		}
2127		const listenerOptions = fetchSupportedListenerOptions(options);
2128		if (eventName in aliases) {
2129			aliases[eventName].forEach(key => {
2130				target.removeEventListener(key, handler, listenerOptions);
2131				registry.delete(target, key, handler);
2132			});
2133			return;
2134		}
2135		target.removeEventListener(eventName, handler, listenerOptions);
2136		registry.delete(target, eventName, handler);
2137	}
2138
2139	function unbindAll$1(target, eventName) {
2140		const events = registry.get(target);
2141		Object.keys(events).forEach(currentEvent => {
2142			events[currentEvent].forEach(handler => {
2143				if (!Type.isString(eventName) || eventName === currentEvent) {
2144					unbind$1(target, currentEvent, handler);
2145				}
2146			});
2147		});
2148	}
2149
2150	function bindOnce$1(target, eventName, handler, options) {
2151		if (handler === null) {
2152			return;
2153		}
2154		const once = function once(event) {
2155			unbind$1(target, eventName, once, options);
2156			if (Type.isFunction(handler)) {
2157				handler(event);
2158			} else if (Type.isObject(handler) && Type.isFunction(handler.handleEvent)) {
2159				handler.handleEvent(event);
2160			}
2161		};
2162		bind$1(target, eventName, once, options);
2163	}
2164
2165	let debugState = true;
2166	function enableDebug() {
2167		debugState = true;
2168	}
2169	function disableDebug() {
2170		debugState = false;
2171	}
2172	function isDebugEnabled() {
2173		return debugState;
2174	}
2175	function debug$1(...args) {
2176		if (!isDebugEnabled() || !Type.isObject(window.console)) {
2177			return;
2178		}
2179		let limit = 5;
2180		if (typeof args[args.length - 1] === 'number') {
2181			limit = args.pop();
2182		}
2183		if (Type.isFunction(window.console.log)) {
2184			window.console.log('BX.debug:', ...args);
2185			if (args[0] instanceof Error && args[0].stack) {
2186				const errorStack = args[0].stack.split('\n').slice(0, limit).join('\n');
2187				window.console.log(`BX.debug error stack trace:\n${errorStack}`);
2188			}
2189		}
2190		const stack = new Error('debug').stack;
2191		if (stack && Type.isFunction(window.console.log)) {
2192			const formattedStack = stack.split('\n').slice(1, limit + 1).join('\n');
2193			window.console.log(`BX.debug trace:\n${formattedStack}`);
2194		}
2195	}
2196
2197	var debugNs = Object.freeze({
2198		__proto__: null,
2199		get debugState () { return debugState; },
2200		default: debug$1,
2201		disableDebug: disableDebug,
2202		enableDebug: enableDebug,
2203		isDebugEnabled: isDebugEnabled
2204	});
2205
2206	const extensionsStorage = new Map();
2207
2208	const ajaxController = 'main.bitrix.main.controller.loadext.getextensions';
2209	function loadAssets(options) {
2210		return new Promise((resolve, reject) => {
2211			const getParameters = {
2212				e: (options?.extension || []).join(',')
2213			};
2214			BX.ajax.runAction(ajaxController, {
2215				data: options,
2216				getParameters
2217			}).then(result => {
2218				resolve(result?.data);
2219			}).catch(err => {
2220				reject(err);
2221			});
2222		});
2223	}
2224
2225	function fetchInlineScripts(acc, item) {
2226		if (item.isInternal) {
2227			acc.push(item.JS);
2228		}
2229		return acc;
2230	}
2231	function fetchExternalScripts(acc, item) {
2232		if (!item.isInternal) {
2233			acc.push(item.JS);
2234		}
2235		return acc;
2236	}
2237	function fetchExternalStyles(acc, item) {
2238		if (Type.isString(item) && item !== '') {
2239			acc.push(item);
2240		}
2241		return acc;
2242	}
2243	function fetchExtensionSettings(html) {
2244		if (Type.isStringFilled(html)) {
2245			const scripts = html.match(/<script type="extension\/settings" \b[^>]*>([\S\s]*?)<\/script>/g);
2246			if (Type.isArrayFilled(scripts)) {
2247				return scripts.map(script => {
2248					const [, extension] = script.match(/data-extension="(.[\d._a-z-]+)"/);
2249					return {
2250						extension,
2251						script
2252					};
2253				});
2254			}
2255		}
2256		return [];
2257	}
2258	function loadAll(items) {
2259		const itemsList = Type.isArray(items) ? items : [items];
2260		if (itemsList.length === 0) {
2261			return Promise.resolve();
2262		}
2263		return new Promise((resolve, reject) => {
2264			BX.load(itemsList, resolve, document, reject);
2265		});
2266	}
2267
2268	function parseExtensionHtml(html) {
2269		const result = window.BX.processHTML(html);
2270		const inlinePreScripts = [];
2271		const inlineAfterScripts = [];
2272		result.SCRIPT.reduce((accumulator, element) => {
2273			return fetchInlineScripts(accumulator, element);
2274		}
2274, []).forEach(script => {
2275			if (script.startsWith('BX.Runtime.registerExtension')) {
2276				inlineAfterScripts.push(script);
2277			} else {
2278				inlinePreScripts.push(script);
2279			}
2280		});
2281		return {
2282			inlinePreScripts,
2283			inlineAfterScripts,
2284			externalScripts: result.SCRIPT.reduce((accumulator, element) => {
2285				return fetchExternalScripts(accumulator, element);
2286			}, []),
2287			externalStyles: result.STYLE.reduce((accumulator, element) => {
2288				return fetchExternalStyles(accumulator, element);
2289			}, []),
2290			settingsScripts: fetchExtensionSettings(result.HTML)
2291		};
2292	}
2293
2294	function waitOnline() {
2295		return new Promise(resolve => {
2296			Event.bindOnce(window, 'online', () => resolve());
2297		});
2298	}
2299
2300	const TIMEOUTS = [1000, 3000, 5000];
2301	async function tryLoad(extensions, callback) {
2302		for (let i = 0; i <= TIMEOUTS.length; i++) {
2303			try {
2304				return await callback();
2305			} catch {
2306				if (navigator.onLine === false) {
2307					console.warn(`Wait online for load ${extensions.join(', ')}`);
2308					await waitOnline();
2309					i--;
2310					continue;
2311				}
2312				if (i === TIMEOUTS.length) {
2313					throw new Error(`${extensions.join(', ')} loading failed...`);
2314				}
2315				const delay = TIMEOUTS[i];
2316				const displayRetryCount = i + 1;
2317				console.warn(`Retry load #${displayRetryCount}: ${extensions.join(', ')}`);
2318				await new Promise(resolve => {
2319					setTimeout(resolve, delay);
2320				});
2321			}
2322		}
2323		throw new Error('Unexpected end of retry loop');
2324	}
2325
2326	async function processExtensions(map) {
2327		const loadableExtensions = [...map.keys()];
2328		const rawAssets = (await tryLoad(loadableExtensions, () => loadAssets({
2329			extension: loadableExtensions
2330		}))) ?? [];
2331		rawAssets.forEach(rawAsset => {
2332			const preparedHtml = rawAsset.html ?? '';
2333			const extensionAssets = parseExtensionHtml(preparedHtml);
2334			extensionAssets.settingsScripts.forEach(({
2335				script
2336			}) => {
2337				document.body.insertAdjacentHTML('beforeend', script);
2338			});
2339			extensionAssets.inlinePreScripts.forEach(script => {
2340				window.BX.evalGlobal(script);
2341			});
2342			const loadableExtensionEntry = map.get(rawAsset.extension);
2343			void Promise.all([tryLoad(loadableExtensions, () => loadAll(extensionAssets.externalScripts)), tryLoad(loadableExtensions, () => loadAll(extensionAssets.externalStyles))]).then(() => {
2344				extensionAssets.inlineAfterScripts.forEach(script => {
2345					window.BX.evalGlobal(script);
2346				});
2347				const namespace = rawAsset?.config?.namespace ?? 'window';
2348				loadableExtensionEntry.resolve(namespace);
2349			}).catch(error => {
2350				loadableExtensionEntry.reject(error);
2351			});
2352		});
2353	}
2354
2355	const queue = new Map();
2356	let timerId = null;
2357	async function loadExtension(...name) {
2358		if (Type.isNumber(timerId)) {
2359			clearTimeout(timerId);
2360		}
2361		const requestedNames = name.flat();
2362		const extensionsToLoad = requestedNames.filter(extensionName => {
2363			return !extensionsStorage.has(extensionName);
2364		});
2365		extensionsToLoad.forEach(extensionName => {
2366			let resolve = null;
2367			let reject = null;
2368			const loadableExtensionEntry = {
2369				promise: new Promise((sourceResolve, sourceReject) => {
2370					resolve = sourceResolve;
2371					reject = sourceReject;
2372				}),
2373				resolve,
2374				reject
2375			};
2376			extensionsStorage.set(extensionName, loadableExtensionEntry.promise);
2377			queue.set(extensionName, loadableExtensionEntry);
2378		});
2379		timerId = setTimeout(() => {
2380			if (queue.size > 0) {
2381				void processExtensions(new Map(queue.entries()));
2382				queue.clear();
2383			}
2384		});
2385		const namespaces = await Promise.all(requestedNames.map(extensionName => {
2386			return extensionsStorage.get(extensionName);
2387		}));
2388		return namespaces.reduce((acc, namespace) => {
2389			return {
2390				...acc,
2391				...Reflection.getClass(namespace)
2392			};
2393		}, {});
2394	}
2395
2396	const cloneableTags = new Set(['[object Object]', '[object Array]', '[object RegExp]', '[object Arguments]', '[object Date]', '[object Error]', '[object Map]', '[object Set]', '[object ArrayBuffer]', '[object DataView]', '[object Float32Array]', '[object Float64Array]', '[object Int8Array]', '[object Int16Array]', '[object Int32Array]', '[object Uint8Array]', '[object Uint16Array]', '[object Uint32Array]', '[object Uint8ClampedArray]']);
2397	function isCloneable(value) {
2398		const isCloneableValue = Type.isObjectLike(value) && cloneableTags.has(getTag(value));
2399		return isCloneableValue || Type.isDomNode(value);
2400	}
2401	function internalClone(value, map) {
2402		if (map.has(value)) {
2403			return map.get(value);
2404		}
2405		if (isCloneable(value)) {
2406			if (Type.isArray(value)) {
2407				const cloned = [...value];
2408				map.set(value, cloned);
2409				value.forEach((item, index) => {
2410					cloned[index] = internalClone(item, map);
2411				});
2412				return map.get(value);
2413			}
2414			if (Type.isDomNode(value)) {
2415				return value.cloneNode(true);
2416			}
2417			if (Type.isMap(value)) {
2418				const result = new Map();
2419				map.set(value, result);
2420				value.forEach((item, key) => {
2421					result.set(internalClone(key, map), internalClone(item, map));
2422				});
2423				return result;
2424			}
2425			if (Type.isSet(value)) {
2426				const result = new Set();
2427				map.set(value, result);
2428				value.forEach(item => {
2429					result.add(internalClone(item, map));
2430				});
2431				return result;
2432			}
2433			if (Type.isDate(value)) {
2434				return new Date(value);
2435			}
2436			if (Type.isRegExp(value)) {
2437				const regExpFlags = /\w*$/;
2438				const flags = regExpFlags.exec(value);
2439				let result = new RegExp(value.source);
2440				if (flags && Type.isArray(flags)) {
2441					result = new RegExp(value.source, flags[0]);
2442				}
2443				result.lastIndex = value.lastIndex;
2444				return result;
2445			}
2446			const proto = Object.getPrototypeOf(value);
2447			const result = Object.assign(Object.create(proto), value);
2448			map.set(value, result);
2449			Object.keys(value).forEach(key => {
2450				result[key] = internalClone(value[key], map);
2451			});
2452			return result;
2453		}
2454		return value;
2455	}
2456	function clone$1(value) {
2457		return internalClone(value, new WeakMap());
2458	}
2459
2460	function merge(current, target) {
2461		return Object.entries(target).reduce((acc, [key, value]) => {
2462			if (!Type.isDomNode(acc[key]) && Type.isObjectLike(acc[key]) && Type.isObjectLike(value)) {
2463				acc[key] = merge(acc[key], value);
2464				return acc;
2465			}
2466			acc[key] = value;
2467			return acc;
2468		}, current);
2469	}
2470
2471	function createComparator(fields, orders = []) {
2472		return (a, b) => {
2473			const field = fields[0];
2474			const order = orders[0] || 'asc';
2475			if (Type.isUndefined(field)) {
2476				return 0;
2477			}
2478			let valueA = a[field];
2479			let valueB = b[field];
2480			if (Type.isString(valueA) && Type.isString(valueB)) {
2481				valueA = valueA.toLowerCase();
2482				valueB = valueB.toLowerCase();
2483			}
2484			if (valueA < valueB) {
2485				return order === 'asc' ? -1 : 1;
2486			}
2487			if (valueA > valueB) {
2488				return order === 'asc' ? 1 : -1;
2489			}
2490			return createComparator(fields.slice(1), orders.slice(1))(a, b);
2491		};
2492	}
2493
2494	function registerExtension(options) {
2495		if (!extensionsStorage.has(options.name)) {
2496			const namespace = options?.namespace ?? 'window';
2497			extensionsStorage.set(options.name, Promise.resolve(namespace));
2498		}
2499	}
2500
2501	class Runtime {
2502		static debug = debug$1;
2503		static loadExtension = loadExtension;
2504		static registerExtension = registerExtension;
2505		static clone = clone$1;
2506		static debounce(func, wait = 0, context = null) {
2507			let timeoutId = null;
2508			return function debounced(...args) {
2509				if (Type.isNumber(timeoutId)) {
2510					clearTimeout(timeoutId);
2511				}
2512				timeoutId = setTimeout(() => {
2513					func.apply(context || this, args);
2514				}, wait);
2515			};
2516		}
2517		static throttle(func, wait = 0, context = null) {
2518			let timer = null;
2519			let invoke = false;
2520			return function wrapper(...args) {
2521				invoke = true;
2522				if (!timer) {
2523					const q = function q() {
2524						if (invoke) {
2525							func.apply(context || this, args);
2526							invoke = false;
2527							timer = setTimeout(q, wait);
2528						} else {
2529							timer = null;
2530						}
2531					};
2532					q();
2533				}
2534			};
2535		}
2536		static html(node, html, params = {}) {
2537			if (Type.isNil(html) && Type.isDomNode(node)) {
2538				return node.innerHTML;
2539			}
2540			const parsedHtml = BX.processHTML(html);
2541			const externalCss = parsedHtml.STYLE.reduce((acc, item) => fetchExternalStyles(acc, item), []);
2542			const externalJs = parsedHtml.SCRIPT.reduce((acc, item) => fetchExternalScripts(acc, item), []);
2543			const inlineJs = parsedHtml.SCRIPT.reduce((acc, item) => fetchInlineScripts(acc, item), []);
2544			if (Type.isDomNode(node) && (params.htmlFirst || externalJs.length === 0 && externalCss.length === 0)) {
2545				if (params.useAdjacentHTML) {
2546					node.insertAdjacentHTML('beforeend', parsedHtml.HTML);
2547				} else {
2548					node.innerHTML = parsedHtml.HTML;
2549				}
2550			}
2551			return Promise.all([loadAll(externalJs), loadAll(externalCss)]).then(() => {
2552				if (Type.isDomNode(node) && (externalJs.length > 0 || externalCss.length > 0)) {
2553					if (params.useAdjacentHTML) {
2554						node.insertAdjacentHTML('beforeend', parsedHtml.HTML);
2555					} else {
2556						node.innerHTML = parsedHtml.HTML;
2557					}
2558				}
2559				inlineJs.forEach(script => BX.evalGlobal(script));
2560				if (Type.isFunction(params.callback)) {
2561					params.callback();
2562				}
2563			});
2564		}
2565		static merge(...targets) {
2566			if (Type.isArray(targets[0])) {
2567				targets.unshift([]);
2568			} else if (Type.isObject(targets[0])) {
2569				targets.unshift({});
2570			}
2571			return targets.reduce((acc, item) => {
2572				return merge(acc, item);
2573			}, targets[0]);
2574		}
2575		static orderBy(collection, fields = [], orders = []) {
2576			const comparator = createComparator(fields, orders);
2577			return Object.values(collection).sort(comparator);
2578		}
2579		static destroy(target, errorMessage = 'Object is destroyed') {
2580			if (Type.isObject(target)) {
2581				const onPropertyAccess = () => {
2582					throw new Error(errorMessage);
2583				};
2584				const ownProperties = Object.keys(target);
2585				const prototypeProperties = (() => {
2586					const targetPrototype = Object.getPrototypeOf(target);
2587					if (Type.isObject(targetPrototype)) {
2588						return Object.getOwnPropertyNames(targetPrototype);
2589					}
2590					return [];
2591				})();
2592				const uniquePropertiesList = [...new Set([...ownProperties, ...prototypeProperties])];
2593				uniquePropertiesList.filter(name => {
2594					const descriptor = Object.getOwnPropertyDescriptor(target, name);
2595					return !/__(.+)__/.test(name) && (!Type.isObject(descriptor) || descriptor.configurable === true);
2596				}
2596).forEach(name => {
2597					Object.defineProperty(target, name, {
2598						get: onPropertyAccess,
2599						set: onPropertyAccess,
2600						configurable: false
2601					});
2602				});
2603				Object.setPrototypeOf(target, null);
2604			}
2605		}
2606	}
2607
2608	const isError = Symbol.for('BX.BaseError.isError');
2609	class BaseError {
2610		[isError];
2611		message;
2612		code;
2613		customData;
2614		constructor(message, code, customData) {
2615			this[isError] = true;
2616			this.message = '';
2617			this.code = null;
2618			this.customData = null;
2619			this.setMessage(message);
2620			this.setCode(code);
2621			this.setCustomData(customData);
2622		}
2623		getMessage() {
2624			return this.message;
2625		}
2626		setMessage(message) {
2627			if (Type.isString(message)) {
2628				this.message = message;
2629			}
2630			return this;
2631		}
2632		getCode() {
2633			return this.code;
2634		}
2635		setCode(code) {
2636			if (Type.isStringFilled(code) || code === null) {
2637				this.code = code;
2638			}
2639			return this;
2640		}
2641		getCustomData() {
2642			return this.customData;
2643		}
2644		setCustomData(customData) {
2645			if (!Type.isUndefined(customData)) {
2646				this.customData = customData;
2647			}
2648			return this;
2649		}
2650		toString() {
2651			const code = this.getCode();
2652			const message = this.getMessage();
2653			if (!Type.isStringFilled(code) && !Type.isStringFilled(message)) {
2654				return '';
2655			}
2656			if (!Type.isStringFilled(code)) {
2657				return `Error: ${message}`;
2658			}
2659			if (!Type.isStringFilled(message)) {
2660				return code;
2661			}
2662			return `${code}: ${message}`;
2663		}
2664		static isError(error) {
2665			return Type.isObject(error) && error[isError] === true;
2666		}
2667	}
2668
2669	let BaseEvent = function () {
2670		function BaseEvent(options = {
2671			data: {}
2672		}) {
2673			babelHelpers.classCallCheck(this, BaseEvent);
2674			babelHelpers.defineProperty(this, "type", '');
2675			babelHelpers.defineProperty(this, "data", null);
2676			babelHelpers.defineProperty(this, "target", null);
2677			babelHelpers.defineProperty(this, "compatData", null);
2678			babelHelpers.defineProperty(this, "defaultPrevented", false);
2679			babelHelpers.defineProperty(this, "immediatePropagationStopped", false);
2680			babelHelpers.defineProperty(this, "errors", []);
2681			this.setData(options.data);
2682			this.setCompatData(options.compatData);
2683		}
2684		return babelHelpers.createClass(BaseEvent, [{
2685			key: "getType",
2686			value:
2687			function getType() {
2688				return this.type;
2689			}
2690		}, {
2691			key: "setType",
2692			value: function setType(type) {
2693				if (Type.isStringFilled(type)) {
2694					this.type = type;
2695				}
2696				return this;
2697			}
2698		}, {
2699			key: "getData",
2700			value: function getData() {
2701				return this.data;
2702			}
2703		}, {
2704			key: "setData",
2705			value: function setData(data) {
2706				if (!Type.isUndefined(data)) {
2707					this.data = data;
2708				}
2709				return this;
2710			}
2711		}, {
2712			key: "getCompatData",
2713			value: function getCompatData() {
2714				return this.compatData;
2715			}
2716		}, {
2717			key: "setCompatData",
2718			value: function setCompatData(data) {
2719				if (Type.isArrayLike(data)) {
2720					this.compatData = data;
2721				}
2722				return this;
2723			}
2724		}, {
2725			key: "setTarget",
2726			value: function setTarget(target) {
2727				this.target = target;
2728				return this;
2729			}
2730		}, {
2731			key: "getTarget",
2732			value: function getTarget() {
2733				return this.target;
2734			}
2735		}, {
2736			key: "getErrors",
2737			value: function getErrors() {
2738				return this.errors;
2739			}
2740		}, {
2741			key: "setError",
2742			value: function setError(error) {
2743				if (BaseError.isError(error)) {
2744					this.errors.push(error);
2745				}
2746			}
2747		}, {
2748			key: "preventDefault",
2749			value: function preventDefault() {
2750				this.defaultPrevented = true;
2751			}
2752		}, {
2753			key: "isDefaultPrevented",
2754			value: function isDefaultPrevented() {
2755				return this.defaultPrevented;
2756			}
2757		}, {
2758			key: "stopImmediatePropagation",
2759			value: function stopImmediatePropagation() {
2760				this.immediatePropagationStopped = true;
2761			}
2762		}, {
2763			key: "isImmediatePropagationStopped",
2764			value: function isImmediatePropagationStopped() {
2765				return this.immediatePropagationStopped;
2766			}
2767		}], [{
2768			key: "create",
2769			value: function create(options) {
2770				return new this(options);
2771			}
2772		}]);
2773	}();
2774
2775	class EventStore {
2776		defaultMaxListeners;
2777		eventStore = new WeakMap();
2778		constructor(options = {}) {
2779			this.defaultMaxListeners = Type.isNumber(options.defaultMaxListeners) ? options.defaultMaxListeners : 10;
2780		}
2781		add(target, options = {}) {
2782			const record = this.getRecordScheme();
2783			if (Type.isNumber(options.maxListeners)) {
2784				record.maxListeners = options.maxListeners;
2785			}
2786			this.eventStore.set(target, record);
2787			return record;
2788		}
2789		get(target) {
2790			return this.eventStore.get(target);
2791		}
2792		getOrAdd(target, options = {}) {
2793			return this.get(target) || this.add(target, options);
2794		}
2795		delete(context) {
2796			this.eventStore.delete(context);
2797		}
2798		getRecordScheme() {
2799			return {
2800				eventsMap: new Map(),
2801				onceMap: new Map(),
2802				maxListeners: this.getDefaultMaxListeners(),
2803				eventsMaxListeners: new Map()
2804			};
2805		}
2806		getDefaultMaxListeners() {
2807			return this.defaultMaxListeners;
2808		}
2809	}
2810
2811	class WarningStore {
2812		warnings = new Map();
2813		printDelayed;
2814		constructor() {
2815			this.printDelayed = Runtime.debounce(this.print.bind(this), 500);
2816		}
2817		add(target, eventName, listeners) {
2818			let contextWarnings = this.warnings.get(target);
2819			if (!contextWarnings) {
2820				contextWarnings = Object.create(null);
2821				this.warnings.set(target, contextWarnings);
2822			}
2823			if (!contextWarnings[eventName]) {
2824				contextWarnings[eventName] = {};
2825			}
2826			contextWarnings[eventName].size = listeners.size;
2827			if (!Type.isArray(contextWarnings[eventName].errors)) {
2828				contextWarnings[eventName].errors = [];
2829			}
2830			contextWarnings[eventName].errors.push(new Error('EventEmitter warning'));
2831		}
2832		print() {
2833			this.warnings.forEach(warnings => {
2834				for (const eventName of Object.keys(warnings)) {
2835					console.groupCollapsed('Possible BX.Event.EventEmitter memory leak detected. ' + `${warnings[eventName].size} "${eventName}" listeners added. ` + 'Use emitter.setMaxListeners() to increase limit.');
2836					console.dir(warnings[eventName].errors);
2837					console.groupEnd();
2838				}
2839			});
2840			this.clear();
2841		}
2842		clear() {
2843			this.warnings.clear();
2844		}
2845	}
2846
2847	const eventStore = new EventStore({
2848		defaultMaxListeners: 10
2849	});
2850	const warningStore = new WarningStore();
2851	const aliasStore = new Map();
2852	const globalTarget = {
2853		GLOBAL_TARGET: 'GLOBAL_TARGET'
2854	};
2855	eventStore.add(globalTarget, {
2856		maxListeners: 25
2857	});
2858	const isEmitterProperty = Symbol.for('BX.Event.EventEmitter.isEmitter');
2859	const namespaceProperty = Symbol('namespaceProperty');
2860	const targetProperty = Symbol('targetProperty');
2861	let EventEmitter = function () {
2862		function EventEmitter(...args) {
2863			babelHelpers.classCallCheck(this, EventEmitter);
2864			this[targetProperty] = null;
2865			this[namespaceProperty] = null;
2866			this[isEmitterProperty] = true;
2867			let target = this;
2868			if (Object.getPrototypeOf(this) === EventEmitter.prototype && args.length > 0) {
2869				if (!Type.isObject(args[0])) {
2870					throw new TypeError('The "target" argument must be an object.');
2871				}
2872				target = args[0];
2873				this.setEventNamespace(args[1]);
2874			}
2875			this[targetProperty] = target;
2876		}
2877		return babelHelpers.createClass(EventEmitter, [{
2878			key: "setEventNamespace",
2879			value: function setEventNamespace(namespace) {
2880				if (Type.isStringFilled(namespace)) {
2881					this[namespaceProperty] = namespace;
2882				}
2883			}
2884		}, {
2885			key: "getEventNamespace",
2886			value: function getEventNamespace() {
2887				return this[namespaceProperty];
2888			}
2889		}, {
2890			key: "subscribe",
2891			value:
2892			function subscribe(eventName, listener) {
2893				EventEmitter.subscribe(this, eventName, listener);
2894				return this;
2895			}
2896		}, {
2897			key: "subscribeFromOptions",
2898			value: function subscribeFromOptions(options, aliases, compatMode) {
2899				if (Type.isArrayFilled(options)) {
2900					options.forEach(events => {
2901						this.subscribeFromOptions(events);
2902					});
2903					return;
2904				}
2905				if (!Type.isPlainObject(options)) {
2906					return;
2907				}
2908				const normalizedAliases = Type.isPlainObject(aliases) ? EventEmitter.normalizeAliases(aliases) : {};
2909				const optionsRecord = options;
2910				Object.keys(optionsRecord).forEach(eventName => {
2911					const listener = EventEmitter.normalizeListener(optionsRecord[eventName]);
2912					eventName = EventEmitter.normalizeEventName(eventName);
2913					if (normalizedAliases[eventName]) {
2914						const {
2915							eventName: actualName
2916						} = normalizedAliases[eventName];
2917						EventEmitter.subscribe(this, actualName, listener, {
2918							compatMode: compatMode !== false
2919						});
2920					} else {
2921						EventEmitter.subscribe(this, eventName, listener, {
2922							compatMode: compatMode === true
2923						});
2924					}
2925				});
2926			}
2927		}, {
2928			key: "subscribeOnce",
2929			value:
2930			function subscribeOnce(eventName, listener) {
2931				EventEmitter.subscribeOnce(this, eventName, listener);
2932				return this;
2933			}
2934		}, {
2935			key: "unsubscribe",
2936			value:
2937			function unsubscribe(eventName, listener) {
2938				EventEmitter.unsubscribe(this, eventName, listener);
2939				return this;
2940			}
2941		}, {
2942			key: "unsubscribeAll",
2943			value:
2944			function unsubscribeAll(eventName) {
2945				EventEmitter.unsubscribeAll(this, eventName);
2946			}
2947		}, {
2948			key: "emit",
2949			value:
2950			function emit(eventName, event) {
2951				if (this.getEventNamespace() === null) {
2952					console.warn('The instance of BX.Event.EventEmitter is supposed to have an event namespace. ' + 'Use emitter.setEventNamespace() to make events more unique.');
2953				}
2954				EventEmitter.emit(this, eventName, event);
2955				return this;
2956			}
2957		}, {
2958			key: "emitAsync",
2959			value:
2960			function emitAsync(eventName, event) {
2961				if (this.getEventNamespace() === null) {
2962					console.warn('The instance of BX.Event.EventEmitter is supposed to have an event namespace. ' + 'Use emitter.setEventNamespace() to make events more unique.');
2963				}
2964				return EventEmitter.emitAsync(this, eventName, event);
2965			}
2966		}, {
2967			key: "setMaxListeners",
2968			value:
2969			function setMaxListeners(...args) {
2970				EventEmitter.setMaxListeners(this, ...args);
2971				return this;
2972			}
2973		}, {
2974			key: "getMaxListeners",
2975			value:
2976			function getMaxListeners(eventName) {
2977				return EventEmitter.getMaxListeners(this, eventName);
2978			}
2979		}, {
2980			key: "incrementMaxListeners",
2981			value:
2982			function incrementMaxListeners(...args) {
2983				return EventEmitter.incrementMaxListeners(this, ...args);
2984			}
2985		}, {
2986			key: "decrementMaxListeners",
2987			value:
2988			function decrementMaxListeners(...args) {
2989				return EventEmitter.decrementMaxListeners(this, ...args);
2990			}
2991		}, {
2992			key: "getListeners",
2993			value:
2994			function getListeners(eventName) {
2995				return EventEmitter.getListeners(this, eventName);
2996			}
2997		}, {
2998			key: "getFullEventName",
2999			value: function getFullEventName(eventName) {
3000				if (!Type.isStringFilled(eventName)) {
3001					throw new TypeError('The "eventName" argument must be a string.');
3002				}
3003				return EventEmitter.makeFullEventName(this.getEventNamespace(), eventName);
3004			}
3005		}], [{
3006			key: "makeObservable",
3007			value: function makeObservable(target, namespace) {
3008				if (!Type.isObject(target)) {
3009					throw new TypeError('The "target" argument must be an object.');
3010				}
3011				if (!Type.isStringFilled(namespace)) {
3012					throw new TypeError('The "namespace" must be an non-empty string.');
3013				}
3014				if (EventEmitter.isEventEmitter(target)) {
3015					throw new TypeError('The "target" is an event emitter already.');
3016				}
3017				const targetProto = Object.getPrototypeOf(target);
3018				const emitter = new EventEmitter();
3019				emitter.setEventNamespace(namespace);
3020				Object.setPrototypeOf(emitter, targetProto);
3021				Object.setPrototypeOf(target, emitter);
3022				Object.getOwnPropertyNames(EventEmitter.prototype).forEach(method => {
3023					if (['constructor'].includes(method)) {
3024						return;
3025					}
3026					emitter[method] = function (...args) {
3027						return EventEmitter.prototype[method].apply(target, args);
3028					};
3029				});
3030			}
3031		}, {
3032			key: "subscribe",
3033			value: function subscribe(target, eventName, listener, options) {
3034				if (Type.isString(target)) {
3035					options = listener;
3036					listener = eventName;
3037					eventName = target;
3038					target = this.GLOBAL_TARGET;
3039				}
3040				if (!Type.isObject(target)) {
3041					throw new TypeError('The "target" argument must be an object.');
3042				}
3043				eventName = this.normalizeEventName(eventName);
3044				if (!Type.isStringFilled(eventName)) {
3045					throw new TypeError('The "eventName" argument must be a string.');
3046				}
3047				listener = this.normalizeListener(listener);
3048				options = Type.isPlainObject(options) ? options : {};
3049				const fullEventName = this.resolveEventName(eventName, target, options.useGlobalNaming === true);
3050				const {
3051					eventsMap,
3052					onceMap
3053				} = eventStore.getOrAdd(target);
3054				const onceListeners = onceMap.get(fullEventName);
3055				let listeners = eventsMap.get(fullEventName);
3056				if (listeners && listeners.has(listener) || onceListeners && onceListeners.has(listener)) {
3057					console.error(`You cannot subscribe the same "${fullEventName}" event listener twice.`);
3058				} else if (listeners) {
3059					listeners.set(listener, {
3060						listener,
3061						options,
3062						sort: this.getNextSequenceValue()
3063					});
3064				} else {
3065					listeners = new Map([[listener, {
3066						listener,
3067						options,
3068						sort: this.getNextSequenceValue()
3069					}]]);
3070					eventsMap.set(fullEventName, listeners);
3071				}
3072				const maxListeners = this.getMaxListeners(target, eventName);
3073				if (listeners.size > maxListeners) {
3074					warningStore.add(target, fullEventName, listeners);
3075					warningStore.printDelayed();
3076				}
3077			}
3078		}, {
3079			key: "subscribeOnce",
3080			value: function subscribeOnce(target, eventName, listener) {
3081				if (Type.isString(target)) {
3082					listener = eventName;
3083					eventName = target;
3084					target = this.GLOBAL_TARGET;
3085				}
3086				if (!Type.isObject(target)) {
3087					throw new TypeError('The "target" argument must be an object.');
3088				}
3089				eventName = this.normalizeEventName(eventName);
3090				if (!Type.isStringFilled(eventName)) {
3091					throw new TypeError('The "eventName" argument must be a string.');
3092				}
3093				listener = this.normalizeListener(listener);
3094				const fullEventName = this.resolveEventName(eventName, target);
3095				const {
3096					eventsMap,
3097					onceMap
3098				} = eventStore.getOrAdd(target);
3099				const listeners = eventsMap.get(fullEventName);
3100				let onceListeners = onceMap.get(fullEventName);
3101				if (listeners && listeners.has(listener) || onceListeners && onceListeners.has(listener)) {
3102					console.error(`You cannot subscribe the same "${fullEventName}" event listener twice.`);
3103				} else {
3104					const once = (...args) => {
3105						this.unsubscribe(target, eventName, once);
3106						onceListeners.delete(listener);
3107						listener(...args);
3108					};
3109					if (onceListeners) {
3110						onceListeners.set(listener, once);
3111					} else {
3112						onceListeners = new Map([[listener, once]]);
3113						onceMap.set(fullEventName, onceListeners);
3114					}
3115					this.subscribe(target, eventName, once);
3116				}
3117			}
3118		}, {
3119			key: "unsubscribe",
3120			value: function unsubscribe(target, eventName, listener, options) {
3121				if (Type.isString(target)) {
3122					listener = eventName;
3123					eventName = target;
3124					target = this.GLOBAL_TARGET;
3125				}
3126				eventName = this.normalizeEventName(eventName);
3127				if (!Type.isStringFilled(eventName)) {
3128					throw new TypeError('The "eventName" argument must be a string.');
3129				}
3130				listener = this.normalizeListener(listener);
3131				options = Type.isPlainObject(options) ? options : {};
3132				const fullEventName = this.resolveEventName(eventName, target, options.useGlobalNaming === true);
3133				const targetInfo = eventStore.get(target);
3134				const listeners = targetInfo && targetInfo.eventsMap.get(fullEventName);
3135				const onceListeners = targetInfo && targetInfo.onceMap.get(fullEventName);
3136				if (listeners) {
3137					listeners.delete(listener);
3138				}
3139				if (onceListeners) {
3140					const once = onceListeners.get(listener);
3141					if (once) {
3142						onceListeners.delete(listener);
3143						listeners.delete(once);
3144					}
3145				}
3146			}
3147		}, {
3148			key: "unsubscribeAll",
3149			value: function unsubscribeAll(target, eventName, options) {
3150				if (Type.isString(target)) {
3151					eventName = target;
3152					target = this.GLOBAL_TARGET;
3153				}
3154				if (Type.isStringFilled(eventName)) {
3155					const targetInfo = eventStore.get(target);
3156					if (targetInfo) {
3157						options = Type.isPlainObject(options) ? options : {};
3158						const fullEventName = this.resolveEventName(eventName, target, options.useGlobalNaming === true);
3159						targetInfo.eventsMap.delete(fullEventName);
3160						targetInfo.onceMap.delete(fullEventName);
3161					}
3162				} else if (Type.isNil(eventName)) {
3163					if (target === this.GLOBAL_TARGET) {
3164						console.error('You cannot unsubscribe all global listeners.');
3165					} else {
3166						eventStore.delete(target);
3167					}
3168				}
3169			}
3170		}, {
3171			key: "emit",
3172			value: function emit(target, eventName, event, options) {
3173				if (Type.isString(target)) {
3174					options = event;
3175					event = eventName;
3176					eventName = target;
3177					target = this.GLOBAL_TARGET;
3178				}
3179				if (!Type.isObject(target)) {
3180					throw new TypeError('The "target" argument must be an object.');
3181				}
3182				eventName = this.normalizeEventName(eventName);
3183				if (!Type.isStringFilled(eventName)) {
3184					throw new TypeError('The "eventName" argument must be a string.');
3185				}
3186				options = Type.isPlainObject(options) ? options : {};
3187				const fullEventName = this.resolveEventName(eventName, target, options.useGlobalNaming === true);
3188				const globalEvents = eventStore.get(this.GLOBAL_TARGET);
3189				const globalListeners = globalEvents && globalEvents.eventsMap.get(fullEventName) || new Map();
3190				let targetListeners = new Set();
3191				if (target !== this.GLOBAL_TARGET) {
3192					const targetEvents = eventStore.get(target);
3193					targetListeners = targetEvents && targetEvents.eventsMap.get(fullEventName) || new Map();
3194				}
3195				const listeners = [...globalListeners.values(), ...targetListeners.values()];
3196				listeners.sort((a, b) => {
3197					return a.sort - b.sort;
3198				});
3199				const preparedEvent = this.prepareEvent(target, fullEventName, event);
3200				const result = [];
3201				for (const {
3202					listener,
3203					options: listenerOptions
3204				} of listeners) {
3205					if (preparedEvent.isImmediatePropagationStopped()) {
3206						break;
3207					}
3208					if (globalListeners.has(listener) || targetListeners.has(listener)) {
3209						let listenerResult = null;
3210						if (listenerOptions.compatMode) {
3211							const compatData = preparedEvent.getCompatData();
3212							const params = compatData === null ? [preparedEvent] : options.cloneData === true ? Runtime.clone(compatData) : compatData;
3213							const context = Type.isUndefined(options.thisArg) ? target : options.thisArg;
3214							listenerResult = listener.apply(context, params);
3215						} else {
3216							listenerResult = Type.isUndefined(options.thisArg) ? listener(preparedEvent) : listener.call(options.thisArg, preparedEvent);
3217						}
3218						result.push(listenerResult);
3219					}
3220				}
3221				return result;
3222			}
3223		}, {
3224			key: "emitAsync",
3225			value: function emitAsync(target, eventName, event) {
3226				if (Type.isString(target)) {
3227					event = eventName;
3228					eventName = target;
3229					target = this.GLOBAL_TARGET;
3230				}
3231				return Promise.all(this.emit(target, eventName, event));
3232			}
3233		}, {
3234			key: "prepareEvent",
3235			value: function prepareEvent(target, eventName, event) {
3236				const preparedEvent = event instanceof BaseEvent ? event : new BaseEvent();
3237				if (!(event instanceof BaseEvent)) {
3238					preparedEvent.setData(event);
3239				}
3240				preparedEvent.setTarget(this.isEventEmitter(target) ? target[targetProperty] : target);
3241				preparedEvent.setType(eventName);
3242				return preparedEvent;
3243			}
3244		}, {
3245			key: "getNextSequenceValue",
3246			value: function getNextSequenceValue() {
3247				return this.sequenceValue++;
3248			}
3249		}, {
3250			key: "setMaxListeners",
3251			value: function setMaxListeners(...args) {
3252				let target = this.GLOBAL_TARGET;
3253				let eventName = null;
3254				let count = null;
3255				if (args.length === 1) {
3256					count = args[0];
3257				} else if (args.length === 2) {
3258					if (Type.isString(args[0])) {
3259						[eventName, count] = args;
3260					} else {
3261						[target, count] = args;
3262					}
3263				} else if (args.length >= 3) {
3264					[target, eventName, count] = args;
3265				}
3266				if (!Type.isObject(target)) {
3267					throw new TypeError('The "target" argument must be an object.');
3268				}
3269				if (eventName !== null && !Type.isStringFilled(eventName)) {
3270					throw new TypeError('The "eventName" argument must be a string.');
3271				}
3272				if (!Type.isNumber(count) || count < 0) {
3273					throw new TypeError(`The value of "count" is out of range. It must be a non-negative number. Received ${count}.`);
3274				}
3275				const targetInfo = eventStore.getOrAdd(target);
3276				if (Type.isStringFilled(eventName)) {
3277					const fullEventName = this.resolveEventName(eventName, target);
3278					targetInfo.eventsMaxListeners.set(fullEventName, count);
3279				} else {
3280					targetInfo.maxListeners = count;
3281				}
3282			}
3283		}, {
3284			key: "getMaxListeners",
3285			value: function getMaxListeners(target, eventName) {
3286				if (Type.isString(target)) {
3287					eventName = target;
3288					target = this.GLOBAL_TARGET;
3289				} else if (Type.isNil(target)) {
3290					target = this.GLOBAL_TARGET;
3291				}
3292				if (!Type.isObject(target)) {
3293					throw new TypeError('The "target" argument must be an object.');
3294				}
3295				const targetInfo = eventStore.get(target);
3296				if (targetInfo) {
3297					let maxListeners = targetInfo.maxListeners;
3298					if (Type.isStringFilled(eventName)) {
3299						const fullEventName = this.resolveEventName(eventName, target);
3300						maxListeners = targetInfo.eventsMaxListeners.get(fullEventName) || maxListeners;
3301					}
3302					return maxListeners;
3303				}
3304				return this.DEFAULT_MAX_LISTENERS;
3305			}
3306		}, {
3307			key: "addMaxListeners",
3308			value: function addMaxListeners(...args) {
3309				const [target, eventName, increment] = this.destructMaxListenersArgs(...args);
3310				const maxListeners = Math.max(this.getMaxListeners(target, eventName) + increment, 0);
3311				if (Type.isStringFilled(eventName)) {
3312					EventEmitter.setMaxListeners(target, eventName, maxListeners);
3313				} else {
3314					EventEmitter.setMaxListeners(target, maxListeners);
3315				}
3316				return maxListeners;
3317			}
3318		}, {
3319			key: "incrementMaxListeners",
3320			value: function incrementMaxListeners(...args) {
3321				const [target, eventName, increment] = this.destructMaxListenersArgs(...args);
3322				return this.addMaxListeners(target, eventName, Math.abs(increment));
3323			}
3324		}, {
3325			key: "decrementMaxListeners",
3326			value: function decrementMaxListeners(...args) {
3327				const [target, eventName, increment] = this.destructMaxListenersArgs(...args);
3328				return this.addMaxListeners(target, eventName, -Math.abs(increment));
3329			}
3330		}, {
3331			key: "destructMaxListenersArgs",
3332			value: function destructMaxListenersArgs(...args) {
3333				let eventName = null;
3334				let increment = 1;
3335				let target = this.GLOBAL_TARGET;
3336				if (args.length === 1) {
3337					if (Type.isNumber(args[0])) {
3338						increment = args[0];
3339					} else if (Type.isString(args[0])) {
3340						eventName = args[0];
3341					} else {
3342						target = args[0];
3343					}
3344				} else if (args.length === 2) {
3345					if (Type.isString(args[0])) {
3346						[eventName, increment] = args;
3347					} else if (Type.isString(args[1])) {
3348						[target, eventName] = args;
3349					} else {
3350						[target, increment] = args;
3351					}
3352				} else if (args.length >= 3) {
3353					[target, eventName, increment] = args;
3354				}
3355				if (!Type.isObject(target)) {
3356					throw new TypeError('The "target" argument must be an object.');
3357				}
3358				if (eventName !== null && !Type.isStringFilled(eventName)) {
3359					throw new TypeError('The "eventName" argument must be a string.');
3360				}
3361				if (!Type.isNumber(increment)) {
3362					throw new TypeError('The value of "increment" must be a number.');
3363				}
3364				return [target, eventName, increment];
3365			}
3366		}, {
3367			key: "getListeners",
3368			value: function getListeners(target, eventName) {
3369				if (Type.isString(target)) {
3370					eventName = target;
3371					target = this.GLOBAL_TARGET;
3372				}
3373				if (!Type.isObject(target)) {
3374					throw new TypeError('The "target" argument must be an object.');
3375				}
3376				eventName = this.normalizeEventName(eventName);
3377				if (!Type.isStringFilled(eventName)) {
3378					throw new TypeError('The "eventName" argument must be a string.');
3379				}
3380				const targetInfo = eventStore.get(target);
3381				if (!targetInfo) {
3382					return new Map();
3383				}
3384				const fullEventName = this.resolveEventName(eventName, target);
3385				return targetInfo.eventsMap.get(fullEventName) || new Map();
3386			}
3387		}, {
3388			key: "registerAliases",
3389			value: function registerAliases(aliases) {
3390				const normalizedAliases = this.normalizeAliases(aliases);
3391				Object.keys(normalizedAliases).forEach(alias => {
3392					aliasStore.set(alias, {
3393						eventName: normalizedAliases[alias].eventName,
3394						namespace: normalizedAliases[alias].namespace
3395					});
3396				});
3397				EventEmitter.mergeEventAliases(normalizedAliases);
3398			}
3399		}, {
3400			key: "normalizeAliases",
3401			value: function normalizeAliases(aliases) {
3402				if (!Type.isPlainObject(aliases)) {
3403					throw new TypeError('The "aliases" argument must be an object.');
3404				}
3405				const aliasesRecord = aliases;
3406				const result = Object.create(null);
3407				for (const key of Object.keys(aliasesRecord)) {
3408					if (!Type.isStringFilled(key)) {
3409						throw new TypeError('The alias must be an non-empty string.');
3410					}
3411					const options = aliasesRecord[key];
3412					if (!options || !Type.isStringFilled(options.eventName) || !Type.isStringFilled(options.namespace)) {
3413						throw new TypeError('The alias options must set the "eventName" and the "namespace".');
3414					}
3415					const normalizedAlias = this.normalizeEventName(key);
3416					result[normalizedAlias] = {
3417						eventName: options.eventName,
3418						namespace: options.namespace
3419					};
3420				}
3421				return result;
3422			}
3423		}, {
3424			key: "mergeEventAliases",
3425			value: function mergeEventAliases(aliases) {
3426				const globalEvents = eventStore.get(this.GLOBAL_TARGET);
3427				if (!globalEvents) {
3428					return;
3429				}
3430				Object.keys(aliases).forEach(alias => {
3431					const options = aliases[alias];
3432					alias = this.normalizeEventName(alias);
3433					const fullEventName = this.makeFullEventName(options.namespace, options.eventName);
3434					const aliasListeners = globalEvents.eventsMap.get(alias);
3435					if (aliasListeners) {
3436						const listeners = globalEvents.eventsMap.get(fullEventName) || new Map();
3437						globalEvents.eventsMap.set(fullEventName, new Map([...listeners, ...aliasListeners]));
3438						globalEvents.eventsMap.delete(alias);
3439					}
3440					const aliasOnceListeners = globalEvents.onceMap.get(alias);
3441					if (aliasOnceListeners) {
3442						const onceListeners = globalEvents.onceMap.get(fullEventName) || new Map();
3443						globalEvents.onceMap.set(fullEventName, new Map([...onceListeners, ...aliasOnceListeners]));
3444						globalEvents.onceMap.delete(alias);
3445					}
3446					const aliasMaxListeners = globalEvents.eventsMaxListeners.get(alias);
3447					if (aliasMaxListeners) {
3448						const eventMaxListeners = globalEvents.eventsMaxListeners.get(fullEventName) || 0;
3449						globalEvents.eventsMaxListeners.set(fullEventName, Math.max(eventMaxListeners, aliasMaxListeners));
3450						globalEvents.eventsMaxListeners.delete(alias);
3451					}
3452				});
3453			}
3454		}, {
3455			key: "isEventEmitter",
3456			value: function isEventEmitter(target) {
3457				return Type.isObject(target) && target[isEmitterProperty] === true;
3458			}
3459		}, {
3460			key: "normalizeEventName",
3461			value: function normalizeEventName(eventName) {
3462				if (!Type.isStringFilled(eventName)) {
3463					return '';
3464				}
3465				return eventName.toLowerCase();
3466			}
3467		}, {
3468			key: "normalizeListener",
3469			value: function normalizeListener(listener) {
3470				if (Type.isString(listener)) {
3471					listener = Reflection.getClass(listener);
3472				}
3473				if (!Type.isFunction(listener)) {
3474					throw new TypeError(`The "listener" argument must be of type Function. Received type ${typeof listener}.`);
3475				}
3476				return listener;
3477			}
3478		}, {
3479			key: "resolveEventName",
3480			value: function resolveEventName(eventName, target, useGlobalNaming = false) {
3481				eventName = this.normalizeEventName(eventName);
3482				if (!Type.isStringFilled(eventName)) {
3483					return '';
3484				}
3485				if (this.isEventEmitter(target) && useGlobalNaming !== true) {
3486					if (target.getEventNamespace() !== null && eventName.includes('.')) {
3487						console.warn(`Possible the wrong event name "${eventName}".`);
3488					}
3489					eventName = target.getFullEventName(eventName);
3490				} else if (aliasStore.has(eventName)) {
3491					const {
3492						namespace,
3493						eventName: actualEventName
3494					} = aliasStore.get(eventName);
3495					eventName = this.makeFullEventName(namespace, actualEventName);
3496				}
3497				return eventName;
3498			}
3499		}, {
3500			key: "makeFullEventName",
3501			value: function makeFullEventName(namespace, eventName) {
3502				const fullName = Type.isStringFilled(namespace) ? `${namespace}:${eventName}` : eventName;
3503				return Type.isStringFilled(fullName) ? fullName.toLowerCase() : '';
3504			}
3505		}]);
3506	}();
3507	babelHelpers.defineProperty(EventEmitter, "GLOBAL_TARGET", globalTarget);
3508	babelHelpers.defineProperty(EventEmitter, "DEFAULT_MAX_LISTENERS", eventStore.getDefaultMaxListeners());
3509	babelHelpers.defineProperty(EventEmitter, "sequenceValue", 1);
3510
3511	let stack = [];
3512	exports.isReady = false;
3513	function ready$1(handler) {
3514		if (!Type.isFunction(handler)) {
3515			return;
3516		}
3517		if (exports.isReady) {
3518			handler();
3519		} else {
3520			stack.push(handler);
3521		}
3522	}
3523	bindOnce$1(document, 'DOMContentLoaded', () => {
3524		exports.isReady = true;
3525		stack.forEach(handler => {
3526			handler();
3527		});
3528		stack = [];
3529	});
3530
3531	function getEventListeners(target, eventName) {
3532		const listeners = [];
3533		if (Type.isEventTargetLike(target)) {
3534			const events = registry.get(target);
3535			if (events[eventName]) {
3536				events[eventName].forEach(listener => {
3537					listeners.push({
3538						type: eventName,
3539						listener
3540					});
3541				});
3542			}
3543		}
3544		return listeners;
3545	}
3546
3547	class Event {
3548		static bind = bind$1;
3549		static bindOnce = bindOnce$1;
3550		static unbind = unbind$1;
3551		static unbindAll = unbindAll$1;
3552		static ready = ready$1;
3553		static getEventListeners = getEventListeners;
3554		static EventEmitter = EventEmitter;
3555		static BaseEvent = BaseEvent;
3556	}
3557
3558	function encodeAttributeValue(value) {
3559		if (Type.isPlainObject(value) || Type.isArray(value)) {
3560			return JSON.stringify(value);
3561		}
3562		return Text.encode(Text.decode(value));
3563	}
3564
3565	function decodeAttributeValue(value) {
3566		if (Type.isString(value)) {
3567			const decodedValue = Text.decode(value);
3568			let result = null;
3569			try {
3570				result = JSON.parse(decodedValue);
3571			} catch {
3572				result = decodedValue;
3573			}
3574			if (result === decodedValue && /^[\d.]+[.]?\d+$/.test(result)) {
3575				return Number(result);
3576			}
3577			if (result === 'true' || result === 'false') {
3578				return Boolean(result);
3579			}
3580			return result;
3581		}
3582		return value;
3583	}
3584
3585	function getPageScroll() {
3586		const {
3587			documentElement,
3588			body
3589		} = document;
3590		const scrollTop = Math.max(window.pageYOffset || 0, documentElement ? documentElement.scrollTop : 0, body ? body.scrollTop : 0);
3591		const scrollLeft = Math.max(window.pageXOffset || 0, documentElement ? documentElement.scrollLeft : 0, body ? body.scrollLeft : 0);
3592		return {
3593			scrollTop,
3594			scrollLeft
3595		};
3596	}
3597
3598	class Dom {
3599		static replace(oldElement, newElement) {
3600			if (Type.isDomNode(oldElement) && Type.isDomNode(newElement) && Type.isDomNode(oldElement.parentNode)) {
3601				oldElement.parentNode.replaceChild(newElement, oldElement);
3602			}
3603		}
3604		static remove(element) {
3605			if (Type.isDomNode(element) && Type.isDomNode(element.parentNode)) {
3606				element.parentNode.removeChild(element);
3607			}
3608		}
3609		static clean(element) {
3610			if (Type.isDomNode(element)) {
3611				while (element.firstChild) {
3612					element.removeChild(element.firstChild);
3613				}
3614				return;
3615			}
3616			if (Type.isString(element)) {
3617				Dom.clean(document.getElementById(element));
3618			}
3619		}
3620		static insertBefore(current, target) {
3621			if (Type.isDomNode(current) && Type.isDomNode(target) && Type.isDomNode(target.parentNode)) {
3622				target.parentNode.insertBefore(current, target);
3623			}
3624		}
3625		static insertAfter(current, target) {
3626			if (Type.isDomNode(current) && Type.isDomNode(target) && Type.isDomNode(target.parentNode)) {
3627				const parent = target.parentNode;
3628				if (Type.isDomNode(target.nextSibling)) {
3629					parent.insertBefore(current, target.nextSibling);
3630					return;
3631				}
3632				parent.appendChild(current);
3633			}
3634		}
3635		static append(current, target) {
3636			if (Type.isDomNode(current) && Type.isDomNode(target)) {
3637				target.appendChild(current);
3638			}
3639		}
3640		static prepend(current, target) {
3641			if (Type.isDomNode(current) && Type.isDomNode(target)) {
3642				if (Type.isDomNode(target.firstChild)) {
3643					target.insertBefore(current, target.firstChild);
3644					return;
3645				}
3646				Dom.append(current, target);
3647			}
3648		}
3649		static hasClass(element, className) {
3650			if (Type.isElementNode(element)) {
3651				if (Type.isString(className)) {
3652					const preparedClassName = className.trim();
3653					if (preparedClassName.length > 0) {
3654						if (preparedClassName.includes(' ')) {
3655							return preparedClassName.split(' ').every(name => Dom.hasClass(element, name));
3656						}
3657						return element.classList.contains(preparedClassName);
3658					}
3659				}
3660				if (Type.isArray(className) && className.length > 0) {
3661					return className.every(name => Dom.hasClass(element, name));
3662				}
3663			}
3664			return false;
3665		}
3666		static addClass(element, className) {
3667			if (Type.isElementNode(element)) {
3668				if (Type.isString(className)) {
3669					const preparedClassName = className.trim();
3670					if (preparedClassName.length > 0) {
3671						if (preparedClassName.includes(' ')) {
3672							Dom.addClass(element, preparedClassName.split(' '));
3673							return;
3674						}
3675						element.classList.add(preparedClassName);
3676						return;
3677					}
3678				}
3679				if (Type.isArray(className)) {
3680					className.forEach(name => Dom.addClass(element, name));
3681				}
3682			}
3683		}
3684		static removeClass(element, className) {
3685			if (Type.isElementNode(element)) {
3686				if (Type.isString(className)) {
3687					const preparedClassName = className.trim();
3688					if (preparedClassName.length > 0) {
3689						if (preparedClassName.includes(' ')) {
3690							Dom.removeClass(element, preparedClassName.split(' '));
3691							return;
3692						}
3693						element.classList.remove(preparedClassName);
3694						return;
3695					}
3696				}
3697				if (Type.isArray(className)) {
3698					className.forEach(name => Dom.removeClass(element, name));
3699				}
3700			}
3701		}
3702		static toggleClass(element, className, force) {
3703			if (!Type.isElementNode(element) || !Type.isStringFilled(className) && !Type.isArrayFilled(className)) {
3704				return;
3705			}
3706			[className].flat().flatMap(it =>
3706 it?.trim?.().split(' ')).forEach(token => {
3707				if (Type.isStringFilled(token)) {
3708					element.classList.toggle(token, Type.isBoolean(force) ? force : undefined);
3709				}
3710			});
3711		}
3712		static style(element, prop, value) {
3713			if (Type.isElementNode(element)) {
3714				if (Type.isNull(prop)) {
3715					element.removeAttribute('style');
3716					return element;
3717				}
3718				if (Type.isPlainObject(prop)) {
3719					Object.entries(prop).forEach(([currentKey, currentValue]) => {
3720						Dom.style(element, currentKey, currentValue);
3721					});
3722					return element;
3723				}
3724				if (Type.isString(prop)) {
3725					if (Type.isUndefined(value) && element.nodeType !== Node.DOCUMENT_NODE) {
3726						const computedStyle = getComputedStyle(element);
3727						if (prop in computedStyle) {
3728							return computedStyle[prop];
3729						}
3730						return computedStyle.getPropertyValue(prop);
3731					}
3732					if (Type.isNull(value) || value === '' || value === 'null') {
3733						if (String(prop).startsWith('--')) {
3734							element.style.removeProperty(prop);
3735							return element;
3736						}
3737						element.style[prop] = '';
3738						return element;
3739					}
3740					if (Type.isString(value) || Type.isNumber(value)) {
3741						if (String(prop).startsWith('--')) {
3742							element.style.setProperty(prop, String(value));
3743							return element;
3744						}
3745						element.style[prop] = value;
3746						return element;
3747					}
3748				}
3749			}
3750			return null;
3751		}
3752		static adjust(target, data = {}) {
3753			if (!target.nodeType) {
3754				return null;
3755			}
3756			let element = target;
3757			if (target.nodeType === Node.DOCUMENT_NODE) {
3758				element = target.body;
3759			}
3760			if (Type.isPlainObject(data)) {
3761				if (Type.isPlainObject(data.attrs)) {
3762					const attrs = data.attrs;
3763					Object.keys(attrs).forEach(key => {
3764						if (key === 'class' || key.toLowerCase() === 'classname') {
3765							element.className = attrs[key];
3766							return;
3767						}
3768						if (attrs[key] == '') {
3769							element.removeAttribute(key);
3770							return;
3771						}
3772						element.setAttribute(key, attrs[key]);
3773					});
3774				}
3775				if (Type.isPlainObject(data.style)) {
3776					Dom.style(element, data.style);
3777				}
3778				if (Type.isPlainObject(data.props)) {
3779					const props = data.props;
3780					Object.keys(props).forEach(key => {
3781						element[key] = props[key];
3782					});
3783				}
3784				if (Type.isPlainObject(data.events)) {
3785					const events = data.events;
3786					Object.keys(events).forEach(key => {
3787						Event.bind(element, key, events[key]);
3788					});
3789				}
3790				if (Type.isPlainObject(data.dataset)) {
3791					const dataset = data.dataset;
3792					Object.keys(dataset).forEach(key => {
3793						element.dataset[key] = dataset[key];
3794					});
3795				}
3796				const children = Type.isString(data.children) ? [data.children] : data.children;
3797				if (Type.isArray(children) && children.length > 0) {
3798					children.forEach(item => {
3799						if (Type.isDomNode(item)) {
3800							Dom.append(item, element);
3801						}
3802						if (Type.isString(item)) {
3803							element.insertAdjacentHTML('beforeend', item);
3804						}
3805					});
3806					return element;
3807				}
3808				if ('text' in data && !Type.isNil(data.text)) {
3809					element.textContent = data.text;
3810					return element;
3811				}
3812				if ('html' in data && !Type.isNil(data.html)) {
3813					element.innerHTML = data.html;
3814				}
3815			}
3816			return element;
3817		}
3818		static create(tag, data = {}, context = document) {
3819			let tagName = tag;
3820			let options = data;
3821			if (Type.isObjectLike(tag)) {
3822				const tagOptions = tag;
3823				options = tagOptions;
3824				tagName = tagOptions.tag;
3825			}
3826			return Dom.adjust(context.createElement(tagName), options);
3827		}
3828		static show(element) {
3829			if (Type.isDomNode(element)) {
3830				element.hidden = false;
3831			}
3832		}
3833		static hide(element) {
3834			if (Type.isDomNode(element)) {
3835				element.hidden = true;
3836			}
3837		}
3838		static isShown(element) {
3839			return Type.isDomNode(element) && !element.hidden && element.style.getPropertyValue('display') !== 'none';
3840		}
3841		static isShownRecursive(element) {
3842			if (!Type.isDomNode(element)) {
3843				return false;
3844			}
3845			if (element === document.body) {
3846				return Dom.isShown(element);
3847			}
3848			return Dom.isShown(element) && Dom.isShownRecursive(element.parentElement);
3849		}
3850		static toggle(element) {
3851			if (Type.isDomNode(element)) {
3852				if (Dom.isShown(element)) {
3853					Dom.hide(element);
3854				} else {
3855					Dom.show(element);
3856				}
3857			}
3858		}
3859		static getPosition(element) {
3860			if (Type.isDomNode(element)) {
3861				const elementRect = element.getBoundingClientRect();
3862				const {
3863					scrollLeft,
3864					scrollTop
3865				} = getPageScroll();
3866				return new DOMRect(elementRect.left + scrollLeft, elementRect.top + scrollTop, elementRect.width, elementRect.height);
3867			}
3868			return new DOMRect();
3869		}
3870		static getRelativePosition(element, relationElement) {
3871			if (Type.isDomNode(element) && Type.isDomNode(relationElement)) {
3872				const elementPosition = Dom.getPosition(element);
3873				const relationElementPosition = Dom.getPosition(relationElement);
3874				return new DOMRect(elementPosition.left - relationElementPosition.left, elementPosition.top - relationElementPosition.top, elementPosition.width, elementPosition.height);
3875			}
3876			return new DOMRect();
3877		}
3878		static attr(element, attr, value) {
3879			if (Type.isElementNode(element)) {
3880				if (Type.isString(attr)) {
3881					if (!Type.isNil(value)) {
3882						if (Type.isObjectLike(value)) {
3883							element.setAttribute(attr, encodeAttributeValue(value));
3884						} else {
3885							element.setAttribute(attr, String(value));
3886						}
3887					} else if (Type.isNull(value)) {
3888						element.removeAttribute(attr);
3889					} else {
3890						return decodeAttributeValue(element.getAttribute(attr));
3891					}
3892				}
3893				if (Type.isPlainObject(attr)) {
3894					Object.entries(attr).forEach(([attrKey, attrValue]) => {
3895						Dom.attr(element, attrKey, attrValue);
3896					});
3897				}
3898			}
3899			return null;
3900		}
3901	}
3902
3903	const UA = navigator.userAgent.toLowerCase();
3904	class Browser {
3905		static isOpera() {
3906			return UA.includes('opera');
3907		}
3908		static isIE() {
3909			return false;
3910		}
3911		static isIE6() {
3912			return false;
3913		}
3914		static isIE7() {
3915			return false;
3916		}
3917		static isIE8() {
3918			return false;
3919		}
3920		static isIE9() {
3921			return false;
3922		}
3923		static isIE10() {
3924			return false;
3925		}
3926		static isSafari() {
3927			return UA.includes('safari') && !UA.includes('chrome');
3928		}
3929		static isFirefox() {
3930			return UA.includes('firefox');
3931		}
3932		static isChrome() {
3933			return UA.includes('chrome');
3934		}
3935		static detectIEVersion() {
3936			return -1;
3937		}
3938		static isIE11() {
3939			return false;
3940		}
3941		static isMac() {
3942			return UA.includes('macintosh');
3943		}
3944		static isWin() {
3945			return UA.includes('windows');
3946		}
3947		static isLinux() {
3948			return UA.includes('linux') && !Browser.isAndroid();
3949		}
3950		static isAndroid() {
3951			return UA.includes('android');
3952		}
3953		static isIPad() {
3954			return UA.includes('ipad;') || this.isMac() && this.isTouchDevice();
3955		}
3956		static isIPhone() {
3957			return UA.includes('iphone;');
3958		}
3959		static isIOS() {
3960			return Browser.isIPad() || Browser.isIPhone();
3961		}
3962		static isMobile() {
3963			return Browser.isIPhone() || Browser.isIPad() || Browser.isAndroid() || UA.includes('mobile') || UA.includes('touch');
3964		}
3965		static isRetina() {
3966			return window.devicePixelRatio >= 2;
3967		}
3968		static isTouchDevice() {
3969			return 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
3970		}
3971		static isDoctype(target) {
3972			const doc = target || document;
3973			if (doc.compatMode) {
3974				return doc.compatMode === 'CSS1Compat';
3975			}
3976			return Boolean(doc.documentElement && doc.documentElement.clientHeight);
3977		}
3978		static isLocalStorageSupported() {
3979			return true;
3980		}
3981		static addGlobalClass(target) {
3982			const element = Type.isElementNode(target) ? target : document.documentElement;
3983			let globalClass = 'bx-core';
3984			if (Dom.hasClass(element, globalClass)) {
3985				return;
3986			}
3987			if (Browser.isIOS()) {
3988				globalClass += ' bx-ios';
3989			} else if (Browser.isWin()) {
3990				globalClass += ' bx-win';
3991			} else if (Browser.isMac()) {
3992				globalClass += ' bx-mac';
3993			} else if (Browser.isLinux()) {
3994				globalClass += ' bx-linux';
3995			} else if (Browser.isAndroid()) {
3996				globalClass += ' bx-android';
3997			}
3998			globalClass += Browser.isMobile() ? ' bx-touch' : ' bx-no-touch';
3999			globalClass += Browser.isRetina() ? ' bx-retina' : ' bx-no-retina';
4000			if (Browser.isSafari()) {
4001				globalClass += ' bx-safari';
4002			} else if (/AppleWebKit/.test(navigator.userAgent)) {
4003				globalClass += ' bx-chrome';
4004			} else if (/Opera/.test(navigator.userAgent)) {
4005				globalClass += ' bx-opera';
4006			} else if (Browser.isFirefox()) {
4007				globalClass += ' bx-firefox';
4008			}
4009			Dom.addClass(element, globalClass);
4010		}
4011		static detectAndroidVersion() {
4012			const re = /Android ([\d.]+)/;
4013			if (re.exec(navigator.userAgent) !== null) {
4014				const res = navigator.userAgent.match(re);
4015				if (Type.isArrayLike(res) && res.length > 0) {
4016					return parseFloat(res[1]);
4017				}
4018			}
4019			return 0;
4020		}
4021		static isPropertySupported(jsProperty, returnCSSName) {
4022			if (jsProperty === '') {
4023				return false;
4024			}
4025			function getCssName(propertyName) {
4026				return propertyName.replaceAll(/[A-Z]/g, match => `-${match.toLowerCase()}`);
4027			}
4028			function getJsName(cssName) {
4029				const reg = /(\\-([a-z]))/g;
4030				if (reg.test(cssName)) {
4031					return cssName.replaceAll(reg, (...args) => args[2].toUpperCase());
4032				}
4033				return cssName;
4034			}
4035			const property = jsProperty.includes('-') ? getJsName(jsProperty) : jsProperty;
4036			const bReturnCSSName = Boolean(returnCSSName);
4037			const ucProperty = property.charAt(0).toUpperCase() + property.slice(1);
4038			const props = ['Webkit', 'Moz', 'O', 'ms'].join(`${ucProperty} `);
4039			const properties = `${property} ${props} ${ucProperty}`.split(' ');
4040			const obj = document.body || document.documentElement;
4041			for (const prop of properties) {
4042				if (obj && 'style' in obj && prop in obj.style) {
4043					const lowerProp = prop.slice(0, prop.length - property.length).toLowerCase();
4044					const prefix = prop === property ? '' : `-${lowerProp}-`;
4045					return bReturnCSSName ? prefix + getCssName(property) : prop;
4046				}
4047			}
4048			return false;
4049		}
4050		static addGlobalFeatures(features) {
4051			if (!Type.isArray(features)) {
4052				return;
4053			}
4054			const classNames = [];
4055			for (const feature of features) {
4056				const support = Boolean(Browser.isPropertySupported(feature));
4057				classNames.push(`bx-${support ? '' : 'no-'}${feature.toLowerCase()}`);
4058			}
4059			Dom.addClass(document.documentElement, classNames.join(' '));
4060		}
4061	}
4062
4063	class Cookie {
4064		static getList() {
4065			return document.cookie.split(';').map(item => item.split('=')).map(item => item.map(subItem => subItem.trim())).reduce((acc, item) => {
4066				const [key, value] = item;
4067				acc[decodeURIComponent(key)] = decodeURIComponent(value);
4068				return acc;
4069			}, {});
4070		}
4071		static get(name) {
4072			const cookiesList = Cookie.getList();
4073			if (name in cookiesList) {
4074				return cookiesList[name];
4075			}
4076			return undefined;
4077		}
4078		static set(name, value, options = {}) {
4079			const attributes = {
4080				expires: '',
4081				...options
4082			};
4083			if (Type.isNumber(attributes.expires)) {
4084				const now = Date.now();
4085				const days = attributes.expires;
4086				const dayInMs = 864e5;
4087				attributes.expires = new Date(now + days * dayInMs);
4088			}
4089			if (Type.isDate(attributes.expires)) {
4090				attributes.expires = attributes.expires.toUTCString();
4091			}
4092			const safeName = decodeURIComponent(String(name)).replaceAll(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent).replaceAll(/[()]/g, escape);
4093			const safeValue = encodeURIComponent(String(value)).replaceAll(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
4094			const stringifiedAttributes = Object.keys(attributes).reduce((acc, key) => {
4095				const attributeValue = attributes[key];
4096				if (!attributeValue) {
4097					return acc;
4098				}
4099				if (attributeValue === true) {
4100					return `${acc}; ${key}`;
4101				}
4102				return `${acc}; ${key}=${attributeValue.split(';')[0]}`;
4103			}, '');
4104			document.cookie = `${safeName}=${safeValue}${stringifiedAttributes}`;
4105		}
4106		static remove(name, options = {}) {
4107			Cookie.set(name, '', {
4108				...options,
4109				expires: -1
4110			});
4111		}
4112	}
4113
4114	function objectToFormData(source, formData = new FormData(), pre = null) {
4115		if (Type.isUndefined(source)) {
4116			return formData;
4117		}
4118		if (Type.isNull(source)) {
4119			formData.append(pre, '');
4120		} else if (Type.isArray(source)) {
4121			if (source.length > 0) {
4122				source.forEach((value, index) => {
4123					const key = `${pre}[${index}]`;
4124					objectToFormData(value, formData, key);
4125				});
4126			} else {
4127				const key = `${pre}[]`;
4128				formData.append(key, '');
4129			}
4130		} else if (Type.isDate(source)) {
4131			formData.append(pre, source.toISOString());
4132		} else if (Type.isObject(source) && !Type.isFile(source) && !Type.isBlob(source)) {
4133			Object.keys(source).forEach(property => {
4134				const value = source[property];
4135				let preparedProperty = property;
4136				if (Type.isArray(value)) {
4137					while (preparedProperty.length > 2 && preparedProperty.lastIndexOf('[]') === preparedProperty.length - 2) {
4138						preparedProperty = preparedProperty.slice(0, -2);
4139					}
4140				}
4141				const key = pre ? `${pre}[${preparedProperty}]` : preparedProperty;
4142				objectToFormData(value, formData, key);
4143			});
4144		} else {
4145			formData.append(pre, source);
4146		}
4147		return formData;
4148	}
4149
4150	class Data {
4151		static convertObjectToFormData(source) {
4152			return objectToFormData(source);
4153		}
4154	}
4155
4156	class Http {
4157		static Cookie = Cookie;
4158		static Data = Data;
4159	}
4160
4161	const message$1 = function (value) {
4162		if (Type.isString(value)) {
4163			if (Type.isNil(message$1[value])) {
4164				EventEmitter.emit('onBXMessageNotFound', new BaseEvent({
4165					compatData: [value]
4166				}));
4167				if (Type.isNil(message$1[value])) {
4168					Runtime.debug(`message undefined: ${value}`);
4169					message$1[value] = '';
4170				}
4171			}
4172			return message$1[value];
4173		}
4174		if (Type.isPlainObject(value)) {
4175			Object.keys(value).forEach(key => {
4176				message$1[key] = value[key];
4177			});
4178		}
4179		return undefined;
4180	};
4181	if (!Type.isNil(window.BX) && Type.isFunction(window.BX.message)) {
4182		Object.keys(window.BX.message).forEach(key => {
4183			message$1({
4184				[key]: window.BX.message[key]
4185			});
4186		});
4187	}
4188
4189	class Loc {
4190		static getMessage(messageId, replacements = null) {
4191			let mess = message$1(messageId);
4192			if (Type.isString(mess) && Type.isPlainObject(replacements)) {
4193				const escape = str => String(str).replaceAll(/[$()*+.?[\\\]^{|}]/g, '\\$&');
4194				Object.keys(replacements).forEach(replacement => {
4195					const globalRegexp = new RegExp(escape(replacement), 'gi');
4196					mess = mess.replaceAll(globalRegexp, () => {
4197						return Type.isNil(replacements[replacement]) ? '' : String(replacements[replacement]);
4198					});
4199				});
4200			}
4201			return mess;
4202		}
4203		static hasMessage(messageId) {
4204			return Type.isString(messageId) && !Type.isNil(message$1[messageId]);
4205		}
4206		static setMessage(id, value) {
4207			if (Type.isString(id) && Type.isString(value)) {
4208				message$1({
4209					[id]: value
4210				});
4211			}
4212			if (Type.isObject(id)) {
4213				message$1(id);
4214			}
4215		}
4216		static getMessagePlural(messageId, value, replacements = null) {
4217			let result = '';
4218			if (Type.isNumber(value)) {
4219				if (this.hasMessage(`${messageId}_PLURAL_${this.getPluralForm(value)}`)) {
4220					result = this.getMessage(`${messageId}_PLURAL_${this.getPluralForm(value)}`, replacements);
4221				} else {
4222					result = this.getMessage(`${messageId}_PLURAL_1`, replacements);
4223				}
4224			} else {
4225				result = this.getMessage(messageId, replacements);
4226			}
4227			return result;
4228		}
4229		static getPluralForm(value, languageId) {
4230			let pluralForm = 1;
4231			let lang = languageId;
4232			if (!Type.isStringFilled(lang)) {
4233				lang = message$1('LANGUAGE_ID');
4234			}
4235			const absValue = Math.abs(value);
4236			switch (lang) {
4237				case 'ar':
4238					pluralForm = absValue === 1 ? 0 : 1;
4239					break;
4240				case 'br':
4241				case 'fr':
4242				case 'tr':
4243					pluralForm = absValue > 1 ? 1 : 0;
4244					break;
4245				case 'de':
4246				case 'en':
4247				case 'hi':
4248				case 'it':
4249				case 'la':
4250					pluralForm = absValue === 1 ? 0 : 1;
4251					break;
4252				case 'ru':
4253				case 'ua':
4254					if (absValue % 10 === 1 && absValue % 100 !== 11) {
4255						pluralForm = 0;
4256					} else if (absValue % 10 >= 2 && absValue % 10 <= 4 && (absValue % 100 < 10 || absValue % 100 >= 20)) {
4257						pluralForm = 1;
4258					} else {
4259						pluralForm = 2;
4260					}
4261					break;
4262				case 'pl':
4263					if (absValue === 1) {
4264						pluralForm = 0;
4265					} else if (absValue % 10 >= 2 && absValue % 10 <= 4 && (absValue % 100 < 10 || absValue % 100 >= 20)) {
4266						pluralForm = 1;
4267					} else {
4268						pluralForm = 2;
4269					}
4270					break;
4271				case 'id':
4272				case 'ja':
4273				case 'ms':
4274				case 'sc':
4275				case 'tc':
4276				case 'th':
4277				case 'vn':
4278					pluralForm = 0;
4279					break;
4280				default:
4281					pluralForm = 1;
4282					break;
4283			}
4284			return pluralForm;
4285		}
4286	}
4287
4288	const voidElements = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr']);
4289	function isVoidElement(element) {
4290		return voidElements.has(element);
4291	}
4292
4293	const matchers = {
4294		tag: /<[\d!/A-Za-z-](?:"[^"]*"|'[^']*'|[^"'>])*>|{{uid\d+}}/g,
4295		comment: /<!--(?!<!)[^>[].*?-->/g,
4296		tagName: /<\/?(\S+?)[\s/>]/,
4297		attributes: /\s([\w.:-]+)\s?\n?=\s?\n?"([^"]+)?"|\s([\w.:-]+)\s?\n?=\s?\n?'([^']+)?'|\s([\w.:-]+)/gs,
4298		placeholder: /{{uid\d+}}/g
4299	};
4300
4301	function parseTag(tag) {
4302		const tagResult = {
4303			type: 'tag',
4304			name: '',
4305			svg: false,
4306			attrs: {},
4307			children: [],
4308			voidElement: false
4309		};
4310		if (tag.startsWith('<!--')) {
4311			const endIndex = tag.indexOf('-->');
4312			const openTagLength = '<!--'.length;
4313			return {
4314				type: 'comment',
4315				content: endIndex === -1 ? '' : tag.slice(openTagLength, endIndex)
4316			};
4317		}
4318		const tagNameMatch = tag.match(matchers.tagName);
4319		if (Type.isArrayFilled(tagNameMatch)) {
4320			const [, tagName] = tagNameMatch;
4321			tagResult.name = tagName;
4322			tagResult.svg = tagName === 'svg';
4323			tagResult.voidElement = isVoidElement(tagName) || tag.trim().endsWith('/>');
4324		}
4325		const reg = new RegExp(matchers.attributes);
4326		for (;;) {
4327			const result = reg.exec(tag);
4328			if (Type.isNil(result)) {
4329				break;
4330			}
4331			const [, doubleQuoteName, doubleQuoteValue] = result;
4332			if (Type.isNil(doubleQuoteName)) {
4333				const singleQuoteName = result[3];
4334				const singleQuoteValue = result[4];
4335				if (Type.isNil(singleQuoteName)) {
4336					const booleanAttrName = result[5];
4337					tagResult.attrs[booleanAttrName] = '';
4338				} else {
4339					tagResult.attrs[singleQuoteName] = Type.isStringFilled(singleQuoteValue) ? singleQuoteValue : '';
4340				}
4341			} else {
4342				tagResult.attrs[doubleQuoteName] = Type.isStringFilled(doubleQuoteValue) ? doubleQuoteValue : '';
4343			}
4344		}
4345		return tagResult;
4346	}
4347
4348	function parseText(input) {
4349		const preparedText = input.replace(/[\t\n\r]$/, '');
4350		const placeholders = preparedText.match(matchers.placeholder);
4351		return preparedText.split(matchers.placeholder).reduce((acc, item, index) => {
4352			if (Type.isStringFilled(item)) {
4353				acc.push(...item.split(/\n/).reduce((textAcc, text) => {
4354					const preparedItemText = text.replaceAll(/[\t\r]/g, '');
4355					if (Type.isStringFilled(preparedItemText)) {
4356						textAcc.push({
4357							type: 'text',
4358							content: preparedItemText
4359						});
4360					}
4361					return textAcc;
4362				}, []));
4363			}
4364			if (placeholders && placeholders[index]) {
4365				acc.push({
4366					type: 'placeholder',
4367					uid: parseInt(placeholders[index].replace(/{{uid|}}/, ''), 10)
4368				});
4369			}
4370			return acc;
4371		}, []);
4372	}
4373
4374	function parse(html, substitutions) {
4375		const result = [];
4376		if (html.indexOf('<') !== 0 && !html.startsWith('{{')) {
4377			const end = html.indexOf('<');
4378			result.push(...parseText(end === -1 ? html : html.slice(0, end)));
4379		}
4380		const commentsContent = [];
4381		let commentIndex = -1;
4382		html = html.replace(matchers.comment, tag => {
4383			commentIndex += 1;
4384			commentsContent.push(tag.replaceAll(/^<!--|-->$/g, ''));
4385			return `<!--{{cUid${commentIndex}}}-->`;
4386		});
4387		const arr = [];
4388		let level = -1;
4389		let current = null;
4390		html.replace(matchers.tag, (tag, index) => {
4391			const start = index + tag.length;
4392			const nextChar = html.charAt(start);
4393			let parent = null;
4394			if (tag.startsWith('<!--')) {
4395				const comment = parseTag(tag);
4396				comment.content = commentsContent[tag.replaceAll(/<!--{{cUid|}}-->/g, '')];
4397				if (level < 0) {
4398					result.push(comment);
4399					return result;
4400				}
4401				parent = arr[level];
4402				parent.children.push(comment);
4403				return result;
4404			}
4405			if (tag.startsWith('{{')) {
4406				const [placeholder] = parseText(tag);
4407				if (level < 0) {
4408					result.push(placeholder);
4409					return result;
4410				}
4411				parent = arr[level];
4412				parent.children.push(placeholder);
4413				return result;
4414			}
4415			if (!tag.startsWith('</')) {
4416				level++;
4417				current = parseTag(tag);
4418				if (!current.voidElement && nextChar && nextChar !== '<') {
4419					current.children.push(...parseText(html.slice(start, html.indexOf('<', start))));
4420				}
4421				if (level === 0) {
4422					result.push(current);
4423				}
4424				parent = arr[level - 1];
4425				if (parent) {
4426					if (!current.svg) {
4427						current.svg = parent.svg;
4428					}
4429					parent.children.push(current);
4430				}
4431				arr[level] = current;
4432			}
4433			if (tag.startsWith('</') || current.voidElement) {
4434				if (level > -1 && (current.voidElement || current.name === tag.slice(2, -1))) {
4435					level--;
4436					current = level === -1 ? result : arr[level];
4437				}
4438				if (nextChar && nextChar !== '<') {
4439					parent = level === -1 ? result : arr[level].children;
4440					const end = html.indexOf('<', start);
4441					const content = html.slice(start, end === -1 ? undefined : end);
4442					if (end >
4442 -1 && level + parent.length >= 0 || content !== ' ') {
4443						parent.push(...parseText(content));
4444					}
4445				}
4446			}
4447			return result;
4448		});
4449		return result;
4450	}
4451
4452	const appendElement = (current, target) => {
4453		if (Type.isDomNode(current) && Type.isDomNode(target)) {
4454			if (target.nodeName === 'TEMPLATE') {
4455				target.content.append(current);
4456			} else {
4457				Dom.append(current, target);
4458			}
4459		}
4460	};
4461	function renderNode(options) {
4462		const {
4463			node,
4464			parentElement,
4465			substitutions,
4466			refs = []
4467		} = options;
4468		if (node.type === 'tag') {
4469			const element = (() => {
4470				if (node.svg) {
4471					return document.createElementNS('http://www.w3.org/2000/svg', node.name);
4472				}
4473				return document.createElement(node.name);
4474			})();
4475			if (Object.hasOwn(node.attrs, 'ref')) {
4476				refs.push([node.attrs.ref, element]);
4477				delete node.attrs.ref;
4478			}
4479			Object.entries(node.attrs).forEach(([key, value]) => {
4480				if (key.startsWith('on') && new RegExp(`^${matchers.placeholder.source}$`).test(String(value).trim())) {
4481					const substitution = substitutions[parseInt(String(value).trim().replace('{{uid', ''), 10) - 1];
4482					if (Type.isFunction(substitution)) {
4483						const bindFunctionName = key.endsWith('once') ? 'bindOnce' : 'bind';
4484						Event[bindFunctionName](element, key.replaceAll(/^on|once$/g, ''), substitution);
4485					} else {
4486						element.setAttribute(key, substitution);
4487					}
4488				} else if (new RegExp(matchers.placeholder).test(value)) {
4489					const preparedValue = value.split(/{{|}}/).reduce((acc, item) => {
4490						if (item.startsWith('uid')) {
4491							const substitution = substitutions[parseInt(item.replace('uid', ''), 10) - 1];
4492							return `${acc}${Text.decode(String(substitution))}`;
4493						}
4494						return `${acc}${Text.decode(item)}`;
4495					}, '');
4496					element.setAttribute(key, preparedValue);
4497				} else {
4498					element.setAttribute(key, Text.decode(value));
4499				}
4500			});
4501			node.children.forEach(childNode => {
4502				const result = renderNode({
4503					node: childNode,
4504					parentElement: element,
4505					substitutions,
4506					refs
4507				});
4508				if (Type.isArray(result)) {
4509					result.forEach(subChildElement => {
4510						appendElement(subChildElement, element);
4511					});
4512				} else {
4513					appendElement(result, element);
4514				}
4515			});
4516			return element;
4517		}
4518		if (node.type === 'comment') {
4519			return document.createComment(node.content);
4520		}
4521		if (node.type === 'text') {
4522			if (parentElement) {
4523				if (parentElement.nodeName === 'TEMPLATE') {
4524					parentElement.content.append(node.content);
4525				} else {
4526					parentElement.insertAdjacentHTML('beforeend', node.content);
4527				}
4528				return undefined;
4529			}
4530			return document.createTextNode(node.content);
4531		}
4532		if (node.type === 'placeholder') {
4533			return substitutions[node.uid - 1];
4534		}
4535		return undefined;
4536	}
4537
4538	const SECTION_STATE_OUTSIDE_TAG = 0;
4539	const SECTION_STATE_IN_TAG = 1;
4540	const SECTION_STATE_IN_ATTR_VALUE_DOUBLE = 2;
4541	const SECTION_STATE_IN_ATTR_VALUE_SINGLE = 3;
4542	const tagNameStart = /[A-Za-z]/;
4543	function transitionFromOutsideTag(section, position) {
4544		if (section.charAt(position) === '<') {
4545			const next = section.charAt(position + 1);
4546			if (next === '!' || next === '/' || tagNameStart.test(next)) {
4547				return SECTION_STATE_IN_TAG;
4548			}
4549		}
4550		return SECTION_STATE_OUTSIDE_TAG;
4551	}
4552	function transitionFromInTag(char) {
4553		if (char === '"') {
4554			return SECTION_STATE_IN_ATTR_VALUE_DOUBLE;
4555		}
4556		if (char === '\'') {
4557			return SECTION_STATE_IN_ATTR_VALUE_SINGLE;
4558		}
4559		if (char === '>') {
4560			return SECTION_STATE_OUTSIDE_TAG;
4561		}
4562		return SECTION_STATE_IN_TAG;
4563	}
4564	function advanceState(state, section, position) {
4565		const char = section.charAt(position);
4566		switch (state) {
4567			case SECTION_STATE_OUTSIDE_TAG:
4568				return transitionFromOutsideTag(section, position);
4569			case SECTION_STATE_IN_TAG:
4570				return transitionFromInTag(char);
4571			case SECTION_STATE_IN_ATTR_VALUE_DOUBLE:
4572				return char === '"' ? SECTION_STATE_IN_TAG : state;
4573			case SECTION_STATE_IN_ATTR_VALUE_SINGLE:
4574				return char === '\'' ? SECTION_STATE_IN_TAG : state;
4575			default:
4576				return state;
4577		}
4578	}
4579	function computeSectionStates(sections) {
4580		const states = [];
4581		let state = SECTION_STATE_OUTSIDE_TAG;
4582		for (const section of sections) {
4583			for (let position = 0; position < section.length; position++) {
4584				state = advanceState(state, section, position);
4585			}
4586			states.push(state);
4587		}
4588		return states;
4589	}
4590	function render(sections, ...substitutions) {
4591		const sectionStates = computeSectionStates(sections);
4592		const html = sections.reduce((acc, item, index) => {
4593			if (index > 0) {
4594				const substitution = substitutions[index - 1];
4595				const previousSectionState = sectionStates[index - 1];
4596				const isInsideAttributeValue = previousSectionState === SECTION_STATE_IN_ATTR_VALUE_DOUBLE || previousSectionState === SECTION_STATE_IN_ATTR_VALUE_SINGLE;
4597				if (!isInsideAttributeValue && (Type.isString(substitution) || Type.isNumber(substitution))) {
4598					return `${acc}${substitution}${item}`;
4599				}
4600				return `${acc}{{uid${index}}}${item}`;
4601			}
4602			return acc;
4603		}, sections[0]).replaceAll(/^\s+/gm, '').replaceAll(/>\n+/g, '>').replaceAll(/}\n+/g, '}');
4604		const ast = parse(html);
4605		if (ast.length === 1) {
4606			const refs = [];
4607			const renderedNode = renderNode({
4608				node: ast[0],
4609				substitutions,
4610				refs
4611			});
4612			if (Type.isArrayFilled(refs)) {
4613				return Object.fromEntries([['root', renderedNode], ...refs]);
4614			}
4615			return renderedNode;
4616		}
4617		if (ast.length > 1) {
4618			const refs = [];
4619			const renderedNodes = ast.map(node => {
4620				return renderNode({
4621					node,
4622					substitutions,
4623					refs
4624				});
4625			});
4626			if (Type.isArrayFilled(refs)) {
4627				return Object.fromEntries([['root', renderedNodes], ...refs]);
4628			}
4629			return renderedNodes;
4630		}
4631		return false;
4632	}
4633
4634	function parseProps(...args) {
4635		const [sections, ...substitutions] = args;
4636		return substitutions.reduce((acc, item, index) => {
4637			const nextSectionIndex = index + 1;
4638			if (!Type.isPlainObject(item) && !Type.isArray(item)) {
4639				return acc + item + sections[nextSectionIndex];
4640			}
4641			return `${acc}__s${index}${sections[nextSectionIndex]}`;
4642		}, sections[0]).replaceAll(/[\t\r]/gm, '').split(';\n').map(item => item.replace(/\n/, '')).reduce((acc, item) => {
4643			if (item !== '') {
4644				const matches = item.match(/^[\w-. ]+:/);
4645				const splitted = item.split(/^[\w-. ]+:/);
4646				const key = matches[0].replace(':', '').trim();
4647				const value = splitted[1].trim();
4648				const substitutionPlaceholderExp = /^__s\d+/;
4649				if (substitutionPlaceholderExp.test(value)) {
4650					acc[key] = substitutions[value.replace('__s', '')];
4651					return acc;
4652				}
4653				acc[key] = value;
4654			}
4655			return acc;
4656		}, {});
4657	}
4658	class Tag {
4659		static safe(sections, ...substitutions) {
4660			return substitutions.reduce((acc, item, index) => acc + Text.encode(item) + sections[index + 1], sections[0]);
4661		}
4662		static unsafe(sections, ...substitutions) {
4663			return substitutions.reduce((acc, item, index) => acc + Text.decode(item) + sections[index + 1], sections[0]);
4664		}
4665		static style(element) {
4666			if (!Type.isDomNode(element)) {
4667				throw new Error('element is not HTMLElement');
4668			}
4669			return function styleTagHandler(...args) {
4670				Dom.style(element, parseProps(...args));
4671			};
4672		}
4673		static message(sections, ...substitutions) {
4674			return substitutions.reduce((acc, item, index) => acc + Loc.getMessage(item) + sections[index + 1], sections[0]);
4675		}
4676		static render = render;
4677		static attrs(element) {
4678			if (!Type.isDomNode(element)) {
4679				throw new Error('element is not HTMLElement');
4680			}
4681			return function attrsTagHandler(...args) {
4682				Dom.attr(element, parseProps(...args));
4683			};
4684		}
4685		static attr = Tag.attrs;
4686	}
4687
4688	function getParser(format) {
4689		switch (format) {
4690			case 'index':
4691				return (sourceKey, value, accumulator) => {
4692					const result = /\[(\w*)]$/.exec(sourceKey);
4693					const key = sourceKey.replace(/\[\w*]$/, '');
4694					if (Type.isNil(result)) {
4695						accumulator[key] = value;
4696						return;
4697					}
4698					if (Type.isUndefined(accumulator[key])) {
4699						accumulator[key] = {};
4700					}
4701					accumulator[key][result[1]] = value;
4702				};
4703			case 'bracket':
4704				return (sourceKey, value, accumulator) => {
4705					const result = /(\[])$/.exec(sourceKey);
4706					const key = sourceKey.replace(/\[]$/, '');
4707					if (Type.isNil(result)) {
4708						accumulator[key] = value;
4709						return;
4710					}
4711					if (Type.isUndefined(accumulator[key])) {
4712						accumulator[key] = Type.isNil(value) ? [] : [value];
4713						return;
4714					}
4715					accumulator[key] = [].concat(accumulator[key], value);
4716				};
4717			default:
4718				return (sourceKey, value, accumulator) => {
4719					const key = sourceKey.replace(/\[]$/, '');
4720					accumulator[key] = value;
4721				};
4722		}
4723	}
4724	function getKeyFormat(key) {
4725		if (/^\w+\[(\w+)]$/.test(key)) {
4726			return 'index';
4727		}
4728		if (/^\w+\[]$/.test(key)) {
4729			return 'bracket';
4730		}
4731		return 'default';
4732	}
4733	function isAllowedKey(key) {
4734		return !String(key).startsWith('__proto__');
4735	}
4736	function parseQuery(input) {
4737		if (!Type.isString(input)) {
4738			return {};
4739		}
4740		const url = input.trim().replace(/^[#&?]/, '');
4741		if (!url) {
4742			return {};
4743		}
4744		return {
4745			...url.split('&').reduce((acc, param) => {
4746				const [key, value] = param.replaceAll('+', ' ').split('=');
4747				if (isAllowedKey(key)) {
4748					const keyFormat = getKeyFormat(key);
4749					const formatter = getParser(keyFormat);
4750					formatter(key, value, acc);
4751				}
4752				return acc;
4753			}, Object.create(null))
4754		};
4755	}
4756	const urlExp = /^((\w+):)?(\/\/((\w+)?(:(\w+))?@)?([^/:?]+)(:(\d+))?)?(\/?([^#/?][^#?]*)?)?(\?([^#]+))?(#((?:[\w-?/:@.~!$&'()*+,;=]|%\w{2})*))?/;
4757	function prepareParams(params) {
4758		const paramsEntries = Object.entries(params);
4759		return paramsEntries.reduce((acc, [key, value]) => {
4760			if (Type.isNil(value)) {
4761				acc[key] = '';
4762			} else if (Type.isPlainObject(value)) {
4763				acc[key] = prepareParams(value);
4764			} else {
4765				acc[key] = value;
4766			}
4767			return acc;
4768		}, {});
4769	}
4770	function parseUrl(url) {
4771		const result = url.match(urlExp);
4772		if (Type.isArray(result)) {
4773			const sourceParams = parseQuery(result[14]);
4774			const preparedParams = prepareParams(sourceParams);
4775			return {
4776				useShort: /^\/\//.test(url),
4777				href: result[0] || '',
4778				schema: result[2] || '',
4779				host: result[8] || '',
4780				port: result[10] || '',
4781				path: result[11] || '',
4782				query: result[14] || '',
4783				sourceQueryParams: sourceParams,
4784				queryParams: preparedParams,
4785				hash: result[16] || '',
4786				username: result[5] || '',
4787				password: result[7] || '',
4788				origin: result[8] || ''
4789			};
4790		}
4791		return {};
4792	}
4793
4794	function renderParam(param, value) {
4795		if (Type.isNil(value)) {
4796			return param;
4797		}
4798		return `${param}=${value}`;
4799	}
4800
4801	function buildQueryString(params = {}) {
4802		const queryString = Object.keys(params).reduce((acc, key) => {
4803			if (Type.isArray(params[key])) {
4804				if (Type.isArrayFilled(params[key])) {
4805					params[key].forEach(paramValue => {
4806						acc.push(renderParam(`${key}[]`, paramValue));
4807					});
4808				} else {
4809					acc.push(renderParam(`${key}[]`, null));
4810				}
4811			}
4812			if (Type.isPlainObject(params[key])) {
4813				Object.keys(params[key]).forEach(paramIndex => {
4814					acc.push(renderParam(`${key}[${paramIndex}]`, params[key][paramIndex]));
4815				});
4816			}
4817			if (!Type.isObject(params[key]) && !Type.isArray(params[key])) {
4818				acc.push(renderParam(key, params[key]));
4819			}
4820			return acc;
4821		}, []).join('&');
4822		if (queryString.length > 0) {
4823			return `?${queryString}`;
4824		}
4825		return queryString;
4826	}
4827
4828	function prepareParamValue(value) {
4829		if (Type.isArray(value)) {
4830			return value.map(item => String(item));
4831		}
4832		if (Type.isPlainObject(value)) {
4833			return {
4834				...value
4835			};
4836		}
4837		return String(value);
4838	}
4839
4840	const map = new WeakMap();
4841	class Uri {
4842		static addParam(url, params = {}) {
4843			return new Uri(url).setQueryParams(params).toString();
4844		}
4845		static removeParam(url, params) {
4846			const removableParams = Type.isArray(params) ? params : [params];
4847			return new Uri(url).removeQueryParam(...removableParams).toString();
4848		}
4849		constructor(url = '') {
4850			map.set(this, parseUrl(url));
4851		}
4852		getSchema() {
4853			return map.get(this).schema;
4854		}
4855		setSchema(schema) {
4856			map.get(this).schema = String(schema);
4857			return this;
4858		}
4859		getHost() {
4860			return map.get(this).host;
4861		}
4862		setHost(host) {
4863			map.get(this).host = String(host);
4864			return this;
4865		}
4866		getPort() {
4867			return map.get(this).port;
4868		}
4869		setPort(port) {
4870			map.get(this).port = String(port);
4871			return this;
4872		}
4873		getPath() {
4874			return map.get(this).path;
4875		}
4876		setPath(path) {
4877			if (!/^\//.test(path)) {
4878				map.get(this).path = `/${String(path)}`;
4879				return this;
4880			}
4881			map.get(this).path = String(path);
4882			return this;
4883		}
4884		getQuery() {
4885			return buildQueryString(map.get(this).queryParams);
4886		}
4887		getQueryParam(key) {
4888			const params = this.getQueryParams();
4889			if (Object.hasOwn(params, key)) {
4890				return params[key];
4891			}
4892			return null;
4893		}
4894		setQueryParam(key, value = '') {
4895			map.get(this).queryParams[key] = prepareParamValue(value);
4896			map.get(this).sourceQueryParams[key] = prepareParamValue(value);
4897			return this;
4898		}
4899		getQueryParams() {
4900			return {
4901				...map.get(this).queryParams
4902			};
4903		}
4904		setQueryParams(params = {}) {
4905			if (Type.isPlainObject(params)) {
4906				const {
4907					queryParams,
4908					sourceQueryParams
4909				} = map.get(this);
4910				Object.entries(params).forEach(([key, value]) => {
4911					const preparedValue = prepareParamValue(value);
4912					queryParams[key] = preparedValue;
4913					sourceQueryParams[key] = preparedValue;
4914				});
4915			}
4916			return this;
4917		}
4918		removeQueryParam(...keys) {
4919			const {
4920				queryParams,
4921				sourceQueryParams
4922			} = map.get(this);
4923			keys.forEach(key => {
4924				delete queryParams[key];
4925				delete sourceQueryParams[key];
4926			});
4927			return this;
4928		}
4929		getFragment() {
4930			return map.get(this).hash;
4931		}
4932		setFragment(hash) {
4933			map.get(this).hash = String(hash);
4934			return this;
4935		}
4936		serialize() {
4937			const serialized = {
4938				...map.get(this)
4939			};
4940			delete serialized.sourceQueryParams;
4941			serialized.href = this.toString();
4942			return serialized;
4943		}
4944		toString() {
4945			const data = {
4946				...map.get(this)
4947			};
4948			let protocol = data.schema ? `${data.schema}://` : '';
4949			if (data.useShort) {
4950				protocol = '//';
4951			}
4952			const port = (() => {
4953				if (Type.isString(data.port) && !['', '80'].includes(data.port)) {
4954					return `:${data.port}`;
4955				}
4956				return '';
4957			})();
4958			const host = this.getHost();
4959			const path = this.getPath();
4960			const query = buildQueryString(data.sourceQueryParams);
4961			const hash = data.hash ? `#${data.hash}` : '';
4962			return `${host ? protocol : ''}${host}${host ? port : ''}${path}${query}${hash}`;
4963		}
4964	}
4965
4966	class Validation {
4967		static MAX_EMAIL_LENGTH = 254;
4968		static MAX_LOCAL_LENGTH = 64;
4969		static LOCAL_ALLOWED_CHARS = /^[\w%+.ЁА-яё-]+$/;
4970		static DOMAIN_LABEL_CHARS = /^[\w.ЁА-яё-]+$/;
4971		static isEmail(email) {
4972			if (!Type.isStringFilled(email)) {
4973				return false;
4974			}
4975			if (email.length > Validation.MAX_EMAIL_LENGTH) {
4976				return false;
4977			}
4978			const atPos = email.indexOf('@');
4979			if (atPos <= 0 || atPos === email.length - 1 || email.includes('@', atPos + 1)) {
4980				return false;
4981			}
4982			const local = email.slice(0, atPos);
4983			const domain = email.slice(atPos + 1);
4984			if (!Validation.LOCAL_ALLOWED_CHARS.test(local)) {
4985				return false;
4986			}
4987			if (local.startsWith('.') || local.endsWith('.') || local.startsWith('-') || local.endsWith('-') || local.includes('..') || local.length > Validation.MAX_LOCAL_LENGTH) {
4988				return false;
4989			}
4990			if (!Validation.DOMAIN_LABEL_CHARS.test(domain)) {
4991				return false;
4992			}
4993			if (domain.startsWith('.') || domain.endsWith('.') || domain.includes('..')) {
4994				return false;
4995			}
4996			const labels = domain.split('.');
4997			if (labels.length < 2) {
4998				return false;
4999			}
5000			const tld = labels[labels.length - 1];
5001			if (tld.length < 2 || tld.length > 24) {
5002				return false;
5003			}
5004			for (const label of labels) {
5005				if (label.startsWith('-') || label.endsWith('-')) {
5006					return false;
5007				}
5008				const startsWithLetterOrDigit = /^[\dA-Za-zЁА-яё]/.test(label);
5009				const endsWithLetterOrDigit = /[\dA-Za-zЁА-яё]$/.test(label);
5010				if (!startsWithLetterOrDigit || !endsWithLetterOrDigit) {
5011					return false;
5012				}
5013			}
5014			return true;
5015		}
5016	}
5017
5018	class BaseCache {
5019		storage = new Map();
5020		get(key, defaultValue) {
5021			if (!this.storage.has(key)) {
5022				if (Type.isFunction(defaultValue)) {
5023					return defaultValue();
5024				}
5025				if (!Type.isUndefined(defaultValue)) {
5026					return defaultValue;
5027				}
5028			}
5029			return this.storage.get(key);
5030		}
5031		set(key, value) {
5032			this.storage.set(key, value);
5033		}
5034		delete(key) {
5035			this.storage.delete(key);
5036		}
5037		has(key) {
5038			return this.storage.has(key);
5039		}
5040		remember(key, defaultValue) {
5041			if (!this.storage.has(key)) {
5042				if (Type.isFunction(defaultValue)) {
5043					this.storage.set(key, defaultValue());
5044				} else if (!Type.isUndefined(defaultValue)) {
5045					this.storage.set(key, defaultValue);
5046				}
5047			}
5048			return this.storage.get(key);
5049		}
5050		size() {
5051			return this.storage.size;
5052		}
5053		keys() {
5054			return [...this.storage.keys()];
5055		}
5056		values() {
5057			return [...this.storage.values()];
5058		}
5059	}
5060
5061	var MemoryStorage = Map;
5062
5063	class MemoryCache extends BaseCache {
5064		storage = new MemoryStorage();
5065	}
5066
5067	class LsStorage {
5068		stackKey = 'BX.Cache.Storage.LsStorage.stack';
5069		stack = null;
5070		getStack() {
5071			if (Type.isPlainObject(this.stack)) {
5072				return this.stack;
5073			}
5074			const stack = localStorage.getItem(this.stackKey);
5075			if (Type.isString(stack) && stack !== '') {
5076				const parsedStack = JSON.parse(stack);
5077				if (Type.isPlainObject(parsedStack)) {
5078					this.stack = parsedStack;
5079					return this.stack;
5080				}
5081			}
5082			this.stack = {};
5083			return this.stack;
5084		}
5085		saveStack() {
5086			if (Type.isPlainObject(this.stack)) {
5087				const preparedStack = JSON.stringify(this.stack);
5088				localStorage.setItem(this.stackKey, preparedStack);
5089			}
5090		}
5091		get(key) {
5092			const stack = this.getStack();
5093			return stack[key];
5094		}
5095		set(key, value) {
5096			const stack = this.getStack();
5097			stack[key] = value;
5098			this.saveStack();
5099		}
5100		delete(key) {
5101			const stack = this.getStack();
5102			if (key in stack) {
5103				delete stack[key];
5104			}
5105		}
5106		has(key) {
5107			const stack = this.getStack();
5108			return key in stack;
5109		}
5110		get size() {
5111			const stack = this.getStack();
5112			return Object.keys(stack).length;
5113		}
5114		keys() {
5115			const stack = this.getStack();
5116			return Object.keys(stack);
5117		}
5118		values() {
5119			const stack = this.getStack();
5120			return Object.values(stack);
5121		}
5122	}
5123
5124	class LocalStorageCache extends BaseCache {
5125		storage = new LsStorage();
5126	}
5127
5128	class Cache {
5129		static BaseCache = BaseCache;
5130		static MemoryCache = MemoryCache;
5131		static LocalStorageCache = LocalStorageCache;
5132	}
5133
5134	function convertPath(path) {
5135		if (Type.isStringFilled(path)) {
5136			return path.split('.').reduce((acc, item) => {
5137				item.split(/\[["']?(.+?)["']?]/g).forEach(key => {
5138					if (Type.isStringFilled(key)) {
5139						acc.push(key);
5140					}
5141				});
5142				return acc;
5143			}, []);
5144		}
5145		return [];
5146	}
5147
5148	class SettingsCollection {
5149		constructor(options = {}) {
5150			if (Type.isPlainObject(options)) {
5151				Object.assign(this, options);
5152			}
5153		}
5154		get(path, defaultValue = null) {
5155			const convertedPath = convertPath(path);
5156			return convertedPath.reduce((acc, key) => {
5157				if (!Type.isNil(acc) && acc !== defaultValue) {
5158					if (!Type.isUndefined(acc[key])) {
5159						return acc[key];
5160					}
5161					return defaultValue;
5162				}
5163				return acc;
5164			}, this);
5165		}
5166	}
5167
5168	function deepFreeze(target) {
5169		if (Type.isObject(target)) {
5170			Object.values(target).forEach(value => {
5171				deepFreeze(value);
5172			});
5173			return Object.freeze(target);
5174		}
5175		return target;
5176	}
5177
5178	const settingsStorage = new Map();
5179	class Extension {
5180		static getSettings(extensionName) {
5181			if (Type.isStringFilled(extensionName)) {
5182				if (settingsStorage.has(extensionName)) {
5183					return settingsStorage.get(extensionName);
5184				}
5185				const settingsScriptNode = document.querySelector(`script[data-extension="${extensionName}"]`);
5186				if (Type.isDomNode(settingsScriptNode)) {
5187					const decodedSettings = (() => {
5188						try {
5189							return new SettingsCollection(JSON.parse(settingsScriptNode.innerHTML));
5190						} catch {
5191							return new SettingsCollection();
5192						}
5193					})();
5194					const frozenSettings = deepFreeze(decodedSettings);
5195					settingsStorage.set(extensionName, frozenSettings);
5196					return frozenSettings;
5197				}
5198			}
5199			return deepFreeze(new SettingsCollection());
5200		}
5201	}
5202
5203	function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
5204	function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
5205	function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
5206	var _OrderedArray_brand = new WeakSet();
5207	let OrderedArray = function () {
5208		function OrderedArray(comparator = null) {
5209			babelHelpers.classCallCheck(this, OrderedArray);
5210			_classPrivateMethodInitSpec(this, _OrderedArray_brand);
5211			babelHelpers.defineProperty(this, "comparator", null);
5212			babelHelpers.defineProperty(this, "items", []);
5213			this.comparator = Type.isFunction(comparator) ? comparator : null;
5214		}
5215		return babelHelpers.createClass(OrderedArray, [{
5216			key: "add",
5217			value: function add(item) {
5218				let index = -1;
5219				if (this.comparator) {
5220					index = _assertClassBrand(_OrderedArray_brand, this, _searchIndexToInsert).call(this, item);
5221					this.items.splice(index, 0, item);
5222				} else {
5223					this.items.push(item);
5224				}
5225				return index;
5226			}
5227		}, {
5228			key: "has",
5229			value: function has(item) {
5230				return this.items.includes(item);
5231			}
5232		}, {
5233			key: "getIndex",
5234			value: function getIndex(item) {
5235				return this.items.indexOf(item);
5236			}
5237		}, {
5238			key: "getByIndex",
5239			value: function getByIndex(index) {
5240				if (Type.isNumber(index) && index >= 0) {
5241					const item = this.items[index];
5242					return Type.isUndefined(item) ? null : item;
5243				}
5244				return null;
5245			}
5246		}, {
5247			key: "getFirst",
5248			value: function getFirst() {
5249				const first = this.items[0];
5250				return Type.isUndefined(first) ? null : first;
5251			}
5252		}, {
5253			key: "getLast",
5254			value: function getLast() {
5255				const last = this.items[this.count() - 1];
5256				return Type.isUndefined(last) ? null : last;
5257			}
5258		}, {
5259			key: "count",
5260			value: function count() {
5261				return this.items.length;
5262			}
5263		}, {
5264			key: "delete",
5265			value: function _delete(item) {
5266				const index = this.getIndex(item);
5267				if (index !== -1) {
5268					this.items.splice(index, 1);
5269					return true;
5270				}
5271				return false;
5272			}
5273		}, {
5274			key: "clear",
5275			value: function clear() {
5276				this.items = [];
5277			}
5278		}, {
5279			key: Symbol.iterator,
5280			value: function () {
5281				return this.items[Symbol.iterator]();
5282			}
5283		}, {
5284			key: "forEach",
5285			value: function forEach(callbackfn, thisArg) {
5286				const callback = thisArg ? callbackfn.bind(thisArg) : callbackfn;
5287				this.items.forEach((value, index, array) => {
5288					callback(value, index, array);
5289				});
5290			}
5291		}, {
5292			key: "getAll",
5293			value: function getAll() {
5294				return this.items;
5295			}
5296		}, {
5297			key: "getComparator",
5298			value: function getComparator() {
5299				return this.comparator;
5300			}
5301		}, {
5302			key: "sort",
5303			value: function sort() {
5304				const comparator = this.getComparator();
5305				if (comparator === null) {
5306					return;
5307				}
5308				const length = this.items.length;
5309				const indexes = Array.from({
5310					length
5311				}, (_, i) => i);
5312				indexes.sort((index1, index2) => {
5313					return comparator(this.items[index1], this.items[index2]) || index1 - index2;
5314				});
5315				for (let i = 0; i < length; i++) {
5316					indexes[i] = this.items[indexes[i]];
5317				}
5318				for (let i = 0; i < length; i++) {
5319					this.items[i] = indexes[i];
5320				}
5321			}
5322		}]);
5323	}();
5324	function _searchIndexToInsert(value) {
5325		let low = 0;
5326		let high = this.items.length;
5327		while (low < high) {
5328			const mid = Math.floor((low + high) / 2);
5329			if (this.comparator(this.items[mid], value) >= 0) {
5330				high = mid;
5331			} else {
5332				low = mid + 1;
5333			}
5334		}
5335		return low;
5336	}
5337
5338	class ZIndexComponent extends EventEmitter {
5339		sort = 0;
5340		alwaysOnTop = false;
5341		zIndex = 0;
5342		element = null;
5343		overlay = null;
5344		overlayGap = -5;
5345		stack = null;
5346		constructor(element, componentOptions = {}) {
5347			super();
5348			this.setEventNamespace('BX.Main.ZIndexManager.Component');
5349			if (!Type.isElementNode(element)) {
5350				throw new Error("ZIndexManager.Component: The argument 'element' must be a DOM element.");
5351			}
5352			this.element = element;
5353			const options = Type.isPlainObject(componentOptions) ? componentOptions : {};
5354			this.setAlwaysOnTop(options.alwaysOnTop);
5355			this.setOverlay(options.overlay);
5356			this.setOverlayGap(options.overlayGap);
5357			this.subscribeFromOptions(options.events);
5358		}
5359		getSort() {
5360			return this.sort;
5361		}
5362		setSort(sort) {
5363			if (Type.isNumber(sort)) {
5364				this.sort = sort;
5365			}
5366		}
5367		setStack(stack) {
5368			this.stack = stack;
5369		}
5370		getStack() {
5371			return this.stack;
5372		}
5373		getZIndex() {
5374			return this.zIndex;
5375		}
5376		setZIndex(zIndex) {
5377			const changed = this.getZIndex() !== zIndex;
5378			this.getElement().style.setProperty('z-index', String(zIndex), 'important');
5379			this.zIndex = zIndex;
5380			if (this.getOverlay() !== null) {
5381				this.getOverlay().style.setProperty('z-index', String(zIndex + this.getOverlayGap()), 'important');
5382			}
5383			if (changed) {
5384				this.emit('onZIndexChange', {
5385					component: this
5386				});
5387			}
5388		}
5389		getAlwaysOnTop() {
5390			return this.alwaysOnTop;
5391		}
5392		setAlwaysOnTop(value) {
5393			if (Type.isNumber(value) || Type.isBoolean(value)) {
5394				this.alwaysOnTop = value;
5395			}
5396		}
5397		getElement() {
5398			return this.element;
5399		}
5400		setOverlay(overlay, gap) {
5401			if (Type.isElementNode(overlay) || overlay === null) {
5402				this.overlay = overlay;
5403				this.setOverlayGap(gap);
5404				if (this.getStack()) {
5405					this.getStack().sort();
5406				}
5407			}
5408		}
5409		getOverlay() {
5410			return this.overlay;
5411		}
5412		setOverlayGap(gap) {
5413			if (Type.isNumber(gap)) {
5414				this.overlayGap = gap;
5415			}
5416		}
5417		getOverlayGap() {
5418			return this.overlayGap;
5419		}
5420	}
5421
5422	class ZIndexStack {
5423		container;
5424		components;
5425		elements = new WeakMap();
5426		baseIndex = 1000;
5427		baseStep = 50;
5428		sortCount = 0;
5429		constructor(container) {
5430			if (!Type.isDomNode(container)) {
5431				throw new Error("ZIndexManager.Stack: The 'container' argument must be a DOM element.");
5432			}
5433			this.container = container;
5434			const comparator = (componentA, componentB) => {
5435				let result = (Number(componentA.getAlwaysOnTop()) || 0) - (Number(componentB.getAlwaysOnTop()) || 0);
5436				if (!result) {
5437					result = componentA.getSort() - componentB.getSort();
5438				}
5439				return result;
5440			};
5441			this.components = new OrderedArray(comparator);
5442		}
5443		getBaseIndex() {
5444			return this.baseIndex;
5445		}
5446		setBaseIndex(index) {
5447			if (Type.isNumber(index) && index >= 0) {
5448				this.baseIndex = index;
5449				this.sort();
5450			}
5451		}
5452		setBaseStep(step) {
5453			if (Type.isNumber(step) && step > 0) {
5454				this.baseStep = step;
5455				this.sort();
5456			}
5457		}
5458		getBaseStep() {
5459			return this.baseStep;
5460		}
5461		register(element, options = {}) {
5462			if (this.getComponent(element)) {
5463				console.warn('ZIndexManager: You cannot register the element twice.', element);
5464				return this.getComponent(element);
5465			}
5466			const component = new ZIndexComponent(element, options);
5467			component.setStack(this);
5468			component.setSort(++this.sortCount);
5469			this.elements.set(element, component);
5470			this.components.add(component);
5471			this.sort();
5472			return component;
5473		}
5474		unregister(element) {
5475			const component = this.elements.get(element);
5476			this.components.delete(component);
5477			this.elements.delete(element);
5478			this.sort();
5479		}
5480		getComponent(element) {
5481			return this.elements.get(element) || null;
5482		}
5483		getComponents() {
5484			return this.components.getAll();
5485		}
5486		getMaxZIndex() {
5487			const last = this.components.getLast();
5488			return last ? last.getZIndex() : this.baseIndex;
5489		}
5490		sort() {
5491			this.components.sort();
5492			let zIndex = this.baseIndex;
5493			this.components.forEach(component => {
5494				component.setZIndex(zIndex);
5495				zIndex += this.baseStep;
5496			});
5497		}
5498		bringToFront(element) {
5499			const component = this.getComponent(element);
5500			if (!component) {
5501				console.error('ZIndexManager: element was not found in the stack.', element);
5502				return null;
5503			}
5504			component.setSort(++this.sortCount);
5505			this.sort();
5506			return component;
5507		}
5508	}
5509
5510	class ZIndexManager {
5511		static stacks = new WeakMap();
5512		static register(element, options = {}) {
5513			const parentNode = this.#getParentNode(element);
5514			if (!parentNode) {
5515				return null;
5516			}
5517			const stack = this.getOrAddStack(parentNode);
5518			return stack.register(element, options);
5519		}
5520		static unregister(element) {
5521			const parentNode = this.#getParentNode(element);
5522			const stack = this.getStack(parentNode);
5523			if (stack) {
5524				stack.unregister(element);
5525			}
5526		}
5527		static addStack(container) {
5528			const stack = new ZIndexStack(container);
5529			this.stacks.set(container, stack);
5530			return stack;
5531		}
5532		static getStack(container) {
5533			return this.stacks.get(container) || null;
5534		}
5535		static getOrAddStack(container) {
5536			return this.getStack(container) || this.addStack(container);
5537		}
5538		static getComponent(element) {
5539			const parentNode = this.#getParentNode(element, true);
5540			if (!parentNode) {
5541				return null;
5542			}
5543			const stack = this.getStack(parentNode);
5544			return stack ? stack.getComponent(element) : null;
5545		}
5546		static bringToFront(element) {
5547			const parentNode = this.#getParentNode(element);
5548			const stack = this.getStack(parentNode);
5549			if (stack) {
5550				return stack.bringToFront(element);
5551			}
5552			return null;
5553		}
5554		static #getParentNode(element, suppressWarnings = false) {
5555			if (!Type.isElementNode(element)) {
5556				if (!suppressWarnings) {
5557					console.error("ZIndexManager: The argument 'element' must be a DOM element.", element);
5558				}
5559				return null;
5560			}
5561			if (!Type.isElementNode(element.parentNode)) {
5562				if (!suppressWarnings) {
5563					console.error("ZIndexManager: The 'element' doesn't have a parent node.", element);
5564				}
5565				return null;
5566			}
5567			return element.parentNode;
5568		}
5569	}
5570
5571	const IS_WEAK_REF_SUPPORTED = typeof WeakRef !== 'undefined';
5572	class WeakRefMap {
5573		#refs = new Map();
5574		#registry = null;
5575		constructor() {
5576			if (IS_WEAK_REF_SUPPORTED) {
5577				this.#registry = new FinalizationRegistry(this.#cleanupCallback.bind(this));
5578			}
5579		}
5580		clear() {
5581			if (!IS_WEAK_REF_SUPPORTED) {
5582				this.#refs.clear();
5583				return;
5584			}
5585			this.#refs.forEach(ref => {
5586				const value = ref.deref();
5587				if (!Type.isUndefined(value)) {
5588					this.#registry.unregister(value);
5589				}
5590			});
5591			this.#refs.clear();
5592		}
5593		delete(key) {
5594			if (!IS_WEAK_REF_SUPPORTED) {
5595				return this.#refs.delete(key);
5596			}
5597			const value = this.get(key);
5598			if (!Type.isUndefined(value)) {
5599				this.#registry.unregister(value);
5600			}
5601			return this.#refs.delete(key);
5602		}
5603		get(key) {
5604			if (!IS_WEAK_REF_SUPPORTED) {
5605				return this.#refs.get(key);
5606			}
5607			return this.#refs.get(key)?.deref();
5608		}
5609		has(key) {
5610			if (!IS_WEAK_REF_SUPPORTED) {
5611				return this.#refs.has(key);
5612			}
5613			return !Type.isUndefined(this.#refs.get(key)?.deref());
5614		}
5615		set(key, value) {
5616			if (!IS_WEAK_REF_SUPPORTED) {
5617				this.#refs.set(key, value);
5618				return this;
5619			}
5620			this.#refs.set(key, new WeakRef(value));
5621			this.#registry.register(value, key, value);
5622			return this;
5623		}
5624		#cleanupCallback(key) {
5625			const ref = this.#refs.get(key);
5626			if (ref && !ref.deref()) {
5627				this.#refs.delete(key);
5628			}
5629		}
5630	}
5631
5632	var collections = {
5633		OrderedArray,
5634		SettingsCollection,
5635		WeakRefMap
5636	};
5637
5638	class Transition {
5639		static linear(progress) {
5640			return progress;
5641		}
5642		static quad(progress) {
5643			return progress ** 2;
5644		}
5645		static cubic(progress) {
5646			return progress ** 3;
5647		}
5648		static quart(progress) {
5649			return progress ** 4;
5650		}
5651		static quint(progress) {
5652			return progress ** 5;
5653		}
5654		static circ(progress) {
5655			return 1 - Math.sin(Math.acos(progress));
5656		}
5657		static back(progress) {
5658			return progress ** 2 * ((1.5 + 1) * progress - 1.5);
5659		}
5660		static elasti(progress) {
5661			return 2 ** (10 * (progress - 1)) * Math.cos(20 * Math.PI * 1.5 / 3 * progress);
5662		}
5663		static bounce(progress) {
5664			for (let a = 0, b = 1;; a += b, b /= 2) {
5665				if (progress >= (7 - 4 * a) / 11) {
5666					return -(((11 - 6 * a - 11 * progress) / 4) ** 2) + b ** 2;
5667				}
5668			}
5669		}
5670	}
5671
5672	class Easing {
5673		#duration = 1000;
5674		#transition = Transition.linear;
5675		#begin = null;
5676		#step = null;
5677		#complete = null;
5678		#start = {};
5679		#finish = {};
5680		#currentState = {};
5681		#progress = null;
5682		#timer = null;
5683		#options = null;
5684		constructor(easingOptions) {
5685			this.setOptions(easingOptions);
5686		}
5687		setOptions(easingOptions) {
5688			const options = Type.isPlainObject(easingOptions) ? easingOptions : {};
5689			this.#duration = Type.isNumber(options.duration) && options.duration > 0 ? options.duration : this.#duration;
5690			this.#begin = Type.isFunction(options.begin) || options.begin === null ? options.begin : this.#begin;
5691			this.#step = Type.isFunction(options.step) || options.step === null ? options.step : this.#step;
5692			this.#complete = Type.isFunction(options.complete) || options.complete === null ? options.complete : this.#complete;
5693			this.#progress = Type.isFunction(options.progress) || options.progress === null ? options.progress : this.#progress;
5694			this.#start = Type.isPlainObject(options.start) ? {
5695				...options.start
5696			} : this.#start;
5697			this.#finish = Type.isPlainObject(options.finish) ? {
5698				...options.finish
5699			} : this.#finish;
5700		}
5701		setTransition(transition) {
5702			if (Type.isFunction(transition)) {
5703				this.#transition = transition;
5704			} else if (Type.isStringFilled(transition)) {
5705				let funcName = transition;
5706				let decorator = null;
5707				if (transition.startsWith('ease-out-')) {
5708					funcName = funcName.replace('ease-out-', '');
5709					decorator = Easing.makeEaseOut;
5710				} else if (transition.startsWith('ease-in-out-')) {
5711					funcName = funcName.replace('ease-in-out-', '');
5712					decorator = Easing.makeEaseInOut;
5713				}
5714				if (Type.isFunction(Transition[funcName])) {
5715					this.#transition = decorator === null ? Transition[funcName] : decorator(Transition[funcName]);
5716				}
5717			}
5718		}
5719		animateProgress() {
5720			this.#animate();
5721		}
5722		animate() {
5723			this.#progress = progress => {
5724				this.#currentState = {};
5725				for (const propName of Object.keys(this.#start)) {
5726					this.#currentState[propName] = Math.round(this.#start[propName] + (this.#finish[propName] - this.#start[propName]) * progress);
5727				}
5728				if (this.#step !== null) {
5729					this.#step(this.#currentState);
5730				}
5731			};
5732			this.#animate();
5733		}
5734		#animate() {
5735			for (const propName of Object.keys(this.#start)) {
5736				if (Type.isUndefined(this.#finish[propName])) {
5737					delete this.#start[propName];
5738				}
5739			}
5740			let start = null;
5741			const animation = time => {
5742				if (start === null) {
5743					start = time;
5744				}
5745				let progress = (time - start) / this.#duration;
5746				if (progress > 1) {
5747					progress = 1;
5748				}
5749				const delta = this.#transition(progress);
5750				this.#progress(delta);
5751				if (progress === 1) {
5752					this.stop(true);
5753				} else {
5754					this.#timer = requestAnimationFrame(animation);
5755				}
5756			};
5757			if (this.#begin !== null) {
5758				this.#begin(this.#currentState);
5759			}
5760			this.#timer = requestAnimationFrame(animation);
5761		}
5762		get options() {
5763			if (this.#options === null) {
5764				this.#options = new Proxy(this, {
5765					get(target, property, receiver) {
5766						switch (property) {
5767							case 'transition':
5768								return target.#transition;
5769							case 'start':
5770								return target.#start;
5771							case 'finish':
5772								return target.#finish;
5773							case 'duration':
5774								return target.#duration;
5775							default:
5776								return null;
5777						}
5778					},
5779					set(target, property, value, receiver) {
5780						target.setOptions({
5781							[property]: value
5782						});
5783						return true;
5784					}
5785				});
5786			}
5787			return this.#options;
5788		}
5789		stop(completed = false) {
5790			if (this.#timer !== null) {
5791				cancelAnimationFrame(this.#timer);
5792				this.#timer = null;
5793				if (completed && this.#complete !== null) {
5794					this.#complete(this.#currentState);
5795				}
5796			}
5797		}
5798		static makeEaseInOut(delta) {
5799			return progress => {
5800				if (progress < 0.5) {
5801					return delta(2 * progress) / 2;
5802				}
5803				return (2 - delta(2 * (1 - progress))) / 2;
5804			};
5805		}
5806		static makeEaseOut(delta) {
5807			return progress => {
5808				return 1 - delta(1 - progress);
5809			};
5810		}
5811		static get transitions() {
5812			return Transition;
5813		}
5814	}
5815
5816	class LocalStorage {
5817		#prefix = null;
5818		constructor(storageOptions = {}) {
5819			const options = Type.isPlainObject(storageOptions) ? storageOptions : {};
5820			this.#setPrefix(options.prefix);
5821			Event.bind(window, 'storage', this.#handleStorageChange.bind(this));
5822			setInterval(this.#clear.bind(this), 5000);
5823		}
5824		set(key, value, ttl = 60) {
5825			if (!Type.isStringFilled(key) || Type.isNil(value)) {
5826				return false;
5827			}
5828			try {
5829				window.localStorage.setItem(this.getPrefix() + key, `${Math.round(Date.now() / 1000) + ttl}:${this.#encode(value)}`);
5830			} catch {
5831				console.error('LocalStorage error', key, ttl);
5832				return false;
5833			}
5834			return true;
5835		}
5836		get(key) {
5837			const storageValue = window.localStorage.getItem(this.getPrefix() + key);
5838			if (storageValue) {
5839				const valueParts = this.#parseValue(storageValue);
5840				if (valueParts === null) {
5841					return null;
5842				}
5843				const [ttl, value] = valueParts;
5844				if (Date.now() <= ttl) {
5845					return this.#decode(value);
5846				}
5847				this.remove(key);
5848			}
5849			return null;
5850		}
5851		remove(key) {
5852			window.localStorage.removeItem(this.getPrefix() + key);
5853		}
5854		getPrefix() {
5855			if (this.#prefix === null) {
5856				const userId = Loc.hasMessage('USER_ID') ? Loc.getMessage('USER_ID') : '';
5857				const siteId = Loc.hasMessage('SITE_ID') ? Loc.getMessage('SITE_ID') : 'admin';
5858				this.#prefix = `${this.getBasePrefix()}${userId}-${siteId}-`;
5859			}
5860			return this.#prefix;
5861		}
5862		getBasePrefix() {
5863			return 'bx';
5864		}
5865		#setPrefix(prefix) {
5866			if (Type.isString(prefix)) {
5867				this.#prefix = `${this.getBasePrefix()}-${prefix}`;
5868			}
5869		}
5870		#handleStorageChange(event) {
5871			if (!Type.isStringFilled(event.key) || !event.key.startsWith(this.getPrefix())) {
5872				return;
5873			}
5874			const key = event.key.slice(this.getPrefix().length);
5875			const value = this.#getRealValue(event.newValue);
5876			const oldValue = this.#getRealValue(event.oldValue);
5877			const data = {
5878				key,
5879				value,
5880				oldValue
5881			};
5882			if (key === 'BXGCE') {
5883				if (value) {
5884					const val = data.value;
5885					EventEmitter.emit(val.e, new BaseEvent({
5886						data: val.p,
5887						compatData: val.p
5888					}));
5889				}
5890			} else {
5891				if (event.newValue) {
5892					EventEmitter.emit('onLocalStorageSet', new BaseEvent({
5893						data: [data],
5894						compatData: [data]
5895					}));
5896				}
5897				if (event.oldValue && !event.newValue) {
5898					EventEmitter.emit('onLocalStorageRemove', new BaseEvent({
5899						data: [data],
5900						compatData: [data]
5901					}));
5902				}
5903				EventEmitter.emit('onLocalStorageChange', new BaseEvent({
5904					data: [data],
5905					compatData: [data]
5906				}));
5907			}
5908		}
5909		#clear() {
5910			const curDate = Date.now();
5911			for (let i = 0; i < window.localStorage.length; i++) {
5912				const key = window.localStorage.key(i);
5913				if (key !== null && key.startsWith(this.getBasePrefix())) {
5914					const value = window.localStorage.getItem(key);
5915					const valueParts = this.#parseValue(value);
5916					if (valueParts === null) {
5917						continue;
5918					}
5919					const [ttl] = valueParts;
5920					if (curDate >= ttl) {
5921						window.localStorage.removeItem(key);
5922					}
5923				}
5924			}
5925		}
5926		#encode(value) {
5927			if (Type.isJsonValue(value)) {
5928				return JSON.stringify(value);
5929			}
5930			return value.toString();
5931		}
5932		#decode(value) {
5933			let result = null;
5934			if (Type.isStringFilled(value)) {
5935				try {
5936					result = JSON.parse(value);
5937				} catch {
5938					result = value;
5939				}
5940			}
5941			return result;
5942		}
5943		#getRealValue(value) {
5944			const valueParts = this.#parseValue(value);
5945			if (valueParts === null) {
5946				return null;
5947			}
5948			return this.#decode(valueParts[1]);
5949		}
5950		#parseValue(value) {
5951			if (!this.#isValueValid(value)) {
5952				return null;
5953			}
5954			const [ttl] = value.split(':', 1);
5955			const realValue = value.slice(ttl.length + 1);
5956			return [parseInt(ttl, 10) * 1000, realValue];
5957		}
5958		#isValueValid(value) {
5959			return Type.isStringFilled(value) && /^\d{10}:/.test(value);
5960		}
5961	}
5962	const localStorage$1 = new LocalStorage();
5963
5964	class Page {
5965		static getRootWindow() {
5966			return this.getTopWindowOfCurrentHost(window);
5967		}
5968		static isCrossOriginObject(currentWindow) {
5969			try {
5970				void currentWindow.location.host;
5971			} catch {
5972				return true;
5973			}
5974			return false;
5975		}
5976		static getTopWindowOfCurrentHost(currentWindow) {
5977			if (!this.isCrossOriginObject(currentWindow.parent) && currentWindow.parent !== currentWindow && currentWindow.parent.location.host === currentWindow.location.host) {
5978				return this.getTopWindowOfCurrentHost(currentWindow.parent);
5979			}
5980			return currentWindow;
5981		}
5982		static getParentWindowOfCurrentHost(currentWindow) {
5983			if (this.isCrossOriginObject(currentWindow.parent)) {
5984				return currentWindow;
5985			}
5986			return currentWindow.parent;
5987		}
5988		static redirect(redirectUrl, redirectOptions = {}) {
5989			if (!Type.isStringFilled(redirectUrl)) {
5990				throw new Error('Redirect: "url" must be a non-empty string.');
5991			}
5992			const rootWindow = this.getRootWindow();
5993			let url = null;
5994			try {
5995				url = new URL(redirectUrl, rootWindow.location.origin);
5996			} catch {
5997				throw new Error(`Redirect: invalid URL: ${redirectUrl}`);
5998			}
5999			const options = Type.isPlainObject(redirectOptions) ? redirectOptions : {};
6000			if (!this.#isSafeUrl(url, options.allowedOrigins)) {
6001				console.error(`Redirect: blocked potentially unsafe URL: ${url}`);
6002				return;
6003			}
6004			const wholeUrl = url.toString();
6005			if (options.newTab === true) {
6006				const win = rootWindow.open(wholeUrl, '_blank', 'noopener,noreferrer');
6007				if (win) {
6008					win.opener = null;
6009				}
6010				return;
6011			}
6012			if (options.replaceHistory === true) {
6013				rootWindow.location.replace(wholeUrl);
6014			} else {
6015				rootWindow.location.assign(wholeUrl);
6016			}
6017		}
6018		static reload() {
6019			const rootWindow = this.getRootWindow();
6020			rootWindow.location.reload();
6021		}
6022		static #isSafeUrl(url, allowedOrigins = []) {
6023			if (!(url instanceof URL)) {
6024				return false;
6025			}
6026			const allowedProtocols = ['http:', 'https:'];
6027			if (!allowedProtocols.includes(url.protocol)) {
6028				return false;
6029			}
6030			const rootWindow = this.getRootWindow();
6031			if (url.origin === rootWindow.location.origin) {
6032				return true;
6033			}
6034			if (Type.isArray(allowedOrigins) && allowedOrigins.length > 0) {
6035				return allowedOrigins.includes(url.origin);
6036			}
6037			return false;
6038		}
6039	}
6040
6041	function getElement(element) {
6042		if (Type.isString(element)) {
6043			return document.getElementById(element);
6044		}
6045		return element;
6046	}
6047
6048	function getWindow(element) {
6049		if (Type.isElementNode(element)) {
6050			return element.ownerDocument.parentWindow || element.ownerDocument.defaultView || window;
6051		}
6052		if (Type.isDomNode(element)) {
6053			return element.parentWindow || element.defaultView || window;
6054		}
6055		return window;
6056	}
6057
6058	class FX {
6059		#easing = null;
6060		constructor(options) {
6061			const fxOptions = Type.isPlainObject(options) ? options : {};
6062			const callback = Type.isFunction(fxOptions.callback) ? fxOptions.callback : null;
6063			const callbackStart = Type.isFunction(fxOptions.callback_start) ? fxOptions.callback_start : null;
6064			const callbackComplete = Type.isFunction(fxOptions.callback_complete) ? fxOptions.callback_complete : null;
6065			const easingOptions = {
6066				transition: 'linear',
6067				duration: Type.isNumber(fxOptions.time) && fxOptions.time > 0 ? fxOptions.time * 1000 : 1000,
6068				begin: state => {
6069					if (callbackStart !== null) {
6070						callbackStart(Type.isUndefined(state._param) ? state : state._param);
6071					}
6072				},
6073				step: state => {
6074					if (callback !== null) {
6075						callback(Type.isUndefined(state._param) ? state : state._param);
6076					}
6077				},
6078				complete: state => {
6079					if (callbackComplete !== null) {
6080						callbackComplete(Type.isUndefined(state._param) ? state : state._param);
6081					}
6082				}
6083			};
6084			if (Type.isPlainObject(fxOptions.start)) {
6085				easingOptions.start = fxOptions.start;
6086				easingOptions.finish = fxOptions.finish;
6087			} else {
6088				easingOptions.start = {
6089					_param: fxOptions.start
6090				};
6091				easingOptions.finish = {
6092					_param: fxOptions.finish
6093				};
6094			}
6095			if (fxOptions.type === 'accelerated') {
6096				easingOptions.transition = 'quint';
6097			} else if (fxOptions.type === 'decelerated') {
6098				fxOptions.transition = 'ease-out-quint';
6099			}
6100			this.#easing = new Easing(easingOptions);
6101		}
6102		start() {
6103			this.#easing.animate();
6104			return this;
6105		}
6106		stop(silent = false) {
6107			this.#easing.stop(silent);
6108		}
6109		pause() {
6110		}
6111		static hide(el, type, opts) {
6112			return this.#toggle('hide', el, type, opts);
6113		}
6114		static show(el, type, opts) {
6115			return this.#toggle('show', el, type, opts);
6116		}
6117		static #toggle(mode, el, type, opts) {
6118			let options = {};
6119			let effect = null;
6120			const element = Type.isStringFilled(el) ? document.getElementById(el) : el;
6121			if (Type.isPlainObject(type) && Type.isNil(opts)) {
6122				options = type;
6123				effect = options.type;
6124			} else if (Type.isPlainObject(opts)) {
6125				options = opts;
6126				effect = type;
6127			}
6128			if (!Type.isStringFilled(effect)) {
6129				Dom.style(element, 'display', mode === 'show' ? 'block' : 'none');
6130				return undefined;
6131			}
6132			const fxOptions = effect === 'scroll' ? this.#scroll(element, options, mode) : this.#fade(element, options, mode);
6133			fxOptions.callback_complete = () => {
6134				if (options.show !== false && options.hide !== false) {
6135					Dom.style(element, 'display', mode === 'show' ? 'block' : 'none');
6136				}
6137				if (options.callback_complete) {
6138					options.callback_complete();
6139				}
6140			};
6141			return new FX(fxOptions).start();
6142		}
6143		static #scroll(el, opts, mode) {
6144			const param = opts.direction === 'horizontal' ? 'width' : 'height';
6145			let currentValue = parseInt(String(Dom.style(el, param)), 10);
6146			if (Number.isNaN(currentValue)) {
6147				currentValue = Dom.getPosition(el)[param];
6148			}
6149			const start = currentValue;
6150			const finish = opts.min_height ? parseInt(opts.min_height, 10) : 0;
6151			return {
6152				start,
6153				finish,
6154				time: opts.time || 1,
6155				type: 'linear',
6156				callback_start: () => {
6157					if (Dom.style(el, 'position') === 'static') {
6158						Dom.style(el, 'position', 'relative');
6159					}
6160					Dom.style(el, 'overflow', 'hidden');
6161					Dom.style(el, param, `${start}px`);
6162					Dom.style(el, 'display', 'block');
6163				},
6164				callback: value => {
6165					Dom.style(el, param, `${value}px`);
6166				}
6167			};
6168		}
6169		static #fade(element, opts, mode) {
6170			return {
6171				time: opts.time || 1,
6172				type: mode === 'show' ? 'linear' : 'decelerated',
6173				start: mode === 'show' ? 0 : 100,
6174				finish: mode === 'show' ? 100 : 0,
6175				callback_start: () => {
6176					Dom.style(element, 'display', 'block');
6177				},
6178				callback: val => {
6179					Dom.style(element, 'opacity', val / 100);
6180				}
6181			};
6182		}
6183	}
6184
6185	const {
6186		getClass,
6187		namespace
6188	} = Reflection;
6189	const message = message$1;
6190	const easing = Easing;
6191	const fx = FX;
6192	const PageObject = Page;
6193	const {
6194		replace,
6195		remove,
6196		clean,
6197		insertBefore,
6198		insertAfter,
6199		append,
6200		prepend,
6201		style,
6202		adjust,
6203		create,
6204		isShown
6205	} = Dom;
6206	const addClass = function addClass() {
6207		Dom.addClass(...Runtime.merge([], Array.from(arguments), [getElement(arguments[0])]));
6208	};
6209	const removeClass = function removeClass() {
6210		Dom.removeClass(...Runtime.merge(Array.from(arguments), [getElement(arguments[0])]));
6211	};
6212	const hasClass = function hasClass() {
6213		return Dom.hasClass(...Runtime.merge(Array.from(arguments), [getElement(arguments[0])]));
6214	};
6215	const toggleClass = function toggleClass() {
6216		Dom.toggleClass(...Runtime.merge(Array.from(arguments), [getElement(arguments[0])]));
6217	};
6218	const cleanNode = (element, removeElement = false) => {
6219		const currentElement = getElement(element);
6220		if (Type.isDomNode(currentElement)) {
6221			Dom.clean(currentElement);
6222			if (removeElement) {
6223				Dom.remove(currentElement);
6224				return currentElement;
6225			}
6226		}
6227		return currentElement;
6228	};
6229	const getCookie = Http.Cookie.get;
6230	const setCookie = (name, value, options = {}) => {
6231		const attributes = {
6232			...options
6233		};
6234		if (Type.isNumber(attributes.expires)) {
6235			attributes.expires /= 3600 * 24;
6236		}
6237		Http.Cookie.set(name, value, attributes);
6238	};
6239	const {
6240		bind,
6241		unbind,
6242		unbindAll,
6243		bindOnce,
6244		ready
6245	} = Event;
6246	const {
6247		debugState: debugEnableFlag,
6248		isDebugEnabled: debugStatus,
6249		default: debug
6250	} = debugNs;
6251	const debugEnable = value => {
6252		if (value) {
6253			enableDebug();
6254		} else {
6255			disableDebug();
6256		}
6257	};
6258	const {
6259		clone,
6260		loadExtension: loadExt,
6261		debounce,
6262		throttle,
6263		html
6264	} = Runtime;
6265	const type = {
6266		...Object.getOwnPropertyNames(Type).filter(key => !['name', 'length', 'prototype', 'caller', 'arguments'].includes(key)).reduce((acc, key) => {
6267			acc[key] = Type[key];
6268			return acc;
6269		}, {}),
6270		isNotEmptyString: value => Type.isString(value) && value !== '',
6271		isNotEmptyObject: value => Type.isObjectLike(value) && Object.keys(value).length > 0,
6272		isMapKey: Type.isObject,
6273		stringToInt: value => {
6274			const parsed = parseInt(value);
6275			return !Number.isNaN(parsed) ? parsed : 0;
6276		}
6277	};
6278	const browser = {
6279		IsOpera: Browser.isOpera,
6280		IsIE: Browser.isIE,
6281		IsIE6: Browser.isIE6,
6282		IsIE7: Browser.isIE7,
6283		IsIE8: Browser.isIE8,
6284		IsIE9: Browser.isIE9,
6285		IsIE10: Browser.isIE10,
6286		IsIE11: Browser.isIE11,
6287		IsSafari: Browser.isSafari,
6288		IsFirefox: Browser.isFirefox,
6289		IsChrome: Browser.isChrome,
6290		DetectIeVersion: Browser.detectIEVersion,
6291		IsMac: Browser.isMac,
6292		IsAndroid: Browser.isAndroid,
6293		isIPad: Browser.isIPad,
6294		isIPhone: Browser.isIPhone,
6295		IsIOS: Browser.isIOS,
6296		IsMobile: Browser.isMobile,
6297		isRetina: Browser.isRetina,
6298		IsDoctype: Browser.isDoctype,
6299		SupportLocalStorage: Browser.isLocalStorageSupported,
6300		addGlobalClass: Browser.addGlobalClass,
6301		DetectAndroidVersion: Browser.detectAndroidVersion,
6302		isPropertySupported: Browser.isPropertySupported,
6303		addGlobalFeatures: Browser.addGlobalFeatures
6304	};
6305	const ajax = window.BX ? window.BX.ajax : () => {};
6306	function GetWindowScrollSize(doc = document) {
6307		return {
6308			scrollWidth: doc.documentElement.scrollWidth,
6309			scrollHeight: doc.documentElement.scrollHeight
6310		};
6311	}
6312	function GetWindowScrollPos(doc = document) {
6313		const win = getWindow(doc);
6314		return {
6315			scrollLeft: win.pageXOffset,
6316			scrollTop: win.pageYOffset
6317		};
6318	}
6319	function GetWindowInnerSize(doc = document) {
6320		const win = getWindow(doc);
6321		return {
6322			innerWidth: win.innerWidth,
6323			innerHeight: win.innerHeight
6324		};
6325	}
6326	function GetWindowSize(doc = document) {
6327		return {
6328			...GetWindowInnerSize(doc),
6329			...GetWindowScrollPos(doc),
6330			...GetWindowScrollSize(doc)
6331		};
6332	}
6333	function GetContext(node) {
6334		return getWindow(node);
6335	}
6336	function pos(element, relative = false) {
6337		if (!element) {
6338			return new DOMRect().toJSON();
6339		}
6340		if (element.ownerDocument === document && !relative) {
6341			const clientRect = element.getBoundingClientRect();
6342			const root = document.documentElement;
6343			const {
6344				body
6345			} = document;
6346			return {
6347				top: Math.round(clientRect.top + (root.scrollTop || body.scrollTop)),
6348				left: Math.round(clientRect.left + (root.scrollLeft || body.scrollLeft)),
6349				width: Math.round(clientRect.right - clientRect.left),
6350				height: Math.round(clientRect.bottom - clientRect.top),
6351				right: Math.round(clientRect.right + (root.scrollLeft || body.scrollLeft)),
6352				bottom: Math.round(clientRect.bottom + (root.scrollTop || body.scrollTop))
6353			};
6354		}
6355		let x = 0;
6356		let y = 0;
6357		const w = element.offsetWidth;
6358		const h = element.offsetHeight;
6359		let first = true;
6360		for (; element != null; element = element.offsetParent) {
6361			if (!first && relative && window.BX.is_relative(element)) {
6362				break;
6363			}
6364			x += element.offsetLeft;
6365			y += element.offsetTop;
6366			if (first) {
6367				first = false;
6368				continue;
6369			}
6370			x += Text.toNumber(Dom.style(element, 'border-left-width'));
6371			y += Text.toNumber(Dom.style(element, 'border-top-width'));
6372		}
6373		return new DOMRect(x, y, w, h).toJSON();
6374	}
6375	function addCustomEvent(eventObject, eventName, eventHandler) {
6376		if (Type.isString(eventObject)) {
6377			eventHandler = eventName;
6378			eventName = eventObject;
6379			eventObject = EventEmitter.GLOBAL_TARGET;
6380		}
6381		if (eventObject === window) {
6382			eventObject = EventEmitter.GLOBAL_TARGET;
6383		}
6384		if (!Type.isObject(eventObject)) {
6385			console.error('The "eventObject" argument must be an object. Received type ' + typeof eventObject + '.');
6386			return;
6387		}
6388		if (!Type.isStringFilled(eventName)) {
6389			console.error('The "eventName" argument must be a string.');
6390			return;
6391		}
6392		if (!Type.isFunction(eventHandler)) {
6393			console.error('The "eventHandler" argument must be a function. Received type ' + typeof eventHandler + '.');
6394			return;
6395		}
6396		eventName = eventName.toLowerCase();
6397		EventEmitter.subscribe(eventObject, eventName, eventHandler, {
6398			compatMode: true,
6399			useGlobalNaming: true
6400		});
6401	}
6402	function onCustomEvent(eventObject, eventName, eventParams, secureParams) {
6403		if (Type.isString(eventObject)) {
6404			secureParams = eventParams;
6405			eventParams = eventName;
6406			eventName = eventObject;
6407			eventObject = EventEmitter.GLOBAL_TARGET;
6408		}
6409		if (!Type.isObject(eventObject) || eventObject === window) {
6410			eventObject = EventEmitter.GLOBAL_TARGET;
6411		}
6412		if (!eventParams) {
6413			eventParams = [];
6414		}
6415		eventName = eventName.toLowerCase();
6416		const event = new BaseEvent();
6417		event.setData(eventParams);
6418		event.setCompatData(eventParams);
6419		EventEmitter.emit(eventObject, eventName, event, {
6420			cloneData: secureParams === true,
6421			useGlobalNaming: true
6422		});
6423	}
6424	function removeCustomEvent(eventObject, eventName, eventHandler) {
6425		if (Type.isString(eventObject)) {
6426			eventHandler = eventName;
6427			eventName = eventObject;
6428			eventObject = EventEmitter.GLOBAL_TARGET;
6429		}
6430		if (!Type.isFunction(eventHandler)) {
6431			console.error('The "eventHandler" argument must be a function. Received type ' + typeof eventHandler + '.');
6432			return;
6433		}
6434		if (eventObject === window) {
6435			eventObject = EventEmitter.GLOBAL_TARGET;
6436		}
6437		eventName = eventName.toLowerCase();
6438		EventEmitter.unsubscribe(eventObject, eventName, eventHandler, {
6439			useGlobalNaming: true
6440		});
6441	}
6442	function removeAllCustomEvents(eventObject, eventName) {
6443		if (Type.isString(eventObject)) {
6444			eventName = eventObject;
6445			eventObject = EventEmitter.GLOBAL_TARGET;
6446		}
6447		if (eventObject === window) {
6448			eventObject = EventEmitter.GLOBAL_TARGET;
6449		}
6450		eventName = eventName.toLowerCase();
6451		EventEmitter.unsubscribeAll(eventObject, eventName, {
6452			useGlobalNaming: true
6453		});
6454	}
6455	function onGlobalCustomEvent(eventName, arEventParams, bSkipSelf) {
6456		localStorage$1.set('BXGCE', {
6457			e: eventName,
6458			p: arEventParams
6459		}, 1);
6460		if (!bSkipSelf) {
6461			onCustomEvent(eventName, arEventParams);
6462		}
6463	}
6464
6465	exports.BaseError = BaseError;
6466	exports.Browser = Browser;
6467	exports.Cache = Cache;
6468	exports.Collections = collections;
6469	exports.Dom = Dom;
6470	exports.Easing = Easing;
6471	exports.Event = Event;
6472	exports.Extension = Extension;
6473	exports.GetContext = GetContext;
6474	exports.GetWindowInnerSize = GetWindowInnerSize;
6475	exports.GetWindowScrollPos = GetWindowScrollPos;
6476	exports.GetWindowScrollSize = GetWindowScrollSize;
6477	exports.GetWindowSize = GetWindowSize;
6478	exports.Http = Http;
6479	exports.Loc = Loc;
6480	exports.LocalStorage = LocalStorage;
6481	exports.Page = Page;
6482	exports.PageObject = PageObject;
6483	exports.Reflection = Reflection;
6484	exports.Runtime = Runtime;
6485	exports.Tag = Tag;
6486	exports.Text = Text;
6487	exports.Type = Type;
6488	exports.Uri = Uri;
6489	exports.Validation = Validation;
6490	exports.ZIndexManager = ZIndexManager;
6491	exports.addClass = addClass;
6492	exports.addCustomEvent = addCustomEvent;
6493	exports.adjust = adjust;
6494	exports.ajax = ajax;
6495	exports.append = append;
6496	exports.bind = bind;
6497	exports.bindOnce = bindOnce;
6498	exports.browser = browser;
6499	exports.clean = clean;
6500	exports.cleanNode = cleanNode;
6501	exports.clone = clone;
6502	exports.create = create;
6503	exports.debounce = debounce;
6504	exports.debug = debug;
6505	exports.debugEnable = debugEnable;
6506	exports.debugEnableFlag = debugEnableFlag;
6507	exports.debugStatus = debugStatus;
6508	exports.easing = easing;
6509	exports.fx = fx;
6510	exports.getClass = getClass;
6511	exports.getCookie = getCookie;
6512	exports.hasClass = hasClass;
6513	exports.html = html;
6514	exports.insertAfter = insertAfter;
6515	exports.insertBefore = insertBefore;
6516	exports.isShown = isShown;
6517	exports.loadExt = loadExt;
6518	exports.localStorage = localStorage$1;
6519	exports.message = message;
6520	exports.namespace = namespace;
6521	exports.onCustomEvent = onCustomEvent;
6522	exports.onGlobalCustomEvent = onGlobalCustomEvent;
6523	exports.pos = pos;
6524	exports.prepend = prepend;
6525	exports.ready = ready;
6526	exports.remove = remove;
6527	exports.removeAllCustomEvents = removeAllCustomEvents;
6528	exports.removeClass = removeClass;
6529	exports.removeCustomEvent = removeCustomEvent;
6530	exports.replace = replace;
6531	exports.setCookie = setCookie;
6532	exports.style = style;
6533	exports.throttle = throttle;
6534	exports.toggleClass = toggleClass;
6535	exports.type = type;
6536	exports.unbind = unbind;
6537	exports.unbindAll = unbindAll;
6538
6539})(this.BX = this.BX || {});
6540
6541
6542
6543(function(BX) {
6544	/* list of registered proxy functions */
6545	var proxyList = new WeakMap();
6546	var deferList = new WeakMap();
6547
6548	/* List of denied event handlers */
6549	var deniedEvents = [];
6550
6551	/* list of registered custom events */
6552	var customEvents = new WeakMap();
6553	var customEventsCnt = 0;
6554
6555	/* list of external garbage collectors */
6556	var garbageCollectors = [];
6557
6558	/* list of loaded CSS files */
6559	var cssList = [];
6560	var cssInit = false;
6561
6562	/* list of loaded JS files */
6563	var jsList = [];
6564	var jsInit = false;
6565
6566	var eventTypes = {
6567		click: 'MouseEvent',
6568		dblclick: 'MouseEvent',
6569		mousedown: 'MouseEvent',
6570		mousemove: 'MouseEvent',
6571		mouseout: 'MouseEvent',
6572		mouseover: 'MouseEvent',
6573		mouseup: 'MouseEvent',
6574		focus: 'MouseEvent',
6575		blur: 'MouseEvent'
6576	};
6577
6578	var lastWait = [];
6579
6580	var CHECK_FORM_ELEMENTS = {tagName: /^INPUT|SELECT|TEXTAREA|BUTTON$/i};
6581
6582	BX.MSLEFT = 1;
6583	BX.MSMIDDLE = 2;
6584	BX.MSRIGHT = 4;
6585
6586	BX.AM_PM_UPPER = 1;
6587	BX.AM_PM_LOWER = 2;
6588	BX.AM_PM_NONE = false;
6589
6590	BX.ext = function(ob)
6591	{
6592		for (var i in ob)
6593		{
6594			if(ob.hasOwnProperty(i))
6595			{
6596				this[i] = ob[i];
6597			}
6598		}
6599	};
6600
6601	var r = {
6602		script: /<script([^>]*)>/ig,
6603		script_end: /<\/script>/ig,
6604		script_src: /src=["\']([^"\']+)["\']/i,
6605		script_type: /type=["\']([^"\']+)["\']/i,
6606		space: /\s+/,
6607		ltrim: /^[\s\r\n]+/g,
6608		rtrim: /[\s\r\n]+$/g,
6609		style: /<link[^>]*?(rel="stylesheet"|type="text\/css")[^>]*>/i,
6610		style_href: /href=["\']([^"\']+)["\']/i
6611	};
6612
6613	BX.processHTML = function(data, scriptsRunFirst)
6614	{
6615		var matchScript, matchStyle, matchSrc, matchHref, matchType, scripts = [], styles = [];
6616		var textIndexes = [];
6617		var lastIndex = r.script.lastIndex = r.script_end.lastIndex = 0;
6618
6619		while ((matchScript = r.script.exec(data)) !== null)
6620		{
6621			r.script_end.lastIndex = r.script.lastIndex;
6622			var matchScriptEnd = r.script_end.exec(data);
6623			if (matchScriptEnd === null)
6624			{
6625				break;
6626			}
6627
6628			// skip script tags of special types
6629			var skipTag = false;
6630			if ((matchType = matchScript[1].match(r.script_type)) !== null)
6631			{
6632				if(
6633					matchType[1] == 'text/html'
6634					|| matchType[1] == 'text/template'
6635					|| matchType[1] == 'extension/settings'
6636				)
6637				{
6638					skipTag = true;
6639				}
6640			}
6641
6642			if(skipTag)
6643			{
6644				textIndexes.push([lastIndex, r.script_end.lastIndex - lastIndex]);
6645			}
6646			else
6647			{
6648				textIndexes.push([lastIndex, matchScript.index - lastIndex]);
6649
6650				var bRunFirst = scriptsRunFirst || (matchScript[1].indexOf('bxrunfirst') != '-1');
6651
6652				if ((matchSrc = matchScript[1].match(r.script_src)) !== null)
6653				{
6654					scripts.push({"bRunFirst": bRunFirst, "isInternal": false, "JS": matchSrc[1]});
6655				}
6656				else
6657				{
6658					var start = matchScript.index + matchScript[0].length;
6659					var js = data.substr(start, matchScriptEnd.index-start);
6660
6661					scripts.push({"bRunFirst": bRunFirst, "isInternal": true, "JS": js});
6662				}
6663			}
6664
6665			lastIndex = matchScriptEnd.index + 9;
6666			r.script.lastIndex = lastIndex;
6667		}
6668
6669		textIndexes.push([lastIndex, lastIndex === 0 ? data.length : data.length - lastIndex]);
6670		var pureData = "";
6671		for (var i = 0, length = textIndexes.length; i < length; i++)
6672		{
6673			if (BX.type.isString(data) && BX.type.isFunction(data.substr))
6674			{
6675				pureData += data.substr(textIndexes[i][0], textIndexes[i][1]);
6676			}
6677		}
6678
6679		while ((matchStyle = pureData.match(r.style)) !== null)
6680		{
6681			if ((matchHref = matchStyle[0].match(r.style_href)) !== null && matchStyle[0].indexOf('media="') < 0)
6682			{
6683				styles.push(matchHref[1]);
6684			}
6685
6686			pureData = pureData.replace(matchStyle[0], '');
6687		}
6688
6689		return {'HTML': pureData, 'SCRIPT': scripts, 'STYLE': styles};
6690	};
6691
6692	/* OO emulation utility */
6693	BX.extend = function(child, parent)
6694	{
6695		var f = function() {};
6696		f.prototype = parent.prototype;
6697
6698		child.prototype = new f();
6699		child.prototype.constructor = child;
6700
6701		child.superclass = parent.prototype;
6702		child.prototype.superclass = parent.prototype;
6703		if(parent.prototype.constructor == Object.prototype.constructor)
6704		{
6705			parent.prototype.constructor = parent;
6706		}
6707	};
6708
6709	BX.is_subclass_of = function(ob, parent_class)
6710	{
6711		if (ob instanceof parent_class)
6712			return true;
6713
6714		if (parent_class.superclass)
6715			return BX.is_subclass_of(ob, parent_class.superclass);
6716
6717		return false;
6718	};
6719
6720	BX.clearNodeCache = function()
6721	{
6722		return false;
6723	};
6724
6725	BX.bitrix_sessid = function() {return BX.message("bitrix_sessid"); };
6726
6727	/**
6728	 * Creates document fragment with child nodes.
6729	 *
6730	 * @param {Node[]} nodes
6731	 * @return {DocumentFragment}
6732	 */
6733	BX.createFragment = function(nodes)
6734	{
6735		var fragment = document.createDocumentFragment();
6736
6737		if(!BX.type.isArray(nodes))
6738		{
6739			return fragment;
6740		}
6741		for(var i = 0; i < nodes.length; i++)
6742		{
6743			fragment.appendChild(nodes[i]);
6744		}
6745
6746		return fragment;
6747	};
6748
6749	/**
6750	 * @deprecated
6751	 * @use BX.style
6752	 * @param element
6753	 * @param opacity
6754	 */
6755	BX.setOpacity = function(element, opacity)
6756	{
6757		var opacityValue = parseFloat(opacity);
6758
6759		if (!isNaN(opacityValue) && BX.type.isDomNode(element))
6760		{
6761			opacityValue = opacityValue < 1 ? opacityValue : opacityValue / 100;
6762			BX.style(element, 'opacity', opacityValue);
6763		}
6764	};
6765
6766	/**
6767	 * @deprecated
6768	 * @param el
6769	 * @return {*}
6770	 */
6771	BX.hoverEvents = function(el)
6772	{
6773		if (el)
6774			return BX.adjust(el, {events: BX.hoverEvents()});
6775		else
6776			return {mouseover: BX.hoverEventsHover, mouseout: BX.hoverEventsHout};
6777	};
6778
6779	/**
6780	 * @deprecated
6781	 */
6782	BX.hoverEventsHover = function(){BX.addClass(this,'bx-hover');this.BXHOVER=true;};
6783	/**
6784	 * @deprecated
6785	 */
6786	BX.hoverEventsHout = function(){BX.removeClass(this,'bx-hover');this.BXHOVER=false;};
6787
6788	/**
6789	 * @deprecated
6790	 */
6791	BX.focusEvents = function(el)
6792	{
6793		if (el)
6794			return BX.adjust(el, {events: BX.focusEvents()});
6795		else
6796			return {mouseover: BX.focusEventsFocus, mouseout: BX.focusEventsBlur};
6797	};
6798
6799	/**
6800	 * @deprecated
6801	 */
6802	BX.focusEventsFocus = function(){BX.addClass(this,'bx-focus');this.BXFOCUS=true;};
6803	/**
6804	 * @deprecated
6805	 */
6806	BX.focusEventsBlur = function(){BX.removeClass(this,'bx-focus');this.BXFOCUS=false;};
6807
6808	BX.setUnselectable = function(node)
6809	{
6810		BX.style(node, {
6811			'userSelect': 'none',
6812			'MozUserSelect': 'none',
6813			'WebkitUserSelect': 'none',
6814			'KhtmlUserSelect': 'none',
6815		});
6816		node.setAttribute('unSelectable', 'on');
6817	};
6818
6819	BX.setSelectable = function(node)
6820	{
6821		BX.style(node, {
6822			'userSelect': null,
6823			'MozUserSelect': null,
6824			'WebkitUserSelect': null,
6825			'KhtmlUserSelect': null,
6826		});
6827		node.removeAttribute('unSelectable');
6828	};
6829
6830	BX.styleIEPropertyName = function(name)
6831	{
6832		if (name == 'float')
6833			name = BX.browser.IsIE() ? 'styleFloat' : 'cssFloat';
6834		else
6835		{
6836			var res = BX.browser.isPropertySupported(name);
6837			if (res)
6838			{
6839				name = res;
6840			}
6841			else
6842			{
6843				var reg = /(\-([a-z]){1})/g;
6844				if (reg.test(name))
6845				{
6846					name = name.replace(reg, function () {return arguments[2].toUpperCase();});
6847				}
6848			}
6849		}
6850		return name;
6851	};
6852
6853	BX.focus = function(el)
6854	{
6855		try
6856		{
6857			el.focus();
6858			return true;
6859		}
6860		catch (e)
6861		{
6862			return false;
6863		}
6864	};
6865
6866	BX.firstChild = function(el)
6867	{
6868		return BX.type.isDomNode(el) ? el.firstElementChild : null;
6869	};
6870
6871	BX.lastChild = function(el)
6872	{
6873		return BX.type.isDomNode(el) ? el.lastElementChild : null;
6874	};
6875
6876	BX.previousSibling = function(el)
6877	{
6878		return BX.type.isDomNode(el) ? el.previousElementSibling : null;
6879	};
6880
6881	BX.nextSibling = function(el)
6882	{
6883		return BX.type.isDomNode(el) ? el.nextElementSibling : null;
6884	};
6885
6886	/*
6887		params: {
6888			obj : html node
6889			className : className value
6890			recursive : used only for older browsers to optimize the tree traversal, in new browsers the search is always recursively, default - true
6891		}
6892
6893		Search all nodes with className
6894	*/
6895	/**
6896	 * @deprecated
6897	 * @use .querySelectorAll
6898	 * @param obj
6899	 * @param className
6900	 * @param recursive
6901	 * @return {*}
6902	 */
6903	BX.findChildrenByClassName = function(obj, className, recursive)
6904	{
6905		if(!obj || !obj.childNodes) return null;
6906
6907		var result = [];
6908		if (typeof(obj.getElementsByClassName) == 'undefined')
6909		{
6910			recursive = recursive !== false;
6911			result = BX.findChildren(obj, {className : className}, recursive);
6912		}
6913		else
6914		{
6915			var col = obj.getElementsByClassName(className);
6916			for (i=0,l=col.length;i<l;i++)
6917			{
6918				result[i] = col[i];
6919			}
6920		}
6921		return result;
6922	};
6923
6924	/*
6925		params: {
6926			obj : html node
6927			className : className value
6928			recursive : used only for older browsers to optimize the tree traversal, in new browsers the search is always recursively, default - true
6929		}
6930
6931		Search first node with className
6932	*/
6933	/**
6934	 * @deprecated
6935	 * @use .querySelector
6936	 * @param obj
6937	 * @param className
6938	 * @param recursive
6939	 * @return {*}
6940	 */
6941	BX.findChildByClassName = function(obj, className, recursive)
6942	{
6943		if(!obj || !obj.childNodes) return null;
6944
6945		var result = null;
6946		if (typeof(obj.getElementsByClassName) == 'undefined')
6947		{
6948			recursive = recursive !== false;
6949			result = BX.findChild(obj, {className : className}, recursive);
6950		}
6951		else
6952		{
6953			var col = obj.getElementsByClassName(className);
6954			if (col && typeof(col[0]) != 'undefined')
6955			{
6956				result = col[0];
6957			}
6958			else
6959			{
6960				result = null;
6961			}
6962		}
6963		return result;
6964	};
6965
6966	/*
6967		params: {
6968			tagName|tag : 'tagName',
6969			className|class : 'className',
6970			attribute : {attribute : value, attribute : value} | attribute | [attribute, attribute....],
6971			property : {prop: value, prop: value} | prop | [prop, prop]
6972		}
6973
6974		all values can be RegExps or strings
6975	*/
6976	/**
6977	 * @deprecated
6978	 * @use .querySelectorAll
6979	 * @param obj
6980	 * @param params
6981	 * @param recursive
6982	 * @return {*|Node}
6983	 */
6984	BX.findChildren = function(obj, params, recursive)
6985	{
6986		return BX.findChild(obj, params, recursive, true);
6987	};
6988
6989	/**
6990	 * @deprecated
6991	 * @use .querySelectorAll
6992	 * @param obj
6993	 * @param params
6994	 * @param recursive
6995	 * @param get_all
6996	 * @return {*}
6997	 */
6998	BX.findChild = function(obj, params, recursive, get_all)
6999	{
7000		if(!obj || !obj.childNodes) return null;
7001
7002		recursive = !!recursive; get_all = !!get_all;
7003
7004		var n = obj.childNodes.length, result = [];
7005
7006		for (var j=0; j<n; j++)
7007		{
7008			var child = obj.childNodes[j];
7009
7010			if (_checkNode(child, params))
7011			{
7012				if (get_all)
7013					result.push(child);
7014				else
7015					return child;
7016			}
7017
7018			if(recursive == true)
7019			{
7020				var res = BX.findChild(child, params, recursive, get_all);
7021				if (res)
7022				{
7023					if (get_all)
7024						result = BX.util.array_merge(result, res);
7025					else
7026						return res;
7027				}
7028			}
7029		}
7030
7031		if (get_all || result.length > 0)
7032			return result;
7033		else
7034			return null;
7035	};
7036
7037	/**
7038	 * @deprecated
7039	 * @use .closest()
7040	 * @param obj
7041	 * @param params
7042	 * @param maxParent
7043	 * @return {*}
7044	 */
7045	BX.findParent = function(obj, params, maxParent)
7046	{
7047		if(!obj)
7048			return null;
7049
7050		var o = obj;
7051		while(o.parentNode)
7052		{
7053			var parent = o.parentNode;
7054
7055			if (_checkNode(parent, params))
7056				return parent;
7057
7058			o = parent;
7059
7060			if (!!maxParent &&
7061				(BX.type.isFunction(maxParent)
7062					|| typeof maxParent == 'object'))
7063			{
7064				if (BX.type.isElementNode(maxParent))
7065				{
7066					if (o == maxParent)
7067						break;
7068				}
7069				else
7070				{
7071					if (_checkNode(o, maxParent))
7072						break;
7073				}
7074			}
7075		}
7076		return null;
7077	};
7078
7079	/**
7080	 * @deprecated
7081	 * @use .querySelector
7082	 * @param obj
7083	 * @param params
7084	 * @return {*}
7085	 */
7086	BX.findNextSibling = function(obj, params)
7087	{
7088		if(!obj)
7089			return null;
7090		var o = obj;
7091		while(o.nextSibling)
7092		{
7093			var sibling = o.nextSibling;
7094			if (_checkNode(sibling, params))
7095				return sibling;
7096			o = sibling;
7097		}
7098		return null;
7099	};
7100
7101	/**
7102	 * @deprecated
7103	 * @use .querySelector
7104	 * @param obj
7105	 * @param params
7106	 * @return {*}
7107	 */
7108	BX.findPreviousSibling = function(obj, params)
7109	{
7110		if(!obj)
7111			return null;
7112
7113		var o = obj;
7114		while(o.previousSibling)
7115		{
7116			var sibling = o.previousSibling;
7117			if(_checkNode(sibling, params))
7118				return sibling;
7119			o = sibling;
7120		}
7121		return null;
7122	};
7123
7124	BX.checkNode = function(obj, params)
7125	{
7126		return _checkNode(obj, params);
7127	};
7128
7129	/**
7130	 * @deprecated
7131	 * @use .querySelectorAll
7132	 * @param form
7133	 * @return {Array}
7134	 */
7135	BX.findFormElements = function(form)
7136	{
7137		if (BX.type.isString(form))
7138			form = document.forms[form]||BX(form);
7139
7140		var res = [];
7141
7142		if (BX.type.isElementNode(form))
7143		{
7144			if (form.tagName.toUpperCase() == 'FORM')
7145			{
7146				res = form.elements;
7147			}
7148			else
7149			{
7150				res = BX.findChildren(form, CHECK_FORM_ELEMENTS, true);
7151			}
7152		}
7153
7154		return res;
7155	};
7156
7157	/**
7158	 * @deprecated
7159	 * @use .contains()
7160	 * @param whichNode
7161	 * @param forNode
7162	 * @return {boolean}
7163	 */
7164	BX.isParentForNode = function(whichNode, forNode)
7165	{
7166		if (BX.type.isDomNode(whichNode) && BX.type.isDomNode(forNode))
7167		{
7168			return whichNode.contains(forNode);
7169		}
7170
7171		return false;
7172	};
7173
7174	BX.getCaretPosition = function(node)
7175	{
7176		var pos = 0;
7177
7178		if(node.selectionStart || node.selectionStart == 0)
7179		{
7180			pos = node.selectionStart;
7181		}
7182		else if(document.selection)
7183		{
7184			node.focus();
7185			var selection = document.selection.createRange();
7186			selection.moveStart('character', -node.value.length);
7187			pos = selection.text.length;
7188		}
7189
7190		return (pos);
7191	};
7192
7193	BX.setCaretPosition = function(node, pos)
7194	{
7195		if(!BX.isNodeInDom(node) || BX.isNodeHidden(node) || node.disabled)
7196		{
7197			return;
7198		}
7199
7200		if(node.setSelectionRange)
7201		{
7202			node.focus();
7203			node.setSelectionRange(pos, pos);
7204		}
7205		else if(node.createTextRange)
7206		{
7207			var range = node.createTextRange();
7208			range.collapse(true);
7209			range.moveEnd('character', pos);
7210			range.moveStart('character', pos);
7211			range.select();
7212		}
7213	};
7214
7215	// access private. use BX.mergeEx instead.
7216	// todo: refactor BX.merge, make it work through BX.mergeEx
7217	BX.merge = function(){
7218		var arg = Array.prototype.slice.call(arguments);
7219
7220		if(arg.length < 2)
7221			return {};
7222
7223		var result = arg.shift();
7224
7225		for(var i = 0; i < arg.length; i++)
7226		{
7227			for(var k in arg[i]){
7228
7229				if(typeof arg[i] == 'undefined' || arg[i] == null)
7230					continue;
7231
7232				if(arg[i].hasOwnProperty(k)){
7233
7234					if(typeof arg[i][k] == 'undefined' || arg[i][k] == null)
7235						continue;
7236
7237					if(typeof arg[i][k] == 'object' && !BX.type.isDomNode(arg[i][k]) && (typeof arg[i][k]['isUIWidget'] == 'undefined')){
7238
7239						// go deeper
7240
7241						var isArray = 'length' in arg[i][k];
7242
7243						if(typeof result[k] != 'object')
7244							result[k] = isArray ? [] : {};
7245
7246						if(isArray)
7247							BX.util.array_merge(result[k], arg[i][k]);
7248						else
7249							BX.merge(result[k], arg[i][k]);
7250
7251					}else
7252						result[k] = arg[i][k];
7253				}
7254			}
7255		}
7256
7257		return result;
7258	};
7259
7260	BX.mergeEx = function()
7261	{
7262		var arg = Array.prototype.slice.call(arguments);
7263		if(arg.length < 2)
7264		{
7265			return {};
7266		}
7267
7268		var result = arg.shift();
7269		for (var i = 0; i < arg.length; i++)
7270		{
7271			for (var k in arg[i])
7272			{
7273				if (typeof arg[i] == "undefined" || arg[i] == null || !arg[i].hasOwnProperty(k))
7274				{
7275					continue;
7276				}
7277
7278				if (BX.type.isPlainObject(arg[i][k]) && BX.type.isPlainObject(result[k]))
7279				{
7280					BX.mergeEx(result[k], arg[i][k]);
7281				}
7282				else
7283				{
7284					result[k] = BX.type.isPlainObject(arg[i][k]) ? BX.clone(arg[i][k]) : arg[i][k];
7285				}
7286			}
7287		}
7288
7289		return result;
7290	};
7291
7292	BX.getEventButton = function(e)
7293	{
7294		e = e || window.event;
7295
7296		var flags = 0;
7297
7298		if (typeof e.which != 'undefined')
7299		{
7300			switch (e.which)
7301			{
7302				case 1: flags = flags|BX.MSLEFT; break;
7303				case 2: flags = flags|BX.MSMIDDLE; break;
7304				case 3: flags = flags|BX.MSRIGHT; break;
7305			}
7306		}
7307		else if (typeof e.button != 'undefined')
7308		{
7309			flags = event.button;
7310		}
7311
7312		return flags || BX.MSLEFT;
7313	};
7314
7315	var captured_events = null, _bind = null;
7316	BX.CaptureEvents = function(el_c, evname_c)
7317	{
7318		if (_bind)
7319			return;
7320
7321		_bind = BX.bind;
7322		captured_events = [];
7323
7324		BX.bind = function(el, evname, func)
7325		{
7326			if (el === el_c && evname === evname_c)
7327				captured_events.push(func);
7328
7329			_bind.apply(this, arguments);
7330		}
7331	};
7332
7333	BX.CaptureEventsGet = function()
7334	{
7335		if (_bind)
7336		{
7337			BX.bind = _bind;
7338
7339			var captured = captured_events;
7340
7341			_bind = null;
7342			captured_events = null;
7343			return captured;
7344		}
7345		return null;
7346	};
7347
7348	// Don't even try to use it for submit event!
7349	BX.fireEvent = function(ob,ev)
7350	{
7351		var result = false, e = null;
7352		if (BX.type.isDomNode(ob))
7353		{
7354			result = true;
7355			if (document.createEventObject)
7356			{
7357				// IE
7358				if (eventTypes[ev] != 'MouseEvent')
7359				{
7360					e = document.createEventObject();
7361					e.type = ev;
7362					result = ob.fireEvent('on' + ev, e);
7363				}
7364
7365				if (ob[ev])
7366				{
7367					ob[ev]();
7368				}
7369			}
7370			else
7371			{
7372				// non-IE
7373				e = null;
7374
7375				switch (eventTypes[ev])
7376				{
7377					case 'MouseEvent':
7378						e = document.createEvent('MouseEvent');
7379						try
7380						{
7381							e.initMouseEvent(ev, true, true, top, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, null);
7382						}
7383						catch (initException)
7384						{
7385							e.initMouseEvent(ev, true, true, window, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, null);
7386						}
7387
7388					break;
7389					default:
7390						e = document.createEvent('Event');
7391						e.initEvent(ev, true, true);
7392				}
7393
7394				result = ob.dispatchEvent(e);
7395			}
7396		}
7397
7398		return result;
7399	};
7400
7401	BX.getWheelData = function(e)
7402	{
7403		e = e || window.event;
7404		e.wheelData = e.detail ? e.detail * -1 : e.wheelDelta / 40;
7405		return e.wheelData;
7406	};
7407
7408	BX.proxy_context = null;
7409
7410	BX.delegate = function (func, thisObject)
7411	{
7412		if (!func || !thisObject)
7413			return func;
7414
7415		return function() {
7416			var cur = BX.proxy_context;
7417			BX.proxy_context = this;
7418			var res = func.apply(thisObject, arguments);
7419			BX.proxy_context = cur;
7420			return res;
7421		}
7422	};
7423
7424	BX.delegateLater = function (func_name, thisObject, contextObject)
7425	{
7426		return function()
7427		{
7428			if (thisObject[func_name])
7429			{
7430				var cur = BX.proxy_context;
7431				BX.proxy_context = this;
7432				var res = thisObject[func_name].apply(contextObject||thisObject, arguments);
7433				BX.proxy_context = cur;
7434				return res;
7435			}
7436			return null;
7437		}
7438	};
7439
7440	BX.proxy = function(func, thisObject)
7441	{
7442		return getObjectDelegate(func, thisObject, proxyList);
7443	};
7444
7445	BX.defer = function(func, thisObject)
7446	{
7447		if (!!thisObject)
7448			return BX.defer_proxy(func, thisObject);
7449		else
7450			return function() {
7451				var arg = arguments;
7452				setTimeout(function(){func.apply(this,arg)}, 10);
7453			};
7454	};
7455
7456	BX.defer_proxy = function(func, thisObject)
7457	{
7458		return getObjectDelegate(func, thisObject, deferList, BX.defer);
7459	};
7460
7461	/**
7462	 *
7463	 * @private
7464	 */
7465	function getObjectDelegate(func, thisObject, collection, decorator)
7466	{
7467		if (!BX.type.isFunction(func) || !BX.type.isMapKey(thisObject))
7468		{
7469			return func;
7470		}
7471
7472		var objectDelegates = collection.get(thisObject);
7473		if (!objectDelegates)
7474		{
7475			objectDelegates = new WeakMap();
7476			collection.set(thisObject, objectDelegates);
7477		}
7478
7479		var delegate = objectDelegates.get(func);
7480		if (!delegate)
7481		{
7482			delegate = decorator ? decorator(BX.delegate(func, thisObject)) : BX.delegate(func, thisObject);
7483			objectDelegates.set(func, delegate);
7484		}
7485
7486		return delegate;
7487	}
7488
7489	BX.once = function(el, evname, func)
7490	{
7491		var fn = function()
7492		{
7493			BX.unbind(el, evname, fn);
7494			func.apply(this, arguments);
7495		};
7496
7497		return fn;
7498	};
7499
7500	BX.bindDelegate = function (elem, eventName, isTarget, handler)
7501	{
7502		var h = BX.delegateEvent(isTarget, handler);
7503		BX.bind(elem, eventName, h);
7504		return h;
7505	};
7506
7507	BX.delegateEvent = function(isTarget, handler)
7508	{
7509		return function(e)
7510		{
7511			e = e || window.event;
7512			var target = e.target || e.srcElement;
7513
7514			while (target != this)
7515			{
7516				if (_checkNode(target, isTarget))
7517				{
7518					return handler.call(target, e);
7519				}
7520				if (target && target.parentNode)
7521					target = target.parentNode;
7522				else
7523					break;
7524			}
7525			return null;
7526		}
7527	};
7528
7529	BX.False = function() {return false;};
7530	BX.DoNothing = function() {};
7531
7532	// TODO: also check event handlers set via BX.bind()
7533	BX.denyEvent = function(el, ev)
7534	{
7535		deniedEvents.push([el, ev, el['on' + ev]]);
7536		el['on' + ev] = BX.DoNothing;
7537	};
7538
7539	BX.allowEvent = function(el, ev)
7540	{
7541		for(var i=0, len=deniedEvents.length; i<len; i++)
7542		{
7543			if (deniedEvents[i][0] == el && deniedEvents[i][1] == ev)
7544			{
7545				el['on' + ev] = deniedEvents[i][2];
7546				BX.util.deleteFromArray(deniedEvents, i);
7547				return;
7548			}
7549		}
7550	};
7551
7552	BX.fixEventPageXY = function(event)
7553	{
7554		BX.fixEventPageX(event);
7555		BX.fixEventPageY(event);
7556		return event;
7557	};
7558
7559	BX.fixEventPageX = function(event)
7560	{
7561		if (event.pageX == null && event.clientX != null)
7562		{
7563			event.pageX =
7564				event.clientX +
7565				(document.documentElement && document.documentElement.scrollLeft || document.body && document.body.scrollLeft || 0) -
7566				(document.documentElement.clientLeft || 0);
7567		}
7568
7569		return event;
7570	};
7571
7572	BX.fixEventPageY = function(event)
7573	{
7574		if (event.pageY == null && event.clientY != null)
7575		{
7576			event.pageY =
7577				event.clientY +
7578				(document.documentElement && document.documentElement.scrollTop || document.body && document.body.scrollTop || 0) -
7579				(document.documentElement.clientTop || 0);
7580		}
7581
7582		return event;
7583	};
7584
7585	/**
7586	 * @deprecated
7587	 * @see e.preventDefault()
7588	 */
7589	BX.PreventDefault = function(e)
7590	{
7591		if(!e) e = window.event;
7592		if(e.stopPropagation)
7593		{
7594			e.preventDefault();
7595			e.stopPropagation();
7596		}
7597		else
7598		{
7599			e.cancelBubble = true;
7600			e.returnValue = false;
7601		}
7602		return false;
7603	};
7604
7605	/**
7606	 * @deprecated
7607	 * @see e.preventDefault();
7608	 *
7609	 * @param e
7610	 * @return {boolean}
7611	 */
7612	BX.eventReturnFalse = function(e)
7613	{
7614		e=e||window.event;
7615		if (e && e.preventDefault) e.preventDefault();
7616		else e.returnValue = false;
7617		return false;
7618	};
7619
7620	/**
7621	 * @deprecated
7622	 * @see e.stopPropagation()
7623	 * @param e
7624	 */
7625	BX.eventCancelBubble = function(e)
7626	{
7627		e=e||window.event;
7628		if(e && e.stopPropagation)
7629			e.stopPropagation();
7630		else
7631			e.cancelBubble = true;
7632	};
7633
7634	BX.bindDebouncedChange = function(node, fn, fnInstant, timeout, ctx)
7635	{
7636		ctx = ctx || window;
7637		timeout = timeout || 300;
7638
7639		var dataTag = 'bx-dc-previous-value';
7640		BX.data(node, dataTag, node.value);
7641
7642		var act = function(fn, val){
7643
7644			var pVal = BX.data(node, dataTag);
7645
7646			if(typeof pVal == 'undefined' || pVal != val){
7647				if(typeof ctx != 'object')
7648					fn(val);
7649				else
7650					fn.apply(ctx, [val]);
7651			}
7652		};
7653
7654		var actD = BX.debounce(function(){
7655			var val = node.value;
7656			act(fn, val);
7657			BX.data(node, dataTag, val);
7658		}, timeout);
7659
7660		BX.bind(node, 'keyup', actD);
7661		BX.bind(node, 'change', actD);
7662		BX.bind(node, 'input', actD);
7663
7664		if(BX.type.isFunction(fnInstant)){
7665
7666			var actI = function(){
7667				act(fnInstant, node.value);
7668			};
7669
7670			BX.bind(node, 'keyup', actI);
7671			BX.bind(node, 'change', actI);
7672			BX.bind(node, 'input', actI);
7673		}
7674	};
7675
7676	BX.parseJSON = function(data, context)
7677	{
7678		var result = null;
7679		if (BX.type.isNotEmptyString(data))
7680		{
7681			try {
7682				if (data.indexOf("\n") >= 0)
7683					eval('result = ' + data);
7684				else
7685					result = (new Function("return " + data))();
7686			} catch(e) {
7687				BX.onCustomEvent(context, 'onParseJSONFailure', [data, context])
7688			}
7689		}
7690		else if(BX.type.isPlainObject(data))
7691		{
7692			return data;
7693		}
7694
7695		return result;
7696	};
7697
7698	BX.submit = function(obForm, action_name, action_value, onAfterSubmit)
7699	{
7700		action_name = action_name || 'save';
7701		if (!obForm['BXFormSubmit_' + action_name])
7702		{
7703			obForm['BXFormSubmit_' + action_name] = obForm.appendChild(BX.create('INPUT', {
7704				'props': {
7705					'type': 'submit',
7706					'name': action_name,
7707					'value': action_value || 'Y'
7708				},
7709				'style': {
7710					'display': 'none'
7711				}
7712			}));
7713		}
7714
7715		if (obForm.sessid)
7716			obForm.sessid.value = BX.bitrix_sessid();
7717
7718		setTimeout(BX.delegate(function() {BX.fireEvent(this, 'click'); if (onAfterSubmit) onAfterSubmit();}, obForm['BXFormSubmit_' + action_name]), 10);
7719	};
7720
7721	BX.show = function(ob, displayType)
7722	{
7723		if (ob.BXDISPLAY || !_checkDisplay(ob, displayType))
7724		{
7725			ob.style.display = ob.BXDISPLAY;
7726		}
7727	};
7728
7729	BX.hide = function(ob, displayType)
7730	{
7731		if (!ob.BXDISPLAY)
7732			_checkDisplay(ob, displayType);
7733
7734		ob.style.display = 'none';
7735	};
7736
7737	BX.toggle = function(ob, values)
7738	{
7739		if (!values && BX.type.isElementNode(ob))
7740		{
7741			var bShow = true;
7742			if (ob.BXDISPLAY)
7743				bShow = !_checkDisplay(ob);
7744			else
7745				bShow = ob.style.display == 'none';
7746
7747			if (bShow)
7748				BX.show(ob);
7749			else
7750				BX.hide(ob);
7751		}
7752		else if (BX.type.isArray(values))
7753		{
7754			for (var i=0,len=values.length; i<len; i++)
7755			{
7756				if (ob == values[i])
7757				{
7758					ob = values[i==len-1 ? 0 : i+1];
7759					break;
7760				}
7761			}
7762			if (i==len)
7763				ob = values[0];
7764		}
7765
7766		return ob;
7767	};
7768
7769	function _checkDisplay(ob, displayType)
7770	{
7771		if (typeof displayType != 'undefined')
7772			ob.BXDISPLAY = displayType;
7773
7774		var d = ob.style.display || BX.style(ob, 'display');
7775		if (d != 'none')
7776		{
7777			ob.BXDISPLAY = ob.BXDISPLAY || d;
7778			return true;
7779		}
7780		else
7781		{
7782			ob.BXDISPLAY = ob.BXDISPLAY || 'block';
7783			return false;
7784		}
7785	}
7786
7787	/* some useful util functions */
7788
7789	BX.util = {
7790		/**
7791		 * @deprecated
7792		 * @use [].filter(value => !BX.Type.isNil(value))
7793		 * @param ar
7794		 * @return {*}
7795		 */
7796		array_values: function(ar)
7797		{
7798			if (!BX.type.isArray(ar))
7799				return BX.util._array_values_ob(ar);
7800			var arv = [];
7801			for(var i=0,l=ar.length;i<l;i++)
7802				if (ar[i] !== null && typeof ar[i] != 'undefined')
7803					arv.push(ar[i]);
7804			return arv;
7805		},
7806
7807		/**
7808		 * @deprecated
7809		 * @use Object.values([]).filter(value => !BX.Type.isNil(value))
7810		 * @param ar
7811		 * @return {Array}
7812		 * @private
7813		 */
7814		_array_values_ob: function(ar)
7815		{
7816			var arv = [];
7817			for(var i in ar)
7818				if (ar[i] !== null && typeof ar[i] != 'undefined')
7819					arv.push(ar[i]);
7820			return arv;
7821		},
7822
7823		/**
7824		 * @deprecated
7825		 * @use
7826		 * @param ar
7827		 * @return {*}
7828		 */
7829		array_keys: function(ar)
7830		{
7831			if (!BX.type.isArray(ar))
7832				return BX.util._array_keys_ob(ar);
7833			var arv = [];
7834			for(var i=0,l=ar.length;i<l;i++)
7835				if (ar[i] !== null && typeof ar[i] != 'undefined')
7836					arv.push(i);
7837			return arv;
7838		},
7839
7840		_array_keys_ob: function(ar)
7841		{
7842			var arv = [];
7843			for(var i in ar)
7844				if (ar[i] !== null && typeof ar[i] != 'undefined')
7845					arv.push(i);
7846			return arv;
7847		},
7848
7849		object_keys: function(obj)
7850		{
7851			var arv = [];
7852			for(var k in obj)
7853			{
7854				if(obj.hasOwnProperty(k))
7855				{
7856					arv.push(k);
7857				}
7858			}
7859			return arv;
7860		},
7861
7862		/**
7863		 * @deprecated
7864		 * @use firstArr.concat(secondArr);
7865		 * @param first
7866		 * @param second
7867		 * @return {*[]}
7868		 */
7869		array_merge: function(first, second)
7870		{
7871			if (!BX.type.isArray(first)) first = [];
7872			if (!BX.type.isArray(second)) second = [];
7873
7874			var i = first.length, j = 0;
7875
7876			if (typeof second.length === "number")
7877			{
7878				for (var l = second.length; j < l; j++)
7879				{
7880					first[i++] = second[j];
7881				}
7882			}
7883			else
7884			{
7885				while (second[j] !== undefined)
7886				{
7887					first[i++] = second[j++];
7888				}
7889			}
7890
7891			first.length = i;
7892
7893			return first;
7894		},
7895
7896		array_flip: function (object)
7897		{
7898			var newObject = {};
7899
7900			for (var key in object)
7901			{
7902				newObject[object[key]] = key;
7903			}
7904
7905			return newObject;
7906		},
7907
7908		array_diff: function(ar1, ar2, hash)
7909		{
7910			hash = BX.type.isFunction(hash) ? hash : null;
7911			var i, length, v, h, map = {}, result = [];
7912			for(i = 0, length = ar2.length; i < length; i++)
7913			{
7914				v = ar2[i];
7915				h = hash ? hash(v) : v;
7916				map[h] = true;
7917			}
7918
7919			for(i = 0, length = ar1.length; i < length; i++)
7920			{
7921				v = ar1[i];
7922				h = hash ? hash(v) : v;
7923				if(typeof(map[h]) === "undefined")
7924				{
7925					result.push(v);
7926				}
7927			}
7928			return result;
7929		},
7930
7931		/**
7932		 * @deprecated
7933		 * @use Set
7934		 */
7935		array_unique: function(ar)
7936		{
7937			var i=0,j,len=ar.length;
7938			if(len<2) return ar;
7939
7940			for (; i<len-1;i++)
7941			{
7942				for (j=i+1; j<len;j++)
7943				{
7944					if (ar[i]==ar[j])
7945					{
7946						ar.splice(j--,1); len--;
7947					}
7948				}
7949			}
7950
7951			return ar;
7952		},
7953
7954		/**
7955		 * @deprecated
7956		 * @use myArr.includes(needle)
7957		 */
7958		in_array: function(needle, haystack)
7959		{
7960			for(var i=0; i<haystack.length; i++)
7961			{
7962				if(haystack[i] == needle)
7963					return true;
7964			}
7965			return false;
7966		},
7967
7968		/**
7969		 * @deprecated
7970		 * @use myArr.findIndex(item => item === needle);
7971		 */
7972		array_search: function(needle, haystack)
7973		{
7974			for(var i=0; i<haystack.length; i++)
7975			{
7976				if(haystack[i] == needle)
7977					return i;
7978			}
7979			return -1;
7980		},
7981
7982		object_search_key: function(needle, haystack)
7983		{
7984			if (typeof haystack[needle] != 'undefined')
7985				return haystack[needle];
7986
7987			for(var i in haystack)
7988			{
7989				if (typeof haystack[i] == "object")
7990				{
7991					var result = BX.util.object_search_key(needle, haystack[i]);
7992					if (result !== false)
7993						return result;
7994				}
7995			}
7996			return false;
7997		},
7998
7999		trim: function(s)
8000		{
8001			if (BX.type.isString(s))
8002			{
8003				return s.trim();
8004			}
8005
8006			return s;
8007		},
8008
8009		urlencode: function(s){return encodeURIComponent(s);},
8010
8011		// it may also be useful. via sVD.
8012		deleteFromArray: function(ar, ind) {return ar.slice(0, ind).concat(ar.slice(ind + 1));},
8013		insertIntoArray: function(ar, ind, el) {return ar.slice(0, ind).concat([el]).concat(ar.slice(ind));},
8014
8015		htmlspecialchars: function(str)
8016		{
8017			return BX.Text.encode(str);
8018		},
8019
8020		htmlspecialcharsback: function(str)
8021		{
8022			return BX.Text.decode(str);
8023		},
8024
8025		// Quote regular expression characters plus an optional character
8026		preg_quote: function(str, delimiter)
8027		{
8028			if(!str.replace)
8029				return str;
8030			return str.replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
8031		},
8032
8033		jsencode: function(str)
8034		{
8035			if (!str || !str.replace)
8036				return str;
8037
8038			var escapes =
8039				[
8040					{ c: "\\\\", r: "\\\\" }, // should be first
8041					{ c: "\\t", r: "\\t" },
8042					{ c: "\\n", r: "\\n" },
8043					{ c: "\\r", r: "\\r" },
8044					{ c: "\"", r: "\\\"" },
8045					{ c: "'", r: "\\'" },
8046					{ c: "<", r: "\\x3C" },
8047					{ c: ">", r: "\\x3E" },
8048					{ c: "\\u2028", r: "\\u2028" },
8049					{ c: "\\u2029", r: "\\u2029" }
8050				];
8051			for (var i = 0; i < escapes.length; i++)
8052				str = str.replace(new RegExp(escapes[i].c, 'g'), escapes[i].r);
8053			return str;
8054		},
8055
8056		getCssName: function(jsName)
8057		{
8058			if (!BX.type.isNotEmptyString(jsName))
8059			{
8060				return "";
8061			}
8062
8063			return jsName.replace(/[A-Z]/g, function(match) {
8064				return "-" + match.toLowerCase();
8065			});
8066		},
8067
8068		getJsName: function(cssName)
8069		{
8070			var regex = /\-([a-z]){1}/g;
8071			if (regex.test(cssName))
8072			{
8073				return cssName.replace(regex, function(match, letter) {
8074					return letter.toUpperCase();
8075				});
8076			}
8077
8078			return cssName;
8079		},
8080
8081		nl2br: function(str)
8082		{
8083			if (!str || !str.replace)
8084				return str;
8085
8086			return str.replace(/([^>])\n/g, '$1<br/>');
8087		},
8088
8089		/**
8090		 * @deprecated
8091		 * @use .padStart() / .padEnd()
8092		 * @param input
8093		 * @param pad_length
8094		 * @param pad_string
8095		 * @param pad_type
8096		 * @return {*}
8097		 */
8098		str_pad: function(input, pad_length, pad_string, pad_type)
8099		{
8100			pad_string = pad_string || ' ';
8101			pad_type = pad_type || 'right';
8102			input = input.toString();
8103
8104			if (pad_type === 'left')
8105			{
8106				return BX.util.str_pad_left(input, pad_length, pad_string);
8107			}
8108
8109			return BX.util.str_pad_right(input, pad_length, pad_string);
8110		},
8111
8112		str_pad_left: function(input, pad_length, pad_string)
8113		{
8114			return input.toString().padStart(pad_length, pad_string);
8115		},
8116
8117		str_pad_right: function(input, pad_length, pad_string)
8118		{
8119			return input.toString().padEnd(pad_length, pad_string);
8120		},
8121
8122		strip_tags: function(str)
8123		{
8124			return str.split(/<[^>]+>/g).join('');
8125		},
8126
8127		strip_php_tags: function(str)
8128		{
8129			return str.replace(/<\?(.|[\r\n])*?\?>/g, '');
8130		},
8131
8132		popup: function(url, width, height)
8133		{
8134			var w, h;
8135			if(BX.browser.IsOpera())
8136			{
8137				w = document.body.offsetWidth;
8138				h = document.body.offsetHeight;
8139			}
8140			else
8141			{
8142				w = screen.width;
8143				h = screen.height;
8144			}
8145			return window.open(url, '', 'status=no,scrollbars=yes,resizable=yes,width='+width+',height='+height+',top='+Math.floor((h - height)/2-14)+',left='+Math.floor((w - width)/2-5));
8146		},
8147
8148		shuffle: function(array)
8149		{
8150			var temporaryValue, randomIndex;
8151			var currentIndex = array.length;
8152
8153			while (0 !== currentIndex)
8154			{
8155				randomIndex = Math.floor(Math.random() * currentIndex);
8156				currentIndex -= 1;
8157
8158				temporaryValue = array[currentIndex];
8159				array[currentIndex] = array[randomIndex];
8160				array[randomIndex] = temporaryValue;
8161			}
8162
8163			return array;
8164		},
8165
8166		// BX.util.objectSort(object, sortBy, sortDir) - Sort object by property
8167		// function params: 1 - object for sort, 2 - sort by property, 3 - sort direction (asc/desc)
8168		// return: sort array [[objectElement], [objectElement]] in sortDir direction
8169
8170		// example: BX.util.objectSort({'L1': {'name': 'Last'}, 'F1': {'name': 'First'}}, 'name', 'asc');
8171		// return: [{'name' : 'First'}, {'name' : 'Last'}]
8172		objectSort: function(object, sortBy, sortDir)
8173		{
8174			sortDir = sortDir == 'asc'? 'asc': 'desc';
8175
8176			var arItems = [], i;
8177			for (i in object)
8178			{
8179				if (object.hasOwnProperty(i) && object[i][sortBy])
8180				{
8181					arItems.push([i, object[i][sortBy]]);
8182				}
8183			}
8184
8185			if (sortDir == 'asc')
8186			{
8187				arItems.sort(function(i, ii) {
8188					var s1, s2;
8189					if (BX.type.isDate(i[1]))
8190					{
8191						s1 = i[1].getTime();
8192					}
8193					else if (!isNaN(i[1]))
8194					{
8195						s1 = parseInt(i[1]);
8196					}
8197					else
8198					{
8199						s1 = i[1].toString().toLowerCase();
8200					}
8201
8202					if (BX.type.isDate(ii[1]))
8203					{
8204						s2 = ii[1].getTime();
8205					}
8206					else if (!isNaN(ii[1]))
8207					{
8208						s2 = parseInt(ii[1]);
8209					}
8210					else
8211					{
8212						s2 = ii[1].toString().toLowerCase();
8213					}
8214
8215					if (s1 > s2)
8216						return 1;
8217					else if (s1 < s2)
8218						return -1;
8219					else
8220						return 0;
8221				});
8222			}
8223			else
8224			{
8225				arItems.sort(function(i, ii) {
8226					var s1, s2;
8227					if (BX.type.isDate(i[1]))
8228					{
8229						s1 = i[1].getTime();
8230					}
8231					else if (!isNaN(i[1]))
8232					{
8233						s1 = parseInt(i[1]);
8234					}
8235					else
8236					{
8237						s1 = i[1].toString().toLowerCase();
8238					}
8239
8240					if (BX.type.isDate(ii[1]))
8241					{
8242						s2 = ii[1].getTime();
8243					}
8244					else if (!isNaN(ii[1]))
8245					{
8246						s2 = parseInt(ii[1]);
8247					}
8248					else
8249					{
8250						s2 = ii[1].toString().toLowerCase();
8251					}
8252
8253					if (s1 < s2)
8254						return 1;
8255					else if (s1 > s2)
8256						return -1;
8257					else
8258						return 0;
8259				});
8260			}
8261
8262			var arReturnArray = Array();
8263			for (i = 0; i < arItems.length; i++)
8264			{
8265				arReturnArray.push(object[arItems[i][0]]);
8266			}
8267
8268			return arReturnArray;
8269		},
8270
8271		objectMerge: function()
8272		{
8273			return BX.mergeEx.apply(window, arguments);
8274		},
8275
8276		objectClone : function(object)
8277		{
8278			return BX.clone(object, true);
8279		},
8280
8281		// #fdf9e5 => {r=253, g=249, b=229}
8282		hex2rgb: function(color)
8283		{
8284			var rgb = color.replace(/[# ]/g,"").replace(/^(.)(.)(.)$/,'$1$1$2$2$3$3').match(/.{2}/g);
8285			for (var i=0;  i<3; i++)
8286			{
8287				rgb[i] = parseInt(rgb[i], 16);
8288			}
8289			return {'r':rgb[0],'g':rgb[1],'b':rgb[2]};
8290		},
8291
8292		/**
8293		 * @deprecated
8294		 * @use BX.Uri
8295		 * @param url
8296		 * @param param
8297		 * @return {string}
8298		 */
8299		remove_url_param: function(url, param)
8300		{
8301			return BX.Uri.removeParam(url, param);
8302		},
8303
8304		/*
8305		{'param1': 'value1', 'param2': 'value2'}
8306		 */
8307		/**
8308		 * @deprecated
8309		 * @use BX.Uri
8310		 * @param url
8311		 * @param params
8312		 * @return {string}
8313		 */
8314		add_url_param: function(url, params)
8315		{
8316			var preparedParams = Object.entries(params).reduce(function(acc, item) {
8317				acc[item[0]] = BX.type.isArray(item[1]) ? item[1].join() : item[1];
8318				return acc;
8319			}, {});
8320
8321			return BX.Uri.addParam(url, preparedParams);
8322		},
8323
8324		/*
8325	{'param1': 'value1', 'param2': 'value2'}
8326	 */
8327		buildQueryString: function(params)
8328		{
8329			var result = '';
8330			for (var key in params)
8331			{
8332				var value = params[key];
8333				if(BX.type.isArray(value))
8334				{
8335					value.forEach(function(valueElement, index)
8336					{
8337						result += encodeURIComponent(key + "[" + index + "]") + "=" + encodeURIComponent(valueElement) + "&";
8338					});
8339				}
8340				else
8341				{
8342					result += encodeURIComponent(key) + "=" + encodeURIComponent(value) + "&";
8343				}
8344			}
8345
8346			if(result.length > 0)
8347			{
8348				result = result.substr(0, result.length - 1);
8349			}
8350			return result;
8351		},
8352
8353		even: function(digit)
8354		{
8355			return (parseInt(digit) % 2 == 0);
8356		},
8357
8358		hashCode: function(str)
8359		{
8360			if(!BX.type.isNotEmptyString(str))
8361			{
8362				return 0;
8363			}
8364
8365			var hash = 0;
8366			for (var i = 0; i < str.length; i++)
8367			{
8368				var c = str.charCodeAt(i);
8369				hash = ((hash << 5) - hash) + c;
8370				hash = hash & hash;
8371			}
8372			return hash;
8373		},
8374
8375		getRandomString: function (length)
8376		{
8377			return BX.Text.getRandom(length);
8378		},
8379
8380		number_format: function(number, decimals, dec_point, thousands_sep)
8381		{
8382			var i, j, kw, kd, km, sign = '';
8383			decimals = Math.abs(decimals);
8384			if (isNaN(decimals) || decimals < 0)
8385			{
8386				decimals = 2;
8387			}
8388			dec_point = dec_point || ',';
8389			if (typeof thousands_sep === 'undefined')
8390				thousands_sep = '.';
8391
8392			number = (+number || 0).toFixed(decimals);
8393			if (number < 0)
8394			{
8395				sign = '-';
8396				number = -number;
8397			}
8398
8399			i = parseInt(number, 10) + '';
8400			j = (i.length > 3 ? i.length % 3 : 0);
8401
8402			km = (j ? i.substr(0, j) + thousands_sep : '');
8403			kw = i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands_sep);
8404			kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).replace(/-/, '0').slice(2) : '');
8405
8406			return sign + km + kw + kd;
8407		},
8408
8409		getExtension: function (url)
8410		{
8411			url = url || "";
8412			var items = url.split("?")[0].split(".");
8413			return items[items.length-1].toLowerCase();
8414		},
8415		addObjectToForm: function(object, form, prefix)
8416		{
8417			if(!BX.type.isString(prefix))
8418			{
8419				prefix = "";
8420			}
8421
8422			for(var key in object)
8423			{
8424				if(!object.hasOwnProperty(key))
8425				{
8426					continue;
8427				}
8428
8429				var value = object[key];
8430				var name = prefix !== "" ? (prefix + "[" + key + "]") : key;
8431				if(BX.type.isArray(value))
8432				{
8433					var obj = {};
8434					for(var i = 0; i < value.length; i++)
8435					{
8436						obj[i] = value[i];
8437					}
8438
8439					BX.util.addObjectToForm(obj, form, name);
8440				}
8441				else if(BX.type.isPlainObject(value))
8442				{
8443					BX.util.addObjectToForm(value, form, name);
8444				}
8445				else
8446				{
8447					value = BX.type.isFunction(value.toString) ? value.toString() : "";
8448					if(value !== "")
8449					{
8450						form.appendChild(BX.create("INPUT", { attrs: { type: "hidden", name: name, value: value } }));
8451					}
8452				}
8453			}
8454		},
8455
8456		observe: function(object, enable)
8457		{
8458			console.error('BX.util.observe: function is no longer supported by browser.');
8459			return false;
8460		},
8461
8462		escapeRegExp: function(str)
8463		{
8464			return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
8465		}
8466	};
8467
8468	BX.validation = {
8469		checkIfEmail: function(s)
8470		{
8471			var atom = "[=a-z0-9_+~'!$&*^`|#%/?{}-]";
8472			return (new RegExp('^\\s*'+atom+'+(\\.'+atom+'+)*@([a-z0-9-]+\\.)+[a-z0-9-]{2,20}\\s*$', 'i')).test(s);
8473		},
8474		checkIfPhone: function(s)
8475		{
8476			var regexp = new RegExp(
8477				typeof(BX.PhoneNumber) === "undefined"
8478					? BX.PhoneNumber.getValidNumberPattern()
8479					: '^\\s*\\+?\s*[0-9(-)\\s]+\\s*$',
8480				'i'
8481			);
8482			return regexp.test(s);
8483		}
8484	};
8485
8486	BX.prop =
8487		{
8488			get: function(object, key, defaultValue)
8489			{
8490				return object && object.hasOwnProperty(key) ? object[key] : defaultValue;
8491			},
8492			getObject: function(object, key, defaultValue)
8493			{
8494				return object && BX.type.isPlainObject(object[key]) ? object[key] : defaultValue;
8495			},
8496			getElementNode: function(object, key, defaultValue)
8497			{
8498				return object && BX.type.isElementNode(object[key]) ? object[key] : defaultValue;
8499			},
8500			getArray: function(object, key, defaultValue)
8501			{
8502				return object && BX.type.isArray(object[key]) ? object[key] : defaultValue;
8503			},
8504			getFunction: function(object, key, defaultValue)
8505			{
8506				return object && BX.type.isFunction(object[key]) ? object[key] : defaultValue;
8507			},
8508			getNumber: function(object, key, defaultValue)
8509			{
8510				if(!(object && object.hasOwnProperty(key)))
8511				{
8512					return defaultValue;
8513				}
8514
8515				var value = object[key];
8516				if(BX.type.isNumber(value))
8517				{
8518					return value;
8519				}
8520
8521				value = parseFloat(value);
8522				return !isNaN(value) ? value : defaultValue;
8523			},
8524			getInteger: function(object, key, defaultValue)
8525			{
8526				if(!(object && object.hasOwnProperty(key)))
8527				{
8528					return defaultValue;
8529				}
8530
8531				var value = object[key];
8532				if(BX.type.isNumber(value))
8533				{
8534					return value;
8535				}
8536
8537				value = parseInt(value);
8538				return !isNaN(value) ? value : defaultValue;
8539			},
8540			getBoolean: function(object, key, defaultValue)
8541			{
8542				if(!(object && object.hasOwnProperty(key)))
8543				{
8544					return defaultValue;
8545				}
8546
8547				var value = object[key];
8548				return (BX.type.isBoolean(value)
8549						? value
8550						: (BX.type.isString(value) ? (value.toLowerCase() === "true") : !!value)
8551				);
8552			},
8553			getString: function(object, key, defaultValue)
8554			{
8555				if(!(object && object.hasOwnProperty(key)))
8556				{
8557					return defaultValue;
8558				}
8559
8560				var value = object[key];
8561				return BX.type.isString(value) ? value : (value ? value.toString() : '');
8562			},
8563			extractDate: function(datetime)
8564			{
8565				if(!BX.type.isDate(datetime))
8566				{
8567					datetime = new Date();
8568				}
8569
8570				datetime.setHours(0);
8571				datetime.setMinutes(0);
8572				datetime.setSeconds(0);
8573				datetime.setMilliseconds(0);
8574
8575				return datetime;
8576			}
8577		};
8578
8579	BX.isNodeInDom = function(node, doc)
8580	{
8581		return node === (doc || document) ? true :
8582			(node.parentNode ? BX.isNodeInDom(node.parentNode) : false);
8583	};
8584
8585	BX.isNodeHidden = function(node)
8586	{
8587		if (node === document)
8588			return false;
8589		else if (BX.style(node, 'display') == 'none')
8590			return true;
8591		else
8592			return (node.parentNode ? BX.isNodeHidden(node.parentNode) : true);
8593	};
8594
8595	BX.evalPack = function(code)
8596	{
8597		while (code.length > 0)
8598		{
8599			var c = code.shift();
8600
8601			if (c.TYPE == 'SCRIPT_EXT' || c.TYPE == 'SCRIPT_SRC')
8602			{
8603				BX.loadScript(c.DATA, function() {BX.evalPack(code)});
8604				return;
8605			}
8606			else if (c.TYPE == 'SCRIPT')
8607			{
8608				BX.evalGlobal(c.DATA);
8609			}
8610		}
8611	};
8612
8613	BX.evalGlobal = function(data)
8614	{
8615		if (data)
8616		{
8617			var head = document.getElementsByTagName("head")[0] || document.documentElement,
8618				script = document.createElement("script");
8619
8620			script.type = "text/javascript";
8621
8622			if (!BX.browser.IsIE())
8623			{
8624				script.appendChild(document.createTextNode(data));
8625			}
8626			else
8627			{
8628				script.text = data;
8629			}
8630
8631			head.insertBefore(script, head.firstChild);
8632			head.removeChild(script);
8633		}
8634	};
8635
8636	BX.garbage = function(call, thisObject)
8637	{
8638		garbageCollectors.push({callback: call, context: thisObject});
8639	};
8640
8641	BX.GetDocElement = function (pDoc)
8642	{
8643		pDoc = pDoc || document;
8644		return (BX.browser.IsDoctype(pDoc) ? pDoc.documentElement : pDoc.body);
8645	};
8646
8647	BX.scrollTop = function(node, val){
8648		if(typeof val != 'undefined'){
8649
8650			if(node == window){
8651				throw new Error('scrollTop() for window is not implemented');
8652			}else
8653				node.scrollTop = parseInt(val);
8654
8655		}else{
8656
8657			if(node == window)
8658				return BX.GetWindowScrollPos().scrollTop;
8659
8660			return node.scrollTop;
8661		}
8662	};
8663
8664	BX.scrollLeft = function(node, val){
8665		if(typeof val != 'undefined'){
8666
8667			if(node == window){
8668				throw new Error('scrollLeft() for window is not implemented');
8669			}else
8670				node.scrollLeft = parseInt(val);
8671
8672		}else{
8673
8674			if(node == window)
8675				return BX.GetWindowScrollPos().scrollLeft;
8676
8677			return node.scrollLeft;
8678		}
8679	};
8680
8681	BX.hide_object = function(ob)
8682	{
8683		ob = BX(ob);
8684		ob.style.position = 'absolute';
8685		ob.style.top = '-1000px';
8686		ob.style.left = '-1000px';
8687		ob.style.height = '10px';
8688		ob.style.width = '10px';
8689	};
8690
8691	BX.is_relative = function(el)
8692	{
8693		var p = BX.style(el, 'position');
8694		return p == 'relative' || p == 'absolute';
8695	};
8696
8697	BX.is_float = function(el)
8698	{
8699		var p = BX.style(el, 'float');
8700		return p == 'right' || p == 'left';
8701	};
8702
8703	BX.is_fixed = function(el)
8704	{
8705		var p = BX.style(el, 'position');
8706		return p == 'fixed';
8707	};
8708
8709	BX.width = function(node, val){
8710		if(typeof val != 'undefined')
8711			BX.style(node, 'width', parseInt(val)+'px');
8712		else{
8713
8714			if(node == window)
8715				return window.innerWidth;
8716
8717			//return parseInt(BX.style(node, 'width'));
8718			return BX.pos(node).width;
8719		}
8720	};
8721
8722	BX.height = function(node, val){
8723		if(typeof val != 'undefined')
8724			BX.style(node, 'height', parseInt(val)+'px');
8725		else{
8726
8727			if(node == window)
8728				return window.innerHeight;
8729
8730			//return parseInt(BX.style(node, 'height'));
8731			return BX.pos(node).height;
8732		}
8733	};
8734
8735	BX.align = function(pos, w, h, type)
8736	{
8737		if (type)
8738			type = type.toLowerCase();
8739		else
8740			type = '';
8741
8742		var pDoc = document;
8743		if (BX.type.isElementNode(pos))
8744		{
8745			pDoc = pos.ownerDocument;
8746			pos = BX.pos(pos);
8747		}
8748
8749		var x = pos["left"], y = pos["bottom"];
8750
8751		var scroll = BX.GetWindowScrollPos(pDoc);
8752		var size = BX.GetWindowInnerSize(pDoc);
8753
8754		if((size.innerWidth + scroll.scrollLeft) - (pos["left"] + w) < 0)
8755		{
8756			if(pos["right"] - w >= 0 )
8757				x = pos["right"] - w;
8758			else
8759				x = scroll.scrollLeft;
8760		}
8761
8762		if(((size.innerHeight + scroll.scrollTop) - (pos["bottom"] + h) < 0) || ~type.indexOf('top'))
8763		{
8764			if(pos["top"] - h >= 0 || ~type.indexOf('top'))
8765				y = pos["top"] - h;
8766			else
8767				y = scroll.scrollTop;
8768		}
8769
8770		return {'left':x, 'top':y};
8771	};
8772
8773	BX.scrollToNode = function(node)
8774	{
8775		var obNode = BX(node);
8776
8777		if (obNode.scrollIntoView)
8778			obNode.scrollIntoView(true);
8779		else
8780		{
8781			var arNodePos = BX.pos(obNode);
8782			window.scrollTo(arNodePos.left, arNodePos.top);
8783		}
8784	};
8785
8786	/* non-xhr loadings */
8787	BX.showWait = function(node, msg)
8788	{
8789		node = BX(node) || document.body || document.documentElement;
8790		msg = msg || BX.message('JS_CORE_LOADING');
8791
8792		var container_id = node.id || Math.random();
8793
8794		var obMsg = node.bxmsg = document.body.appendChild(BX.create('DIV', {
8795			props: {
8796				id: 'wait_' + container_id
8797			},
8798			style: {
8799				background: 'url("/bitrix/js/main/core/images/wait.gif") no-repeat scroll 10px center #fcf7d1',
8800				border: '1px solid #E1B52D',
8801				color: 'black',
8802				fontFamily: 'Verdana,Arial,sans-serif',
8803				fontSize: '11px',
8804				padding: '10px 30px 10px 37px',
8805				position: 'absolute',
8806				textAlign:'center'
8807			},
8808			text: msg
8809		}));
8810
8811		BX.ZIndexManager.register(obMsg);
8812		BX.ZIndexManager.bringToFront(obMsg);
8813
8814		setTimeout(BX.delegate(_adjustWait, node), 10);
8815
8816		lastWait[lastWait.length] = obMsg;
8817		return obMsg;
8818	};
8819
8820	BX.closeWait = function(node, obMsg)
8821	{
8822		if(node && !obMsg)
8823			obMsg = node.bxmsg;
8824		if(node && !obMsg && BX.hasClass(node, 'bx-core-waitwindow'))
8825			obMsg = node;
8826		if(node && !obMsg)
8827			obMsg = BX('wait_' + node.id);
8828		if(!obMsg)
8829			obMsg = lastWait.pop();
8830
8831		if (obMsg && obMsg.parentNode)
8832		{
8833			for (var i=0,len=lastWait.length;i<len;i++)
8834			{
8835				if (obMsg == lastWait[i])
8836				{
8837					lastWait = BX.util.deleteFromArray(lastWait, i);
8838					break;
8839				}
8840			}
8841
8842			BX.ZIndexManager.unregister(obMsg);
8843			obMsg.parentNode.removeChild(obMsg);
8844			if (node) node.bxmsg = null;
8845			BX.cleanNode(obMsg, true);
8846		}
8847	};
8848
8849	BX.setJSList = function(scripts)
8850	{
8851		if (BX.type.isArray(scripts))
8852		{
8853			scripts = scripts.map(function(script) {
8854				return normalizeUrl(script)
8855			});
8856
8857			jsList = jsList.concat(scripts);
8858		}
8859	};
8860
8861	BX.getJSList = function()
8862	{
8863		initJsList();
8864		return jsList;
8865	};
8866
8867	BX.setCSSList = function(cssFiles)
8868	{
8869		if (BX.type.isArray(cssFiles))
8870		{
8871			cssFiles = cssFiles.map(function(cssFile) {
8872				return normalizeUrl(cssFile);
8873			});
8874
8875			cssList = cssList.concat(cssFiles);
8876		}
8877	};
8878
8879	BX.getCSSList = function()
8880	{
8881		initCssList();
8882		return cssList;
8883	};
8884
8885	BX.getJSPath = function(js)
8886	{
8887		return js.replace(/^(http[s]*:)*\/\/[^\/]+/i, '');
8888	};
8889
8890	BX.getCSSPath = function(css)
8891	{
8892		return css.replace(/^(http[s]*:)*\/\/[^\/]+/i, '');
8893	};
8894
8895	BX.getCDNPath = function(path)
8896	{
8897		return path;
8898	};
8899
8900	BX.loadScript = function(script, callback, doc)
8901	{
8902		if (BX.type.isString(script))
8903		{
8904			script = [script];
8905		}
8906
8907		return BX.load(script, callback, doc);
8908	};
8909
8910	BX.loadCSS = function(css, doc, win)
8911	{
8912		if (BX.type.isString(css))
8913		{
8914			css = [css];
8915		}
8916
8917		if (BX.type.isArray(css))
8918		{
8919			css = css.map(function(url) {
8920				return { url: url, ext: "css" }
8921			});
8922
8923			BX.load(css, null, doc);
8924		}
8925	};
8926
8927	const LOADING = 3;
8928	const LOADED = 4;
8929	const assets = {};
8930	const loadingAssetCallbacks = {};
8931
8932	BX.load = function(items, callback, doc, reject)
8933	{
8934		if (!BX.isReady)
8935		{
8936			var _args = arguments;
8937			BX.ready(function() {
8938				BX.load.apply(this, _args);
8939			});
8940
8941			return null;
8942		}
8943
8944		doc = doc || document;
8945
8946		callback = BX.Type.isFunction(callback) ? callback : () => {};
8947
8948		return loadAsync(items, callback, doc, reject);
8949	};
8950
8951	function loadAsync(items, callback, doc, reject)
8952	{
8953		if (!BX.type.isArray(items))
8954		{
8955			callback();
8956
8957			return;
8958		}
8959
8960		function onLoad()
8961		{
8962			const nextAsset = queue.shift();
8963			if (nextAsset)
8964			{
8965				load(nextAsset, onLoad, doc, reject);
8966			}
8967			else if (allLoaded())
8968			{
8969				callback();
8970			}
8971		}
8972
8973		function allLoaded()
8974		{
8975			for (const name in assetMap)
8976			{
8977				if (assetMap[name].state !== LOADED)
8978				{
8979					return false;
8980				}
8981			}
8982
8983			return true;
8984		}
8985
8986		const queue = [];
8987		const assetMap = {};
8988		items.forEach(item => {
8989			const asset = getAsset(item);
8990			if (asset && asset.state !== LOADED)
8991			{
8992				queue.push(asset);
8993				assetMap[asset.name] = asset;
8994			}
8995		});
8996
8997		if (queue.length > 0)
8998		{
8999			const maxParallelLoads = 6;
9000			const parallelLoads = Math.min(queue.length, maxParallelLoads);
9001			const firstPackage = queue.splice(0, parallelLoads);
9002			firstPackage.forEach(asset => {
9003				load(asset, onLoad, doc, reject);
9004			});
9005		}
9006		else
9007		{
9008			callback();
9009		}
9010	}
9011
9012	function load(asset, callback, doc, reject)
9013	{
9014		callback = callback || BX.DoNothing;
9015
9016		if (asset.state === LOADED)
9017		{
9018			callback();
9019			return;
9020		}
9021
9022		if (asset.state === LOADING)
9023		{
9024			if (!BX.Type.isArray(loadingAssetCallbacks[asset.name]))
9025			{
9026				loadingAssetCallbacks[asset.name] = [];
9027			}
9028
9029			loadingAssetCallbacks[asset.name].push(callback);
9030
9031			return;
9032		}
9033
9034		asset.state = LOADING;
9035
9036		const onReject = () => {
9037			delete assets[asset.name];
9038			delete loadingAssetCallbacks[asset.name];
9039			reject();
9040		};
9041
9042		loadAsset(
9043			asset,
9044			function () {
9045				asset.state = LOADED;
9046				callback();
9047				if (BX.Type.isArrayFilled(loadingAssetCallbacks[asset.name]))
9048				{
9049					for (const cb of loadingAssetCallbacks[asset.name])
9050					{
9051						cb();
9052					}
9053				}
9054
9055				delete loadingAssetCallbacks[asset.name];
9056			},
9057			doc,
9058			BX.Type.isFunction(reject) ? onReject : null,
9059		);
9060	}
9061
9062	function loadAsset(asset, callback, doc, reject)
9063	{
9064		callback = callback || BX.DoNothing;
9065
9066		function error(event)
9067		{
9068			window.clearTimeout(asset.errorTimeout);
9069			window.clearTimeout(asset.cssTimeout);
9070			ele.onload = ele.onreadystatechange = ele.onerror = null;
9071			if (BX.Type.isFunction(reject))
9072			{
9073				reject();
9074			}
9075			else
9076			{
9077				callback();
9078			}
9079		}
9080
9081		function process(event)
9082		{
9083			if (ext === "css")
9084			{
9085				cssList.push(normalizeMinUrl(normalizeUrl(asset.url)));
9086			}
9087			else
9088			{
9089				jsList.push(normalizeMinUrl(normalizeUrl(asset.url)));
9090			}
9091
9092			event = event || window.event;
9093			if (event.type === "load" || (/loaded|complete/.test(ele.readyState) && (!doc.documentMode || doc.documentMode < 9)))
9094			{
9095				window.clearTimeout(asset.errorTimeout);
9096				window.clearTimeout(asset.cssTimeout);
9097				ele.onload = ele.onreadystatechange = ele.onerror = null;
9098				callback();
9099			}
9100		}
9101
9102		function isCssLoaded()
9103		{
9104			if (asset.state !== LOADED && asset.cssRetries <= 20)
9105			{
9106				for (var i = 0, l = doc.styleSheets.length; i < l; i++)
9107				{
9108					if (doc.styleSheets[i].href === ele.href)
9109					{
9110						process({"type": "load"});
9111						return;
9112					}
9113				}
9114
9115				asset.cssRetries++;
9116				asset.cssTimeout = window.setTimeout(isCssLoaded, 250);
9117			}
9118		}
9119
9120		let ele = null;
9121		const ext = BX.type.isNotEmptyString(asset.ext) ? asset.ext : BX.util.getExtension(asset.url);
9122
9123		if (ext === "css")
9124		{
9125			ele = doc.createElement("link");
9126			ele.type = "text/" + (asset.type || "css");
9127			ele.rel = "stylesheet";
9128			ele.href = asset.url;
9129
9130			asset.cssRetries = 0;
9131			asset.cssTimeout = window.setTimeout(isCssLoaded, 500);
9132		}
9133		else
9134		{
9135			ele = doc.createElement("script");
9136			ele.type = "text/" + (asset.type || "javascript");
9137			ele.src = asset.url;
9138		}
9139
9140		ele.onload = ele.onreadystatechange = process;
9141		ele.onerror = error;
9142
9143		ele.async = asset.async === true;
9144		ele.defer = false;
9145
9146		asset.errorTimeout = window.setTimeout(function () {
9147			error({type: "timeout"});
9148		}, 7000);
9149
9150		let templateLink = null;
9151		const head = doc.head || doc.getElementsByTagName("head")[0];
9152		if (ext === "css" && (templateLink = getTemplateLink(head)) !== null)
9153		{
9154			templateLink.parentNode.insertBefore(ele, templateLink);
9155		}
9156		else
9157		{
9158			head.insertBefore(ele, head.lastChild);
9159		}
9160	}
9161
9162	function getAsset(item)
9163	{
9164		var asset = {};
9165		if (typeof item === "object")
9166		{
9167			asset = item;
9168			asset.name = asset.name ? asset.name : BX.util.hashCode(item.url);
9169		}
9170		else
9171		{
9172			asset = { name: BX.util.hashCode(item), url : item };
9173		}
9174
9175		var ext = BX.type.isNotEmptyString(asset.ext) ? asset.ext : BX.util.getExtension(asset.url);
9176		if ((ext === "css" && isCssLoaded(asset.url)) || isScriptLoaded(asset.url))
9177		{
9178			asset.state = LOADED;
9179		}
9180
9181		var existing = assets[asset.name];
9182		if (existing && existing.url === asset.url)
9183		{
9184			return existing;
9185		}
9186
9187		assets[asset.name] = asset;
9188
9189		return asset;
9190	}
9191
9192	function normalizeUrl(url)
9193	{
9194		if (!BX.type.isNotEmptyString(url))
9195		{
9196			return "";
9197		}
9198
9199		url = BX.getJSPath(url);
9200		url = url.replace(/\?[0-9]*$/, "");
9201
9202		return url;
9203	}
9204
9205	function normalizeMinUrl(url)
9206	{
9207		if (!BX.type.isNotEmptyString(url))
9208		{
9209			return "";
9210		}
9211
9212		var minPos = url.indexOf(".min");
9213		return minPos >= 0 ? url.substr(0, minPos) + url.substr(minPos + 4) : url;
9214	}
9215
9216	function isCssLoaded(fileSrc)
9217	{
9218		initCssList();
9219
9220		fileSrc = normalizeUrl(fileSrc);
9221		var fileSrcMin = normalizeMinUrl(fileSrc);
9222
9223		return (fileSrc !== fileSrcMin && BX.util.in_array(fileSrcMin, cssList)) || BX.util.in_array(fileSrc, cssList);
9224	}
9225
9226	function initCssList()
9227	{
9228		if(!cssInit)
9229		{
9230			var linksCol = document.getElementsByTagName('link');
9231
9232			if(!!linksCol && linksCol.length > 0)
9233			{
9234				for(var i = 0; i < linksCol.length; i++)
9235				{
9236					var href = linksCol[i].getAttribute('href');
9237					if (BX.type.isNotEmptyString(href))
9238					{
9239						href = normalizeMinUrl(normalizeUrl(href));
9240						cssList.push(href);
9241					}
9242				}
9243			}
9244			cssInit = true;
9245		}
9246	}
9247
9248	function getTemplateLink(head)
9249	{
9250		var findLink = function(tag)
9251		{
9252			var links = head.getElementsByTagName(tag);
9253			for (var i = 0, length = links.length; i < length; i++)
9254			{
9255				var templateStyle = links[i].getAttribute("data-template-style");
9256				if (BX.type.isNotEmptyString(templateStyle) && templateStyle == "true")
9257				{
9258					return links[i];
9259				}
9260			}
9261
9262			return null;
9263		};
9264
9265		var link = findLink("link");
9266		if (link === null)
9267		{
9268			link = findLink("style");
9269		}
9270
9271		return link;
9272	}
9273
9274	function isScriptLoaded(fileSrc)
9275	{
9276		initJsList();
9277
9278		fileSrc = normalizeUrl(fileSrc);
9279		var fileSrcMin = normalizeMinUrl(fileSrc);
9280
9281		return (fileSrc !== fileSrcMin && BX.util.in_array(fileSrcMin, jsList)) || BX.util.in_array(fileSrc, jsList);
9282	}
9283
9284	function initJsList()
9285	{
9286		if(!jsInit)
9287		{
9288			var scriptCol = document.getElementsByTagName('script');
9289
9290			if(!!scriptCol && scriptCol.length > 0)
9291			{
9292				for(var i=0; i<scriptCol.length; i++)
9293				{
9294					var src = scriptCol[i].getAttribute('src');
9295
9296					if (BX.type.isNotEmptyString(src))
9297					{
9298						src = normalizeMinUrl(normalizeUrl(src));
9299						jsList.push(src);
9300					}
9301				}
9302			}
9303			jsInit = true;
9304		}
9305	}
9306
9307	function reloadInternal(back_url, bAddClearCache)
9308	{
9309		if (back_url === true)
9310		{
9311			bAddClearCache = true;
9312			back_url = null;
9313		}
9314
9315		var topWindow = (function() {
9316			if (BX.PageObject && BX.PageObject.getRootWindow)
9317			{
9318				return BX.PageObject.getRootWindow();
9319			}
9320
9321			return window.top;
9322		})();
9323		var new_href = back_url || topWindow.location.href;
9324
9325		var hashpos = new_href.indexOf('#'), hash = '';
9326
9327		if (hashpos != -1)
9328		{
9329			hash = new_href.substr(hashpos);
9330			new_href = new_href.substr(0, hashpos);
9331		}
9332
9333		if (bAddClearCache && new_href.indexOf('clear_cache=Y') < 0)
9334			new_href += (new_href.indexOf('?') == -1 ? '?' : '&') + 'clear_cache=Y';
9335
9336		if (hash)
9337		{
9338			// hack for clearing cache in ajax mode components with history emulation
9339			if (bAddClearCache && (hash.substr(0, 5) == 'view/' || hash.substr(0, 6) == '#view/') && hash.indexOf('clear_cache%3DY') < 0)
9340				hash += (hash.indexOf('%3F') == -1 ? '%3F' : '%26') + 'clear_cache%3DY';
9341
9342			new_href = new_href.replace(/(\?|\&)_r=[\d]*/, '');
9343			new_href += (new_href.indexOf('?') == -1 ? '?' : '&') + '_r='+Math.round(Math.random()*10000) + hash;
9344		}
9345
9346		topWindow.location.href = new_href;
9347	}
9348
9349	BX.reload = function(back_url, bAddClearCache)
9350	{
9351		reloadInternal(back_url, bAddClearCache);
9352	};
9353
9354	BX.clearCache = function()
9355	{
9356		BX.showWait();
9357		BX.reload(true);
9358	};
9359
9360	BX.template = function(tpl, callback, bKillTpl)
9361	{
9362		BX.ready(function() {
9363			_processTpl(BX(tpl), callback, bKillTpl);
9364		});
9365	};
9366
9367	BX.isAmPmMode = function(returnConst)
9368	{
9369		if (returnConst === true)
9370		{
9371			return BX.message.AMPM_MODE;
9372		}
9373		return BX.message.AMPM_MODE !== false;
9374	};
9375
9376	BX.formatDate = function(date, format)
9377	{
9378		date = date || new Date();
9379
9380		var bTime = date.getHours() || date.getMinutes() || date.getSeconds(),
9381			str = !!format
9382				? format :
9383				(bTime ? BX.message('FORMAT_DATETIME') : BX.message('FORMAT_DATE')
9384				);
9385
9386		return str.replace(/YYYY/ig, date.getFullYear())
9387			.replace(/MMMM/ig, BX.util.str_pad_left((date.getMonth()+1).toString(), 2, '0'))
9388			.replace(/MM/ig, BX.util.str_pad_left((date.getMonth()+1).toString(), 2, '0'))
9389			.replace(/DD/ig, BX.util.str_pad_left(date.getDate().toString(), 2, '0'))
9390			.replace(/HH/ig, BX.util.str_pad_left(date.getHours().toString(), 2, '0'))
9391			.replace(/MI/ig, BX.util.str_pad_left(date.getMinutes().toString(), 2, '0'))
9392			.replace(/SS/ig, BX.util.str_pad_left(date.getSeconds().toString(), 2, '0'));
9393	};
9394	BX.formatName = function(user, template, login)
9395	{
9396		user = user || {};
9397		template = (template || '');
9398		var replacement = {
9399			TITLE : (user["TITLE"] || ''),
9400			NAME : (user["NAME"] || ''),
9401			LAST_NAME : (user["LAST_NAME"] || ''),
9402			SECOND_NAME : (user["SECOND_NAME"] || ''),
9403			LOGIN : (user["LOGIN"] || ''),
9404			NAME_SHORT : user["NAME"] ? user["NAME"].substr(0, 1) + '.' : '',
9405			LAST_NAME_SHORT : user["LAST_NAME"] ? user["LAST_NAME"].substr(0, 1) + '.' : '',
9406			SECOND_NAME_SHORT : user["SECOND_NAME"] ? user["SECOND_NAME"].substr(0, 1) + '.' : '',
9407			EMAIL : (user["EMAIL"] || ''),
9408			ID : (user["ID"] || ''),
9409			NOBR : "",
9410			'/NOBR' : ""
9411		}, result = template;
9412		for (var ii in replacement)
9413		{
9414			if (replacement.hasOwnProperty(ii))
9415			{
9416				result = result.replace("#" + ii+ "#", replacement[ii])
9417			}
9418		}
9419		result = result.replace(/([\s]+)/gi, " ").trim();
9420		if (result == "")
9421		{
9422			result = (login == "Y" ? replacement["LOGIN"] : "");
9423			result = (result == "" ? "Noname" : result);
9424		}
9425		return result;
9426	};
9427
9428	BX.getNumMonth = function(month)
9429	{
9430		var wordMonthCut = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
9431		var wordMonth = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
9432
9433		var q = month.toUpperCase();
9434		for (i = 1; i <= 12; i++)
9435		{
9436			if (q == BX.message('MON_'+i).toUpperCase() || q == BX.message('MONTH_'+i).toUpperCase() || q == wordMonthCut[i-1].toUpperCase() || q == wordMonth[i-1].toUpperCase())
9437			{
9438				return i;
9439			}
9440		}
9441		return month;
9442	};
9443
9444	BX.parseDate = function(str, bUTC, formatDate, formatDatetime)
9445	{
9446		if (BX.type.isNotEmptyString(str))
9447		{
9448			if (!formatDate)
9449				formatDate = BX.message('FORMAT_DATE');
9450			if (!formatDatetime)
9451				formatDatetime = BX.message('FORMAT_DATETIME');
9452
9453			var regMonths = '';
9454			for (i = 1; i <= 12; i++)
9455			{
9456				regMonths = regMonths + '|' + BX.message('MON_'+i);
9457			}
9458
9459			var expr = new RegExp('([0-9]+|[a-z]+' + regMonths + ')', 'ig');
9460			var aDate = str.match(expr),
9461				aFormat = formatDate.match(/(DD|MI|MMMM|MM|M|YYYY)/ig),
9462				i, cnt,
9463				aDateArgs=[], aFormatArgs=[],
9464				aResult={};
9465
9466			if (!aDate)
9467				return null;
9468
9469			if(aDate.length > aFormat.length)
9470			{
9471				aFormat = formatDatetime.match(/(DD|MI|MMMM|MM|M|YYYY|HH|H|SS|TT|T|GG|G)/ig);
9472			}
9473
9474			for(i = 0, cnt = aDate.length; i < cnt; i++)
9475			{
9476				if(BX.util.trim(aDate[i]) != '')
9477				{
9478					aDateArgs[aDateArgs.length] = aDate[i];
9479				}
9480			}
9481
9482			for(i = 0, cnt = aFormat.length; i < cnt; i++)
9483			{
9484				if(BX.util.trim(aFormat[i]) != '')
9485				{
9486					aFormatArgs[aFormatArgs.length] = aFormat[i];
9487				}
9488			}
9489
9490
9491			var m = BX.util.array_search('MMMM', aFormatArgs);
9492			if (m > 0)
9493			{
9494				aDateArgs[m] = BX.getNumMonth(aDateArgs[m]);
9495				aFormatArgs[m] = "MM";
9496			}
9497			else
9498			{
9499				m = BX.util.array_search('M', aFormatArgs);
9500				if (m > 0)
9501				{
9502					aDateArgs[m] = BX.getNumMonth(aDateArgs[m]);
9503					aFormatArgs[m] = "MM";
9504				}
9505			}
9506
9507			for(i = 0, cnt = aFormatArgs.length; i < cnt; i++)
9508			{
9509				var k = aFormatArgs[i].toUpperCase();
9510				aResult[k] = k == 'T' || k == 'TT' ? aDateArgs[i] : parseInt(aDateArgs[i], 10);
9511			}
9512
9513			if(aResult['DD'] > 0 && aResult['MM'] > 0 && aResult['YYYY'] > 0)
9514			{
9515				var d = new Date();
9516
9517				if(bUTC)
9518				{
9519					d.setUTCDate(1);
9520					d.setUTCFullYear(aResult['YYYY']);
9521					d.setUTCMonth(aResult['MM'] - 1);
9522					d.setUTCDate(aResult['DD']);
9523					d.setUTCHours(0, 0, 0, 0);
9524				}
9525				else
9526				{
9527					d.setDate(1);
9528					d.setFullYear(aResult['YYYY']);
9529					d.setMonth(aResult['MM'] - 1);
9530					d.setDate(aResult['DD']);
9531					d.setHours(0, 0, 0, 0);
9532				}
9533
9534				if(
9535					(!isNaN(aResult['HH']) || !isNaN(aResult['GG']) || !isNaN(aResult['H']) || !isNaN(aResult['G']))
9536					&& !isNaN(aResult['MI'])
9537				)
9538				{
9539					if (!isNaN(aResult['H']) || !isNaN(aResult['G']))
9540					{
9541						var bPM = (aResult['T']||aResult['TT']||'am').toUpperCase()=='PM';
9542						var h = parseInt(aResult['H']||aResult['G']||0, 10);
9543						if(bPM)
9544						{
9545							aResult['HH'] = h + (h == 12 ? 0 : 12);
9546						}
9547						else
9548						{
9549							aResult['HH'] = h < 12 ? h : 0;
9550						}
9551					}
9552					else
9553					{
9554						aResult['HH'] = parseInt(aResult['HH']||aResult['GG']||0, 10);
9555					}
9556
9557					if (isNaN(aResult['SS']))
9558						aResult['SS'] = 0;
9559
9560					if(bUTC)
9561					{
9562						d.setUTCHours(aResult['HH'], aResult['MI'], aResult['SS']);
9563					}
9564					else
9565					{
9566						d.setHours(aResult['HH'], aResult['MI'], aResult['SS']);
9567					}
9568				}
9569
9570				return d;
9571			}
9572		}
9573
9574		return null;
9575	};
9576
9577	BX.selectUtils =
9578		{
9579			addNewOption: function(oSelect, opt_value, opt_name, do_sort, check_unique)
9580			{
9581				oSelect = BX(oSelect);
9582				if(oSelect)
9583				{
9584					var n = oSelect.length;
9585					if(check_unique !== false)
9586					{
9587						for(var i=0;i<n;i++)
9588						{
9589							if(oSelect[i].value==opt_value)
9590							{
9591								return;
9592							}
9593						}
9594					}
9595
9596					oSelect.options[n] = new Option(opt_name, opt_value, false, false);
9597				}
9598
9599				if(do_sort === true)
9600				{
9601					this.sortSelect(oSelect);
9602				}
9603			},
9604
9605			deleteOption: function(oSelect, opt_value)
9606			{
9607				oSelect = BX(oSelect);
9608				if(oSelect)
9609				{
9610					for(var i=0;i<oSelect.length;i++)
9611					{
9612						if(oSelect[i].value==opt_value)
9613						{
9614							oSelect.remove(i);
9615							break;
9616						}
9617					}
9618				}
9619			},
9620
9621			deleteSelectedOptions: function(oSelect)
9622			{
9623				oSelect = BX(oSelect);
9624				if(oSelect)
9625				{
9626					var i=0;
9627					while(i<oSelect.length)
9628					{
9629						if(oSelect[i].selected)
9630						{
9631							oSelect[i].selected=false;
9632							oSelect.remove(i);
9633						}
9634						else
9635						{
9636							i++;
9637						}
9638					}
9639				}
9640			},
9641
9642			deleteAllOptions: function(oSelect)
9643			{
9644				oSelect = BX(oSelect);
9645				if(oSelect)
9646				{
9647					for(var i=oSelect.length-1; i>=0; i--)
9648					{
9649						oSelect.remove(i);
9650					}
9651				}
9652			},
9653
9654			optionCompare: function(record1, record2)
9655			{
9656				var value1 = record1.optText.toLowerCase();
9657				var value2 = record2.optText.toLowerCase();
9658				if (value1 > value2) return(1);
9659				if (value1 < value2) return(-1);
9660				return(0);
9661			},
9662
9663			sortSelect: function(oSelect)
9664			{
9665				oSelect = BX(oSelect);
9666				if(oSelect)
9667				{
9668					var myOptions = [];
9669					var n = oSelect.options.length;
9670					var i;
9671					for (i=0;i<n;i++)
9672					{
9673						myOptions[i] = {
9674							optText:oSelect[i].text,
9675							optValue:oSelect[i].value
9676						};
9677					}
9678					myOptions.sort(this.optionCompare);
9679					oSelect.length=0;
9680					n = myOptions.length;
9681					for(i=0;i<n;i++)
9682					{
9683						oSelect[i] = new Option(myOptions[i].optText, myOptions[i].optValue, false, false);
9684					}
9685				}
9686			},
9687
9688			selectAllOptions: function(oSelect)
9689			{
9690				oSelect = BX(oSelect);
9691				if(oSelect)
9692				{
9693					var n = oSelect.length;
9694					for(var i=0;i<n;i++)
9695					{
9696						oSelect[i].selected=true;
9697					}
9698				}
9699			},
9700
9701			selectOption: function(oSelect, opt_value)
9702			{
9703				oSelect = BX(oSelect);
9704				if(oSelect)
9705				{
9706					var n = oSelect.length;
9707					for(var i=0;i<n;i++)
9708					{
9709						oSelect[i].selected = (oSelect[i].value == opt_value);
9710					}
9711				}
9712			},
9713
9714			addSelectedOptions: function(oSelect, to_select_id, check_unique, do_sort)
9715			{
9716				oSelect = BX(oSelect);
9717				if(!oSelect)
9718					return;
9719				var n = oSelect.length;
9720				for(var i=0; i<n; i++)
9721					if(oSelect[i].selected)
9722						this.addNewOption(to_select_id, oSelect[i].value, oSelect[i].text, do_sort, check_unique);
9723			},
9724
9725			moveOptionsUp: function(oSelect)
9726			{
9727				oSelect = BX(oSelect);
9728				if(!oSelect)
9729					return;
9730				var n = oSelect.length;
9731				for(var i=0; i<n; i++)
9732				{
9733					if(oSelect[i].selected && i>0 && oSelect[i-1].selected == false)
9734					{
9735						var option = new Option(oSelect[i].text, oSelect[i].value);
9736						oSelect[i] = new Option(oSelect[i-1].text, oSelect[i-1].value);
9737						oSelect[i].selected = false;
9738						oSelect[i-1] = option;
9739						oSelect[i-1].selected = true;
9740					}
9741				}
9742			},
9743
9744			moveOptionsDown: function(oSelect)
9745			{
9746				oSelect = BX(oSelect);
9747				if(!oSelect)
9748					return;
9749				var n = oSelect.length;
9750				for(var i=n-1; i>=0; i--)
9751				{
9752					if(oSelect[i].selected && i<n-1 && oSelect[i+1].selected == false)
9753					{
9754						var option = new Option(oSelect[i].text, oSelect[i].value);
9755						oSelect[i] = new Option(oSelect[i+1].text, oSelect[i+1].value);
9756						oSelect[i].selected = false;
9757						oSelect[i+1] = option;
9758						oSelect[i+1].selected = true;
9759					}
9760				}
9761			}
9762		};
9763
9764	BX.getEventTarget = function(e)
9765	{
9766		if(e.target)
9767		{
9768			return e.target;
9769		}
9770		else if(e.srcElement)
9771		{
9772			return e.srcElement;
9773		}
9774		return null;
9775	};
9776
9777	BX.convert = {
9778		toNumber: function(value)
9779		{
9780			if(BX.type.isNumber(value))
9781			{
9782				return value;
9783			}
9784
9785			value = Number(value);
9786			return !isNaN(value) ? value : 0;
9787		},
9788		nodeListToArray: function(nodes)
9789		{
9790			try
9791			{
9792				return (Array.prototype.slice.call(nodes, 0));
9793			}
9794			catch (ex)
9795			{
9796				var ary = [];
9797				for(var i = 0, l = nodes.length; i < l; i++)
9798				{
9799					ary.push(nodes[i]);
9800				}
9801				return ary;
9802			}
9803		}
9804	};
9805
9806	/******* HINT ***************/
9807// if function has 2 params - the 2nd one is hint html. otherwise hint_html is third and hint_title - 2nd;
9808// '<div onmouseover="BX.hint(this, 'This is &lt;b&gt;Hint&lt;/b&gt;')"'>;
9809// BX.hint(el, 'This is <b>Hint</b>') - this won't work, use constructor
9810	BX.hint = function(el, hint_title, hint_html, hint_id)
9811	{
9812		if (null == hint_html)
9813		{
9814			hint_html = hint_title;
9815			hint_title = '';
9816		}
9817
9818		if (null == el.BXHINT)
9819		{
9820			el.BXHINT = new BX.CHint({
9821				parent: el, hint: hint_html, title: hint_title, id: hint_id
9822			});
9823			el.BXHINT.Show();
9824		}
9825	};
9826
9827	BX.hint_replace = function(el, hint_title, hint_html)
9828	{
9829		if (null == hint_html)
9830		{
9831			hint_html = hint_title;
9832			hint_title = '';
9833		}
9834
9835		if (!el || !el.parentNode || !hint_html)
9836			return null;
9837
9838		var obHint = new BX.CHint({
9839			hint: hint_html,
9840			title: hint_title
9841		});
9842
9843		obHint.CreateParent();
9844
9845		el.parentNode.insertBefore(obHint.PARENT, el);
9846		el.parentNode.removeChild(el);
9847
9848		obHint.PARENT.style.marginLeft = '5px';
9849
9850		return el;
9851	};
9852
9853	BX.CHint = function(params)
9854	{
9855		if (BX.CHint.cssLoaded === false)
9856		{
9857			BX.load(['/bitrix/js/main/core/css/core_hint.css']);
9858			BX.CHint.cssLoaded = true;
9859		}
9860
9861		this.PARENT = BX(params.parent);
9862
9863		this.HINT = params.hint;
9864		this.HINT_TITLE = params.title;
9865
9866		this.PARAMS = {};
9867		for (var i in this.defaultSettings)
9868		{
9869			if (null == params[i])
9870				this.PARAMS[i] = this.defaultSettings[i];
9871			else
9872				this.PARAMS[i] = params[i];
9873		}
9874
9875		if (null != params.id)
9876			this.ID = params.id;
9877
9878		this.timer = null;
9879		this.bInited = false;
9880		this.msover = true;
9881
9882		if (this.PARAMS.showOnce)
9883		{
9884			this.__show();
9885			this.msover = false;
9886			this.timer = setTimeout(BX.proxy(this.__hide, this), this.PARAMS.hide_timeout);
9887		}
9888		else if (this.PARENT)
9889		{
9890			BX.bind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
9891			BX.bind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
9892		}
9893	};
9894
9895	BX.CHint.cssLoaded = false;
9896
9897	BX.CHint.openHints = new Set();
9898
9899	BX.CHint.globalDisabled = false;
9900
9901	BX.CHint.handleMenuOpen = function() {
9902		BX.CHint.globalDisabled = true;
9903
9904		BX.CHint.openHints.forEach(function(hint) {
9905			hint.__hide_immediately();
9906		});
9907	};
9908
9909	BX.CHint.handleMenuClose = function() {
9910		BX.CHint.globalDisabled = false;
9911	};
9912
9913	BX.addCustomEvent('onMenuOpen', BX.CHint.handleMenuOpen);
9914	BX.addCustomEvent('onMenuClose', BX.CHint.handleMenuClose);
9915
9916	BX.CHint.prototype.defaultSettings = {
9917		show_timeout: 1000,
9918		hide_timeout: 500,
9919		dx: 2,
9920		showOnce: false,
9921		preventHide: true,
9922		min_width: 250
9923	};
9924
9925	BX.CHint.prototype.CreateParent = function(element, params)
9926	{
9927		if (this.PARENT)
9928		{
9929			BX.unbind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
9930			BX.unbind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
9931		}
9932
9933		if (!params) params = {};
9934		var type = 'icon';
9935
9936		if (params.type && (params.type == "link" || params.type == "icon"))
9937			type = params.type;
9938
9939		if (element)
9940			type = "element";
9941
9942		if (type == "icon")
9943		{
9944			element = BX.create('IMG', {
9945				props: {
9946					src: params.iconSrc
9947						? params.iconSrc
9948						: "/bitrix/js/main/core/images/hint.gif"
9949				}
9950			});
9951		}
9952		else if (type == "link")
9953		{
9954			element = BX.create("A", {
9955				props: {href: 'javascript:void(0)'},
9956				html: '[?]'
9957			});
9958		}
9959
9960		this.PARENT = element;
9961
9962		BX.bind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
9963		BX.bind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
9964
9965		return this.PARENT;
9966	};
9967
9968	BX.CHint.prototype.Show = function()
9969	{
9970		this.msover = true;
9971
9972		if (null != this.timer)
9973			clearTimeout(this.timer);
9974
9975		this.timer = setTimeout(BX.proxy(this.__show, this), this.PARAMS.show_timeout);
9976	};
9977
9978	BX.CHint.prototype.Hide = function()
9979	{
9980		this.msover = false;
9981
9982		if (null != this.timer)
9983			clearTimeout(this.timer);
9984
9985		this.timer = setTimeout(BX.proxy(this.__hide, this), this.PARAMS.hide_timeout);
9986	};
9987
9988	BX.CHint.prototype.__show = function()
9989	{
9990		if (!this.msover || this.disabled || BX.CHint.globalDisabled) return;
9991		if (!this.bInited) this.Init();
9992
9993		if (this.prepareAdjustPos())
9994		{
9995			this.DIV.style.display = 'block';
9996			BX.ZIndexManager.bringToFront(this.DIV);
9997
9998			this.adjustPos();
9999
10000			BX.CHint.openHints.add(this);
10001
10002			BX.bind(window, 'scroll', BX.proxy(this.__onscroll, this));
10003
10004			if (this.PARAMS.showOnce)
10005			{
10006				this.timer = setTimeout(BX.proxy(this.__hide, this), this.PARAMS.hide_timeout);
10007			}
10008		}
10009	};
10010
10011	BX.CHint.prototype.__onscroll = function()
10012	{
10013		if (!BX.admin || !BX.admin.panel || !BX.admin.panel.isFixed()) return;
10014
10015		if (this.scrollTimer) clearTimeout(this.scrollTimer);
10016
10017		this.DIV.style.display = 'none';
10018		this.scrollTimer = setTimeout(BX.proxy(this.Reopen, this), this.PARAMS.show_timeout);
10019	};
10020
10021	BX.CHint.prototype.Reopen = function()
10022	{
10023		if (null != this.timer) clearTimeout(this.timer);
10024		this.timer = setTimeout(BX.proxy(this.__show, this), 50);
10025	};
10026
10027	BX.CHint.prototype.__hide = function()
10028	{
10029		if (this.msover) return;
10030		if (!this.bInited) return;
10031
10032		BX.unbind(window, 'scroll', BX.proxy(this.Reopen, this));
10033
10034		BX.CHint.openHints.delete(this);
10035
10036		if (this.PARAMS.showOnce)
10037		{
10038			this.Destroy();
10039		}
10040		else
10041		{
10042			this.DIV.style.display = 'none';
10043		}
10044	};
10045
10046	BX.CHint.prototype.__hide_immediately = function()
10047	{
10048		this.msover = false;
10049		this.__hide();
10050	};
10051
10052	BX.CHint.prototype.Init = function()
10053	{
10054		this.DIV = document.body.appendChild(BX.create('DIV', {
10055			props: {className: 'bx-panel-tooltip'},
10056			style: {
10057				display: 'none',
10058				position: 'absolute',
10059				visibility: 'hidden'
10060			},
10061			children: [
10062				(this.CONTENT = BX.create('DIV', {
10063					props: {className: 'bx-panel-tooltip-content'},
10064					children: [
10065						BX.create('DIV', {
10066							props: {className: 'bx-panel-tooltip-underlay'},
10067							children: [
10068								BX.create('DIV', {props: {className: 'bx-panel-tooltip-underlay-bg'}})
10069							]
10070						})
10071					]
10072				}))
10073			]
10074		}));
10075
10076		BX.ZIndexManager.register(this.DIV);
10077
10078		if (this.ID)
10079		{
10080			this.CONTENT.insertBefore(BX.create('A', {
10081				attrs: {href: 'javascript:void(0)'},
10082				props: {className: 'bx-panel-tooltip-close'},
10083				events: {click: BX.delegate(this.Close, this)}
10084			}), this.CONTENT.firstChild);
10085		}
10086
10087		if (this.HINT_TITLE)
10088		{
10089			this.CONTENT.appendChild(
10090				BX.create('DIV', {
10091					props: {className: 'bx-panel-tooltip-title'},
10092					text: this.HINT_TITLE
10093				})
10094			);
10095		}
10096
10097		if (this.HINT)
10098		{
10099			this.CONTENT_TEXT = this.CONTENT.appendChild(BX.create('DIV', {props: {className: 'bx-panel-tooltip-text'}})).appendChild(BX.create('SPAN', {html: this.HINT}));
10100		}
10101
10102		if (this.PARAMS.preventHide)
10103		{
10104			BX.bind(this.DIV, 'mouseout', BX.proxy(this.Hide, this));
10105			BX.bind(this.DIV, 'mouseover', BX.proxy(this.Show, this));
10106		}
10107
10108		this.bInited = true;
10109	};
10110
10111	BX.CHint.prototype.setContent = function(content)
10112	{
10113		this.HINT = content;
10114
10115		if (this.CONTENT_TEXT)
10116			this.CONTENT_TEXT.innerHTML = this.HINT;
10117		else
10118			this.CONTENT_TEXT = this.CONTENT.appendChild(BX.create('DIV', {props: {className: 'bx-panel-tooltip-text'}})).appendChild(BX.create('SPAN', {html: this.HINT}));
10119	};
10120
10121	BX.CHint.prototype.prepareAdjustPos = function()
10122	{
10123		this._wnd = {scrollPos: BX.GetWindowScrollPos(),scrollSize:BX.GetWindowScrollSize()};
10124		return BX.style(this.PARENT, 'display') != 'none';
10125	};
10126
10127	BX.CHint.prototype.getAdjustPos = function()
10128	{
10129		var res = {}, pos = BX.pos(this.PARENT), min_top = 0;
10130
10131		res.top = pos.bottom + this.PARAMS.dx;
10132
10133		if (BX.admin && BX.admin.panel.DIV)
10134		{
10135			min_top = BX.admin.panel.DIV.offsetHeight + this.PARAMS.dx;
10136
10137			if (BX.admin.panel.isFixed())
10138			{
10139				min_top += this._wnd.scrollPos.scrollTop;
10140			}
10141		}
10142
10143		if (res.top < min_top)
10144			res.top = min_top;
10145		else
10146		{
10147			if (res.top + this.DIV.offsetHeight > this._wnd.scrollSize.scrollHeight)
10148				res.top = pos.top - this.PARAMS.dx - this.DIV.offsetHeight;
10149		}
10150
10151		res.left = pos.left;
10152		if (pos.left < this.PARAMS.dx)
10153			pos.left = this.PARAMS.dx;
10154		else
10155		{
10156			var floatWidth = this.DIV.offsetWidth;
10157
10158			var max_left = this._wnd.scrollSize.scrollWidth - floatWidth - this.PARAMS.dx;
10159
10160			if (res.left > max_left)
10161				res.left = max_left;
10162		}
10163
10164		return res;
10165	};
10166
10167	BX.CHint.prototype.adjustWidth = function()
10168	{
10169		if (this.bWidthAdjusted) return;
10170
10171		var w = this.DIV.offsetWidth, h = this.DIV.offsetHeight;
10172
10173		if (w > this.PARAMS.min_width)
10174			w = Math.round(Math.sqrt(1.618*w*h));
10175
10176		if (w < this.PARAMS.min_width)
10177			w = this.PARAMS.min_width;
10178
10179		this.DIV.style.width = w + "px";
10180
10181		if (this._adjustWidthInt)
10182			clearInterval(this._adjustWidthInt);
10183		this._adjustWidthInt = setInterval(BX.delegate(this._adjustWidthInterval, this), 5);
10184
10185		this.bWidthAdjusted = true;
10186	};
10187
10188	BX.CHint.prototype._adjustWidthInterval = function()
10189	{
10190		if (!this.DIV || this.DIV.style.display == 'none')
10191			clearInterval(this._adjustWidthInt);
10192
10193		var
10194			dW = 20,
10195			maxWidth = 1500,
10196			w = this.DIV.offsetWidth,
10197			w1 = this.CONTENT_TEXT.offsetWidth;
10198
10199		if (w > 0 && w1 > 0 && w - w1 < dW && w < maxWidth)
10200		{
10201			this.DIV.style.width = (w + dW) + "px";
10202			return;
10203		}
10204
10205		clearInterval(this._adjustWidthInt);
10206	};
10207
10208	BX.CHint.prototype.adjustPos = function()
10209	{
10210		this.adjustWidth();
10211
10212		var pos = this.getAdjustPos();
10213
10214		this.DIV.style.top = pos.top + 'px';
10215		this.DIV.style.left = pos.left + 'px';
10216	};
10217
10218	BX.CHint.prototype.Close = function()
10219	{
10220		if (this.ID && BX.WindowManager)
10221			BX.WindowManager.saveWindowOptions(this.ID, {display: 'off'});
10222		this.__hide_immediately();
10223		this.Destroy();
10224	};
10225
10226	BX.CHint.prototype.Destroy = function()
10227	{
10228		if (this.PARENT)
10229		{
10230			BX.unbind(this.PARENT, 'mouseover', BX.proxy(this.Show, this));
10231			BX.unbind(this.PARENT, 'mouseout', BX.proxy(this.Hide, this));
10232		}
10233
10234		if (this.DIV)
10235		{
10236			BX.unbind(this.DIV, 'mouseover', BX.proxy(this.Show, this));
10237			BX.unbind(this.DIV, 'mouseout', BX.proxy(this.Hide, this));
10238
10239			BX.ZIndexManager.unregister(this.DIV);
10240
10241			BX.cleanNode(this.DIV, true);
10242		}
10243	};
10244
10245	BX.CHint.prototype.enable = function(){this.disabled = false;};
10246	BX.CHint.prototype.disable = function(){this.__hide_immediately(); this.disabled = true;};
10247
10248
10249	function _adjustWait()
10250	{
10251		if (!this.bxmsg) return;
10252
10253		var arContainerPos = BX.pos(this),
10254			div_top = arContainerPos.top;
10255
10256		if (div_top < BX.GetDocElement().scrollTop)
10257			div_top = BX.GetDocElement().scrollTop + 5;
10258
10259		this.bxmsg.style.top = (div_top + 5) + 'px';
10260
10261		if (this == BX.GetDocElement())
10262		{
10263			this.bxmsg.style.right = '5px';
10264		}
10265		else
10266		{
10267			this.bxmsg.style.left = (arContainerPos.right - this.bxmsg.offsetWidth - 5) + 'px';
10268		}
10269	}
10270
10271	function _processTpl(tplNode, cb, bKillTpl)
10272	{
10273		if (tplNode)
10274		{
10275			if (bKillTpl)
10276				tplNode.parentNode.removeChild(tplNode);
10277
10278			var res = {}, nodes = BX.findChildren(tplNode, {attribute: 'data-role'}, true);
10279
10280			for (var i = 0, l = nodes.length; i < l; i++)
10281			{
10282				res[nodes[i].getAttribute('data-role')] = nodes[i];
10283			}
10284
10285			cb.apply(tplNode, [res]);
10286		}
10287	}
10288
10289	function _checkNode(obj, params)
10290	{
10291		params = params || {};
10292
10293		if (BX.type.isFunction(params))
10294			return params.call(window, obj);
10295
10296		if (!params.allowTextNodes && !BX.type.isElementNode(obj))
10297			return false;
10298		var i,j,len;
10299		for (i in params)
10300		{
10301			if(params.hasOwnProperty(i))
10302			{
10303				switch(i)
10304				{
10305					case 'tag':
10306					case 'tagName':
10307						if (BX.type.isString(params[i]))
10308						{
10309							if (obj.tagName.toUpperCase() != params[i].toUpperCase())
10310								return false;
10311						}
10312						else if (params[i] instanceof RegExp)
10313						{
10314							if (!params[i].test(obj.tagName))
10315								return false;
10316						}
10317						break;
10318
10319					case 'class':
10320					case 'className':
10321						if (BX.type.isString(params[i]))
10322						{
10323							if (!BX.hasClass(obj, params[i]))
10324								return false;
10325						}
10326						else if (params[i] instanceof RegExp)
10327						{
10328							if (!BX.type.isString(obj.className) || !params[i].test(obj.className))
10329								return false;
10330						}
10331						break;
10332
10333					case 'attr':
10334					case 'attrs':
10335					case 'attribute':
10336						if (BX.type.isString(params[i]))
10337						{
10338							if (!obj.getAttribute(params[i]))
10339								return false;
10340						}
10341						else if (BX.type.isArray(params[i]))
10342						{
10343							for (j = 0, len = params[i].length; j < len; j++)
10344							{
10345								if (params[i] && !obj.getAttribute(params[i]))
10346									return false;
10347							}
10348						}
10349						else
10350						{
10351							for (j in params[i])
10352							{
10353								if(params[i].hasOwnProperty(j))
10354								{
10355									var q = obj.getAttribute(j);
10356									if (params[i][j] instanceof RegExp)
10357									{
10358										if (!BX.type.isString(q) || !params[i][j].test(q))
10359										{
10360											return false;
10361										}
10362									}
10363									else
10364									{
10365										if (q != '' + params[i][j])
10366										{
10367											return false;
10368										}
10369									}
10370								}
10371							}
10372						}
10373						break;
10374
10375					case 'property':
10376					case 'props':
10377						if (BX.type.isString(params[i]))
10378						{
10379							if (!obj[params[i]])
10380								return false;
10381						}
10382						else if (BX.type.isArray(params[i]))
10383						{
10384							for (j = 0, len = params[i].length; j < len; j++)
10385							{
10386								if (params[i] && !obj[params[i]])
10387									return false;
10388							}
10389						}
10390						else
10391						{
10392							for (j in params[i])
10393							{
10394								if (BX.type.isString(params[i][j]))
10395								{
10396									if (obj[j] != params[i][j])
10397										return false;
10398								}
10399								else if (params[i][j] instanceof RegExp)
10400								{
10401									if (!BX.type.isString(obj[j]) || !params[i][j].test(obj[j]))
10402										return false;
10403								}
10404							}
10405						}
10406						break;
10407
10408					case 'callback':
10409						return params[i](obj);
10410				}
10411			}
10412		}
10413
10414		return true;
10415	}
10416
10417	window.addEventListener('pagehide', () => {
10418		garbageCollectors.forEach(({ callback, context = window }) => {
10419			try
10420			{
10421				callback.apply(context);
10422			} catch (err) {}
10423		});
10424	});
10425
10426	// set empty ready handler
10427	BX(BX.DoNothing);
10428	window.BX = BX;
10429
10430	BX.browser.addGlobalClass();
10431
10432	/* data storage */
10433	BX.data = function(node, key, value)
10434	{
10435		if(typeof node == 'undefined')
10436			return undefined;
10437
10438		if(typeof key == 'undefined')
10439			return undefined;
10440
10441		if(typeof value != 'undefined')
10442		{
10443			// write to manager
10444			dataStorage.set(node, key, value);
10445		}
10446		else
10447		{
10448			var data;
10449
10450			// from manager
10451			if((data = dataStorage.get(node, key)) != undefined)
10452			{
10453				return data;
10454			}
10455			else
10456			{
10457				// from attribute data-*
10458				if('getAttribute' in node)
10459				{
10460					data = node.getAttribute('data-'+key.toString());
10461					if(data === null)
10462					{
10463						return undefined;
10464					}
10465					return data;
10466				}
10467			}
10468
10469			return undefined;
10470		}
10471	};
10472
10473	BX.DataStorage = function()
10474	{
10475
10476		this.keyOffset = 1;
10477		this.data = {};
10478		this.uniqueTag = 'BX-'+Math.random();
10479
10480		this.resolve = function(owner, create){
10481			if(typeof owner[this.uniqueTag] == 'undefined')
10482				if(create)
10483				{
10484					try
10485					{
10486						Object.defineProperty(owner, this.uniqueTag, {
10487							value: this.keyOffset++
10488						});
10489					}
10490					catch(e)
10491					{
10492						owner[this.uniqueTag] = this.keyOffset++;
10493					}
10494				}
10495				else
10496					return undefined;
10497
10498			return owner[this.uniqueTag];
10499		};
10500		this.get = function(owner, key){
10501			if((owner != document && !BX.type.isElementNode(owner)) || typeof key == 'undefined')
10502				return undefined;
10503
10504			owner = this.resolve(owner, false);
10505
10506			if(typeof owner == 'undefined' || typeof this.data[owner] == 'undefined')
10507				return undefined;
10508
10509			return this.data[owner][key];
10510		};
10511		this.set = function(owner, key, value){
10512
10513			if((owner != document && !BX.type.isElementNode(owner)) || typeof value == 'undefined')
10514				return;
10515
10516			var o = this.resolve(owner, true);
10517
10518			if(typeof this.data[o] == 'undefined')
10519				this.data[o] = {};
10520
10521			this.data[o][key] = value;
10522		};
10523	};
10524
10525// some internal variables for new logic
10526	var dataStorage = new BX.DataStorage();	// manager which BX.data() uses to keep data
10527})(window.BX);
10528
10529
10530;(function(window)
10531{
10532	/****************** ATTENTION *******************************
10533	 * Please do not use Bitrix CoreJS in this class.
10534	 * This class can be called on page without Bitrix Framework
10535	*************************************************************/
10536
10537	if (!window.BX)
10538	{
10539		window.BX = {};
10540	}
10541
10542	var BX = window.BX;
10543
10544	BX.Promise = function(fn, ctx) // fn is future-reserved
10545	{
10546		this.state = null;
10547		this.value = null;
10548		this.reason = null;
10549		this.next = null;
10550		this.ctx = ctx || this;
10551
10552		this.onFulfilled = [];
10553		this.onRejected = [];
10554	};
10555	BX.Promise.prototype.fulfill = function(value)
10556	{
10557		this.checkState();
10558
10559		this.value = value;
10560		this.state = true;
10561		this.execute();
10562	};
10563	BX.Promise.prototype.reject = function(reason)
10564	{
10565		this.checkState();
10566
10567		this.reason = reason;
10568		this.state = false;
10569		this.execute();
10570	};
10571	BX.Promise.prototype.then = function(onFulfilled, onRejected)
10572	{
10573		if(typeof (onFulfilled) == "function" || onFulfilled instanceof Function)
10574		{
10575			this.onFulfilled.push(onFulfilled);
10576		}
10577		if(typeof (onRejected) == "function" || onRejected instanceof Function)
10578		{
10579			this.onRejected.push(onRejected);
10580		}
10581
10582		if(this.next === null)
10583		{
10584			this.next = new BX.Promise(null, this.ctx);
10585		}
10586
10587		if(this.state !== null) // if promise was already resolved, execute immediately
10588		{
10589			this.execute();
10590		}
10591
10592		return this.next;
10593	};
10594
10595	BX.Promise.prototype.catch = function(onRejected)
10596	{
10597		if(typeof (onRejected) == "function" || onRejected instanceof Function)
10598		{
10599			this.onRejected.push(onRejected);
10600		}
10601
10602		if(this.next === null)
10603		{
10604			this.next = new BX.Promise(null, this.ctx);
10605		}
10606
10607		if(this.state !== null) // if promise was already resolved, execute immediately
10608		{
10609			this.execute();
10610		}
10611
10612		return this.next;
10613	};
10614
10615	BX.Promise.prototype.setAutoResolve = function(way, ms)
10616	{
10617		this.timer = setTimeout(function(){
10618			if(this.state === null)
10619			{
10620				this[way ? 'fulfill' : 'reject']();
10621			}
10622		}.bind(this), ms || 15);
10623	};
10624	BX.Promise.prototype.cancelAutoResolve = function()
10625	{
10626		clearTimeout(this.timer);
10627	};
10628	/**
10629	 * Resolve function. This function allows promise chaining, like ..then().then()...
10630	 * Typical usage:
10631	 *
10632	 * var p = new Promise();
10633	 *
10634	 * p.then(function(value){
10635	 *  return someValue; // next promise in the chain will be fulfilled with someValue
10636	 * }).then(function(value){
10637	 *
10638	 *  var p1 = new Promise();
10639	 *  *** some async code here, that eventually resolves p1 ***
10640	 *
10641	 *  return p1; // chain will resume when p1 resolved (fulfilled or rejected)
10642	 * }).then(function(value){
10643	 *
10644	 *  // you can also do
10645	 *  var e = new Error();
10646	 *  throw e;
10647	 *  // it will cause next promise to be rejected with e
10648	 *
10649	 *  return someOtherValue;
10650	 * }).then(function(value){
10651	 *  ...
10652	 * }, function(reason){
10653	 *  // promise was rejected with reason
10654	 * })...;
10655	 *
10656	 * p.fulfill('let`s start this chain');
10657	 *
10658	 * @param x
10659	 */
10660	BX.Promise.prototype.resolve = function(x)
10661	{
10662		var this_ = this;
10663
10664		if(this === x)
10665		{
10666			this.reject(new TypeError('Promise cannot fulfill or reject itself')); // avoid recursion
10667		}
10668		// allow "pausing" promise chaining until promise x is fulfilled or rejected
10669		else if(x && x.toString() === "[object BX.Promise]")
10670		{
10671			x.then(function(value){
10672				this_.fulfill(value);
10673			}, function(reason){
10674				this_.reject(reason);
10675			});
10676		}
10677		else // auto-fulfill this promise
10678		{
10679			this.fulfill(x);
10680		}
10681	};
10682
10683	BX.Promise.prototype.toString = function()
10684	{
10685		return "[object BX.Promise]";
10686	};
10687
10688	BX.Promise.prototype.execute = function()
10689	{
10690		if(this.state === null)
10691		{
10692			//then() must not be called before BX.Promise resolve() happens
10693			return;
10694		}
10695
10696		var value = undefined;
10697		var reason = undefined;
10698		var x = undefined;
10699		var k;
10700		if(this.state === true) // promise was fulfill()-ed
10701		{
10702			if(this.onFulfilled.length)
10703			{
10704				try
10705				{
10706					for(k = 0; k < this.onFulfilled.length; k++)
10707					{
10708						x = this.onFulfilled[k].apply(this.ctx, [this.value]);
10709						if(typeof x != 'undefined')
10710						{
10711							value = x;
10712						}
10713					}
10714				}
10715				catch(e)
10716				{
10717					if('console' in window)
10718					{
10719						console.dir(e);
10720					}
10721
10722					if (typeof BX.debug !== 'undefined')
10723					{
10724						BX.debug(e);
10725					}
10726
10727					reason = e; // reject next
10728				}
10729			}
10730			else
10731			{
10732				value = this.value; // resolve next
10733			}
10734		}
10735		else if(this.state === false) // promise was reject()-ed
10736		{
10737			if(this.onRejected.length)
10738			{
10739				try
10740				{
10741					for(k = 0; k < this.onRejected.length; k++)
10742					{
10743						x = this.onRejected[k].apply(this.ctx, [this.reason]);
10744						if(typeof x != 'undefined')
10745						{
10746							value = x;
10747						}
10748					}
10749				}
10750				catch(e)
10751				{
10752					if('console' in window)
10753					{
10754						console.dir(e);
10755					}
10756
10757					if (typeof BX.debug !== 'undefined')
10758					{
10759						BX.debug(e);
10760					}
10761
10762					reason = e; // reject next
10763				}
10764			}
10765			else
10766			{
10767				reason = this.reason; // reject next
10768			}
10769		}
10770
10771		if(this.next !== null)
10772		{
10773			if(typeof reason != 'undefined')
10774			{
10775				this.next.reject(reason);
10776			}
10777			else if(typeof value != 'undefined')
10778			{
10779				this.next.resolve(value);
10780			}
10781		}
10782	};
10783	BX.Promise.prototype.checkState = function()
10784	{
10785		if(this.state !== null)
10786		{
10787			throw new Error('You can not do fulfill() or reject() multiple times');
10788		}
10789	};
10790})(window);
10791
10792
10793
10794
10795;(function(window){
10796
10797if (window.BX.ajax)
10798	return;
10799
10800var
10801	BX = window.BX,
10802
10803	tempDefaultConfig = {},
10804	defaultConfig = {
10805		method: 'GET', // request method: GET|POST
10806		dataType: 'html', // type of data loading: html|json|script
10807		timeout: 0, // request timeout in seconds. 0 for browser-default
10808		async: true, // whether request is asynchronous or not
10809		processData: true, // any data processing is disabled if false, only callback call
10810		scriptsRunFirst: false, // whether to run _all_ found scripts before onsuccess call. script tag can have an attribute "bxrunfirst" to turn  this flag on only for itself
10811		emulateOnload: true,
10812		skipAuthCheck: false, // whether to check authorization failure (SHOUD be set to true for CORS requests)
10813		start: true, // send request immediately (if false, request can be started manually via XMLHttpRequest object returned)
10814		cache: true, // whether NOT to add random addition to URL
10815		preparePost: true, // whether set Content-Type x-www-form-urlencoded in POST
10816		headers: false, // add additional headers, example: [{'name': 'If-Modified-Since', 'value': 'Wed, 15 Aug 2012 08:59:08 GMT'}, {'name': 'If-None-Match', 'value': '0'}]
10817		lsTimeout: 30, //local storage data TTL. useless without lsId.
10818		lsForce: false //wheter to force query instead of using localStorage data. useless without lsId.
10819/*
10820other parameters:
10821	url: url to get/post
10822	data: data to post
10823	onsuccess: successful request callback. BX.proxy may be used.
10824	onfailure: request failure callback. BX.proxy may be used.
10825	onprogress: request progress callback. BX.proxy may be used.
10826
10827	lsId: local storage id - for constantly updating queries which can communicate via localStorage. core_ls.js needed
10828
10829any of the default parameters can be overridden. defaults can be changed by BX.ajax.Setup() - for all further requests!
10830*/
10831	},
10832	loadedScripts = {},
10833	loadedScriptsQueue = [],
10834	r = {
10835		'url_utf': /[^\034-\254]+/g,
10836		'script_self': /\/bitrix\/js\/main\/core\/core(_ajax)*.js$/i,
10837		'script_self_window': /\/bitrix\/js\/main\/core\/core_window.js$/i,
10838		'script_self_admin': /\/bitrix\/js\/main\/core\/core_admin.js$/i,
10839		'script_onload': /window.onload/g
10840	};
10841
10842// low-level method
10843BX.ajax = function(config)
10844{
10845	var status, data;
10846
10847	if (!config || !config.url || !BX.type.isString(config.url))
10848	{
10849		return false;
10850	}
10851
10852	for (var i in tempDefaultConfig)
10853		if (typeof (config[i]) == "undefined") config[i] = tempDefaultConfig[i];
10854
10855	tempDefaultConfig = {};
10856
10857	for (i in defaultConfig)
10858		if (typeof (config[i]) == "undefined") config[i] = defaultConfig[i];
10859
10860	config.method = config.method.toUpperCase();
10861
10862	if (!BX.localStorage)
10863		config.lsId = null;
10864
10865	if (BX.browser.IsIE())
10866	{
10867		var result = r.url_utf.exec(config.url);
10868		if (result)
10869		{
10870			do
10871			{
10872				config.url = config.url.replace(result, BX.util.urlencode(result));
10873				result = r.url_utf.exec(config.url);
10874			} while (result);
10875		}
10876	}
10877
10878	if(config.dataType == 'json')
10879		config.emulateOnload = false;
10880
10881	if (!config.cache && config.method == 'GET')
10882		config.url = BX.ajax._uncache(config.url);
10883
10884	if (config.method == 'POST')
10885	{
10886		if (config.preparePost)
10887		{
10888			config.data = BX.ajax.prepareData(config.data);
10889		}
10890		else if (getLastContentTypeHeader(config.headers) === 'application/json')
10891		{
10892			const isJson = (
10893				BX.Type.isPlainObject(config.data)
10894				|| BX.Type.isString(config.data)
10895				|| BX.Type.isNumber(config.data)
10896				|| BX.Type.isBoolean(config.data)
10897				|| BX.Type.isArray(config.data)
10898			);
10899
10900			if (isJson)
10901			{
10902				config.data = JSON.stringify(config.data);
10903			}
10904		}
10905	}
10906
10907	var bXHR = true;
10908	if (config.lsId && !config.lsForce)
10909	{
10910		var v = BX.localStorage.get('ajax-' + config.lsId);
10911		if (v !== null)
10912		{
10913			bXHR = false;
10914
10915			var lsHandler = function(lsData) {
10916				if (lsData.key == 'ajax-' + config.lsId && lsData.value != 'BXAJAXWAIT')
10917				{
10918					var data = lsData.value,
10919						bRemove = !!lsData.oldValue && data == null;
10920					if (!bRemove)
10921						BX.ajax.__run(config, data);
10922					else if (config.onfailure)
10923						config.onfailure("timeout");
10924
10925					BX.removeCustomEvent('onLocalStorageChange', lsHandler);
10926				}
10927			};
10928
10929			if (v == 'BXAJAXWAIT')
10930			{
10931				BX.addCustomEvent('onLocalStorageChange', lsHandler);
10932			}
10933			else
10934			{
10935				setTimeout(function() {lsHandler({key: 'ajax-' + config.lsId, value: v})}, 10);
10936			}
10937		}
10938	}
10939
10940	if (bXHR)
10941	{
10942		config.xhr = BX.ajax.xhr();
10943		if (!config.xhr) return;
10944
10945		if (config.lsId)
10946		{
10947			BX.localStorage.set('ajax-' + config.lsId, 'BXAJAXWAIT', config.lsTimeout);
10948		}
10949
10950		if (BX.Type.isFunction(config.onprogress))
10951		{
10952			BX.bind(config.xhr, 'progress', config.onprogress);
10953		}
10954
10955		if (BX.Type.isFunction(config.onprogressupload) && config.xhr.upload)
10956		{
10957			BX.bind(config.xhr.upload, 'progress', config.onprogressupload);
10958		}
10959
10960		config.xhr.open(config.method, config.url, config.async);
10961
10962		if (!config.skipBxHeader && !BX.ajax.isCrossDomain(config.url))
10963		{
10964			config.xhr.setRequestHeader('Bx-ajax', 'true');
10965		}
10966
10967		if (config.method == 'POST' && config.preparePost)
10968		{
10969			config.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
10970		}
10971		if (typeof(config.headers) == "object")
10972		{
10973			for (i = 0; i < config.headers.length; i++)
10974				config.xhr.setRequestHeader(config.headers[i].name, config.headers[i].value);
10975		}
10976
10977		var bRequestCompleted = false;
10978		var onreadystatechange = config.xhr.onreadystatechange = function(additional)
10979		{
10980			if (bRequestCompleted)
10981				return;
10982
10983			if (additional === 'timeout')
10984			{
10985				if (config.onfailure)
10986				{
10987					config.onfailure('timeout', '', config);
10988				}
10989
10990				BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['timeout', '', config]);
10991
10992				config.xhr.onreadystatechange = BX.DoNothing;
10993				config.xhr.abort();
10994
10995				if (config.async)
10996				{
10997					config.xhr = null;
10998				}
10999			}
11000			else
11001			{
11002				if (config.xhr.readyState == 4 || additional == 'run')
11003				{
11004					status = BX.ajax.xhrSuccess(config.xhr) ? "success" : "error";
11005					bRequestCompleted = true;
11006					config.xhr.onreadystatechange = BX.DoNothing;
11007
11008					if (status == 'success')
11009					{
11010						var authHeader = (!!config.skipAuthCheck || BX.ajax.isCrossDomain(config.url))
11011							? false
11012							: config.xhr.getResponseHeader('X-Bitrix-Ajax-Status');
11013
11014						if(!!authHeader && authHeader == 'Authorize')
11015						{
11016							if (config.onfailure)
11017							{
11018								config.onfailure('auth', config.xhr.status, config);
11019							}
11020
11021							BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['auth', config.xhr.status, config]);
11022						}
11023						else
11024						{
11025							var data = config.xhr.responseText;
11026
11027							if (config.lsId)
11028							{
11029								BX.localStorage.set('ajax-' + config.lsId, data, config.lsTimeout);
11030							}
11031
11032							BX.ajax.__run(config, data);
11033						}
11034					}
11035					else
11036					{
11037						if (config.onfailure)
11038						{
11039							config.onfailure('status', config.xhr.status, config);
11040						}
11041
11042						BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['status', config.xhr.status, config]);
11043					}
11044
11045					if (config.async)
11046					{
11047						config.xhr = null;
11048					}
11049				}
11050			}
11051		};
11052
11053		if (config.async && config.timeout > 0)
11054		{
11055			setTimeout(function() {
11056				if (config.xhr && !bRequestCompleted)
11057				{
11058					onreadystatechange("timeout");
11059				}
11060			}, config.timeout * 1000);
11061		}
11062
11063		if (config.start)
11064		{
11065			config.xhr.send(config.data);
11066
11067			if (!config.async)
11068			{
11069				onreadystatechange('run');
11070			}
11071		}
11072
11073		return config.xhr;
11074	}
11075};
11076
11077BX.ajax.xhr = function()
11078{
11079	if (window.XMLHttpRequest)
11080	{
11081		try {return new XMLHttpRequest();} catch(e){}
11082	}
11083	else if (window.ActiveXObject)
11084	{
11085		try { return new window.ActiveXObject("Msxml2.XMLHTTP.6.0"); }
11086			catch(e) {}
11087		try { return new window.ActiveXObject("Msxml2.XMLHTTP.3.0"); }
11088			catch(e) {}
11089		try { return new window.ActiveXObject("Msxml2.XMLHTTP"); }
11090			catch(e) {}
11091		try { return new window.ActiveXObject("Microsoft.XMLHTTP"); }
11092			catch(e) {}
11093		throw new Error("This browser does not support XMLHttpRequest.");
11094	}
11095
11096	return null;
11097};
11098
11099BX.ajax.isCrossDomain = function(url, location)
11100{
11101	location = location || window.location;
11102
11103	//Relative URL gets a current protocol
11104	if (url.indexOf("//") === 0)
11105	{
11106		url = location.protocol + url;
11107	}
11108
11109	//Fast check
11110	if (url.indexOf("http") !== 0)
11111	{
11112		return false;
11113	}
11114
11115	var link = window.document.createElement("a");
11116	link.href = url;
11117
11118	return  link.protocol !== location.protocol ||
11119			link.hostname !== location.hostname ||
11120			BX.ajax.getHostPort(link.protocol, link.host) !== BX.ajax.getHostPort(location.protocol, location.host);
11121};
11122
11123BX.ajax.getHostPort = function(protocol, host)
11124{
11125	var match = /:(\d+)$/.exec(host);
11126	if (match)
11127	{
11128		return match[1];
11129	}
11130	else
11131	{
11132		if (protocol === "http:")
11133		{
11134			return "80";
11135		}
11136		else if (protocol === "https:")
11137		{
11138			return "443";
11139		}
11140	}
11141
11142	return "";
11143};
11144
11145BX.ajax.__prepareOnload = function(scripts, ajax_session)
11146{
11147	if (scripts.length > 0)
11148	{
11149		BX.ajax['onload_' + ajax_session] = null;
11150
11151		for (var i=0,len=scripts.length;i<len;i++)
11152		{
11153			if (scripts[i].isInternal)
11154			{
11155				scripts[i].JS = scripts[i].JS.replace(r.script_onload, 'BX.aja
11155x.onload_' + ajax_session);
11156			}
11157		}
11158	}
11159
11160	BX.CaptureEventsGet();
11161	BX.CaptureEvents(window, 'load');
11162};
11163
11164BX.ajax.__runOnload = function(ajax_session)
11165{
11166	if (null != BX.ajax['onload_' + ajax_session])
11167	{
11168		BX.ajax['onload_' + ajax_session].apply(window);
11169		BX.ajax['onload_' + ajax_session] = null;
11170	}
11171
11172	var h = BX.CaptureEventsGet();
11173
11174	if (h)
11175	{
11176		for (var i=0; i<h.length; i++)
11177			h[i].apply(window);
11178	}
11179};
11180
11181BX.ajax.__run = function(config, data)
11182{
11183	if (!config.processData)
11184	{
11185		if (config.onsuccess)
11186		{
11187			config.onsuccess(data);
11188		}
11189
11190		BX.onCustomEvent(config.xhr, 'onAjaxSuccess', [data, config]);
11191	}
11192	else
11193	{
11194		data = BX.ajax.processRequestData(data, config);
11195	}
11196};
11197
11198
11199BX.ajax._onParseJSONFailure = function(data)
11200{
11201	this.jsonFailure = true;
11202	this.jsonResponse = data;
11203	this.jsonProactive = /^\[WAF\]/.test(data);
11204};
11205
11206BX.ajax.processRequestData = function(data, config)
11207{
11208	var result, scripts = [], styles = [];
11209	switch (config.dataType.toUpperCase())
11210	{
11211		case 'JSON':
11212
11213			var context = config.xhr || {};
11214			BX.addCustomEvent(context, 'onParseJSONFailure', BX.proxy(BX.ajax._onParseJSONFailure, config));
11215			result = BX.parseJSON(data, context);
11216			BX.removeCustomEvent(context, 'onParseJSONFailure', BX.proxy(BX.ajax._onParseJSONFailure, config));
11217
11218			if(!!result && BX.type.isArray(result['bxjs']))
11219			{
11220				for(var i = 0; i < result['bxjs'].length; i++)
11221				{
11222					if(BX.type.isNotEmptyString(result['bxjs'][i]))
11223					{
11224						scripts.push({
11225							"isInternal": false,
11226							"JS": result['bxjs'][i],
11227							"bRunFirst": config.scriptsRunFirst
11228						});
11229					}
11230					else
11231					{
11232						scripts.push(result['bxjs'][i])
11233					}
11234				}
11235			}
11236
11237			if(!!result && BX.type.isArray(result['bxcss']))
11238			{
11239				styles = result['bxcss'];
11240			}
11241
11242		break;
11243		case 'SCRIPT':
11244			scripts.push({"isInternal": true, "JS": data, "bRunFirst": config.scriptsRunFirst});
11245			result = data;
11246		break;
11247
11248		default: // HTML
11249			var ob = BX.processHTML(data, config.scriptsRunFirst);
11250			result = ob.HTML; scripts = ob.SCRIPT; styles = ob.STYLE;
11251		break;
11252	}
11253
11254	if (styles.length > 0)
11255	{
11256		BX.loadCSS(styles);
11257	}
11258
11259	let ajax_session = null;
11260	if (config.emulateOnload)
11261	{
11262		ajax_session = parseInt(Math.random() * 1000000);
11263		BX.ajax.__prepareOnload(scripts, ajax_session);
11264	}
11265
11266	const cb = BX.defer(function()
11267	{
11268		if (config.emulateOnload)
11269		{
11270			BX.ajax.__runOnload(ajax_session);
11271		}
11272
11273		BX.onCustomEvent(config.xhr, 'onAjaxSuccessFinish', [config]);
11274	});
11275
11276	try
11277	{
11278		if (!!config.jsonFailure)
11279		{
11280			throw {type: 'json_failure', data: config.jsonResponse, bProactive: config.jsonProactive};
11281		}
11282
11283		config.scripts = scripts;
11284
11285		BX.ajax.processScripts(config.scripts, true);
11286
11287		if (config.onsuccess)
11288		{
11289			config.onsuccess(result);
11290		}
11291
11292		BX.onCustomEvent(config.xhr, 'onAjaxSuccess', [result, config]);
11293
11294		BX.ajax.processScripts(config.scripts, false, cb);
11295	}
11296	catch (e)
11297	{
11298		if (config.onfailure)
11299			config.onfailure("processing", e);
11300		BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['processing', e, config]);
11301	}
11302};
11303
11304BX.ajax.processScripts = function(scripts, bRunFirst, cb)
11305{
11306	var scriptsExt = [], scriptsInt = '';
11307
11308	cb = cb || BX.DoNothing;
11309
11310	for (var i = 0, length = scripts.length; i < length; i++)
11311	{
11312		if (typeof bRunFirst != 'undefined' && bRunFirst != !!scripts[i].bRunFirst)
11313			continue;
11314
11315		if (scripts[i].isInternal)
11316			scriptsInt += ';' + scripts[i].JS;
11317		else
11318			scriptsExt.push(scripts[i].JS);
11319	}
11320
11321	scriptsExt = BX.util.array_unique(scriptsExt);
11322	var inlineScripts = scriptsInt.length > 0 ? function() { BX.evalGlobal(scriptsInt); } : BX.DoNothing;
11323
11324	if (scriptsExt.length > 0)
11325	{
11326		BX.load(scriptsExt, function() {
11327			inlineScripts();
11328			cb();
11329		});
11330	}
11331	else
11332	{
11333		inlineScripts();
11334		cb();
11335	}
11336};
11337
11338// TODO: extend this function to use with any data objects or forms
11339BX.ajax.prepareData = function(arData, prefix)
11340{
11341	var data = '';
11342	if (BX.type.isString(arData))
11343		data = arData;
11344	else if (null != arData)
11345	{
11346		for(var i in arData)
11347		{
11348			if (arData.hasOwnProperty(i))
11349			{
11350				if (data.length > 0)
11351					data += '&';
11352				var name = BX.util.urlencode(i);
11353				if(prefix)
11354					name = prefix + '[' + name + ']';
11355				if(typeof arData[i] == 'object')
11356					data += BX.ajax.prepareData(arData[i], name);
11357				else
11358					data += name + '=' + BX.util.urlencode(arData[i]);
11359			}
11360		}
11361	}
11362	return data;
11363};
11364
11365BX.ajax.xhrSuccess = function(xhr)
11366{
11367	return (xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
11368};
11369
11370BX.ajax.Setup = function(config, bTemp)
11371{
11372	bTemp = !!bTemp;
11373
11374	for (var i in config)
11375	{
11376		if (bTemp)
11377			tempDefaultConfig[i] = config[i];
11378		else
11379			defaultConfig[i] = config[i];
11380	}
11381};
11382
11383BX.ajax.replaceLocalStorageValue = function(lsId, data, ttl)
11384{
11385	if (!!BX.localStorage)
11386		BX.localStorage.set('ajax-' + lsId, data, ttl);
11387};
11388
11389
11390BX.ajax._uncache = function(url)
11391{
11392	return url + ((url.indexOf('?') !== -1 ? "&" : "?") + '_=' + (new Date()).getTime());
11393};
11394
11395/* simple interface */
11396BX.ajax.get = function(url, data, callback)
11397{
11398	if (BX.type.isFunction(data))
11399	{
11400		callback = data;
11401		data = '';
11402	}
11403
11404	data = BX.ajax.prepareData(data);
11405
11406	if (data)
11407	{
11408		url += (url.indexOf('?') !== -1 ? "&" : "?") + data;
11409		data = '';
11410	}
11411
11412	return BX.ajax({
11413		'method': 'GET',
11414		'dataType': 'html',
11415		'url': url,
11416		'data':  '',
11417		'onsuccess': callback
11418	});
11419};
11420
11421BX.ajax.getCaptcha = function(callback)
11422{
11423	return BX.ajax.loadJSON('/bitrix/tools/ajax_captcha.php', callback);
11424};
11425
11426BX.ajax.insertToNode = function(url, node)
11427{
11428	node = BX(node);
11429	if (!!node)
11430	{
11431		var eventArgs = { cancel: false };
11432		BX.onCustomEvent('onAjaxInsertToNode', [{ url: url, node: node, eventArgs: eventArgs }]);
11433		if(eventArgs.cancel === true)
11434		{
11435			return;
11436		}
11437
11438		var show = null;
11439		if (!tempDefaultConfig.denyShowWait)
11440		{
11441			show = BX.showWait(node);
11442			delete tempDefaultConfig.denyShowWait;
11443		}
11444
11445		return BX.ajax.get(url, function(data) {
11446			node.innerHTML = data;
11447			BX.closeWait(node, show);
11448		});
11449	}
11450};
11451
11452BX.ajax.post = function(url, data, callback)
11453{
11454	data = BX.ajax.prepareData(data);
11455
11456	return BX.ajax({
11457		'method': 'POST',
11458		'dataType': 'html',
11459		'url': url,
11460		'data':  data,
11461		'onsuccess': callback
11462	});
11463};
11464
11465/**
11466 * BX.ajax with BX.Promise
11467 *
11468 * @param config
11469 * @returns {BX.Promise|false}
11470 */
11471BX.ajax.promise = function(config)
11472{
11473	var result = new BX.Promise();
11474
11475	config.onsuccess = function(data)
11476	{
11477		result.fulfill(data);
11478	};
11479	config.onfailure = function(reason, httpStatus, config)
11480	{
11481		result.reject({
11482			reason: reason,
11483			data: httpStatus,
11484			ajaxConfig: config,
11485			xhr: config.xhr
11486		});
11487	};
11488
11489	var xhr = BX.ajax(config);
11490	if (xhr)
11491	{
11492		if (typeof config.onrequeststart === 'function')
11493		{
11494			config.onrequeststart(xhr);
11495		}
11496	}
11497	else
11498	{
11499		result.reject({
11500			reason: "init",
11501			data: false
11502		});
11503	}
11504
11505	return result;
11506};
11507
11508/* load and execute external file script with onload emulation */
11509BX.ajax.loadScriptAjax = function(script_src, callback, bPreload)
11510{
11511	if (BX.type.isArray(script_src))
11512	{
11513		for (var i=0,len=script_src.length;i<len;i++)
11514		{
11515			BX.ajax.loadScriptAjax(script_src[i], callback, bPreload);
11516		}
11517	}
11518	else
11519	{
11520		var script_src_test = script_src.replace(/\.js\?.*/, '.js');
11521
11522		if (r.script_self.test(script_src_test)) return;
11523		if (r.script_self_window.test(script_src_test) && BX.CWindow) return;
11524		if (r.script_self_admin.test(script_src_test) && BX.admin) return;
11525
11526		if (typeof loadedScripts[script_src_test] == 'undefined')
11527		{
11528			if (!!bPreload)
11529			{
11530				loadedScripts[script_src_test] = '';
11531				return BX.loadScript(script_src);
11532			}
11533			else
11534			{
11535				return BX.ajax({
11536					url: script_src,
11537					method: 'GET',
11538					dataType: 'script',
11539					processData: true,
11540					emulateOnload: false,
11541					scriptsRunFirst: true,
11542					async: false,
11543					start: true,
11544					onsuccess: function(result) {
11545						loadedScripts[script_src_test] = result;
11546						if (callback)
11547							callback(result);
11548					}
11549				});
11550			}
11551		}
11552		else if (callback)
11553		{
11554			callback(loadedScripts[script_src_test]);
11555		}
11556	}
11557};
11558
11559/* non-xhr loadings */
11560BX.ajax.loadJSON = function(url, data, callback, callback_failure)
11561{
11562	if (BX.type.isFunction(data))
11563	{
11564		callback_failure = callback;
11565		callback = data;
11566		data = '';
11567	}
11568
11569	data = BX.ajax.prepareData(data);
11570
11571	if (data)
11572	{
11573		url += (url.indexOf('?') !== -1 ? "&" : "?") + data;
11574		data = '';
11575	}
11576
11577	return BX.ajax({
11578		'method': 'GET',
11579		'dataType': 'json',
11580		'url': url,
11581		'onsuccess': callback,
11582		'onfailure': callback_failure
11583	});
11584};
11585
11586var getLastContentTypeHeader = function (headers) {
11587	if (!BX.Type.isArray(headers))
11588	{
11589		return null;
11590	}
11591	var lastHeader = headers
11592		.filter(function (header) {
11593			return header.name === 'Content-Type';
11594		})
11595		.pop();
11596
11597	return lastHeader ? lastHeader.value : null;
11598};
11599
11600/**
11601 * @see isValidAnalyticsData in ui.analytics
11602* */
11603const isValidAnalyticsData = function (analytics)
11604{
11605	if (!BX.Type.isPlainObject(analytics))
11606	{
11607		console.error('BX.ajax: {analytics} must be an object.');
11608
11609		return false;
11610	}
11611
11612	const requiredFields = ['event', 'tool', 'category'];
11613	for (const field of requiredFields)
11614	{
11615		if (!BX.Type.isStringFilled(analytics[field]))
11616		{
11617			console.error(`BX.ajax: The "${field}" property in the "analytics" object must be a non-empty string.`);
11618
11619			return false;
11620		}
11621	}
11622
11623	const additionalFields = ['p1', 'p2', 'p3', 'p4', 'p5'];
11624	for (const field of additionalFields)
11625	{
11626		const value = analytics[field];
11627		if (!BX.Type.isStringFilled(value))
11628		{
11629			continue;
11630		}
11631
11632		if (value.split('_').length > 2)
11633		{
11634			console.error(`BX.ajax: The "${field}" property (${value}) in the "analytics" object must be a string containing a single underscore.`);
11635
11636			return false;
11637		}
11638	}
11639
11640	return true;
11641};
11642
11643const processAnalyticsDataToGetParameters = function(config)
11644{
11645	const getParameters = {};
11646	if (BX.Type.isStringFilled(config.analyticsLabel) || BX.Type.isPlainObject(config.analyticsLabel))
11647	{
11648		getParameters.analyticsLabel = config.analyticsLabel;
11649	}
11650
11651	if (BX.Type.isPlainObject(config.analytics))
11652	{
11653		if (config.analyticsLabel)
11654		{
11655			delete getParameters.analyticsLabel;
11656			console.error('BX.ajax: Only {analytics} or {analyticsLabel} should be used. If both are present, {analyticsLabel} will be ignored.');
11657		}
11658
11659		if (isValidAnalyticsData(config.analytics))
11660		{
11661			getParameters.st = config.analytics;
11662		}
11663		else
11664		{
11665			console.error('BX.ajax: {analytics} is invalid and is skipped.');
11666		}
11667	}
11668
11669	return getParameters;
11670};
11671
11672const prepareAjaxGetParameters = function(config)
11673{
11674	let getParameters = config.getParameters || {};
11675	getParameters = { ...getParameters, ...processAnalyticsDataToGetParameters(config) };
11676
11677	if (typeof config.mode !== 'undefined')
11678	{
11679		getParameters.mode = config.mode;
11680	}
11681	if (config.navigation)
11682	{
11683		if (config.navigation.page)
11684		{
11685			getParameters.nav = 'page-' + config.navigation.page;
11686		}
11687		if (config.navigation.size)
11688		{
11689			if (getParameters.nav)
11690			{
11691				getParameters.nav += '-';
11692			}
11693			else
11694			{
11695				getParameters.nav = '';
11696			}
11697			getParameters.nav += 'size-' + config.navigation.size;
11698		}
11699	}
11700
11701	return getParameters;
11702};
11703
11704var prepareAjaxConfig = function(config)
11705{
11706	config = BX.type.isPlainObject(config) ? config : {};
11707
11708	config.headers = config.headers || [];
11709	config.headers.push({name: 'X-Bitrix-Csrf-Token', value: BX.bitrix_sessid()});
11710	if (BX.message.SITE_ID)
11711	{
11712		config.headers.push({name: 'X-Bitrix-Site-Id', value: BX.message.SITE_ID});
11713	}
11714
11715	if (typeof config.json !== 'undefined')
11716	{
11717		if (!BX.type.isPlainObject(config.json))
11718		{
11719			throw new Error('Wrong `config.json`, plain object expected.')
11720		}
11721
11722		config.headers.push({name: 'Content-Type', value: 'application/json'});
11723		config.data = config.json;
11724		config.preparePost = false;
11725	}
11726	else if (config.data instanceof FormData)
11727	{
11728		config.preparePost = false;
11729		if (typeof config.signedParameters !== 'undefined')
11730		{
11731			config.data.append('signedParameters', config.signedParameters);
11732		}
11733	}
11734	else if (BX.type.isPlainObject(config.data) || BX.Type.isNil(config.data))
11735	{
11736		config.data = BX.type.isPlainObject(config.data) ? config.data : {};
11737		if (typeof config.signedParameters !== 'undefined')
11738		{
11739			config.data.signedParameters = config.signedParameters;
11740		}
11741	}
11742
11743	if (!config.method)
11744	{
11745		config.method = 'POST'
11746	}
11747
11748	return config;
11749};
11750
11751var buildAjaxPromiseToRestoreCsrf = function(config, withoutRestoringCsrf)
11752{
11753	withoutRestoringCsrf = withoutRestoringCsrf || false;
11754	var originalConfig = BX.clone(config);
11755	var request = null;
11756
11757	var onrequeststart = config.onrequeststart;
11758	config.onrequeststart = function(xhr) {
11759		request = xhr;
11760		if (BX.type.isFunction(onrequeststart))
11761		{
11762			onrequeststart(xhr);
11763		}
11764	};
11765	var onrequeststartOrig = originalConfig.onrequeststart;
11766	originalConfig.onrequeststart = function(xhr) {
11767		request = xhr;
11768		if (BX.type.isFunction(onrequeststartOrig))
11769		{
11770			onrequeststartOrig(xhr);
11771		}
11772	};
11773
11774	var promise = BX.ajax.promise(config);
11775
11776	return promise.then(function(response) {
11777		if (!withoutRestoringCsrf && BX.type.isPlainObject(response) && BX.type.isArray(response.errors))
11778		{
11779			var csrfProblem = false;
11780			response.errors.forEach(function(error) {
11781				if (error.code === 'invalid_csrf' && error.customData.csrf)
11782				{
11783					BX.message({'bitrix_sessid': error.customData.csrf});
11784
11785					originalConfig.headers = originalConfig.headers || [];
11786					originalConfig.headers = originalConfig.headers.filter(function(header) {
11787						return header && header.name !== 'X-Bitrix-Csrf-Token';
11788					});
11789					originalConfig.headers.push({name: 'X-Bitrix-Csrf-Token', value: BX.bitrix_sessid()});
11790
11791					csrfProblem = true;
11792				}
11793			});
11794
11795			if (csrfProblem)
11796			{
11797				return buildAjaxPromiseToRestoreCsrf(originalConfig, true);
11798			}
11799		}
11800
11801		if (!BX.type.isPlainObject(response) || response.status !== 'success')
11802		{
11803			var errorPromise = new BX.Promise();
11804			errorPromise.reject(response);
11805
11806			return errorPromise;
11807		}
11808
11809		return response;
11810	}).catch(function(data) {
11811		var ajaxReject = new BX.Promise();
11812
11813		var originalJsonResponse;
11814		if (BX.type.isPlainObject(data) && data.xhr && data.xhr.responseText)
11815		{
11816			try
11817			{
11818				originalJsonResponse = JSON.parse(data.xhr.responseText);
11819				data = originalJsonResponse;
11820			}
11821			catch (err)
11822			{}
11823		}
11824
11825		if (BX.type.isPlainObject(data) && data.status && data.hasOwnProperty('data'))
11826		{
11827			ajaxReject.reject(data);
11828		}
11829		else
11830		{
11831			ajaxReject.reject({
11832				status: 'error',
11833				data: {
11834					ajaxRejectData: data
11835				},
11836				errors: [
11837					{
11838						code: 'NETWORK_ERROR',
11839						message: 'Network error'
11840					}
11841				]
11842			});
11843		}
11844
11845		return ajaxReject;
11846	}).then(function(response){
11847
11848		var assetsLoaded = new BX.Promise();
11849
11850		var headers = request.getAllResponseHeaders().trim().split(/[\r\n]+/);
11851		var headerMap = {};
11852		headers.forEach(function (line) {
11853			var parts = line.split(': ');
11854			var header = parts.shift().toLowerCase();
11855			headerMap[header] = parts.join(': ');
11856		});
11857
11858		if (!headerMap['x-process-assets'])
11859		{
11860			assetsLoaded.fulfill(response);
11861
11862			return assetsLoaded;
11863		}
11864
11865		var assets = BX.prop.getObject(BX.prop.getObject(response, "data", {}), "assets", {});
11866
11867		var inlineScripts = [];
11868		if (BX.Type.isArrayFilled(assets.string))
11869		{
11870			assets.string
11871				.reduce(function(acc, item) {
11872					if (String(item).length > 0 && !acc.includes(item))
11873					{
11874						acc.push(item);
11875					}
11876
11877					return acc;
11878				}, [])
11879				.forEach(function(item) {
11880					if (String(item).startsWith('<script type="extension/settings"'))
11881					{
11882						BX.html(document.head, item, { useAdjacentHTML: true });
11883					}
11884					else
11885					{
11886						inlineScripts.push(item);
11887					}
11888				});
11889		}
11890
11891		var promise = new Promise(function(resolve, reject) {
11892			var css = BX.prop.getArray(assets, "css", []);
11893			BX.load(css, function(){
11894				BX.loadScript(
11895					BX.prop.getArray(assets, "js", []),
11896					resolve
11897				);
11898			});
11899		});
11900
11901		promise.then(function(){
11902			var stringAsset = inlineScripts.join('\n');
11903			BX.html(document.head, stringAsset, { useAdjacentHTML: true }).then(function(){
11904				assetsLoaded.fulfill(response);
11905			});
11906		});
11907
11908		return assetsLoaded;
11909	});
11910};
11911
11912/**
11913 *
11914 * @param {string} action
11915 * @param {Object} config
11916 * @param {?string|?Object} [config.analyticsLabel]
11917 * @param {?Object} [config.analytics]
11918 * @param {string} [config.analytics.event]
11919 * @param {string} [config.analytics.tool]
11920 * @param {string} [config.analytics.category]
11921 * @param {?string} [config.analytics.c_section]
11922 * @param {?string} [config.analytics.c_sub_section]
11923 * @param {?string} [config.analytics.c_element]
11924 * @param {?string} [config.analytics.type]
11925 * @param {?string} [config.analytics.p1]
11926 * @param {?string} [config.analytics.p2]
11927 * @param {?string} [config.analytics.p3]
11928 * @param {?string} [config.analytics.p4]
11929 * @param {?string} [config.analytics.p5]
11930 * @param {?('success' | 'error' | 'attempt' | 'cancel')} [config.analytics.status]
11931 * @param {string} [config.method='POST']
11932 * @param {Object} [config.data]
11933 * @param {?Object} [config.getParameters]
11934 * @param {?Object} [config.headers]
11935 * @param {?Object} [config.timeout]
11936 * @param {Object} [config.navigation]
11937 * @param {number} [config.navigation.page]
11938 */
11939BX.ajax.runAction = function(action, config)
11940{
11941	config = prepareAjaxConfig(config);
11942	var getParameters = prepareAjaxGetParameters(config);
11943	getParameters.action = action;
11944
11945	var url = '/bitrix/services/main/ajax.php?' + BX.ajax.prepareData(getParameters);
11946	return buildAjaxPromiseToRestoreCsrf({
11947		method: config.method,
11948		dataType: 'json',
11949		url: url,
11950		data: config.data,
11951		timeout: config.timeout,
11952		preparePost: config.preparePost,
11953		headers: config.headers,
11954		onrequeststart: config.onrequeststart,
11955		onprogress: config.onprogress,
11956		onprogressupload: config.onprogressupload
11957	});
11958};
11959
11960/**
11961 *
11962 * @param {string} component
11963 * @param {string} action
11964 * @param {Object} config
11965 * @param {?string|?Object} [config.analyticsLabel]
11966 * @param {?Object} [config.analytics]
11967 * @param {string} [config.analytics.event]
11968 * @param {string} [config.analytics.tool]
11969 * @param {string} [config.analytics.category]
11970 * @param {?string} [config.analytics.c_section]
11971 * @param {?string} [config.analytics.c_sub_section]
11972 * @param {?string} [config.analytics.c_element]
11973 * @param {?string} [config.analytics.type]
11974 * @param {?string} [config.analytics.p1]
11975 * @param {?string} [config.analytics.p2]
11976 * @param {?string} [config.analytics.p3]
11977 * @param {?string} [config.analytics.p4]
11978 * @param {?string} [config.analytics.p5]
11979 * @param {?string} [config.signedParameters]
11980 * @param {string} [config.method='POST']
11981 * @param {string} [config.mode='ajax'] Ajax or class.
11982 * @param {Object} [config.data]
11983 * @param {?Object} [config.getParameters]
11984 * @param {?array} [config.headers]
11985 * @param {?number} [config.timeout]
11986 * @param {Object} [config.navigation]
11987 */
11988BX.ajax.runComponentAction = function (component, action, config)
11989{
11990	config = prepareAjaxConfig(config);
11991	config.mode = config.mode || 'ajax';
11992
11993	var getParameters = prepareAjaxGetParameters(config);
11994	getParameters.c = component;
11995	getParameters.action = action;
11996
11997	var url = '/bitrix/services/main/ajax.php?' + BX.ajax.prepareData(getParameters);
11998
11999	return buildAjaxPromiseToRestoreCsrf({
12000		method: config.method,
12001		dataType: 'json',
12002		url: url,
12003		data: config.data,
12004		timeout: config.timeout,
12005		preparePost: config.preparePost,
12006		headers: config.headers,
12007		onrequeststart: (config.onrequeststart ? config.onrequeststart : null),
12008		onprogress: config.onprogress,
12009		onprogressupload: config.onprogressupload
12010	});
12011};
12012
12013/*
12014arObs = [{
12015	url: url,
12016	type: html|script|json|css,
12017	callback: function
12018}]
12019*/
12020BX.ajax.load = function(arObs, callback)
12021{
12022	if (!BX.type.isArray(arObs))
12023		arObs = [arObs];
12024
12025	var cnt = 0;
12026
12027	if (!BX.type.isFunction(callback))
12028		callback = BX.DoNothing;
12029
12030	var handler = function(data)
12031		{
12032			if (BX.type.isFunction(this.callback))
12033				this.callback(data);
12034
12035			if (++cnt >= len)
12036				callback();
12037		};
12038
12039	for (var i = 0, len = arObs.length; i<len; i++)
12040	{
12041		switch(arObs[i].type.toUpperCase())
12042		{
12043			case 'SCRIPT':
12044				BX.loadScript([arObs[i].url], BX.proxy(handler, arObs[i]));
12045			break;
12046			case 'CSS':
12047				BX.loadCSS([arObs[i].url]);
12048
12049				if (++cnt >= len)
12050					callback();
12051			break;
12052			case 'JSON':
12053				BX.ajax.loadJSON(arObs[i].url, BX.proxy(handler, arObs[i]));
12054			break;
12055
12056			default:
12057				BX.ajax.get(arObs[i].url, '', BX.proxy(handler, arObs[i]));
12058			break;
12059		}
12060	}
12061};
12062
12063/* ajax form sending */
12064BX.ajax.submit = function(obForm, callback)
12065{
12066	if (!obForm.target)
12067	{
12068		if (null == obForm.BXFormTarget)
12069		{
12070			var frame_name = 'formTarget_' + Math.random();
12071			obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', {
12072				props: {
12073					name: frame_name,
12074					id: frame_name,
12075					src: 'javascript:void(0)'
12076				},
12077				style: {
12078					display: 'none'
12079				}
12080			}));
12081		}
12082
12083		obForm.target = obForm.BXFormTarget.name;
12084	}
12085
12086	obForm.BXFormCallback = callback;
12087	BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm));
12088
12089	BX.submit(obForm);
12090
12091	return false;
12092};
12093
12094BX.ajax.submitComponentForm = function(obForm, container, bWait)
12095{
12096	if (!obForm.target)
12097	{
12098		if (null == obForm.BXFormTarget)
12099		{
12100			var frame_name = 'formTarget_' + Math.random();
12101			obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', {
12102				props: {
12103					name: frame_name,
12104					id: frame_name,
12105					src: 'javascript:void(0)'
12106				},
12107				style: {
12108					display: 'none'
12109				}
12110			}));
12111		}
12112
12113		obForm.target = obForm.BXFormTarget.name;
12114	}
12115
12116	if (!!bWait)
12117		var w = BX.showWait(container);
12118
12119	obForm.BXFormCallback = function(d) {
12120		if (!!bWait)
12121			BX.closeWait(w);
12122
12123		var callOnload = function(){
12124			if(!!window.bxcompajaxframeonload)
12125			{
12126				setTimeout(function(){window.bxcompajaxframeonload();window.bxcompajaxframeonload=null;}, 10);
12127			}
12128		};
12129
12130		BX(container).innerHTML = d;
12131		BX.onCustomEvent('onAjaxSuccess', [null,null,callOnload]);
12132	};
12133
12134	BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm));
12135
12136	return true;
12137};
12138
12139// func will be executed in form context
12140BX.ajax._submit_callback = function()
12141{
12142	//opera and IE8 triggers onload event even on empty iframe
12143	try
12144	{
12145		if(this.BXFormTarget.contentWindow.location.href.indexOf('http') != 0)
12146			return;
12147	} catch (e) {
12148		return;
12149	}
12150
12151	if (this.BXFormCallback)
12152		this.BXFormCallback.apply(this, [this.BXFormTarget.contentWindow.document.body.innerHTML]);
12153
12154	BX.unbindAll(this.BXFormTarget);
12155};
12156
12157BX.ajax.prepareForm = function(obForm, data)
12158{
12159	data = (!!data ? data : {});
12160	var i, ii, el,
12161		_data = [],
12162		n = obForm.elements.length,
12163		files = 0, length = 0;
12164	if(!!obForm)
12165	{
12166		for (i = 0; i < n; i++)
12167		{
12168			el = obForm.elements[i];
12169			if (el.disabled)
12170				continue;
12171
12172			if(!el.type)
12173				continue;
12174
12175			switch(el.type.toLowerCase())
12176			{
12177				case 'text':
12178				case 'textarea':
12179				case 'password':
12180				case 'number':
12181				case 'hidden':
12182				case 'select-one':
12183					_data.push({name: el.name, value: el.value});
12184					length += (el.name.length + el.value.length);
12185					break;
12186				case 'file':
12187					if (!!el.files)
12188					{
12189						for (ii = 0; ii < el.files.length; ii++)
12190						{
12191							files++;
12192							_data.push({name: el.name, value: el.files[ii], file : true});
12193							length += el.files[ii].size;
12194						}
12195					}
12196					break;
12197				case 'radio':
12198				case 'checkbox':
12199					if(el.checked)
12200					{
12201						_data.push({name: el.name, value: el.value});
12202						length += (el.name.length + el.value.length);
12203					}
12204					break;
12205				case 'select-multiple':
12206					for (var j = 0; j < el.options.length; j++)
12207					{
12208						if (el.options[j].selected)
12209						{
12210							_data.push({name : el.name, value : el.options[j].value});
12211							length += (el.name.length + el.options[j].length);
12212						}
12213					}
12214					break;
12215				default:
12216					break;
12217			}
12218		}
12219
12220		i = 0; length = 0;
12221		var current = data, name, rest, pp, tmpKey;
12222
12223		while(i < _data.length)
12224		{
12225			var p = _data[i].name.indexOf('[');
12226			if (tmpKey)
12227			{
12228				current[_data[i].name] = {};
12229				current[_data[i].name][tmpKey.replace(/\[|\]/gi, '')] = _data[i].value;
12230				current = data;
12231				tmpKey = null;
12232				i++;
12233			}
12234			else if (p == -1)
12235			{
12236				current[_data[i].name] = _data[i].value;
12237				current = data;
12238				i++;
12239			}
12240			else
12241			{
12242				name = _data[i].name.substring(0, p);
12243				rest = _data[i].name.substring(p+1);
12244				pp = rest.indexOf(']');
12245
12246				if(pp == -1)
12247				{
12248					if (!current[name])
12249						current[name] = [];
12250					current = data;
12251					i++;
12252				}
12253				else if(pp == 0)
12254				{
12255					if (!current[name])
12256						current[name] = [];
12257					//No index specified - so take the next integer
12258					current = current[name];
12259					_data[i].name = '' + current.length;
12260					if (rest.substring(pp+1).indexOf('[') === 0)
12261						tmpKey = rest.substring(0, pp) + rest.substring(pp+1);
12262				}
12263				else
12264				{
12265					if (!current[name])
12266						current[name] = {};
12267					//Now index name becomes and name and we go deeper into the array
12268					current = current[name];
12269					_data[i].name = rest.substring(0, pp) + rest.substring(pp+1);
12270				}
12271			}
12272		}
12273	}
12274	return {data : data, filesCount : files, roughSize : length};
12275};
12276BX.ajax.submitAjax = function(obForm, config)
12277{
12278	config = (config !== null && typeof config == "object" ? config : {});
12279	config.url = (config["url"] || obForm.getAttribute("action"));
12280
12281	var additionalData = (config["data"] || {});
12282	config.data = BX.ajax.prepareForm(obForm).data;
12283	for (var ii in additionalData)
12284	{
12285		if (additionalData.hasOwnProperty(ii))
12286		{
12287			config.data[ii] = additionalData[ii];
12288		}
12289	}
12290
12291	if (!window["FormData"])
12292	{
12293		BX.ajax(config);
12294	}
12295	else
12296	{
12297		var isFile = function(item)
12298		{
12299			var res = Object.prototype.toString.call(item);
12300			return (res == '[object File]' || res == '[object Blob]');
12301		},
12302		appendToForm = function(fd, key, val)
12303		{
12304			if (!!val && typeof val == "object" && !isFile(val))
12305			{
12306				for (var ii in val)
12307				{
12308					if (val.hasOwnProperty(ii))
12309					{
12310						appendToForm(fd, (key == '' ? ii : key + '[' + ii + ']'), val[ii]);
12311					}
12312				}
12313			}
12314			else
12315				fd.append(key, (!!val ? val : ''));
12316		},
12317		prepareData = function(arData)
12318		{
12319			var data = {};
12320			if (null != arData)
12321			{
12322				if(typeof arData == 'object')
12323				{
12324					for(var i in arData)
12325					{
12326						if (arData.hasOwnProperty(i))
12327						{
12328							var name = BX.util.urlencode(i);
12329							if(typeof arData[i] == 'object' && arData[i]["file"] !== true)
12330								data[name] = prepareData(arData[i]);
12331							else if (arData[i]["file"] === true)
12332								data[name] = arData[i]["value"];
12333							else
12334								data[name] = BX.util.urlencode(arData[i]);
12335						}
12336					}
12337				}
12338				else
12339					data = BX.util.urlencode(arData);
12340			}
12341			return data;
12342		},
12343		fd = new window.FormData();
12344
12345		if (config.method !== 'POST')
12346		{
12347			config.data = BX.ajax.prepareData(config.data);
12348			if (config.data)
12349			{
12350				config.url += (config.url.indexOf('?') !== -1 ? "&" : "?") + config.data;
12351				config.data = '';
12352			}
12353		}
12354		else
12355		{
12356			if (config.preparePost === true)
12357				config.data = prepareData(config.data);
12358			appendToForm(fd, '', config.data);
12359			config.data = fd;
12360		}
12361
12362		config.preparePost = false;
12363		config.start = false;
12364
12365		var xhr = BX.ajax(config);
12366		if (!!config["onprogress"])
12367			xhr.upload.addEventListener(
12368				'progress',
12369				function(e){
12370					var percent = null;
12371					if(e.lengthComputable && (e.total || e["totalSize"])) {
12372						percent = e.loaded * 100 / (e.total || e["totalSize"]);
12373					}
12374					config["onprogress"](e, percent);
12375				}
12376			);
12377		xhr.send(fd);
12378	}
12379};
12380
12381BX.ajax.UpdatePageData = function (arData)
12382{
12383	if (arData.TITLE)
12384		BX.ajax.UpdatePageTitle(arData.TITLE);
12385	if (arData.WINDOW_TITLE || arData.TITLE)
12386		BX.ajax.UpdateWindowTitle(arData.WINDOW_TITLE || arData.TITLE);
12387	if (arData.NAV_CHAIN)
12388		BX.ajax.UpdatePageNavChain(arData.NAV_CHAIN);
12389	if (arData.CSS && arData.CSS.length > 0)
12390		BX.loadCSS(arData.CSS);
12391	if (arData.SCRIPTS && arData.SCRIPTS.length > 0)
12392	{
12393		var f = function(result,config,cb){
12394
12395			if(!!config && BX.type.isArray(config.scripts))
12396			{
12397				for(var i=0,l=arData.SCRIPTS.length;i<l;i++)
12398				{
12399					config.scripts.push({isInternal:false,JS:arData.SCRIPTS[i]});
12400				}
12401			}
12402			else
12403			{
12404				BX.loadScript(arData.SCRIPTS,cb);
12405			}
12406
12407			BX.removeCustomEvent('onAjaxSuccess',f);
12408		};
12409		BX.addCustomEvent('onAjaxSuccess',f);
12410	}
12411	else
12412	{
12413		var f1 = function(result,config,cb){
12414			if(BX.type.isFunction(cb))
12415			{
12416				cb();
12417			}
12418			BX.removeCustomEvent('onAjaxSuccess',f1);
12419		};
12420		BX.addCustomEvent('onAjaxSuccess', f1);
12421	}
12422};
12423
12424BX.ajax.UpdatePageTitle = function(title)
12425{
12426	var obTitle = BX('pagetitle');
12427	if (obTitle)
12428	{
12429		BX.remove(obTitle.firstChild);
12430		if (!obTitle.firstChild)
12431			obTitle.appendChild(document.createTextNode(title));
12432		else
12433			obTitle.insertBefore(document.createTextNode(title), obTitle.firstChild);
12434	}
12435};
12436
12437BX.ajax.UpdateWindowTitle = function(title)
12438{
12439	document.title = title;
12440};
12441
12442BX.ajax.UpdatePageNavChain = function(nav_chain)
12443{
12444	var obNavChain = BX('navigation');
12445	if (obNavChain)
12446	{
12447		obNavChain.innerHTML = nav_chain;
12448	}
12449};
12450
12451/* user options handling */
12452BX.userOptions = {
12453	options: null,
12454	bSend: false,
12455	delay: 5000,
12456	path: '/bitrix/admin/user_options.php?'
12457};
12458
12459BX.userOptions.setAjaxPath = function(url)
12460{
12461	// eslint-disable-next-line no-console
12462	console.warn('BX.userOptions.setAjaxPath is deprecated. There is no way to change ajax path.');
12463};
12464BX.userOptions.save = function(category, name, valueName, value, common)
12465{
12466	if (BX.userOptions.options === null)
12467	{
12468		BX.userOptions.options = {};
12469	}
12470
12471	common = Boolean(common);
12472	BX.userOptions.options[`${category}.${name}.${valueName}`] = [category, name, valueName, value, common];
12473
12474	const stringPackedValue = BX.userOptions.__get();
12475	if (stringPackedValue)
12476	{
12477		document.cookie = `${BX.message('COOKIE_PREFIX')}_LAST_SETTINGS=${encodeURIComponent(stringPackedValue)}&sessid=${BX.bitrix_sessid()}; expires=Thu, 31 Dec ${(new Date()).getFullYear() + 1} 23:59:59 GMT; path=/;`;
12478	}
12479
12480	if (!BX.userOptions.bSend)
12481	{
12482		BX.userOptions.bSend = true;
12483		setTimeout(() => {
12484			BX.userOptions.send(null);
12485		}, BX.userOptions.delay);
12486	}
12487};
12488
12489BX.userOptions.send = function(callback)
12490{
12491	const values = BX.userOptions.__get_values({ backwardCompatibility: true});
12492
12493	BX.userOptions.options = null;
12494	BX.userOptions.bSend = false;
12495
12496	if (values)
12497	{
12498		document.cookie = `${BX.message('COOKIE_PREFIX')}_LAST_SETTINGS=; path=/;`;
12499
12500		BX.ajax.runAction(
12501			'main.userOption.saveOptions',
12502			{
12503				json: {
12504					newValues: values,
12505				},
12506			},
12507		).then((response) => {
12508			if (BX.type.isFunction(callback))
12509			{
12510				callback(response);
12511			}
12512		});
12513	}
12514};
12515
12516BX.userOptions.del = function(category, name, common, callback)
12517{
12518	BX.ajax.runAction(
12519		'main.userOption.deleteOption',
12520		{
12521			json: {
12522				category,
12523				name,
12524				common,
12525			},
12526		},
12527	).then((response) => {
12528		if (BX.type.isFunction(callback))
12529		{
12530			callback(response);
12531		}
12532	});
12533};
12534
12535BX.userOptions.__get_values = function({ backwardCompatibility })
12536{
12537	if (!BX.userOptions || !BX.Type.isPlainObject(BX.userOptions.options))
12538	{
12539		return null;
12540	}
12541
12542	const CATEGORY = 0;
12543	const NAME = 1;
12544	const VALUE_NAME = 2;
12545	const VALUE = 3;
12546	const IS_DEFAULT = 4;
12547
12548	const packedValues = { p: [] };
12549	let currentIndex = -1;
12550	let previousOptionIdentifier = '';
12551
12552	Object.entries(BX.userOptions.options).forEach(([key, userOption]) => {
12553		const category = userOption[CATEGORY];
12554		const name = userOption[NAME];
12555		const currentOptionIdentifier = `${category}.${name}`;
12556
12557		if (previousOptionIdentifier !== currentOptionIdentifier)
12558		{
12559			currentIndex++;
12560			packedValues.p.push({
12561				c: category,
12562				n: name,
12563				v: {},
12564			});
12565			if (userOption[IS_DEFAULT] === true)
12566			{
12567				packedValues.p[currentIndex].d = 'Y';
12568			}
12569			previousOptionIdentifier = currentOptionIdentifier;
12570		}
12571
12572		if (userOption[VALUE_NAME] === null)
12573		{
12574			packedValues.p[currentIndex].v = userOption[VALUE];
12575		}
12576		else
12577		{
12578			let data = userOption[VALUE];
12579			if (backwardCompatibility && Array.isArray(userOption[VALUE]))
12580			{
12581				data = userOption[VALUE].join(',');
12582			}
12583			packedValues.p[currentIndex].v[userOption[VALUE_NAME]] = data;
12584		}
12585	});
12586
12587	return packedValues.p.length > 0 ? packedValues.p : null;
12588};
12589
12590/**
12591 * @deprecated Use instead BX.userOptions.__get_values.
12592 * */
12593BX.userOptions.__get = function()
12594{
12595	if (!BX.userOptions.options) return '';
12596
12597	var sParam = '', n = -1, prevParam = '', aOpt, i;
12598
12599	for (i in BX.userOptions.options)
12600	{
12601		if(BX.userOptions.options.hasOwnProperty(i))
12602		{
12603			aOpt = BX.userOptions.options[i];
12604
12605			if (prevParam != aOpt[0]+'.'+aOpt[1])
12606			{
12607				n++;
12608				sParam += '&p['+n+'][c]='+BX.util.urlencode(aOpt[0]);
12609				sParam += '&p['+n+'][n]='+BX.util.urlencode(aOpt[1]);
12610				if (aOpt[4] == true)
12611					sParam += '&p['+n+'][d]=Y';
12612				prevParam = aOpt[0]+'.'+aOpt[1];
12613			}
12614
12615			var valueName = aOpt[2];
12616			var value = aOpt[3];
12617
12618			if (valueName === null)
12619			{
12620				sParam += '&p['+n+'][v]='+BX.util.urlencode(value);
12621			}
12622			else
12623			{
12624				sParam += '&p['+n+'][v]['+BX.util.urlencode(valueName)+']='+BX.util.urlencode(value);
12625			}
12626		}
12627	}
12628
12629	return sParam.substr(1);
12630};
12631
12632BX.ajax.history = {
12633	expected_hash: '',
12634
12635	obParams: null,
12636
12637	obFrame: null,
12638	obImage: null,
12639
12640	obTimer: null,
12641
12642	bInited: false,
12643	bHashCollision: false,
12644	bPushState: !!(history.pushState && BX.type.isFunction(history.pushState)),
12645
12646	startState: null,
12647
12648	init: function(obParams)
12649	{
12650		if (BX.ajax.history.bInited)
12651			return;
12652
12653		this.obParams = obParams;
12654		var obCurrentState = this.obParams.getState();
12655
12656		if (BX.ajax.history.bPushState)
12657		{
12658			BX.ajax.history.expected_hash = window.location.pathname;
12659			if (window.location.search)
12660				BX.ajax.history.expected_hash += window.location.search;
12661
12662			BX.ajax.history.put(obCurrentState, BX.ajax.history.expected_hash, '', true);
12663			// due to some strange thing, chrome calls popstate event on page start. so we should delay it
12664			setTimeout(function(){BX.bind(window, 'popstate', BX.ajax.history.__hashListener);}, 500);
12665		}
12666		else
12667		{
12668			BX.ajax.history.expected_hash = window.location.hash;
12669
12670			if (!BX.ajax.history.expected_hash || BX.ajax.history.expected_hash == '#')
12671				BX.ajax.history.expected_hash = '__bx_no_hash__';
12672
12673			jsAjaxHistoryContainer.put(BX.ajax.history.expected_hash, obCurrentState);
12674			BX.ajax.history.obTimer = setTimeout(BX.ajax.history.__hashListener, 500);
12675
12676			if (BX.browser.IsIE())
12677			{
12678				BX.ajax.history.obFrame = document.createElement('IFRAME');
12679				BX.hide_object(BX.ajax.history.obFrame);
12680
12681				document.body.appendChild(BX.ajax.history.obFrame);
12682
12683				BX.ajax.history.obFrame.contentWindow.document.open();
12684				BX.ajax.history.obFrame.contentWindow.document.write(BX.ajax.history.expected_hash);
12685				BX.ajax.history.obFrame.contentWindow.document.close();
12686			}
12687			else if (BX.browser.IsOpera())
12688			{
12689				BX.ajax.history.obImage = document.createElement('IMG');
12690				BX.hide_object(BX.ajax.history.obImage);
12691
12692				document.body.appendChild(BX.ajax.history.obImage);
12693
12694				BX.ajax.history.obImage.setAttribute('src', 'javascript:location.href = \'javascript:BX.ajax.history.__hashListener();\';');
12695			}
12696		}
12697
12698		BX.ajax.history.bInited = true;
12699	},
12700
12701	__hashListener: function(e)
12702	{
12703		e = e || window.event || {state:false};
12704
12705		if (BX.ajax.history.bPushState)
12706		{
12707			BX.ajax.history.obParams.setState(e.state||BX.ajax.history.startState);
12708		}
12709		else
12710		{
12711			if (BX.ajax.history.obTimer)
12712			{
12713				window.clearTimeout(BX.ajax.history.obTimer);
12714				BX.ajax.history.obTimer = null;
12715			}
12716
12717			var current_hash;
12718			if (null != BX.ajax.history.obFrame)
12719				current_hash = BX.ajax.history.obFrame.contentWindow.document.body.innerText;
12720			else
12721				current_hash = window.location.hash;
12722
12723			if (!current_hash || current_hash == '#')
12724				current_hash = '__bx_no_hash__';
12725
12726			if (current_hash.indexOf('#') == 0)
12727				current_hash = current_hash.substring(1);
12728
12729			if (current_hash != BX.ajax.history.expected_hash)
12730			{
12731				var state = jsAjaxHistoryContainer.get(current_hash);
12732				if (state)
12733				{
12734					BX.ajax.history.obParams.setState(state);
12735
12736					BX.ajax.history.expected_hash = current_hash;
12737					if (null != BX.ajax.history.obFrame)
12738					{
12739						var __hash = current_hash == '__bx_no_hash__' ? '' : current_hash;
12740						if (window.location.hash != __hash && window.location.hash != '#' + __hash)
12741							window.location.hash = __hash;
12742					}
12743				}
12744			}
12745
12746			BX.ajax.history.obTimer = setTimeout(BX.ajax.history.__hashListener, 500);
12747		}
12748	},
12749
12750	put: function(state, new_hash, new_hash1, bStartState)
12751	{
12752		if (this.bPushState)
12753		{
12754			if(!bStartState)
12755			{
12756				history.pushState(state, '', new_hash);
12757			}
12758			else
12759			{
12760				BX.ajax.history.startState = state;
12761			}
12762		}
12763		else
12764		{
12765			if (typeof new_hash1 != 'undefined')
12766				new_hash = new_hash1;
12767			else
12768				new_hash = 'view' + new_hash;
12769
12770			jsAjaxHistoryContainer.put(new_hash, state);
12771			BX.ajax.history.expected_hash = new_hash;
12772
12773			window.location.hash = BX.util.urlencode(new_hash);
12774
12775			if (null != BX.ajax.history.obFrame)
12776			{
12777				BX.ajax.history.obFrame.contentWindow.document.open();
12778				BX.ajax.history.obFrame.contentWindow.document.write(new_hash);
12779				BX.ajax.history.obFrame.contentWindow.document.close();
12780			}
12781		}
12782	},
12783
12784	checkRedirectStart: function(param_name, param_value)
12785	{
12786		var current_hash = window.location.hash;
12787		if (current_hash.substring(0, 1) == '#') current_hash = current_hash.substring(1);
12788
12789		var test = current_hash.substring(0, 5);
12790		if (test == 'view/' || test == 'view%')
12791		{
12792			BX.ajax.history.bHashCollision = true;
12793			document.write('<' + 'div id="__ajax_hash_collision_' + param_value + '" style="display: none;">');
12794		}
12795	},
12796
12797	checkRedirectFinish: function(param_name, param_value)
12798	{
12799		document.write('</div>');
12800
12801		var current_hash = window.location.hash;
12802		if (current_hash.substring(0, 1) == '#') current_hash = current_hash.substring(1);
12803
12804		BX.ready(function ()
12805		{
12806			var test = current_hash.substring(0, 5);
12807			if (test == 'view/' || test == 'view%')
12808			{
12809				var obColNode = BX('__ajax_hash_collision_' + param_value);
12810				var obNode = obColNode.firstChild;
12811				BX.cleanNode(obNode);
12812				obColNode.style.display = 'block';
12813
12814				// IE, Opera and Chrome automatically modifies hash with urlencode, but FF doesn't ;-(
12815				if (test != 'view%')
12816					current_hash = BX.util.urlencode(current_hash);
12817
12818				current_hash += (current_hash.indexOf('%3F') == -1 ? '%3F' : '%26') + param_name + '=' + param_value;
12819
12820				var url = '/bitrix/tools/ajax_redirector.php?hash=' + current_hash;
12821
12822				BX.ajax.insertToNode(url, obNode);
12823			}
12824		});
12825	}
12826};
12827
12828BX.ajax.component = function(node)
12829{
12830	this.node = node;
12831};
12832
12833BX.ajax.component.prototype.getState = function()
12834{
12835	var state = {
12836		'node': this.node,
12837		'title': window.document.title,
12838		'data': BX(this.node).innerHTML
12839	};
12840
12841	var obNavChain = BX('navigation');
12842	if (null != obNavChain)
12843		state.nav_chain = obNavChain.innerHTML;
12844
12845	BX.onCustomEvent(BX(state.node), "onComponentAjaxHistoryGetState", [state]);
12846
12847	return state;
12848};
12849
12850BX.ajax.component.prototype.setState = function(state)
12851{
12852	BX(state.node).innerHTML = state.data;
12853	BX.ajax.UpdatePageTitle(state.title);
12854
12855	if (state.nav_chain)
12856	{
12857		BX.ajax.UpdatePageNavChain(state.nav_chain);
12858	}
12859
12860	BX.onCustomEvent(BX(state.node), "onComponentAjaxHistorySetState", [state]);
12861};
12862
12863var jsAjaxHistoryContainer = {
12864	arHistory: {},
12865
12866	put: function(hash, state)
12867	{
12868		this.arHistory[hash] = state;
12869	},
12870
12871	get: function(hash)
12872	{
12873		return this.arHistory[hash];
12874	}
12875};
12876
12877
12878BX.ajax.FormData = function()
12879{
12880	this.elements = [];
12881	this.files = [];
12882	this.features = {};
12883	this.isSupported();
12884	this.log('BX FormData init');
12885};
12886
12887BX.ajax.FormData.isSupported = function()
12888{
12889	var f = new BX.ajax.FormData();
12890	var result = f.features.supported;
12891	f = null;
12892	return result;
12893};
12894
12895BX.ajax.FormData.prototype.log = function(o)
12896{
12897	if (false) {
12898		try {
12899			if (BX.browser.IsIE()) o = JSON.stringify(o);
12900			console.log(o);
12901		} catch(e) {}
12902	}
12903};
12904
12905BX.ajax.FormData.prototype.isSupported = function()
12906{
12907	var f = {};
12908	f.fileReader = (window.FileReader && window.FileReader.prototype.readAsBinaryString);
12909	f.readFormData = f.sendFormData = !!(window.FormData);
12910	f.supported = !!(f.readFormData && f.sendFormData);
12911	this.features = f;
12912	this.log('features:');
12913	this.log(f);
12914
12915	return f.supported;
12916};
12917
12918BX.ajax.FormData.prototype.append = function(name, value)
12919{
12920	if (typeof(value) === 'object') { // seems to be files element
12921		this.files.push({'name': name, 'value':value});
12922	} else {
12923		this.elements.push({'name': name, 'value':value});
12924	}
12925};
12926
12927BX.ajax.FormData.prototype.send = function(url, callbackOk, callbackProgress, callbackError)
12928{
12929	this.log('FD send');
12930	this.xhr = BX.ajax({
12931			'method': 'POST',
12932			'dataType': 'html',
12933			'url': url,
12934			'onsuccess': callbackOk,
12935			'onfailure': callbackError,
12936			'start': false,
12937			'preparePost':false
12938		});
12939
12940	if (callbackProgress)
12941	{
12942		this.xhr.upload.addEventListener(
12943			'progress',
12944			function(e) {
12945				if (e.lengthComputable)
12946					callbackProgress(e.loaded / (e.total || e.totalSize));
12947			},
12948			false
12949		);
12950	}
12951
12952	if (this.features.readFormData && this.features.sendFormData)
12953	{
12954		var fd = new FormData();
12955		this.log('use browser formdata');
12956		for (var i in this.elements)
12957		{
12958			if(this.elements.hasOwnProperty(i))
12959				fd.append(this.elements[i].name,this.elements[i].value);
12960		}
12961		for (i in this.files)
12962		{
12963			if(this.files.hasOwnProperty(i))
12964				fd.append(this.files[i].name, this.files[i].value);
12965		}
12966		this.xhr.send(fd);
12967	}
12968
12969	return this.xhr;
12970};
12971
12972BX.addCustomEvent('onAjaxFailure', BX.debug);
12973})(window);
12974
12975
12976
12977(function (exports,main_core) {
12978	'use strict';
12979
12980	var LazyLoad = {
12981		observer: null,
12982		images: {},
12983		imageStatus: {
12984			hidden: -2,
12985			error: -1,
12986			"undefined": 0,
12987			inited: 1,
12988			loaded: 2
12989		},
12990		imageTypes: {
12991			image: 1,
12992			background: 2
12993		},
12994		initObserver: function initObserver() {
12995			this.observer = new IntersectionObserver(this.onIntersection.bind(this), {
12996				rootMargin: '20% 0% 20% 0%',
12997				threshold: 0.10
12998			});
12999		},
13000		onIntersection: function onIntersection(entries) {
13001			entries.forEach(function (entry) {
13002				if (entry.isIntersecting) {
13003					this.showImage(entry.target);
13004				}
13005			}.bind(this));
13006		},
13007		registerImage: function registerImage(id, isImageVisibleCallback, options) {
13008			if (this.observer === null) {
13009				this.initObserver();
13010			}
13011
13012			options = options || {};
13013
13014			if (!main_core.Type.isStringFilled(id)) {
13015				return;
13016			}
13017
13018			if (main_core.Type.isObject(this.images[id])) {
13019				return;
13020			}
13021
13022			var element = document.getElementById(id);
13023
13024			if (!main_core.Type.isDomNode(element)) {
13025				return;
13026			}
13027
13028			this.observer.observe(element);
13029			this.images[id] = {
13030				id: id,
13031				node: null,
13032				src: null,
13033				dataSrcName: options.dataSrcName || 'src',
13034				type: null,
13035				func: main_core.Type.isFunction(isImageVisibleCallback) ? isImageVisibleCallback : null,
13036				status: this.imageStatus.undefined
13037			};
13038		},
13039		registerImages: function registerImages(ids, isImageVisibleCallback, options) {
13040			if (main_core.Type.isArray(ids)) {
13041				for (var i = 0, length = ids.length; i < length; i++) {
13042					this.registerImage(ids[i], isImageVisibleCallback, options);
13043				}
13044			}
13045		},
13046		showImage: function showImage(imageNode) {
13047			var imageNodeId = imageNode.id;
13048
13049			if (!main_core.Type.isStringFilled(imageNodeId)) {
13050				return;
13051			}
13052
13053			var image = this.images[imageNodeId];
13054
13055			if (!main_core.Type.isPlainObject(image)) {
13056				return;
13057			}
13058
13059			if (image.status == this.imageStatus.undefined) {
13060				this.initImage(image);
13061			}
13062
13063			if (image.status !== this.imageStatus.inited) {
13064				return;
13065			}
13066
13067			if (!image.node || !image.node.parentNode) {
13068				image.node = null;
13069				image.status = this.imageStatus.error;
13070				return;
13071			}
13072
13073			if (image.type == this.imageTypes.image) {
13074				image.node.src = image.src;
13075			} else {
13076				image.node.style.backgroundImage = "url('" + image.src + "')";
13077			}
13078
13079			image.node.dataset[image.dataSrcName] = "";
13080			image.status = this.imageStatus.loaded;
13081		},
13082		showImages: function showImages(checkOwnVisibility) {
13083			checkOwnVisibility = checkOwnVisibility !== false;
13084
13085			for (var id in this.images) {
13086				if (!this.images.hasOwnProperty(id)) {
13087					continue;
13088				}
13089
13090				var image = this.images[id];
13091
13092				if (image.status == this.imageStatus.undefined) {
13093					this.initImage(image);
13094				}
13095
13096				if (image.status !== this.imageStatus.inited) {
13097					continue;
13098				}
13099
13100				if (!image.node || !image.node.parentNode) {
13101					image.node = null;
13102					image.status = this.imageStatus.error;
13103					continue;
13104				}
13105
13106				var isImageVisible = true;
13107
13108				if (checkOwnVisibility && main_core.Type.isFunction(image.func)) {
13109					isImageVisible = image.func(image);
13110				}
13111
13112				if (isImageVisible === true && this.isElementVisibleOnScreen(image.node)) {
13113					if (image.type == this.imageTypes.image) {
13114						image.node.src = image.src;
13115					} else {
13116						image.node.style.backgroundImage = "url('" + image.src + "')";
13117					}
13118
13119					image.node.dataset[image.dataSrcName] = "";
13120					image.status = this.imageStatus.loaded;
13121				}
13122			}
13123		},
13124		initImage: function initImage(image) {
13125			image.status = this.imageStatus.error;
13126			var node = document.getElementById(image.id);
13127
13128			if (!main_core.Type.isDomNode(node)) {
13129				return;
13130			}
13131
13132			var src = node.dataset[image.dataSrcName];
13133
13134			if (main_core.Type.isStringFilled(src)) {
13135				image.node = node;
13136				image.src = src;
13137				image.status = this.imageStatus.inited;
13138				image.type = image.node.tagName.toLowerCase() == "img" ? this.imageTypes.image : this.imageTypes.background;
13139			}
13140		},
13141		isElementVisibleOnScreen: function isElementVisibleOnScreen(element) {
13142			var coords = this.getElementCoords(element);
13143			var windowTop = window.pageYOffset || document.documentElement.scrollTop;
13144			var windowBottom = windowTop + document.documentElement.clientHeight;
13145			coords.bottom = coords.top + element.offsetHeight;
13146			return coords.top > windowTop && coords.top < windowBottom || // topVisible
13147			coords.bottom < windowBottom && coords.bottom > windowTop // bottomVisible
13148			;
13149		},
13150		isElementVisibleOn2Screens: function isElementVisibleOn2Screens(element) {
13151			var windowHeight = document.documentElement.clientHeight;
13152			var windowTop = window.pageYOffset || document.documentElement.scrollTop;
13153			var windowBottom = windowTop + windowHeight;
13154			var coords = this.getElementCoords(element);
13155			coords.bottom = coords.top + element.offsetHeight;
13156			windowTop -= windowHeight;
13157			windowBottom += windowHeight;
13158			return coords.top > windowTop && coords.top < windowBottom || // topVisible
13159			coords.bottom < windowBottom && coords.bottom > windowTop // bottomVisible
13160			;
13161		},
13162		getElementCoords: function getElementCoords(element) {
13163			var box = element.getBoundingClientRect();
13164			return {
13165				originTop: box.top,
13166				originLeft: box.left,
13167				top: box.top + window.pageYOffset,
13168				left: box.left + window.pageXOffset
13169			};
13170		},
13171		onScroll: function onScroll() {},
13172		clearImages: function clearImages() {
13173			this.images = [];
13174		}
13175	};
13176
13177	exports.LazyLoad = LazyLoad;
13178
13179}((this.BX = this.BX || {}),BX));
13180
13181
13182
13183(function (exports) {
13184	'use strict';
13185
13186	var ParamBag = /*#__PURE__*/function () {
13187		function ParamBag() {
13188			var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
13189			babelHelpers.classCallCheck(this, ParamBag);
13190
13191			if (!!params && babelHelpers.typeof(params) === 'object') {
13192				this.params = new Map(Object.entries(params));
13193			} else {
13194				this.params = new Map();
13195			}
13196		}
13197
13198		babelHelpers.createClass(ParamBag, [{
13199			key: "getParam",
13200			value: function getParam(key) {
13201				var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
13202
13203				if (this.params.has(key)) {
13204					return this.params.get(key);
13205				}
13206
13207				return defaultValue;
13208			}
13209		}, {
13210			key: "setParam",
13211			value: function setParam(key, value) {
13212				this.params.set(key, value);
13213			}
13214		}, {
13215			key: "clear",
13216			value: function clear() {
13217				this.params.clear();
13218			}
13219		}], [{
13220			key: "create",
13221			value: function create() {
13222				var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
13223				return new ParamBag(params);
13224			}
13225		}]);
13226		return ParamBag;
13227	}();
13228
13229	exports.ParamBag = ParamBag;
13230
13231}((this.BX = this.BX || {})));
13232
13233
13234
13235(function() {
13236	BX.FixFontSize = function(params)
13237	{
13238		var widthNode, computedStyles, width;
13239
13240		this.node = null;
13241		this.prevWindowSize = 0;
13242		this.prevWrapperSize = 0;
13243		this.mainWrapper = null;
13244		this.textWrapper = null;
13245		this.objList = params.objList;
13246		this.minFontSizeList = [];
13247		this.minFontSize = 0;
13248
13249		if (params.onresize)
13250		{
13251			this.prevWindowSize = window.innerWidth || document.documentElement.clientWidth;
13252			BX.bind(window, 'resize', BX.throttle(this.onResize, 350, this));
13253		}
13254
13255		if (params.onAdaptiveResize)
13256		{
13257			widthNode = this.objList[0].scaleBy || this.objList[0].node;
13258			computedStyles = getComputedStyle(widthNode);
13259			this.prevWrapperSize = parseInt(computedStyles["width"]) - parseInt(computedStyles["paddingLeft"]) - parseInt(computedStyles["paddingRight"]);
13260			BX.bind(window, 'resize', BX.throttle(this.onAdaptiveResize, 350, this));
13261		}
13262
13263		this.createTestNodes();
13264		this.decrease();
13265	};
13266
13267	BX.FixFontSize.prototype =
13268		{
13269			createTestNodes: function()
13270			{
13271				this.textWrapper = BX.create('div',{
13272					style : {
13273						display : 'inline-block',
13274						whiteSpace : 'nowrap'
13275					}
13276				});
13277
13278				this.mainWrapper = BX.create('div',{
13279					style : {
13280						height : 0,
13281						overflow : 'hidden'
13282					},
13283					children : [this.textWrapper]
13284				});
13285
13286			},
13287			insertTestNodes: function()
13288			{
13289				document.body.appendChild(this.mainWrapper);
13290			},
13291			removeTestNodes: function()
13292			{
13293				document.body.removeChild(this.mainWrapper);
13294			},
13295			decrease: function()
13296			{
13297				var width,
13298					fontSize,
13299					widthNode,
13300					computedStyles;
13301
13302				this.insertTestNodes();
13303
13304				for(var i=this.objList.length-1; i>=0; i--)
13305				{
13306					widthNode = this.objList[i].scaleBy || this.objList[i].node;
13307					computedStyles = getComputedStyle(widthNode);
13308					width  = parseInt(computedStyles["width"]) - parseInt(computedStyles["paddingLeft"]) - parseInt(computedStyles["paddingRight"]);
13309					fontSize = parseInt(getComputedStyle(this.objList[i].node)["font-size"]);
13310
13311					this.textWrapperSetStyle(this.objList[i].node);
13312
13313					if(this.textWrapperInsertText(this.objList[i].node))
13314					{
13315						while(this.textWrapper.offsetWidth > width && fontSize > 0)
13316						{
13317							this.textWrapper.style.fontSize = --fontSize + 'px';
13318						}
13319
13320						if(this.objList[i].smallestValue)
13321						{
13322							this.minFontSize = this.minFontSize ? Math.min(this.minFontSize, fontSize) : fontSize;
13323
13324							this.minFontSizeList.push(this.objList[i].node)
13325						}
13326						else
13327						{
13328							this.objList[i].node.style.fontSize = fontSize + 'px';
13329						}
13330					}
13331				}
13332
13333				if(this.minFontSizeList.length > 0)
13334					this.setMinFont();
13335
13336				this.removeTestNodes();
13337
13338			},
13339			increase: function()
13340			{
13341				this.insertTestNodes();
13342				var width,
13343					fontSize,
13344					widthNode,
13345					computedStyles;
13346
13347				this.insertTestNodes();
13348
13349				for(var i=this.objList.length-1; i>=0; i--)
13350				{
13351					widthNode = this.objList[i].scaleBy || this.objList[i].node;
13352					computedStyles = getComputedStyle(widthNode);
13353					width  = parseInt(computedStyles["width"]) - parseInt(computedStyles["paddingLeft"]) - parseInt(computedStyles["paddingRight"]);
13354					fontSize = parseInt(getComputedStyle(this.objList[i].node)["font-size"]);
13355
13356					this.textWrapperSetStyle(this.objList[i].node);
13357
13358					if(this.textWrapperInsertText(this.objList[i].node))
13359					{
13360						while(this.textWrapper.offsetWidth < width && fontSize < this.objList[i].maxFontSize)
13361						{
13362							this.textWrapper.style.fontSize = ++fontSize + 'px';
13363						}
13364
13365						fontSize--;
13366
13367						if(this.objList[i].smallestValue)
13368						{
13369							this.minFontSize = this.minFontSize ? Math.min(this.minFontSize, fontSize) : fontSize;
13370
13371							this.minFontSizeList.push(this.objList[i].node)
13372						}
13373						else
13374						{
13375							this.objList[i].node.style.fontSize = fontSize + 'px';
13376						}
13377					}
13378				}
13379
13380				if(this.minFontSizeList.length > 0)
13381					this.setMinFont();
13382
13383				this.removeTestNodes();
13384			},
13385			setMinFont : function()
13386			{
13387				for(var i = this.minFontSizeList.length-1; i>=0; i--)
13388				{
13389					this.minFontSizeList[i].style.fontSize = this.minFontSize + 'px';
13390				}
13391
13392				this.minFontSize = 0;
13393			},
13394			onResize : function()
13395			{
13396				var width = window.innerWidth || document.documentElement.clientWidth;
13397
13398				if(this.prevWindowSize > width)
13399					this.decrease();
13400
13401				else if (this.prevWindowSize < width)
13402					this.increase();
13403
13404				this.prevWindowSize = width;
13405			},
13406			onAdaptiveResize : function()
13407			{
13408				var widthNode = this.objList[0].scaleBy || this.objList[0].node,
13409					computedStyles = getComputedStyle(widthNode),
13410					width = parseInt(computedStyles["width"]) - parseInt(computedStyles["paddingLeft"]) - parseInt(computedStyles["paddingRight"]);
13411
13412				if (this.prevWrapperSize > width)
13413					this.decrease();
13414				else if (this.prevWrapperSize < width)
13415					this.increase();
13416
13417				this.prevWrapperSize = width;
13418			},
13419			textWrapperInsertText : function(node)
13420			{
13421				if(node.textContent){
13422					this.textWrapper.textContent = node.textContent;
13423					return true;
13424				}
13425				else if(node.innerText)
13426				{
13427					this.textWrapper.innerText = node.innerText;
13428					return true;
13429				}
13430				else {
13431					return false;
13432				}
13433			},
13434			textWrapperSetStyle : function(node)
13435			{
13436				this.textWrapper.style.fontFamily = getComputedStyle(node)["font-family"];
13437				this.textWrapper.style.fontSize = getComputedStyle(node)["font-size"];
13438				this.textWrapper.style.fontStyle = getComputedStyle(node)["font-style"];
13439				this.textWrapper.style.fontWeight = getComputedStyle(node)["font-weight"];
13440				this.textWrapper.style.lineHeight = getComputedStyle(node)["line-height"];
13441			}
13442		};
13443
13444	BX.FixFontSize.init = function(params)
13445	{
13446		return new BX.FixFontSize(params);
13447	};
13448})();
13449
13450})();
13451//# sourceMappingURL=core.js.map

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.