import { Types } from "../types";
import * as Models from "../ivprog_elements";
import { LocalizedStrings } from "../../services/localizedStringsService";
import * as VariableValueMenuManagement from "./variable_value_menu";
import { registerUserEvent, ActionTypes } from "../../services/userLog";
import WatchJS from "melanke-watchjs";
window.timer = false;
export function renderExpression (
command,
function_obj,
div_to_render,
expression_array
) {
div_to_render.empty();
WatchJS.unwatch(command, "expression");
WatchJS.watch(
command,
"expression",
function () {
if (window.timer) return;
const m = div_to_render
.find(".single_element_expression")
.not(".mouse_distance")
.not(".add_parentheses");
let s = "";
m.each(function (e) {
if ($(this).hasClass("parentheses_in_expression")) {
s += $(this).text() + " ";
} else {
s += $(this)
.find(".text")
.text();
s += $(this)
.find(".var_name")
.text();
s += $(this)
.find(".parameters_function_called")
.text();
s += $(this)
.find(".value_rendered")
.text();
s += " ";
}
});
if (s) {
window.timer = true;
} else {
return;
}
registerUserEvent(
function_obj.name,
ActionTypes.CHANGE_COMMAND_EXP,
command.type,
"/",
s
);
setTimeout(function () {
window.timer = false;
}, 200);
},
20,
true
);
if (command.type === Models.COMMAND_TYPES.attribution) {
WatchJS.unwatch(command.variable);
WatchJS.watch(
command.variable,
function () {
renderExpression(
command,
function_obj,
div_to_render,
expression_array
);
},
0
);
if (command.variable.content) {
const types_included = [];
if (
command.variable.content.type == Types.INTEGER ||
command.variable.content.type == Types.REAL
) {
types_included.push(Models.EXPRESSION_TYPES.exp_arithmetic);
} else if (command.variable.content.type == Types.BOOLEAN) {
types_included.push(Models.EXPRESSION_TYPES.exp_conditional);
types_included.push(Models.EXPRESSION_TYPES.exp_logic);
types_included.push(Models.EXPRESSION_TYPES.exp_arithmetic);
} else if (command.variable.content.type == Types.TEXT) {
types_included.push(Models.EXPRESSION_TYPES.exp_conditional);
types_included.push(Models.EXPRESSION_TYPES.exp_logic);
types_included.push(Models.EXPRESSION_TYPES.exp_arithmetic);
} else {
//console.log("NÃO RECONHECI! VEJA: ", command.variable.content.type);
}
renderElements(
command,
function_obj,
div_to_render,
expression_array,
types_included
);
} else {
div_to_render.text(
LocalizedStrings.getUI("var_menu_select_var").toLowerCase()
);
}
} else {
const types_included = [];
types_included.push(Models.EXPRESSION_TYPES.exp_conditional);
types_included.push(Models.EXPRESSION_TYPES.exp_logic);
if (command.type === Models.COMMAND_TYPES.writer)
types_included.push(Models.EXPRESSION_TYPES.write_sep);
types_included.push(Models.EXPRESSION_TYPES.exp_arithmetic);
renderElements(
command,
function_obj,
div_to_render,
expression_array,
types_included
);
}
div_to_render.children(".mouse_distance").addClass("mouse_distance_hidden");
div_to_render.children(".higher_element").on("mousemove", function (evt) {
if (!window.open_or_close) {
$(this).css("position", "relative", "!important");
$(this)
.children(".mouse_distance")
.css("opacity", "1");
}
});
div_to_render.children(".higher_element").on("mouseout", function (evt) {
if (!window.open_or_close) {
$(this).css("position", "absolute", "!important");
$(this)
.children(".mouse_distance")
.css("opacity", "0");
}
});
const lixeira = $('
');
div_to_render
.find(".single_element_expression")
.on("mousedown", function (evt) {
window.posX = evt.clientX;
window.posY = evt.clientY;
});
Sortable.create(div_to_render[0], {
animation: 100,
ghostClass: "ghost",
group: {
name: "shared",
put: false, // Do not allow items to be put into this list
},
draggable: ".single_element_expression",
sort: false,
filter: ".not_allowed",
onStart: function () {
$("body").append(lixeira);
lixeira.css("display", "block");
lixeira.css("top", window.posY + 70, "!important");
lixeira.css("left", window.posX - 20, "!important");
},
onMove: function () {
lixeira.addClass("color_test");
},
onEnd: function () {
lixeira.remove();
div_to_render.find(".ghost").removeClass("ghost");
},
});
new Sortable(lixeira[0], {
group: "shared",
animation: 150,
onAdd: function (evt) {
lixeira.css("display", "none");
lixeira.find(".single_element_expression").remove();
lixeira.css("background-color", "");
lixeira.remove();
removeElement(evt, expression_array);
renderExpression(command, function_obj, div_to_render, expression_array);
},
});
}
function removeElement (event, expression_array) {
const indice = $(event.item).data("index");
const first = expression_array[0];
if (expression_array[indice].type) {
// if is alone in expression:
if (expression_array.length == 1) {
//function_obj.commands.splice(function_obj.commands.indexOf(command), 1);
expression_array.splice(0, 1);
} else if (expression_array.length > 1) {
if (indice > 0 && expression_array[indice - 1].type_op) {
if (
indice < expression_array.length &&
expression_array[indice - 2] == "(" &&
expression_array[indice + 1].type_op
) {
expression_array.splice(indice + 1, 1);
}
expression_array.splice(indice, 1);
expression_array.splice(indice - 1, 1);
if (
indice - 2 < expression_array.length &&
expression_array[indice - 2] == "(" &&
expression_array[indice - 1] == ")"
) {
expression_array.splice(indice - 1, 1);
expression_array.splice(indice - 2, 1);
if (
indice - 3 >= 0 &&
indice - 3 < expression_array.length &&
expression_array[indice - 3].type_op
) {
expression_array.splice(indice - 3, 1);
}
}
} else if (
indice < expression_array.length - 1 &&
expression_array[indice + 1].type_op
) {
expression_array.splice(indice + 1, 1);
expression_array.splice(indice, 1);
} else if (
indice < expression_array.length - 1 &&
indice > 0 &&
expression_array[indice - 1] == "(" &&
expression_array[indice + 1] == ")"
) {
if (indice > 1 && expression_array[indice - 2].type_op) {
expression_array.splice(indice + 1, 1);
expression_array.splice(indice, 1);
expression_array.splice(indice - 1, 1);
expression_array.splice(indice - 2, 1);
} else if (
indice < expression_array.length - 2 &&
expression_array[indice + 2].type_op
) {
expression_array.splice(indice + 1, 1);
expression_array.splice(indice, 1);
expression_array.splice(indice - 1, 1);
} else {
expression_array.splice(indice + 1, 1);
expression_array.splice(indice, 1);
expression_array.splice(indice - 1, 1);
}
}
}
} else if (expression_array[indice].type_op) {
// iVProg doesn't support operator remove
} else {
let opening = -1;
let closing = -1;
if (expression_array[indice] == "(") {
opening = indice;
for (var i = indice + 1; i < expression_array.length; i++) {
if (expression_array[i] == ")") {
closing = i;
break;
}
}
} else {
closing = indice;
for (var i = indice - 1; i >= 0; i--) {
if (expression_array[i] == "(") {
opening = i;
break;
}
}
}
if (expression_array[opening + 1].type_op) {
expression_array.splice(closing, 1);
expression_array.splice(opening + 1, 1);
expression_array.splice(opening, 1);
} else {
expression_array.splice(closing, 1);
expression_array.splice(opening, 1);
}
}
// if expression is empty, add a new var value:
if (expression_array.length == 0) {
expression_array.push(
new Models.VariableValueMenu(
VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all,
null,
null,
null,
true
)
);
}
if (first != expression_array[0] && expression_array[0].type_op) {
expression_array.splice(0, 1);
}
}
function renderElements (
command,
function_obj,
div_to_render,
expression_array,
types_included
) {
/*if (expression_array.length > 0) {
if (!expression_array[0].type_op) {
renderStartAddOperator(div_to_render, types_included, expression_array, command, function_obj, 0);
}
}*/
let i = 0;
for (i = 0; i < expression_array.length; i++) {
if (expression_array[i].type == "var_value") {
const div_temp = $(
''
);
if (i == 0) {
if (expression_array.length > 0 && !expression_array[0].type_op) {
//renderStartAddOperator(div_to_render, types_included, expression_array, command, function_obj, 0);
}
}
VariableValueMenuManagement.renderMenu(
command,
expression_array[i],
div_temp,
function_obj
);
div_to_render.append(div_temp);
} else if (expression_array[i] == "(" || expression_array[i] == ")") {
if (expression_array[i] == ")") {
renderFinalAddElements(
div_to_render,
types_included,
expression_array,
command,
function_obj,
i
);
renderParenthesis(
div_to_render,
expression_array[i],
command,
function_obj,
i,
expression_array
);
} else if (
expression_array[i] == "(" &&
!expression_array[i + 1].type_op
) {
renderParenthesis(
div_to_render,
expression_array[i],
command,
function_obj,
i,
expression_array
);
renderStartAddOperator(
div_to_render,
types_included,
expression_array,
command,
function_obj,
i + 1
);
} else {
renderParenthesis(
div_to_render,
expression_array[i],
command,
function_obj,
i,
expression_array
);
}
} else {
if (i == 0) {
} else if (expression_array[i - 1] == "(") {
}
renderOperatorMenu(
command,
function_obj,
div_to_render,
expression_array[i],
types_included,
i,
expression_array
);
}
}
renderFinalAddElements(
div_to_render,
types_included,
expression_array,
command,
function_obj,
i,
true
);
renderAddParenthesis(
command,
function_obj,
div_to_render,
expression_array,
types_included
);
}
window.parentheses_activate = false;
window.open_or_close = null;
function renderAddParenthesis (
command,
function_obj,
div_to_render,
expression_array,
types_included
) {
const addParentheses = $(
''
);
div_to_render.append(addParentheses);
addParentheses.popup({
content: "Adicionar parênteses",
delay: {
show: 750,
hide: 0,
},
});
addParentheses.on("click", function (mouse_event) {
// verificar se já está ativado
if (window.parentheses_activate) {
return;
}
div_to_render.find(".usepointer").off("click");
window.parentheses_activate = true;
window.open_or_close = "open";
div_to_render.find(".dropdown").addClass("disabled");
div_to_render.find(".ghost_element").addClass("temp_class");
div_to_render.find(".ghost_element").removeClass("ghost_element");
const floatingObject = $(' (
');
floatingObject.draggable().appendTo("body");
floatingObject.css("position", "absolute");
mouse_event.type = "mousedown.draggable";
mouse_event.target = floatingObject[0];
floatingObject.css("left", mouse_event.pageX + 10);
floatingObject.css("top", mouse_event.pageY + 10);
floatingObject.trigger(mouse_event);
div_to_render.on("mousemove", function (evt) {
let actual_target = null;
if ($(evt.target).hasClass("single_element_expression")) {
actual_target = $(evt.target);
} else {
actual_target = $(evt.target).closest(".single_element_expression");
}
if (
$(evt.target).hasClass("temp_class") ||
actual_target.length < 1 ||
actual_target.hasClass("add_parentheses") ||
actual_target.hasClass("rendered_parentheses") ||
$(evt.target).hasClass("expression_elements")
) {
return;
}
renderGhostParentheses(
actual_target,
command,
function_obj,
div_to_render,
expression_array
);
});
div_to_render.on("mouseleave", function () {
/*window.open_parentheses.remove();
window.close_parentheses.remove();*/
});
let floating;
$("body").on("mouseup", function (evt) {
if (window.open_or_close == "open") {
window.open_or_close = "close";
floatingObject.remove();
var comando_que_esta = $(evt.target).closest(".command_container");
var comando_certo = div_to_render.closest(".command_container");
if (!comando_que_esta.is(comando_certo)) {
window.parentheses_activate = false;
div_to_render.find(".temp_class").addClass("ghost_element");
div_to_render.find(".temp_class").removeClass("temp_class");
div_to_render.off("mousemove");
div_to_render.off("mouseleave");
$("body").off("mouseup");
window.open_parentheses.remove();
window.close_parentheses.remove();
window.inserir_open = -1;
window.inserir_close = -1;
window.open_or_close = null;
renderExpression(
command,
function_obj,
div_to_render,
expression_array
);
return;
}
window.open_parentheses.addClass("parentheses_fixed");
floating = $(' )
');
floating.draggable().appendTo("body");
floating.css("position", "absolute");
floating.css("left", evt.pageX + 10);
floating.css("top", evt.pageY + 10);
$("body").on("mousemove", function (evts) {
floating.css("left", evts.pageX + 10);
floating.css("top", evts.pageY + 10);
});
} else {
floating.remove();
window.open_parentheses.removeClass("parentheses_fixed");
div_to_render.off("mousemove");
div_to_render.off("mouseleave");
$("body").off("mouseup");
setTimeout(function () {
window.parentheses_activate = false;
}, 50);
var comando_que_esta = $(evt.target).closest(".command_container");
var comando_certo = div_to_render.closest(".command_container");
let is_correct = false;
if (comando_que_esta.is(comando_certo)) {
is_correct = true;
}
if (is_correct) {
expression_array.splice(window.inserir_open, 0, "(");
expression_array.splice(window.inserir_close, 0, ")");
}
window.inserir_open = -1;
window.inserir_close = -1;
window.open_or_close = null;
renderExpression(
command,
function_obj,
div_to_render,
expression_array
);
}
});
});
}
window.open_parentheses = $('(
');
window.close_parentheses = $(')
');
window.inserir_open = -1;
window.inserir_close = -1;
function renderGhostParentheses (
actual_target,
command,
function_obj,
div_to_render,
expression_array
) {
/*window.open_parentheses.remove();
window.close_parentheses.remove();*/
const index_in_array = actual_target.data("index");
if (
expression_array[index_in_array] == "(" ||
expression_array[index_in_array] == ")"
) {
return;
}
if (window.open_or_close == "close") {
if (index_in_array < window.inserir_open) {
return;
}
}
// Tratando a situação quando é na primeira posição:
if (index_in_array == 0) {
if (expression_array[index_in_array].type == "var_value") {
if (window.open_or_close == "open") {
window.open_parentheses.insertBefore(actual_target);
window.inserir_open = index_in_array;
}
/*if (expression_array.length == 1) {
if (window.open_or_close == "close") {
window.close_parentheses.insertAfter(actual_target);
window.inserir_close = index_in_array + 2;
}*/
//} else {
var count_opened = 0;
var count_closed = 0;
for (var i = 0; i < expression_array.length; i++) {
if (expression_array[i] == "(") {
count_opened++;
}
if (expression_array[i] == ")") {
count_closed++;
}
if (count_opened != count_closed) {
} else {
if (count_opened > 0) {
if (window.open_or_close == "close") {
window.close_parentheses.insertAfter(
div_to_render.find(
'.single_element_expression[data-index="' + i + '"]'
)
);
window.inserir_close = i + 2;
}
break;
} else {
if (expression_array[i].type == "var_value") {
if (window.open_or_close == "close") {
window.close_parentheses.insertAfter(
div_to_render.find(
'.single_element_expression[data-index="' + i + '"]'
)
);
window.inserir_close = i + 2;
}
break;
}
}
}
}
//}
} else if (expression_array[index_in_array].type_op) {
if (window.open_or_close == "open") {
window.open_parentheses.insertBefore(actual_target);
window.inserir_open = index_in_array;
}
var count_opened = 0;
var count_closed = 0;
for (var i = 1; i < expression_array.length; i++) {
// $('.slide-link[data-slide="0"]')
if (expression_array[i] == "(") {
count_opened++;
}
if (expression_array[i] == ")") {
count_closed++;
}
if (count_opened != count_closed) {
} else {
if (count_opened > 0) {
if (expression_array[i].type == "var_value") {
window.close_parentheses.insertAfter(
div_to_render.find(
'.single_element_expression[data-index="' + i + '"]'
)
);
window.inserir_close = i + 2;
}
break;
} else {
if (expression_array[i].type == "var_value") {
if (expression_array[i].type == "var_value") {
window.close_parentheses.insertAfter(
div_to_render.find(
'.single_element_expression[data-index="' + i + '"]'
)
);
window.inserir_close = i + 2;
}
break;
}
}
}
}
}
return;
}
// Tratando quando não é no índice 0:
if (expression_array[index_in_array].type == "var_value") {
if (window.open_or_close == "open") {
window.open_parentheses.insertBefore(actual_target);
window.inserir_open = index_in_array;
}
if (window.open_or_close == "close") {
window.close_parentheses.insertAfter(actual_target);
window.inserir_close = index_in_array + 2;
}
return;
}
if (expression_array[index_in_array].type_op) {
// buscar para a esquerda primeiro:
if (expression_array[index_in_array - 1] == "(") {
if (window.open_or_close == "open") {
window.open_parentheses.insertBefore(actual_target);
window.inserir_open = index_in_array;
}
} else if (expression_array[index_in_array - 1] == ")") {
// buscar a abertura
var count_opened = 0;
var count_closed = 0;
for (var j = index_in_array - 1; j >= 0; j--) {
if (expression_array[j] == "(") {
count_opened++;
}
if (expression_array[j] == ")") {
count_closed++;
}
if (count_opened != count_closed) {
} else {
if (count_closed > 0) {
if (window.open_or_close == "open") {
window.open_parentheses.insertBefore(
div_to_render.find(
'.single_element_expression[data-index="' + j + '"]'
)
);
window.inserir_open = j;
}
break;
}
}
}
} else if (expression_array[index_in_array - 1].type == "var_value") {
if (window.open_or_close == "open") {
window.open_parentheses.insertBefore(
div_to_render.find(
'.single_element_expression[data-index="' +
(index_in_array - 1) +
'"]'
)
);
window.inserir_open = index_in_array - 1;
}
}
// buscar para a direita agora:
if (expression_array[index_in_array + 1] == "(") {
// buscar o fechamento:
var count_opened = 0;
var count_closed = 0;
for (var j = index_in_array + 1; j < expression_array.length; j++) {
if (expression_array[j] == "(") {
count_opened++;
}
if (expression_array[j] == ")") {
count_closed++;
}
if (count_opened != count_closed) {
} else {
if (count_opened > 0) {
if (window.open_or_close == "close") {
window.close_parentheses.insertAfter(
div_to_render.find(
'.single_element_expression[data-index="' + j + '"]'
)
);
window.inserir_close = j + 2;
}
break;
}
}
}
} else if (expression_array[index_in_array + 1].type == "var_value") {
if (window.open_or_close == "close") {
window.close_parentheses.insertAfter(
div_to_render.find(
'.single_element_expression[data-index="' +
(index_in_array + 1) +
'"]'
)
);
window.inserir_close = index_in_array + 3;
}
}
}
}
function renderParenthesis (
div_to_render,
expression_content,
command,
function_obj,
position,
expression_array
) {
const ghost_parenthesis = $(
'' +
expression_content +
"
"
);
div_to_render.append(ghost_parenthesis);
}
function renderStartAddOperator (
div_to_render,
types_included,
expression_array,
command,
function_obj,
position
) {
let menu_final =
'";
menu_final = $(menu_final);
const div_temp = $(
''
);
div_temp.append(menu_final);
const div_higher = $('');
div_higher.append(div_temp);
div_to_render.append(div_higher);
menu_final.dropdown("set selected", Models.ARITHMETIC_TYPES.minus);
div_temp.on("click", function () {
if (!window.open_or_close) {
const sera = position;
if (types_included.indexOf(Models.EXPRESSION_TYPES.exp_arithmetic) >= 0) {
expression_array.splice(
sera,
0,
new Models.ExpressionOperator(
Models.EXPRESSION_TYPES.exp_arithmetic,
Models.ARITHMETIC_TYPES.minus
)
);
} else if (
types_included.indexOf(Models.EXPRESSION_TYPES.exp_logic) >= 0
) {
expression_array.splice(
sera,
0,
new Models.ExpressionOperator(
Models.EXPRESSION_TYPES.exp_logic,
Models.LOGIC_COMPARISON.equals_to
)
);
} else if (
types_included.indexOf(Models.EXPRESSION_TYPES.exp_conditional) >= 0
) {
expression_array.splice(
sera,
0,
new Models.ExpressionOperator(
Models.EXPRESSION_TYPES.exp_conditional,
Models.ARITHMETIC_COMPARISON.greater_than
)
);
}
renderExpression(command, function_obj, div_to_render, expression_array);
}
});
}
function renderFinalAddElements (
div_to_render,
types_included,
expression_array,
command,
function_obj,
position,
is_last = false
) {
let menu_final =
'";
menu_final = $(menu_final);
const div_temp = $('');
const div_higher = $('');
const button = $(
''
);
div_temp.append(button);
if (!is_last) {
div_higher.append(div_temp);
div_to_render.append(div_higher);
//div_temp.append(menu_final);
div_temp.css("opacity", "0", "!important");
} else {
div_temp.removeClass("mouse_distance");
div_temp.css("opacity", "1", "!important");
//div_temp.append(menu_final);
div_to_render.append(div_temp);
}
menu_final.dropdown("set selected", Models.ARITHMETIC_TYPES.plus);
div_temp.on("click", function () {
const sera = position;
if (expression_array[sera] == ")" && expression_array[sera - 1] == "(") {
expression_array.splice(
sera,
0,
new Models.VariableValueMenu(
VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all,
null,
null,
null,
true
)
);
renderExpression(command, function_obj, div_to_render, expression_array);
return;
}
if (types_included.indexOf(Models.EXPRESSION_TYPES.exp_arithmetic) >= 0) {
expression_array.splice(
sera,
0,
new Models.ExpressionOperator(
Models.EXPRESSION_TYPES.exp_arithmetic,
Models.ARITHMETIC_TYPES.plus
)
);
expression_array.splice(
sera + 1,
0,
new Models.VariableValueMenu(
VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all,
null,
null,
null,
true
)
);
} else if (types_included.indexOf(Models.EXPRESSION_TYPES.exp_logic) >= 0) {
expression_array.splice(
sera,
0,
new Models.ExpressionOperator(
Models.EXPRESSION_TYPES.exp_logic,
Models.LOGIC_COMPARISON.equals_to
)
);
expression_array.splice(
sera + 1,
0,
new Models.VariableValueMenu(
VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all,
null,
null,
null,
true
)
);
} else if (
types_included.indexOf(Models.EXPRESSION_TYPES.exp_conditional) >= 0
) {
expression_array.splice(
sera,
0,
new Models.ExpressionOperator(
Models.EXPRESSION_TYPES.exp_conditional,
Models.ARITHMETIC_COMPARISON.greater_than
)
);
expression_array.splice(
sera + 1,
0,
new Models.VariableValueMenu(
VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all,
null,
null,
null,
true
)
);
}
renderExpression(command, function_obj, div_to_render, expression_array);
});
}
function renderOperatorMenu (
command,
function_obj,
div_to_render,
expression_element,
types_included,
position,
expression_array
) {
let menu_final =
'";
menu_final = $(menu_final);
menu_final.find(".ivprog-write-sep").popup({
content: LocalizedStrings.getUI("write_seprator_menu_tooltip"),
delay: {
show: 500,
hide: 0,
},
});
const div_temp = $(
''
);
div_temp.append(menu_final);
div_to_render.append(div_temp);
menu_final.dropdown({
onChange: function (_value, _text, $selectedItem) {
expression_element.item = $selectedItem.data("value");
expression_element.type_op = $selectedItem.data("type");
},
});
menu_final.dropdown("set selected", expression_element.item);
}
function getArithmeticOperators () {
let arithmetic_operators;
arithmetic_operators =
'+
';
arithmetic_operators +=
'-
';
arithmetic_operators +=
'*
';
arithmetic_operators +=
'/
';
arithmetic_operators +=
'%
';
return arithmetic_operators;
}
function getLogicOperators () {
let logic_operators;
logic_operators =
'==
';
logic_operators +=
'!=
';
logic_operators +=
'' +
LocalizedStrings.getUI("logic_operator_and") +
"
";
logic_operators +=
'' +
LocalizedStrings.getUI("logic_operator_or") +
"
";
logic_operators +=
'' +
LocalizedStrings.getUI("logic_operator_not") +
"
";
return logic_operators;
}
function getRelationalOperators () {
let relational_operators;
relational_operators =
'>
';
relational_operators +=
'<
';
relational_operators +=
'==
';
relational_operators +=
'!=
';
relational_operators +=
'>=
';
relational_operators +=
'<=
';
return relational_operators;
}
function getSeparator () {
return `${LocalizedStrings.getUI(
"write_seprator_menu_text"
)}
`;
}