218 lines
18 KiB
HTML
218 lines
18 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>WEVAL — Value Stream Mapping</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&family=DM+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
<style>@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@600;700;800;900&display=swap');
|
|
*{margin:0;padding:0;box-sizing:border-box}
|
|
:root{--bg:#0f1117;--card:#1a1d27;--border:#2a2d3a;--text:#e2e4eb;--dim:#6b7280;--accent:#3b82f6;--green:#10b981;--orange:#f59e0b;--red:#ef4444;--purple:#8b5cf6;--cyan:#06b6d4;--pink:#ec4899}
|
|
body{background:var(--bg);color:var(--text);font-family:'DM Sans',sans-serif;min-height:100vh}
|
|
.header{background:linear-gradient(135deg,#1a1d27 0%,#0f1117 100%);border-bottom:1px solid var(--border);padding:16px 24px;display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:100}
|
|
.header h1{font-family:'JetBrains Mono',monospace;font-size:18px;font-weight:700;background:linear-gradient(135deg,#3b82f6,#8b5cf6);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
.header .live{font-size:11px;color:var(--green);animation:pulse 2s infinite}
|
|
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
|
|
.tabs{display:flex;gap:2px;background:var(--card);border-radius:8px;padding:3px;border:1px solid var(--border)}
|
|
.tab{padding:6px 14px;border-radius:6px;font-size:12px;font-weight:600;cursor:pointer;color:var(--dim);transition:.2s}
|
|
.tab:hover{color:var(--text)}
|
|
.tab.active{background:var(--accent);color:#fff}
|
|
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(100px,1fr));gap:10px;padding:16px 24px}
|
|
.kpi{background:var(--card);border:1px solid var(--border);border-radius:10px;padding:12px;text-align:center}
|
|
.kpi .val{font-family:'JetBrains Mono',monospace;font-size:22px;font-weight:700}
|
|
.kpi .lbl{font-size:10px;color:var(--dim);margin-top:2px;text-transform:uppercase;letter-spacing:1px}
|
|
.kpi.green .val{color:var(--green)}.kpi.blue .val{color:var(--accent)}.kpi.orange .val{color:var(--orange)}.kpi.purple .val{color:var(--purple)}.kpi.cyan .val{color:var(--cyan)}.kpi.pink .val{color:var(--pink)}.kpi.red .val{color:var(--red)}
|
|
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(420px,1fr));gap:12px;padding:0 24px 24px}
|
|
.dept{background:var(--card);border:1px solid var(--border);border-radius:12px;overflow:hidden;transition:.2s}
|
|
.dept:hover{border-color:var(--accent);transform:translateY(-1px)}
|
|
.dept-head{padding:12px 16px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--border)}
|
|
.dept-head h3{font-size:14px;font-weight:700;display:flex;align-items:center;gap:8px}
|
|
.dept-head .badge{font-size:10px;padding:2px 8px;border-radius:10px;font-weight:600}
|
|
.dept-head .cnt{font-size:11px;color:var(--dim)}
|
|
.dept-body{padding:12px 16px;display:flex;flex-wrap:wrap;gap:6px}
|
|
.agent{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;border-radius:6px;font-size:11px;font-weight:500;border:1px solid transparent;transition:.15s;cursor:default}
|
|
.agent:hover{transform:scale(1.05);border-color:rgba(255,255,255,.1)}
|
|
.agent .icon{font-size:13px}
|
|
.pipeline{padding:8px 16px;border-top:1px solid var(--border);display:flex;align-items:center;gap:8px;overflow-x:auto}
|
|
.pipe-step{font-size:10px;padding:3px 8px;border-radius:4px;background:rgba(59,130,246,.1);color:var(--accent);font-weight:600;white-space:nowrap}
|
|
.pipe-arrow{color:var(--dim);font-size:10px}
|
|
.output{padding:8px 16px;border-top:1px solid var(--border);font-size:11px;color:var(--dim);display:flex;align-items:center;gap:6px}
|
|
.output .metric{font-family:'JetBrains Mono',monospace;font-weight:700;font-size:13px}
|
|
.section-title{padding:20px 24px 8px;font-size:13px;font-weight:700;color:var(--dim);text-transform:uppercase;letter-spacing:2px;display:flex;align-items:center;gap:8px}
|
|
.section-title::after{content:'';flex:1;height:1px;background:var(--border)}
|
|
.n8n-tag{font-size:9px;padding:1px 5px;border-radius:3px;background:rgba(59,130,246,.2);color:var(--accent);font-weight:700;margin-left:4px}
|
|
.status-dot{width:6px;height:6px;border-radius:50%;display:inline-block}
|
|
.status-dot.green{background:var(--green)}.status-dot.orange{background:var(--orange)}.status-dot.red{background:var(--red)}
|
|
#view-agents,#view-n8n,#view-infra{display:none}
|
|
#view-overview{display:block}
|
|
</style>
|
|
</head>
|
|
<body style="padding-top:60px"><div style="position:fixed;top:0;left:0;right:0;height:28px;background:#ffffffee;z-index:100;display:flex;align-items:center;padding:0 14px;font-family:Nunito,sans-serif;font-size:.65rem;gap:12px;border-bottom:1px solid #e2e8f0;backdrop-filter:blur(8px)"><b style="color:#059669">WEVIA</b></div>
|
|
<div style="position:fixed;top:30px;left:0;right:0;display:flex;justify-content:center;gap:5px;padding:4px;z-index:100;background:#f8fafcee;backdrop-filter:blur(8px);font-family:Nunito,sans-serif">
|
|
<a href="/agents-archi.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Architecture</a>
|
|
<a href="/director-center.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Director</a>
|
|
<a href="/wevia-meeting-rooms.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Rooms</a>
|
|
<a href="/enterprise-model.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Enterprise</a>
|
|
<a href="/agents-ia.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Pyramid</a>
|
|
<a href="/director-chat.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">Chat</a>
|
|
<a href="/l99-brain.html" style="padding:2px 8px;border-radius:4px;font:700 8px Nunito;text-decoration:none;color:#5a6a80;border:1px solid #c8d8e8">L99</a>
|
|
</div>
|
|
<div class="header">
|
|
<h1>⚡ WEVAL Value Stream Mapping</h1>
|
|
<div style="display:flex;align-items:center;gap:16px">
|
|
<div class="tabs" id="tabs">
|
|
<div class="tab active" onclick="showView('overview')">Overview</div>
|
|
<div class="tab" onclick="showView('agents')">Agents</div>
|
|
<div class="tab" onclick="showView('n8n')">n8n Workflows</div>
|
|
<div class="tab" onclick="showView('infra')">Infrastructure</div>
|
|
</div>
|
|
<span class="live">● LIVE</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="kpis">
|
|
<div class="kpi blue"><div class="val">191</div><div class="lbl">Agents</div></div>
|
|
<div class="kpi purple"><div class="val">21</div><div class="lbl">Depts</div></div>
|
|
<div class="kpi cyan"><div class="val">15</div><div class="lbl">n8n Flows</div></div>
|
|
<div class="kpi green"><div class="val">685</div><div class="lbl">OSS Tools</div></div>
|
|
<div class="kpi orange"><div class="val">3M</div><div class="lbl">Contacts</div></div>
|
|
<div class="kpi pink"><div class="val">141K+</div><div class="lbl">HCPs</div></div>
|
|
<div class="kpi blue"><div class="val">20</div><div class="lbl">Docker</div></div>
|
|
<div class="kpi green"><div class="val">94%</div><div class="lbl">L99 Score</div></div>
|
|
</div>
|
|
|
|
<div id="view-overview">
|
|
<div class="section-title">🏢 Departments & Pipelines</div>
|
|
<div class="grid" id="dept-grid"></div>
|
|
</div>
|
|
|
|
<div id="view-agents">
|
|
<div class="section-title">🤖 All Agents by Department</div>
|
|
<div class="grid" id="agent-grid"></div>
|
|
</div>
|
|
|
|
<div id="view-n8n">
|
|
<div class="section-title">⚙ n8n Workflows (15)</div>
|
|
<div class="grid" id="n8n-grid"></div>
|
|
</div>
|
|
|
|
<div id="view-infra">
|
|
<div class="section-title">🏗️ Infrastructure</div>
|
|
<div class="grid" id="infra-grid"></div>
|
|
</div>
|
|
|
|
<script>
|
|
const DEPTS=[
|
|
{id:'ceo',name:'CEO Office',icon:'👑',color:'#f59e0b',agents:['CEO Brain','Decision','Budget','Strategy','Hiring','Review'],pipeline:['Decision','Orchestration','TaskMgr','Intro','Brief'],output:'1 brief/j',metric:'Leadership'},
|
|
{id:'sal',name:'Prospect & Sales',icon:'🎯',color:'#ef4444',agents:['Leads','Qualify','Outreach','Convert','Close','Ethica','Analyst','Writer','Proposal','Contract'],pipeline:['LeadForge','Outreach','MailWarm','Proposal'],output:'1052 leads',metric:'B2B Pipeline'},
|
|
{id:'con',name:'Consulting',icon:'💼',color:'#8b5cf6',agents:['Architect','Planner','DeerFlow','Critic','Translate','Academy','ECC-36','Persona-6'],pipeline:['Analyse','Design','Process','Deliver','Support'],output:'3 proposals',metric:'SAP/Cloud/IA'},
|
|
{id:'dev',name:'Dev Lab',icon:'⚡',color:'#3b82f6',agents:['FullCode','Review','Test','Deploy','Mauricio','Debugger','Designer','WEDROID','Simplifier','Blueprint','DevForge'],pipeline:['Code','Review','Test','Deploy'],output:'12 deploys/j',metric:'CI/CD'},
|
|
{id:'srv',name:'Infrastructure',icon:'🏗️',color:'#06b6d4',agents:['Watchdog','Guardian','Blade','GitMaster','Loki','Monitor','Fix','Discover','Verify','Report'],pipeline:['Watch','Alert','Fix','Report'],output:'99.9% uptime',metric:'S204+S95+S151'},
|
|
{id:'sec',name:'Security',icon:'🛡️',color:'#ef4444',agents:['Security','Verifier','TruffleHog','DetectSecrets','KeyHacks','shhgit','GitDorking','Nuclei'],pipeline:['Scan','Audit','Patch','Lock'],output:'0 CVE',metric:'5 scanners'},
|
|
{id:'qa',name:'QA / L99',icon:'🧪',color:'#10b981',agents:['QA','Testing','Tracer','Scientist','L99','Plan','Execute','Analyse','Report','Fix'],pipeline:['Plan','Run','Report','Ship'],output:'148 PASS',metric:'153/153'},
|
|
{id:'pha',name:'Pharma & Ethica',icon:'💊',color:'#ec4899',agents:['Explore','DabaDoc','MiroFish','Validate','Enrich','Campaign','Ship'],pipeline:['Scrape','Enrich','Campaign','Ship'],output:'132.7K HCPs',metric:'DZ+MA+TN'},
|
|
{id:'ops',name:'Monitor',icon:'📊',color:'#f59e0b',agents:['TrustMRR','Grafana','Alert','Ortho','Dashboard'],pipeline:['Watch','Alert','Fix','Report'],output:'7.7K opens',metric:'1394 stats'},
|
|
{id:'cron',name:'Automation / Crons',icon:'⏰',color:'#f97316',agents:['EthicaCron','B2BCron','NonRegCron','BackupCron','OSSChainCron','L99AliveCron','GuardianCron','SecretScanCron','KeySyncCron'],pipeline:['Ethica','B2B','NonReg','Backup'],output:'50+ crons',metric:'24/7 auto'},
|
|
{id:'mta',name:'Email MTA',icon:'📧',color:'#6366f1',agents:['PMTA :25','KumoMTA :587','Postfix :2525'],pipeline:['PMTA','KumoMTA','Postfix','Deliver'],output:'7.7K opens',metric:'3M contacts'},
|
|
{id:'ai',name:'AI Engine',icon:'🧠',color:'#8b5cf6',agents:['Groq','Cerebras','MistralAI','SambaNovaAI','AlibabaQwen','NVIDIA-GLM5','Ollama','Sovereign','ClaudeCode','OpenWebUI','Lyria3','SunoAI'],pipeline:['Ingest','Route','Infer','Validate','Deliver'],output:'12 models',metric:'6 providers'},
|
|
{id:'saas',name:'SaaS Products',icon:'📦',color:'#10b981',agents:['LeadForge','OutreachAI','MailWarm','ProposalAI','WEVIA PUBLIC','Manager','WhatsApp API'],pipeline:['Build','Launch','Sell','Support','Scale'],output:'28 tools',metric:'7 products'},
|
|
{id:'intg',name:'OSS Integration',icon:'🔗',color:'#06b6d4',agents:['BrowserUse','OpenClaw','Goose','AIOS','Dify','Mastra','EvoMaster','Activepieces','AEGIS','Prometheus','CrewAI','LangChain','Scrapy','Supermemory','SkillSmith','Flowise','HuggingFace','Langflow','LibreChat','llama-cpp'],pipeline:['Discover','Evaluate','Wire','Test','Deploy'],output:'685 tools',metric:'22/22 INTG'},
|
|
{id:'dock',name:'Docker / Services',icon:'🐳',color:'#2563eb',agents:['Authentik x3','Plausible x3','Uptime-Kuma','Mattermost','SearXNG','Loki','Twenty-Redis','Paperclip','OpenWebUI','Flowise','Vaultwarden','n8n','Qdrant','Redis','Sovereign','CrowdSec'],pipeline:['Start','Configure','Monitor','Scale','Update'],output:'20 dock',metric:'19 UP'},
|
|
{id:'wevia',name:'WEVIA Suite',icon:'🤖',color:'#ec4899',agents:['WEVCODE','WEVIA Life','WEVIAGateway','TTS','MermaidGen','L99','ClaudeSync'],pipeline:['Chat','Code','Life','Gateway'],output:'200/j',metric:'71 modules'},
|
|
{id:'plat',name:'Platform',icon:'🔧',color:'#0d9488',agents:['SkillsRAG','PromptsLib','CodeWiki','AIBench','ModelScope','OSSDiscover','GHGrab','AgentShield','Obsidian'],pipeline:['Skills','Prompts','Wiki','Bench'],output:'4414 sk',metric:'528 skills'},
|
|
{id:'n8n',name:'n8n Workflows',icon:'⚙',color:'#3b82f6',agents:['n8n-EthicaHCP','n8n-B2BLeads','n8n-NonReg','n8n-Sovereign','n8n-WhatsApp','n8n-EmailDrip','n8n-OSSSync','n8n-DeerFlow','n8n-Paperclip','n8n-AzureAD','n8n-Guardian','n8n-SecretScan','n8n-KeySync','n8n-L99Alive','n8n-Backup'],pipeline:['Trigger','Process','Transform','Output'],output:'15 WF',metric:'13 active'},
|
|
{id:'wire',name:'TO WIRE',icon:'🔌',color:'#f97316',agents:['OVH SMS','ListMonk','NoVNC'],pipeline:['Commit','Config','Test','Activate'],output:'3 TODO',metric:'Needs creds'},
|
|
{id:'dorm',name:'Dormants',icon:'💤',color:'#6b7280',agents:['vLLM→Colab','LocalAI→HF','AutoGen→Eval','AnythingLLM','Wazuh','LlamaIndex'],pipeline:['Clone','Evaluate','Wire','Activate'],output:'6 wait',metric:'GPU/eval'},
|
|
];
|
|
|
|
function renderDepts(container,depts){
|
|
const g=document.getElementById(container);
|
|
g.innerHTML='';
|
|
depts.forEach(d=>{
|
|
const agents=d.agents.map(a=>{
|
|
const isN8n=a.startsWith('n8n-');
|
|
const isCron=a.includes('Cron');
|
|
const bg=isN8n?'rgba(59,130,246,.15)':isCron?'rgba(249,115,22,.15)':`rgba(${hexToRgb(d.color)},.12)`;
|
|
const fg=isN8n?'#60a5fa':isCron?'#fb923c':d.color;
|
|
return `<span class="agent" style="background:${bg};color:${fg}">${a}${isN8n?'<span class="n8n-tag">n8n</span>':''}</span>`;
|
|
}).join('');
|
|
const pipe=d.pipeline.map((s,i)=>`<span class="pipe-step">${i+1}. ${s}</span>${i<d.pipeline.length-1?'<span class="pipe-arrow">→</span>':''}`).join('');
|
|
g.innerHTML+=`<div class="dept">
|
|
<div class="dept-head"><h3>${d.icon} ${d.name} <span class="cnt">${d.agents.length}</span></h3><span class="badge" style="background:${d.color}20;color:${d.color}">${d.metric}</span></div>
|
|
<div class="dept-body">${agents}</div>
|
|
<div class="pipeline">${pipe}</div>
|
|
<div class="output"><span class="status-dot green"></span> OUTPUT: <span class="metric" style="color:${d.color}">${d.output}</span></div>
|
|
</div>`;
|
|
});
|
|
}
|
|
|
|
function hexToRgb(h){const r=parseInt(h.slice(1,3),16),g=parseInt(h.slice(3,5),16),b=parseInt(h.slice(5,7),16);return`${r},${g},${b}`}
|
|
|
|
const N8N_FLOWS=[
|
|
{name:'Ethica HCP Enrichment',schedule:'*/6h',nodes:12,status:'active',desc:'DabaDoc scrape → enrich tel/email → Telegram alert'},
|
|
{name:'B2B Lead Generation',schedule:'*/4h',nodes:8,status:'active',desc:'LinkedIn → email pattern → CRM → outbound sequence'},
|
|
{name:'NonReg Watchdog',schedule:'6h/18h',nodes:6,status:'active',desc:'153 tests → Telegram + Mattermost → L99 update'},
|
|
{name:'Sovereign AI Router',schedule:'Webhook',nodes:5,status:'active',desc:'Request → Ollama/Cerebras/Groq → format Anthropic'},
|
|
{name:'WhatsApp Campaign',schedule:'Manual',nodes:7,status:'ready',desc:'HCP list → template → Meta API → track delivery'},
|
|
{name:'Email Drip DZ+MA+TN',schedule:'*/5min',nodes:9,status:'active',desc:'Queue → KumoMTA → track opens/clicks → re-engage'},
|
|
{name:'OSS Discovery Sync',schedule:'*/6h',nodes:6,status:'active',desc:'GitHub scan → score → wire → Paperclip sync'},
|
|
{name:'DeerFlow Research',schedule:'Webhook',nodes:8,status:'active',desc:'Query → 528 skills → Groq → synthesize → report'},
|
|
{name:'Paperclip Chain',schedule:'API',nodes:10,status:'active',desc:'CEO heartbeat → agents → tools → execute → report'},
|
|
{name:'Azure AD O365',schedule:'Daily',nodes:5,status:'active',desc:'6 tenants → token refresh → 1311 accounts sync'},
|
|
{name:'Guardian Auto-Heal',schedule:'*/5min',nodes:4,status:'active',desc:'chattr check → service health → disk → auto-fix'},
|
|
{name:'Secret Scanner',schedule:'Sun 3am',nodes:5,status:'active',desc:'TruffleHog → detect-secrets → dorking → report'},
|
|
{name:'Key Sync',schedule:'*/6h',nodes:4,status:'active',desc:'secrets.env → inventory → validate → alert expired'},
|
|
{name:'L99 Alive Monitor',schedule:'*/30min',nodes:7,status:'active',desc:'14 pages → Playwright → screenshot → state update'},
|
|
{name:'Backup GOLD',schedule:'4am',nodes:5,status:'active',desc:'PG dump → vault → S95 → verify → clean old'},
|
|
];
|
|
|
|
function renderN8n(){
|
|
const g=document.getElementById('n8n-grid');
|
|
g.innerHTML='';
|
|
N8N_FLOWS.forEach(f=>{
|
|
const st=f.status==='active'?'green':'orange';
|
|
g.innerHTML+=`<div class="dept">
|
|
<div class="dept-head"><h3>⚙ ${f.name} <span class="n8n-tag">n8n</span></h3><span class="badge" style="background:rgba(59,130,246,.2);color:#60a5fa">${f.schedule}</span></div>
|
|
<div style="padding:10px 16px;font-size:12px;color:var(--dim)">${f.desc}</div>
|
|
<div class="output"><span class="status-dot ${st}"></span> ${f.nodes} nodes — <span class="metric" style="color:var(--accent)">${f.status.toUpperCase()}</span></div>
|
|
</div>`;
|
|
});
|
|
}
|
|
|
|
const INFRA=[
|
|
{name:'S204 (204.168.152.13)',status:'UP',details:'Hetzner AX102 · 150G SSD · 84% used · 24G free · 20 Docker · Nginx+PHP8.5+PG13 · Ollama 7 models'},
|
|
{name:'S95 (95.216.167.89)',status:'UP',details:'Hetzner · Apache+PHP8.4 · PG13 · 12 schemas 619 tables · PMTA+KumoMTA+Postfix · 192 Arsenal · 40 crons'},
|
|
{name:'S151 (151.80.235.110)',status:'UP',details:'OVH · OpenClaw+Ollama · Tracking relay · 45% disk · Redis+PG+Nginx'},
|
|
{name:'Blade (Razer)',status:'ONLINE',details:'Windows · Claude Code v2.1.89 · Sentinel v2.4 · GLM-5 · 34 capabilities'},
|
|
{name:'S88 (88.198.4.195)',status:'DEAD',details:'GPU mort · Hetzner ANNULÉ · -45€/mois économisés · Archives dans vault'},
|
|
{name:'Sovereign API (:4000)',status:'UP',details:'FastAPI · Ollama PRIMARY → Cerebras → Groq fallback · Anthropic Messages API'},
|
|
{name:'Paperclip (:3100)',status:'UP',details:'150 agents · 520 files · 747KB instructions · CEO org chart'},
|
|
{name:'DeerFlow',status:'UP',details:'528 skills · 3 systemd · Groq primary · Mattermost alerts'},
|
|
];
|
|
|
|
function renderInfra(){
|
|
const g=document.getElementById('infra-grid');
|
|
g.innerHTML='';
|
|
INFRA.forEach(s=>{
|
|
const color=s.status==='UP'||s.status==='ONLINE'?'var(--green)':s.status==='DEAD'?'var(--red)':'var(--orange)';
|
|
g.innerHTML+=`<div class="dept">
|
|
<div class="dept-head"><h3>🖥️ ${s.name}</h3><span class="badge" style="background:${color}20;color:${color}">${s.status}</span></div>
|
|
<div style="padding:10px 16px;font-size:12px;color:var(--dim)">${s.details}</div>
|
|
</div>`;
|
|
});
|
|
}
|
|
|
|
function showView(v){
|
|
['overview','agents','n8n','infra'].forEach(x=>document.getElementById('view-'+x).style.display='none');
|
|
document.getElementById('view-'+v).style.display='block';
|
|
document.querySelectorAll('.tab').forEach(t=>t.classList.remove('active'));
|
|
event.target.classList.add('active');
|
|
if(v==='n8n')renderN8n();
|
|
if(v==='infra')renderInfra();
|
|
if(v==='agents')renderDepts('agent-grid',DEPTS);
|
|
}
|
|
|
|
renderDepts('dept-grid',DEPTS);
|
|
</script>
|
|
</body>
|
|
</html>
|