Skip to content

Commit d7bb182

Browse files
committed
chore: add ai tools
1 parent e5dbf3f commit d7bb182

1 file changed

Lines changed: 250 additions & 0 deletions

File tree

calculadora-custo-ai-tools.html

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
<!DOCTYPE html>
2+
<html lang="pt-BR">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Calculadora de Custo — AI Coding Tools</title>
7+
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
8+
<style>
9+
:root{--bg:#0c0c10;--sf:#151519;--sf2:#1c1c22;--bd:#2a2a34;--tx:#e4e4ec;--mt:#7a7a90;--ac:#3b82f6;--gn:#22c55e;--or:#f59e0b;--rd:#ef4444;--pu:#a78bfa}
10+
*{margin:0;padding:0;box-sizing:border-box}
11+
body{font-family:'IBM Plex Sans',sans-serif;background:var(--bg);color:var(--tx);min-height:100vh}
12+
.mono{font-family:'IBM Plex Mono',monospace}
13+
.ctn{max-width:960px;margin:0 auto;padding:32px 20px 80px}
14+
h1{font-size:26px;font-weight:700;margin-bottom:4px}
15+
.sub{color:var(--mt);font-size:13px;margin-bottom:28px}
16+
.ctrl{background:var(--sf);border:1px solid var(--bd);border-radius:12px;padding:24px;margin-bottom:24px}
17+
.cr{margin-bottom:20px}.cr:last-child{margin-bottom:0}
18+
.cl{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:8px}
19+
.cl label{font-size:14px;font-weight:600}
20+
.cl .v{font-family:'IBM Plex Mono',monospace;font-size:14px;color:var(--ac);font-weight:600}
21+
input[type=range]{-webkit-appearance:none;width:100%;height:6px;background:var(--sf2);border-radius:3px;outline:none}
22+
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;border-radius:50%;background:var(--ac);cursor:pointer}
23+
.ms{display:grid;grid-template-columns:1fr 1fr;gap:12px}
24+
.ms>div label{display:block;font-size:13px;color:var(--mt);margin-bottom:4px}
25+
select{width:100%;background:var(--sf2);color:var(--tx);border:1px solid var(--bd);border-radius:8px;padding:8px 12px;font-family:'IBM Plex Sans',sans-serif;font-size:14px;cursor:pointer}
26+
select:focus{outline:none;border-color:var(--ac)}
27+
.asm{background:var(--sf);border:1px solid var(--bd);border-radius:12px;padding:14px 20px;margin-bottom:24px;font-size:13px;color:var(--mt);line-height:1.7}
28+
.asm strong{color:var(--tx)}
29+
.res{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-bottom:24px}
30+
@media(max-width:720px){.res{grid-template-columns:1fr}.ms{grid-template-columns:1fr}}
31+
.tc{background:var(--sf);border:1px solid var(--bd);border-radius:12px;padding:18px;position:relative;transition:border-color .2s}
32+
.tc.best{border-color:var(--gn)}
33+
.tc.best::after{content:'MENOR CUSTO';position:absolute;top:-10px;left:50%;transform:translateX(-50%);background:var(--gn);color:#000;font-size:10px;font-weight:700;letter-spacing:1px;padding:2px 10px;border-radius:8px;white-space:nowrap}
34+
.tn{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:1.5px;margin-bottom:10px}
35+
.tn.cop{color:var(--ac)}.tn.cur{color:var(--pu)}.tn.cla{color:var(--or)}
36+
.po{background:var(--sf2);border-radius:8px;padding:10px 12px;margin-bottom:6px}
37+
.po:last-child{margin-bottom:0}
38+
.po.rec{background:#22c55e10;border:1px solid #22c55e25}
39+
.ph{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:3px}
40+
.pn{font-size:13px;font-weight:600}
41+
.pp{font-family:'IBM Plex Mono',monospace;font-size:17px;font-weight:700}
42+
.pp.g{color:var(--gn)}.pp.w{color:var(--or)}.pp.d{color:var(--rd)}
43+
.pd{font-size:11px;color:var(--mt);line-height:1.5}
44+
.tg{display:inline-block;padding:1px 6px;border-radius:4px;font-size:10px;font-weight:600;margin-left:4px}
45+
.tg-f{background:#22c55e18;color:var(--gn)}.tg-o{background:#f59e0b15;color:var(--or)}.tg-n{background:#ef444415;color:var(--rd)}
46+
.rco{background:var(--sf);border:1px solid var(--bd);border-radius:12px;padding:18px}
47+
.rco h3{font-size:15px;margin-bottom:6px}
48+
.rco p{font-size:13px;color:var(--mt);line-height:1.7}
49+
.rco strong{color:var(--tx)}
50+
.ft{text-align:center;margin-top:36px;font-size:11px;color:var(--mt);line-height:1.7}
51+
.validation{background:var(--sf);border:1px solid var(--bd);border-radius:12px;padding:14px 20px;margin-bottom:24px;font-size:12px;color:var(--mt);line-height:1.8}
52+
.validation h4{font-size:13px;color:var(--tx);margin-bottom:6px}
53+
.validation .ok{color:var(--gn)}.validation .fail{color:var(--rd)}
54+
</style>
55+
</head>
56+
<body>
57+
<div class="ctn">
58+
59+
<h1>Calculadora de Custo: AI Coding Tools</h1>
60+
<p class="sub">Cursor vs Copilot vs Claude Code — Marco 2026 — Multiplicadores Copilot verificados em docs.github.com</p>
61+
62+
<div class="ctrl">
63+
<div class="cr">
64+
<div class="cl"><label>Requests totais por mes</label><span class="v" id="reqV">1000</span></div>
65+
<input type="range" id="totR" min="100" max="10000" step="100" value="1000">
66+
</div>
67+
<div class="cr">
68+
<div class="cl"><label>% dedicado a research (resto = implementacao)</label><span class="v" id="splV">30%</span></div>
69+
<input type="range" id="rSpl" min="10" max="70" step="5" value="30">
70+
</div>
71+
<div class="cr">
72+
<div class="ms">
73+
<div>
74+
<label>Modelo para research</label>
75+
<select id="rMod">
76+
<option value="opus">Claude Opus 4.6 (melhor reasoning)</option>
77+
<option value="sonnet" selected>Claude Sonnet 4.6 (custo-beneficio)</option>
78+
<option value="gpt5">GPT-5</option>
79+
<option value="gemini">Gemini 2.5 Pro</option>
80+
</select>
81+
</div>
82+
<div>
83+
<label>Modelo para implementacao</label>
84+
<select id="iMod">
85+
<option value="auto" selected>Auto / Incluido (mais barato)</option>
86+
<option value="haiku">Haiku 4.5</option>
87+
<option value="sonnet">Claude Sonnet 4.6</option>
88+
<option value="composer">Composer 2 (Cursor only)</option>
89+
</select>
90+
</div>
91+
</div>
92+
</div>
93+
</div>
94+
95+
<div class="asm" id="asm"></div>
96+
<div class="res" id="res"></div>
97+
<div class="rco" id="rco"></div>
98+
<div class="validation" id="val"></div>
99+
100+
<div class="ft">
101+
Multiplicadores Copilot (docs.github.com): Haiku 0.33x | Sonnet/GPT-5/Gemini 1x | Opus 3x | Overage $0.04/prem req<br>
102+
Cursor: Auto ilimitado em planos pagos. Pool em dolares = preco do plano. Manual = custo API real<br>
103+
Claude Code: Pro ~300 req max | Max 5x ~1.500 | Max 20x ~5.000 | API = pay per token<br>
104+
Tokens/request: research ~5K in + ~3K out | impl ~3K in + ~1.5K out
105+
</div>
106+
</div>
107+
108+
<script>
109+
// ====== PRICING (Marco 2026, verificado) ======
110+
// Per-req cost: research 5K in + 3K out, impl 3K in + 1.5K out
111+
const MD = {
112+
opus: {r:.025+.075, i:.015+.0375, l:'Opus 4.6', pin:'$5/M in, $25/M out'},
113+
sonnet: {r:.015+.045, i:.009+.0225, l:'Sonnet 4.6', pin:'$3/M in, $15/M out'},
114+
gpt5: {r:.0125+.045,i:.0075+.0225,l:'GPT-5', pin:'$2.50/M in, $15/M out'},
115+
gemini: {r:.01+.036, i:.006+.018, l:'Gemini 2.5 Pro',pin:'$2/M in, $12/M out'},
116+
haiku: {r:.005+.015, i:.003+.0075, l:'Haiku 4.5', pin:'$1/M in, $5/M out'},
117+
composer:{r:.0025+.006,i:.0015+.003, l:'Composer 2', pin:'$0.50/M in, $2/M out'},
118+
auto: {r:0,i:0, l:'Auto/Incluido', pin:'Gratis'}
119+
};
120+
// Copilot multipliers (docs.github.com Mar 2026)
121+
const CM={opus:3,sonnet:1,gpt5:1,gemini:1,haiku:.33,composer:1,auto:0};
122+
const CPL=[{n:'Pro',p:10,q:300},{n:'Pro+',p:39,q:1500}];
123+
const COV=.04;
124+
// Cursor
125+
const CUR=[{n:'Pro',p:20,pl:20},{n:'Pro+',p:60,pl:60},{n:'Ultra',p:200,pl:200}];
126+
// Claude Code
127+
const CLC=[{n:'Pro',p:20,mx:300},{n:'Max 5x',p:100,mx:1500},{n:'Max 20x',p:200,mx:5000}];
128+
129+
function go(){
130+
const tot=+document.getElementById('totR').value;
131+
const rP=+document.getElementById('rSpl').value/100;
132+
const rK=document.getElementById('rMod').value;
133+
const iK=document.getElementById('iMod').value;
134+
const rN=Math.round(tot*rP), iN=tot-rN;
135+
const rC=MD[rK], iC=MD[iK];
136+
137+
document.getElementById('reqV').textContent=tot.toLocaleString();
138+
document.getElementById('splV').textContent=Math.round(rP*100)+'%';
139+
document.getElementById('asm').innerHTML=
140+
`<strong>${tot.toLocaleString()} req/mes</strong>: ${rN.toLocaleString()} research (${rC.l}${rC.pin}) + ${iN.toLocaleString()} impl (${iC.l}${iC.pin})`;
141+
142+
// COPILOT
143+
const cop=CPL.map(p=>{
144+
const ip=iK==='auto'?0:iN*(CM[iK]||1);
145+
const rp=rN*(CM[rK]||1);
146+
const tp=Math.round(ip+rp);
147+
const ov=Math.max(0,tp-p.q);
148+
const ovc=ov*COV;
149+
const t=p.p+ovc;
150+
const d=iK==='auto'
151+
?`${iN.toLocaleString()} impl GPT-4.1 (gratis) + ${rN.toLocaleString()} res ${CM[rK]}x = ${tp.toLocaleString()} prem de ${p.q}`
152+
:`${iN.toLocaleString()} impl ${CM[iK]}x + ${rN.toLocaleString()} res ${CM[rK]}x = ${tp.toLocaleString()} prem de ${p.q}`;
153+
return{name:p.n,total:t,ov,ovc,det:d,ok:true};
154+
});
155+
156+
// CURSOR
157+
const cur=CUR.map(p=>{
158+
const ic=iK==='auto'?0:iN*iC.i;
159+
const rc=rN*rC.r;
160+
const pu=ic+rc;
161+
const ov=Math.max(0,pu-p.pl);
162+
const aa=iK==='auto'&&rK==='auto';
163+
const t=aa?p.p:p.p+ov;
164+
const d=aa?'Tudo Auto — ilimitado, $0 do pool'
165+
:iK==='auto'?`Impl Auto (gratis) + Research $${rc.toFixed(2)} do pool de $${p.pl}`
166+
:`Pool usado: $${pu.toFixed(2)} de $${p.pl}`;
167+
return{name:p.n,total:t,ov,det:d,ok:true,aa};
168+
});
169+
170+
// CLAUDE CODE
171+
const cla=CLC.map(p=>{
172+
const ok=tot<=p.mx;
173+
return{name:p.n,total:ok?p.p:null,ok,
174+
det:ok?`Flat rate — ${tot.toLocaleString()} de ${p.mx.toLocaleString()} max`:`Nao cabe: limite ~${p.mx.toLocaleString()} req`};
175+
});
176+
const aic=iK==='auto'?iN*MD.sonnet.i:iN*iC.i;
177+
const arc=rN*rC.r;
178+
const at=aic+arc;
179+
const ail=iK==='auto'?'Sonnet 4.6':iC.l;
180+
const api={name:'API pay-as-you-go',total:at,ok:true,
181+
det:`${iN.toLocaleString()} impl (${ail}) $${aic.toFixed(2)} + ${rN.toLocaleString()} res (${rC.l}) $${arc.toFixed(2)}`};
182+
183+
// BEST
184+
const nums=[...cop,...cur,...cla.filter(x=>x.ok),api].filter(x=>x.ok).map(x=>x.total);
185+
const best=Math.min(...nums);
186+
const copB=Math.min(...cop.map(x=>x.total));
187+
const curB=Math.min(...cur.map(x=>x.total));
188+
const claA=[...cla.filter(x=>x.ok).map(x=>x.total),api.total];
189+
const claB=claA.length?Math.min(...claA):1e9;
190+
const oB=Math.min(copB,curB,claB);
191+
192+
function pc(t){return t===best?'g':t>150?'d':t>80?'w':'';}
193+
function rp(p){
194+
if(!p.ok) return`<div class="po"><div class="ph"><span class="pn">${p.name}</span><span class="pp d">N/A</span></div><div class="pd">${p.det}<span class="tg tg-n">NAO CABE</span></div></div>`;
195+
const c=p.total===best?' rec':'';
196+
let tg='';
197+
if(p.ovc>0)tg=`<span class="tg tg-o">${p.ov.toLocaleString()} overage = +$${p.ovc.toFixed(2)}</span>`;
198+
else if(p.ov>0)tg=`<span class="tg tg-o">+$${p.ov.toFixed(2)} overage</span>`;
199+
else if(p.aa)tg=`<span class="tg tg-f">ILIMITADO</span>`;
200+
else tg=`<span class="tg tg-f">CABE</span>`;
201+
return`<div class="po${c}"><div class="ph"><span class="pn">${p.name}</span><span class="pp ${pc(p.total)}">$${p.total.toFixed(2)}</span></div><div class="pd">${p.det}${tg}</div></div>`;
202+
}
203+
204+
document.getElementById('res').innerHTML=`
205+
<div class="tc${copB===oB?' best':''}"><div class="tn cop">GitHub Copilot</div>${cop.map(rp).join('')}</div>
206+
<div class="tc${curB===oB?' best':''}"><div class="tn cur">Cursor</div>${cur.map(rp).join('')}</div>
207+
<div class="tc${claB===oB?' best':''}"><div class="tn cla">Claude Code</div>${cla.map(rp).join('')}${rp(api)}</div>`;
208+
209+
// RECO
210+
let rc='';
211+
if(iK==='auto'&&cur[0].total<=20)rc+=`<strong>Cursor Pro $20</strong> — Auto ilimitado cobre ${tot.toLocaleString()} req sem overage. `;
212+
if(copB<curB)rc+=`<strong>Copilot $${copB.toFixed(2)}</strong> e mais barato, mas impl fica no GPT-4.1 (reasoning limitado). `;
213+
if(rK==='opus')rc+=`Com Opus, <strong>Claude Code Max $100 flat</strong> e o mais previsivel — sem multiplicadores ou overages. Copilot cobra Opus a 3x. `;
214+
if(api.total<50&&tot<=2000)rc+=`<strong>Claude Code API $${api.total.toFixed(2)}</strong> e opcao pay-as-you-go competitiva. `;
215+
if(tot>=3000)rc+=`Pra heavy use, combo <strong>Cursor Pro ($20) + Claude Code API</strong> da autocomplete ilimitado + reasoning sob demanda. `;
216+
if(!rc)rc=`Ajuste modelos e volume pra explorar cenarios.`;
217+
document.getElementById('rco').innerHTML=`<h3>Recomendacao</h3><p>${rc}</p>`;
218+
219+
// VALIDATION
220+
let vl='<h4>Validacao dos calculos</h4>';
221+
// Copilot Pro with current settings
222+
const cp=cop[0];
223+
const cpPremExpected=iK==='auto'?rN*(CM[rK]||1):(iN*(CM[iK]||1)+rN*(CM[rK]||1));
224+
const cpOvExpected=Math.max(0,Math.round(cpPremExpected)-300);
225+
const cpTotalExpected=10+cpOvExpected*0.04;
226+
const cpOk=Math.abs(cp.total-cpTotalExpected)<0.01;
227+
vl+=`<span class="${cpOk?'ok':'fail'}">Copilot Pro: ${Math.round(cpPremExpected)} prem, ${cpOvExpected} overage x $0.04 = $${cpTotalExpected.toFixed(2)} ${cpOk?'OK':'ERRO'}</span><br>`;
228+
229+
// Cursor Pro
230+
const cuP=cur[0];
231+
const cuPoolExpected=iK==='auto'?rN*rC.r:(iN*iC.i+rN*rC.r);
232+
const cuOvExpected=Math.max(0,cuPoolExpected-20);
233+
const cuTotalExpected=(iK==='auto'&&rK==='auto')?20:20+cuOvExpected;
234+
const cuOk=Math.abs(cuP.total-cuTotalExpected)<0.01;
235+
vl+=`<span class="${cuOk?'ok':'fail'}">Cursor Pro: pool $${cuPoolExpected.toFixed(2)} de $20, overage $${cuOvExpected.toFixed(2)}, total $${cuTotalExpected.toFixed(2)} ${cuOk?'OK':'ERRO'}</span><br>`;
236+
237+
// Claude API
238+
const clApiExpected=aic+arc;
239+
const clOk=Math.abs(api.total-clApiExpected)<0.01;
240+
vl+=`<span class="${clOk?'ok':'fail'}">Claude API: impl $${aic.toFixed(2)} + res $${arc.toFixed(2)} = $${clApiExpected.toFixed(2)} ${clOk?'OK':'ERRO'}</span>`;
241+
242+
document.getElementById('val').innerHTML=vl;
243+
}
244+
245+
['totR','rSpl'].forEach(id=>document.getElementById(id).addEventListener('input',go));
246+
['rMod','iMod'].forEach(id=>document.getElementById(id).addEventListener('change',go));
247+
go();
248+
</script>
249+
</body>
250+
</html>

0 commit comments

Comments
 (0)