Initial Commit

This commit is contained in:
2026-05-28 13:03:57 +00:00
commit beba3eb000
5 changed files with 484 additions and 0 deletions
+34
View File
@@ -0,0 +1,34 @@
function calculate() {
const gross = parseFloat(document.getElementById('grossPay').value) || 0;
const freq = parseInt(document.getElementById('payFreq').value);
const status = document.getElementById('filingStatus').value;
const stateCode = document.getElementById('state').value;
const retPct = parseFloat(document.getElementById('retPct').value) / 100;
const preTax = (parseFloat(document.getElementById('preTaxPay').value) || 0) * freq;
const postTax = (parseFloat(document.getElementById('postTaxPay').value) || 0) * freq;
const other = (parseFloat(document.getElementById('otherPay').value) || 0) * freq;
const cityPct = (parseFloat(document.getElementById('cityTax').value) / 100) || 0;
const stdDed = STD_DEDUCTIONS[status];
document.getElementById('stdDedLabel').textContent = '$' + stdDed.toLocaleString();
const retirement = gross * retPct;
const preTaxTotal = retirement + preTax;
const fedtaxable = Math.max(0, gross - stdDed - preTaxTotal);
const taxable = Math.max(0, gross - preTaxTotal);
const fed = calcBracketTax(fedtaxable, FED_BRACKETS[status]);
const ss = Math.min(gross, SS_BASE) * SS_RATE;
const med = gross * MED_RATE;
const addMed = gross > ADD_MED_THRESH[status] ? (gross - ADD_MED_THRESH[status]) * 0.009 : 0;
const fica = ss + med + addMed;
const stTax = calcStateTax(taxable, stateCode);
const ctTax = Math.max(0,taxable * cityPct);
const totalTax = fed + fica + stTax + ctTax;
const totalDeductions = preTaxTotal + postTax + other + totalTax;
const net = gross - totalDeductions;
const netPer = net / freq;
currentData = { gross, retPct, retirement, preTax, preTaxTotal, postTax, other, fed, ss, med, addMed, fica, stTax, ctTax, totalTax, net, netPer, taxable, stdDed, freq, status, stateCode };
renderResults(currentData);
}
+212
View File
@@ -0,0 +1,212 @@
function calcBracketTax(taxable, brackets) {
let tax = 0, remaining = taxable;
for (let b of brackets) {
if (remaining <= 0) break;
let inBracket = Math.min(remaining, Math.max(0, b.max - b.min));
tax += inBracket * b.r;
remaining -= inBracket;
}
return tax;
}
function calcStateTax(taxable, stateCode) {
const s = STATE_DATA[stateCode] || {t:'none'};
if (s.t === 'none') return 0;
if (s.t === 'flat') return Math.max(0, taxable * s.v);
if (s.t === 'brackets') return calcBracketTax(taxable, s.v);
return 0;
}
function formatMoney(n) {
//return '$' + Math.round(n).toLocaleString('en-US');
return '$' + n.toFixed(2).toLocaleString('en-US');
}
let currentData = {};
function renderResults(d) {
const panel = document.getElementById('rightPanel');
panel.innerHTML = `
<div class="card fade-in">
<h2><span class="icon">💵</span> Paycheck Breakdown</h2>
<div class="results-grid">
<div class="result-box primary">
<div class="label">Net Take-Home</div>
<div class="value positive">${formatMoney(d.net)}</div>
<div class="sub">/year | ${formatMoney(d.netPer)} /${d.freq === 52 ? 'week' : d.freq === 26 ? '2 weeks' : d.freq === 24 ? '2 weeks' : d.freq === 12 ? 'month' : 'year'}</div>
</div>
<div class="result-box">
<div class="label">Federal Tax</div>
<div class="value negative">${formatMoney(d.fed)}</div>
<div class="sub effective-rate">${(d.fed/d.gross*100||0).toFixed(1)}% effective rate</div>
</div>
<div class="result-box">
<div class="label">FICA (SS + Medicare)</div>
<div class="value negative">${formatMoney(d.fica)}</div>
<div class="sub">SS: ${formatMoney(d.ss)} | Medicare: ${formatMoney(d.med + d.addMed)}</div>
</div>
<div class="result-box">
<div class="label">State Tax</div>
<div class="value negative">${formatMoney(d.stTax)}</div>
<div class="sub effective-rate">${(d.stTax/d.gross*100||0).toFixed(1)}% effective rate</div>
</div>
<div class="result-box">
<div class="label">City Tax</div>
<div class="value negative">${formatMoney(d.ctTax)}</div>
<div class="sub effective-rate">${(d.ctTax/d.gross*100||0).toFixed(1)}% effective rate</div>
</div>
<div class="result-box">
<div class="label">Retirement (401k)</div>
<div class="value accent">${formatMoney(d.retirement)}</div>
<div class="sub">${(d.retPct*100).toFixed(1)}% of gross</div>
</div>
<div class="result-box">
<div class="label">Other Deductions</div>
<div class="value">${formatMoney(d.preTax + d.postTax + d.other)}</div>
<div class="sub">Pre/Post/Other combined</div>
</div>
</div>
</div>
<div class="card fade-in">
<h2><span class="icon">📊</span> Allocation Breakdown</h2>
<table class="breakdown-table">
<thead><tr><th>Category</th><th>Annual</th><th>Per Pay</th><th>% of Gross</th></tr></thead>
<tbody>
<tr><td>Gross Pay</td><td class="amount">${formatMoney(d.gross)}</td><td class="amount">${formatMoney(d.gross/d.freq)}</td><td class="amount">100%</td></tr>
<tr><td>Retirement (401k)</td><td class="amount negative">${formatMoney(d.retirement)}</td><td class="amount">${formatMoney(d.retirement/d.freq)}</td><td class="amount">${(d.retPct*100).toFixed(1)}%</td></tr>
<tr><td>Pre-Tax Deductions</td><td class="amount negative">${formatMoney(d.preTax)}</td><td class="amount">${formatMoney(d.preTax/d.freq)}</td><td class="amount">${(d.preTax/d.gross*100).toFixed(1)}%</td></tr>
<tr><td>Federal Tax</td><td class="amount negative">${formatMoney(d.fed)}</td><td class="amount">${formatMoney(d.fed/d.freq)}</td><td class="amount">${(d.fed/d.gross*100).toFixed(1)}%</td></tr>
<tr><td>FICA (SS + Med)</td><td class="amount negative">${formatMoney(d.fica)}</td><td class="amount">${formatMoney(d.fica/d.freq)}</td><td class="amount">${(d.fica/d.gross*100).toFixed(1)}%</td></tr>
<tr><td>State Tax</td><td class="amount negative">${formatMoney(d.stTax)}</td><td class="amount">${formatMoney(d.stTax/d.freq)}</td><td class="amount">${(d.stTax/d.gross*100).toFixed(1)}%</td></tr>
<tr><td>City Tax</td><td class="amount negative">${formatMoney(d.ctTax)}</td><td class="amount">${formatMoney(d.ctTax/d.freq)}</td><td class="amount">${(d.ctTax/d.gross*100).toFixed(1)}%</td></tr>
<tr><td>Post-Tax & Other</td><td class="amount negative">${formatMoney(d.postTax + d.other)}</td><td class="amount">${formatMoney((d.postTax + d.other)/d.freq)}</td><td class="amount">${((d.postTax + d.other)/d.gross*100).toFixed(1)}%</td></tr>
<tr class="total-row"><td><strong>Net Take-Home</strong></td><td class="amount positive"><strong>${formatMoney(d.net)}</strong></td><td class="amount"><strong>${formatMoney(d.netPer)}</strong></td><td class="amount"><strong>${(d.net/d.gross*100).toFixed(1)}%</strong></td></tr>
</tbody>
</table>
</div>
<div class="card fade-in analysis-section">
<h3><span class="icon">🔄</span> Retirement Contribution Analysis</h3>
<div class="slider-container">
<label>401(k) Contribution <span id="sliderVal">${(d.retPct*100).toFixed(1)}%</span></label>
<input type="range" id="retSlider" min="0" max="25" step="0.5" value="${(d.retPct*100)}" oninput="updateAnalysis()">
</div>
<div class="comparison-table">
<table>
<thead><tr><th>Contribution %</th><th>Annual 401k</th><th>Net Pay / Period</th><th>Effective Tax Rate</th><th>Annual Take-Home</th></tr></thead>
<tbody id="analysisBody"></tbody>
</table>
</div>
<div class="chart-container"><canvas id="analysisChart"></canvas></div>
<div class="savings-summary">
<div class="savings-box">
<div class="sb-label">Annual Tax Shield</div>
<div class="sb-value positive">-${formatMoney(d.fed * d.retPct)}</div>
</div>
<div class="savings-box">
<div class="sb-label">Annual 401k Savings</div>
<div class="sb-value accent">${formatMoney(d.retirement)}</div>
</div>
</div>
</div>
`;
updateAnalysis();
}
function updateAnalysis() {
if (!currentData.gross) return;
const d = currentData;
const currentPct = parseFloat(document.getElementById('retSlider').value);
document.getElementById('sliderVal').textContent = currentPct.toFixed(1) + '%';
const rows = [];
const step = 1;
for (let p = 0; p <= 25; p += step) {
const pct = p / 100;
const retAmt = d.gross * pct;
const stateCode = document.getElementById('state').value;
const fedtaxable = Math.max(0, d.gross - d.stdDed - retAmt - d.preTax);
const taxable = Math.max(0, d.gross - retAmt - d.preTax);
const fed = calcBracketTax(fedtaxable, FED_BRACKETS[d.status]);
const fica = d.fica; // SS/Medicare don't change with 401k
//const stTax = d.stTax;
const stTax = calcStateTax(taxable, stateCode);
const cityPct = (parseFloat(document.getElementById('cityTax').value) / 100) || 0;
const ctTax = Math.max(0,taxable * cityPct);
const net = d.gross - retAmt - d.preTax - fed - fica - stTax - ctTax - d.postTax - d.other;
const netPer = net / d.freq;
const effRate = d.gross > 0 ? ((fed + fica + stTax + ctTax) / d.gross) * 100 : 0;
rows.push({pct, retAmt, netPer, effRate, net});
}
const tbody = document.getElementById('analysisBody');
tbody.innerHTML = rows.map(r => `
<tr class="${Math.abs(r.pct - currentPct) < 0.01 ? 'highlight-row' : ''}">
<td>${(r.pct*100).toFixed(1)}%</td>
<td>${formatMoney(r.retAmt)}</td>
<td>${formatMoney(r.netPer)}</td>
<td>${r.effRate.toFixed(1)}%</td>
<td>${formatMoney(r.net)}</td>
</tr>
`).join('');
drawChart(rows, currentPct);
}
function drawChart(rows, currentPct) {
const canvas = document.getElementById('analysisChart');
const ctx = canvas.getContext('2d');
const dpr = window.devicePixelRatio || 1;
const rect = canvas.parentElement.getBoundingClientRect();
canvas.width = rect.width * dpr;
canvas.height = rect.height * dpr;
ctx.scale(dpr, dpr);
const w = rect.width, h = rect.height;
ctx.clearRect(0, 0, w, h);
const maxVal = Math.max(...rows.map(r => r.net));
const barWidth = Math.min((w - 40) / rows.length * 0.6, 40);
const gap = (w - 40) / rows.length * 0.4;
rows.forEach((r, i) => {
const barH = (r.net / maxVal) * (h - 50);
const x = 20 + i * (barWidth + gap);
const y = h - 30 - barH;
ctx.fillStyle = Math.abs(r.pct - currentPct) < 0.005 ? '#6c5ce7' : '#2d3148';
ctx.beginPath();
ctx.roundRect(x, y, barWidth, barH, 4);
ctx.fill();
ctx.fillStyle = '#8b8fa3';
ctx.font = '11px sans-serif';
ctx.textAlign = 'center';
ctx.fillText((r.pct*100).toFixed(0) + '%', x + barWidth/2, h - 10);
if (Math.abs(r.pct - currentPct) < 0.005) {
ctx.fillStyle = '#a29bfe';
ctx.font = 'bold 12px sans-serif';
ctx.fillText(formatMoney(r.net), x + barWidth/2, y - 8);
}
});
}
// Wire up events
document.getElementById('calcBtn').addEventListener('click', calculate);
document.getElementById('retPct').addEventListener('input', (e) => {
document.getElementById('retPctDisplay').textContent = e.target.value + '%';
});
document.getElementById('cityTax').addEventListener('input', (e) => {
document.getElementById('cityTaxDisplay').textContent = e.target.value + '%';
});
// Auto-calculate on load
window.addEventListener('DOMContentLoaded', () => {
// Attach listeners to all inputs for auto-update
['grossPay','payCheck','payFreq','filingStatus','state','preTaxPay','postTaxPay','otherPay'].forEach(id => {
document.getElementById(id).addEventListener('input', calculate);
document.getElementById(id).addEventListener('change', calculate);
});
calculate();
});
+25
View File
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Take-Home Pay Calculator & Retirement Analyzer</title>
<link rel="stylesheet" href="retirement.css">
</head>
<body>
<div class="container">
<header>
<a href="/">
<h1>💰 Take-Home Pay Calculator</h1>
</a>
<p>2026 Federal & State Tax Calculator with Retirement Analysis</p>
<a href="/annual">
<button class="btn">Use Annual Salary</button>
</a>
<a href="/paycheck">
<button class="btn">Use Last Paycheck</button>
</a>
</header>
</div>
</body>
</html>
+107
View File
@@ -0,0 +1,107 @@
:root {
--bg: #0f1117; --card: #1a1d28; --card-alt: #222636;
--accent: #6c5ce7; --accent-light: #a29bfe;
--green: #00cec9; --red: #ff6b6b; --orange: #fdcb6e;
--text: #e2e4f0; --text-dim: #8b8fa3; --border: #2d3148;
--input-bg: #161825;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
background: var(--bg); color: var(--text); min-height: 100vh; line-height: 1.5;
}
.container { max-width: 1400px; margin: 0 auto; padding: 20px; }
header { text-align: center; padding: 30px 0 10px; }
header h1 {
font-size: 2.2rem;
background: linear-gradient(135deg, var(--accent-light), var(--green));
-webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
margin-bottom: 6px;
}
header a { text-decoration: none; }
header p { color: var(--text-dim); font-size: 1rem; }
.layout { display: grid; grid-template-columns: 380px 1fr; gap: 24px; margin-top: 24px; }
.card { background: var(--card); border: 1px solid var(--border); border-radius: 16px; padding: 24px; }
.card h2 { font-size: 1.15rem; margin-bottom: 18px; display: flex; align-items: center; gap: 8px; }
.input-group { margin-bottom: 16px; }
.input-group label {
display: block; font-size: 0.82rem; color: var(--text-dim); margin-bottom: 5px;
font-weight: 500; text-transform: uppercase; letter-spacing: 0.5px;
}
.input-group input, .input-group select {
width: 100%; padding: 10px 14px; background: var(--input-bg);
border: 1px solid var(--border); border-radius: 10px; color: var(--text);
font-size: 0.95rem; outline: none; transition: border-color 0.2s;
}
.input-group input:focus, .input-group select:focus { border-color: var(--accent); }
.input-group select { cursor: pointer; appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%238b8fa3' viewBox='0 0 16 16'%3E%3Cpath d='M8 11L3 6h10l-5 5z'/%3E%3C/svg%3E");
background-repeat: no-repeat; background-position: right 12px center; padding-right: 32px;
}
.input-group select option { background: var(--card); }
.btn {
width: 100%; padding: 12px; background: linear-gradient(135deg, var(--accent), #8b5cf6);
color: #fff; border: none; border-radius: 10px; font-size: 1rem; font-weight: 600;
cursor: pointer; transition: transform 0.15s, box-shadow 0.2s; margin-top: 8px;
}
.btn:hover { transform: translateY(-1px); box-shadow: 0 6px 20px rgba(108,92,231,0.35); }
.right-panel { display: flex; flex-direction: column; gap: 24px; }
.results-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; }
.result-box {
background: var(--card-alt); border-radius: 12px; padding: 18px;
text-align: center; border: 1px solid var(--border);
}
.result-box.primary {
background: linear-gradient(135deg, rgba(108,92,231,0.15), rgba(0,206,201,0.1));
border-color: var(--accent);
}
.result-box .label { font-size: 0.75rem; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px; }
.result-box .value { font-size: 1.6rem; font-weight: 700; }
.result-box .sub { font-size: 0.78rem; color: var(--text-dim); margin-top: 2px; }
.result-box .value.positive { color: var(--green); }
.result-box .value.negative { color: var(--red); }
.result-box .value.accent { color: var(--accent-light); }
.breakdown-table { width: 100%; border-collapse: collapse; }
.breakdown-table th, .breakdown-table td { padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--border); font-size: 0.9rem; }
.breakdown-table th { color: var(--text-dim); font-weight: 600; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.5px; }
.breakdown-table tr:last-child td { border-bottom: none; }
.breakdown-table .amount { text-align: right; font-variant-numeric: tabular-nums; }
.breakdown-table .total-row td { border-top: 2px solid var(--border); font-weight: 700; padding-top: 14px; }
.slider-container { margin-bottom: 16px; }
.slider-container label { display: flex; justify-content: space-between; align-items: center; font-size: 0.85rem; color: var(--text-dim); margin-bottom: 10px; }
.slider-container label span { font-weight: 700; color: var(--accent-light); font-size: 1rem; }
input[type="range"] {
-webkit-appearance: none; width: 100%; height: 6px; background: var(--border);
border-radius: 3px; outline: none;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none; width: 22px; height: 22px; border-radius: 50%;
background: var(--accent); cursor: pointer; box-shadow: 0 0 10px rgba(108,92,231,0.4);
}
.chart-container { position: relative; height: 300px; margin-top: 10px; }
canvas { width: 100% !important; height: 100% !important; }
.empty-state { text-align: center; padding: 60px 20px; color: var(--text-dim); }
.empty-state .icon { font-size: 3rem; margin-bottom: 12px; }
.tax-brackets-info {
font-size: 0.78rem; color: var(--text-dim); margin-top: 12px; padding: 12px;
background: rgba(108,92,231,0.05); border-radius: 8px; border: 1px solid var(--border);
}
.tax-brackets-info strong { color: var(--accent-light); }
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 900px) { .layout { grid-template-columns: 1fr; } .results-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 600px) { .results-grid { grid-template-columns: 1fr; } .two-col { grid-template-columns: 1fr; } }
.fade-in { animation: fadeIn 0.3s ease-in; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.effective-rate { font-size: 0.8rem; color: var(--text-dim); margin-top: 2px; }
.analysis-section h3 { font-size: 1rem; margin-bottom: 16px; }
.comparison-table { margin-top: 16px; }
.comparison-table table { width: 100%; border-collapse: collapse; }
.comparison-table th, .comparison-table td { padding: 10px 12px; text-align: right; font-size: 0.85rem; border-bottom: 1px solid var(--border); }
.comparison-table th { color: var(--text-dim); font-weight: 600; font-size: 0.75rem; text-transform: uppercase; }
.comparison-table th:first-child, .comparison-table td:first-child { text-align: left; }
.comparison-table .highlight-row { background: rgba(108,92,231,0.1); }
.comparison-table .highlight-row td { color: var(--accent-light); font-weight: 600; }
.savings-summary { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 16px; }
.savings-box { background: var(--card-alt); border-radius: 10px; padding: 14px; text-align: center; }
.savings-box .sb-label { font-size: 0.72rem; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.3px; }
.savings-box .sb-value { font-size: 1.2rem; font-weight: 700; margin-top: 4px; }
+106
View File
@@ -0,0 +1,106 @@
// 2026 Tax Configuration
const FED_BRACKETS = {
single: [
{min:0,max:12400,r:0.10},
{min:12400,max:50400,r:0.12},
{min:50400,max:105700,r:0.22},
{min:105700,max:201775,r:0.24},
{min:201775,max:256225,r:0.32},
{min:256225,max:640600,r:0.35},
{min:640600,max:Infinity,r:0.37}
],
married_joint: [
{min:0,max:19300,r:0.00},
{min:19300,max:44100,r:0.10},
{min:44100,max:120100,r:0.12},
{min:120100,max:230700,r:0.22},
{min:230700,max:422850,r:0.24},
{min:422850,max:531750,r:0.32},
{min:531750,max:788000,r:0.35},
{min:788000,max:Infinity,r:0.37}
],
head_household: [
{min:0,max:15550,r:0.00},
{min:15550,max:33250,r:0.10},
{min:33250,max:83000,r:0.12},
{min:83000,max:121250,r:0.22},
{min:121250,max:217300,r:0.24},
{min:217300,max:271750,r:0.32},
{min:271750,max:656150,r:0.35},
{min:656150,max:Infinity,r:0.37}
],
married_separate: [
{min:0,max:12400,r:0.10},
{min:12400,max:50400,r:0.12},
{min:50400,max:105700,r:0.22},
{min:105700,max:201775,r:0.24},
{min:201775,max:256225,r:0.32},
{min:256225,max:640600,r:0.35},
{min:640600,max:Infinity,r:0.37}
]
};
const STD_DEDUCTIONS = { single: 16100, married_joint: 32200, head_household: 24150, married_separate: 16100 };
const SS_BASE = 168600;
const SS_RATE = 0.062;
const MED_RATE = 0.0145;
const ADD_MED_THRESH = { single: 200000, married_joint: 250000, head_household: 200000, married_separate: 125000 };
// State Tax Data (2026)
const STATE_DATA = {
//States with No Income Tax
AK: {t:'none',n:'Alaska'},
FL: {t:'none',n:'Florida'},
NV: {t:'none',n:'Nevada'},
NH: {t:'none',n:'New Hampshire'},
SD: {t:'none',n:'South Dakota'},
TN: {t:'none',n:'Tennessee'},
TX: {t:'none',n:'Texas'},
WA: {t:'none',n:'Washington'},
WY: {t:'none',n:'Wyoming'},
//States with Flat Income Tax
AZ: {t:'flat',v:0.025,n:'Arizona'},
CO: {t:'flat',v:0.044,n:'Colorado'},
GA: {t:'flat',v:0.0539,n:'Georgia'},
IL: {t:'flat',v:0.0495,n:'Illinois'},
IN: {t:'flat',v:0.03,n:'Indiana'},
IA: {t:'flat',v:0.038,n:'Iowa'},
KY: {t:'flat',v:0.04,n:'Kentucky'},
LA: {t:'flat',v:0.03,n:'Louisiana'},
MI: {t:'flat',v:0.0425,n:'Michigan'},
NC: {t:'flat',v:0.0399,n:'North Carolina'},
PA: {t:'flat',v:0.0307,n:'Pennsylvania'},
UT: {t:'flat',v:0.0455,n:'Utah'},
//States with Flat Income Tax and Standard Deduction
ID: {t:'brackets',v:[{min:0,max:4673,r:0},{min:4673,max:Infinity,r:0.05695}],n:'Idaho'},
MS: {t:'brackets',v:[{min:0,max:10000,r:0},{min:10000,max:Infinity,r:0.044}],n:'Mississippi'},
OH: {t:'brackets',v:[{min:0,max:26050,r:0},{min:26050,max:Infinity,r:0.0275}],n:'Ohio'},
//States with Bracketed Income Tax
AL: {t:'brackets',v:[{min:0,max:500,r:0.02},{min:500,max:3000,r:0.04},{min:3000,max:Infinity,r:0.05}],n:'Alabama'},
AR: {t:'brackets',v:[{min:0,max:4500,r:0.02},{min:4500,max:Infinity,r:0.039}],n:'Arkansas'},
CA: {t:'brackets',v:[{min:0,max:10756,r:0.01},{min:10756,max:25499,r:0.02},{min:25499,max:40245,r:0.04},{min:40245,max:55866,r:0.06},{min:55866,max:70606,r:0.08},{min:70606,max:360659,r:0.093},{min:360659,max:432787,r:0.103},{min:432787,max:721314,r:0.113},{min:721314,max:1000000,r:0.123},{min:1000000,max:Infinity,r:0.133}],n:'California'},
CT: {t:'brackets',v:[{min:0,max:10000,r:0.02},{min:10000,max:50000,r:0.045},{min:50000,max:100000,r:0.055},{min:100000,max:200000,r:0.06},{min:200000,max:250000,r:0.065},{min:250000,max:500000,r:0.069},{min:500000,max:Infinity,r:0.0699}],n:'Connecticut'},
DE: {t:'brackets',v:[{min:0,max:2000,r:0},{min:2000,max:5000,r:0.022},{min:5000,max:10000,r:0.039},{min:10000,max:20000,r:0.048},{min:20000,max:25000,r:0.052},{min:25000,max:60000,r:0.0555},{min:60000,max:Infinity,r:0.066}],n:'Delaware'},
HI: {t:'brackets',v:[{min:0,max:9600,r:0.014},{min:9600,max:14400,r:0.032},{min:14400,max:19200,r:0.055},{min:19200,max:24000,r:0.064},{min:24000,max:36000,r:0.068},{min:36000,max:48000,r:0.072},{min:48000,max:125000,r:0.076},{min:125000,max:175000,r:0.079},{min:175000,max:225000,r:0.0825},{min:225000,max:275000,r:0.09},{min:275000,max:325000,r:0.1},{min:325000,max:Infinity,r:0.11}],n:'Hawaii'},
KS: {t:'brackets',v:[{min:0,max:23000,r:0.052},{min:23000,max:Infinity,r:0.0558}],n:'Kansas'},
ME: {t:'brackets',v:[{min:0,max:26800,r:0.058},{min:26800,max:63450,r:0.0675},{min:63450,max:Infinity,r:0.0715}],n:'Maine'},
MD: {t:'brackets',v:[{min:0,max:1000,r:0.02},{min:1000,max:2000,r:0.03},{min:2000,max:3000,r:0.04},{min:3000,max:100000,r:0.0475},{min:100000,max:125000,r:0.05},{min:125000,max:150000,r:0.0525},{min:150000,max:250000,r:0.055},{min:250000,max:Infinity,r:0.0575}],n:'Maryland'},
MA: {t:'brackets',v:[{min:0,max:1083150,r:0.05},{min:1083150,max:Infinity,r:0.09}],n:'Massachusetts'},
MN: {t:'brackets',v:[{min:0,max:32570,r:0.0535},{min:32570,max:106990,r:0.068},{min:106990,max:198630,r:0.0785},{min:198630,max:Infinity,r:0.0985}],n:'Minnesota'},
MO: {t:'brackets',v:[{min:0,max:1313,r:0},{min:1313,max:2626,r:0.02},{min:2626,max:3939,r:0.025},{min:3939,max:5252,r:0.03},{min:5252,max:6565,r:0.035},{min:6565,max:7878,r:0.04},{min:7878,max:9191,r:0.045},{min:9191,max:Infinity,r:0.047}],n:'Missouri'},
MT: {t:'brackets',v:[{min:0,max:21100,r:0.047},{min:21100,max:Infinity,r:0.059}],n:'Montana'},
NE: {t:'brackets',v:[{min:0,max:4030,r:0.0246},{min:4030,max:24120,r:0.0351},{min:24120,max:38870,r:0.0501},{min:38870,max:Infinity,r:0.052}],n:'Nebraska'},
NJ: {t:'brackets',v:[{min:0,max:20000,r:0.014},{min:20000,max:35000,r:0.0175},{min:35000,max:40000,r:0.035},{min:40000,max:75000,r:0.05525},{min:75000,max:500000,r:0.0637},{min:500000,max:1000000,r:0.0897},{min:1000000,max:Infinity,r:0.1075}],n:'New Jersey'},
NM: {t:'brackets',v:[{min:0,max:5500,r:0.015},{min:5500,max:16500,r:0.032},{min:16500,max:33500,r:0.043},{min:33500,max:66500,r:0.047},{min:66500,max:210000,r:0.049},{min:210000,max:Infinity,r:0.059}],n:'New Mexico'},
NY: {t:'brackets',v:[{min:0,max:8500,r:0.04},{min:8500,max:11700,r:0.045},{min:11700,max:13900,r:0.0525},{min:13900,max:80650,r:0.055},{min:80650,max:215400,r:0.06},{min:215400,max:1077550,r:0.0685},{min:1077550,max:5000000,r:0.0965},{min:5000000,max:25000000,r:0.103},{min:25000000,max:Infinity,r:0.109}],n:'New York'},
ND: {t:'brackets',v:[{min:0,max:48485,r:0},{min:48485,max:244825,r:0.0195},{min:244825,max:Infinity,r:0.025}],n:'North Dakota'},
OK: {t:'brackets',v:[{min:0,max:1000,r:0.0025},{min:1000,max:2500,r:0.0075},{min:2500,max:3750,r:0.0175},{min:3750,max:4900,r:0.0275},{min:4900,max:7200,r:0.0375},{min:7200,max:Infinity,r:0.0475}],n:'Oklahoma'},
OR: {t:'brackets',v:[{min:0,max:4400,r:0.0475},{min:4400,max:11050,r:0.0675},{min:11050,max:125000,r:0.0875},{min:125000,max:Infinity,r:0.099}],n:'Oregon'},
RI: {t:'brackets',v:[{min:0,max:79900,r:0.0375},{min:79900,max:181650,r:0.0475},{min:181650,max:Infinity,r:0.0599}],n:'Rhode Island'},
SC: {t:'brackets',v:[{min:0,max:3560,r:0},{min:3560,max:17830,r:0.03},{min:17830,max:Infinity,r:0.062}],n:'South Carolina'},
VT: {t:'brackets',v:[{min:0,max:47900,r:0.0335},{min:47900,max:116000,r:0.066},{min:116000,max:242000,r:0.076},{min:242000,max:Infinity,r:0.0875}],n:'Vermont'},
VA: {t:'brackets',v:[{min:0,max:3000,r:0.02},{min:3000,max:5000,r:0.03},{min:5000,max:17000,r:0.05},{min:17000,max:Infinity,r:0.0575}],n:'Virginia'},
WV: {t:'brackets',v:[{min:0,max:10000,r:0.0222},{min:10000,max:25000,r:0.0296},{min:25000,max:40000,r:0.0333},{min:40000,max:60000,r:0.0444},{min:60000,max:Infinity,r:0.0482}],n:'West Virginia'},
WI: {t:'brackets',v:[{min:0,max:14680,r:0.035},{min:14680,max:29370,r:0.044},{min:29370,max:323290,r:0.053},{min:323290,max:Infinity,r:0.0765}],n:'Wisconsin'},
DC: {t:'brackets',v:[{min:0,max:10000,r:0.04},{min:10000,max:40000,r:0.06},{min:40000,max:60000,r:0.065},{min:60000,max:250000,r:0.085},{min:250000,max:500000,r:0.0925},{min:500000,max:1000000,r:0.0975},{min:1000000,max:Infinity,r:0.1075}],n:'Washington DC'}
};