From 6471a4b183c099ff7eafc0ef2c4c1361c860fd1a Mon Sep 17 00:00:00 2001 From: TCB13 Date: Thu, 24 Oct 2024 20:08:11 +0100 Subject: [PATCH] JS Modernization; Credit Simulator; Update math.js --- INCLUDED_LICENSES.txt | 4 +- cache.manifest | 3 +- functions/credit.js | 119 ++++++++++++++++++++++++++++++++++++++++++ index.html | 9 ++-- main.js | 49 +++++++++-------- math.min.js | 58 ++------------------ style.css | 2 +- 7 files changed, 158 insertions(+), 86 deletions(-) create mode 100644 functions/credit.js diff --git a/INCLUDED_LICENSES.txt b/INCLUDED_LICENSES.txt index f263d9d..534f050 100644 --- a/INCLUDED_LICENSES.txt +++ b/INCLUDED_LICENSES.txt @@ -7,14 +7,12 @@ /** * math.js * https://github.com/josdejong/mathjs + * Licensed under Apache License 2.0 (https://github.com/josdejong/mathjs/blob/develop/LICENSE) * * Math.js is an extensive math library for JavaScript and Node.js, * It features real and complex numbers, units, matrices, a large set of * mathematical functions, and a flexible expression parser. * - * @version 5.9.0 - * @date 2019-05-08 - * * @license * Copyright (C) 2013-2019 Jos de Jong * diff --git a/cache.manifest b/cache.manifest index 6a5a73c..55e3527 100644 --- a/cache.manifest +++ b/cache.manifest @@ -1,6 +1,6 @@ CACHE MANIFEST -# Version 0.0.2 +# Version 1.3.0 NETWORK: * @@ -16,5 +16,6 @@ popper.min.js style.css favicons/favicon.ico favicons/icon.svg +functions/credit.js FALLBACK: diff --git a/functions/credit.js b/functions/credit.js new file mode 100644 index 0000000..b3b762e --- /dev/null +++ b/functions/credit.js @@ -0,0 +1,119 @@ +export class Credit { + + static docs = { + name: "credit", + category: "Advanced Functions", + syntax: [ + "credit(principal, interest_rate, remaining_terms)", + "credit(principal, interest_rate, remaining_terms, extra_payment)", + ], + description: "Simulate your credit/mortgage/loan repayment using this function.", + examples: [ + "credit(150000, 2.5, 50)", + "credit(150000, 2.5, 50, 35000)" + ], + seealso: [] + } + + static paymentCalc(principal, interest, terms) { + interest = interest / 100 / 12; + const termPaymentTotal = (principal * interest * Math.pow(1 + interest, terms)) / (Math.pow(1 + interest, terms) - 1); + const termPaymentInterest = principal * interest; + return { + termPaymentTotal, + termPaymentInterest, + termPaymentCapital: termPaymentTotal - termPaymentInterest, + terms, + total: termPaymentTotal * terms + }; + } + + static termCalc(newPrincipal, termPaymentTotal, interest) { + const fInterest = interest / 100 / 12; + const n = Math.log10((termPaymentTotal / fInterest) / ((termPaymentTotal / fInterest) - newPrincipal)) / Math.log10(1 + fInterest); + return Credit.paymentCalc(newPrincipal, interest, n); + } + + static formatNumber(num, fractionDigits = 2) { + return num.toFixed(fractionDigits).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1 ").trim(); + } + + static simulate(principal, interest, terms, extraPayment) { + if (principal === undefined || interest === undefined || terms === undefined) { + throw Error("One or more arguments are missing. Syntax:\n " + Credit.docs.syntax[0] + "\n " + Credit.docs.syntax[1]); + } + if (extraPayment > principal) { + throw Error("The extra payment can't be bigger than the principal"); + } + + const indent = " "; + let rendered = "\n"; + const baseLoan = Credit.paymentCalc(principal, interest, terms); + + let data = [ + ["> Principal", Credit.formatNumber(principal)], + ["> Interest Rate", Credit.formatNumber(interest)], + ["> Remaining Terms", Credit.formatNumber(baseLoan.terms, 0)] + ]; + + if (extraPayment) { + data.push(["> Extra Payment", Credit.formatNumber(extraPayment)]); + } + + data.push(...[ + [], + ["Credit Simulation:"], + [indent + "Term Interest Payment", Credit.formatNumber(baseLoan.termPaymentInterest)], + [indent + "Term Capital Payment", Credit.formatNumber(baseLoan.termPaymentCapital)], + [indent + "Term Total Payment", Credit.formatNumber(baseLoan.termPaymentTotal)], + [indent + "Total", Credit.formatNumber(baseLoan.total)] + ]); + + rendered += Credit.renderOutput(data, 28); + + if (extraPayment) { + const newLoanKeepTerms = Credit.paymentCalc(principal - extraPayment, interest, terms); + const newLoanKeepMonthly = Credit.termCalc(principal - extraPayment, baseLoan.termPaymentTotal, interest); + const extraData = [ + ["Extra Payment Simulation"], + [indent + "Strategy - Term Number:"], + [indent + indent + "Remaining Terms", Credit.formatNumber(newLoanKeepTerms.terms, 0)], + [indent + indent + "Term Interest Payment", Credit.formatNumber(newLoanKeepTerms.termPaymentInterest)], + [indent + indent + "Term Capital Payment", Credit.formatNumber(newLoanKeepTerms.termPaymentCapital)], + [indent + indent + "Term Total Payment", Credit.formatNumber(newLoanKeepTerms.termPaymentTotal), Credit.formatNumber((newLoanKeepTerms.termPaymentTotal - baseLoan.termPaymentTotal))], + [indent + indent + "Total", Credit.formatNumber(newLoanKeepTerms.total), Credit.formatNumber((newLoanKeepTerms.total - baseLoan.total))], + [indent + "Strategy - Term Payment:"], + [indent + indent + "Remaining Terms", Credit.formatNumber(newLoanKeepMonthly.terms, 0), Credit.formatNumber((newLoanKeepMonthly.terms - baseLoan.terms), 0)], + [indent + indent + "Term Interest Payment", Credit.formatNumber(newLoanKeepMonthly.termPaymentInterest)], + [indent + indent + "Term Capital Payment", Credit.formatNumber(newLoanKeepMonthly.termPaymentCapital)], + [indent + indent + "Term Total Payment", Credit.formatNumber(newLoanKeepMonthly.termPaymentTotal)], + [indent + indent + "Total", Credit.formatNumber(newLoanKeepMonthly.total), Credit.formatNumber((newLoanKeepMonthly.total - baseLoan.total))], + ]; + rendered += "\n" + Credit.renderOutput(extraData, 33); + } + rendered += "\n"; + return rendered; + } + + static renderOutput(lines, maxChars = 50) { + let output = ""; + lines.forEach(function (line) { + if (line[0] !== undefined) { + if (line.length === 1 && line[0] === "\\-") { + output += "-------------------------------------"; + } else { + output += line.length === 1 ? "" + line[0] + "" : line[0]; + } + } + if (line[1] !== undefined) { + output += " ".repeat(maxChars - line[0].length) + line[1]; + } + if (line[2] !== undefined) { + output += "\t " + line[2]; + } + output += "\n"; + }); + return output; + } + +} diff --git a/index.html b/index.html index 64eb87c..636f9d1 100644 --- a/index.html +++ b/index.html @@ -2,8 +2,7 @@ - + TBCalc @@ -43,7 +42,7 @@ - + @@ -211,8 +210,8 @@

Settings