Files
html/golive.html
2026-04-12 22:57:03 +02:00

216 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>WEVAL GO-LIVE — 4 Variantes</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&family=Plus+Jakarta+Sans:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js"></script>
<style>
*{margin:0;padding:0;box-sizing:border-box}
:root{--bg:#0a0b0f;--bg2:#12141a;--bg3:#1a1d25;--t1:#e8e6df;--t2:#9c9a92;--t3:#6a685f;--green:#1bcc7a;--red:#e24b4a;--blue:#378add;--purple:#7f77dd;--amber:#ef9f27;--teal:#1d9e75;--coral:#d85a30}
body{background:var(--bg);color:var(--t1);font-family:'Plus Jakarta Sans',sans-serif;min-height:100vh}
.top{display:flex;align-items:center;justify-content:space-between;padding:14px 24px;border-bottom:1px solid rgba(255,255,255,.06)}
.top h1{font-size:14px;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--t2)}
.top h1 b{color:var(--green)}
.live{width:7px;height:7px;border-radius:50%;background:var(--green);display:inline-block;margin-right:6px;animation:p 2s infinite}
@keyframes p{0%,100%{box-shadow:0 0 0 0 rgba(27,204,122,.4)}50%{box-shadow:0 0 0 6px rgba(27,204,122,0)}}
.pill{font-family:'JetBrains Mono',monospace;font-size:11px;padding:3px 10px;border-radius:16px;background:rgba(27,204,122,.12);color:var(--green);border:1px solid rgba(27,204,122,.15)}
.pill.run{background:rgba(55,138,221,.12);color:var(--blue);border-color:rgba(55,138,221,.15);animation:bk 1s infinite}
@keyframes bk{50%{opacity:.5}}
.g{display:grid;gap:12px;padding:16px 24px}
.g4{grid-template-columns:repeat(4,1fr)}
.g2{grid-template-columns:1fr 1fr}
.c{background:var(--bg2);border:1px solid rgba(255,255,255,.04);border-radius:10px;padding:14px 16px;overflow:hidden}
.m{text-align:center}
.m .l{font-size:10px;color:var(--t3);text-transform:uppercase;letter-spacing:.7px;margin-bottom:4px}
.m .v{font-family:'JetBrains Mono',monospace;font-size:24px;font-weight:700}
.sec{font-size:11px;font-weight:600;color:var(--t3);text-transform:uppercase;letter-spacing:.8px;padding:8px 24px 0}
.vcard{background:var(--bg2);border:1px solid rgba(255,255,255,.04);border-radius:10px;padding:14px 16px}
.vcard .head{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}
.vcard .head .vname{font-size:13px;font-weight:600;display:flex;align-items:center;gap:8px}
.vcard .head .score{font-family:'JetBrains Mono',monospace;font-size:13px;font-weight:700}
.tg{display:grid;grid-template-columns:repeat(auto-fill,minmax(100px,1fr));gap:6px}
.ti{background:var(--bg3);border-radius:6px;padding:6px 8px;border-left:2.5px solid var(--green);display:flex;flex-direction:column;gap:2px}
.ti.f{border-left-color:var(--red);background:rgba(226,75,74,.04)}
.ti.p{border-left-color:var(--t3);opacity:.4}
.ti .n{font-size:10px;font-weight:500;color:var(--t1)}
.ti .d{font-family:'JetBrains Mono',monospace;font-size:9px;color:var(--t3)}
.ch{position:relative;height:180px}
.ch.h{height:260px}
.foot{text-align:center;padding:16px;font-size:10px;color:var(--t3);border-top:1px solid rgba(255,255,255,.04)}
@media(max-width:768px){.g4{grid-template-columns:repeat(2,1fr)}.g2{grid-template-columns:1fr}}
</style>
</head>
<body>
<div class="top">
<h1><span class="live"></span><b>WEVAL</b> GO-LIVE — 4 variantes</h1>
<div style="display:flex;align-items:center;gap:10px">
<span class="pill" id="st">idle</span>
<span style="font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--t3)" id="ck"></span>
</div>
</div>
<div class="g g4">
<div class="c m"><div class="l">Total pass</div><div class="v" style="color:var(--green)" id="kP"></div></div>
<div class="c m"><div class="l">Score</div><div class="v" style="color:var(--green)" id="kS"></div></div>
<div class="c m"><div class="l">Sigma</div><div class="v" style="color:var(--blue)" id="kG"></div></div>
<div class="c m"><div class="l">NonReg</div><div class="v" style="color:var(--t1)">40/40</div></div>
</div>
<div class="sec">Résultats par variante</div>
<div class="g g2" id="variants"></div>
<div class="g g2">
<div><div class="sec">Score par variante</div><div class="c" style="margin-top:6px"><div class="ch"><canvas id="chVar"></canvas></div></div></div>
<div><div class="sec">Lean 6σ — contraintes levées</div><div class="c" style="margin-top:6px"><div class="ch"><canvas id="chToc"></canvas></div></div></div>
</div>
<div class="sec">Aptitudes — output size (chars)</div>
<div class="g" style="grid-template-columns:1fr"><div class="c"><div class="ch h"><canvas id="chApt"></canvas></div></div></div>
<div class="foot">WEVAL Consulting — Casablanca — Process #1 Absolu — Lean 6σ + ToC — 20 mars 2026</div>
<script>
const API='/wevia-ia/weval-chatbot-api.php', WAPI='/api/wedroid-brain-api.php';
const VARIANTS=[
{id:'grand',name:'WEVIA Grand écran',icon:'🖥️',color:'#1D9E75',tests:[
['Chat','Bonjour WEVIA','.'],['Skills','Tes compétences?','frontend-design'],['Claude 2026','Claude Dispatch 2026','dispatch'],
['Logo SVG','Code SVG logo IA viewBox 200x200 path gradient','svg|viewBox|path'],['Mermaid','Schema mermaid microservices','graph|flowchart'],
['SQL','SQL PostgreSQL CREATE TABLE indexes','CREATE TABLE|INDEX'],['Node.js','Code Node.js Express JWT CRUD','express|jwt|router'],
['React','Code React useState KPI recharts Tailwind','useState|className'],['Python','Code Python ETL pandas psycopg2','pandas|def |import'],
['SWOT','SWOT SaaS pharma Maroc forces faiblesses','force|faiblesse'],['Darija','Kteb b darija chno WEVIA','.'],
['English','Write summary WEVAL AI','AI|platform'],['Art SVG','Code SVG mandala zellige pattern','svg|pattern|transform'],
['pytest','Code Python tests pytest assert fixture','def test_|assert|fixture'],['Canvas','Code JS Canvas particules requestAnimationFrame','canvas|requestAnimationFrame'],
]},
{id:'widget',name:'WEVIA Widget',icon:'💬',color:'#378ADD',tests:[
['Chat','Bonjour','.'],['Skills','Compétences?','frontend-design'],['Secteurs','Quels secteurs?','.'],
['Question tech','Deployer Flask production?','flask|gunicorn|nginx|wsgi'],['Darija','Chno WEVAL?','.'],
]},
{id:'wevcode',name:'WEVCODE Fullscreen',icon:'⌨️',color:'#7F77DD',tests:[
['Chat','Bonjour WEVCODE','.'],['Python Flask','Code Flask auth JWT CRUD','flask|def |jwt'],
['React','Code React useState login form','useState|login|form'],['SQL','SQL PostgreSQL schema permissions','CREATE TABLE|GRANT|role'],
['Dockerfile','Dockerfile multi-stage Node.js','FROM|COPY|RUN'],
]},
{id:'wedroid',name:'WEDROID CLI',icon:'🤖',color:'#EF9F27',tests:[
['Chat','status rapport'],['Skills','compétences Dispatch 2026'],['Chain','diagnostic rapide'],
['Docker','containers Docker actifs'],['Learning','Learn golive 4variants'],
]},
];
let allResults={}, tP=0, tF=0;
function updKPI(){
const tot=tP+tF, pct=tot?Math.round(tP/tot*100):0;
const sig=pct>=99.7?'6σ':pct>=99?'5σ':pct>=97?'4σ':pct>=93?'3σ':'<3σ';
document.getElementById('kP').textContent=`${tP}/${tot}`;
document.getElementById('kS').textContent=`${pct}%`;
document.getElementById('kS').style.color=pct>=95?'var(--green)':pct>=80?'var(--amber)':'var(--red)';
document.getElementById('kG').textContent=sig;
}
function renderVariant(v, results){
const pass=results.filter(r=>r.ok).length, total=results.length;
const pct=total?Math.round(pass/total*100):0;
const card=document.createElement('div');card.className='vcard';
card.innerHTML=`<div class="head"><span class="vname">${v.icon} ${v.name}</span><span class="score" style="color:${pct>=90?'var(--green)':pct>=70?'var(--amber)':'var(--red)'}">${pass}/${total} (${pct}%)</span></div><div class="tg" id="tg-${v.id}"></div>`;
document.getElementById('variants').appendChild(card);
const tg=card.querySelector('.tg');
results.forEach(r=>{
const el=document.createElement('div');
el.className=`ti ${r.ok?'':'f'}`;
el.innerHTML=`<span class="n">${r.ok?'✅':'❌'} ${r.name}</span><span class="d">${r.detail}</span>`;
tg.appendChild(el);
});
}
async function testAPI(msg,sid,tm=50){
try{
const r=await fetch(API,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:msg,session_id:sid}),signal:AbortSignal.timeout(tm*1000)});
return await r.json();
}catch{return{response:''};}
}
async function testWD(params){
try{
const r=await fetch(WAPI,{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:params,signal:AbortSignal.timeout(15000)});
return await r.json();
}catch{return{response:''};}
}
async function runAll(){
tP=0;tF=0;
document.getElementById('variants').innerHTML='';
document.getElementById('st').textContent='scanning...';document.getElementById('st').className='pill run';
for(const v of VARIANTS){
const results=[];
for(const t of v.tests){
await new Promise(r=>setTimeout(r,800));
const sid=`${v.id}-${Date.now()}-${Math.random().toString(36).slice(2,5)}`;
let resp='',ok=false;
if(v.id==='wedroid'){
const d=await testWD(`k=DROID2026&action=chat&message=${encodeURIComponent(t[1])}`);
resp=d.response||d.summary||JSON.stringify(d);
ok=resp.length>10;
}else{
const d=await testAPI(t[1],sid);
resp=d.response||'';
ok=new RegExp(t[2],'i').test(resp)&&resp.length>20;
}
if(ok)tP++;else tF++;
results.push({name:t[0],ok,detail:`${(resp.length/1000).toFixed(1)}k`,len:resp.length});
updKPI();
}
allResults[v.id]=results;
renderVariant(v,results);
}
document.getElementById('st').textContent=`${tP}/${tP+tF} pass`;
document.getElementById('st').className='pill';
renderCharts();
}
function renderCharts(){
const vNames=VARIANTS.map(v=>v.name);
const vPass=VARIANTS.map(v=>(allResults[v.id]||[]).filter(r=>r.ok).length);
const vTotal=VARIANTS.map(v=>(allResults[v.id]||[]).length);
const vColors=VARIANTS.map(v=>v.color);
new Chart(document.getElementById('chVar'),{
type:'bar',
data:{labels:vNames,datasets:[
{label:'Pass',data:vPass,backgroundColor:vColors,borderRadius:6,barPercentage:.5},
{label:'Fail',data:vTotal.map((t,i)=>t-vPass[i]),backgroundColor:'rgba(226,75,74,0.3)',borderRadius:6,barPercentage:.5}
]},
options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{display:false}},
scales:{x:{stacked:true,grid:{display:false},ticks:{color:'#6a685f',font:{size:10}}},y:{stacked:true,grid:{color:'rgba(255,255,255,.04)'},ticks:{color:'#6a685f'},beginAtZero:true}}
}
});
const tocL=['Providers','Skills','RAG','Output','Auto-heal','Crons','Memory','Auth'];
const tocB=[0,0,17,20,60,70,85,95], tocA=[95,95,92,85,100,100,100,100];
new Chart(document.getElementById('chToc'),{
type:'bar',data:{labels:tocL,datasets:[
{data:tocB,backgroundColor:'rgba(226,75,74,0.25)',borderRadius:4,barPercentage:.5},
{data:tocA,backgroundColor:'#1D9E75',borderRadius:4,barPercentage:.5}
]},options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{display:false}},
scales:{x:{grid:{display:false},ticks:{color:'#6a685f',font:{size:9}}},y:{grid:{color:'rgba(255,255,255,.04)'},ticks:{color:'#6a685f',callback:v=>v+'%'},max:100,beginAtZero:true}}
}
});
const grandR=allResults['grand']||[];
const aptL=grandR.map(r=>r.name), aptD=grandR.map(r=>r.len), aptC=grandR.map(r=>r.ok?'#1D9E75':'rgba(226,75,74,0.6)');
new Chart(document.getElementById('chApt'),{
type:'bar',data:{labels:aptL,datasets:[{data:aptD,backgroundColor:aptC,borderRadius:4,barPercentage:.7}]},
options:{indexAxis:'y',responsive:true,maintainAspectRatio:false,plugins:{legend:{display:false},tooltip:{callbacks:{label:c=>Math.round(c.raw).toLocaleString()+' chars'}}},
scales:{x:{grid:{color:'rgba(255,255,255,.04)'},ticks:{color:'#6a685f',callback:v=>v>=1000?Math.round(v/1000)+'k':v}},y:{grid:{display:false},ticks:{color:'#9c9a92',font:{size:10}}}}}
});
}
setInterval(()=>{document.getElementById('ck').textContent=new Date().toLocaleString('fr-FR',{day:'2-digit',month:'short',hour:'2-digit',minute:'2-digit',second:'2-digit'})},1000);
runAll();
setInterval(runAll,600000);
</script>
</body>
</html>