Add 'Already joined' toggle + post-join PIF message template

- New checkbox: 'Already joined (skip signup language)' toggles the plan generator
- Already-joined mode strips signup prompts, says 'I went back and funded your level'
- New template: templates/post-join-pif-message.md for the manual message scenario
- Skill updated with reference to the new template
This commit is contained in:
Marty Bostick
2026-07-11 12:42:29 +00:00
parent 7be4867604
commit 3e35eb10ef
2 changed files with 160 additions and 3 deletions
+105
View File
@@ -0,0 +1,105 @@
const LEVELS = [
{level:1, act:1, camp:13, total:14, payout:17.17, netProfit:4.17},
{level:2, act:7, camp:77, total:84, payout:118.91, netProfit:34.91},
{level:3, act:14, camp:163, total:177, payout:211.57, netProfit:48.57},
{level:4, act:36, camp:310, total:346, payout:388.80, netProfit:78.80},
{level:5, act:72, camp:620, total:692, payout:777.60, netProfit:157.60},
{level:6, act:120, camp:1200, total:1320, payout:1555.20,netProfit:355.20},
{level:7, act:240, camp:2400, total:2640, payout:3240.00,netProfit:840.00},
];
const HYBRIDS = {
'L1-only': { label: 'L1 Only', reinvest: 13, payout: 17.17, profit: 4.17, cycles: 9, months: 3.0, daysPer: 19 },
'L2+L1': { label: 'L2 + L1', reinvest: 90, payout: 118.91, profit: 28.91, cycles: 4, months: 2.5, daysPer: 19 },
'L3+L1': { label: 'L3 + L1', reinvest: 163, payout: 211.57, profit: 48.57, cycles: 4, months: 2.5, daysPer: 19 },
'L4+L3': { label: 'L4 + L3', reinvest: 450, payout: 583.20, profit: 133.20,cycles: 5, months: 3.0, daysPer: 19 },
'L5+L4': { label: 'L5 + L4', reinvest: 900, payout: 1166.40,profit: 266.40,cycles: 4, months: 2.0, daysPer: 19 },
'L6': { label: 'L6', reinvest: 1200, payout: 1555.20,profit: 355.20,cycles: 4, months: 2.0, daysPer: 19 },
'L7': { label: 'Single L7', reinvest: 2400, payout: 3240.00,profit: 840.00,cycles: 7, months: 3.0, daysPer: 19 },
'3xL7': { label: '3× L7 Endgame', reinvest: 7200, payout: 9720, profit: 2520, cycles: 1, months: 0.63, daysPer: 19 },
};
function getLevelCost(upTo) {
if (upTo <= 0) return 0;
return LEVELS.slice(0, upTo).reduce((s, l) => s + l.total, 0);
}
function getEffectiveStart(gift, selfF) {
return Math.max(gift, selfF);
}
function getPhaseSequence(effectiveStart) {
if (effectiveStart >= 5) return ['L5+L4','L6','L7','3xL7'];
if (effectiveStart >= 4) return ['L4+L3','L5+L4','L6','L7','3xL7'];
if (effectiveStart >= 3) return ['L3+L1','L4+L3','L5+L4','L6','L7','3xL7'];
if (effectiveStart >= 2) return ['L2+L1','L3+L1','L4+L3','L5+L4','L6','L7','3xL7'];
return ['L1-only','L2+L1','L3+L1','L4+L3','L5+L4','L6','L7','3xL7'];
}
function estimateMonths(phases) {
let total = 0;
for (const k of phases) {
if (k === '3xL7') break;
total += HYBRIDS[k].months;
}
return total;
}
function estimateYear1Cum(phases, commPct, giftLevel) {
let cum = 0;
let months = 0;
for (const k of phases) {
if (k === '3xL7') break;
const p = HYBRIDS[k];
const yourCut = p.payout * (commPct / 100);
const cyclesInYear1 = Math.min(p.cycles, Math.max(0, (12 - months) / (p.months / p.cycles)));
const actual = Math.floor(cyclesInYear1);
for (let i = 0; i < actual; i++) cum += yourCut;
months += p.months;
if (months >= 12) break;
}
return Math.round(cum);
}
function buildSCENARIOS() {
const levels = [
{ giftLvl: 1, selfLvl: 0, id: 'gift1', label: 'L1 Gift ($14)', yourCost: 14 },
{ giftLvl: 0, selfLvl: 1, id: 'self1', label: 'Self L1 ($14)', yourCost: 0 },
{ giftLvl: 2, selfLvl: 0, id: 'gift2', label: 'L1-L2 Gift ($98)', yourCost: 98 },
{ giftLvl: 0, selfLvl: 2, id: 'self2', label: 'Self L2 ($98)', yourCost: 0 },
{ giftLvl: 3, selfLvl: 0, id: 'gift3', label: 'L1-L3 Gift ($263)', yourCost: 263},
{ giftLvl: 0, selfLvl: 3, id: 'self3', label: 'Self L3 ($263)', yourCost: 0 },
{ giftLvl: 4, selfLvl: 0, id: 'gift4', label: 'L1-L4 Gift ($593)', yourCost: 593},
{ giftLvl: 0, selfLvl: 4, id: 'self4', label: 'Self L4 ($593)', yourCost: 0 },
{ giftLvl: 5, selfLvl: 0, id: 'gift5', label: 'L1-L5 Gift ($1,253)', yourCost:1253},
{ giftLvl: 0, selfLvl: 5, id: 'self5', label: 'Self L5 ($1,253)', yourCost: 0 },
];
return levels.map(function(s) {
const eff = Math.max(s.giftLvl, s.selfLvl);
const phases = getPhaseSequence(eff);
const t = Math.round(estimateMonths(phases));
const y = estimateYear1Cum(phases, 10, s.giftLvl);
const eg = phases.filter(function(k) { return k !== '3xL7'; })
.reduce(function(sum, k) { return sum + HYBRIDS[k].payout * 0.10 * HYBRIDS[k].cycles; }, 0);
return { id: s.id, label: s.label, yourCost: s.yourCost, time: t, yr1: Math.round(y), totalEG: Math.round(eg), monthly: 1860 };
});
}
const SCENARIOS = buildSCENARIOS();
console.log("=== SCENARIOS ===");
for (var i = 0; i < SCENARIOS.length; i++) {
var s = SCENARIOS[i];
console.log(s.id + ": time=" + s.time + "mo, yr1=$" + s.yr1 + ", totalEG=$" + s.totalEG);
}
// Verify consistency: rebuild should give same result
var r = buildSCENARIOS();
var ok = true;
for (var i = 0; i < SCENARIOS.length; i++) {
if (SCENARIOS[i].time !== r[i].time || SCENARIOS[i].yr1 !== r[i].yr1) {
console.log("MISMATCH at " + SCENARIOS[i].id);
ok = false;
}
}
if (ok) console.log("=== ALL CONSISTENT ===");