/* Minification failed. Returning unminified contents.
(1,10): run-time error CSS1031: Expected selector, found 'UrlController_('
(1,10): run-time error CSS1025: Expected comma or open brace, found 'UrlController_('
(22,10): run-time error CSS1031: Expected selector, found 'BreadCrumbs('
(22,10): run-time error CSS1025: Expected comma or open brace, found 'BreadCrumbs('
(94,10): run-time error CSS1031: Expected selector, found 'SEOcontent_('
(94,10): run-time error CSS1025: Expected comma or open brace, found 'SEOcontent_('
(210,17): run-time error CSS1031: Expected selector, found '='
(210,17): run-time error CSS1025: Expected comma or open brace, found '='
(461,13): run-time error CSS1030: Expected identifier, found 'onReady('
(461,13): run-time error CSS1031: Expected selector, found 'onReady('
(461,13): run-time error CSS1025: Expected comma or open brace, found 'onReady('
(463,10): run-time error CSS1031: Expected selector, found 'inputMask('
(463,10): run-time error CSS1025: Expected comma or open brace, found 'inputMask('
(538,10): run-time error CSS1031: Expected selector, found 'inputMaskFormControl('
(538,10): run-time error CSS1025: Expected comma or open brace, found 'inputMaskFormControl('
(544,10): run-time error CSS1031: Expected selector, found 'inputMaskFormControl2('
(544,10): run-time error CSS1025: Expected comma or open brace, found 'inputMaskFormControl2('
(573,10): run-time error CSS1031: Expected selector, found 'TopHotels_('
(573,10): run-time error CSS1025: Expected comma or open brace, found 'TopHotels_('
(683,10): run-time error CSS1031: Expected selector, found 'Pagination_('
(683,10): run-time error CSS1025: Expected comma or open brace, found 'Pagination_('
(873,22): run-time error CSS1031: Expected selector, found '='
(873,22): run-time error CSS1025: Expected comma or open brace, found '='
(875,10): run-time error CSS1031: Expected selector, found 'Catalog_('
(875,10): run-time error CSS1025: Expected comma or open brace, found 'Catalog_('
(1563,10): run-time error CSS1031: Expected selector, found 'Country_('
(1563,10): run-time error CSS1025: Expected comma or open brace, found 'Country_('
(1588,10): run-time error CSS1031: Expected selector, found 'Resort_('
(1588,10): run-time error CSS1025: Expected comma or open brace, found 'Resort_('
(1612,10): run-time error CSS1031: Expected selector, found 'Airport_('
(1612,10): run-time error CSS1025: Expected comma or open brace, found 'Airport_('
(1627,10): run-time error CSS1031: Expected selector, found 'Operator_('
(1627,10): run-time error CSS1025: Expected comma or open brace, found 'Operator_('
(1640,10): run-time error CSS1031: Expected selector, found 'Star_('
(1640,10): run-time error CSS1025: Expected comma or open brace, found 'Star_('
(1656,10): run-time error CSS1031: Expected selector, found 'starsRender('
(1656,10): run-time error CSS1025: Expected comma or open brace, found 'starsRender('
(1665,10): run-time error CSS1031: Expected selector, found 'starsRenderInner('
(1665,10): run-time error CSS1025: Expected comma or open brace, found 'starsRenderInner('
(1681,10): run-time error CSS1031: Expected selector, found 'starIdToInt('
(1681,10): run-time error CSS1025: Expected comma or open brace, found 'starIdToInt('
(1711,10): run-time error CSS1031: Expected selector, found 'starIdToName('
(1711,10): run-time error CSS1025: Expected comma or open brace, found 'starIdToName('
(1754,10): run-time error CSS1031: Expected selector, found 'starIdToLocalizedName('
(1754,10): run-time error CSS1025: Expected comma or open brace, found 'starIdToLocalizedName('
(1798,10): run-time error CSS1031: Expected selector, found 'Meal_('
(1798,10): run-time error CSS1025: Expected comma or open brace, found 'Meal_('
(1812,10): run-time error CSS1031: Expected selector, found 'getShortMeal('
(1812,10): run-time error CSS1025: Expected comma or open brace, found 'getShortMeal('
(1819,10): run-time error CSS1031: Expected selector, found 'mealIdToName('
(1819,10): run-time error CSS1025: Expected comma or open brace, found 'mealIdToName('
(1850,10): run-time error CSS1031: Expected selector, found 'mealIdToLocalizedName('
(1850,10): run-time error CSS1025: Expected comma or open brace, found 'mealIdToLocalizedName('
(1882,16): run-time error CSS1030: Expected identifier, found 'ready('
(1882,16): run-time error CSS1031: Expected selector, found 'ready('
(1882,16): run-time error CSS1025: Expected comma or open brace, found 'ready('
 */
function UrlController_(model) {
	var self = this;
	this.url = window.location.href;
	this.parse = function(array) {
		return ['/',(LL.current=='ru'?'':LL.current+'/'), array.join(self.model.pathSeparator), '/'].join('');
	};
	this.change = function(url) {
		history.pushState(null, null, url);
	};
	this.parseAndChange = function(array) {
		self.change(self.parse(array));
	};
	this.init = function(model) {
		self.model = model;
		if (!isset(self.model)) self.model = {};
		if (!isset(self.model.pathSeparator)) self.model.pathSeparator = '/';
	};
	this.init(model);
}
/// <reference path="../../Scripts/_references.js" />

function BreadCrumbs(model) {
	var self = this;

	this.elements = {};
	this.elements.container = (isset(model.container)?model.container:null);
	this.elements.elements = [];
	this.array = (isset(model.array)?model.array:[]);

	this.render = function(array) {
		if (isset(array)) self.array = array;
		var i, len = self.array.length;
		removeChilds(self.elements.container);
		self.elements.container.appendChild(self.renderItem({
			link: '/',
			title: 'Farvater',
			icon: 'home3'
		}, 1));
		for (i = 0; i < len; i++) {
			//if (i == (len - 1)) delete self.array[i].link;
			self.elements.container.appendChild(self.renderItem(self.array[i], i + 2));
		}
	};

	/**
	 * 
	 * @param {any} model
	 * @param {number} position
	 */
	this.renderItem = function(model, position) {
		return createElement({
			tag: 'li',
			attributes: {
				itemscope: '',
				itemprop: 'itemListElement',
				itemtype: 'http://schema.org/ListItem'
			},
			childs: [
				createElement({
					tag: 'a',
					attributes: {
						href: (isset(model.link) ? model.link : '#'),
						itemprop: 'item'
					},
					childs: [
						(isset(model.icon) ?
							createElement({
								tag: 'i',
								className: ['i __', model.icon].join('')
							})
						: void 0),
						createElement({
							tag: 'span',
							attributes: {
								itemprop: 'name'
							},
							innerHTML: (isset(model.title) ? model.title : '')
						})
					]
				}),
				createElement({
					tag: 'meta',
					attributes: {
						itemprop: 'position',
						content: position || 1
					}
				})
			]
		});
	};
}


function SEOcontent_(model) {
	var self = this;
	this.elements = {};
	if (isset(model.parent)) this.elements.parent = model.parent;
	if (isset(model.header)) this.elements.header = model.header;
	if (isset(model.title)) this.elements.title = model.title;
	if (isset(model.main)) this.elements.main = model.main;
	if (isset(model.content)) this.elements.content = model.content;
	if (isset(model.footer)) this.elements.footer = model.footer;
	this.elements.titles = {
		title: document.querySelector('head title'),
		descs: [
			document.querySelector('header meta[property="og:description"]'),
			document.querySelector('header meta[property="og:description"]'),
			document.querySelector('header meta[property="og:description"]'),
		],
		metas: [
			document.querySelector('head meta[property="og:title"]'),
			document.querySelector('head meta[property="twitter:description"]'),
			document.querySelector('head meta[name="description"]')
		]
	};
	this.SEOBlocks = [];
	this.reRender = function(model) {
		//console.log(model);
		model.content = (isset(model.content)?(model.content?model.content:''):'');
		if ((model.content=='')||(isset(model.hide)&&model.hide)) {
			self.hide();
		} else if ((model.content!='')||(isset(model.show)&&model.show)) {
			self.show();
		}
		if (isset(model.h1)&&model.h1) model.h1 = decodeHTMLEntities(model.h1);
		if (isset(model.title)&&model.title) model.title = decodeHTMLEntities(model.title);
		if (isset(self.elements.content)&&model.content) self.elements.content.innerHTML = model.content;
		if (isset(model.footer)&&isset(self.elements.footer)&&model.footer) self.elements.footer.innerHTML = model.footer;
		if (isset(self.elements.title)) {
			if (isset(model.h1)&&model.h1) {
				if (self.elements.title) self.elements.title.innerHTML = model.h1;
			} else if (isset(model.title)&&model.title) {
				if (self.elements.title) self.elements.title.innerHTML = model.title;
			}
		}
		if (isset(model.title)&&isset(self.elements.title)&&model.title) {
			if (self.elements.titles.title) self.elements.titles.title.innerHTML = model.title;
			for (var i=(self.elements.titles.metas.length - 1);i>=0;i--) {
				if (self.elements.titles.metas[i]) self.elements.titles.metas[i].setAttribute('content', model.title);
			}
		}
	};
	this.renderSub = function (model) {
		var element = createElement({
			tag: 'article',
			className: 'shadowPanel'
		});
		//console.log(model);
		if (!isset(model.qasId) && (model.content == '' || !model.content)) {
			element.hidden = true;
		}
		else {
			var header = (isset(model.title) && model.title.length > 1 ? createElement({
					tag: 'header',
					className: 'shadowPanel__header',
					innerHTML: ['<h3>', decodeHTMLEntities(model.title), '</h3>'].join('')
				}) : null),
				image = (isset(model.image) ? createElement({
					className: 'shadowPanel__image',
					innerHTML: ['<img src="', model.image, '">'].join('')
				}) : null),
				body = isset(model.content) && model.content.length > 1 ? createElement({
					className: 'shadowPanel__body',
					innerHTML: decodeHTMLEntities(model.content)
				}) : null,
				footer = (isset(model.footer) ? createElement({
					tag: 'footer',
					className: 'shadowPanel__footer',
					innerHTML: model.footer
				}) : null),
				qas = (isset(model.qasId) ? createElement({ tag: 'DIV', className: 'shadowPanel__body', id: model.qasId }) : null)
			if (header) {
				element.appendChild(header);
			}
			if (qas) {
				element.appendChild(qas);
			}
			if (image) {
				element.appendChild(image);
				element.classList.add('__hasImage');
			}
			if (body) {
				element.appendChild(body);
			}
			if (footer) {
				element.appendChild(footer);
			}
		}
		return element;
	};
	this.hide = function() {
		if (isset(self.elements.parent)&&!self.elements.parent.hidden) {
			self.elements.parent.hidden = true;
		}
	};
	this.show = function() {
		if (isset(self.elements.parent)&&self.elements.parent.hidden) {
			self.elements.parent.hidden = false;
		}
	};
	this.init = function() {
		if (self.elements.content.innerHTML=='') self.hide();
	};
	this.init();
}


/// <reference path="../../../Scripts/_references.js" />

var FormControl = {
	hasSuccess: function(a) {
		var input = (isset(this.FormControl)?this.FormControl:this);
		if (a) {
			input.container.classList.add('__hasSuccess');
		} else {
			input.container.classList.remove('__hasSuccess');
		}
	},
	hasError: function(a) {
		var input = (isset(this.FormControl)?this.FormControl:this);
		if (a) {
			input.container.classList.add('__hasError');
		} else {
			input.container.classList.remove('__hasError');
		}
	},
	setActive: function() {
		var input = (isset(this.FormControl)?this.FormControl:this);
		input.input.setAttribute('checked', true);
		input.input.checked = true;
		input.container.classList.add('__active');
	},
	unsetActive: function() {
		var input = (isset(this.FormControl)?this.FormControl:this);
		input.input.removeAttribute('checked');
		input.input.checked = false;
		input.container.classList.remove('__active');
	},
	setAvailable: function() {
		var input = (isset(this.FormControl)?this.FormControl:this);
		if (!input.container.classList.contains('__available')) input.container.classList.add('__available');
	},
	unsetAvailable: function() {
		var input = (isset(this.FormControl)?this.FormControl:this);
		if (input.container.classList.contains('__available')) input.container.classList.remove('__available');
	},
	toggleActive: function() {
		var input = (isset(this.FormControl)?this.FormControl:this);
		if (input.container.classList.contains('__active')) {
			input.container.classList.remove('__active');
		} else {
			if (input.input.type=='radio') {
				var radios = document.querySelectorAll(['input[type="radio"][name="',input.input.name,'"]'].join(''));
				for (i=(radios.length - 1);i>=0;i--) radios[i].FormControl.container.classList.remove('__active');
			} else if (input.input.type=='checkbox') {
				var checkboxes = document.querySelectorAll(['input[type="checkbox"][name="',input.input.name,'"]'].join(''));
				if (input.input.getAttribute('primary')) {
					for (i=(checkboxes.length - 1);i>=0;i--) {
						checkboxes[i].FormControl.unsetActive();
					}
				} else {
					for (i=(checkboxes.length - 1);i>=0;i--) {
						if (checkboxes[i].getAttribute('primary')) {
							checkboxes[i].FormControl.unsetActive();
						}
					}
				}
				input.input.setAttribute('checked', true);
			}
			input.container.classList.add('__active');
		}
	},
	badgeUpdate: function(text) {
		var input = (isset(this.FormControl)?this.FormControl:this);
		if (input.badge) {
			input.badge.innerHTML = text;
		} else {
			console.error(input);
		}
	},
	badgeHelperUpdate: function(innerHTML, hideTimer) {
		var input = (isset(this.FormControl)?this.FormControl:this), helper;
		if (!input.badge) return;
		helper = input.badge.querySelector('.FormControl__badge__helper');
		if (helper) {
			helper.innerHTML = innerHTML;
			helper.hidden = false;
		} else {
			helper = FormControl.renderBadgeHelper(innerHTML);
			input.badge.appendChild(helper);
		}
		if (hideTimer) {
			setTimeout(function(){
				helper.hidden = true;
			}, hideTimer);
		}
	},
	labelUpdate: function(text) {
		input.label.innerHTML = text;
	},
	renderBadgeHelper: function(innerHTML) {
		return createElement({
			tag: 'span',
			className: 'FormControl__badge__helper',
			innerHTML: innerHTML
		});
	},
	renderControl: function(model) {
		/*
		model = {
			name: 'name',		// String
			value: 'value', 	// String
			label: 'Some label',// String
			badge: 20, 			// Integer
			className: '', 		// String
			active: true,		// false||true
			hasError: false,	// false||true
			hasSuccess: false,	// false||true
			primary: false, 	// false||true
			box: false, 		// false||true||half
			size: false, 		// false||xs||sm||md||lg||xl
			type: 'checkbox', 	// text||email||number||date||range||radio||checkbox||select||textarea||password||color||datetime-local||file||image||month||tel||time||url||week
			_parent: HtmlElement, | undefined
			attributes: { 		// Object
				// min: 0,
				// max: 10,
				// step: 1
			},
			onRendered: function(element) {
				anyElementProcedure
			},
			onInited: function(FormControl) {
				anyFormControlProcedure
			}
		};
		*/
		if (!isset(model.attributes)) model.attributes = {};
		model.attributes.name = model.name;
		if (isset(model.primary)&&model.primary) model.attributes.primary = true;
		if (!isset(model.events)) model.events = {};
		var inputTag,
			inputType,
			inputInnerHTML,
			childs = [];
		switch (model.type) {
			case 'text': case 'email': case 'number': case 'date': case 'range':
			case 'password': case 'color': case 'datetime-local': case 'file':
			case 'image': case 'month': case 'tel': case 'time': case 'url': case 'week':
				inputTag = 'input';
				model.attributes.value = (isset(model.value)?model.value:'');
				model.attributes.type = model.type;
				inputType = model.type;
			break;
			case 'radio': case 'checkbox':
				inputTag = 'input';
				model.attributes.value = (isset(model.value)?model.value:'');
				model.attributes.type = model.type;
				inputType = model.type;
				if (isset(model.active)&&model.active) model.attributes.checked = true;
			break;
			case 'select':
				inputTag = 'select';
				inputInnerHTML = null;
				inputType = 'select';
			break;
			case 'textarea':
				inputTag = 'textarea';
				inputInnerHTML = model.value;
				inputType = 'textarea';
			break;
			default:
				inputTag = 'input';
				model.attributes.value = (isset(model.value)?model.value:'');
				model.attributes.type = 'text';
				inputType = 'text';
			break;
		}
		var input = createElement({
			tag: inputTag,
			attributes: model.attributes,
			events: model.events
		});
		input.name = model.attributes.name;
		input.type = model.attributes.type;
		input.value = model.attributes.value;
		childs.push(input);
		if (isset(model.label)) childs.push(createElement({
			tag: 'span',
			className: 'FormControl__label formControl__label',
			innerHTML: model.label
		}));
		if (isset(model.badge)) childs.push(createElement({
			tag: 'span',
			className: 'FormControl__badge formControl__badge',
			innerHTML: model.badge
		}));
		var element = createElement({
			tag: 'label',
			attributes:  {
				style: (isset(model.labelStyles) ? model.labelStyles : '')
			},
			className: [
							'FormControl formControl',
							['__',inputType].join(''),
							(isset(model.active)&&model.active?'__active':''),
							(isset(model.hasError)&&model.hasError?'__hasError':''),
							(isset(model.hasSuccess)&&model.hasSuccess?'__hasSuccess':''),
							(isset(model.box)&&model.box?'__box':''),
							(isset(model.size)&&model.size?['__',model.size].join(''):''),
						].join(' '),
			childs: childs
		});
		if (isset(model.className)) {
			element.classList.add(model.className);
		}
		FormControl.initControl(element);
		if (isset(model.onInited)) model.onInited(element);
		return element;
	},
	initControl: function(element) {
		if (isset(element.FormControl)) return;
		var input = element.querySelector('input, select, textarea');
		if (input) {
			element.input = input;
			input.FormControl = {
				hasError: FormControl.hasError,
				hasSuccess: FormControl.hasSuccess,
				toggleActive: FormControl.toggleActive,
				labelUpdate: FormControl.labelUpdate,
				badgeUpdate: FormControl.badgeUpdate,
				unsetActive: FormControl.unsetActive,
				setActive: FormControl.setActive,
				unsetAvailable: FormControl.unsetAvailable,
				setAvailable: FormControl.setAvailable,
				badgeHelperUpdate: FormControl.badgeHelperUpdate,
				container: element,
				input: input,
				badge: element.querySelector('.FormControl__badge'),
				label: element.querySelector('.FormControl__label')
			};
			if (input.type=='checkbox'||input.type=='radio') {
				input.addEventListener('change', input.FormControl.toggleActive);
			}
		} else {
			switch (element.tagName.toLowerCase()) {
				case 'select':
				case 'input':
				case 'textarea':
					FormControl.initControl(element.parentNode);
				break;
			}
		}
	},
	init: function() {
		var controls = document.querySelectorAll('.FormControl');
		for (var i=(controls.length - 1);i>=0;i--) {
			FormControl.initControl(controls[i]);
		}
	}
};
farDocument.onReady(FormControl.init);

function inputMask(model) {
	var self = this;
	this.getPattern = function() {
		var pattern = (isset(self.model.pattern)?self.model.pattern:self.model.input.getAttribute('data-pattern')),
			new_pattern = [],
			i;
		pattern.split('');
		for (i=0;i<pattern.length;i++) {
			switch (pattern[i]) {
				case '0':
					new_pattern.push({f: self.symbolDigit, s:pattern[i]});
				break;
				case 'Z':
					new_pattern.push({f: self.symbolLeter, s:pattern[i]});
				break;
				default:
					new_pattern.push({f: self.symbolAny, s:pattern[i]});
				break;
			}
		}
		return new_pattern;
	};
	this.codes = [49,50,51,52,53,54,55,56,57,48,189,187,192,81,87,69,82,84,89,85,73,79,80,219,221,220,65,83,68,70,71,72,74,75,76,186,222,90,88,67,86,66,78,77,188,190,191,103,104,105,100,101,102,97,98,99,110,96,111,106,109];
	this.onInput = function(e) {
		var code = e.keyCode,
			char = e.key;
		if (char.length==1&&self.codes.indexOf(code)!=-1) {
			e.preventDefault();
			var new_value = [],
				value = self.model.input.value.split(''),
				i, obj, v;
			value.push(char.toString());
			for (i=0;i<self.pattern.length;i++) {
				v = (isset(value[i])?value[i]:null);
				obj = self.pattern[i].f(v, self.pattern[i].s);
				if (obj==null) {
					break;
				} else {
					new_value.push(obj);
				}
			}
			new_value = new_value.join('');
			self.previous_value = new_value;
			self.model.input.value = new_value;
		}
		switch (code) {
			case 8:
			break;
			default:
			break;
		}
		return false;
	};
	this.symbolDigit = function(v, s) {
		if (v==null) return null;
		return (v.toLowerCase().match(/[0-9]/i)?v:null);
	};
	this.symbolLeter = function(v, s) {
		if (v==null) return null;
		return (v.toLowerCase().match(/[a-zа-яіїєэ]/i)?v:null);
	};
	this.symbolAny = function(v, s) {
		return s;
	};
	this.init = function(model) {
		self.model = model;
		self.model.input.value = (self.model.input.value?self.model.input.value:'');
		self.previous_value = self.model.input.value;
		self.new_value = self.model.input.value;
		self.pattern = self.getPattern();
		self.model.input.addEventListener('keydown', self.onInput);
	};
	this.init(model);
}

function inputMaskFormControl(formControl) {
	return new inputMask({
		input: formControl.input.FormControl.input
	});
}

function inputMaskFormControl2(formControl, countryCodeExtractorFn) {
	window.Far.Global.appendScript({
		url: '/plugins/imask/imask.min.js',
		context: formControl,
		predicate: function () {
			return typeof IMask !== 'undefined';
		},
		callback: function () {
			formControl.input.FormControl.IMask = IMask(formControl.input.FormControl.input, {
				mask: '(QN) NNN-NN-NN',
				lazy: false,
				placeholderChar: '_',
				blocks: {
					Q: {
						mask: IMask.MaskedPhoneFirstDigitRange,
						from: 0,
						to: 9,
						countryCodeExtractorFn: countryCodeExtractorFn
					},
					N: {
						mask: IMask.MaskedRange,
						from: 0,
						to: 9
					}
				}
			});
		}
	});
}
function TopHotels_(model) {
	var self = this;
	this.elements = {};
	this.elements.parent = model.parent;
	this.elements.container = (isset(model.parent)?model.container:null);
	this.elements.pagination = (isset(model.pagination)?model.pagination:null);
	this.elements.hotelsCount = (isset(model.hotelsCount)?model.hotelsCount:null);
	this.hotels = (isset(model.hotels)?model.hotels:[]);
	this.settings = {
		pageIndex: 1,
		totalPagesCount: Math.ceil(this.hotels.length?this.hotels.length / (isset(model.itemsPerPage)?model.itemsPerPage:10):0),
		itemsPerPage: (isset(model.itemsPerPage)?model.itemsPerPage:10),
		load: false,
		useNumberInput: (isset(model.useNumberInput)?model.useNumberInput:false),
		hideNextPrevPaginationLinx: true
	};
	this.ajax = null;
	this.firstQuery = function() {
		self.query(window.Catalog.filterModel.countryId, window.Catalog.filterModel.resorts);
	};
	this.query = function(countryId, resorts) {
		if (self.ajax) self.ajax.abort();
		self.ajax = window.Far.Global.jsonRequest({
			method: 'POST',
			url: ['/',localization,'/catalog/static-tophotels'].join(''),
			onSuccess: function(response){
				if (response.statusCode==200) {
					self.hotels = [];
					var hotelsCount = response.data.topHotels.length;
					if (response.data.topHotels&&hotelsCount) {
						self.elements.parent.hidden = false;
						self.hotels=response.data.topHotels;
						self.settings.pageIndex = 1;
						self.settings.totalPagesCount = Math.ceil(hotelsCount / self.settings.itemsPerPage);
						self.showPage();
						self.Pagination.render();
						self.elements.hotelsCount.innerText = [hotelsCount,LL.getMethering('hotels', hotelsCount)].join(' ');
					} else {
						self.elements.parent.hidden = true;
					}
				}
			},
			onError: function(){},
			data: {
				countryId: countryId,
				resorts: resorts
			}
		});
	};
	this.showPage = function() {
		removeChilds(self.elements.container);
		var fragment = document.createDocumentFragment();
		for (var i=0;i<self.settings.itemsPerPage;i++) {
			x = (self.settings.itemsPerPage * (self.settings.pageIndex - 1)) + i;
			if (isset(self.hotels[x])) fragment.appendChild(self.renderItem(self.hotels[x]));
		}
		self.elements.container.appendChild(fragment);
	};
	this.renderItem = function(hotel) {
		var a = createElement({
			tag: 'a',
			className: 'hotelsList__item',
			attributes: {
			    href: localizationFn.localizeUrl(hotel.info.link, localizationFn.current),
				target: '_blank'
			}
		});
		var imgServerUrl = imageServicesURL || 'https://img.farvater.travel';
		var html = [
					'<div class="hotelsList__item__image"><img src="', imgServerUrl, '/mapkey/', hotel.info.hotel.mapKey, '/0?size=thumb360" alt="', hotel.info.hotel.name, '"></div>',
					'<div class="hotelsList__item__stars stars">',
						starsRenderInner(starIdToInt(hotel.info.hotel.starId)),
					'</div>',
					//'<div class="hotelsList__item__location">',
					//	'<span>',hotel.info.country.name,', ',hotel.info.resort.name,'</span>',
					//'</div>',
					'<div class="hotelsList__item__title">',
						hotel.info.hotel.name,
						'<div class="hotelsList__item__location">',
							'<span>', hotel.info.country.name, ', ', hotel.info.resort.name, '</span>',
						'</div>',
					'</div>',
					'<div class="hotelsList__item__rating">',
						'<b>', hotel.info.hotel.rate, '</b>',
						(hotel.info.hotel.reviewsCount > 0 ? '<span>' + hotel.info.hotel.reviewsCount + ' ' + LL.getMethering('reviews', hotel.info.hotel.reviewsCount) + '</span>' : ''),
					'</div>',
			(hotel.prices && hotel.prices[0] && hotel.prices[0].min && hotel.prices[0].min.priceUAH ? ['<div class="hotelsList__item__price">',
						'<a class="btn __goldGradient __md">', localizationValues.from3, ' ', intHumanize(hotel.prices[0].min.priceUAH), ' ', localizationValues.currency_uah, '</span>',
					'</div>'].join(''):'')
				].join('');
		a.innerHTML = html;
		a.model = hotel;
		// a.addEventListener('click', self.gotoLink);
		return a;
	};
	this.init = function() {
		if (!self.elements.container) self.elements.container = document.getElementById([self.elements.parent.id,'container'].join('__'));
		if (!self.elements.pagination) self.elements.pagination = document.getElementById([self.elements.parent.id,'pagination'].join('__'));
		if (!self.elements.hotelsCount) self.elements.hotelsCount = document.getElementById([self.elements.parent.id,'hotelsCount'].join('__'));
		if (self.elements.pagination) {
			self.Pagination = new Pagination_(self, self.elements.pagination, self.showPage, function(){}, 2, false);
			self.Pagination.render();
		}
	};
	this.init();
}


/// <reference path="../../Scripts/_references.js" />

function Pagination_(parent, element, onShowPage, onInit, tabsAllowed, autoPaged, usePageIndexLinks) {
	var self = this;

	this.parent = parent;
	this.tabsAllowed = (typeof tabsAllowed == 'undefined'?3:tabsAllowed);
	this.autoPaged = (typeof autoPaged == 'undefined'?false:autoPaged);
	this.onInit = onInit;
	this.onShowPage = onShowPage;
	this.element = element;
	this.element.classList.add('Pagination');
	this.usePageIndexLinks = (typeof usePageIndexLinks=='undefined'?false:usePageIndexLinks);

	if (typeof this.parent.settings=='undefined') {
		this.parent.settings = {};
	}
	if (typeof this.parent.settings.pageIndex=='undefined') this.parent.settings.pageIndex = 1;
	this.parent.settings.pageIndex = parseInt(this.parent.settings.pageIndex);
	if (typeof this.parent.settings.totalPagesCount=='undefined') this.parent.settings.totalPagesCount = 1;
	this.parent.settings.totalPagesCount = parseInt(this.parent.settings.totalPagesCount);

	this.getPageLink = function(n) {
		if (!self.usePageIndexLinks) return false;
		var link = window.location.pathname;
		if (link.indexOf('page-')!=-1) link = link.split('page-')[0];
		switch (n) {
			case 'next':
				var nextPage = parseInt(self.parent.settings.pageIndex)+1;
				n = (nextPage>parseInt(self.parent.settings.totalPagesCount)?self.parent.settings.totalPagesCount:nextPage);
			break;
			case 'prev':
				var prevPage = parseInt(self.parent.settings.pageIndex)-1;
				n = (prevPage<0?0:prevPage);
			break;
			default:
			break;
		}
		if (n>1) link+='page-'+n+'/';
		return link + window.location.search;
	};
	this.render = function () {
		var totalPagesCount = parseInt(self.parent.settings.totalPagesCount),
			pageIndex 		= parseInt(self.parent.settings.pageIndex),
			link;
		if (self.autoPaged) {
			self.element.style.visibility = 'hidden';
			self.element.style.height = 'calc(var(--s-bs) * 4)';
			self.element.style.background = 'background: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22200px%22%20%20height%3D%22200px%22%20%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20100%20100%22%20preserveAspectRatio%3D%22xMidYMid%22%20class%3D%22lds-ripple%22%20style%3D%22background%3A%20none%3B%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2228.407%22%20fill%3D%22none%22%20ng-attr-stroke%3D%22%7B%7Bconfig.c1%7D%7D%22%20ng-attr-stroke-width%3D%22%7B%7Bconfig.width%7D%7D%22%20stroke%3D%22%238cd0e5%22%20stroke-width%3D%222%22%3E%3Canimate%20attributeName%3D%22r%22%20calcMode%3D%22spline%22%20values%3D%220%3B40%22%20keyTimes%3D%220%3B1%22%20dur%3D%221%22%20keySplines%3D%220%200.2%200.8%201%22%20begin%3D%22-0.5s%22%20repeatCount%3D%22indefinite%22%3E%3C%2Fanimate%3E%3Canimate%20attributeName%3D%22opacity%22%20calcMode%3D%22spline%22%20values%3D%221%3B0%22%20keyTimes%3D%220%3B1%22%20dur%3D%221%22%20keySplines%3D%220.2%200%200.8%201%22%20begin%3D%22-0.5s%22%20repeatCount%3D%22indefinite%22%3E%3C%2Fanimate%3E%3C%2Fcircle%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%226.15459%22%20fill%3D%22none%22%20ng-attr-stroke%3D%22%7B%7Bconfig.c2%7D%7D%22%20ng-attr-stroke-width%3D%22%7B%7Bconfig.width%7D%7D%22%20stroke%3D%22%23376888%22%20stroke-width%3D%222%22%3E%3Canimate%20attributeName%3D%22r%22%20calcMode%3D%22spline%22%20values%3D%220%3B40%22%20keyTimes%3D%220%3B1%22%20dur%3D%221%22%20keySplines%3D%220%200.2%200.8%201%22%20begin%3D%220s%22%20repeatCount%3D%22indefinite%22%3E%3C%2Fanimate%3E%3Canimate%20attributeName%3D%22opacity%22%20calcMode%3D%22spline%22%20values%3D%221%3B0%22%20keyTimes%3D%220%3B1%22%20dur%3D%221%22%20keySplines%3D%220.2%200%200.8%201%22%20begin%3D%220s%22%20repeatCount%3D%22indefinite%22%3E%3C%2Fanimate%3E%3C%2Fcircle%3E%3C%2Fsvg%3E") no-repeat center transparent';
			self.element.style.backgroundSize = 'calc(var(--s-bs) * 3)';
		} else {
			removeChilds(self.element);
			var x = 1, item, subItem;
			if (totalPagesCount>1) {
				if (!(isset(self.parent.settings.hideNextPrevPaginationLinx)&&self.parent.settings.hideNextPrevPaginationLinx)) {
					item = createElement('li');
					item.className = ['Pagination__item', (pageIndex > 1 ? '' : '__disabled')].join(' ');
					subItem = createElement('a');
					if (pageIndex > 1) {
						subItem.addEventListener('click', function(e){
							e.preventDefault();
							self.prev_page();
							return false;
						});
						link = self.getPageLink('prev');
						if (link) subItem.setAttribute('href', link);
					}
					subItem.innerText = localizationValues.back;
					item.appendChild(subItem);
					self.element.appendChild(item);
				}

				while (x <= totalPagesCount) {
					if (x == pageIndex || x == totalPagesCount || x == 1 || (x > pageIndex && x <= pageIndex + self.tabsAllowed) || (x < pageIndex && x >= pageIndex - self.tabsAllowed)) {
						item = createElement('li');
						item.className = ['Pagination__item', (x == pageIndex ? '__active' : '')].join(' ');
						subItem = createElement('a');
						if (x !== pageIndex) {
							subItem._page = x;
							subItem.addEventListener('click', function(e){
								e.preventDefault();
								self.show_page(this._page);
								return false;
							});
							link = self.getPageLink(x);
							if (link) subItem.setAttribute('href', link);
						}
						subItem.innerText = x;
						item.appendChild(subItem);
						self.element.appendChild(item);
					} else if (x == (pageIndex + (self.tabsAllowed + 1)) || x == (pageIndex - (self.tabsAllowed + 1))) {
						item = createElement('li');
						item.className = 'Pagination__item';
						subItem = createElement('a');
						subItem.innerText = '';
						subItem.addEventListener('click', function(e){
							e.preventDefault();
							return false;
						});
						item.appendChild(subItem);
						self.element.appendChild(item);
					}
					x++;
				}
				if (totalPagesCount>10&&self.parent.settings.useNumberInput) {
					item = createElement('li');
					item.className = 'Pagination__item';
					subItem = createElement('input');
					subItem.type = 'number';
					subItem.setAttribute('min', 1);
					subItem.setAttribute('max', totalPagesCount);
					subItem.value = pageIndex;
					subItem.addEventListener('change', function(e){
						e.preventDefault();
						var v = parseInt(this.value);
						if (v>1&&v<=totalPagesCount) {
						} else if (v>1) {
							v = totalPagesCount;
						} else {
							v = 1;
						}
						self.show_page(v);
						return false;
					});
					item.appendChild(subItem);
					self.element.appendChild(item);
				}

				if (!(isset(self.parent.settings.hideNextPrevPaginationLinx)&&self.parent.settings.hideNextPrevPaginationLinx)) {
					item = createElement('li');
					item.className = ['Pagination__item', (pageIndex < totalPagesCount ? '' : '__disabled')].join(' ');
					subItem = createElement('a');
					if (pageIndex < totalPagesCount) {
						subItem.addEventListener('click', function(e){
							e.preventDefault();
							self.next_page();
							return false;
						});
					}
					link = self.getPageLink('next');
					if (link) subItem.setAttribute('href', link);
					subItem.innerText = localizationValues.forward;
					item.appendChild(subItem);
					self.element.appendChild(item);
				}
			}
		}
	};
	this.next_page = function (e) {
		var x = self.parent.settings.pageIndex + 1;
		x = (x > self.parent.settings.totalPagesCount ? self.parent.settings.totalPagesCount : x);
		self.show_page(x);
	};
	this.prev_page = function (e) {
		var x = self.parent.settings.pageIndex - 1;
		x = (x < 1 ? 1 : x);
		self.show_page(x);
	};
	this.show_page = function (pageNumber) {
		self.parent.settings.pageIndex = pageNumber;
		self.onShowPage__action();
		self.render();
		if (self.usePageIndexLinks) {
			var link = self.getPageLink(pageNumber);
			if (link) window.history.pushState('page'+pageNumber, 'Title', link);
		};
	};
	this.reload = function() {
		self.onShowPage__action();
	};
	this.onShowPage__action = function() {
		self.onShowPage(self.parent.settings.pageIndex, function(){
			self.element.style.visibility = 'visible';
		}, function(){
			self.element.style.visibility = 'hidden';
		});
	};
	this.onScroll = function(scrolled){
		if (scrolled>=(self.element.offsetTop - 200 - window.innerHeight) && !self.parent.settings.load) {
			self.next_page();
		}
	};
	this.init = function() {
		if (typeof self.onInit == 'function') self.onInit(self.parent.settings.pageIndex);
		if (self.autoPaged) {
			window.onscroll__add(['Pagination',self.element.id].join('__'), self.onScroll);
		}
	};
	this.init();
}


window.CatalogChilds = {};

function Catalog_(model) {
	var self = this;
	this.resultsPage = 0;
	this.Hotels = {};
	this.id = model.id;
	this.SearchForm = model.SearchForm;
	this.elements = {
		fragment: document.createDocumentFragment()
	};
	this.SEOBlocksItems = model.SEOBlocksItems ?? [];
	this.isVersionWithLoader = model.isVersionWithLoader === true;
	this.CatalogPathSeparator = (isset(model.CatalogPathSeparator)?model.CatalogPathSeparator:'/');
	this.useOperatorsIcons = (isset(model.useOperatorsIcons)?model.useOperatorsIcons:false);
	this.insertedHotels = 0;
	this.hotelsCount = isset(model.hotelsCount)?model.hotelsCount:0;
	this.settings = {
		pageIndex: (isset(model.pageIndex)?model.pageIndex:1),
		totalPagesCount: Math.ceil(this.hotelsCount / (isset(model.itemsPerPage)?model.itemsPerPage:10)),
		itemsPerPage: (isset(model.itemsPerPage)?parseInt(model.itemsPerPage):10),
		load: false,
		useNumberInput: (isset(model.useNumberInput)?model.useNumberInput:false),
		hideNextPrevPaginationLinx: true
	};
	if (isset(model.seoModels)) {
		this.seoModels = {
			metaV2: (isset(model.seoModels.metaV2)?model.seoModels.metaV2:null),
			metaV2block1: (isset(model.seoModels.metaV2block1)?model.seoModels.metaV2block1:null),
			metaV2block2: (isset(model.seoModels.metaV2block2)?model.seoModels.metaV2block2:null)
		};
	}
	this.paginationHidden = (isset(model.paginationHidden)?model.paginationHidden:true);
	this.calendarMinColumns = HotelSharedMethods.calendarMinColumns;
	this.calendarMaxColumns = HotelSharedMethods.calendarMaxColumns;
	this.lazyLoad = (isset(model.lazyLoad)?model.lazyLoad:500);
	this.toursCount = 0;
	this.requestsCount = {
		start: 0,
		success: 0,
		errors: 0
	};
	this.mobile = (deviceConfig.type=='Mobile'?true:false);
	this.hotelDescriptions = {};
	this.hotelSpecialLinx = (isset(model.hotelSpecialLinx)?model.hotelSpecialLinx:{});
	this.mainPage = window.location.href;
	this.hotelsMode = (isset(model.hotelsMode)?model.hotelsMode:'default');
	this.othersDesign = (isset(model.othersDesign)?model.othersDesign:'callendar');
	this.filterModel = (isset(model.filterModel)?model.filterModel:{});
	this.static = (isset(model.static)?model.static:false);
	this.hotelClassName = (isset(model.hotelClassName)?model.hotelClassName:'');
	this.othersDisableCallendar = (isset(model.othersDisableCallendar)?model.othersDisableCallendar:false);
	this.othersDisableList = (isset(model.othersDisableList)?model.othersDisableList:false);
	this.containerHorisontal = (isset(model.containerHorisontal)?model.containerHorisontal:false);
	this.log = console.log;
	this.sort = 'priceASC';
	this.model = {
		descByPrice: false,
		sortType: 0
	};
	this.stat = {};
	this.currentSHash = (isset(model.currentSHash)?model.currentSHash:undefined);
	this.onHotelClickEvent = function() {
	};
	this.onNewHotel = (isset(model.onNewHotel)?model.onNewHotel:[]);
	this.onNewTour = (isset(model.onNewTour)?model.onNewTour:[]);
	this.onNewCheapestTour = (isset(model.onNewCheapestTour)?model.onNewCheapestTour:[]);
	this.ContainerLoader = null;
	this.SearchFormLoader = null;
	this.setLoadContainer = function() {
		self.log('setLoadContainer');
		self.elements.containerInner.classList.add('__load');
		if (isset(self.elements.pagination)&&self.elements.pagination) self.elements.pagination.hidden = true;
		if (!self.ContainerLoader) self.ContainerLoader = new Loader_({parent: self.elements.container});
		if (!self.SearchFormLoader) self.SearchFormLoader = new HorisontalLoader_({parent: document.getElementById('SearchForm'), windowWidth:true});
		self.ContainerLoader.start(localizationValues.Searching_more_tours+'...');
		setTimeout(function() {
			self.ContainerLoader.setDesc(localizationValues.Refreshing_prices+'...');
		}, 4000);
		setTimeout(function() {
			self.ContainerLoader.setDesc(localizationValues.Selecting_the_best_prices+'...');
		}, 8000);
		self.SearchFormLoader.start();
	};
	this.minPrice = (isset(model.minPrice)?model.minPrice:Number.MAX_SAFE_INTEGER);
	this.maxPrice = (isset(model.maxPrice)?model.maxPrice:Number.MIN_SAFE_INTEGER);
	this.minPriceHotel = null;
	this.maxPriceHotel = null;
	this.minPriceTour = null;
	this.maxPriceTour = null;
	this.setMinMaxPrice = function(tour) {
		if (self.minPrice>tour.model.price.redPriceUAH) {
			self.minPrice = tour.model.price.redPriceUAH;
			self.minPriceHotel = tour.Hotel;
			self.minPriceTour = tour;
		}
		if (self.maxPrice<tour.model.price.redPriceUAH) {
			self.maxPrice = tour.model.price.redPriceUAH;
			self.maxPriceHotel = tour.Hotel;
			self.maxPriceTour = tour;
		}
	};
	this.isDesc = false;
	this.setSort = function(sort) {
		if (!is_string(sort)||self.sort===sort) return false;
		self.sort = sort;
		switch (self.sort) {
			case 'priceDESC':
				self.model.sortType = 0;
			break;
			case 'ratingDESC':
				self.model.sortType = 1;
			break;
			case 'bestsDESC':
				self.model.sortType = 2;
			break;
			case 'priceASC':
				self.model.sortType = 0;
			break;
			case 'ratingASC':
				self.model.sortType = 1;
			break;
			case 'bestsASC':
				self.model.sortType = 2;
			break;
		}
		if (self.sort.indexOf('DESC')!=-1) {
			self.model.descByPrice = true;
			if (self.hotelsMode!='preview') {
				if (!self.elements.containerInner.classList.contains('__DESC')) self.elements.containerInner.classList.add('__DESC');
			}
			self.isDesc = true;
		} else if (self.sort.indexOf('ASC')!=-1) {
			self.model.descByPrice = false;
			if (self.hotelsMode!='preview') {
				if (self.elements.containerInner.classList.contains('__DESC')) self.elements.containerInner.classList.remove('__DESC');
			}
			self.isDesc = false;
		}
		self.readResults();
	};
	this.onSearchParamethersChange = function(parameterName, parametherValue, parametherChecked) {
		var stop = false;
		if (isset(self.onSearchParamethersChange__actions[parameterName])) {
			for (var actionName in self.onSearchParamethersChange__actions[parameterName]) {
				stop = self.onSearchParamethersChange__actions[parameterName][actionName](parametherValue, parametherChecked);
				if (stop===false) break;
			}
		}
	};
	this.onSearchParamethersChange__add = function(parameterName, actionName, func) {
		if (!isset(self.onSearchParamethersChange__actions[parameterName])) self.onSearchParamethersChange__actions[parameterName]={};
		if (isset(self.onSearchParamethersChange__actions[parameterName][actionName])) return;
		self.onSearchParamethersChange__actions[parameterName][actionName] = func;
	};
	this.onSearchParamethersChange__remove = function(parameterName, actionName) {
		if (!isset(self.onSearchParamethersChange__actions[parameterName])) return;
		if (!isset(self.onSearchParamethersChange__actions[parameterName][actionName])) return;
		delete self.onSearchParamethersChange__actions[parameterName][actionName];
	};
	this.onSearchParamethersChange__actions = {
		any: {}
	};
	this.sorterChangeEvent = function(e){
		e.preventDefault();
		self.setSort(e.currentTarget.value);
		return false;
	};
	this.sorterClickChildEvent = function(e){
		var el = e.currentTarget,
			current = el.getAttribute('current-value'),
			ord 	= el.getAttribute('value');
		if (current) {
			ord = ord.split('/');
			var index = ord.indexOf(current);
			if (index==(ord.length - 1)) {
				index = 0;
			} else {
				index++;
			}
			ord = ord[index];
			el.setAttribute('current-value', ord);
		}
		self.elements.sorting.value = ord;
		self.elements.sorting.dispatchEvent(new Event('change'));
		for (var i=(self.elements.sortingGroup.length - 1);i>=0;i--) self.elements.sortingGroup[i].classList.remove('__active');
		el.classList.add('__active');
	};
	this.init = function() {
		var i;
		self.elements.body = document.getElementById('body');
		self.elements.html = document.getElementById('html');
		self.elements.parent = document.getElementById(self.id);
		if (self.elements.parent) {
			self.elements.parent.classList.add('Catalog');
		}
		self.elements.container = document.getElementById([self.id,'__container'].join(''));
		self.elements.container.classList.add('Catalog__Container');
		if (self.containerHorisontal) {
			self.elements.container.classList.add('__horisontal');
		}
		self.elements.containerInner = self.elements.container.querySelector('.Catalog__Container__inner');
		self.elements.desc = document.getElementById([self.id,'__desc'].join(''));
		if (self.elements.desc) {
			self.elements.desc.classList.add('Catalog__Desc');
		}
		self.elements.sorting = document.getElementById([self.id,'__sorting'].join(''));
		if (self.elements.sorting) {
			self.elements.sorting.classList.add('Catalog__Sorting');
			var v = self.elements.sorting.value;
			self.setSort(v);
			self.elements.sorting.addEventListener('change', self.sorterChangeEvent);
		}
		self.elements.sortingGroup = document.getElementById([self.id,'__sortingGroup'].join(''));
		if (self.elements.sortingGroup) {
			self.elements.sortingGroup = self.elements.sortingGroup.querySelectorAll('button');
			for (i=(self.elements.sortingGroup.length - 1);i>=0;i--) {
				self.elements.sortingGroup[i].addEventListener('click', self.sorterClickChildEvent);
			}
		}
		self.elements.pagination = document.getElementById([self.id,'__pagination'].join(''));
		if (self.elements.pagination) {
			self.elements.pagination.classList.add('Catalog__Pagination');
			self.Pagination = new Pagination_(self, self.elements.pagination, self.paginatePage, null, 2, self.paginationHidden, true);
		}

		if (self.mobile) {
			self.elements.showSearchForm = document.getElementById([self.id, '__showSearchForm'].join(''));
			var modalPanel = new Far.Impl.Control.DropdownPanel('searchFormPanel');
			if (self.elements.showSearchForm) {
			    self.elements.showSearchForm.addEventListener('click', modalPanel.open);
			}
		}
		self.elements.filters = document.getElementById([self.id,'__filters'].join(''));
		if (self.elements.filters) {
			self.elements.filters.classList.add('Catalog__Filters');
		}
		self.elements.map = document.getElementById([self.id,'__map'].join(''));
		if (self.elements.map) {
			self.elements.map.classList.add('Catalog__Map');
			self.Map = new Catalog_Map_(self);
		}
		self.elements.minPricesContainer = document.getElementsByClassName([self.id,'__minPricesContainer'].join(''));
		self.elements.minPrices = document.getElementsByClassName([self.id,'__minPrices'].join(''));
		self.elements.minPricesM = document.getElementsByClassName([self.id,'__minPricesM'].join(''));
		self.elements.maxPricesContainer = document.getElementsByClassName([self.id,'__maxPricesContainer'].join(''));
		self.elements.maxPrices = document.getElementsByClassName([self.id,'__maxPrices'].join(''));
		self.elements.maxPricesM = document.getElementsByClassName([self.id,'__maxPricesM'].join(''));
		self.elements.hotelsCounters = document.getElementsByClassName([self.id,'__hotelsCounters'].join(''));
		self.elements.hotelsCountersM = document.getElementsByClassName([self.id,'__hotelsCountersM'].join(''));
		self.elements.toursCounters = document.getElementsByClassName([self.id,'__toursCounters'].join(''));
		self.elements.toursCountersM = document.getElementsByClassName([self.id,'__toursCountersM'].join(''));
		self.elements.currentRequestStatus = document.getElementsByClassName([self.id,'__currentRequestStatus'].join(''));
		if (!isset(model.Hotels)) model.Hotels = model.hotels;
		if (isset(model.Hotels)) {
			//setTimeout(function(){
				var hotelKey, SystemKey, hotel,
					len = model.hotels.length;
				for (i=0;i<len;i++) {
					hotelKey = model.Hotels[i].hotelKey;
					SystemKey = model.Hotels[i].SystemKey;
					hotel = (isset(self.Hotels[hotelKey])?self.Hotels[hotelKey]:null);
					if (hotel==null) {
						hotel = new Hotel(self, model.Hotels[i]);
						self.hotelsCount++;
						self.toursCount++;
					} else {
						hotel.addTour(model.Hotels[i], false);
						self.toursCount++;
					}
				}
			//}, 0);
		}
		if (self.isVersionWithLoader === false) {
			self.Start();
		}
	};
	this.paginatePage = function(pageIndex) {
		// self.initFilter(function(){
			window.scrollTo(0, self.elements.parent.offsetTop);
			self.settings.pageIndex = parseInt(pageIndex);
			self.readResults();
		// });
	};
	this.prepareModelForReaders = function() {
		var model = Object.assign({}, self.model),
			filterModel;
		if (isset(self.Filter)) {
			filterModel = self.Filter.getModel().sForm;
		} else {
			filterModel = Object.assign({}, self.filterModel);
		}
		for (var x in filterModel) model[x] = filterModel[x];
		model.pageSize = self.settings.itemsPerPage;
		model.pageIndex = self.settings.pageIndex;
		model.descByPrice = self.model.descByPrice;
		return model;
	};
	this.ajax__ReadResults = null;
	this.readResults = function(m, onRead, setLoadContainer) {
		self.requestsCount.start++;
		if (self.static) {
			self.Hotels = {};
			self.hotelsCount = 0;
			self.toursCount = 0;
			if (isset(self.Map)&&self.Map&&isset(self.Map.GM)&&self.Map.GM) self.Map.GM.storage.empty();
		}
		self.setLoadContainer();
		if (self.ajax__ReadResults) self.ajax__ReadResults.abort();
		var model = self.prepareModelForReaders();
		self.ajax__ReadResults = window.Far.Global.jsonRequest({
			method: 'POST',
			url: ['/',localization,'/catalog/static-tours'].join(''),
			onSuccess: function(response){
				if (response.statusCode==200) {
					self.requestsCount.success++;
					response = {
						data: {
							sResult: response.data.tourPackage.tours,
							hasMore: false,
							hasResult: true,
							totalItems: response.data.tourPackage.totalItems,
							hotelDescriptions: response.data.hotelDescription,
							hotelSpecialLinx: response.data.hotelSpecialLinx,
							minPrice: response.data.tourPackage.minPrice,
							maxPrice: 0,
							pageSize: (isset(response.data.tourPackage.pageSize)?response.data.tourPackage.pageSize:self.settings.itemsPerPage)
						}
					};
					self.useResults(response, onRead);
				} else {
					self.requestsCount.errors++;
				}
			},
			onError: function(){
				self.requestsCount.errors++;
			},
			data: model
		});
	};
	this.ajax__ReadStatistic = null;
	this.readStatistic__firstEntry = true;
	this.readStatistic = function() {
		if (self.ajax__ReadStatistic) self.ajax__ReadStatistic.abort();
		var sForm = self.prepareModelForReaders(),
			model = { sForm: sForm, firstEntry: self.readStatistic__firstEntry };
		self.ajax__ReadStatistic = window.Far.Global.jsonRequest({
			method: 'POST',
			url: ['/',localization,'/catalog/static-statistic'].join(''),
			onSuccess: function(response){
				if (response.statusCode==200) {
					if (isset(self.Filter)&&self.Filter) self.Filter.setBadges(response.data);
				}
			},
			onError: function(){},
			data: model
		});
		self.readStatistic__firstEntry = false;
	};
	this.useResults = function(response, onRead) {
		setTimeout(function(){
			self.parseResults(response.data, onRead);
		},0);
		if (response.data.hasMore) {
			setTimeout(self.nextResults, response.data.synkTime);
		} else {
			self.Stop();
		}
	};
	this.parseResults = function (data, onRead) {
		if (isset(data.pageSize)) self.settings.itemsPerPage = parseInt(data.pageSize);
		var len, m, i, hotel, hotelKey, SystemKey, hotelsListOrder = [], hotels_order = [];
		delete data.filter;
		if (isset(data.hotelDescriptions)&&data.hotelDescriptions) {
			for (hotelKey in data.hotelDescriptions) {
				self.hotelDescriptions[hotelKey] = data.hotelDescriptions[hotelKey];
			}
		}
		if (isset(data.hotelSpecialLinx)&&data.hotelSpecialLinx) {
			for (hotelKey in data.hotelSpecialLinx) {
				self.hotelSpecialLinx[hotelKey] = data.hotelSpecialLinx[hotelKey];
			}
		}
		len = (data.sResult?data.sResult.length:0);
		if (data.hasResult&&data.sResult&&len) {
			if (self.elements.parent&&self.elements.parent.classList.contains('__empty')) {
				self.elements.parent.classList.remove('__empty');
			}
			for (i=0;i<len;i++) {
				hotels_order.push(data.sResult[i].hotelKey);
				hotelKey = data.sResult[i].hotelKey;
				SystemKey = data.sResult[i].SystemKey;
				hotel = (isset(self.Hotels[hotelKey])?self.Hotels[hotelKey]:null);
				if (hotel==null) {
					hotel = new Hotel(self, data.sResult[i]);
					self.hotelsCount++;
					self.toursCount++;
					hotelsListOrder.push(data.sResult[i].hotelKey);
				} else {
					hotel.addTour(data.sResult[i]);
					self.toursCount++;
				}
			}
		}
		if (isset(self.Map)&&self.Map&&isset(self.Map.GM)&&self.Map.GM) self.Map.GM.onHotelsAdd();
		var updateTotals = false;
		if (isset(data.totalItems)) {
			if (data.totalItems!=-1) {
				updateTotals = true;
				self.settings.totalPagesCount = Math.ceil(data.totalItems / self.settings.itemsPerPage);
			}
		} else {
			updateTotals = true;
			self.settings.totalPagesCount = Math.ceil(self.hotelsCount / self.settings.itemsPerPage);
		}
		if (self.Pagination) {
			self.Pagination.render();
		}
		var v;
		if (updateTotals) {
			v = (isset(data.totalItems)?data.totalItems:self.hotelsCount);
			m = LL.getMethering('hotels', v);
			for (i = (self.elements.hotelsCounters.length - 1); i >= 0; i--) {
				var wrap = self.elements.hotelsCounters[i].closest('.hotelsCountersWrap');
				if (wrap) {
					wrap.style.visibility = 'visible';
				}
				self.elements.hotelsCounters[i].innerHTML = v;
			}
			for (i = (self.elements.hotelsCountersM.length - 1); i >= 0; i--) {
				self.elements.hotelsCountersM[i].innerHTML = m;
			}

			v = (isset(data.totalItems)?data.totalItems:self.toursCount);
			m = LL.getMethering('tours', v);
			for (i = (self.elements.toursCounters.length - 1); i >= 0; i--) {
				var wrap = self.elements.toursCounters[i].closest('.hotelsCountersWrap');
				if (wrap) {
					wrap.style.visibility = 'visible';
				}
				self.elements.toursCounters[i].innerHTML = v;
			}
			for (i = (self.elements.toursCountersM.length - 1); i >= 0; i--) {
				self.elements.toursCountersM[i].innerHTML = m;
			}
		}

		v = parseInt(isset(data.minPrice)?data.minPrice:self.minPrice);
		m = LL.getMethering('price', v);
		if (v>0) {
			for (i=(self.elements.minPricesContainer.length - 1);i>=0;i--) self.elements.minPricesContainer[i].hidden = false;
		} else {
			for (i=(self.elements.minPricesContainer.length - 1);i>=0;i--) self.elements.minPricesContainer[i].hidden = true;
		}
		v = intHumanize(v);
		for (i=(self.elements.minPrices.length - 1);i>=0;i--) self.elements.minPrices[i].innerHTML = v;
		for (i=(self.elements.minPricesM.length - 1);i>=0;i--) self.elements.minPricesM[i].innerHTML = m;

		v = (isset(data.maxPrice)?data.maxPrice:self.maxPrice);
		m = LL.getMethering('price', v);
		if (v>0) {
			for (i=(self.elements.maxPricesContainer.length - 1);i>=0;i--) self.elements.maxPricesContainer.hidden = false;
		} else {
			for (i=(self.elements.maxPricesContainer.length - 1);i>=0;i--) self.elements.maxPricesContainer.hidden = true;
		}
		v = intHumanize(v);
		for (i=(self.elements.maxPrices.length - 1);i>=0;i--) self.elements.maxPrices[i].innerHTML = v;
		for (i = (self.elements.maxPricesM.length - 1); i >= 0; i--) self.elements.maxPricesM[i].innerHTML = m;
		if (self.ContainerLoader) {
			self.ContainerLoader.stop();
		}
		if (self.SearchFormLoader) {
			self.SearchFormLoader.stop();
		}
		self.renderPage(undefined, undefined, undefined, undefined, (self.hotelsMode == 'preview' ? hotels_order : undefined), onRead);
	};
	this.loadContainer = function(a) {
		if (self.elements.parent) {
			if (a) {
				self.elements.parent.classList.add('__load');
			} else {
				self.elements.parent.classList.remove('__load');
			}
		}
	};
	this.startNewSchema = function (onResult, onRead) {
		self.requestsCount.start++;
		if (self.static) {
			self.Hotels = {};
			self.hotelsCount = 0;
			self.toursCount = 0;
			if (isset(self.Map) && self.Map && isset(self.Map.GM) && self.Map.GM) self.Map.GM.storage.empty();
		}
		if (self.ajax__ReadResults) self.ajax__ReadResults.abort();
		var model = self.prepareModelForReaders();
		self.ajax__ReadResults = window.Far.Global.jsonRequest({
			method: 'POST',
			url: ['/', localization, '/catalog/static-tours'].join(''),
			onSuccess: function (response) {
				if (response.statusCode == 200) {
					self.requestsCount.success++;
					response = {
						data: {
							sResult: response.data.tourPackage.tours,
							hasMore: false,
							hasResult: true,
							totalItems: response.data.tourPackage.totalItems,
							hotelDescriptions: response.data.hotelDescription,
							hotelSpecialLinx: response.data.hotelSpecialLinx,
							minPrice: response.data.tourPackage.minPrice,
							maxPrice: 0,
							pageSize: (isset(response.data.tourPackage.pageSize) ? response.data.tourPackage.pageSize : self.settings.itemsPerPage)
						}
					};
					var filteredTours = onResult(response);
					if (filteredTours.length) {
						response.data.sResult = filteredTours;
						self.useResults(response, onRead);
					}
				}
				else {
					self.requestsCount.errors++;
				}
			},
			onError: function () {
				self.requestsCount.errors++;
			},
			data: model
		});
	};
	this.Start = function() {
		//self.log('Start');
		if (self.elements.parent) {
			self.loadContainer(true);
			self.elements.parent.classList.add('__empty');
		}
		for (var i=(self.elements.currentRequestStatus.length - 1);i>=0;i--) {
		    self.elements.currentRequestStatus[i].innerHTML = localizationValues.still_searching;
		}
		setTimeout(self.readResults, 500);
	};
	this.Stop = function() {
		self.log('Stop');
		for (var i=(self.elements.currentRequestStatus.length - 1);i>=0;i--) {
		    self.elements.currentRequestStatus[i].innerHTML = localizationValues.end_searching;
		}
		self.loadContainer(false);
	};
	this.nextResults = function() {
		self.log('nextResults');
		self.resultsPage++;
		self.readResults();
	};
	this.emptyContainer = function() {
		self.log('emptyContainer');
		self.hotelsRendered = [];
		if (isset(self.elements.pagination)&&self.elements.pagination) self.elements.pagination.hidden = false;
		self.elements.containerInner.classList.remove('__load');
		self.elements.parent.classList.add('__empty');
		removeChilds(self.elements.containerInner);
	};
	this.initFilter = function(callback) {
		if (!isset(self.Filter)||!self.Filter) {
			window.FilterPanel.mount(self.initFilterModel._impl, self.initFilterModel._options);
			window.FilterPanel.onReady(callback);
		} else {
			callback();
		}
	};
	this.sortFuncs = {
		priceDESC: function(a,b) {return a.lastCheapestTour.model.price.redPriceUAH - b.lastCheapestTour.model.price.redPriceUAH;},
		priceASC: function(a,b) {return b.lastCheapestTour.model.price.redPriceUAH - a.lastCheapestTour.model.price.redPriceUAH;},
		ratingDESC: function(a,b) {return a.model.rating - b.model.rating;},
		ratingASC: function(a,b) {return b.model.rating - a.model.rating;},
		bestsDESC: function(a,b) {return a.lastCheapestTour.model.price.redPriceUAH - b.lastCheapestTour.model.price.redPriceUAH;},
		bestsASC: function(a,b) {return b.lastCheapestTour.model.price.redPriceUAH - a.lastCheapestTour.model.price.redPriceUAH;}
	};
	this.getSortedHotels = function() {
		var hotels = Object.values(self.Hotels),
			new_hotels = [], i;
		switch (self.sort) {
			case 'priceDESC':
				hotels.sort(self.sortFuncs.priceDESC);
			break;
			case 'priceASC':
				hotels.sort(self.sortFuncs.priceASC);
			break;
			case 'ratingDESC':
				hotels.sort(self.sortFuncs.ratingDESC);
			break;
			case 'ratingASC':
				hotels.sort(self.sortFuncs.ratingASC);
			break;
			case 'bestsDESC':
				for (i=(hotels.length - 1);i>=0;i--) if (hotels[i].lastCheapestTour.model.is.choiceFarvater) new_hotels.push(hotels[i]);
				new_hotels.sort(self.sortFuncs.bestsDESC);
				hotels = new_hotels;
			break;
			case 'bestsASC':
				for (i=(hotels.length - 1);i>=0;i--) if (hotels[i].lastCheapestTour.model.is.choiceFarvater) new_hotels.push(hotels[i]);
				new_hotels.sort(self.sortFuncs.bestsASC);
				hotels = new_hotels;
			break;
		}
		return hotels;
	};
	this.hotelsRendered = [];
	this.renderFirstPage = function(hotelsListOrder) {
		self.renderPage(undefined, undefined, undefined, (self.settings.itemsPerPage - self.hotelsRendered.length), hotelsListOrder);
	};
	this.renderPage = function(page, callbackBefore, callbackAfter, renderHotelsCount, hotelsListOrder, onRead) {
		if (isset(callbackBefore)) callbackBefore();
		renderHotelsCount = (!isset(renderHotelsCount)?Number.MAX_SAFE_INTEGER:renderHotelsCount);
		var hotels = [], i, el, len;
		if (isset(hotelsListOrder)&&hotelsListOrder&&hotelsListOrder.length) {
			len = hotelsListOrder.length;
			for (i=0;i<len;i++) {
				hotels.push(self.Hotels[hotelsListOrder[i]]);
			}
		} else {
			var sortedHotels = self.getSortedHotels();
			len = sortedHotels.length;
			for (i=0;i<len;i++) {
				if (i>=self.settings.itemsPerPage) {
					if (hotels.length>=self.settings.itemsPerPage||renderHotelsCount<=0) continue;
				}
				if (self.hotelsRendered.indexOf(sortedHotels[i].model.key)!==-1) continue;
				hotels.push(sortedHotels[i]);
				renderHotelsCount--;
			}
		}
		var currentlyRendered 	= 0,
			position 			= Number.MAX_SAFE_INTEGER,
			fragment 			= document.createDocumentFragment();
		for (i=0;i<hotels.length;i++) {
			hotels[i].render();
			el = hotels[i].element;
			fragment.appendChild(el);
			self.hotelsRendered.push(hotels[i].model.key);
			self.insertedHotels++;
			currentlyRendered++;
			if (isset(self.SEOBlocksItems) && self.SEOBlocksItems.length) {
				position = (position>hotels[i].lastCheapestTour.model.price.redPriceUAH?hotels[i].lastCheapestTour.model.price.redPriceUAH:position);
				switch (currentlyRendered) {
					case 10:
						if (isset(self.SEOBlocksItems[1])) {
							if (self.hotelsMode!='preview') {
								self.SEOBlocksItems[1].style.order = position;
							}
							fragment.appendChild(self.SEOBlocksItems[1]);
						}
					break;
					case 5:
						if (isset(self.SEOBlocksItems[0])) {
							if (self.hotelsMode!='preview') {
								self.SEOBlocksItems[0].style.order = position;
							}
							fragment.appendChild(self.SEOBlocksItems[0]);
						}
					break;
				}
			}
		}
		self.emptyContainer();
		var f = function() {
			self.elements.containerInner.appendChild(fragment);
			if (typeof onRead === 'function') {
				onRead();
			}
			if (self.lazyLoad) {
				setTimeout(function(){
					for (var i=(hotels.length - 1);i>=0;i--) {
						if (!isset(hotels[i].element._img)||!hotels[i].element._img||!isset(hotels[i].element._img.lazy)||!hotels[i].element._img.lazy) continue;
						hotels[i].element._img.lazy.precheck();
					}
				}, 500);
			}
		};
		requestAnimationFrame(f, self.elements.containerInner);
		if (isset(callbackBefore)) callbackAfter();
	};
	this.urlController = new UrlController_({
		pathSeparator: this.CatalogPathSeparator
	});
	this.init();
}




function Country_(model) {
	var self = this;

	this.model = {
		position: {}
	};

	this.resorts = {};

	this.init = function(model) {
		self.model.id 					= parseInt(model.id||model.Id||0);
		self.model.alpha_2 				= (isset(model.alpha_2)?model.alpha_2.toUpperCase():'');
		self.model.IsEUR 				= (isset(model.IsEUR)?model.IsEUR:undefined);
		self.model.CheckIn 				= (isset(model.CheckIn)?new Date(model.CheckIn):undefined);
		self.model.PreRenderSlayders 	= (isset(model.PreRenderSlayders)?model.PreRenderSlayders:undefined);
		self.model.position.latitude 	= (isset(model.latitude)?parseFloat(model.latitude):0);
		self.model.position.longitude 	= (isset(model.longitude)?parseFloat(model.longitude):0);
		self.model.name 				= (isset(model.name)?model.name:'');
		self.model.parentRegionName 	= (isset(model.parentRegionName)?model.parentRegionName:'');
		self.model.show 				= (isset(model.show)?model.show:0);
		self.model.slug 				= (isset(model.slug)?model.slug:'');
	};
	this.init(model);
}

function Resort_(model) {
	var self = this;

	this.model = {
		position: {}
	};

	this.init = function(model) {
		self.model.id 					= parseInt(model.id||model.Id||0);
		self.model.CountryId 			= (isset(model.CountryId)?model.CountryId:0);
		self.model.name 				= (isset(model.Name)?model.Name:'');
		self.model.NameHash				= (isset(model.NameHash)?model.NameHash:0);
		self.model.RegionId 			= (isset(model.RegionId)?model.RegionId:0);
		self.model.Status 				= (isset(model.Status)?model.Status:0);
		self.model.UrlPart 				= (isset(model.UrlPart)?model.UrlPart:'');
		self.model.UrlPartHash 			= (isset(model.UrlPartHash)?model.UrlPartHash:0);
		self.model.position.latitude 	= (isset(model.latitude)?parseFloat(model.latitude):0);
		self.model.position.longitude = (isset(model.longitude) ? parseFloat(model.longitude) : 0);
		self.model.SearchInRegion = model.SearchInRegion === true ? true : false;

	};
	this.init(model);
}

function Airport_(model) {
	var self = this;

	this.model = {};

	this.init = function(model) {
		self.model.id 					= parseInt(model.id||model.Id||0);
		self.model.airportCode 			= (isset(model.airportCode)?model.airportCode:'');
		self.model.enname 				= (isset(model.enname)?model.enname:'');
		self.model.name 				= (isset(model.name)?model.name:'');
		self.model.translitName 		= (isset(model.translitName)?model.translitName:'');
	};
	this.init(model);
}

function Operator_(model) {
	var self = this;

	this.model = {};

	this.init = function(model) {
		model = parseInt(model);
		self.model.id = model;
	};
	this.init(model);
}


function Star_(model) {
	var self = this;

	this.model = {};

	this.init = function(model) {
		model = parseInt(model);
		self.model.id = model;
		self.model.int = starIdToInt(model);
		self.model.element = starsRender(self.model.int);
		self.model.name = starIdToName(model);
		self.model.localizedName = starIdToLocalizedName(model);
	};
	this.init(model);
}

function starsRender(v) {
    if (isNaN(v)||v<1) return '';
    var html = [];
    html.push('<span class="stars">');
    html.push(starsRenderInner(v));
    html.push('</span>');
    return html.join('');
}

function starsRenderInner(v) {
    if (isNaN(v)||v<1) return '&nbsp;';
    var html = [],
        i = 5;
    while (v>0) {
        html.push('');
        v--;
        i--;
    }
    while (i>0) {
        html.push('');
        i--;
    }
    return html.join('');
}

function starIdToInt(v) {
	var i;
	switch (v) {
		case '0':
		case 0:
			i=1;
		break;
		case '1':
		case 1:
			i=2;
		break;
		case '3':
		case 3:
			i=3;
		break;
		case '4':
		case 4:
			i=4;
		break;
		case '7':
		case 7:
		default:
			i=5;
		break;
	}
	return i;
}



function starIdToName(v) {
	var i;
	switch (v) {
		case '0':
		case 0:
			i=1;
		break;
		case '1':
		case 1:
			i=2;
		break;
		case '3':
		case 3:
			i=3;
		break;
		case '4':
		case 4:
			i=4;
		break;
		case '7':
		case 7:
			i=5;
		break;
		case '9':
		case 9:
			i='HV 2';
		break;
		case '10':
		case 10:
			i='VILLA';
		break;
		case '11':
		case 11:
			i='HV 1';
		break;
		case '12':
		case 12:
			i='APP';
		break;
	}
	return i;
}

function starIdToLocalizedName(v) {
	var i;
	switch (v) {
		case '0':
		case 0:
			i=starsRenderInner(1);
		break;
		case '1':
		case 1:
			i=starsRenderInner(2);
		break;
		case '3':
		case 3:
			i=starsRenderInner(3);
		break;
		case '4':
		case 4:
			i=starsRenderInner(4);
		break;
		case '7':
		case 7:
			i=starsRenderInner(5);
		break;
		case '9':
		case 9:
			i=localizationValues.hv2_stars;
		break;
		case '10':
		case 10:
			i=localizationValues.villa_stars;
		break;
		case '11':
		case 11:
			i=localizationValues.hv1_stars;
		break;
		case '12':
		case 12:
			i=localizationValues.app_stars;
		break;
	}
	return i;
}


function Meal_(model) {
	var self = this;

	this.model = {};

	this.init = function(model) {
		model = parseInt(model);
		self.model.id = model;
		self.model.name = mealIdToName(model);
		self.model.localizedName = mealIdToLocalizedName(model);
	};
	this.init(model);
}

function getShortMeal(v) {
    var s = v,
    	m = v.match(/\((.*?)\)/);
	if (m) s = m[1];
	return s;
}

function mealIdToName(v) {
	var i;
	switch (v) {
		case '0':
		case 0:
			i='BB';
		break;
		case '1':
		case 1:
			i='AI';
		break;
		case '2':
		case 2:
			i='UAI';
		break;
		case '4':
		case 4:
			i='FB';
		break;
		case '5':
		case 5:
			i='HB';
		break;
		case '6':
		case 6:
			i='ro';
		break;
	}
	return i;
}

function mealIdToLocalizedName(v) {
	var i;
	switch (v) {
		case '0':
		case 0:
			i=localizationValues.BB;
		break;
		case '1':
		case 1:
			i=localizationValues.AI;
		break;
		case '2':
		case 2:
			i=localizationValues.UAI;
		break;
		case '4':
		case 4:
			i=localizationValues.FB;
		break;
		case '5':
		case 5:
			i=localizationValues.HB;
		break;
		case '6':
		case 6:
			i=localizationValues.ro;
		break;
	}
	return i;
}


jsV4SEOcatalog.ready(true);
