"use strict"; function formatMoney(num) { return num.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, "$&,"); } function getInputValue(id) { const el = document.getElementById(id); return el ? parseFloat(el.value) : NaN; } function getThemeColors() { const dark = window.matchMedia("(prefers-color-scheme: dark)").matches; return dark ? { bgColor: "#1a1d27", fgColor: "#e8eaf0", gridColor: "#2d3141", lineColor: "#3d4258" } : { bgColor: "#ffffff", fgColor: "#1a1d23", gridColor: "#e2e6ea", lineColor: "#c8cdd5" }; } function buildAxisLayout(title, colors) { const { bgColor, fgColor, gridColor, lineColor } = colors; return { title: { text: title, font: { color: fgColor, size: 13 } }, paper_bgcolor: bgColor, plot_bgcolor: bgColor, font: { color: fgColor, family: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" }, margin: { t: 40, r: 16, b: 48, l: 60 }, yaxis: { gridcolor: gridColor, zerolinecolor: gridColor, linecolor: lineColor }, xaxis: { title: { text: "Months", font: { size: 11 } }, gridcolor: gridColor, zerolinecolor: gridColor, linecolor: lineColor }, }; } class Data { constructor(balance, contribution, returnRate, inflationRate) { this.balance = balance; this.contribution = contribution; this.returnRate = returnRate; this.inflationRate = inflationRate; } summaryRow() { return ` $${formatMoney(this.balance)} $${formatMoney(this.contribution)} ${this.returnRate.toFixed(2)}% ${this.inflationRate.toFixed(2)}% `; } adjustedRate() { return (1 + this.returnRate / 100) / (1 + this.inflationRate / 100) - 1; } } function showResults(data, monthsArr, balanceArr, interestArr) { const infoTbody = document.querySelector("#infoTable tbody"); infoTbody.innerHTML = data.summaryRow(); document.querySelectorAll(".table-section").forEach((el) => (el.style.display = "block")); const graphCard = document.getElementById("graphCard"); graphCard.style.display = "block"; const colors = getThemeColors(); const balanceTrace = { x: monthsArr, y: balanceArr, type: "scatter", line: { color: "#4f6ef7", width: 2 } }; const interestTrace = { x: monthsArr, y: interestArr, type: "scatter", line: { color: "#22c55e", width: 2 } }; Plotly.newPlot("balChartContainer", [balanceTrace], buildAxisLayout("Total Balance", colors), { responsive: true }); Plotly.newPlot("intChartContainer", [interestTrace], buildAxisLayout("Accrued Interest", colors), { responsive: true }); } function runCalculation(data, stopCondition) { document.querySelectorAll("tbody").forEach((el) => (el.innerHTML = "")); const resultsTbody = document.querySelector(".resultsTable tbody"); const adjustedRate = data.adjustedRate(); const monthlyContr = data.contribution; const monthsArr = []; const balanceArr = []; const interestArr = []; let pVal = data.balance; let i = 0; while (!stopCondition(pVal, i)) { const month = i + 1; const interest = pVal * (adjustedRate / 12); const newBalance = pVal + interest + monthlyContr; const row = document.createElement("tr"); row.innerHTML = `${month}$${formatMoney(interest)}$${formatMoney(monthlyContr)}$${formatMoney(newBalance)}`; resultsTbody.appendChild(row); if (month === 1 || month % 12 === 0) { interestArr.push(Math.round(interest * 100) / 100); balanceArr.push(Math.round(newBalance * 100) / 100); monthsArr.push(month); } pVal = newBalance; i++; } showResults(data, monthsArr, balanceArr, interestArr); } function retirementYears() { var _a; const data = new Data(getInputValue("begBalance"), getInputValue("monthlyContr"), getInputValue("returnRate"), getInputValue("inflationRate")); const years = getInputValue("years"); const totalMonths = years * 12; runCalculation(data, (_bal, i) => i >= totalMonths); (_a = document.getElementById("graphCard")) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: "smooth" }); } function retirementMoney() { var _a; const data = new Data(getInputValue("begBalance"), getInputValue("monthlyContr"), getInputValue("returnRate"), getInputValue("inflationRate")); const target = getInputValue("money"); runCalculation(data, (bal) => bal >= target); (_a = document.getElementById("graphCard")) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: "smooth" }); } window.retirementYears = retirementYears; window.retirementMoney = retirementMoney;