').addClass('error').text(error['art']));
1094 | }
1095 | if (error['preis'] !== undefined) {
1096 | $('#input .td-preis').append($('
').addClass('error').text(error['preis']));
1097 | }
1098 | }
1099 | }
1100 |
1101 | function deleteError(id) {
1102 | if (id !== undefined && id !== null) {
1103 | $('.ausgabe[data-id=' + id + '] .error').remove();
1104 | } else {
1105 | $('#input .error').remove();
1106 | }
1107 | }
1108 |
1109 | function formatPreisInput(element) {
1110 | let value = convertPreisToNumber(element.value);
1111 | value = formatPreisWithoutSymbol(value);
1112 | element.value = value;
1113 | }
1114 |
1115 | function saveEntry() {
1116 | var error = {};
1117 | var showError = false;
1118 |
1119 | deleteError();
1120 |
1121 | var datumEntry = $('#input-datum').val();
1122 | if (datumEntry === undefined || datumEntry === "") {
1123 | error['datum'] = "Datum fehlt";
1124 | showError = true;
1125 | } else {
1126 | var datumDB = "";
1127 | if (datumEntry.indexOf(".") > 0) {
1128 | datumDB = localToDate(datumEntry);
1129 | } else {
1130 | datumDB = datumEntry;
1131 | datumEntry = dateToLocal(datumEntry);
1132 | }
1133 | }
1134 |
1135 | var kategorie = $('#input-kategorie').val();
1136 |
1137 | var art = $('#input-art').val();
1138 | if (art === undefined || art === "") {
1139 | error['art'] = "Art der Ausgabe fehlt";
1140 | showError = true;
1141 | }
1142 |
1143 | var preis = $('#input-preis').val();
1144 | if (preis === undefined || preis === "" || preis === NaN) {
1145 | error['preis'] = "Preis fehlt";
1146 | showError = true;
1147 | } else {
1148 | var preisDB = convertPreisToNumber(preis);
1149 | }
1150 |
1151 | var beschreibung = $('#input-beschreibung').val();
1152 |
1153 | if (showError) {
1154 | fehlerAnzeigen(error);
1155 | } else {
1156 | var entry = {};
1157 | entry.datumDB = datumDB;
1158 | entry.datum = datumEntry;
1159 | entry.kategorie = kategorie;
1160 | entry.art = art;
1161 | entry.preisDB = preisDB;
1162 | entry.beschreibung = beschreibung;
1163 |
1164 | //Falls neue Ausgabe nicht im aktuell gewählten Monat ist wird der dazugehörige Monat geladen
1165 | var datumM;
1166 | if (datumDB.split("-")[0].length < 4) {
1167 | datumM = moment(datumDB, "YY-M-D");
1168 | } else {
1169 | datumM = moment(datumDB, "YYYY-M-D");
1170 | }
1171 |
1172 | if (datum.month() !== datumM.month() || datum.year() !== datumM.year()) {
1173 | datum.month(datumM.month());
1174 | datum.year(datumM.year());
1175 | andererMonat(saveEntryRequest, entry);
1176 | } else {
1177 | saveEntryRequest(entry);
1178 | }
1179 | }
1180 | }
1181 |
1182 | function saveEntryRequest(entry) {
1183 | var params = {
1184 | datum: entry.datumDB,
1185 | art: encodeURIComponent(entry.art),
1186 | preis: entry.preisDB,
1187 | action: 'add',
1188 | entrytype: currentView,
1189 | };
1190 | if (entry.kategorie) {
1191 | params.kategorie = encodeURIComponent(entry.kategorie);
1192 | }
1193 | if (entry.beschreibung) {
1194 | params.beschreibung = encodeURIComponent(entry.beschreibung);
1195 | }
1196 |
1197 | $.post("api.php", params).done(function (result) {
1198 | var json = JSON.parse(result);
1199 | if (json['error'] === undefined) {
1200 | //remove empty view if visible
1201 | $('#empty').remove();
1202 | var element = createRow(json['id'], entry.datum, entry.kategorie, entry.art, entry.preisDB, entry.beschreibung);
1203 | element.className += " new";
1204 | //TODO: insert new Ausgabe at the appropriate position
1205 | document.getElementById("ausgabenliste").appendChild(element);
1206 | $('.ausgabe[data-id=' + json['id'] + ']')[0].scrollIntoView();
1207 |
1208 | if (json['entrytype'] === 'earnings') {
1209 | addEarnings(entry.preisDB);
1210 | var einnahme = {
1211 | ideinnahme: json['id'],
1212 | art: entry.art,
1213 | beschreibung: entry.beschreibung,
1214 | datum: entry.datumDB,
1215 | kategorie: entry.kategorie,
1216 | preis: convertPreisToPoint(entry.preisDB)
1217 | };
1218 | addEarningsToJSON(einnahme);
1219 | } else {
1220 | addSpendings(entry.preisDB);
1221 | var ausgabe = {
1222 | idausgabe: json['id'],
1223 | art: entry.art,
1224 | beschreibung: entry.beschreibung,
1225 | datum: entry.datumDB,
1226 | kategorie: entry.kategorie,
1227 | preis: convertPreisToPoint(entry.preisDB)
1228 | };
1229 | addSpendingsToJSON(ausgabe);
1230 | }
1231 |
1232 | clearInput();
1233 |
1234 | entry = {};
1235 | } else {
1236 | errorHandling(json);
1237 | }
1238 | });
1239 | }
1240 |
1241 | function clearInput() {
1242 | $('#input-datum, #input-kategorie, #input-art, #input-preis, #input-beschreibung, #datepicker').val("");
1243 | $('#input-datum').focus();
1244 | }
1245 |
1246 | /**
1247 | * @param float preis Preis der hinzugefügt werden soll, negative Werte zum abziehen
1248 | */
1249 | function addSpendings(preis) {
1250 | var amount = parseFloat(json['summeausgaben']);
1251 | amount += parseFloat(preis); //TODO why parseFloat?
1252 | setSpendings(amount);
1253 | json['summeausgaben'] = amount + "";
1254 | }
1255 |
1256 | function setSpendings(amount) {
1257 | $('#spendings').html("Ausgaben " + Math.round(amount) + " €");
1258 | document.querySelector("#spendings").setAttribute("data-amount", amount);
1259 | }
1260 |
1261 | function addSpendingsToJSON(ausgabe) {
1262 | json['ausgaben'].push(ausgabe);
1263 | }
1264 |
1265 | function changeSpending(params) {
1266 | for (var i = 0; i < json['ausgaben'].length; i++) {
1267 | if (json['ausgaben'][i]['idausgabe'] == params.idausgabe) {
1268 | var entry = json['ausgaben'][i]
1269 | if (params.datum) {
1270 | entry['datum'] = params.datum;
1271 | }
1272 | if (params.kategorie) {
1273 | entry['kategorie'] = params.kategorie;
1274 | }
1275 | if (params.art) {
1276 | entry['art'] = params.art;
1277 | }
1278 | if (params.preis) {
1279 | entry['preis'] = params.preis;
1280 | }
1281 | if (params.beschreibung) {
1282 | entry['beschreibung'] = params.beschreibung;
1283 | }
1284 | break;
1285 | }
1286 | }
1287 | }
1288 |
1289 | function addEarnings(preis) {
1290 | var amount = parseFloat(json['summeeinnahmen']);
1291 | amount += parseFloat(preis); //TODO why parseFloat?
1292 | setEarnings(amount);
1293 | json['summeeinnahmen'] = amount + "";
1294 | }
1295 |
1296 | function setEarnings(amount) {
1297 | $('#earnings').html("Einnahmen " + Math.round(amount) + " €");
1298 | document.querySelector("#earnings").setAttribute("data-amount", amount);
1299 | }
1300 |
1301 | function addEarningsToJSON(einnahme) {
1302 | json['einnahmen'].push(einnahme);
1303 | }
1304 |
1305 | function changeEarning(params) {
1306 | for (var i = 0; i < json['einnahmen'].length; i++) {
1307 | if (json['einnahmen'][i]['ideinnahme'] == params.ideinnahme) {
1308 | var entry = json['einnahmen'][i]
1309 | if (params.datum) {
1310 | entry['datum'] = params.datum;
1311 | }
1312 | if (params.kategorie) {
1313 | entry['kategorie'] = params.kategorie;
1314 | }
1315 | if (params.art) {
1316 | entry['art'] = params.art;
1317 | }
1318 | if (params.preis) {
1319 | entry['preis'] = params.preis;
1320 | }
1321 | if (params.beschreibung) {
1322 | entry['beschreibung'] = params.beschreibung;
1323 | }
1324 | break;
1325 | }
1326 | }
1327 | }
1328 |
1329 | /**
1330 | * @param date Datum in DB-Format
1331 | * @return Datum in lokalen Format
1332 | */
1333 | function dateToLocal(date) {
1334 | var a = date.split("-");
1335 | return a[2] + "." + a[1] + "." + a[0];
1336 | }
1337 |
1338 | /**
1339 | * @param date Datum in lokalen Format
1340 | * @return Datum in DB-Format
1341 | */
1342 | function localToDate(date) {
1343 | var a = date.split(".");
1344 | return a[2] + "-" + a[1] + "-" + a[0];
1345 | }
1346 |
1347 | function createRow(id, datum, kategorie, art, preis, beschreibung) {
1348 |
1349 | var html = `
1350 |
${datum}
1351 |
${kategorie}
1352 |
${art}
1353 |
${formatPreis(preis)}
1354 |
${beschreibung}
1355 |
`;
1358 |
1359 | var element = document.createElement("div");
1360 | element.setAttribute("data-id", id);
1361 | element.className = "tr ausgabe";
1362 | element.innerHTML = html;
1363 | element.getElementsByClassName("remove")[0].addEventListener("click", removeEntry, false);
1364 | element.getElementsByClassName("edit")[0].addEventListener("click", editEntry, false);
1365 | return element;
1366 | }
1367 |
1368 | function getDataFromJSON(id) {
1369 | if (currentView === "spendings") {
1370 | return json['ausgaben'].find(entry => entry.idausgabe === id);
1371 | } else {
1372 | return json['einnahmen'].find(entry => entry.ideinnahme === id);
1373 | }
1374 | }
1375 |
1376 | function editEntry(e) {
1377 | var el = e.target;
1378 | var ausgabenElement = el.parentNode.parentNode;
1379 |
1380 | let dataID = ausgabenElement.getAttribute('data-id');
1381 | let data = getDataFromJSON(dataID);
1382 | console.log(data); // TODO remove
1383 |
1384 | hideEditControls(el.parentNode);
1385 |
1386 | var update = document.createElement("div");
1387 | update.addEventListener("click", updateEntry, "false");
1388 | update.className = "update icon-ok";
1389 |
1390 | var cancel = document.createElement("div");
1391 | cancel.addEventListener("click", cancelEditEntry, "false");
1392 | cancel.className = "cancel icon-cancel";
1393 |
1394 | el.parentNode.appendChild(update);
1395 | el.parentNode.appendChild(cancel);
1396 |
1397 | [...ausgabenElement.querySelectorAll('div.td')]
1398 | .forEach(function (td) {
1399 | if (td.classList.contains('td-datum')) {
1400 | td.innerHTML = '
';
1401 | } else if (td.classList.contains('td-kategorie')) {
1402 | td.innerHTML = '
';
1403 | } else if (td.classList.contains('td-art')) {
1404 | td.innerHTML = '
';
1405 | } else if (td.classList.contains('td-preis')) {
1406 | // type=tel: workaround for number field validation (I want to have a numeric keyboard)
1407 | td.innerHTML =
1408 | '
€';
1409 | td.querySelector('input').addEventListener('change', e => formatPreisInput(e.target));
1410 | } else if (td.classList.contains('td-beschreibung')) {
1411 | td.innerHTML = '
';
1412 | }
1413 | });
1414 |
1415 | ausgabenElement.classList.add("tr-edit");
1416 | }
1417 |
1418 | function cancelEditEntry(e) {
1419 | var tdOptionen = e.target.parentNode;
1420 | removeEditControls(e.target.parentNode);
1421 |
1422 | var trAusgabe = tdOptionen.parentNode;
1423 | reAddEditControls(trAusgabe);
1424 |
1425 | let dataID = trAusgabe.getAttribute('data-id');
1426 | let data = getDataFromJSON(dataID);
1427 | console.log(data); // TODO remove
1428 |
1429 | [...trAusgabe.querySelectorAll('div.td')]
1430 | .forEach(function (td) {
1431 | if (td.classList.contains('td-datum')) {
1432 | td.innerHTML = dateToLocal(data.datum);
1433 | } else if (td.classList.contains('td-kategorie')) {
1434 | td.innerHTML = data.kategorie;
1435 | } else if (td.classList.contains('td-art')) {
1436 | td.innerHTML = data.art;
1437 | } else if (td.classList.contains('td-preis')) {
1438 | td.innerHTML = formatPreis(data.preis);
1439 | } else if (td.classList.contains('td-beschreibung')) {
1440 | td.innerHTML = data.beschreibung;
1441 | }
1442 | });
1443 | }
1444 |
1445 | function updateEntry(e) {
1446 | var error = {};
1447 | var showError = false;
1448 |
1449 | let tdOptionen = e.target.parentNode;
1450 | removeEditControls(tdOptionen);
1451 | editControlShowSpinner(tdOptionen);
1452 |
1453 | var ausgabenElement = tdOptionen.parentNode;
1454 | var id = $(ausgabenElement).attr('data-id');
1455 | deleteError(id);
1456 |
1457 | let dataID = ausgabenElement.getAttribute('data-id');
1458 | let oldData = getDataFromJSON(dataID);
1459 | console.log(oldData); // TODO remove
1460 |
1461 | var params = {};
1462 |
1463 | // TODO prettify dates
1464 | let datumAusgabe = ausgabenElement.querySelector('.td-datum').querySelector('input').value;
1465 | let datumDB = datumAusgabe;
1466 | if (datumAusgabe === undefined || datumAusgabe === "") {
1467 | error['datum'] = "Datum fehlt";
1468 | showError = true;
1469 | } else if (datumAusgabe.indexOf(".") > 0) { // TODO does not work for other date formats
1470 | datumDB = localToDate(datumAusgabe);
1471 | }
1472 | if (oldData.datum !== datumDB) {
1473 | params.datum = datumDB;
1474 | }
1475 |
1476 | if (oldData.kategorie !== $(ausgabenElement).children('.td-kategorie').children('input').val()) {
1477 | params.kategorie = encodeURIComponent($(ausgabenElement).children('.td-kategorie').children('input').val());
1478 | }
1479 |
1480 | if (oldData.art !== $(ausgabenElement).children('.td-art').children('input').val()) {
1481 | var art = $(ausgabenElement).children('.td-art').children('input').val();
1482 | if (art === undefined || art === "") {
1483 | error['art'] = "Art der Ausgabe fehlt";
1484 | showError = true;
1485 | } else {
1486 | params.art = encodeURIComponent(art);
1487 | }
1488 | }
1489 |
1490 | let preis = convertPreisToNumber(ausgabenElement.querySelector('.td-preis').querySelector('input').value);
1491 | if (convertPreisToNumber(oldData.preis) !== preis) {
1492 | if (preis === undefined || preis === "" || preis === NaN) {
1493 | error['preis'] = "Preis fehlt";
1494 | showError = true;
1495 | } else {
1496 | params.preis = convertPreisToPoint(preis);
1497 | }
1498 | }
1499 |
1500 | if (oldData.beschreibung !== $(ausgabenElement).children('.td-beschreibung').children('input').val()) {
1501 | params.beschreibung = encodeURIComponent($(ausgabenElement).children('.td-beschreibung').children('input').val());
1502 | }
1503 |
1504 | if (showError) {
1505 | fehlerAnzeigen(error, id);
1506 | reAddEditControls(ausgabenElement);
1507 | } else if (Object.keys(params).length > 0) {
1508 | if (currentView === "spendings") {
1509 | params.idausgabe = id;
1510 | } else {
1511 | params.ideinnahme = id;
1512 | }
1513 | params.action = 'edit';
1514 | params.entrytype = currentView;
1515 | console.log(params);
1516 | $.post("api.php", params).done(function (result) {
1517 | var json = JSON.parse(result);
1518 | if (json['error'] === undefined) {
1519 |
1520 | if(params.datum !== undefined) {
1521 | oldData.datum = params.datum;
1522 | }
1523 | if(params.kategorie !== undefined) {
1524 | oldData.kategorie = params.kategorie;
1525 | }
1526 | if(params.art !== undefined) {
1527 | oldData.art = params.art;
1528 | }
1529 | if(params.preis !== undefined) {
1530 | oldData.preis = params.preis;
1531 | }
1532 | if(params.beschreibung !== undefined) {
1533 | oldData.beschreibung = params.beschreibung;
1534 | }
1535 | console.log(getDataFromJSON(dataID));
1536 |
1537 | var sameMonth = true;
1538 | if (params.datum !== undefined) {
1539 | var datumM;
1540 | if (params.datum.split("-")[0].length < 4) {
1541 | datumM = moment(params.datum, "YY-M-D");
1542 | } else {
1543 | datumM = moment(params.datum, "YYYY-M-D");
1544 | }
1545 |
1546 | if (datum.month() !== datumM.month() || datum.year() !== datumM.year()) {
1547 | datum.month(datumM.month());
1548 | datum.year(datumM.year());
1549 | andererMonat();
1550 | //andererMonat(/*geänderte Ausgabe markieren*/);
1551 | sameMonth = false;
1552 | }
1553 | }
1554 |
1555 | if (sameMonth) {
1556 | // convert input fields back to normal text
1557 | for (var i = 0; i < (ausgabenElement.childNodes.length - 1); i++) {
1558 | if (ausgabenElement.childNodes[i].nodeType === 1 && ausgabenElement.childNodes[i].className.includes("td")) {
1559 | var text = $(ausgabenElement.childNodes[i]).children('input').val();
1560 | $(ausgabenElement.childNodes[i]).children('input').remove();
1561 | if (ausgabenElement.childNodes[i].classList.contains('preis')) {
1562 | $(ausgabenElement.childNodes[i]).children('span').remove();
1563 | $(ausgabenElement.childNodes[i]).html(convertPreisToComma(text) + ' €');
1564 | } else {
1565 | $(ausgabenElement.childNodes[i]).html(text);
1566 | }
1567 | }
1568 | }
1569 |
1570 | if (params.preis) {
1571 | var preisAlt = convertPreisToPoint(oldData.preis);
1572 | var preisNeu = convertPreisToPoint(params.preis);
1573 | var change = -preisAlt + preisNeu;
1574 | if (currentView === "spendings") {
1575 | addSpendings(parseFloat(change));
1576 | } else {
1577 | addEarnings(parseFloat(change));
1578 | }
1579 | }
1580 |
1581 | if (currentView === "spendings") {
1582 | changeSpending(params);
1583 | } else {
1584 | changeEarning(params);
1585 | }
1586 |
1587 | reAddEditControls(ausgabenElement);
1588 | }
1589 | } else {
1590 | reAddEditControls(ausgabenElement);
1591 | errorHandling(json);
1592 | }
1593 | });
1594 | } else {
1595 | console.log('no changes in entry');
1596 | reAddEditControls(ausgabenElement);
1597 | }
1598 | }
1599 |
1600 | function reAddEditControls(ausgabenElement) {
1601 | $(ausgabenElement).children('.td-optionen').children('.change').remove();
1602 | $(ausgabenElement).children('.td-optionen').children().css('display', '');
1603 | ausgabenElement.classList.remove("tr-edit");
1604 | }
1605 |
1606 | function removeEditControls(tdOptionen) {
1607 | tdOptionen.removeChild(tdOptionen.getElementsByClassName("update")[0]);
1608 | tdOptionen.removeChild(tdOptionen.getElementsByClassName("cancel")[0]);
1609 | }
1610 |
1611 | function prettifyDate() {
1612 | let inDate = $("#input-datum").val();
1613 | let splitChar;
1614 | if (inDate.indexOf(".") > 0 && inDate.indexOf(",") === -1 && inDate.indexOf("-") === -1) {
1615 | splitChar = ".";
1616 | } else if (inDate.indexOf(",") > 0 && inDate.indexOf(".") === -1 && inDate.indexOf("-") === -1) {
1617 | splitChar = ",";
1618 | } else if (inDate.indexOf("-") > 0 && inDate.indexOf(".") === -1 && inDate.indexOf(",") === -1) {
1619 | splitChar = "-";
1620 | } else {
1621 | return;
1622 | }
1623 | if (inDate.length >= 3 && splitChar !== '-') {
1624 | if (occurrences(inDate, splitChar) === 1) {
1625 | let outDate = moment(inDate, "D" + splitChar + "M").year(moment().year()).format("DD.MM.YYYY");
1626 | $("#input-datum").val(outDate);
1627 | } else if (occurrences(inDate, splitChar) === 2) {
1628 | let tempDate = moment(inDate, "D" + splitChar + "M" + splitChar + "YYYY");
1629 | if (tempDate.year() == 0) {
1630 | tempDate.year(moment().year());
1631 | }
1632 | let outDate = tempDate.format("DD.MM.YYYY");
1633 | $("#input-datum").val(outDate);
1634 | }
1635 | } else if (inDate.length >= 5 && splitChar === '-' && occurrences(inDate, splitChar) === 2) {
1636 | let outDate = moment(inDate, "YYYY" + splitChar + "M" + splitChar + "D").format("DD.MM.YYYY");
1637 | $("#input-datum").val(outDate);
1638 | }
1639 | }
1640 |
1641 | function convertPreisToPoint(preis) {
1642 | preis += '';
1643 | preis = preis.replace(",", ".");
1644 | return parseFloat(preis);
1645 | }
1646 |
1647 | function convertPreisToComma(preis) {
1648 | preis += "";
1649 | preis = preis.replace(".", ",");
1650 | if (preis.split(",").length > 1) {
1651 | if (preis.split(",")[1].length === 1) {
1652 | preis += '0';
1653 | }
1654 | } else {
1655 | preis += ',00';
1656 | }
1657 | return preis;
1658 | }
1659 |
1660 | function convertPreisToNumber(preis) {
1661 | if (preis.lastIndexOf('.') > preis.lastIndexOf(',')) { // e.g. 1,000.543
1662 | preis = preis.replace(',', '');
1663 | } else if (preis.lastIndexOf('.') < preis.lastIndexOf(',')) { // e.g 1.000,543
1664 | preis = preis.replace('.', '').replace(',', '.');
1665 | } // else -> both must be -1, therefore no '.' or ','
1666 | return parseFloat(preis);
1667 | }
1668 |
1669 | function formatPreis(preis, withDecimal = true) {
1670 | const options = { style: 'currency', currency: 'EUR' };
1671 | if (!withDecimal) {
1672 | options.minimumFractionDigits = 0;
1673 | options.maximumFractionDigits = 0;
1674 | }
1675 | return new Intl.NumberFormat(undefined, options).format(preis);
1676 | }
1677 |
1678 | function formatPreisWithoutSymbol(preis) {
1679 | return Intl.NumberFormat(undefined, {style: 'currency', currency: 'EUR'})
1680 | .formatToParts(preis).map(({type, value}) => {
1681 | if (type === 'currency' || type === 'literal') {
1682 | return '';
1683 | } else {
1684 | return value;
1685 | }
1686 | }).reduce((string, part) => string + part);
1687 | }
1688 |
1689 | /** Function count the occurrences of substring in a string;
1690 | * @param {String} string Required. The string;
1691 | * @param {String} subString Required. The string to search for;
1692 | * @param {Boolean} allowOverlapping Optional. Default: false;
1693 | * @author Vitim.us http://stackoverflow.com/questions/4009756/how-to-count-string-occurrence-in-string/7924240#7924240
1694 | */
1695 | function occurrences(string, subString, allowOverlapping) {
1696 |
1697 | string += "";
1698 | subString += "";
1699 | if (subString.length <= 0)
1700 | return (string.length + 1);
1701 |
1702 | var n = 0,
1703 | pos = 0,
1704 | step = allowOverlapping ? 1 : subString.length;
1705 |
1706 | while (true) {
1707 | pos = string.indexOf(subString, pos);
1708 | if (pos >= 0) {
1709 | ++n;
1710 | pos += step;
1711 | } else
1712 | break;
1713 | }
1714 | return n;
1715 | }
1716 |
1717 | function hasWebkitDatepicker(element) {
1718 | let style = window.getComputedStyle(document.querySelector('#datepicker'), '::-webkit-calendar-picker-indicator');
1719 | return (style.webkitAppearance !== undefined && style.msWrapFlow === undefined);
1720 | }
1721 |
1722 | // https://stackoverflow.com/a/51411377/1565646
1723 | function getDecimalSeparator(locale) {
1724 | const numberWithDecimalSeparator = 1.1;
1725 | return Intl.NumberFormat(locale)
1726 | .formatToParts(numberWithDecimalSeparator)
1727 | .find(part => part.type === 'decimal')
1728 | .value;
1729 | }
1730 |
--------------------------------------------------------------------------------