Files
html/agents-final.html
opus 9f21f3ca01
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
AUTO-BACKUP 20260416-1905
2026-04-16 19:05:02 +02:00

266 lines
21 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WEVAL Enterprise</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@600;800;900&display=swap');
*{margin:0;padding:0;box-sizing:border-box}body{background:#1a1a2e;overflow:hidden;font-family:'Nunito',sans-serif}canvas{display:block}
#tip{position:fixed;pointer-events:none;display:none;z-index:99;background:#16213eee;border:2px solid;border-radius:14px;padding:12px 16px;color:#e0e8ff;max-width:240px;box-shadow:0 6px 30px #00000060}
#tip b{font-size:1rem;color:#fff;display:block}#tip i{font-size:.62rem;text-transform:uppercase;letter-spacing:2px;font-style:normal;display:block;margin:2px 0 5px}
#tip p{font-size:.78rem;color:#8a98c0;margin:0}#tip s{font-size:.68rem;color:#53d8fb;text-decoration:none;display:block;margin-top:4px;border-top:1px solid #fff1;padding-top:4px}
#tip em{font-size:.66rem;display:block;margin-top:3px;font-style:normal;font-weight:700}
#h{position:fixed;top:0;left:0;right:0;padding:8px 16px;display:flex;justify-content:space-between;align-items:center;z-index:10;background:#1a1a2eee}
#h span{font-size:.72rem;color:#5a6a88}#h span b{color:#53d8fb}
</style>
</head>
<body>
<canvas id="c"></canvas>
<div id="tip"><b></b><i></i><p></p><s></s><em></em></div>
<div id="h"><div style="font-weight:900;font-size:1.1rem"><span style="color:#e94560">WEVAL</span> <span style="color:#53d8fb">Enterprise</span></div><div><span>Agents <b>31</b></span> · <span>Actifs <b id="ac">0</b></span> · <span>Tasks <b id="tc" style="color:#f59e0b">0</b></span></div></div>
<script>
const C=document.getElementById('c'),X=C.getContext('2d');
let W,H,mx=-1,my=-1,hov=null,fr=0,tasks=0;
function resize(){W=innerWidth;H=innerHeight;C.width=W*2;C.height=H*2;X.scale(2,2);lay()}
addEventListener('resize',resize);
const RM=[
{id:'ceo', l:'👑 CEO Office', c:'#e94560'},
{id:'sales',l:'🎯 Prospection', c:'#3b82f6'},
{id:'con', l:'💼 Consulting', c:'#7c3aed'},
{id:'dev', l:'⚡ Dev Lab', c:'#10b981'},
{id:'srv', l:'🖥️ Server Room',c:'#f59e0b'},
{id:'sec', l:'🛡️ Sécurité', c:'#ef4444'},
{id:'qa', l:'🧪 QA Center', c:'#06b6d4'},
{id:'pha', l:'💊 Pharma Lab', c:'#d946ef'},
{id:'ops', l:'📡 Monitoring', c:'#eab308'},
];
RM.forEach(r=>{r.x=0;r.y=0;r.w=0;r.h=0;});
const SN=[{l:'LEADS',c:'#3b82f6'},{l:'QUALIFY',c:'#7c3aed'},{l:'DESIGN',c:'#10b981'},{l:'BUILD',c:'#22c55e'},{l:'SECURE',c:'#ef4444'},{l:'TEST',c:'#06b6d4'},{l:'DEPLOY',c:'#f59e0b'},{l:'DELIVER',c:'#84cc16'}];
SN.forEach(s=>{s.x=0;s.y=0;});
const AG=[
{n:'CEO',e:'👔',r:'ceo',s:1,d:'Agent CEO autonome',p:'Stratégie, budget',sk:'#f0d0b0',ey:'#1a1a3a',sh:'#1a1a2e',hr:'slick',hc:'#111',gl:0},
{n:'Ethica',e:'💊',r:'sales',s:0,d:'Scraping HCP',p:'131K+ médecins',sk:'#d4a574',ey:'#1a1a3a',sh:'#3b82f6',hr:'curly',hc:'#1a0a00',gl:0},
{n:'Analyst',e:'🔍',r:'sales',s:0,d:'Analyse besoins',p:'Specs, études',sk:'#f0d0b0',ey:'#1a3a1a',sh:'#3b82f6',hr:'short',hc:'#4a3020',gl:1},
{n:'Writer',e:'✍️',r:'sales',s:0,d:'Rédaction proposals',p:'Cold emails',sk:'#f0d0b0',ey:'#3a1a1a',sh:'#3b82f6',hr:'bob',hc:'#8a4a20',gl:0},
{n:'Architect',e:'🏗️',r:'con',s:2,d:'Architecture tech',p:'Blueprints',sk:'#e8c8a0',ey:'#1a1a3a',sh:'#7c3aed',hr:'short',hc:'#2a2a3a',gl:1},
{n:'Planner',e:'📋',r:'con',s:1,d:'Roadmaps',p:'Sprint plans',sk:'#f0d0b0',ey:'#1a1a3a',sh:'#7c3aed',hr:'side',hc:'#5a3a1a',gl:0},
{n:'DeerFlow',e:'🦌',r:'con',s:1,d:'Deep research',p:'Synthèses R&D',sk:'#e0b890',ey:'#3a2a1a',sh:'#7c3aed',hr:'wild',hc:'#6a4020',gl:0,ac:'antlers'},
{n:'Critic',e:'⚖️',r:'con',s:1,d:'Validation risques',p:'Reviews',sk:'#e8c8a0',ey:'#1a1a3a',sh:'#7c3aed',hr:'short',hc:'#3a3a4a',gl:1},
{n:'Executor',e:'⚡',r:'dev',s:3,d:'Exécution deploy',p:'Scripts',sk:'#d4a574',ey:'#1a3a1a',sh:'#10b981',hr:'mohawk',hc:'#22c55e',gl:0},
{n:'Debugger',e:'🐛',r:'dev',s:3,d:'Root cause',p:'Fixes',sk:'#f0d0b0',ey:'#1a1a3a',sh:'#10b981',hr:'messy',hc:'#4a2a10',gl:1},
{n:'Reviewer',e:'👁️',r:'dev',s:3,d:'Code review',p:'PR reviews',sk:'#e8c8a0',ey:'#1a1a3a',sh:'#10b981',hr:'short',hc:'#333',gl:0},
{n:'Designer',e:'🎨',r:'dev',s:2,d:'UI/UX design',p:'Mockups',sk:'#f0d0b0',ey:'#3a1a3a',sh:'#10b981',hr:'long',hc:'#d946ef',gl:0,ac:'beret'},
{n:'WEDROID',e:'🤖',r:'dev',s:3,d:'Auto-diag v5',p:'DB fix auto',sk:'#8899aa',ey:'#22c55e',sh:'#10b981',hr:'robot',hc:'#5a7a9a',gl:0},
{n:'Simplifier',e:'✂️',r:'dev',s:3,d:'Refactoring',p:'-40% code',sk:'#e8c8a0',ey:'#1a1a3a',sh:'#10b981',hr:'bun',hc:'#6a4a30',gl:1},
{n:'Watchdog',e:'🐕',r:'srv',s:6,d:'Monitor */3min',p:'Auto-restart',sk:'#e0b890',ey:'#3a2a1a',sh:'#f59e0b',hr:'ears',hc:'#8a6a30',gl:0},
{n:'Guardian',e:'🛡️',r:'srv',s:4,d:'Protection sys',p:'chattr +i',sk:'#d4a574',ey:'#1a1a2a',sh:'#f59e0b',hr:'buzz',hc:'#2a3a2a',gl:0,ac:'helmet'},
{n:'Blade',e:'💻',r:'srv',s:6,d:'Desktop agent',p:'PowerShell',sk:'#f0d0b0',ey:'#1a1a3a',sh:'#f59e0b',hr:'cap',hc:'#1a3050',gl:0,ac:'headset'},
{n:'GitMaster',e:'🌿',r:'srv',s:6,d:'Git releases',p:'Tags, deploys',sk:'#e8c8a0',ey:'#1a3a1a',sh:'#f59e0b',hr:'ponytail',hc:'#3a5a2a',gl:1},
{n:'Security',e:'🔐',r:'sec',s:4,d:'Audit OWASP',p:'Rapports sécu',sk:'#d4a574',ey:'#1a1a1a',sh:'#ef4444',hr:'buzz',hc:'#111',gl:0,ac:'shades'},
{n:'Verifier',e:'✅',r:'sec',s:4,d:'ISO/RGPD',p:'Checks PCI',sk:'#e8c8a0',ey:'#1a1a3a',sh:'#ef4444',hr:'short',hc:'#3a3a4a',gl:1},
{n:'QA',e:'🧪',r:'qa',s:5,d:'Tests E2E',p:'148 NonReg',sk:'#f0d0b0',ey:'#1a3a3a',sh:'#06b6d4',hr:'short',hc:'#2a3a5a',gl:0,ac:'goggles'},
{n:'TestEng',e:'🧰',r:'qa',s:5,d:'CI/CD',p:'Automatisation',sk:'#e8c8a0',ey:'#1a1a3a',sh:'#06b6d4',hr:'short',hc:'#4a3a2a',gl:0},
{n:'Tracer',e:'🔦',r:'qa',s:5,d:'Log tracing',p:'Stack traces',sk:'#e0b890',ey:'#2a1a1a',sh:'#06b6d4',hr:'short',hc:'#3a2a1a',gl:0},
{n:'Scientist',e:'🔬',r:'qa',s:5,d:'Benchmarks',p:'AI Bench 182',sk:'#f0d0b0',ey:'#1a1a3a',sh:'#06b6d4',hr:'einstein',hc:'#999',gl:1},
{n:'Explore',e:'🧭',r:'pha',s:0,d:'Exploration R&D',p:'Sources HCP',sk:'#d4a574',ey:'#3a2a1a',sh:'#d946ef',hr:'wild',hc:'#5a3a10',gl:0},
{n:'DocSpec',e:'📝',r:'pha',s:7,d:'Documentation',p:'Templates',sk:'#e8c8a0',ey:'#1a1a3a',sh:'#d946ef',hr:'short',hc:'#333',gl:1},
{n:'MiroFish',e:'🐟',r:'pha',s:2,d:'Creative AI',p:'Brainstorm',sk:'#f0d0b0',ey:'#1a3a3a',sh:'#d946ef',hr:'wavy',hc:'#06b6d4',gl:0},
{n:'TaskMgr',e:'📋',r:'ops',s:7,d:'Suivi tâches',p:'Kanban',sk:'#e8c8a0',ey:'#1a1a3a',sh:'#eab308',hr:'side',hc:'#4a4a3a',gl:0},
{n:'Brain',e:'💡',r:'ops',s:2,d:'Brainstorming',p:'Idées',sk:'#f0d0b0',ey:'#3a3a1a',sh:'#eab308',hr:'spiky',hc:'#eab308',gl:0},
{n:'Intro',e:'🧠',r:'ops',s:5,d:'Méta-analyse',p:'Amélioration',sk:'#e8c8a0',ey:'#2a1a3a',sh:'#eab308',hr:'short',hc:'#a855f7',gl:0},
{n:'Orch',e:'🎯',r:'ops',s:6,d:'Orchestration',p:'Coordination',sk:'#d4a574',ey:'#1a1a2a',sh:'#eab308',hr:'buzz',hc:'#222',gl:0},
];
AG.forEach(a=>{a.st='idle';a.x=0;a.y=0;a.dx=0;a.dy=0;a.cx=0;a.cy=0;a.bob=Math.random()*6.28;a.wk=0;a.tmr=200+Math.random()*500;a.wtmr=0;a.dir=1;a.bl=0;a.blt=80+Math.random()*200;a.bub='';a.bubt=0;});
function lay(){
// 3x3 room grid at top
const pad=10,topY=36;
const rw=(W-pad*4)/3,rh=(H*.58-topY-pad*3)/3;
for(let i=0;i<9;i++){
const col=i%3,row=Math.floor(i/3);
RM[i].x=pad+col*(rw+pad);RM[i].y=topY+row*(rh+pad);RM[i].w=rw;RM[i].h=rh;
}
// Chain at bottom
const cy=H*.82;
const sg=(W-60)/SN.length;
SN.forEach((s,i)=>{s.x=40+i*sg+sg/2;s.y=cy;});
// Agent desk positions
AG.forEach(a=>{
const rm=RM.find(r=>r.id===a.r);if(!rm)return;
const mates=AG.filter(b=>b.r===a.r);const mi=mates.indexOf(a);
const cols=Math.max(Math.ceil(mates.length/2),1);
const row=Math.floor(mi/cols),col=mi%cols;
a.dx=rm.x+24+col*Math.min((rm.w-48)/Math.max(cols-1,1),48);
a.dy=rm.y+30+row*32;
if(a.st==='idle'){a.x=a.dx;a.y=a.dy;}
const sn=SN[a.s];if(sn){a.cx=sn.x+(Math.random()-.5)*18;a.cy=sn.y-8;}
});
}
resize();
// ═ DRAW ROOM ═
function dR(r){
X.fillStyle='#00000020';X.beginPath();X.roundRect(r.x+3,r.y+3,r.w,r.h,8);X.fill();
const g=X.createLinearGradient(r.x,r.y,r.x,r.y+r.h);g.addColorStop(0,'#161938');g.addColorStop(1,'#0e1025');
X.fillStyle=g;X.beginPath();X.roundRect(r.x,r.y,r.w,r.h,8);X.fill();
X.strokeStyle=r.c+'40';X.lineWidth=1;X.beginPath();X.roundRect(r.x,r.y,r.w,r.h,8);X.stroke();
X.fillStyle=r.c+'60';X.beginPath();X.roundRect(r.x,r.y,r.w,3,[8,8,0,0]);X.fill();
// Floor tiles
X.strokeStyle=r.c+'06';X.lineWidth=.3;
for(let i=1;i<5;i++){X.beginPath();X.moveTo(r.x+i*(r.w/5),r.y+18);X.lineTo(r.x+i*(r.w/5),r.y+r.h-3);X.stroke();}
X.font='800 9px Nunito';X.fillStyle=r.c;X.textAlign='left';X.fillText(r.l,r.x+8,r.y+14);
// Decorations per room
if(r.id==='srv'){for(let i=0;i<3;i++){const rx=r.x+r.w-14-i*14;X.fillStyle='#1a2535';X.fillRect(rx,r.y+18,10,r.h-24);
for(let j=0;j<5;j++){X.fillStyle=Math.sin(fr*.04+i+j)>.2?'#22c55e':'#ef4444';X.beginPath();X.arc(rx+3,r.y+24+j*7,1.2,0,6.28);X.fill();}}}
if(r.id==='ceo'){X.fillStyle='#2a5a2a';X.beginPath();X.arc(r.x+r.w-16,r.y+r.h-10,6,Math.PI,0);X.fill();X.fillStyle='#5a3a2a';X.fillRect(r.x+r.w-18,r.y+r.h-10,4,6);
X.fillStyle='#f59e0b30';X.beginPath();X.arc(r.x+r.w-35,r.y+26,8,0,6.28);X.fill();}
if(r.id==='pha'){for(let i=0;i<3;i++){X.fillStyle=['#d946ef30','#3b82f630','#22c55e30'][i];X.beginPath();X.roundRect(r.x+r.w-12-i*9,r.y+20,5,14,2);X.fill();}}
if(r.id==='sec'){X.fillStyle=Math.sin(fr*.08)>.5?'#ef4444':'#ef444440';X.beginPath();X.arc(r.x+r.w-12,r.y+24,3,0,6.28);X.fill();}
if(r.id==='ops'){X.strokeStyle='#eab30850';X.lineWidth=.8;X.beginPath();for(let i=0;i<6;i++)X.lineTo(r.x+r.w-38+i*5,r.y+35-Math.sin(fr*.015+i)*5);X.stroke();}
}
// ═ DRAW DESK ═
function dD(x,y,c,occ){
X.fillStyle=occ?'#1c2540':'#141a2a';X.beginPath();X.roundRect(x-12,y+2,24,7,2);X.fill();
X.fillStyle=occ?c+'30':'#0e1420';X.fillRect(x-5,y-4,10,6);
if(occ){X.fillStyle=c+'06';X.beginPath();X.arc(x,y,14,0,6.28);X.fill();}
}
// ═ CHIBI CHARACTER ═
function dC(a){
const isH=a===hov,sit=a.st==='idle',sc=isH?1.15:1;
const bob=sit?Math.sin(a.bob)*.3:Math.sin(a.bob)*1.5;
const lsw=sit?0:Math.sin(a.wk)*3;
X.save();X.translate(a.x,a.y+bob);X.scale(sc*a.dir,sc);
if(isH){X.shadowColor=a.sh;X.shadowBlur=14;}
const rm=RM.find(r=>r.id===a.r);
// Shadow
X.fillStyle='rgba(0,0,0,.25)';X.beginPath();X.ellipse(0,sit?6:10,6,2,0,0,6.28);X.fill();
const oy=sit?-2:0;
// Legs
X.fillStyle='#25254a';
if(sit){X.beginPath();X.roundRect(-4,oy+3,3,4,1);X.fill();X.beginPath();X.roundRect(1,oy+3,3,4,1);X.fill();}
else{X.save();X.translate(-2,oy+3);X.rotate(lsw*.04);X.beginPath();X.roundRect(-1.5,0,3,7,1);X.fill();X.restore();
X.save();X.translate(2,oy+3);X.rotate(-lsw*.04);X.beginPath();X.roundRect(-1.5,0,3,7,1);X.fill();X.restore();}
// Shoes
X.fillStyle='#1a1a38';
X.beginPath();X.roundRect(-4.5+lsw*.15,oy+(sit?6:9),4.5,2,[0,0,1.5,1.5]);X.fill();
X.beginPath();X.roundRect(0-lsw*.15,oy+(sit?6:9),4.5,2,[0,0,1.5,1.5]);X.fill();
// Body
const bg=X.createLinearGradient(0,oy-6,0,oy+3);bg.addColorStop(0,a.sh);bg.addColorStop(1,a.sh+'88');
X.fillStyle=bg;X.beginPath();X.roundRect(-5.5,oy-6,11,10,[3,3,1,1]);X.fill();
X.fillStyle='rgba(255,255,255,.06)';X.beginPath();X.roundRect(-4,oy-5,3.5,7,[1,0,0,1]);X.fill();
// Arms
X.fillStyle=a.sk;const asw=sit?.05:Math.sin(a.wk+.5)*.15;
X.save();X.translate(-6.5,oy-3);X.rotate(sit?.25:asw);X.beginPath();X.roundRect(-1.5,0,3,sit?4.5:7,1.5);X.fill();X.restore();
X.save();X.translate(6.5,oy-3);X.rotate(sit?-.25:-asw);X.beginPath();X.roundRect(-1.5,0,3,sit?4.5:7,1.5);X.fill();X.restore();
// HEAD
const hy=oy-15;const hr=8;
X.fillStyle=a.sk;X.beginPath();X.arc(0,hy+1,hr,0,6.28);X.fill();
X.fillStyle='#ff8a8a10';X.beginPath();X.arc(-5,hy+4,2.5,0,6.28);X.fill();X.beginPath();X.arc(5,hy+4,2.5,0,6.28);X.fill();
// HAIR
X.fillStyle=a.hc;
switch(a.hr){
case'slick':X.beginPath();X.arc(0,hy-.5,hr+.5,.7,Math.PI+.5);X.fill();X.fillRect(-6,hy-5,12,5);break;
case'short':X.beginPath();X.arc(0,hy,hr+.5,.5,Math.PI-.3);X.fill();break;
case'buzz':X.beginPath();X.arc(0,hy,hr+.8,.4,Math.PI-.2);X.fill();break;
case'curly':for(let i=0;i<9;i++){const ag=-2.3+i*.5;X.beginPath();X.arc(Math.cos(ag)*7,hy-1+Math.sin(ag)*6.5,3,0,6.28);X.fill();}break;
case'bob':X.beginPath();X.arc(0,hy-.5,hr+.5,.2,Math.PI);X.fill();X.fillRect(-8.5,hy+1,4,7);X.fillRect(4.5,hy+1,4,7);break;
case'side':X.beginPath();X.arc(0,hy,hr+.5,.4,Math.PI-.2);X.fill();X.fillRect(-9,hy-1,4.5,7);break;
case'wild':X.beginPath();X.arc(0,hy-.5,hr+1.5,.2,Math.PI);X.fill();X.beginPath();X.arc(-9,hy-1,3.5,0,6.28);X.fill();X.beginPath();X.arc(9,hy-1,3.5,0,6.28);X.fill();break;
case'mohawk':X.beginPath();X.arc(0,hy,hr+.5,.5,Math.PI-.3);X.fill();for(let i=0;i<4;i++)X.fillRect(-1.5,hy-8-i*2,3,3.5);break;
case'messy':X.beginPath();X.arc(0,hy-.5,hr+.8,.3,Math.PI-.1);X.fill();for(let i=0;i<4;i++)X.fillRect(-5+i*3,hy-7-Math.random()*2,2.5,4);break;
case'long':X.beginPath();X.arc(0,hy-.5,hr+.5,.2,Math.PI);X.fill();X.fillRect(-9,hy,4,8);X.fillRect(5,hy,4,8);break;
case'bun':X.beginPath();X.arc(0,hy,hr+.5,.5,Math.PI-.3);X.fill();X.beginPath();X.arc(0,hy-7,3.5,0,6.28);X.fill();break;
case'ponytail':X.beginPath();X.arc(0,hy,hr+.5,.4,Math.PI-.2);X.fill();X.fillRect(6,hy,2.5,10);X.beginPath();X.arc(7,hy+10,2.5,0,6.28);X.fill();break;
case'ears':X.beginPath();X.arc(0,hy,hr+.5,.5,Math.PI-.3);X.fill();X.beginPath();X.moveTo(-7,hy-2);X.lineTo(-11,hy-9);X.lineTo(-4,hy);X.fill();X.beginPath();X.moveTo(7,hy-2);X.lineTo(11,hy-9);X.lineTo(4,hy);X.fill();break;
case'cap':X.beginPath();X.arc(0,hy-.5,hr+.5,.3,Math.PI-.1);X.fill();X.fillRect(-10,hy,20,3);X.fillRect(-12,hy+2,7,2);break;
case'einstein':X.beginPath();X.arc(0,hy-.5,hr+1.5,.2,Math.PI);X.fill();X.beginPath();X.arc(-9,hy,3.5,0,6.28);X.fill();X.beginPath();X.arc(9,hy,3.5,0,6.28);X.fill();break;
case'spiky':for(let i=0;i<5;i++){const ag=-1.6+i*.6,rr=hr+3;X.beginPath();X.moveTo(Math.cos(ag)*6,hy+Math.sin(ag)*5.5);X.lineTo(Math.cos(ag)*rr,hy-2+Math.sin(ag)*rr*.6);X.lineTo(Math.cos(ag+.3)*6,hy+Math.sin(ag+.3)*5.5);X.fill();}break;
case'wavy':for(let i=0;i<7;i++){const ag=-2+i*.55;X.beginPath();X.arc(Math.cos(ag)*7.5,hy-1+Math.sin(ag)*6+Math.sin(i)*1.2,2.5,0,6.28);X.fill();}break;
case'robot':X.fillStyle='#5a7a9a';X.beginPath();X.roundRect(-8,hy-5,16,13,3);X.fill();X.strokeStyle='#3a5a7a';X.lineWidth=.8;X.strokeRect(-6,hy-1,12,4);
X.strokeStyle='#8aa';X.lineWidth=1.2;X.beginPath();X.moveTo(0,hy-5);X.lineTo(0,hy-9);X.stroke();X.fillStyle='#ef4444';X.beginPath();X.arc(0,hy-9,2,0,6.28);X.fill();break;
default:X.beginPath();X.arc(0,hy,hr+.5,.5,Math.PI-.3);X.fill();
}
// EYES
if(a.hr!=='robot'){
if(a.bl<=0){
X.fillStyle='#fff';X.beginPath();X.ellipse(-3,hy+1,2.8,3.2,0,0,6.28);X.fill();X.beginPath();X.ellipse(3,hy+1,2.8,3.2,0,0,6.28);X.fill();
X.fillStyle=a.ey;X.beginPath();X.arc(-2.5,hy+1.5,1.8,0,6.28);X.fill();X.beginPath();X.arc(3.5,hy+1.5,1.8,0,6.28);X.fill();
X.fillStyle='#000';X.beginPath();X.arc(-2.5,hy+1.8,1,0,6.28);X.fill();X.beginPath();X.arc(3.5,hy+1.8,1,0,6.28);X.fill();
X.fillStyle='#fff';X.beginPath();X.arc(-3.2,hy+.5,.7,0,6.28);X.fill();X.beginPath();X.arc(2.8,hy+.5,.7,0,6.28);X.fill();
}else{X.strokeStyle=a.ey;X.lineWidth=1.2;X.lineCap='round';X.beginPath();X.moveTo(-5,hy+1);X.lineTo(-1,hy+1);X.stroke();X.beginPath();X.moveTo(1,hy+1);X.lineTo(5,hy+1);X.stroke();}
if(a.gl){X.strokeStyle='#8aa0be';X.lineWidth=.6;X.beginPath();X.arc(-3,hy+1,3.8,0,6.28);X.stroke();X.beginPath();X.arc(3,hy+1,3.8,0,6.28);X.stroke();X.beginPath();X.moveTo(-.2,hy+1);X.lineTo(.2,hy+1);X.stroke();}
X.fillStyle=a.sk+'cc';X.beginPath();X.arc(0,hy+4.5,.8,0,6.28);X.fill();
X.strokeStyle='#c08080';X.lineWidth=.6;X.lineCap='round';X.beginPath();
if(a.st==='wk'){X.arc(0,hy+6.5,1.8,.2,Math.PI-.2);}else{X.moveTo(-1.2,hy+7);X.lineTo(1.2,hy+7);}X.stroke();
}else{X.fillStyle=a.st!=='idle'?'#22c55e':'#3b82f6';X.beginPath();X.roundRect(-4,hy,.5,3,2.5,1);X.fill();X.beginPath();X.roundRect(1,hy+.5,3,2.5,1);X.fill();}
// Accessories
if(a.ac==='shades'){X.fillStyle='#000b';X.beginPath();X.roundRect(-6.5,hy-.5,5.5,3.5,1.2);X.fill();X.beginPath();X.roundRect(1,hy-.5,5.5,3.5,1.2);X.fill();}
if(a.ac==='antlers'){X.strokeStyle=a.hc;X.lineWidth=1;X.beginPath();X.moveTo(-6,hy-4);X.lineTo(-9,hy-10);X.moveTo(-8,hy-7);X.lineTo(-11,hy-11);X.stroke();X.beginPath();X.moveTo(6,hy-4);X.lineTo(9,hy-10);X.moveTo(8,hy-7);X.lineTo(11,hy-11);X.stroke();}
if(a.ac==='beret'){X.fillStyle='#e94560';X.beginPath();X.arc(-1,hy-6,5.5,.3,Math.PI);X.fill();X.beginPath();X.arc(-1,hy-8,1.5,0,6.28);X.fill();}
if(a.ac==='goggles'){X.fillStyle='#06b6d430';X.beginPath();X.roundRect(-6.5,hy-1,5.5,4,1.5);X.fill();X.beginPath();X.roundRect(1,hy-1,5.5,4,1.5);X.fill();}
if(a.ac==='headset'){X.strokeStyle='#444';X.lineWidth=1.5;X.beginPath();X.arc(0,hy-1,hr+1.5,.7,Math.PI-.5);X.stroke();X.fillStyle='#333';X.beginPath();X.arc(-8,hy+2,2.5,0,6.28);X.fill();}
if(a.ac==='helmet'){X.fillStyle='#4a6a4a';X.beginPath();X.arc(0,hy-1,hr+1.5,.3,Math.PI-.1);X.fill();}
// Emoji + name
X.font='7px sans-serif';X.textAlign='center';X.fillText(a.e,hr+3,hy-1);
X.font=`${isH?'800':'600'} ${isH?7.5:6}px Nunito`;X.fillStyle=isH?'#fff':a.st!=='idle'?'#b0c0e0':'#3a4a60';X.fillText(a.n,0,sit?14:20);
if(a.st!=='idle'){X.fillStyle='#22c55e';X.beginPath();X.arc(0,oy-20,2,0,6.28);X.fill();}
if(a.bubt>0){const ba=Math.min(a.bubt/16,1);X.globalAlpha=ba;X.fillStyle='#fffd';const bw=Math.min(a.bub.length*3.5+10,90);X.beginPath();X.roundRect(-bw/2,oy-36,bw,13,5);X.fill();
X.fillStyle='#fff';X.beginPath();X.moveTo(-2,oy-23);X.lineTo(2,oy-23);X.lineTo(0,oy-20);X.closePath();X.fill();
X.font='600 5.5px Nunito';X.fillStyle='#1a1a2e';X.fillText(a.bub,0,oy-27.5);X.globalAlpha=1;}
X.restore();
}
// ═ CHAIN ═
function dChain(){const y=SN[0].y;
X.fillStyle='#0c0e1e';X.beginPath();X.roundRect(20,y-16,W-40,32,6);X.fill();
X.strokeStyle='#1a2040';X.lineWidth=.8;X.beginPath();X.roundRect(20,y-16,W-40,32,6);X.stroke();
const off=(fr*.8)%18;X.strokeStyle='#12182a';X.lineWidth=.3;
for(let x=24-off;x<W-24;x+=18){X.beginPath();X.moveTo(x,y-15);X.lineTo(x,y+15);X.stroke();}
SN.forEach((s,i)=>{
X.fillStyle=s.c+'28';X.beginPath();X.arc(s.x,y,16,0,6.28);X.fill();
X.fillStyle=s.c+'50';X.beginPath();X.arc(s.x,y,5,0,6.28);X.fill();
X.strokeStyle=s.c;X.lineWidth=1;X.beginPath();X.arc(s.x,y,5,0,6.28);X.stroke();
X.font='700 7px Nunito';X.textAlign='center';X.fillStyle=s.c;X.fillText(s.l,s.x,y+24);
if(i<SN.length-1){const n=SN[i+1];X.strokeStyle='#182040';X.lineWidth=.6;X.beginPath();X.moveTo(s.x+7,y);X.lineTo(n.x-7,y);X.stroke();}
});
}
// ═ UPDATE ═
function upd(dt){fr++;let ac=0;
AG.forEach(a=>{a.bob+=dt*(a.st==='idle'?1.5:3.2);a.blt-=dt*60;if(a.blt<=0){a.bl=4;a.blt=80+Math.random()*180;}if(a.bl>0)a.bl-=dt*60;if(a.bubt>0)a.bubt-=dt*20;
switch(a.st){
case'idle':a.tmr-=dt*60;if(a.tmr<=0){a.st='wt';a.wk=0;}break;
case'wt':a.wk+=dt*7;ac++;{const dx=a.cx-a.x,dy=a.cy-a.y,d=Math.hypot(dx,dy);if(d>2){const sp=85*dt;a.x+=dx/d*sp;a.y+=dy/d*sp;a.dir=dx>0?1:-1;}else{a.st='wk';a.wtmr=55+Math.random()*90;a.bub=a.p.substring(0,16);a.bubt=40;tasks++;}}break;
case'wk':a.wk+=dt*2.5;ac++;a.wtmr-=dt*60;if(a.wtmr<=0)a.st='wb';break;
case'wb':a.wk+=dt*7;ac++;{const dx=a.dx-a.x,dy=a.dy-a.y,d=Math.hypot(dx,dy);if(d>2){const sp=85*dt;a.x+=dx/d*sp;a.y+=dy/d*sp;a.dir=dx>0?1:-1;}else{a.st='idle';a.x=a.dx;a.y=a.dy;a.dir=1;a.tmr=220+Math.random()*550;}}break;
}});document.getElementById('ac').textContent=ac;document.getElementById('tc').textContent=tasks;}
function hit(){hov=null;AG.forEach(a=>{if(Math.abs(mx-a.x)<9&&Math.abs(my-a.y)<16)hov=a;});
const t=document.getElementById('tip');if(hov){t.style.display='block';t.style.left=Math.min(mx+14,W-250)+'px';t.style.top=Math.max(my-150,10)+'px';
const rm=RM.find(r=>r.id===hov.r);t.style.borderColor=rm?rm.c:'#53d8fb';
t.querySelector('b').textContent=hov.e+' '+hov.n;t.querySelector('i').textContent=rm?rm.l:'';t.querySelector('i').style.color=rm?rm.c:'#fff';
t.querySelector('p').textContent=hov.d;t.querySelector('s').textContent='→ '+hov.p;
const sm={idle:'💤 Au bureau',wt:'🚶 → Production',wk:'⚙️ En production',wb:'🔙 Retour'};
t.querySelector('em').textContent=sm[hov.st]||'';t.querySelector('em').style.color=hov.st==='idle'?'#5a6888':'#22c55e';
}else t.style.display='none';}
let lt=0;function loop(t){const dt=Math.min((t-lt)/1000,.04);lt=t;X.clearRect(0,0,W,H);X.fillStyle='#1a1a2e';X.fillRect(0,0,W,H);
RM.forEach(r=>dR(r));AG.forEach(a=>{const rm=RM.find(r=>r.id===a.r);if(rm)dD(a.dx,a.dy,rm.c,a.st==='idle');});
dChain();upd(dt);
AG.filter(a=>a.st==='wt'||a.st==='wb').forEach(a=>{X.strokeStyle='#22c55e08';X.lineWidth=.6;X.setLineDash([1.5,4]);X.beginPath();X.moveTo(a.dx,a.dy);X.lineTo(a.x,a.y);X.stroke();X.setLineDash([]);});
[...AG].sort((a,b)=>a.y-b.y).forEach(a=>dC(a));hit();requestAnimationFrame(loop);}
C.addEventListener('mousemove',e=>{mx=e.clientX;my=e.clientY;C.style.cursor=hov?'pointer':'default'});
C.addEventListener('mouseleave',()=>{mx=my=-1});
requestAnimationFrame(loop);
</script>
<!-- CARTO_REMOVED -->
</body>
</html>