(function(exports) {
	let request_data = []
	let autoupdate = true
	let get_data_xhr = new XMLHttpRequest()
	let set_data_xhr = new XMLHttpRequest()
	let timeoutHandle
	let response_values = []
	let current_request_index = 0
	let on_window = true
	let access_control = ""

	exports.board_types = {
		reserved: 0,
		hdi: 1,
		di: 2,
		ai: 3,
		cti: 4,
		rtd: 5,
		vi: 6,
		ti: 19,
		ao2: 7,
		ro: 8,
		hdo: 9,
		io1: 10,
		hdi_5: 11,
		f_lcd: 13,
		f_io: 14,
		em_h: 16,
		em_l: 17,
		io3: 18,
		ao4: 20,
		hcr12f_cti: 64,
		hcr12f_hdo_di: 160,
		hcr12f_a_mb: 193,
		hcr12f_d_mb: 194,
		deleted: 255
	}

	exports.change_autoupdate = function (state)
	{
		autoupdate = state;
	}

	exports.set_expert_page_configuration = function ()
	{
		configuration = configuration_expert;
	}

	exports.set_request_data = function (data)
	{
		request_data = data;
	}

	exports.timeHHmm = function (datetime)
	{
		var hours = datetime.getUTCHours()
		var minutes = datetime.getUTCMinutes();
		if (hours <= 9) {
			hours = "0" + hours;
		}
		if (minutes <= 9) {
			minutes = "0" + minutes;
		}
		return `${hours}:${minutes}`
	}

	exports.timeHHmmss = function (datetime)
	{
		var hours = datetime.getUTCHours()
		var minutes = datetime.getUTCMinutes();
		var seconds = datetime.getUTCSeconds();
		if (hours <= 9) {
			hours = "0" + hours;
		}
		if (minutes <= 9) {
			minutes = "0" + minutes;
		}
		if (seconds <= 9) {
			seconds = "0" + seconds;
		}
		return `${hours}:${minutes}:${seconds}`
	}

	exports.dateYYYYMMDD = function (datetime)
	{
		var year = datetime.getUTCFullYear()
		var month = datetime.getUTCMonth();
		var date = datetime.getUTCDate();

		month += 1
		if (month <= 9) {
			month = "0" + month;
		}
		if (date <= 9) {
			date = "0" + date;
		}
		return `${year}-${month}-${date}`
	}

	function get_label_control_tr(name, label, control)
	{
		control.addClass('mbtcp_client').addClass(name)

		let tr = $('<tr>').addClass(`${name}_tr`)
		let label_td = $('<td>').append(label)
		let control_td = $('<td>').append(control).addClass(`${name}_td`)

		tr.append(label_td).append(control_td)
		return tr
	}

	exports.get_cell = function (key, class_type="")
	{
		let form = $('<form>').addClass('apply_form')
		if ((request_data[key] != null) &&
			(request_data[key].DataType != null) &&
			(request_data[key].AccessType != null))
		{
			//console.log("key:"+key)
			let index = request_data[key].index.replace(":","_")
			let apply_input = $('<input type="text">')
			let apply_button = $('<div>')

			let template_object
			let template = ""
			let commands

			let label
			let title //hint message
			let without_button = false

			let searchParams = new URLSearchParams(location.search)
			let raw_data = searchParams.get("raw_data")
			if (raw_data === null)
			{
				$.each(configuration.data_type_template().templates, function(template_index_, template_item_)
				{
					if (template_item_.index === index)
					{
						template_object = template_item_
						if (template_item_.template != null)
						{
							template = template_item_.template
							commands = template_item_.commands
						}
						return false //break
					}
				})
			}

			if (template == "")
			{
				apply_input.addClass(request_data[key].DataType);
			}
			else if (template == "password")
			{
				apply_input.attr({'type':'password'});
				label = $('<label style="display:block">')
				label.append($('<input type="checkbox">').addClass('password_checkbox'))
				label.append($('<label>').text(l100n.localize_string("show_password")))
				//form.append(label)
			}
			else if (template == "combobox" || template == "control_mode" || template == "one_wire_sensors")
			{
				apply_input = $('<select>')
				$.each(commands, function(commands_index, command_item)
				{
					var option = $('<option>')
					option.val(command_item.command)
					option.text(command_item.name)
					apply_input.append(option)
				})
			}
			else if (template == "module_types")
			{
				apply_input = $('<select>')
				apply_input.addClass('need_restart')
				$.each(commands, function(commands_index, command_item)
				{
					if (command_item.command == "13")
					{
						//option.attr('disabled','true')
						return;
					}
					var option = $('<option>')
					option.val(command_item.command)
					option.text(command_item.name);
					apply_input.append(option)
				})
			}
			else if (template == "datetime"  && !class_type.includes("ro"))
			{
				let date_input = $('<input type="text">');
				date_input.attr({"id":"date_input"}).mask('0000-00-00');
				date_input.addClass('datetime');
				date_input.datepicker()
				form.append(date_input);

				apply_input.attr({"id":"time_input"}).mask("99:99:99");
			}
            else if (template == "consumer_heartbeat")
			{
				let hbconsumer_input = $('<input type="text">')
				let node_key = `node_input_${key}`
				let time_key = `hb_time_input_${key}`

				hbconsumer_input.addClass('consumer_heartbeat')
				hbconsumer_input.addClass('consumer_heartbeat_node')
				hbconsumer_input.attr({"id": node_key})
				form.append(hbconsumer_input);

				apply_input.attr({"id": time_key});
			}
			else if (template == "mbtcp_client")
			{
				let table = $('<table>').addClass('mbtcp_client_table')
				/*let header = $(`<tr class="table_header"><td colspan="2">${l100n.localize_string("hl_Line Flags")}</td></tr>`)
				table.append(header)*/

				let close_socket_input = $('<input type="checkbox">').addClass('mbtcp_client')
				table.append(get_label_control_tr('mbtcp_client_cs', 'close_socket', close_socket_input))

				let timeout_input = $('<input type="text">').addClass('mbtcp_client')
				table.append(get_label_control_tr('mbtcp_client_timeout', 'timeout', timeout_input))

				let port_input = $('<input type="text">').addClass('mbtcp_client').addClass('uint16')
				table.append(get_label_control_tr('mbtcp_client_port', 'port', port_input))

				let ip_input = $('<input type="text">').addClass('mbtcp_client')
				table.append(get_label_control_tr('mbtcp_client_ip', 'ip', ip_input))

				form.append(table)
				apply_input.hide()
			}
			else if (template == "mbtcp_client_status")
			{
				let table = $('<table>').addClass('mbtcp_client_status_table')

				let connection_status = $('<input type="checkbox">').addClass('mbtcp_client_status').attr('disabled', 'disabled')
				table.append(get_label_control_tr('mbtcp_client_status_connection', 'connection_status', connection_status))

				let tls_status = $('<input type="text">').addClass('mbtcp_client_status').attr('disabled', 'disabled')
				table.append(get_label_control_tr('mbtcp_client_status_tls', 'tls_status', tls_status))

				let timeout = $('<input type="text">').addClass('mbtcp_client_status').attr('disabled', 'disabled')
				table.append(get_label_control_tr('mbtcp_client_status_timeout', 'timeout', timeout))

				let port = $('<input type="text">').addClass('mbtcp_client_status').addClass('uint16').attr('disabled', 'disabled')
				table.append(get_label_control_tr('mbtcp_client_status_port', 'port', port))

				let misconfig = $('<input type="text">').addClass('mbtcp_client_status').attr('disabled', 'disabled')
				table.append(get_label_control_tr('mbtcp_client_status_misconfig', 'misconfig', misconfig))

				form.append(table)
				apply_input.hide()
			}
            else if (template == "pdo_mapping")
			{
				let index_input = $('<input type="text">')
				let index_key = `index_input_${key}`
				index_input.addClass('pdo_mapping')
				index_input.addClass('pdo_mapping_index')
				
				index_input.attr( {"id": index_key})

				let subi_input = $('<input type="text">')
				let subindex_key = `subindex_input_${key}`
				subi_input.addClass('pdo_mapping')
				subi_input.addClass('pdo_mapping_subindex')
				
				subi_input.attr( {"id": subindex_key})

				form.append(index_input)
				form.append(subi_input)

				size_key = `size_input_${key}`
				apply_input.attr({"id": size_key})
			}
			else if (template == "pdo_cob_id")
			{
				let enable_input = $('<select>')
				$.each(template_object.enable, function(commands_index_, command_item_)
				{
					let option = $('<option>')
					option.val(command_item_.command)
					option.text(command_item_.name)
					enable_input.append(option)
				})
				enable_key = `enable_input_${key}`
				enable_input.addClass('pdo_cob_id')
				enable_input.addClass('pdo_cob_id_enable')
				enable_input.attr({"id": enable_key})
				form.append(enable_input)

				let message_input = $('<select>')
				$.each(template_object.messages, function(commands_index_, command_item_)
				{
					let option = $('<option>')
					//console.log(command_item_.command)
					option.val(command_item_.command)
					option.text(command_item_.name)
					if (command_item_.command === "default")
					{
						option.prop( "disabled", true )
					}
					message_input.append(option)					 
				})
				let message_key = `message_input_${key}`
				message_input.addClass('pdo_cob_id')
				message_input.addClass('pdo_cob_id_message')
				message_input.attr( {"id": message_key});			
				form.append(message_input)

				let node_id_key = `node_id_input_${key}`
				apply_input.attr( {"id": node_id_key})
				apply_input.addClass("1-127")

				let error_label = $(`<label>Please enter PDO COB ID message</label>`)
				error_label.attr({"id": `error_label_${key}`})
				error_label.hide()
				form.append(error_label)
			}
			else if (template == "line_flags")
			{
				//let div = $('<div>').append(l100n.localize_string("hl_Line Flags"))
				//form.append(div)
				let table = $('<table>').addClass('line_flags_table')
				
				let header = $(`<tr class="table_header"><td colspan="2">${l100n.localize_string("hl_Line Flags")}</td></tr>`)
				table.append(header)
				let voltage_tr = $('<tr>').addClass('line_flags_voltage_tr')
				let voltage_label = $('<td>').append(l100n.localize_string("hl_voltage_for_line"))
				let voltage_input_td = $('<td>').addClass('line_flags_voltage_td')
				let voltage_input = $('<select>')
				$.each(template_object.voltage, function(commands_index_, command_item_)
				{
					let option = $('<option>')
					option.val(command_item_.command)
					option.text(command_item_.name)
					voltage_input.append(option)
				})
				voltage_input.addClass('line_flags')
				voltage_input.addClass('line_flags_voltage')
				voltage_input_td.append(voltage_input)
				voltage_tr.append(voltage_label).append(voltage_input_td)
				table.append(voltage_tr)

				//form.append(voltage_input)

				let no_nc_tr = $('<tr>').addClass('line_flags_no_nc_tr')
				let no_nc_label = $('<td>').append(l100n.localize_string("hl_no_nc"))
				let no_nc_input_td = $('<td>').addClass('line_flags_no_nc_td')
				//let no_nc_input = $('<input type="checkbox">')
				let no_nc_input = $('<select>')
				$.each(template_object.no_nc, function(commands_index_, command_item_)
				{
					let option = $('<option>')
					option.val(command_item_.command)
					option.text(command_item_.name)
					no_nc_input.append(option)
				})
				no_nc_input.addClass("line_flags_no_nc")
				no_nc_input.addClass('line_flags')
				no_nc_input_td.append(no_nc_input)
				no_nc_tr.append(no_nc_label).append(no_nc_input_td)
				table.append(no_nc_tr)

				let pwm_tr = $('<tr>').addClass('line_flags_pwm_tr')
				let pwm_label = $('<td>').append(l100n.localize_string("hl_pwm"))
				let pwm_input_td = $('<td>').addClass('line_flags_pwm_td')
				//let pwm_input = $('<input type="checkbox">')
				let pwm_input = $('<select>')
				$.each(template_object.pwm, function(commands_index_, command_item_)
				{
					let option = $('<option>')
					option.val(command_item_.command)
					option.text(command_item_.name)
					pwm_input.append(option)
				})
				pwm_input.addClass("line_flags_pwm")
				pwm_input.addClass('line_flags')
				pwm_input_td.append(pwm_input)
				pwm_tr.append(pwm_label).append(pwm_input_td)
				table.append(pwm_tr)
				

				apply_input = $('<input type="checkbox">').hide()
				//apply_input.addClass('line_flags_pwm')
				form.append(table)
			}
			else if (template == "bit_checkboxes")
			{
				//let table = $('<table>').addClass('bit_checkboxes_table')
				//let header = $(`<tr class="table_header"><td colspan="2">${template_object.header}</td></tr>`)
				//table.append(header)

				for (let number = 0; number < template_object.count; number++)
				{
					//let tr = $('<tr>').addClass(`bit_checkboxes_tr`)
					//let label = $('<td>').append(`bit ${number}`)
					//let input_td = $('<td>').addClass(`bit_checkboxes_td`)
					let input = $('<input type="checkbox">')
	
					input.addClass(`bit_checkboxes_ctrl`)
					input.addClass('bit_checkboxes')
					//input_td.append(input)
					//tr.append(label).append(input_td)
					//table.append(tr)
					form.append(input)
					if (template_object.ro)
					{
						input.attr('disabled', 'disabled')
					}
				}
				apply_input = $('<input type="checkbox">').hide()
				
				if (template_object.ro)
				{
					without_button = true
				}
				//form.append(table)
			}
			else if (template == "date")
			{
				apply_input.attr({"id":"date_input"})
			}
			else if (template == "restore_params")
			{
				title = l100n.localize_string("Restore_params_hint")
			}
			else if (template == "mcuf_sensor_select")
			{
				let module_input = $('<select>')
				$.each(template_object.modules, function(commands_index_, command_item_)
				{
					let option = $('<option>')
					option.val(command_item_.command)
					option.text(command_item_.name);
					module_input.append(option)
				})

				apply_input = $('<select>')
				$.each(template_object.sensors, function(commands_index_, command_item_)
				{
					let option = $('<option>')
					option.val(command_item_.command)
					option.text(command_item_.name)
					apply_input.append(option)
				})

				//let module_input = $('<input type="text">')
				module_input.addClass('mcuf_module_select')
				form.append(module_input)
			}
			

			if (class_type.includes("boolean_input"))
			{
				apply_input = $('<label><span></span></label>').addClass("boolean_input")
			}
			else if (class_type.includes("boolean_output"))
			{
				apply_input = $('<label><span></span></label>').addClass("boolean_output")
			}
			else if (class_type.includes("boolean_alarm"))
			{
				apply_input = $('<label><span></span></label>').addClass("boolean_alarm")
			}
			else if (without_button)
			{
				
			}
			else if (request_data[key].AccessType.includes('ro') 
				|| class_type.includes("ro"))//read only
			{
				if (request_data[key].DataType == "bool" || request_data[key].DataType == "boolean_type" || template == "boolean_type")
				{
					apply_input = $('<label><span></span></label>').addClass("readonly_cb")
				}
				else if (template == "datetime")
				{
					template = ""

					let date_input = $('<div>').attr({"tabindex":"0"})
					date_input.attr({"id":"date_show"})
					form.append(date_input)
					form.append('\u00a0\u00a0')
					apply_input = $('<div>').attr({"tabindex":"0"})
					apply_input.attr({"id":"time_show"}).addClass('datetime_show')
				}
				else
				{
					apply_input = $('<div>').attr({"tabindex":"0"});
				}
			}
			else if (request_data[key].AccessType.includes('w')) //write
			{
				if (request_data[key].DataType == "bool" || request_data[key].DataType == "boolean_type" || template == "boolean_type")
				{
					apply_input = $('<input type="checkbox">').addClass("edit_cb").attr({"index":index})
				}
				else
				{
					apply_button = $('<input type="submit">').addClass('item_edit_b');
					apply_button.attr({"index":index});
					apply_button.val(l100n.localize_string("apply_button"));
				}

				apply_input.addClass('item_edit_textbox');
			}

			if (request_data[key].AccessType.includes('r'))   //read
			{
				apply_input.addClass('value');
			}
		
			if (template_object != null)
			{
				if (template_object.class != null)
				{
					//console.log(template_object.class)
					apply_input.addClass(template_object.class)
				}
			}

			apply_input.addClass(template);
			apply_input.attr({"tb_index":index});

			form.attr({"index":index});
			//form.attr({"id":index});
			form.append(apply_input);
			form.append(apply_button);


			if (label !== null)
			{
				form.append(label);
			}
			if (title !== null)
			{
				apply_input.attr('title', title)
			}

			form.validate();
		}
		else
		{
			form.addClass('empty')
		}

		return form;
	}

	exports.send_query = function()
	{
		var query;
		var j = 0;

		window.clearTimeout(timeoutHandle);
		if ((request_data.length > 0) && (current_request_index < request_data.length) && (j < configuration.response_lenght()))
		{
			query = '/get_od_data.form?';
			var has_request = false;
			for (;;)
			{
				if ((current_request_index >= request_data.length) || (j >= configuration.response_lenght()))
				{
					break;
				}

				//console.log(request_data[current_request_index])
				if (request_data[current_request_index] != null)
				{
					if (request_data[current_request_index].AccessType != null)
					{
						if (request_data[current_request_index].AccessType.includes('r')) //read
						{
							//if (request_data[current_request_index].index != null)
							if ((current_request_index > 0) && (j > 0))
				    		{
				    			query += "&";
				    		}
							has_request = true;
							query += "0x" + request_data[current_request_index].index.replace(":","_");
							j++;
						}
					}
				}

				current_request_index++;
			}

			if (has_request == false)
			{
				query = '';
			}
			get_data_xhr.open('GET', query, true);
			get_data_xhr.send();
		}
		//console.log(query);
	}


// Parse index 1003 Error fiels
	function error_field_parser(error_code)
	{
        if (error_code == 0) {
    		return 'None';
        }
        else if((error_code & 0x0000F000) == 0x00007000) {
            var number = error_code & 0x0000000F;
            var sub_code = (error_code & 0xFFFF0000) >> 16;
            return `Module ${number}. Code 0x${sub_code.toString(16).toUpperCase()}. (${error_code})`;
        }
        else if((error_code & 0x0000FFFF) == 0x00006240) {
            var index = (error_code >> 16) & 0xFFFF;
            return `AppSW. Access to index 0x${index.toString(16).toUpperCase()}. (${error_code})`;
        } else if((error_code & 0x0000FFFF) == 0x00006241) {
            var index = (error_code >> 16) & 0xFFFF;
            return `AppSW. Access to subindex of index 0x${index.toString(16).toUpperCase()}. (${error_code})`;
        } else if((error_code & 0x0000FFFF) == 0x00006242) {
            var index = (error_code >> 16) & 0xFFFF;
            return `AppSW. Access (read) to index 0x${index.toString(16).toUpperCase()}. (${error_code})`;
        } else if((error_code & 0x0000FFFF) == 0x00006243) {
            var index = (error_code >> 16) & 0xFFFF;
            return `AppSW. Access (write) to index 0x${index.toString(16).toUpperCase()}. (${error_code})`;
        } else if((error_code & 0x0000FFFF) == 0x00006220) {
            return `AppSW. Internal error. (${error_code})`;
        } else if((error_code & 0x0000FFFF) == 0x00006221) {
            return `AppSW. Firmware CRC. (${error_code})`;
        }
        else if((error_code & 0x0000FFFF) == 0x00006222) {
            return `AppSW. Firmware size. (${error_code})`;
        }
        else if((error_code & 0x0000FFFF) == 0x00006223) {
            return `AppSW. Device signature. (${error_code})`;
        }
        else if((error_code & 0x0000FFFF) == 0x00006224) {
            return `AppSW. Memory map. (${error_code})`;
        }
        else if((error_code & 0x00003203) == 0x00003203) {
            return `Battery. (${error_code})`;
        }
        else if((error_code & 0x0000500A) == 0x0000500A) {
            return `Real Time Clock. (${error_code})`;
        }
		else if (error_code == 0x31013101) {
			return `No main power supply (${error_code})`;
		}
        else if((error_code & 0x0000FFFF) == 0x0000FF31) {
            var ignore_map = ((error_code >> 16) & 0x0000FFFF)
            return `ModbusMappings. Ignoring last ${ignore_map} mappings (${error_code})`;
        }
		return error_code
	}

	function checkbox_click(checkbox)
	{
		if ($(checkbox).valid())
		{
			let  index_number = $(checkbox).attr('index')
			let new_value = utils.checked2string($(checkbox))

			query = '/set_od_data.form?'
			query += utils.get_set_od_data_query_unit(index_number, new_value)

			set_data_xhr.open('GET', query, true)
			set_data_xhr.send()
		}
	}

	function get_control_by_name_from_table(form, table_name, name)
	{
		let control = form.children(`.${table_name}`)
					.children(`.${name}_tr`)
					.children(`.${name}_td`)
					.children(`.${name}`)
		return control
	}

	function item_edit_click(button)
	{
		$(button).addClass('edited')
		if ($(button).valid())
		{
			var index_number = $(button).attr('index')
			var apply_input = $(`[tb_index='${index_number}']`)
			var new_value = apply_input.val()
			var additional_query = ''

			if (apply_input.hasClass('pdo_mapping'))
			{
				let form = apply_input.parent()
				let index_ctrl = form.children(".pdo_mapping_index")
				let subindex_ctrl = form.children(".pdo_mapping_subindex")
				let size_ctrl = apply_input

				let index_input = index_ctrl.val()
				let subindex_input = subindex_ctrl.val()
				let size_input = size_ctrl.val()
				
				let index_raw_val = (parseInt(index_input) & 0xFFFF) * 0x10000
				let subi_raw_val = (parseInt(subindex_input) & 0xFF) * 0x100
				let size_raw_val = (parseInt(size_input) & 0xFF)

				let pdo_mapping = index_raw_val + subi_raw_val + size_raw_val
				new_value = `${pdo_mapping}`

				index_ctrl.removeClass('changed')
				subindex_ctrl.removeClass('changed')
				size_ctrl.removeClass('changed')
			}
			else if (apply_input.hasClass('pdo_cob_id'))
			{
				let form = apply_input.parent()
				let enable_ctrl = form.children(".pdo_cob_id_enable")
				let message_ctrl = form.children(".pdo_cob_id_message")
				let node_id_ctr = apply_input

				let enable_input = enable_ctrl.val()
				let message_input = message_ctrl.val()
				let node_id_input = node_id_ctr.val()

				let enable_val = parseInt(enable_input << 31)
				let message_val = parseInt(message_input) & 0x780
				let node_id_val = parseInt(node_id_input) & 0x7F

				if (message_val === 0 && node_id_val !== 0)
				{
					$(`#error_label_${apply_input.attr('id').slice(-1)}`).show()
					return
				}

				let pdo_cob_id = (enable_val + message_val + node_id_val) >>> 0
				new_value = `${pdo_cob_id}`

				enable_ctrl.removeClass('changed')
				message_ctrl.removeClass('changed')
				node_id_ctr.removeClass('changed')
			}
			else if (apply_input.hasClass('line_flags'))
			{
				let form = apply_input.parent()
				let voltage_ctrl = form.children(".line_flags_table")
					.children(".line_flags_voltage_tr")
					.children(".line_flags_voltage_td")
					.children(".line_flags_voltage")
				let voltage_input = voltage_ctrl.val()
				let voltage_val = parseInt(voltage_input << 2)
				

				let no_nc_ctrl = form.children(".line_flags_table")
					.children(".line_flags_no_nc_tr")
					.children(".line_flags_no_nc_td")
					.children(".line_flags_no_nc")
				let no_nc_input = no_nc_ctrl.val()
				let no_nc_val = parseInt(no_nc_input << 1)
				

				let pwm_ctrl = form.children(".line_flags_table")
					.children(".line_flags_pwm_tr")
					.children(".line_flags_pwm_td")
					.children(".line_flags_pwm")
				let pwm_input = pwm_ctrl.val()
				let pwm_val = parseInt(pwm_input << 0)

				new_value = voltage_val + no_nc_val + pwm_val

				voltage_ctrl.removeClass('changed')
				no_nc_ctrl.removeClass('changed')
				pwm_ctrl.removeClass('changed')
			}
			else if (apply_input.hasClass('bit_checkboxes'))
			{
				let form = apply_input.parent()
				//let table = form.children(".bit_checkboxes_table")
				new_value = 0		
				$.each(form.children('.bit_checkboxes_ctrl'), function(number, ctrl)
				//$($(form.children('.bit_checkboxes_ctrl')).get().reverse()).each(function(number, ctrl)
				{
					let input = utils.checked2string($(ctrl))
					let val = parseInt(input) << number
					new_value += val 
					$(ctrl).removeClass('changed')
				})
				//console.log(new_value)
			}
    		else if (apply_input.hasClass('consumer_heartbeat'))
			{
				let form = apply_input.parent()
				let node_input_ctrl = form.children(".consumer_heartbeat_node")
				let time_input_ctrl = apply_input
				/*var time_input_ctrl = button.previousElementSibling
                var node_input_ctrl = time_input_ctrl.previousElementSibling*/

                let node_input = node_input_ctrl.val()
				let time_input = apply_input.val()
                //TODO Add check of value
                // heartbeat consumer = node (7 bit from 16 bit) + time (0..15 bit)
                let node_raw_val = (parseInt(node_input) & 0x7F) * 0x10000
                let time_raw_val = parseInt(time_input) & 0xFFFF
                let hb_consumer = node_raw_val + time_raw_val

				new_value = `${hb_consumer}`

				node_input_ctrl.removeClass('changed')
				time_input_ctrl.removeClass('changed')
			}
			else if (apply_input.hasClass('mbtcp_client'))
			{
				let form = apply_input.parent()
				let mbtcp_client_cs_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_table", "mbtcp_client_cs")
                let mbtcp_client_cs_str = utils.checked2string(mbtcp_client_cs_ctrl)
				let mbtcp_client_cs_value = BigInt(mbtcp_client_cs_str) << 60n
				mbtcp_client_cs_ctrl.removeClass('changed')

				let mbtcp_client_timeout_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_table", "mbtcp_client_timeout")
				let mbtcp_client_timeout_str = mbtcp_client_timeout_ctrl.val()
				let mbtcp_client_timeout_value = BigInt(mbtcp_client_timeout_str) << 50n
				mbtcp_client_timeout_ctrl.removeClass('changed')
				//console.log(mbtcp_client_timeout_value)

				let mbtcp_client_port_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_table", "mbtcp_client_port")
				let mbtcp_client_port_str = mbtcp_client_port_ctrl.val()
				let mbtcp_client_port_value = BigInt(mbtcp_client_port_str) << 32n
				mbtcp_client_port_ctrl.removeClass('changed')
				//console.log(mbtcp_client_port_value)

				let mbtcp_client_ip_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_table", "mbtcp_client_ip")
				let mbtcp_client_ip_str = mbtcp_client_ip_ctrl.val()
				let mbtcp_client_ip_value = BigInt(utils.string2int_ip(mbtcp_client_ip_str))
				mbtcp_client_ip_ctrl.removeClass('changed')
				
                let mbtcp_client_value = mbtcp_client_cs_value + mbtcp_client_timeout_value + mbtcp_client_port_value + mbtcp_client_ip_value
				new_value = `${mbtcp_client_value}`
			}
			else if (apply_input.hasClass('mbtcp_client_status'))
			{
				let sum_value = 0

				let form = apply_input.parent()
				let connection_status_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_status_table", "mbtcp_client_status_connection")
				let connection_status_ctrl_value = BigInt(utils.checked2string(connection_status_ctrl)) << 28n
				connection_status_ctrl.removeClass('changed')
				sum_value += connection_status_ctrl_value

				let tls_status_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_status_table", "mbtcp_client_status_tls")
				let tls_status_ctrl_value = BigInt(utils.checked2string(tls_status_ctrl)) << 24n
				tls_status_ctrl.removeClass('changed')
				sum_value += tls_status_ctrl_value

				let timeout_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_status_table", "mbtcp_client_status_timeout")
				let timeout_ctrl_value = BigInt(utils.checked2string(timeout_ctrl)) << 23n
				timeout_ctrl.removeClass('changed')
				sum_value += timeout_ctrl_value

				let misconfig_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_status_table", "mbtcp_client_status_misconfig")
				let misconfig_ctrl_value = BigInt(utils.checked2string(misconfig_ctrl)) << 16n
				misconfig_ctrl.removeClass('changed')
				sum_value += misconfig_ctrl_value

				let port_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_status_table", "mbtcp_client_status_port")
				let port_ctrl_value = BigInt(utils.checked2string(port_ctrl))
				port_ctrl.removeClass('changed')
				sum_value += port_ctrl_value

				new_value = `${sum_value}`
			}
			else if (apply_input.hasClass('datetime'))
			{
				var date_input = $("#date_input");
				var time_input = $("#time_input");
				var date_time_string = date_input.val() + "T" + time_input.val() + ".000Z"
				//console.log(date_time_string)
				new_value = Date.parse(date_time_string)/1000

				//console.log(new_value)
				date_input.removeClass('changed')
			}
			else if (apply_input.hasClass('date'))
			{
				var date_input = $("#date_input");
				//console.log(date_input.val())
				var date_time_string = date_input.val() + "T00:00:00.000Z"
				//console.log(Date.parse(apply_input.val())/1000);
				//console.log(date_time_string)
				new_value = Date.parse(date_time_string)/1000

				//console.log(new_value)
				date_input.removeClass('changed')
			}
			else if (apply_input.hasClass('deadband'))
			{
				new_value = apply_input.val()*1000;
			}
			else if (apply_input.hasClass('ip_addr'))
			{
				new_value = utils.string2int_ip(apply_input.val())
			}
			else if (apply_input.hasClass('password'))
			{
				new_value = utils.pass2ascii(new_value)
				apply_input.val('')
			}
			else if (apply_input.hasClass('restore_params')
				|| apply_input.hasClass('string_command'))
			{
				var new_value_buffer = "0x";
				for (var i = (new_value.length - 1); i >= 0; i--)
				{
				 	new_value_buffer += new_value.charCodeAt(i).toString(16);
				}
				new_value = new_value_buffer;
				apply_input.val('');
			}
			else if (index_number.includes('1027')) //Module Types
			{
				/*var form = $(`div [index='${index_number}']`)
				if (form.children('.restart').length  == 0)
				{
					var div= $('<div class="restart">').attr({"style":"display: blocks;"}).text(l100n.localize_string('Restart and reload'))
					form.append(div)
				}*/

				if (new_value == exports.board_types.f_lcd || new_value == exports.board_types.f_io)
				{
					var sub_index = parseInt(index_number.slice(5))
					var modul_number = sub_index - 1
					//console.log(modul_number)
					if (modul_number % 2 == 1)
					{
						new_value = exports.board_types.f_lcd
						var index_number_2 = `${index_number.slice(0, 5)}${sub_index + 1}`
						additional_query += `&0x${index_number_2}=${exports.board_types.f_io}`
					}
					else
					{
						new_value = exports.board_types.f_io
						var index_number_2 = `${index_number.slice(0, 5)}${sub_index - 1}`
						additional_query += `&0x${index_number_2}=${exports.board_types.f_lcd}`
					}
					//console.log(additional_query)
				}
			}
			else if (apply_input.hasClass('mcuf_sensor_select'))
			{
				let form = apply_input.parent()
				let module = form.children(".mcuf_module_select")
				let module_number = module.val() //module number
				let sensor_number = apply_input.val() //sensor number
				let sensor_number_int = parseInt(sensor_number)

				if (sensor_number_int == 0)
				{
					new_value = 0
				}
				else
				{
					new_value = parseInt(module_number)*16 + sensor_number_int
				}
				
			}

			if (apply_input.hasClass('need_restart'))
			{
				var form = $(`div [index='${index_number}']`)
				if (form.children('.restart').length  == 0)
				{
					var div= $('<div class="restart">').attr({"style":"display: blocks;"}).text(l100n.localize_string('Restart and reload'))
					form.append(div)
				}
			}

			if (access_control == "Admin")
			{
				if (index_number == '2002_1' && new_value == '0x00040000') //change pass
				{
					$("#pass_change_dialog").dialog('open')
				}
			}
			else
			{
				if (index_number == '2002_1' && (/*new_value == '0x10000' ||*/ new_value == '0x00020000' || new_value == '0x00030000' || new_value == '0x00040000'))
				{
					$("#login_dialog").dialog('open')
					return;
					//alert(l100n.localize_string('ACCESS DENIED'));
				}
			}

			if ((new_value.toString() != 'NaN') && (!apply_input.hasClass('error')))
			{
				query = '/set_od_data.form?';
				query += utils.get_set_od_data_query_unit(index_number, new_value)
				query += additional_query;

				set_data_xhr.open('GET', query, true);
				set_data_xhr.send();
			}
			else
			{
				alert(l100n.localize_string("Invalid data format."));
			}

			apply_input.removeClass('changed')
			apply_input.blur()
		}
	}

	function get_bit(value, bit_position)
	{
		return (value & (1 << (bit_position-1))) >>> (bit_position-1)
	}

	function value_paste()
	{
		let new_value = 'empty'
		$(".value").each(function(index, item)
		{
			//console.log(index)
			if (index in response_values)
			{
				new_value = response_values[index].replace(/\u0000/g, '');
				/*let new_value1
				let new_value2
				let new_value3*/
				//console.log($(item).attr('class'))
				if ($(item).hasClass('edit_cb'))
				{
					utils.change_checked($(item), new_value)
				}
				else if ($(item).hasClass('readonly_cb')
					|| $(item).hasClass('boolean_input')
					|| $(item).hasClass('boolean_output')
					|| $(item).hasClass('boolean_alarm'))
				{
					if (new_value == "1")
					{
						$(item).addClass('on')
					}
					else
					{
						$(item).removeClass('on')
					}
				}

				//Change new value
				if ($(item).hasClass('change_value'))
				{
					$.each(configuration.data_type_template().templates, function(template_index, template_item)
					{
						if (template_item.index == $(item).attr('tb_index'))
						{
							var find = false
							$.each(template_item.commands, function(command_index, command_item)
							{
								if (command_item.raw_value == new_value)
								{
									find = true
									new_value = command_item.new_value
									return false //break
								}
							})
							if (!find) {
								$.each(template_item.commands, function(command_index, command_item)
								{
									if (command_item.raw_value == "default")
									{
										new_value = command_item.new_value
									}
								})
							}
							return false //break
						}
					})
				}
                else  if ($(item).hasClass('datetime') || $(item).hasClass('datetime_show'))
				{
					var datetime_int = parseInt(response_values[index].replace(/\u0000/g, ''))
					var subseconds = parseInt(datetime_int / Math.pow(2,32))
					var datetime = new Date((datetime_int - subseconds*Math.pow(2,32))*1000 + subseconds)

					let date = exports.dateYYYYMMDD(datetime)
					let time = exports.timeHHmmss(datetime)

					if ($(item).hasClass('datetime'))
					{
						let date_input = $("#date_input")
						let time_input = $("#time_input")

						if (!date_input.hasClass('changed'))
						{
							date_input.val(date);
							//date_input.datepicker('setDate', date)
						}
						if (!time_input.hasClass('changed'))
						{
							time_input.val(time);
						}
					}
					else if ($(item).hasClass('datetime_show'))
					{
						$("#date_show").text(date);
						$("#time_show").text(time);
					}
				}
				else  if ($(item).hasClass('pdo_mapping'))
				{
					// read value of hex
					let pdo_mapping_int = parseInt(response_values[index].replace(/\u0000/g, ''))

					let index_int = (pdo_mapping_int >> 16) & 0xFFFF
					let subindex_int = (pdo_mapping_int >> 8) & 0xFF
					let size_int = (pdo_mapping_int >> 0) & 0xFF

					let index_value = `0x${index_int.toString(16).toUpperCase()}`
					let subindex_value = `${subindex_int}`
					let size_value = `${size_int}`
					/*console.log(new_value1)
					console.log(new_value2)
					console.log(new_value3)*/
					let form = $(item).parent()
					let index_ctrl = form.children(".pdo_mapping_index")
					let subindex_ctrl = form.children(".pdo_mapping_subindex")

					if (!index_ctrl.hasClass('changed'))
					{
						index_ctrl.val(index_value)
					}
					if (!subindex_ctrl.hasClass('changed'))
					{
						subindex_ctrl.val(subindex_value)
					}
					new_value = size_value
				}
				else  if ($(item).hasClass('pdo_cob_id'))
				{
					let pdo_cob_id_int = parseInt(response_values[index].replace(/\u0000/g, '')) // read value of hex

					let enable_int = pdo_cob_id_int >>> 31
					let message_int = pdo_cob_id_int & 0x780
					let node_id_int = pdo_cob_id_int & 0x7F

					$.each(configuration.data_type_template().templates, function(template_index, template_item)
					{
						if (template_item.index == $(item).attr('tb_index'))
						{
							var find = false
							$.each(template_item.messages, function(command_index, command_item)
							{
								if (command_item.command == message_int)
								{
									message_value = message_int
									find = true
									return false //break
								}
							})
							if (!find) {
								message_value = "default"
							}
							return false //break
						}
					})
					/*console.log(enable_int)
					console.log(message_value)
					console.log(node_id_int)*/
					let form = $(item).parent()
					let enable_ctrl = form.children(".pdo_cob_id_enable")
					let message_ctrl = form.children(".pdo_cob_id_message")

					if (!enable_ctrl.hasClass('changed'))
					{
						enable_ctrl.val(enable_int)
					}
					if (!message_ctrl.hasClass('changed'))
					{
						message_ctrl.val(message_value)
					}
					new_value = node_id_int
				}
				else if  ($(item).hasClass('line_flags'))
				{
					let line_flags_int = parseInt(response_values[index].replace(/\u0000/g, '')) // read value of hex

					//console.log(line_flags_int)
					let voltage_int = (line_flags_int >>> 2) & 0x3
					let no_nc_int = (line_flags_int >>> 1) & 0x1
					let pwm_int = line_flags_int & 0x1
					/*console.log(voltage_int)
					console.log(no_nc_int)
					console.log(pwm_int)*/
					let form = $(item).parent()
					let voltage_ctrl = form.children(".line_flags_table")
						.children(".line_flags_voltage_tr")
						.children(".line_flags_voltage_td")
						.children(".line_flags_voltage")
					let no_nc_ctrl = form.children(".line_flags_table")
						.children(".line_flags_no_nc_tr")
						.children(".line_flags_no_nc_td")
						.children(".line_flags_no_nc")
					let pwm_ctrl = form.children(".line_flags_table")
						.children(".line_flags_pwm_tr")
						.children(".line_flags_pwm_td")
						.children(".line_flags_pwm")

					if (!voltage_ctrl.hasClass('changed'))
					{
						voltage_ctrl.val(voltage_int)
					}
					if (!no_nc_ctrl.hasClass('changed'))
					{
						no_nc_ctrl.val(no_nc_int)
					}
					if (!pwm_ctrl.hasClass('changed'))
					{
						pwm_ctrl.val(pwm_int)
					}
				}
				else if  ($(item).hasClass('bit_checkboxes'))
				{
					let bit_checkboxes_int = parseInt(response_values[index].replace(/\u0000/g, '')) // read value of hex
					//console.log(bit_checkboxes_int)
					let form = $(item).parent()
					//let table = form.children(".bit_checkboxes_table")

					$.each(form.children('.bit_checkboxes_ctrl'), function(number, ctrl)
					//$($(form.children('.bit_checkboxes_ctrl')).get().reverse()).each(function(number, ctrl)
					{
						//console.log(number)
						let item_int = get_bit(bit_checkboxes_int, number + 1)
						//let ctrl = $(tr).children('.bit_checkboxes_td').children(`.bit_checkboxes_ctrl`)

						if (!$(ctrl).hasClass('changed'))
						{
							utils.change_checked($(ctrl), item_int)
						}
						//console.log(item_int)
					})
				}
                else if ($(item).hasClass('consumer_heartbeat'))
				{
					let response = response_values[index].replace(/\u0000/g, '')
					let hb_consumer_int = parseInt(response)

                    // heartbeat consumer = node (7 bit from 16 bit) + time (0..15 bit)
					let node_int = ((hb_consumer_int >> 16) & 0x7F)
					let time_int = hb_consumer_int & 0xFFFF
					node_value = `0x${node_int.toString(16).toUpperCase()}`
					time_value = `${time_int}`

					let form = $(item).parent()
					let node_ctrl = form.children(".consumer_heartbeat_node")
					if (!node_ctrl.hasClass('changed')) {
						node_ctrl.val(node_value)
					}
					new_value = time_value
				}
				else if ($(item).hasClass('mbtcp_client'))
				{
					let form = $(item).parent()
					let response = response_values[index].replace(/\u0000/g, '')
					let mbtcp_client_bigint = BigInt(response)

					let cs_int = (mbtcp_client_bigint >> 60n) & 0x1n // 60
					let cs_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_table", "mbtcp_client_cs")
					if (!cs_ctrl.hasClass('changed')) 
					{
						utils.change_checked(cs_ctrl, cs_int)
					}

					let timeout_int = (mbtcp_client_bigint >> 50n) & 0x3FFn // 50-59
					let timeout_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_table", "mbtcp_client_timeout")
					if (!timeout_ctrl.hasClass('changed')) {
						timeout_ctrl.val(`${timeout_int}`)
					}

					let port_int = (mbtcp_client_bigint >> 32n) & 0x7FFFn // 32-47
					let port_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_table", "mbtcp_client_port")
					if (!port_ctrl.hasClass('changed')) {
						port_ctrl.val(`${port_int}`)
					}

					let ip_int = (mbtcp_client_bigint) & 0xFFFFFFFFn
					let ip_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_table", "mbtcp_client_ip")
					if (!ip_ctrl.hasClass('changed')) {
						ip_ctrl.val(utils.ip2string(ip_int))
					}
				}
				else if ($(item).hasClass('mbtcp_client_status'))
				{
					let form = $(item).parent()
					let response = response_values[index].replace(/\u0000/g, '')
					let response_bigint = BigInt(response)

					let connection_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_status_table", "mbtcp_client_status_connection")
					if (!connection_ctrl.hasClass('changed')) 
					{
						utils.change_checked(connection_ctrl, (response_bigint >> 28n) & 0xFn)
					}

					let tls_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_status_table", "mbtcp_client_status_tls")
					if (!tls_ctrl.hasClass('changed')) 
					{
						utils.change_checked(tls_ctrl, (response_bigint >> 24n) & 0xFn)
					}

					let timeout_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_status_table", "mbtcp_client_status_timeout")
					if (!timeout_ctrl.hasClass('changed')) 
					{
						utils.change_checked(timeout_ctrl, (response_bigint >> 23n) & 0x1n)
					}

					let misconfig_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_status_table", "mbtcp_client_status_misconfig")
					if (!misconfig_ctrl.hasClass('changed')) 
					{
						utils.change_checked(misconfig_ctrl, (response_bigint >> 16n) & 0xFn)
					}

					let port_ctrl = get_control_by_name_from_table(form,  "mbtcp_client_status_table", "mbtcp_client_status_port")
					if (!port_ctrl.hasClass('changed')) 
					{
						utils.change_checked(port_ctrl, (response_bigint) & 0xFFFFn)
					}
				}
				else if ($(item).hasClass('time'))
				{
                    if (new_value == 0) {
                        new_value = 'No time'
                    } else {
					    var datetime_int = parseInt(response_values[index].replace(/\u0000/g, ''));
					    var subseconds = parseInt(datetime_int / Math.pow(2,32));
					    var datetime = new Date((datetime_int - subseconds*Math.pow(2,32))*1000 + subseconds);
					    new_value = exports.timeHHmm(datetime)
                    }
				}
				else if ($(item).hasClass('date'))
				{
                    if (new_value == 0) {
                        new_value = 'No date'
                    } else {
					    var datetime_int = parseInt(response_values[index].replace(/\u0000/g, ''));
					    var subseconds = parseInt(datetime_int / Math.pow(2,32));
					    var datetime = new Date((datetime_int - subseconds*Math.pow(2,32))*1000 + subseconds);
					    new_value = exports.dateYYYYMMDD(datetime)
                    }
				}
				else if($(item).hasClass('datetime_simple'))
				{
                    if (new_value == 0) {
                        new_value = 'No date'
                    } else {
					    var datetime_int = parseInt(response_values[index].replace(/\u0000/g, ''))
					    var subseconds = parseInt(datetime_int / Math.pow(2,32))
					    var datetime = new Date((datetime_int - subseconds*Math.pow(2,32))*1000 + subseconds)
					    new_value = `${exports.dateYYYYMMDD(datetime)} ${exports.timeHHmmss(datetime)}`
                    }
				    //console.log(new_value)
				}
				else if ($(item).hasClass('deadband'))
				{
					new_value = new_value/1000;
				}
				else if ($(item).hasClass('ip_addr'))
				{
					new_value = utils.ip2string(new_value)
				}
				else if ($(item).hasClass('hex'))
				{
					new_value = "0x"+parseInt(new_value).toString(16);
				}
				else if ($(item).hasClass('error_field'))
				{
					new_value = error_field_parser(new_value);
				}
				else if ($(item).hasClass('battery'))
				{
					var value_int = parseFloat(new_value)
					new_value = value_int.toFixed(2)
				}
				/*else if ($(item).hasClass('checkbox_value'))
				{
					$.each(templates_commands.default_checkbox_values(), function(command_index, command_item)
					{
						if (command_item.raw_value == new_value)
						{
							new_value = command_item.new_value
							return false //break
						}
					});
				}*/
				else if ($(item).hasClass('restore_params')
					|| $(item).hasClass('string_command'))
				{
					if (new_value == "0")
					{
						new_value = ""
					}
				}
				else if ($(item).hasClass("bit_value"))
				{
					$.each(configuration.data_type_template().templates, function(template_index, template_item)
					{
						if (template_item.index == $(item).attr('tb_index'))
						{
							if (new_value == 0)
							{
								$.each(template_item.commands, function(command_index, command_item)
								{
									var bit_position = template_item.commands[command_index].bit_position
									if (bit_position == 0)
									{
										new_value = command_item.new_value
										return false //break
									}
								})
								$(item).addClass("no_error")
							}
							else
							{
								var  buf = "";
								$.each(template_item.commands, function(command_index, command_item)
								{
									if (command_index != 0)
									{
										var bit_position = template_item.commands[command_index].bit_position
										if (get_bit(new_value, bit_position)) { buf += `${command_item.new_value}<br>`}//(${bit_position})
									}
								})
								new_value = buf
								$(item).removeClass("no_error")
							}
							return false //break
						}
					})
				}
				else if ($(item).hasClass("control_mode"))
				{
					if (!$(item).hasClass('changed'))
					{
						heat_line_common.mark_control_mode_tab(item, new_value)
					}
				}
				else if ($(item).hasClass("module_types"))
				{
					/*if (new_value == exports.board_types.f_lcd)
					{
						//$(item).attr({"disabled":"true"})
						var index_number_1 = $(item).attr('tb_index')
						var sub_index = parseInt(index_number_1.slice(5))
						var index_number_2 = `${index_number_1.slice(0, 5)}${sub_index + 1}`
						var input_2 = $(`[tb_index='${index_number_2}']`)
						input_2.attr({"disabled":"true"})
					}*/
					if (new_value == exports.board_types.f_io)
					{
						//$(item).attr({"disabled":"true"})
						var index_number_1 = $(item).attr('tb_index')
						var sub_index = parseInt(index_number_1.slice(5))
						var index_number_2 = `${index_number_1.slice(0, 5)}${sub_index - 1}`
						var input_2 = $(`[tb_index='${index_number_2}']`)
						input_2.attr({"disabled": true})
					}
					else
					{
						var index_number_1 = $(item).attr('tb_index')
						var sub_index = parseInt(index_number_1.slice(5))
						var index_number_2 = `${index_number_1.slice(0, 5)}${sub_index - 1}`
						var input_2 = $(`[tb_index='${index_number_2}']`)
						input_2.attr({"disabled": false})
					}
				}
				else if ($(item).hasClass("mcuf_sensor_select"))
				{
					let form = $(item).parent()
					let module = form.children(".mcuf_module_select")
					let module_number = parseInt(new_value/16) //module number
					let sensor_number = new_value % 16 //sensor number

					new_value = sensor_number
					if (!module.hasClass('changed'))
					{
						module.val(module_number)
					}
				}

				if ($(item).hasClass('datetime') || $(item).hasClass('datetime_show'))
				{
					//pass
				}
				else if ($(item).hasClass("bit_value"))
				{
					$(item).html(new_value)
				}
				// default
				else if (!$(item).hasClass('changed'))//!$(item).is(":focus") ||
				{
					if ($(item).is("div"))
					{
						$(item).text(new_value)
					}
					else if ($(item).hasClass('combobox'))
					{
						if ($(item).find(`option[value="${new_value}"]`).length === 0)
						{
							$(item).append( new Option(`${new_value} - ${l100n.localize_string("unknown_value")}`, new_value))
						}
						$(item).val(new_value)
					}
					else
					{
						$(item).val(new_value)
					}
				}

				if ($(item).attr('tb_index') == "2001_9")
				{
					access_control = new_value
				}
				$(item).trigger('value_loaded')
			}
		})
	}



	function autoupdate_off()
	{
		//window.clearTimeout(timeoutHandle);
		autoupdate = false;

		$('.autoupdate').addClass("off");
	}

	function autoupdate_on()
	{
		autoupdate = true;
		set_timeout_handle()

		$('.autoupdate').removeClass("off");
	}

	function set_timeout_handle()
	{
		if (autoupdate && on_window)
		{
			//console.log(timeoutHandle)
			timeoutHandle = setTimeout(exports.send_query, configuration.queryTimeout());
		}
	}

	let get_value_complite_function = function(response_values)
	{
		value_paste()
		set_timeout_handle()
		$(document).trigger("get_value_complite")
	}

	get_data_xhr.onreadystatechange = function()
	{
		//console.log(get_data_xhr.readyState);
		if (get_data_xhr.readyState == 4)
		{
			if (get_data_xhr.status == 200)
			{
				var responseLines = get_data_xhr.responseText.split('\n');
				var responseLine = responseLines[0];
				//console.log("responseLine:"+responseLine);
				if ((responseLines[0].search( />>>ERROR<<</i ) != -1) || (responseLines[0].search( /!!!ERROR!!!/i ) != -1))
				{
					if (confirm(l100n.localize_string("reload page"))) {
						window.location.reload();
					}

					//alert(l100n.localize_string("response error"));// + responseLine);
					//autoupdate_off()
				}

				response_values = response_values.concat(responseLine.split('&#&'));
				response_values.pop();
				//console.log('response_values: ' + response_values);

				if (current_request_index >= (request_data.length))
				{
					//value_paste()
					get_value_complite_function(response_values)
					//t1 = performance.now()
					//console.log('Took', (t1 - t0).toFixed(4))

					current_request_index = 0
					response_values = []
					//set_timeout_handle()
				}
				else if (request_data != null)
				{
					exports.send_query();
				}
			}
			else
			{
				alert(l100n.localize_string("Check device connection..."));
				//autoupdate_off()
				current_request_index = 0;
			}
		}
	}

	set_data_xhr.onreadystatechange = function()
	{
		//console.log(set_data_xhr);
		if (set_data_xhr.readyState == 4)
		{
			if (set_data_xhr.status == 200)
			{
				var responseLines = set_data_xhr.responseText.split('\n');
				var responseLine = responseLines[0];
				var url = new URL(set_data_xhr.responseURL)
				urlSearch = url.search.slice(1)
				params = new URLSearchParams(urlSearch)

				if (params.has('0x2002_1')) //command
				{
					/*if (responseLines[1].includes('!!!ERROR!!!'))
					{
						alert('ACCESS DENIED');
					}
					else
					{
						alert('ACCESS LEVEL CHANGED');
					}*/
				}
				else if (params.has('0x2002_2')) //password
				{
					if (responseLines[0].includes('!!!ERROR!!!'))
					{
						alert(l100n.localize_string('ACCESS DENIED'));
					}
					else
					{
						alert(l100n.localize_string('ACCESS CONFIRMED'));
						$("#login_dialog").dialog('close')
					}
				}
				else
				{
					//console.log("responseLine:"+responseLine);
					if ((responseLines[0].search( />>>ERROR<<</i ) != -1) || (responseLines[0].search( /!!!ERROR!!!/i ) != -1))
					{
						alert(l100n.localize_string("response error"));//: ' + responseLine);
					}
				}
			}
			else
			{
				alert(l100n.localize_string("Check device connection..."));
			}
		}
	}

	exports.get_response_values = function (xhr)
	{
		var response_values = [];
		var responseLines = xhr.responseText.split('\n');
		var responseLine = responseLines[0];
		//console.log("responseLine:"+responseLine);
		/*if ((responseLines[1].search( />>>ERROR<<</i ) != -1) || (responseLines[1].search( /!!!ERROR!!!/i ) != -1))
		{
			alert('Ошибка в ответе с сервера:' + responseLine);
		}*/

		response_values = responseLine.split('&#&');
		response_values.pop();
		//console.log('response_values: ' + response_values);
		return response_values;
	}

	$(document).ready(function()
	{
		/*var expert_page_button = ($(`<input type="submit" value="${l100n.localize_string("Expert_page")}" id="expert_page_button">`))
		$("#expert_page").append(expert_page_button)
		$(document).on('click', '#expert_page_button', function()
		{
			location.replace("raw_access.html")
		})
		var modbus_mapping_page_button = ($(`<input type="submit" value="${l100n.localize_string("modbus_mapping_page")}" id="modbus_mapping_page_button">`))
		$("#modbus_mapping_page").append(modbus_mapping_page_button)
		$(document).on('click', '#modbus_mapping_page_button', function()
		{
			location.replace("modbus_mappings_reader.html")
		})*/

		$(document).on('click', '.item_edit_b', function()
		{
		    item_edit_click(this);
		});

		$(document).on('click', '.edit_cb', function()
		{
		    checkbox_click(this);
		});

		$(document).on('submit', '.apply_form', the_event =>
		{
			the_event.preventDefault();
			the_event.stopImmediatePropagation();
		});

		$(document).on('click', '.autoupdate', function()
		{
		    if (autoupdate)
		    {
		    	window.clearTimeout(timeoutHandle);
		    	autoupdate_off()
		    }
		    else
		    {
		    	autoupdate_on()
		    }
		});

		/*$(document).on('click', '.language', function()
		{
			l100n.change_locale()
			//l100n.show_locale()
		});*/

		$(window).focus(function() //Во вкладке
		{
			on_window = true
			set_timeout_handle()
		});
		$(window).blur(function() //Покинули вкладку
		{
			on_window = false
		});

		$(document).on('focus', '.value', function()
		{
			//console.log($(this).attr('class'))
			$(this).addClass("changed")
		});
		$(document).on('blur', 'div.value', function()//only readonly elements
		{
			$(this).removeClass("changed")
		});
		$(document).on('focus', '.datetime', function()//only readonly elements
		{
			$(this).addClass("changed")
		});
		$(document).on('focus', '.consumer_heartbeat', function()
		{
			$(this).addClass("changed")
		});
		$(document).on('focus', '.mbtcp_client', function()
		{
			$(this).addClass("changed")
		});
		$(document).on('focus', '.pdo_mapping', function()
		{
			$(this).addClass("changed")
		});
		$(document).on('focus', '.pdo_cob_id', function()
		{
			$(this).addClass("changed")
			$(`#error_label_${this.id.slice(-1)}`).hide()
		});
		$(document).on('focus', '.mcuf_module_select', function()
		{
			$(this).addClass("changed")
		});
		$(document).on('focus', '.line_flags', function()
		{
			$(this).addClass("changed")
		});
		$(document).on('focus', '.bit_checkboxes', function()
		{
			$(this).addClass("changed")
		});
		/*$(document).on('blur', '.datetime', function()//only readonly elements
		{
			$(this).removeClass("changed")
		});*/
	})

})(this.get_set_value = {})

/*$.validator.addMethod("restart", function(value, element)
{
	return false
}, l100n.localize_string("Restart and reload"))*/



$.validator.addMethod("ip_addr", function(value, element)
{
	var re = new RegExp("^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$")
    return this.optional(element) || re.test(value)
}, l100n.localize_string("ip_address_pass"))

var rule = "^((0x)?[a-fA-F0-9]+)|(-?\\d+(\\.\\d{0,})?)$"
$.validator.addMethod("hex_dec_number", function(value, element)
{
    var re = new RegExp(rule);
    return this.optional(element) || re.test(value)
}, l100n.localize_string("hex_dec_number"))

$.validator.addMethod("range_localization", function(value, element, params)
{
    return this.optional(element) || (value >= params[0] && value <= params[1])
}, jQuery.validator.format(l100n.localize_string("range_localization") + "({0} ; {1})"))

var hex_dec_real_rule = "^inf$|^-inf$|^nan$|^((0x)?[a-fA-F0-9]+)|(-?\\d+(\\.\\d{0,})?)$"
$.validator.addMethod("hex_dec_real_number", function(value, element)
{
    var re = new RegExp(hex_dec_real_rule)
    return this.optional(element) || re.test(value)
}, "Hex, dec or float (inf/-inf/nan) value") //l100n.localize_string("hex_dec_number"))

//$.validator.addClassRules("item_edit_textbox", {required: true, messages: {required: "Введите значение."}})
//$.validator.addClassRules("bool", {required: true, hex_dec_number: true, range: [0, 1]})
$.validator.addClassRules("1-127", {required: false, hex_dec_number: true, range_localization: [1, 127]})
$.validator.addClassRules("uint8", {required: false, hex_dec_number: true, range_localization: [0, 255]})
$.validator.addClassRules("uint16", {required: false, hex_dec_number: true, range_localization: [0, 65535]})
$.validator.addClassRules("uint32", {required: false, hex_dec_number: true, range_localization: [0, 4294967295]})
$.validator.addClassRules("uint64", {required: false, hex_dec_number: true, range_localization: [0, 18446744073709551615]})
$.validator.addClassRules("int8", {required: false, hex_dec_number: true, range_localization: [-128, 127]})
$.validator.addClassRules("int16", {required: false, hex_dec_number: true, range_localization: [-32768, 32767]})
$.validator.addClassRules("int32", {required: false, hex_dec_number: true, range_localization: [-2147483648, 2147483647]})
$.validator.addClassRules("int64", {required: false, hex_dec_number: true, range_localization: [-9223372036854775808, 9223372036854775807]})
$.validator.addClassRules("real32", {required: false, hex_dec_real_number: true})
$.validator.addClassRules("mbtcp_client_timeout", {required: false, hex_dec_number: true, range_localization: [10, 1023]})
