diff --git a/index.html b/index.html index 24a1308..4cb3fd0 100644 --- a/index.html +++ b/index.html @@ -1256,6 +1256,7 @@ @@ -1511,6 +1512,7 @@

🚀 Accelerate (default): every profit reinvests — fastest path to 3× L7. Best for people who want the endgame and don't need cash along the way.
💰 Pocket along the way: they keep 25/50/75% of each cycle's profit as spending money and bank the rest. The climb honestly slows down — the timeline and tables update to show it — but they see real money the whole way. Best for people who need proof it pays before they trust the climb.
+ ⚡ Front-load: pocket 50% of each cycle until L6, then tighten to 25% for the expensive late jumps. Because early upgrades are funded by the payout roll anyway, this arrives at 3× L7 on nearly the same date as flat 25% while paying roughly double during the early grind — usually the best effort-to-reward line for someone actively working the clicks. The share link remembers this choice too.
🏝 Park & collect: stop at a level on purpose and pocket the whole profit every cycle (e.g. L4+L3 ≈ $213/mo). Best for tight budgets who may never fund an L7 — and you still earn your 10% on every one of their cycles, forever.
The share link remembers the strategy, so the plan they open is the plan you chose for them.

@@ -1608,9 +1610,16 @@ const PHASE_SLOTS = { 'L5+L4': [5, 4], 'L6': [6], 'L7': [7], '3xL7': [7, 7, 7], }; +// pocketPct: number (flat) or the string 'frontload' = 50% below L6, 25% +// from L6 up (Marty 2026-07-31: take the money early when thresholds are +// cheap, tighten for the expensive late jumps — same arrival as flat 25%). +function pocketPctFor(pocketPct, phaseKey) { + if (pocketPct !== 'frontload') return pocketPct; + return Math.max(...PHASE_SLOTS[phaseKey]) >= 6 ? 25 : 50; +} + function computePlan(phases, pocketPct = 0) { const plan = {}; - const keepFrac = 1 - pocketPct / 100; let bal = 0; const activated = new Set(); for (let lv = 1; lv <= Math.max(...PHASE_SLOTS[phases[0]]); lv++) activated.add(lv); @@ -1640,7 +1649,7 @@ function computePlan(phases, pocketPct = 0) { while (cycles < 500) { cycles++; if (bal + p.payout - carriedCamp >= cost) { bal += p.payout - carriedCamp - cost; break; } - bal += p.profit * keepFrac; + bal += p.profit * (1 - pocketPctFor(pocketPct, k) / 100); } plan[k] = { cycles, months: Math.round(cycles * p.daysPer / 30.4 * 10) / 10 }; } @@ -1679,7 +1688,6 @@ function laneStats(lanes) { // Simulate from an arbitrary lane set + starting reserve to 3×L7. // Mirrors computePlan's rules exactly; capped for safety. function boostSim(startLanes, bal0, pocketPct = 0) { - const keepFrac = 1 - pocketPct / 100; let lanes = [...startLanes].sort((a, b) => b - a); let bal = bal0; let cycles = 0; @@ -1709,7 +1717,7 @@ function boostSim(startLanes, bal0, pocketPct = 0) { while (spin++ < 500) { cycles++; if (bal + s.payout - carriedCamp >= cost) { bal += s.payout - carriedCamp - cost; break; } - bal += s.profit * keepFrac; + bal += s.profit * (1 - (pocketPct === 'frontload' ? (Math.max(...lanes) >= 6 ? 25 : 50) : pocketPct) / 100); } lanes = targetSlots.sort((a, b) => b - a); path.push(targetKey); @@ -1792,6 +1800,7 @@ function renderBoost(phaseKey, mode, pocketPct) { 'Activation is charged once per level; unspent cash goes into reserves either way. ' + (mode === 'park' ? 'Shown on the climb-to-endgame basis; if you park, the best combo is simply the highest profit/cycle you can afford.' : mode === 'pocket' ? `Simulated with your ${pocketPct}% pocket setting.` : + mode === 'frontload' ? 'Simulated with the front-load setting: pocket 50% until L6, then 25%.' : 'Simulated in Accelerate mode, same reserve math as the rest of the calculator.'); } @@ -1901,7 +1910,8 @@ function updateAll() { const selfLevel = parseInt(document.getElementById('selfFundLevel').value); const showRef = document.getElementById('showReferral').checked; const mode = document.getElementById('strategyMode').value; - const pocketPct = mode === 'pocket' ? (parseInt(document.getElementById('pocketPct').value) || 50) : 0; + const pocketPct = mode === 'pocket' ? (parseInt(document.getElementById('pocketPct').value) || 50) + : mode === 'frontload' ? 'frontload' : 0; document.getElementById('pocketPctGroup').style.display = mode === 'pocket' ? '' : 'none'; document.getElementById('parkPhaseGroup').style.display = mode === 'park' ? '' : 'none'; @@ -1935,7 +1945,7 @@ function updateAll() { const endCutPerCycle = PI[endKey].parked ? PI[endKey].payout * (commPct / 100) : THREE_L7_YOUR_CUT * mult; const monthlyPassive = Math.round(endCutPerCycle * 30.4 / 19 * numPeople); const pocketedTotal = Math.round(phases.filter(k => k !== '3xL7' && !PI[k].parked) - .reduce((s, k) => s + PI[k].profit * (pocketPct / 100) * PI[k].cycles, 0)); + .reduce((s, k) => s + PI[k].profit * (pocketPctFor(pocketPct, k) / 100) * PI[k].cycles, 0)); let totalToEGPerPerson = 0; for (const k of phases) { @@ -1980,11 +1990,11 @@ function updateAll() {
${mode === 'park' ? 'Time to Park Level' : 'Time to 3× L7'}
~${totalMonths} months
-${mode === 'pocket' ? ` +${(mode === 'pocket' || mode === 'frontload') ? `
Pocketed Along the Way
$${pocketedTotal.toLocaleString()}
-
${pocketPct}% of each cycle's profit
+
${pocketPct === 'frontload' ? "50% early, 25% from L6" : pocketPct + "% of each cycle's profit"}
` : ''} ${mode === 'park' ? `
@@ -2307,7 +2317,7 @@ document.querySelectorAll('.tab-btn').forEach(btn => { if (el && [...el.options].some(o => o.value === self)) el.value = self; } const mode = p.get('mode'); - if (mode === 'pocket' || mode === 'park') { + if (mode === 'pocket' || mode === 'frontload' || mode === 'park') { document.getElementById('strategyMode').value = mode; const pk = p.get('pk'); if (pk && [...document.getElementById('pocketPct').options].some(o => o.value === pk)) @@ -2453,8 +2463,8 @@ function phasePlanLine(k, i, PI, mode, pocketPct) { return `**Phase ${i + 1}: ${p.label} — PARK HERE** 🏝\nRun these campaigns on repeat, every ~19 days, and pocket the ~$${p.profit.toFixed(2)} profit each cycle — about $${perMo.toLocaleString()}/month of spending money for a few minutes of clicking a day. No more reinvesting, no more climbing. This is your income level.`; } const base = `**Phase ${i + 1}: ${p.label}**\n${p.cycles} cycles, ~${p.months} months — $${p.payout.toFixed(2)}/cycle payout`; - if (mode === 'pocket') { - const pk = p.profit * pocketPct / 100; + if (mode === 'pocket' || mode === 'frontload') { + const pk = p.profit * pocketPctFor(pocketPct, k) / 100; const totalPk = Math.round(pk * p.cycles * 100) / 100; return `${base}\nPocket ~$${pk.toFixed(2)} of each cycle's ~$${p.profit.toFixed(2)} profit (about $${totalPk.toFixed(2)} in your pocket across this phase) and bank the rest toward the next level. The timeline above already accounts for the slower climb.`; } @@ -2471,7 +2481,8 @@ function generatePlan() { const selfCost = getLevelCost(selfLevel); const effective = getEffectiveStart(giftLevel, selfLevel); const mode = document.getElementById('strategyMode').value; - const pocketPct = mode === 'pocket' ? (parseInt(document.getElementById('pocketPct').value) || 50) : 0; + const pocketPct = mode === 'pocket' ? (parseInt(document.getElementById('pocketPct').value) || 50) + : mode === 'frontload' ? 'frontload' : 0; let phases = getPhaseSequence(effective); if (mode === 'park') phases = phases.slice(0, phases.indexOf(document.getElementById('parkPhase').value) + 1); const PI = phaseInfo(phases, pocketPct); @@ -2479,7 +2490,7 @@ function generatePlan() { const totalMonths = estimateMonths(phases, pocketPct); const endgameBlock = PI[endKey].parked ? `**The destination: ${PI[endKey].label}** 🏝\nYou stop climbing here on purpose — roughly $${Math.round(HYBRIDS[endKey].profit * 30.4 / 19).toLocaleString()}/month pocketed, indefinitely, for a few minutes of clicking a day. (Want more later? The calculator link above shows the full climb to 3× L7 whenever you're ready.)` - : `**Phase ${phases.filter(x => x !== '3xL7').length + 1}: 3× L7 Endgame** 🎯\nAll three L7 campaigns running at once\n$9,720.00/cycle payout → ~$4,032/month${mode === 'pocket' ? ' — and from here it is ALL pocket money' : ' passive'}\nThis is the finish line${mode === 'pocket' ? `\n\n(CBP has a $10 minimum withdrawal and a 10% fee on external-wallet withdrawals — pocketed money accumulates in your balance until you cash out.)` : ''}`; + : `**Phase ${phases.filter(x => x !== '3xL7').length + 1}: 3× L7 Endgame** 🎯\nAll three L7 campaigns running at once\n$9,720.00/cycle payout → ~$4,032/month${(mode === 'pocket' || mode === 'frontload') ? ' — and from here it is ALL pocket money' : ' passive'}\nThis is the finish line${(mode === 'pocket' || mode === 'frontload') ? `\n\n(CBP has a $10 minimum withdrawal and a 10% fee on external-wallet withdrawals — pocketed money accumulates in your balance until you cash out.)` : ''}`; const roadmapHeading = PI[endKey].parked ? `Your roadmap to ~$${Math.round(HYBRIDS[endKey].profit * 30.4 / 19).toLocaleString()}/month pocket income:` : `Your full roadmap to $4,032/month:`; diff --git a/test_scenarios.js b/test_scenarios.js index 823fa59..39ddc67 100644 --- a/test_scenarios.js +++ b/test_scenarios.js @@ -135,6 +135,23 @@ console.log("7) strategy modes:"); check("parked timeline runs 10 collection cycles", tl.length === 10); } +console.log("7b) Front-load strategy (pocket 50% until L6, then 25%):"); +{ + const phases = getPhaseSequence(0); + const fl = computePlan(phases, "frontload"); + const p25 = computePlan(phases, 25); + const p50 = computePlan(phases, 50); + for (const k of phases) { + if (k === "3xL7") continue; + const isLate = Math.max(...PHASE_SLOTS[k]) >= 6; + const want = isLate ? p25[k].cycles : p50[k].cycles; + check(`frontload ${k} = ${isLate ? "25%" : "50%"} behavior (${fl[k].cycles}cy)`, + fl[k].cycles === want, `want ${want}`); + } + const total = (plan) => phases.reduce((s, k) => s + plan[k].cycles, 0); + check(`frontload total ${total(fl)} <= flat-50 total ${total(p50)}`, total(fl) <= total(p50)); +} + console.log("8) Boost Planner (extra-funds combos, Marty 2026-07-31):"); { // 8a. boostSim with $0 extra must agree with computePlan for every start.