Files
html/weval-technology-platform.html
Opus af2b5ae533 feat(wevia-agent): wave 312 plan-execute autonomous mode S204
- /api/wevia-agent-exec.php: SSE streaming agent (start/thinking/plan/exec_result/recovery/summary/done)
- Cerebras-think model planning + Cerebras-fast recovery + summary
- Safety guardrails: blocklist rm-rf, dd, mkfs, fork bombs, curl|bash, shutdown, etc
- Auto-recovery on cmd failure (LLM proposes fix cmd)
- Max 5 steps default + 25s timeout per cmd
- /wevia-agent.html: SSE streaming UI with timeline events (user/thinking/plan/exec/recovery/summary)
- 5 example prompts to bootstrap usage
- Featured block in WTP + header link in ai-multichat
- Doctrine 312: WEVIA Master agent = Opus equivalent on server
2026-04-24 12:25:18 +02:00

5643 lines
437 KiB
HTML
Raw Permalink 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" data-theme="dark">
<head>
<!-- V86 AUTH GUARD WTP · Yacine doctrine: WTP = point entrée unique AVEC AUTHENTIFICATION -->
<script>
(function() {
if (window.__WEVAL_V86_AUTH) return;
window.__WEVAL_V86_AUTH = true;
// Dev bypass: ?dev=1 or localhost
var isDev = /[?&]dev=1/.test(location.search) || location.hostname === 'localhost' || location.hostname === '127.0.0.1';
// Quick check via async fetch (non-blocking for speed, redirects if fail)
fetch('/api/auth-check.php', { credentials: 'include', cache: 'no-store' })
.then(function(r) {
if (r.status === 200) {
// Authenticated - mark body + log
document.body && document.body.setAttribute('data-auth', 'ok');
if (window.console) console.log('[V86 Auth Guard] SSO authenticated (200)');
} else if (r.status === 401 || r.status === 403) {
if (isDev) {
if (window.console) console.warn('[V86 Auth Guard] DEV mode - 401 bypassed');
document.body && document.body.setAttribute('data-auth', 'dev');
} else {
// Show redirect banner + redirect after 2s (UX premium - pas brutal)
var banner = document.createElement('div');
banner.style.cssText = 'position:fixed;top:0;left:0;right:0;z-index:99999;background:linear-gradient(135deg,#ef4444,#f59e0b);color:#fff;padding:14px 20px;text-align:center;font:600 14px -apple-system,sans-serif;box-shadow:0 4px 20px rgba(0,0,0,.3);';
banner.innerHTML = '🔐 Authentification requise · redirection vers /login.html dans <span id="v86-countdown">2</span>s · <a href="/login.html" style="color:#fff;text-decoration:underline;font-weight:700;">cliquer ici</a>';
(document.body || document.documentElement).appendChild(banner);
var sec = 2;
var iv = setInterval(function() {
sec--;
var span = document.getElementById('v86-countdown');
if (span) span.textContent = sec;
if (sec <= 0) {
clearInterval(iv);
location.href = '/login.html?from=' + encodeURIComponent(location.pathname);
}
}, 1000);
}
} else {
// Other (500, network etc.) - log + non-blocking
if (window.console) console.warn('[V86 Auth Guard] auth-check returned', r.status);
}
})
.catch(function(e) {
// Auth-check unreachable - graceful: allow (don't break WTP if API down)
if (window.console) console.warn('[V86 Auth Guard] auth-check unreachable, allowing (graceful)', e);
});
})();
</script>
<!-- V86 AUTH GUARD WTP END -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WEVAL Technology Platform — All-in-One ERP Portal</title>
<meta name="description" content="WEVAL Technology Platform — Portail unifié ERP-like tous serveurs, toutes apps, toutes capacités">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
<style>
:root{
--bg-0:#05060a;--bg-1:#0a0c14;--bg-2:#11141f;--bg-3:#181c2b;--bg-card:#0e111c;
--border:#1f2436;--border-hover:#3a425f;
--text-0:#f1f5f9;--text-1:#cbd5e1;--text-2:#94a3b8;--text-3:#64748b;
--accent:#6366f1;--accent-hover:#818cf8;
--success:#10b981;--warning:#f59e0b;--danger:#ef4444;--info:#06b6d4;
--shadow-lg:0 16px 48px rgba(99,102,241,.2);
--radius:12px;--radius-sm:8px;
--trans:.18s cubic-bezier(.4,0,.2,1);
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{font-family:'Inter',system-ui,-apple-system,sans-serif;background:var(--bg-0);color:var(--text-0);font-size:13.5px;line-height:1.5;overflow:hidden}
a{color:inherit;text-decoration:none}
/* ===== LAYOUT ===== */
.wtp-root{display:grid;grid-template-columns:240px 1fr 380px;grid-template-rows:58px 1fr 32px;grid-template-areas:"topbar topbar topbar" "sidebar main chat" "status status status";height:100vh}
/* ===== TOP BAR ===== */
.wtp-topbar{grid-area:topbar;background:linear-gradient(90deg,var(--bg-1),var(--bg-2));border-bottom:1px solid var(--border);display:flex;align-items:center;padding:0 18px;gap:18px;z-index:100}
.wtp-brand{display:flex;align-items:center;gap:10px;font-weight:800;cursor:pointer}
.wtp-logo{width:34px;height:34px;background:linear-gradient(135deg,#6366f1,#8b5cf6,#ec4899);border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:17px;font-weight:900;box-shadow:0 4px 14px rgba(99,102,241,.4)}
.wtp-brand-text{display:flex;flex-direction:column;line-height:1.1}
.wtp-brand-text .top{font-size:13px;letter-spacing:-.01em}
.wtp-brand-text .sub{font-size:9.5px;color:var(--text-3);font-weight:500;letter-spacing:.09em;margin-top:2px;text-transform:uppercase}
.wtp-search{flex:1;max-width:580px;position:relative}
.wtp-search input{width:100%;background:var(--bg-3);border:1px solid var(--border);color:var(--text-0);padding:9px 14px 9px 38px;border-radius:8px;font-size:13px;font-family:inherit;transition:var(--trans)}
.wtp-search input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(99,102,241,.13)}
.wtp-search::before{content:'⌕';position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--text-3);font-size:15px}
.wtp-search-results{position:absolute;top:100%;left:0;right:0;background:var(--bg-2);border:1px solid var(--border);border-radius:8px;max-height:420px;overflow-y:auto;margin-top:4px;display:none;z-index:200;box-shadow:var(--shadow-lg)}
.wtp-search-results.show{display:block}
.wtp-search-result{padding:9px 14px;cursor:pointer;border-bottom:1px solid var(--border);transition:var(--trans)}
.wtp-search-result:hover{background:var(--bg-3)}
.wtp-search-result .title{font-size:13px;font-weight:500;color:var(--text-0)}
.wtp-search-result .module{font-size:11px;color:var(--text-2);margin-top:2px;font-family:'JetBrains Mono',monospace}
.wtp-search-result mark{background:rgba(99,102,241,.35);color:var(--text-0);padding:0 2px;border-radius:2px}
.wtp-actions{display:flex;gap:8px;align-items:center}
.wtp-icon-btn{width:34px;height:34px;background:var(--bg-3);border:1px solid var(--border);border-radius:8px;display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--text-1);font-size:15px;transition:var(--trans)}
.wtp-icon-btn:hover{border-color:var(--accent);color:var(--text-0)}
.wtp-icon-btn .dot{position:absolute;top:6px;right:6px;width:7px;height:7px;background:var(--success);border-radius:50%;box-shadow:0 0 8px var(--success)}
.wtp-user{display:flex;align-items:center;gap:8px;padding:4px 12px 4px 4px;background:var(--bg-3);border:1px solid var(--border);border-radius:18px;cursor:pointer}
.wtp-avatar{width:28px;height:28px;border-radius:50%;background:linear-gradient(135deg,#f59e0b,#ef4444);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:11px;color:#fff}
.wtp-user-name{font-size:12px;font-weight:600}
/* ===== SIDEBAR ===== */
.wtp-sidebar{grid-area:sidebar;background:var(--bg-1);border-right:1px solid var(--border);overflow-y:auto;padding:12px 8px}
.wtp-sidebar::-webkit-scrollbar{width:6px}
.wtp-sidebar::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}
.wtp-nav-label{font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--text-3);padding:8px 10px 4px;font-weight:700}
.wtp-nav-item{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:7px;cursor:pointer;color:var(--text-1);font-size:12.5px;font-weight:500;transition:var(--trans);position:relative;margin-bottom:2px}
.wtp-nav-item:hover{background:var(--bg-3);color:var(--text-0)}
.wtp-nav-item.active{background:linear-gradient(90deg,rgba(99,102,241,.18),transparent);color:var(--text-0);padding-left:8px;border-left:2px solid var(--accent)}
.wtp-nav-icon{font-size:15px;width:20px;text-align:center}
.wtp-nav-count{margin-left:auto;font-size:10px;padding:1px 6px;background:var(--bg-3);border-radius:9px;color:var(--text-2);font-family:'JetBrains Mono',monospace;font-weight:700;min-width:24px;text-align:center}
.wtp-nav-item.active .wtp-nav-count{background:var(--accent);color:#fff}
/* ===== MAIN ===== */
.wtp-main{grid-area:main;overflow-y:auto;padding:18px 24px;background:var(--bg-0)}
.wtp-main::-webkit-scrollbar{width:8px}
.wtp-main::-webkit-scrollbar-thumb{background:var(--border);border-radius:4px}
.wtp-header{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:14px;flex-wrap:wrap;gap:12px}
.wtp-header h1{font-size:22px;font-weight:700;letter-spacing:-.02em;display:flex;align-items:center;gap:12px}
.wtp-header h1 .module-icon{width:40px;height:40px;background:var(--bg-card);border:1px solid var(--border);border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:21px}
.wtp-header-desc{font-size:12.5px;color:var(--text-2);margin-top:4px;margin-left:52px}
.wtp-refresh{background:var(--bg-3);border:1px solid var(--border);color:var(--text-1);padding:7px 12px;border-radius:7px;cursor:pointer;font-size:11.5px;font-family:'JetBrains Mono',monospace;transition:var(--trans)}
.wtp-refresh:hover{border-color:var(--accent);color:var(--text-0)}
/* KPI strip */
.wtp-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(155px,1fr));gap:10px;margin-bottom:20px}
.wtp-kpi{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-sm);padding:11px 14px;transition:var(--trans)}
.wtp-kpi:hover{border-color:var(--accent-hover);transform:translateY(-1px)}
.wtp-kpi-label{font-size:9.5px;color:var(--text-3);text-transform:uppercase;letter-spacing:.11em;font-weight:600}
.wtp-kpi-value{font-size:21px;font-weight:700;margin-top:3px;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.wtp-kpi-value.ok{color:var(--success)}
.wtp-kpi-value.warn{color:var(--warning)}
.wtp-kpi-value.info{color:var(--info)}
.wtp-kpi-unit{font-size:11px;color:var(--text-3);font-weight:500;margin-left:4px}
/* Submodule grid (Fiori tiles) */
.wtp-section-title{font-size:11px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:var(--text-3);margin:12px 0 10px}
.wtp-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));gap:12px}
.wtp-tile{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:14px 16px;cursor:pointer;transition:var(--trans);position:relative;overflow:hidden}
.wtp-tile::before{content:'';position:absolute;top:0;left:0;width:100%;height:3px;background:var(--tile-color,var(--accent));opacity:.65;transition:opacity .2s}
.wtp-tile:hover::before{opacity:1}
.wtp-tile:hover{transform:translateY(-2px);border-color:var(--tile-color,var(--accent));box-shadow:0 8px 24px rgba(0,0,0,.35)}
.wtp-tile-head{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:6px;gap:10px}
.wtp-tile-title{font-size:13.5px;font-weight:600;color:var(--text-0);line-height:1.3}
.wtp-tile-badge{font-size:9.5px;padding:2px 7px;background:var(--bg-3);border-radius:10px;color:var(--text-2);font-family:'JetBrains Mono',monospace;white-space:nowrap;flex-shrink:0}
.wtp-tile-badge.live{background:rgba(16,185,129,.18);color:var(--success)}
.wtp-tile-badge.dormant{background:rgba(100,116,139,.2);color:var(--text-3)}
.wtp-tile-desc{font-size:11.5px;color:var(--text-2);margin-bottom:10px;line-height:1.45}
.wtp-tile-meta{display:flex;flex-wrap:wrap;gap:5px;font-size:10.5px}
.wtp-pill{padding:2px 7px;background:rgba(99,102,241,.12);color:var(--accent-hover);border-radius:6px;font-family:'JetBrains Mono',monospace;font-weight:500}
.wtp-pill.page{background:rgba(16,185,129,.12);color:var(--success)}
.wtp-pill.api{background:rgba(245,158,11,.12);color:var(--warning)}
.wtp-pill.docker{background:rgba(6,182,212,.12);color:var(--info)}
.wtp-pill.script{background:rgba(236,72,153,.12);color:#f472b6}
.wtp-pill.path{background:rgba(168,85,247,.12);color:#c084fc}
.wtp-tile-footer{margin-top:10px;display:flex;justify-content:space-between;align-items:center;padding-top:10px;border-top:1px solid var(--border)}
.wtp-tile-open{font-size:11px;color:var(--accent-hover);font-weight:600}
/* HOME view specific */
.wtp-home-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:12px;margin-bottom:20px}
.wtp-home-module{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:18px;cursor:pointer;transition:var(--trans);position:relative;overflow:hidden}
.wtp-home-module::before{content:'';position:absolute;top:0;left:0;width:4px;height:100%;background:var(--mod-color,var(--accent))}
.wtp-home-module:hover{transform:translateY(-3px);border-color:var(--mod-color,var(--accent));box-shadow:var(--shadow-lg)}
.wtp-home-icon{font-size:32px;margin-bottom:10px;display:inline-block;filter:drop-shadow(0 4px 12px rgba(99,102,241,.25))}
.wtp-home-label{font-size:15px;font-weight:700;color:var(--text-0);margin-bottom:4px}
.wtp-home-tag{font-size:11.5px;color:var(--text-2);line-height:1.45;margin-bottom:12px}
.wtp-home-stat{display:flex;gap:14px;font-size:11px}
.wtp-home-stat div{display:flex;align-items:center;gap:4px}
.wtp-home-stat .num{font-weight:700;color:var(--mod-color,var(--accent));font-family:'JetBrains Mono',monospace}
.wtp-home-stat .lbl{color:var(--text-3)}
/* ===== RIGHT CHAT ===== */
.wtp-chat{grid-area:chat;background:var(--bg-1);border-left:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden}
.wtp-chat-head{padding:10px 14px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;background:var(--bg-2)}
.wtp-chat-title{font-size:12.5px;font-weight:600;display:flex;align-items:center;gap:8px}
.wtp-chat-title .pulse{width:7px;height:7px;background:var(--success);border-radius:50%;animation:pulse 2s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}
.wtp-chat-frame{flex:1;width:100%;border:0;background:var(--bg-0)}
/* ===== STATUS BAR ===== */
.wtp-statusbar{grid-area:status;background:linear-gradient(90deg,var(--bg-1),var(--bg-2));border-top:1px solid var(--border);display:flex;align-items:center;padding:0 16px;gap:20px;font-size:11px;color:var(--text-2);font-family:'JetBrains Mono',monospace}
.wtp-status-item{display:flex;align-items:center;gap:5px}
.wtp-status-item .dot{width:7px;height:7px;border-radius:50%}
.wtp-status-item .dot.ok{background:var(--success);box-shadow:0 0 6px var(--success)}
.wtp-status-item .dot.warn{background:var(--warning);box-shadow:0 0 6px var(--warning)}
.wtp-status-item .dot.err{background:var(--danger);box-shadow:0 0 6px var(--danger)}
.wtp-status-item strong{color:var(--text-0);font-weight:700}
.wtp-status-spacer{flex:1}
/* Loading */
.wtp-loading{display:flex;align-items:center;justify-content:center;height:200px;color:var(--text-3);font-size:12px}
.wtp-loading::after{content:'●';animation:dots 1.4s infinite;font-size:20px;margin-left:6px}
@keyframes dots{0%,20%{opacity:0}40%,100%{opacity:1}}
/* Responsive — hide chat on small */
@media(max-width:1280px){.wtp-root{grid-template-columns:220px 1fr 0}.wtp-chat{display:none}}
@media(max-width:900px){.wtp-root{grid-template-columns:0 1fr 0}.wtp-sidebar{display:none}}
/* ===== VISUAL MANAGEMENT PREMIUM (VISUAL-MGMT-PREMIUM-V1, doctrine 60 + L6S) ===== */
.vm-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:14px;margin-bottom:24px}
.vm-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px;position:relative;overflow:hidden;transition:var(--trans)}
.vm-card:hover{border-color:var(--border-hover)}
.vm-card-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}
.vm-card-title{font-size:10.5px;color:var(--text-2);text-transform:uppercase;letter-spacing:.7px;font-weight:600}
.vm-card-badge{font-size:9.5px;padding:2px 7px;border-radius:8px;background:rgba(16,185,129,.15);color:#5eead4;font-weight:600}
.vm-card-badge.warn{background:rgba(245,158,11,.15);color:#fbbf24}
.vm-card-badge.danger{background:rgba(239,68,68,.15);color:#fca5a5}
/* Gauges */
.vm-gauge{position:relative;width:100%;height:125px;display:flex;align-items:center;justify-content:center}
.vm-gauge svg{width:100%;height:100%;max-width:200px}
.vm-gauge-value{position:absolute;top:52%;left:50%;transform:translate(-50%,-50%);text-align:center}
.vm-gauge-num{font-size:28px;font-weight:800;background:linear-gradient(135deg,#22d3ee,#a855f7);-webkit-background-clip:text;background-clip:text;color:transparent;line-height:1}
.vm-gauge-unit{font-size:10px;color:var(--text-3);margin-top:3px;letter-spacing:.5px}
.vm-gauge-label{text-align:center;font-size:11px;color:var(--text-2);margin-top:4px;letter-spacing:.3px}
/* Andon (Lean 6 Sigma light stack) */
.vm-andon{display:flex;flex-direction:column;gap:8px;align-items:center;padding:14px 0}
.vm-light{width:34px;height:34px;border-radius:50%;border:2px solid rgba(255,255,255,.06);position:relative;transition:var(--trans)}
.vm-light.on.green{background:radial-gradient(circle at 30% 30%,#6ee7b7,#10b981);box-shadow:0 0 20px #10b981,0 0 40px #10b981aa;animation:vm-pulse 2s infinite}
.vm-light.on.yellow{background:radial-gradient(circle at 30% 30%,#fde68a,#f59e0b);box-shadow:0 0 20px #f59e0b,0 0 40px #f59e0baa;animation:vm-pulse 1.4s infinite}
.vm-light.on.red{background:radial-gradient(circle at 30% 30%,#fca5a5,#ef4444);box-shadow:0 0 20px #ef4444,0 0 40px #ef4444aa;animation:vm-pulse .9s infinite}
.vm-light.off{background:var(--bg-3)}
.vm-light-label{font-size:9.5px;color:var(--text-3);text-align:center;margin-top:2px;font-family:'JetBrains Mono',monospace}
@keyframes vm-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.07)}}
/* Heatmap */
.vm-heat{display:grid;grid-template-columns:repeat(12,1fr);gap:2px;margin-top:8px}
.vm-heat-cell{aspect-ratio:1;border-radius:2px;background:var(--bg-3);position:relative;cursor:help;transition:var(--trans)}
.vm-heat-cell:hover{transform:scale(1.3);z-index:10;border:1px solid var(--text-0)}
.vm-heat-cell[data-v="0"]{background:#1f2436}
.vm-heat-cell[data-v="1"]{background:rgba(16,185,129,.15)}
.vm-heat-cell[data-v="2"]{background:rgba(16,185,129,.35)}
.vm-heat-cell[data-v="3"]{background:rgba(16,185,129,.6)}
.vm-heat-cell[data-v="4"]{background:rgba(16,185,129,1)}
.vm-heat-cell[data-v="w"]{background:rgba(245,158,11,.6)}
.vm-heat-cell[data-v="r"]{background:rgba(239,68,68,.8)}
.vm-heat-legend{display:flex;gap:6px;font-size:9.5px;color:var(--text-3);margin-top:6px;align-items:center}
.vm-heat-legend span{display:inline-block;width:10px;height:10px;border-radius:2px}
/* Sparkline */
.vm-spark{width:100%;height:54px;display:block}
.vm-spark path.line{fill:none;stroke:url(#grad-spark);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}
.vm-spark path.area{fill:url(#grad-spark-area);opacity:.35}
/* Progress ring for L6S Cp/Cpk */
.vm-ring{position:relative;width:100%;height:100%}
.vm-ring svg{transform:rotate(-90deg)}
.vm-ring-text{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center}
/* Bar compare (ACQUIS vs DORMANTS) */
.vm-bars{display:flex;flex-direction:column;gap:6px;margin-top:6px}
.vm-bar-row{display:grid;grid-template-columns:75px 1fr 42px;gap:8px;align-items:center;font-size:11px}
.vm-bar-label{color:var(--text-1);font-weight:500}
.vm-bar-track{height:8px;background:var(--bg-3);border-radius:4px;overflow:hidden;position:relative}
.vm-bar-fill{height:100%;border-radius:4px;transition:width 1.2s cubic-bezier(.4,0,.2,1);background:linear-gradient(90deg,#10b981,#06b6d4)}
.vm-bar-fill.warn{background:linear-gradient(90deg,#f59e0b,#ef4444)}
.vm-bar-count{text-align:right;color:var(--text-1);font-weight:600;font-family:'JetBrains Mono',monospace}
/* Kanban flow (L6S value stream) */
.vm-flow{display:grid;grid-template-columns:repeat(6,1fr);gap:4px;margin-top:8px}
.vm-flow-step{text-align:center;padding:7px 4px;background:var(--bg-3);border-radius:6px;position:relative;font-size:10px;color:var(--text-2)}
.vm-flow-step.done{background:rgba(16,185,129,.2);color:#6ee7b7}
.vm-flow-step.work{background:rgba(99,102,241,.2);color:#a5b4fc;animation:vm-pulse 2s infinite}
.vm-flow-step.block{background:rgba(239,68,68,.2);color:#fca5a5}
.vm-flow-step .num{display:block;font-size:16px;font-weight:800;margin-bottom:2px}
/* Coverage donut */
.vm-donut-wrap{display:flex;align-items:center;gap:16px}
.vm-donut{position:relative;width:110px;height:110px;flex-shrink:0}
.vm-donut svg{transform:rotate(-90deg)}
.vm-donut-text{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center}
.vm-donut-big{font-size:24px;font-weight:800;color:var(--text-0)}
.vm-donut-lbl{font-size:9px;color:var(--text-3);letter-spacing:.5px;text-transform:uppercase}
.vm-donut-list{flex:1;display:flex;flex-direction:column;gap:5px;font-size:10.5px}
.vm-donut-list div{display:flex;justify-content:space-between;align-items:center}
.vm-donut-list .dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:6px}
/* Scorecard (Andon KPI) */
.vm-score{text-align:center;padding:6px 0}
.vm-score-big{font-size:32px;font-weight:800;line-height:1}
.vm-score-big.ok{color:#10b981}
.vm-score-big.warn{color:#f59e0b}
.vm-score-big.danger{color:#ef4444}
.vm-score-sub{font-size:10.5px;color:var(--text-3);margin-top:4px;letter-spacing:.3px}
/* Span utilities */
.vm-col-4{grid-column:span 4}.vm-col-3{grid-column:span 3}.vm-col-6{grid-column:span 6}.vm-col-8{grid-column:span 8}.vm-col-12{grid-column:span 12}
@media(max-width:1280px){.vm-col-4{grid-column:span 6}.vm-col-3{grid-column:span 6}}
/* Pulse live indicator */
.vm-live{display:inline-flex;align-items:center;gap:5px;font-size:9.5px;color:#10b981}
.vm-live::before{content:'';width:6px;height:6px;background:#10b981;border-radius:50%;box-shadow:0 0 6px #10b981;animation:vm-pulse 1.5s infinite}
/* Hide old static kpi cards when VM active */
.vm-active .wtp-kpis{display:none}
/* ===== V64-DEPTS-KPI-BESTPRACTICES (SAP SAFe PMI L6S) ===== */
.v64-dept-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;margin-top:6px}
@media(max-width:1280px){.v64-dept-grid{grid-template-columns:repeat(3,1fr)}}
@media(max-width:768px){.v64-dept-grid{grid-template-columns:repeat(2,1fr)}}
.v64-dept{background:var(--bg-3);border-radius:8px;padding:9px 10px;border-left:3px solid var(--dcol,#6366f1);position:relative;transition:var(--trans);cursor:default}
.v64-dept:hover{background:var(--bg-2);transform:translateY(-1px)}
.v64-dept-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}
.v64-dept-name{font-size:11px;font-weight:600;color:var(--text-0);display:flex;align-items:center;gap:5px}
.v64-dept-sap{font-size:8.5px;color:var(--text-3);font-family:'JetBrains Mono',monospace;padding:1px 5px;background:rgba(99,102,241,.1);border-radius:3px}
.v64-dept-kpis{display:grid;grid-template-columns:repeat(2,1fr);gap:4px;font-size:9.5px}
.v64-dept-kpi{background:var(--bg-1);padding:4px 6px;border-radius:4px;position:relative}
.v64-dept-kpi .l{color:var(--text-3);font-size:9px;letter-spacing:.2px;display:block;margin-bottom:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.v64-dept-kpi .v{color:var(--text-0);font-weight:700;font-size:10.5px;font-family:'JetBrains Mono',monospace}
.v64-dept-kpi .t{color:var(--text-3);font-size:8.5px;font-family:'JetBrains Mono',monospace}
.v64-dept-kpi.ok{border-left:2px solid #10b981}
.v64-dept-kpi.warn{border-left:2px solid #f59e0b}
.v64-dept-kpi.critical{border-left:2px solid #ef4444}
.v64-dept-kpi.critical .v{color:#fca5a5}
.v64-dept-kpi.warn .v{color:#fbbf24}
.v64-dept-kpi.ok .v{color:#6ee7b7}
.v64-dept-agents{display:flex;align-items:center;gap:6px;margin-top:6px;font-size:9px;color:var(--text-3)}
.v64-dept-agents .pct-bar{flex:1;height:3px;background:var(--bg-0);border-radius:2px;overflow:hidden}
.v64-dept-agents .pct-fill{height:100%;background:linear-gradient(90deg,#10b981,#06b6d4);transition:width 1s cubic-bezier(.4,0,.2,1)}
/* Best practices */
.v64-bp-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;margin-top:8px}
@media(max-width:1280px){.v64-bp-grid{grid-template-columns:repeat(2,1fr)}}
.v64-bp{background:var(--bg-3);border-radius:8px;padding:12px;position:relative}
.v64-bp-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}
.v64-bp-title{font-size:11px;font-weight:600;color:var(--text-0);display:flex;align-items:center;gap:6px}
.v64-bp-maturity{font-size:13px;font-weight:800;font-family:'JetBrains Mono',monospace}
.v64-bp-maturity.ok{color:#10b981}
.v64-bp-maturity.warn{color:#f59e0b}
.v64-bp-maturity.low{color:#ef4444}
.v64-bp-ring{width:100%;height:46px;margin-bottom:10px;display:flex;align-items:center;gap:10px}
.v64-bp-ring-bar{flex:1;height:6px;background:var(--bg-0);border-radius:3px;overflow:hidden;position:relative}
.v64-bp-ring-fill{height:100%;background:linear-gradient(90deg,#ef4444 0%,#f59e0b 40%,#10b981 80%);transition:width 1.2s cubic-bezier(.4,0,.2,1)}
.v64-bp-principles{display:flex;flex-direction:column;gap:4px;font-size:10px}
.v64-bp-p{display:flex;align-items:center;justify-content:space-between;padding:3px 6px;background:var(--bg-1);border-radius:4px}
.v64-bp-p-label{color:var(--text-1);flex:1}
.v64-bp-p-status{font-size:9px;padding:1px 5px;border-radius:8px;font-weight:600;margin-left:4px;white-space:nowrap}
.v64-bp-p-status.ok{background:rgba(16,185,129,.18);color:#6ee7b7}
.v64-bp-p-status.partial{background:rgba(245,158,11,.18);color:#fbbf24}
.v64-bp-p-status.missing{background:rgba(239,68,68,.18);color:#fca5a5}
/* Gaps list */
.v64-gaps{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;max-height:260px;overflow-y:auto;padding-right:4px}
@media(max-width:1280px){.v64-gaps{grid-template-columns:repeat(2,1fr)}}
@media(max-width:768px){.v64-gaps{grid-template-columns:1fr}}
.v64-gap{background:var(--bg-3);border-radius:6px;padding:7px 10px;border-left:2.5px solid #ef4444;display:flex;align-items:center;justify-content:space-between;font-size:10px;gap:8px}
.v64-gap:hover{background:var(--bg-2)}
.v64-gap-name{color:var(--text-0);font-weight:600;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.v64-gap-dept{color:var(--text-3);font-family:'JetBrains Mono',monospace;font-size:8.5px;padding:1px 5px;background:rgba(99,102,241,.12);border-radius:3px;white-space:nowrap}
.v64-gaps::-webkit-scrollbar{width:6px}
.v64-gaps::-webkit-scrollbar-track{background:var(--bg-0)}
.v64-gaps::-webkit-scrollbar-thumb{background:var(--bg-3);border-radius:3px}
/* V73-FIORI-TILES - SAP S/4HANA Fiori-inspired sub-module rendering */
.wtp-tile{display:flex;flex-direction:column;min-height:152px}
.wtp-tile-icon{font-size:22px;line-height:1;margin-bottom:10px;opacity:0.85}
.wtp-tile:hover .wtp-tile-icon{opacity:1;transform:scale(1.1);transition:transform .2s}
.wtp-tile-title{font-weight:700 !important}
.wtp-tile-meta .wtp-pill{transition:all .15s}
.wtp-tile-meta .wtp-pill:hover{transform:translateY(-1px);box-shadow:0 2px 8px rgba(99,102,241,0.25)}
/* V73 new subfooter */
.wtp-tile-subfooter{margin-top:auto;padding-top:10px;border-top:1px solid var(--border);display:flex;justify-content:space-between;align-items:center;font-size:10.5px;color:var(--text-3)}
.wtp-tile-subfooter .kpi-mini{font-family:'JetBrains Mono',monospace;color:var(--success);font-weight:700}
</style>
<!-- V108 Plausible Analytics -->
<script defer data-domain="weval-consulting.com" src="https://analytics.weval-consulting.com/js/script.js"></script>
<link rel="stylesheet" href="/css/wevia-portal-consistency.css">
<style id="wave264-css-override">
/* WAVE_264: prevent collisions between injected Logout and WTP Yacine button */
#weval-gl { top: 92px !important; right: 12px !important; }
/* Prevent Droid old bottom position from being re-added by cache */
a#opus-droid-link[style*="bottom:20px"] { top: 12px !important; right: 200px !important; bottom: auto !important; }
</style>
<!-- DOCTRINE-60-UX-ENRICH cerebras-qwen-235b 20260424-121921 --><style id="doctrine60-ux-weval-technology-platform">
body::before {
content: '';
position: fixed;
width: 100%;
height: 100%;
background: radial-gradient(circle, rgba(0,0,0,0.12), transparent 70%);
z-index: -1;
top: 0;
left: 0;
}
.card, .btn, .kpi, .panel {
opacity: 0;
transform: translateY(20px);
transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}
.enter-stagger {
opacity: 1;
transform: translateY(0);
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.6; }
}
.pulse, .active, .live-indicator, .online {
animation: pulse 3s ease-in-out infinite;
}
.card:hover {
box-shadow: 0 8px 24px rgba(0,0,0,0.15);
border-color: var(--accent);
}
.modal, .chat, .speech, .overlay {
backdrop-filter: blur(12px);
}
</style>
</head>
<body>
<div class="wevia-portal-banner">
<span class="wevia-portal-banner-label">🌐 WEVIA ECOSYSTEM</span>
<a href="/all-ia-hub.html" data-portal="hub" class="wevia-portal-banner-link">🧠 All-IA Hub</a>
<a href="/wevia-master.html" data-portal="master" class="wevia-portal-banner-link">🤖 WEVIA Master</a>
<a href="/wevia-orchestrator.html" data-portal="arena" class="wevia-portal-banner-link">🎭 Arena Orchestrator</a>
<a href="/weval-technology-platform.html" data-portal="wtp" class="wevia-portal-banner-link wevia-current">🧭 WTP Hub</a>
<span class="wevia-portal-badge-wave">WAVE 264</span>
<!-- WAVE_264_CONSOLIDATE: Factory + Archi + Yacine dans top banner -->
<span id="w264-factory-pill" onclick="w263Open()" style="margin-left:12px;padding:4px 12px;border-radius:14px;background:linear-gradient(135deg,rgba(34,211,238,.2),rgba(168,85,247,.15));border:1px solid rgba(34,211,238,.4);color:#67e8f9;font-size:11px;font-weight:700;cursor:pointer;display:inline-flex;align-items:center;gap:5px" title="Factory Health Monitor (30 agents)"><span>🏭</span><span id="w264-factory-badge">Factory: --</span></span>
<button onclick="v80Open()" style="margin-left:8px;background:linear-gradient(135deg,#6366f1,#8b5cf6);color:#fff;border:none;padding:4px 12px;border-radius:14px;cursor:pointer;font-size:11px;font-weight:700;display:inline-flex;align-items:center;gap:5px" title="Archi complete"><span>🧭</span>Archi</button>
<span style="margin-left:8px;display:inline-flex;align-items:center;gap:6px;padding:3px 10px 3px 4px;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.1);border-radius:14px">
<span style="width:22px;height:22px;border-radius:50%;background:linear-gradient(135deg,#f59e0b,#ef4444);color:#fff;font-size:10px;font-weight:800;display:inline-flex;align-items:center;justify-content:center">YM</span>
<span style="color:#cbd5e1;font-size:11px;font-weight:600">Yacine M.</span>
</span>
</div>
<div class="wtp-root">
<!-- TOP BAR -->
<div class="wtp-topbar">
<div class="wtp-brand" onclick="navigateTo('home')">
<div class="wtp-logo">W</div>
<div class="wtp-brand-text">
<div class="top">WEVAL Technology</div>
<div class="sub">Platform · ERP Portal</div>
</div>
</div>
<div class="wtp-search">
<input type="text" id="wtp-search-input" placeholder="Rechercher page, API, app, module, agent…" autocomplete="off">
<div class="wtp-search-results" id="wtp-search-results"></div>
</div>
<div class="wtp-actions">
<div class="wtp-icon-btn" title="Notifications" onclick="showNotifications()" style="position:relative">🔔<span class="dot"></span></div>
<div class="wtp-icon-btn" title="Help" onclick="openUrl('/wiki/')">?</div>
<!-- WAVE_264_CONSOLIDATE: Archi + Yacine moved to top banner -->
</div>
</div>
<!-- LEFT SIDEBAR -->
<div class="wtp-sidebar" id="wtp-sidebar">
<div class="wtp-nav-label">Portail</div>
<div class="wtp-nav-item active" data-mod="home" onclick="navigateTo('home')">
<span class="wtp-nav-icon">🏠</span><span>Accueil</span>
</div>
<div class="wtp-nav-label">Modules ERP</div>
<div id="wtp-nav-modules"></div>
<div class="wtp-nav-label" style="margin-top:16px">📊 Dashboards</div>
<div class="wtp-nav-item" onclick="window.location.href='/dashboards-index.html'" style="cursor:pointer">
<span class="wtp-nav-icon">🎯</span><span>Dashboards Index</span>
</div>
<div class="wtp-nav-item" onclick="window.location.href='/wtp-udock-coverage.html'" style="cursor:pointer">
<span class="wtp-nav-icon">🔗</span><span>Dock Coverage</span>
</div>
<div class="wtp-nav-item" onclick="window.location.href='/token-health-dashboard.html'" style="cursor:pointer">
<span class="wtp-nav-icon">🔑</span><span>Token Health</span>
</div>
<div class="wtp-nav-item" onclick="window.location.href='/command-center.html'" style="cursor:pointer">
<span class="wtp-nav-icon">🎛</span><span>Command Center</span>
</div>
<div class="wtp-nav-label" style="margin-top:16px">🧠 IA</div>
<div class="wtp-nav-item" onclick="window.location.href='/wevia-master.html'" style="cursor:pointer">
<span class="wtp-nav-icon">🤖</span><span>WEVIA Master</span>
</div>
<div class="wtp-nav-item" onclick="window.location.href='/all-ia-hub.html'" style="cursor:pointer">
<span class="wtp-nav-icon">🎓</span><span>All-IA Hub</span>
</div>
<div class="wtp-nav-item" onclick="window.location.href='/wevia-orchestrator.html'" style="cursor:pointer">
<span class="wtp-nav-icon">🎼</span><span>Orchestrator</span>
</div>
<div class="wtp-nav-label" style="margin-top:16px">📘 Knowledge</div>
<div class="wtp-nav-item" onclick="window.location.href='/wiki.html'" style="cursor:pointer">
<span class="wtp-nav-icon">📘</span><span>Wiki</span>
</div>
<div class="wtp-nav-item" onclick="window.location.href='/nonreg.html'" style="cursor:pointer">
<span class="wtp-nav-icon"></span><span>NonReg</span>
</div>
</div>
<!-- MAIN AREA -->
<div class="wtp-main" id="wtp-main">
<div class="wtp-loading">Chargement de la plateforme</div>
</div>
<!-- RIGHT CHAT (WEVIA Master) -->
<div class="wtp-chat">
<div class="wtp-chat-head">
<div class="wtp-chat-title"><span class="pulse"></span>WEVIA Master · multi-agents</div>
<div class="wtp-icon-btn" title="Ouvrir en plein écran" onclick="openUrl('/wevia-master.html')" style="width:28px;height:28px;font-size:12px"></div>
</div>
<iframe class="wtp-chat-frame" src="/wevia-widget.html" title="WEVIA Master chat"></iframe>
</div>
<!-- STATUS BAR -->
<div class="wtp-statusbar" id="wtp-statusbar">
<div class="wtp-status-item"><span class="dot ok"></span>S204 <strong>live</strong></div>
<div class="wtp-status-item"><span class="dot ok"></span>S95 <strong>live</strong></div>
<div class="wtp-status-item" id="st-blade-wrap"><span class="dot warn" id="st-blade-dot"></span><span id="st-blade-label">Blade <strong id="st-blade-text">checking</strong></span></div>
<div class="wtp-status-item">Docker <strong id="st-docker"></strong></div>
<div class="wtp-status-item">Providers <strong id="st-prov"></strong></div>
<div class="wtp-status-item">Qdrant <strong id="st-qdrant"></strong></div>
<div class="wtp-status-item">NonReg <strong id="st-nr"></strong></div>
<div class="wtp-status-item">HCPs <strong id="st-hcp"></strong></div>
<div class="wtp-status-spacer"></div>
<div class="wtp-status-item">WTP <strong id="st-ver">v2.0</strong></div>
<div class="wtp-status-item" id="st-time"></div>
</div>
</div>
<script>
let TREE = null;
let CURRENT_MOD = 'home';
const COLORS = {intelligence:'#6366f1',commerce:'#10b981',finance:'#f97316',marketing:'#f59e0b',growth:'#ec4899',hr:'#0ea5e9',supply:'#84cc16',operations:'#8b5cf6',erp_integrations:'#dc2626',communications:'#f43f5e',security:'#6b7280',development:'#06b6d4',knowledge:'#0d9488',multimodal:'#a855f7',rnd_labs:'#7c3aed'};
// Load full tree from API
async function loadTree(){
try{
const r = await fetch('/api/weval-technology-platform-api.php');
TREE = await r.json();
renderSidebar();
renderStatusBar();
navigateTo(CURRENT_MOD);
}catch(e){
document.getElementById('wtp-main').innerHTML = '<div class="wtp-loading">Erreur chargement API: '+e.message+'</div>';
}
}
function renderSidebar(){
const el = document.getElementById('wtp-nav-modules');
if (!TREE) return;
// 16 ERP modules
let html = Object.entries(TREE.modules).map(([id, mod]) => {
const count = (mod.submodules||[]).length;
return `<div class="wtp-nav-item" data-mod="${id}" onclick="navigateTo('${id}')">
<span class="wtp-nav-icon" style="color:${mod.color}">${mod.icon}</span>
<span>${mod.label}</span>
<span class="wtp-nav-count">${count}</span>
</div>`;
}).join('');
// SECTION SÉPARATRICE · POINT D'ENTRÉE ENRICHI (Opus Yacine 19avr)
html += `<div style="padding:10px 14px 6px;font-size:10px;color:var(--wtp-muted);text-transform:uppercase;letter-spacing:1.5px;margin-top:14px;border-top:1px solid var(--wtp-border);padding-top:14px">POINT D'ENTRÉE TOTAL</div>`;
const extras = [
{id:'infra', icon:'🖥', label:'Infrastructure', color:'#22d3ee', count: (TREE.infra?.machines?.length||0) + (TREE.infra?.docker?.length||0)},
{id:'all_pages', icon:'📂', label:'Toutes les pages', color:'#d4af37', count: TREE.all_pages?.total||0},
{id:'all_apis', icon:'🔌', label:'Toutes les APIs', color:'#a855f7', count: TREE.apis?.total||0},
{id:'multiagent', icon:'🤖', label:'Multi-Agent Modes', color:'#ef4444', count: TREE.multiagent_modes?.length||0},
{id:'truth', icon:'🔒', label:'Truth Registry', color:'#22c55e', count: TREE.truth_registry?.agents||0},
{id:'crm_bridge', icon:'🔗', label:'CRM Bridge (4 CRMs)', color:'#22d3ee', count: 4},
];
html += extras.map(e => `<div class="wtp-nav-item" data-mod="${e.id}" onclick="navigateTo('${e.id}')">
<span class="wtp-nav-icon" style="color:${e.color}">${e.icon}</span>
<span>${e.label}</span>
<span class="wtp-nav-count">${e.count}</span>
</div>`).join('');
el.innerHTML = html;
}
function navigateTo(modId){
CURRENT_MOD = modId;
document.querySelectorAll('.wtp-nav-item').forEach(i => i.classList.toggle('active', i.dataset.mod === modId));
if (modId === 'home') renderHome();
else if (modId === 'infra') renderInfra();
else if (modId === 'crm_bridge') { window.open('/wevia-ia/wevia-admin-crm-v68.php', '_blank'); return; }
else if (modId === 'all_pages') renderAllPages();
else if (modId === 'all_apis') renderAllApis();
else if (modId === 'multiagent') renderMultiagent();
else if (modId === 'truth') renderTruth();
else renderModule(modId);
document.getElementById('wtp-main').scrollTop = 0;
}
// === POINT D'ENTRÉE TOTAL views (Opus Yacine 19avr) ===
function renderInfra(){
const main = document.getElementById('wtp-main');
const i = TREE.infra || {};
const machines = (i.machines||[]).map(m => `
<div style="background:var(--wtp-panel2);padding:18px;border-radius:8px;border:1px solid var(--wtp-border)">
<div style="font-size:18px;font-weight:800;margin-bottom:4px;color:var(--wtp-ac)">${m.id}</div>
<div style="font-size:11px;color:var(--wtp-muted);margin-bottom:10px">${m.type||''}</div>
<div style="font-size:13px;line-height:1.6">${m.role||''}</div>
${m.cpu ? `<div style="margin-top:8px;font-size:11px;color:var(--wtp-muted)">CPU: ${m.cpu} · RAM: ${m.ram||'?'} · Disk: ${m.disk||'?'}</div>` : ''}
</div>`).join('');
const docker = (i.docker||[]).slice(0, 25).map(d => `
<div style="display:flex;justify-content:space-between;padding:8px 12px;background:var(--wtp-panel);border-radius:6px;margin-bottom:4px;font-size:12px">
<span style="font-weight:600">${d.name||'?'}</span>
<span style="color:var(--wtp-muted);font-family:monospace;font-size:10px">${d.status||''}</span>
</div>`).join('');
const gpus = (i.gpus||[]).map(g => `
<div style="background:var(--wtp-panel);padding:14px;border-radius:8px;margin-bottom:6px">
<div style="font-weight:700">${g.name||'?'}</div>
<div style="font-size:11px;color:var(--wtp-muted);margin-top:4px">${g.note||''}</div>
${g.mem_total_mb ? `<div style="margin-top:6px;font-family:monospace;font-size:11px">Mem: ${g.mem_used_mb}/${g.mem_total_mb} MB · Temp: ${g.temp_c}°C · Util: ${g.util_pct}%</div>` : ''}
</div>`).join('');
const subdoms = Object.entries(i.subdomains||{}).map(([d, role]) => `
<a href="https://${d}/" target="_blank" style="display:flex;justify-content:space-between;padding:8px 12px;background:var(--wtp-panel);border-radius:6px;margin-bottom:4px;font-size:12px;text-decoration:none;color:var(--wtp-text)">
<span style="font-family:monospace">${d}</span>
<span style="color:var(--wtp-muted)">${role}</span>
</a>`).join('');
main.innerHTML = `
<div style="padding:24px">
<h1 style="font-size:28px;margin-bottom:6px">🖥 Infrastructure</h1>
<div style="color:var(--wtp-muted);margin-bottom:24px">Machines · Docker · GPUs · Blade · Subdomains · tout en un</div>
<h2 style="font-size:18px;margin-bottom:12px">💻 Machines · ${(i.machines||[]).length}</h2>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px;margin-bottom:28px">${machines}</div>
<h2 style="font-size:18px;margin-bottom:12px">🔧 Blade yacineutt (Sentinel · Chrome persist)</h2>
<div style="background:var(--wtp-panel2);padding:18px;border-radius:8px;border:1px solid var(--wtp-border);margin-bottom:28px">
<div style="font-size:14px;font-weight:700;margin-bottom:8px">${i.blade?.host||'Razer Blade'}</div>
<div style="color:var(--wtp-muted);font-size:12px;margin-bottom:10px">${i.blade?.role||''}</div>
<div style="font-size:12px;margin-bottom:6px">Profile: ${i.blade?.yacineutt_profile||'?'}</div>
<div style="display:flex;gap:6px;flex-wrap:wrap;margin-top:10px">
${(i.blade?.services||[]).map(s=>`<span style="background:var(--wtp-panel);padding:4px 10px;border-radius:99px;font-size:11px;font-family:monospace">${s}</span>`).join('')}
</div>
</div>
<h2 style="font-size:18px;margin-bottom:12px">🎮 GPUs · ${(i.gpus||[]).length}</h2>
${gpus}
<div style="height:24px"></div>
<h2 style="font-size:18px;margin-bottom:12px">🐳 Docker · ${(i.docker||[]).length} containers</h2>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:6px;margin-bottom:28px">${docker}</div>
<h2 style="font-size:18px;margin-bottom:12px">🌐 Subdomains · ${Object.keys(i.subdomains||{}).length}</h2>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:6px">${subdoms}</div>
</div>`;
}
async function renderAllPages(){
// DOCTRINE-156: try enriched API first (thumbs + title + desc), fallback to TREE.all_pages
const main = document.getElementById('wtp-main');
main.innerHTML = '<div style="padding:40px;color:var(--wtp-muted)">📂 Chargement des pages enrichies…</div>';
let useEnriched = false;
let enrichedCats = null;
let enrichedStats = null;
try {
const r = await fetch('/api/wtp-pages-enriched.php', {cache: 'no-cache'});
if (r.ok) {
const d = await r.json();
if (d && d.ok && d.categories) {
enrichedCats = d.categories;
enrichedStats = d.stats;
useEnriched = true;
}
}
} catch(e) { /* fallback below */ }
if (useEnriched) {
// NEW: premium cards with thumb + title + description
const catHtml = Object.entries(enrichedCats).filter(([c, pages]) => pages.length > 0)
.sort((a,b)=>b[1].length-a[1].length).map(([cat, pages]) => {
const items = pages.slice(0, 60).map(p => `
<a href="${p.url}" style="display:block;padding:0;background:var(--wtp-panel);border:1px solid var(--wtp-border);border-radius:8px;text-decoration:none;color:var(--wtp-text);transition:.2s;overflow:hidden"
onmouseover="this.style.borderColor='var(--wtp-ac)';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='var(--wtp-border)';this.style.transform='translateY(0)'">
${p.thumb_url ? `<img src="${p.thumb_url}" loading="lazy" style="width:100%;height:120px;object-fit:cover;display:block;background:#0a0e17" onerror="this.style.display='none'">` : `<div style="height:120px;background:linear-gradient(135deg,rgba(99,102,241,.08),rgba(34,197,94,.04));display:flex;align-items:center;justify-content:center;color:var(--wtp-muted);font-size:22px">📄</div>`}
<div style="padding:10px 12px">
<div style="font-weight:600;font-size:13px;margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">${p.title || p.name.replace(/\.html$/,'')}</div>
${p.description ? `<div style="color:var(--wtp-muted);font-size:11px;line-height:1.4;height:30px;overflow:hidden">${p.description.substring(0,120)}</div>` : `<div style="color:var(--wtp-muted);font-size:11px;line-height:1.4;height:30px">${p.name.replace(/\.html$/,'').replace(/[-_]/g,' ')}</div>`}
<div style="margin-top:6px;font-size:10px;color:var(--wtp-muted);font-family:monospace;display:flex;justify-content:space-between">
<span>${p.size_kb}k · ${p.last_modified||''}</span>
${p.is_orphan?'<span style="color:#f59e0b">⚠ orphan</span>':''}
</div>
</div>
</a>`).join('');
return `<div style="margin-bottom:32px">
<h3 style="font-size:16px;margin-bottom:12px;display:flex;justify-content:space-between;align-items:center">
<span>${cat}</span><span style="color:var(--wtp-muted);font-size:12px;font-weight:400">${pages.length} pages</span>
</h3>
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:12px">${items}</div>
${pages.length>60?`<div style="color:var(--wtp-muted);font-size:11px;margin-top:8px">+${pages.length-60} autres</div>`:''}
</div>`;
}).join('');
main.innerHTML = `
<div style="padding:24px">
<h1 style="font-size:28px;margin-bottom:6px">📂 Toutes les pages · ${enrichedStats.total_pages} <span style="font-size:12px;color:var(--wtp-muted);font-weight:400;margin-left:12px">🖼 ${enrichedStats.with_thumb} thumbs (${enrichedStats.thumb_coverage_pct}%) · 📝 ${enrichedStats.with_meta} meta</span></h1>
<div style="color:var(--wtp-muted);margin-bottom:20px">${enrichedStats.categories_populated} catégories · toutes accessibles depuis WTP · doctrine 155 enriched</div>
<div style="margin-bottom:18px">
<input type="text" id="pg-search" placeholder="Recherche page..." oninput="_pgSearch(this.value)" style="width:100%;padding:12px 16px;background:var(--wtp-panel);border:1px solid var(--wtp-border);color:var(--wtp-text);border-radius:6px;font-size:13px;outline:none">
</div>
<div id="pg-content">${catHtml}</div>
</div>`;
return;
}
// FALLBACK: original behavior preserved (TREE.all_pages)
const ap = TREE.all_pages || {};
const cats = ap.pages_by_category || {};
const catHtml = Object.entries(cats).sort((a,b)=>b[1].length-a[1].length).map(([cat, pages]) => {
const items = pages.slice(0, 50).map(p => `
<a href="${p.url}" style="display:flex;justify-content:space-between;padding:7px 11px;background:var(--wtp-panel);border:1px solid var(--wtp-border);border-radius:5px;text-decoration:none;color:var(--wtp-text);font-size:12px;transition:.15s"
onmouseover="this.style.borderColor='var(--wtp-ac)'" onmouseout="this.style.borderColor='var(--wtp-border)'">
<span style="font-weight:500">${p.name.replace(/\.html$/,'').replace(/[-_]/g,' ')}</span>
<span style="color:var(--wtp-muted);font-family:monospace;font-size:10px">${p.size_kb}k${p.is_orphan?' ·⚠':''}</span>
</a>`).join('');
return `<div style="margin-bottom:24px">
<h3 style="font-size:15px;margin-bottom:10px;display:flex;justify-content:space-between">
<span>${cat}</span><span style="color:var(--wtp-muted);font-size:11px;font-weight:400">${pages.length} pages</span>
</h3>
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:4px">${items}</div>
${pages.length>50?`<div style="color:var(--wtp-muted);font-size:11px;margin-top:6px">+${pages.length-50} autres</div>`:''}
</div>`;
}).join('');
main.innerHTML = `
<div style="padding:24px">
<h1 style="font-size:28px;margin-bottom:6px">📂 Toutes les pages · ${ap.total}</h1>
<div style="color:var(--wtp-muted);margin-bottom:20px">${ap.orphans} orphelines identifiées · toutes accessibles depuis WTP</div>
<div style="margin-bottom:18px">
<input type="text" id="pg-search" placeholder="Recherche page..." oninput="_pgSearch(this.value)" style="width:100%;padding:12px 16px;background:var(--wtp-panel);border:1px solid var(--wtp-border);color:var(--wtp-text);border-radius:6px;font-size:13px;outline:none">
</div>
<div id="pg-content">${catHtml}</div>
</div>`;
}
window._pgSearch = function(q){
q = (q||'').toLowerCase();
document.querySelectorAll('#pg-content a').forEach(a => {
a.style.display = (!q || a.textContent.toLowerCase().includes(q)) ? '' : 'none';
});
};
function renderAllApis(){
const main = document.getElementById('wtp-main');
const a = TREE.apis || {};
main.innerHTML = `
<div style="padding:24px">
<h1 style="font-size:28px;margin-bottom:6px">🔌 Toutes les APIs · ${a.total}</h1>
<div style="color:var(--wtp-muted);margin-bottom:24px">Endpoints PHP dans /api/</div>
<h2 style="font-size:16px;margin-bottom:10px">Top WEVIA APIs (${(a.top_wevia||[]).length})</h2>
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:6px">
${(a.top_wevia||[]).map(api => `
<a href="/api/${api}" target="_blank" style="padding:8px 12px;background:var(--wtp-panel);border:1px solid var(--wtp-border);border-radius:5px;text-decoration:none;color:var(--wtp-text);font-size:12px;font-family:monospace">
${api}
</a>`).join('')}
</div>
</div>`;
}
function renderMultiagent(){
const main = document.getElementById('wtp-main');
const modes = TREE.multiagent_modes || [];
main.innerHTML = `
<div style="padding:24px">
<h1 style="font-size:28px;margin-bottom:6px">🤖 Multi-Agent Modes</h1>
<div style="color:var(--wtp-muted);margin-bottom:24px">3 modes coexistent via WEVIA Master chat · /wevia-master.html</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:14px">
${modes.map((m, i) => `
<div style="background:var(--wtp-panel2);padding:20px;border-radius:10px;border:1px solid var(--wtp-border);border-left:4px solid ${['#6366f1','#22c55e','#f59e0b'][i]||'#6366f1'}">
<div style="font-size:17px;font-weight:800;margin-bottom:6px">${m.mode}</div>
<div style="font-size:22px;font-weight:700;margin:8px 0">${m.agents || m.agents_target} agents</div>
<div style="font-size:12px;color:var(--wtp-muted);margin-bottom:8px">Latency: <span style="color:var(--wtp-ac);font-family:monospace">${m.latency_ms}ms</span></div>
<div style="font-size:12px;margin-bottom:10px">${m.use}</div>
<div style="font-size:10px;color:var(--wtp-muted);font-family:monospace;padding:6px 10px;background:var(--wtp-panel);border-radius:4px">${m.trigger}</div>
</div>`).join('')}
</div>
<div style="margin-top:24px;padding:18px;background:var(--wtp-panel2);border-radius:8px">
<strong>💬 Tester en live:</strong> ouvre <a href="/wevia-master.html" style="color:var(--wtp-ac)">/wevia-master.html</a> et tape "agis en multiagent"
</div>
</div>`;
}
function renderTruth(){
const main = document.getElementById('wtp-main');
const t = TREE.truth_registry || {};
main.innerHTML = `
<div style="padding:24px">
<h1 style="font-size:28px;margin-bottom:6px">🔒 Truth Registry · source unique</h1>
<div style="color:var(--wtp-muted);margin-bottom:24px">Built: <span style="font-family:monospace">${t.built_at||'?'}</span> · rebuild cron /30min</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px;margin-bottom:24px">
${[['Agents',t.agents,'#d4af37'],['Intents',t.intents,'#22c55e'],['Skills',t.skills,'#6366f1'],['Brains',t.brains,'#a855f7'],['Doctrines',t.doctrines,'#ef4444'],['Dashboards',t.dashboards,'#22d3ee'],['Providers',t.providers,'#f59e0b'],['Qdrant Cols',t.qdrant_cols,'#ec4899'],['Qdrant Points',t.qdrant_points,'#10b981'],['Autonomy',(t.autonomy_score||0)+'/100 '+(t.autonomy_level||''),'#d4af37']].map(([l,v,c])=>`
<div style="background:var(--wtp-panel2);padding:16px;border-radius:8px;border-top:2px solid ${c}">
<div style="font-size:10px;color:var(--wtp-muted);text-transform:uppercase;letter-spacing:1px;margin-bottom:6px">${l}</div>
<div style="font-size:24px;font-weight:800;color:${c}">${typeof v==='number' ? v.toLocaleString('fr-FR') : v}</div>
</div>`).join('')}
</div>
<div style="display:flex;gap:10px;flex-wrap:wrap">
<a href="/api/wevia-truth-registry.json" target="_blank" style="padding:10px 16px;background:var(--wtp-panel);border:1px solid var(--wtp-border);border-radius:6px;text-decoration:none;color:var(--wtp-text);font-size:13px">📄 Truth Registry JSON (560 KB)</a>
<a href="/api/source-of-truth.json" target="_blank" style="padding:10px 16px;background:var(--wtp-panel);border:1px solid var(--wtp-border);border-radius:6px;text-decoration:none;color:var(--wtp-text);font-size:13px">📋 Source of Truth (snapshot)</a>
<a href="/api/wevia.php?q=status&format=text" target="_blank" style="padding:10px 16px;background:var(--wtp-panel);border:1px solid var(--wtp-border);border-radius:6px;text-decoration:none;color:var(--wtp-text);font-size:13px">🔍 NL Query API</a>
</div>
</div>`;
}
function renderHome(){
if (!TREE) return;
const kpis = TREE.kpis || {};
const html = `
<div class="wtp-header">
<div>
<h1><div class="module-icon">🏠</div>WEVAL Technology Platform</h1>
<div class="wtp-header-desc">Portail unifié tous serveurs · tous modules · toutes capacités · all-in-one ERP</div>
</div>
<a href="/business-kpi-dashboard.php" target="_blank" class="wtp-refresh" style="background:linear-gradient(135deg,#48bb78,#b794f6);color:#fff;padding:6px 14px;border-radius:6px;text-decoration:none;font-weight:600;font-size:12px;margin-right:8px;display:inline-block">💼 V83 Business KPI (SaaS)</a><a href="/products-kpi-dashboard.php" target="_blank" class="wtp-refresh" style="background:linear-gradient(135deg,#6c9ef8,#8b5cf6);color:#fff;padding:6px 14px;border-radius:6px;text-decoration:none;font-weight:600;font-size:12px;margin-right:8px;display:inline-block">🎯 V80 Products KPI Drill-down</a>
<button class="wtp-refresh" onclick="loadTree()">↻ Refresh</button>
</div>
<!-- VISUAL-MGMT-PREMIUM-V1 doctrine 60 + L6S TOC -->
<div class="vm-grid" id="vm-dashboard">
<!-- Row 1: 4 Gauges (coverage, ethica, agents, sovereign) -->
<div class="vm-card vm-col-3">
<div class="vm-card-head"><div class="vm-card-title">🎯 Coverage Acquis</div><div class="vm-live">live</div></div>
<div class="vm-gauge" id="vm-gauge-cov"></div>
<div class="vm-gauge-label">98.29% écosystème capitalisé</div>
</div>
<div class="vm-card vm-col-3">
<div class="vm-card-head"><div class="vm-card-title">🧬 HCPs Maghreb</div><div class="vm-live">live</div></div>
<div class="vm-gauge" id="vm-gauge-ethica"></div>
<div class="vm-gauge-label">DZ · MA · TN · INTL</div>
</div>
<div class="vm-card vm-col-3">
<div class="vm-card-head"><div class="vm-card-title">🤖 Agents Fleet</div><div class="vm-card-badge" id="vm-agents-b">active</div></div>
<div class="vm-gauge" id="vm-gauge-agents"></div>
<div class="vm-gauge-label">sur ${fmt(kpis.skills_total)} skills indexed</div>
</div>
<div class="vm-card vm-col-3">
<div class="vm-card-head"><div class="vm-card-title">⚡ Sovereign IA</div><div class="vm-card-badge" id="vm-sov-b">0€</div></div>
<div class="vm-gauge" id="vm-gauge-sovereign"></div>
<div class="vm-gauge-label">cascade LLM providers</div>
</div>
<!-- Row 2: Andon L6S + L99 + NonReg + DPMO donut + flow -->
<div class="vm-card vm-col-3">
<div class="vm-card-head"><div class="vm-card-title">🚦 Andon Lean 6 Sigma</div><div class="vm-card-badge" id="vm-andon-b">ON TARGET</div></div>
<div class="vm-andon" id="vm-andon"></div>
</div>
<div class="vm-card vm-col-3">
<div class="vm-card-head"><div class="vm-card-title">🧪 NonReg · L99 · L6S</div><div class="vm-live">live</div></div>
<div class="vm-score">
<div class="vm-score-big ok" id="vm-nonreg-score">—</div>
<div class="vm-score-sub" id="vm-nonreg-sub">tests passés · dpmo 0 · 18 cycles stable</div>
</div>
<div class="vm-bars" id="vm-nonreg-bars"></div>
</div>
<div class="vm-card vm-col-3">
<div class="vm-card-head"><div class="vm-card-title">📊 DPMO (défauts/million)</div><div class="vm-card-badge">6σ target</div></div>
<div class="vm-donut-wrap">
<div class="vm-donut" id="vm-dpmo-donut"></div>
<div class="vm-donut-list" id="vm-dpmo-list"></div>
</div>
</div>
<div class="vm-card vm-col-3">
<div class="vm-card-head"><div class="vm-card-title">🔄 Value Stream Flow</div><div class="vm-card-badge">DMAIC</div></div>
<div class="vm-flow" id="vm-flow">
<div class="vm-flow-step done"><span class="num">D</span>Define</div>
<div class="vm-flow-step done"><span class="num">M</span>Measure</div>
<div class="vm-flow-step done"><span class="num">A</span>Analyze</div>
<div class="vm-flow-step work"><span class="num">I</span>Improve</div>
<div class="vm-flow-step"><span class="num">C</span>Control</div>
<div class="vm-flow-step"><span class="num">∞</span>Kaizen</div>
</div>
<div class="vm-bars" style="margin-top:12px" id="vm-toc-bars"></div>
</div>
<!-- Row 3: Heatmap écosystème + ACQUIS vs DORMANTS bars + sparkline -->
<div class="vm-card vm-col-6">
<div class="vm-card-head"><div class="vm-card-title">🔥 Heatmap écosystème — santé 144 composants</div><div class="vm-live">real-time</div></div>
<div class="vm-heat" id="vm-heat"></div>
<div class="vm-heat-legend">
<span style="background:#1f2436"></span>idle
<span style="background:rgba(16,185,129,.35)"></span>ok
<span style="background:rgba(16,185,129,1)"></span>hot
<span style="background:rgba(245,158,11,.6)"></span>warn
<span style="background:rgba(239,68,68,.8)"></span>fail
</div>
</div>
<div class="vm-card vm-col-6">
<div class="vm-card-head"><div class="vm-card-title">📈 ACQUIS LIVE vs À WIRER (dormants)</div><div class="vm-card-badge" id="vm-acq-b">—</div></div>
<div class="vm-bars" id="vm-acq-bars"></div>
<svg class="vm-spark" viewBox="0 0 400 54" preserveAspectRatio="none" style="margin-top:10px">
<defs>
<linearGradient id="grad-spark" x1="0" x2="1"><stop offset="0%" stop-color="#22d3ee"/><stop offset="100%" stop-color="#a855f7"/></linearGradient>
<linearGradient id="grad-spark-area" x1="0" x2="0" y1="0" y2="1"><stop offset="0%" stop-color="#a855f7" stop-opacity=".5"/><stop offset="100%" stop-color="#22d3ee" stop-opacity="0"/></linearGradient>
</defs>
<path class="area" id="vm-spark-area" d=""/>
<path class="line" id="vm-spark-line" d=""/>
</svg>
</div>
</div>
<!-- Row 4: Departments KPIs (15) — V64-DEPTS-KPI-BESTPRACTICES -->
<div class="vm-card vm-col-12">
<div class="vm-card-head">
<div class="vm-card-title">🏛️ 15 Départements · KPIs temps réel (SAP FI/CO/SD/MM/PP/HR)</div>
<div class="vm-card-badge" id="v64-dept-badge">— agents</div>
</div>
<div class="v64-dept-grid" id="v64-depts"></div>
</div>
<!-- Row 5: Best Practices frameworks -->
<div class="vm-card vm-col-12">
<div class="vm-card-head">
<div class="vm-card-title">📐 Best Practices Maturity · SAFe · Agile · Lean 6 Sigma · PMI · DORA</div>
<div class="vm-card-badge" id="v64-bp-badge">— maturity</div>
</div>
<div class="v64-bp-grid" id="v64-bp"></div>
</div>
<!-- Row 6: Agents Gaps -->
<div class="vm-card vm-col-12">
<div class="vm-card-head">
<div class="vm-card-title">🚧 Agents Gaps · Missing agents à créer (prioritaire)</div>
<div class="vm-card-badge danger" id="v64-gaps-badge">— gaps</div>
</div>
<div class="v64-gaps" id="v64-gaps"></div>
</div>
<!-- Row 7: V65 ERP Gap-Fill OFFRE COMMERCIALE -->
<div class="vm-card vm-col-12" style="background:linear-gradient(135deg,rgba(20,184,166,0.10),rgba(168,85,247,0.08));border:1px solid rgba(20,184,166,0.25);position:relative;overflow:hidden">
<div class="vm-card-head">
<div class="vm-card-title">💼 Offre commerciale · ERP Gap-Fill Agents <span style="color:var(--text-3);font-weight:400;margin-left:6px">— vendable à nos clients Retail/Pharma/Banque/Industrie/Services/Conseil/Énergie</span></div>
<div class="vm-card-badge">V65 · 7.3M€ TAM</div>
</div>
<div style="display:grid;grid-template-columns:repeat(5,1fr);gap:12px;margin-bottom:14px">
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:22px;font-weight:800;color:#fca5a5">25</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Risques 5×5</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:22px;font-weight:800;color:#fbbf24">33</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">ERP Gaps</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:22px;font-weight:800;color:#a5b4fc">7</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Verticaux</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:22px;font-weight:800;color:#5eead4">149</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Agents pack</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:22px;font-weight:800;background:linear-gradient(135deg,#22d3ee,#a855f7);-webkit-background-clip:text;background-clip:text;color:transparent">7.3M€</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">TAM pipeline</div></div>
</div>
<div style="display:flex;gap:10px;flex-wrap:wrap;align-items:center">
<a href="/erp-gap-fill-offer.html" style="padding:9px 18px;background:linear-gradient(135deg,#6366f1,#a855f7);color:white;border-radius:8px;text-decoration:none;font-size:12.5px;font-weight:600">📑 Ouvrir offre complète</a>
<span style="font-size:11.5px;color:var(--text-2)">Services : Discovery 5K€ · POC 15-25K€ · Rollout 80-300K€ · Managed 30-80K€/an</span>
</div>
</div>
<!-- /V65-ERP-GAPFILL-OFFER -->
<!-- Row 8: V66 Pain Points Atlas All ERPs -->
<div class="vm-card vm-col-12" style="background:linear-gradient(135deg,rgba(234,179,8,0.08),rgba(168,85,247,0.06));border:1px solid rgba(234,179,8,0.3);position:relative;overflow:hidden">
<div class="vm-card-head">
<div class="vm-card-title">🗺️ Pain Points Atlas · All ERPs <span style="color:var(--text-3);font-weight:400;margin-left:6px">— SAP/Oracle/Sage/Odoo/D365/NetSuite/Workday/Salesforce/Infor/IFS/Epicor/Veeva/Temenos (25 ERPs)</span></div>
<div class="vm-card-badge" style="background:linear-gradient(135deg,#eab308,#f59e0b);color:#0b0d15">V66 · 17.36M€ savings/client</div>
</div>
<div style="display:grid;grid-template-columns:repeat(5,1fr);gap:12px;margin-bottom:14px">
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:22px;font-weight:800;color:#a5b4fc">25</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">ERPs couverts</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:22px;font-weight:800;color:#fca5a5">35</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Pain points</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:22px;font-weight:800;color:#5eead4">35</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Agents uniques</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:22px;font-weight:800;color:#fbbf24">496k€</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Avg savings/agent/an</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:22px;font-weight:800;background:linear-gradient(135deg,#eab308,#f59e0b);-webkit-background-clip:text;background-clip:text;color:transparent">17.36M€</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Max savings/client/an</div></div>
</div>
<div style="display:flex;gap:10px;flex-wrap:wrap;align-items:center">
<a href="/pain-points-atlas.html" style="padding:9px 18px;background:linear-gradient(135deg,#eab308,#f59e0b);color:#0b0d15;border-radius:8px;text-decoration:none;font-size:12.5px;font-weight:700">🗺️ Ouvrir Pain Points Atlas</a>
<a href="/infra-tour-2s-5c-blade.html" style="padding:9px 18px;background:linear-gradient(135deg,#06b6d4,#8b5cf6);color:#0b0d15;border-radius:8px;text-decoration:none;font-size:12.5px;font-weight:700">🗺️ Ouvrir Infra Tour 2S+5C+Blade</a>
<a href="/growth-engine-v2.html" style="padding:9px 18px;background:linear-gradient(135deg,#eab308,#f59e0b);color:#0b0d15;border-radius:8px;text-decoration:none;font-size:12.5px;font-weight:700">🗺️ Ouvrir Growth Engine v4</a>
<a href="/agent-roi-simulator.html" style="padding:9px 18px;background:linear-gradient(135deg,#14b8a6,#6366f1);color:white;border-radius:8px;text-decoration:none;font-size:12.5px;font-weight:700">🧮 ROI Simulator (V67)</a>
<a href="/erp-gap-fill-offer.html" style="padding:9px 18px;background:var(--bg-3);color:var(--text);border:1px solid var(--border);border-radius:8px;text-decoration:none;font-size:12.5px;font-weight:500">📑 Offre V65</a>
<span style="font-size:11.5px;color:var(--text-2)">🐕 Dogfood : WEVAL comble 35 gaps internes = 2.4M€ savings/an (preuve par l'exemple)</span>
</div>
</div>
<!-- /V66-ALL-ERPS-PAINPOINTS -->
<!-- Row 9: V69 DG Command Center -->
<div class="vm-card vm-col-12" style="background:linear-gradient(135deg,rgba(239,68,68,0.06),rgba(168,85,247,0.06));border:1px solid rgba(239,68,68,0.25);position:relative;overflow:hidden">
<div class="vm-card-head">
<div class="vm-card-title">🎖️ DG Command Center · Real-time <span style="color:var(--text-3);font-weight:400;margin-left:6px">— TOC · Conversion · Data · Marketing · CRM · Risk · Alertes</span></div>
<div class="vm-card-badge danger">V69 · 3 alertes critical</div>
</div>
<div style="display:grid;grid-template-columns:repeat(5,1fr);gap:12px;margin-bottom:14px">
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#fca5a5" id="dg-alerts">—</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Alertes DG</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#fbbf24" id="dg-toc">—</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">TOC Bottleneck</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#5eead4" id="dg-pipe">—</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Pipeline k€</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#a5b4fc" id="dg-opps">—</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Opps actives</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#fca5a5" id="dg-risks">—</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Risques critical</div></div>
</div>
<div style="display:flex;gap:10px;flex-wrap:wrap;align-items:center">
<a href="/dg-command-center.html" style="padding:9px 18px;background:linear-gradient(135deg,#ef4444,#a855f7);color:white;border-radius:8px;text-decoration:none;font-size:12.5px;font-weight:700">🎖️ Ouvrir DG Command Center</a>
<span style="font-size:11.5px;color:var(--text-2)">⏱ auto-refresh 20s · TOC Goldratt + Conversion funnel + CRM stages + 12 risques</span>
</div>
</div>
<!-- Row 10: V71 Intelligence & Growth Insights -->
<div class="vm-card vm-col-12" style="background:linear-gradient(135deg,rgba(99,102,241,0.08),rgba(234,179,8,0.06));border:1px solid rgba(99,102,241,0.28);position:relative">
<div class="vm-card-head">
<div class="vm-card-title">🌐 Intelligence &amp; Growth Insights (V71) <span style="color:var(--text-3);font-weight:400;margin-left:6px">— DarkScout + WEVL Predict + Agility + Leads + Opportunities</span></div>
<div class="vm-card-badge info">V71 · 8 comp · 13 innov · 36 bots</div>
</div>
<div style="display:grid;grid-template-columns:repeat(5,1fr);gap:12px;margin-bottom:14px">
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#fca5a5" id="v71-comp">8</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Compétiteurs</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#86efac" id="v71-innov">13</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Innovations</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#d4a7fa" id="v71-agil">12</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Agility Gap</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#7dd3fc" id="v71-chat">40/40</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Chatbots</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#fde047" id="v71-oppo">1.8M€</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Opportunities</div></div>
</div>
<div style="display:flex;gap:10px;flex-wrap:wrap;align-items:center">
<a href="/intelligence-growth.html" style="padding:9px 18px;background:linear-gradient(135deg,#6366f1,#eab308);color:white;border-radius:8px;text-decoration:none;font-size:12.5px;font-weight:700">🌐 Ouvrir Intelligence &amp; Growth</a>
<span style="font-size:11.5px;color:var(--text-2)">⏱ auto-refresh 30s · veille compétiteurs + innovations + leads + opportunités LinkedIn/Web</span>
</div>
</div>
<!-- /V71-INTELLIGENCE-GROWTH -->
<!-- /V69-DG-COMMAND-CENTER -->
<!-- Row 10: V70 Enterprise Complete + Integration Hub -->
<div class="vm-card vm-col-12" style="background:linear-gradient(135deg,rgba(234,179,8,0.08),rgba(6,182,212,0.06));border:1px solid rgba(234,179,8,0.3);position:relative;overflow:hidden">
<div class="vm-card-head">
<div class="vm-card-title">🏢 Enterprise Complete · All Depts · All KPIs · All Integrations <span style="color:var(--text-3);font-weight:400;margin-left:6px">— 20 départements · 169 KPIs · 61 connecteurs universels</span></div>
<div class="vm-card-badge" style="background:linear-gradient(135deg,#eab308,#f59e0b);color:#0b0d15">V70 · Universal</div>
</div>
<div style="display:grid;grid-template-columns:repeat(6,1fr);gap:10px;margin-bottom:14px">
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#5eead4">20</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Départements</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#fbbf24">169</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">KPIs Total</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#a5b4fc">61</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Intégrations</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#86efac">16</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">ERP supportés</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#7dd3fc">9</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Auth methods</div></div>
<div style="text-align:center;padding:10px;background:var(--bg-3);border-radius:8px"><div style="font-size:20px;font-weight:800;color:#fca5a5">10</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Protocoles</div></div>
</div>
<div style="display:flex;gap:10px;flex-wrap:wrap;align-items:center">
<a href="/enterprise-complete.html" style="padding:9px 18px;background:linear-gradient(135deg,#eab308,#06b6d4);color:#0b0d15;border-radius:8px;text-decoration:none;font-size:12.5px;font-weight:700">🏢 Ouvrir Enterprise Complete</a>
<span style="font-size:11.5px;color:var(--text-2)">🔌 Universal adapter: SAP · Oracle · Sage · Salesforce · Workday · Stripe · PostgreSQL · MongoDB · + scraping fallback</span>
</div>
</div>
<!-- /V70-ENTERPRISE-COMPLETE -->
<!-- Row 11: V85 Business KPI SaaS Premium -->
<div class="vm-card vm-col-12" style="background:linear-gradient(135deg,rgba(72,187,120,0.10),rgba(183,148,246,0.08),rgba(108,158,248,0.05));border:1px solid rgba(183,148,246,0.35);position:relative;overflow:hidden">
<div class="vm-card-head">
<div class="vm-card-title">💼 V85 Business KPI · SaaS Ready <span style="color:var(--text-3);font-weight:400;margin-left:6px">— Revenue · Customer · Growth · Predictive · SLA · Productivité</span></div>
<div class="vm-card-badge" style="background:linear-gradient(135deg,#48bb78,#b794f6,#6c9ef8);color:#fff">V85 · Premium</div>
</div>
<div style="display:grid;grid-template-columns:repeat(6,1fr);gap:12px;margin-bottom:16px">
<div style="text-align:center;padding:12px;background:var(--bg-3);border-radius:10px;border-left:3px solid #48bb78"><div style="font-size:22px;font-weight:800;color:#48bb78" id="v85-total-kpis">—</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Total KPIs</div></div>
<div style="text-align:center;padding:12px;background:var(--bg-3);border-radius:10px;border-left:3px solid #6c9ef8"><div style="font-size:22px;font-weight:800;color:#6c9ef8" id="v85-categories">—</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Categories</div></div>
<div style="text-align:center;padding:12px;background:var(--bg-3);border-radius:10px;border-left:3px solid #48bb78"><div style="font-size:22px;font-weight:800;color:#48bb78" id="v85-live">—</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Live on target</div></div>
<div style="text-align:center;padding:12px;background:var(--bg-3);border-radius:10px;border-left:3px solid #f6ad55"><div style="font-size:22px;font-weight:800;color:#f6ad55" id="v85-warn">—</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Below target</div></div>
<div style="text-align:center;padding:12px;background:var(--bg-3);border-radius:10px;border-left:3px solid #b794f6"><div style="font-size:22px;font-weight:800;color:#b794f6" id="v85-wire">—</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Wire needed</div></div>
<div style="text-align:center;padding:12px;background:var(--bg-3);border-radius:10px;border-left:3px solid #6c9ef8"><div style="font-size:22px;font-weight:800;color:#6c9ef8" id="v85-completeness">—</div><div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-top:3px">Data Completeness</div></div>
</div>
<div id="v85-categories-grid" style="display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:12px;margin-bottom:16px">
<div style="padding:16px;background:var(--bg-3);border-radius:10px;color:var(--text-3);text-align:center;grid-column:1/-1">Loading V85 business KPIs (7 categories × 8 KPIs = 56)...</div>
</div>
<div style="margin-bottom:14px">
<div style="font-size:12px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px;margin-bottom:8px">⚡ KPI Highlights (live data)</div>
<div id="v85-highlights" style="display:grid;grid-template-columns:repeat(5,1fr);gap:10px">
<div style="padding:12px;background:var(--bg-3);border-radius:8px;color:var(--text-3);grid-column:1/-1">Loading highlights...</div>
</div>
</div>
<div style="display:flex;gap:10px;flex-wrap:wrap;align-items:center">
<a href="/business-kpi-dashboard.php" target="_blank" style="padding:9px 18px;background:linear-gradient(135deg,#48bb78,#b794f6);color:#fff;border-radius:8px;text-decoration:none;font-size:12.5px;font-weight:700">💼 Business KPI Dashboard (Drill-down)</a>
<a href="/products-kpi-dashboard.php" target="_blank" style="padding:9px 18px;background:linear-gradient(135deg,#6c9ef8,#8b5cf6);color:#fff;border-radius:8px;text-decoration:none;font-size:12.5px;font-weight:700">🎯 V80 Products KPI Drill-down</a>
<span style="font-size:11.5px;color:var(--text-2)">🚀 SaaS-ready: Revenue · Customer · Growth · Predictive · SLA · Productivité</span>
</div>
</div>
<!-- /V85-BUSINESS-KPI-SAAS-PREMIUM -->
<!-- Row 12: V67-WEVIA-APPLE — Photos Scanner OSS Intelligence (Opus 19avr) -->
<section id="wevia-apple-section" style="margin:16px 12px;padding:20px 24px;border-radius:16px;background:linear-gradient(135deg,rgba(0,0,0,.35),rgba(30,30,50,.25));backdrop-filter:blur(10px);border:1px solid rgba(229,229,234,.18);box-shadow:0 6px 24px rgba(0,0,0,.28)">
<div style="display:flex;align-items:center;gap:14px;margin-bottom:12px">
<div style="width:44px;height:44px;background:linear-gradient(135deg,#000,#1d1d1f);border-radius:11px;display:grid;place-items:center;font-size:26px">🍎</div>
<div style="flex:1">
<div style="font-size:1.05rem;font-weight:700;letter-spacing:-.2px">WEVIA Apple — Photos Scanner OSS Intelligence</div>
<div style="font-size:.78rem;color:rgba(229,229,234,.7);margin-top:2px">Upload photo iPhone → OCR tesseract + Vision Gemini 2.5 → extract GitHub/OSS/Docker · iPhone Shortcuts ready</div>
</div>
<a href="/wevia-apple.html" style="padding:8px 14px;background:rgba(96,165,250,.15);border:1px solid rgba(96,165,250,.4);color:#60a5fa;border-radius:8px;text-decoration:none;font-size:.85rem;font-weight:600;white-space:nowrap">Ouvrir →</a>
</div>
<div id="wevia-apple-kpi" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:8px;margin-top:8px">
<div style="padding:10px 12px;background:rgba(96,165,250,.08);border:1px solid rgba(96,165,250,.25);border-radius:8px"><div style="font-size:.68rem;color:rgba(229,229,234,.6);text-transform:uppercase;letter-spacing:.6px">Photos</div><div id="wa-k-total" style="font-size:1.4rem;font-weight:700">—</div></div>
<div style="padding:10px 12px;background:rgba(251,191,36,.08);border:1px solid rgba(251,191,36,.25);border-radius:8px"><div style="font-size:.68rem;color:rgba(229,229,234,.6);text-transform:uppercase;letter-spacing:.6px">OSS trouvés</div><div id="wa-k-oss" style="font-size:1.4rem;font-weight:700;color:#fbbf24">—</div></div>
<div style="padding:10px 12px;background:rgba(34,197,94,.08);border:1px solid rgba(34,197,94,.25);border-radius:8px"><div style="font-size:.68rem;color:rgba(229,229,234,.6);text-transform:uppercase;letter-spacing:.6px">GitHub URLs</div><div id="wa-k-gh" style="font-size:1.4rem;font-weight:700;color:#22c55e">—</div></div>
<div style="padding:10px 12px;background:rgba(192,132,252,.08);border:1px solid rgba(192,132,252,.25);border-radius:8px"><div style="font-size:.68rem;color:rgba(229,229,234,.6);text-transform:uppercase;letter-spacing:.6px">Top</div><div id="wa-k-top" style="font-size:.95rem;font-weight:600;line-height:1.3;color:#c084fc">—</div></div>
</div>
<script>(function(){fetch('/api/wevia-apple-scan.php?action=stats').then(r=>r.json()).then(d=>{document.getElementById('wa-k-total').textContent=d.scans_total||0;document.getElementById('wa-k-oss').textContent=d.oss_total||0;document.getElementById('wa-k-gh').textContent=d.github_urls_total||0;var top=d.top_projects?Object.entries(d.top_projects)[0]:null;document.getElementById('wa-k-top').textContent=top?(top[0]+' ('+top[1]+')'):'—';}).catch(()=>{});})();<\/script>
</section>
<!-- /V67-WEVIA-APPLE -->
<!-- /VISUAL-MGMT-PREMIUM-V1 -->
<div class="wtp-section-title">15 modules ERP disponibles</div>
<div class="wtp-home-grid">
${Object.entries(TREE.modules).map(([id, mod]) => `
<div class="wtp-home-module" style="--mod-color:${mod.color}" onclick="navigateTo('${id}')">
<div class="wtp-home-icon">${mod.icon}</div>
<div class="wtp-home-label">${mod.label}</div>
<div class="wtp-home-tag">${mod.tagline}</div>
<div class="wtp-home-stat">
<div><span class="num">${(mod.submodules||[]).length}</span><span class="lbl">sub-modules</span></div>
<div><span class="num">${countAssets(mod)}</span><span class="lbl">assets</span></div>
</div>
</div>`).join('')}
</div>
<div class="wtp-section-title">Subdomains live</div>
<div class="wtp-kpis">
${Object.entries(TREE.subdomains||{}).map(([dom, name]) => `
<a href="https://${dom}/" target="_blank" class="wtp-kpi" style="text-decoration:none;display:block">
<div class="wtp-kpi-label">${name}</div>
<div style="font-size:12px;color:var(--text-1);margin-top:4px;font-family:'JetBrains Mono',monospace;word-break:break-all">${dom}</div>
</a>`).join('')}
</div>
<div class="wtp-section-title">Docker containers (${TREE.docker.length})</div>
<div class="wtp-tiles">
${TREE.docker.map(d => `
<div class="wtp-tile" style="--tile-color:#06b6d4">
<div class="wtp-tile-head">
<div class="wtp-tile-title">${d.name}</div>
<div class="wtp-tile-badge live">● running</div>
</div>
<div class="wtp-tile-desc" style="font-family:'JetBrains Mono',monospace;font-size:10.5px">${d.status}</div>
</div>`).join('')}
</div>`;
document.getElementById('wtp-main').innerHTML = html;
}
function countAssets(mod){
let n = 0;
(mod.submodules||[]).forEach(s => {
n += (s.pages||[]).length + (s.apis||[]).length + (s.scripts||[]).length;
});
return n;
}
function renderModule(modId){
const mod = TREE.modules[modId];
if (!mod) { document.getElementById('wtp-main').innerHTML = '<div class="wtp-loading">Module introuvable</div>'; return; }
const html = `
<div class="wtp-header">
<div>
<h1><div class="module-icon" style="color:${mod.color}">${mod.icon}</div>${mod.label}</h1>
<div class="wtp-header-desc">${mod.tagline}</div>
</div>
<button class="wtp-refresh" onclick="loadTree()">↻ Refresh</button>
</div>
<div class="wtp-section-title">${(mod.submodules||[]).length} sous-modules</div>
<div class="wtp-tiles">
${(mod.submodules||[]).map(sub => renderTile(sub, mod.color)).join('')}
</div>`;
document.getElementById('wtp-main').innerHTML = html;
}
function renderTile(sub, color){
const badge = sub.status === 'dormant' ? '<div class="wtp-tile-badge dormant">● dormant</div>'
: sub.status === 'live' ? '<div class="wtp-tile-badge live">● live</div>' : '';
const desc = sub.desc ? `<div class="wtp-tile-desc">${sub.desc}</div>` : '';
const pages = (sub.pages||[]).map(p => {
const label = p.replace(/^https?:\/\/[^/]+\//,'').replace(/\.html$/,'').substring(0,28);
const href = p.startsWith('http') ? p : '/' + p;
return `<a href="${href}" target="_blank" class="wtp-pill page" onclick="event.stopPropagation()">📄 ${label}</a>`;
}).join(' ');
const apis = (sub.apis||[]).map(a => {
const label = a.replace(/^https?:\/\/[^/]+/,'').substring(0,28) || a.substring(0,28);
return `<a href="${a}" target="_blank" class="wtp-pill api" onclick="event.stopPropagation()">⚡ ${label}</a>`;
}).join(' ');
const scripts = (sub.scripts||[]).slice(0,4).map(s => `<span class="wtp-pill script">🔧 ${s}</span>`).join(' ');
const moreScripts = (sub.scripts||[]).length > 4 ? `<span class="wtp-pill script">+${sub.scripts.length-4} scripts</span>` : '';
const docker = sub.docker ? `<span class="wtp-pill docker">🐳 ${sub.docker}</span>` : '';
const path = sub.path ? `<span class="wtp-pill path">📁 ${sub.path}</span>` : '';
const url = sub.url ? `<a href="${sub.url}" target="_blank" class="wtp-pill" onclick="event.stopPropagation()">🌐 ${sub.url.substring(0,35)}</a>` : '';
const stakeholders = (sub.stakeholders||[]).length ? `<div class="wtp-tile-meta" style="margin-top:6px"><span class="wtp-pill">👤 ${sub.stakeholders.join(', ')}</span></div>` : '';
const note = sub.note ? `<div style="font-size:10.5px;color:var(--warning);margin-top:6px;font-style:italic">⚠ ${sub.note}</div>` : '';
const firstUrl = (sub.pages||[])[0] || (sub.apis||[])[0] || sub.url || '#';
return `<div class="wtp-tile" style="--tile-color:${color}" onclick="openUrl('${firstUrl}')">
<div class="wtp-tile-head">
<div class="wtp-tile-title">${sub.label}</div>
${badge}
</div>
${desc}
<div class="wtp-tile-meta">${pages}${apis}${scripts}${moreScripts}${docker}${path}${url}</div>
${stakeholders}
${note}
</div>`;
}
function openUrl(u){
if (u.startsWith('http')) window.open(u, '_blank');
else window.location.href = u;
}
function renderStatusBar(){
const k = TREE.kpis || {};
const setT = (id, v) => { const e=document.getElementById(id); if(e) e.textContent=v; };
setT('st-docker', (k.docker_running||''));
setT('st-prov', (k.sovereign_providers||'')+'/13');
setT('st-qdrant',(k.qdrant_collections||''));
setT('st-nr', (k.nonreg_pass||'')+'/'+(k.nonreg_total||''));
setT('st-hcp', fmt(k.ethica_hcps));
setT('st-ver', TREE.version || 'v2.0');
// Time
const updT = () => document.getElementById('st-time').textContent = new Date().toLocaleTimeString('fr-FR');
updT(); setInterval(updT, 1000);
}
function fmt(n){ if (n==null) return ''; return Number(n).toLocaleString('fr-FR'); }
// Search (fuzzy)
const searchInput = document.getElementById('wtp-search-input');
const searchResults = document.getElementById('wtp-search-results');
searchInput.addEventListener('input', debounce((e) => {
const q = e.target.value.toLowerCase().trim();
if (q.length < 2) { searchResults.classList.remove('show'); return; }
const hits = [];
Object.entries(TREE.modules).forEach(([modId, mod]) => {
(mod.submodules||[]).forEach(sub => {
const hay = [sub.label, sub.desc||'', ...(sub.pages||[]), ...(sub.apis||[]), ...(sub.scripts||[])].join(' ').toLowerCase();
if (hay.includes(q)) hits.push({modId, mod, sub});
});
});
const html = hits.slice(0, 20).map(h => `
<div class="wtp-search-result" onclick="navigateTo('${h.modId}');document.getElementById('wtp-search-results').classList.remove('show');document.getElementById('wtp-search-input').value=''">
<div class="title">${highlight(h.sub.label, q)}</div>
<div class="module">${h.mod.icon} ${h.mod.label}</div>
</div>`).join('');
searchResults.innerHTML = html || '<div class="wtp-search-result"><div class="title" style="color:var(--text-3)">Aucun résultat</div></div>';
searchResults.classList.add('show');
}, 200));
searchInput.addEventListener('blur', () => setTimeout(() => searchResults.classList.remove('show'), 200));
function highlight(txt, q){ return txt.replace(new RegExp('('+escapeReg(q)+')','ig'), '<mark>$1</mark>'); }
function escapeReg(s){ return s.replace(/[.*+?^${}()|[\]\\]/g,'\\$&'); }
function debounce(fn, ms){ let t; return (...a) => { clearTimeout(t); t=setTimeout(()=>fn(...a), ms); }; }
function showNotifications(){ alert('Notifications: NonReg 153/153 OK · Guardian watchdog active · 0 bans CrowdSec'); }
loadTree();
setInterval(loadTree, 60000); // refresh every 60s
// ===== VISUAL-MGMT-PREMIUM-V1 (doctrine 60) =====
async function vmUpdate(){
if (!document.getElementById('vm-dashboard')) return;
let v63 = null;
try { const r = await fetch('/api/wevia-v63-acquired-enriched.php?action=full&t='+Date.now()); v63 = await r.json(); } catch(e){}
const s = v63 ? v63.summary : {};
const l6s = v63 ? v63.lean6sigma : {};
const k = (TREE && TREE.kpis) || {};
// Gauges — Coverage
gaugeSVG('vm-gauge-cov', s.coverage_ratio_pct||0, '%', '#14b8a6', '#a855f7');
// Ethica
const ethicaPct = k.ethica_hcps ? Math.min(100, (k.ethica_hcps/150000*100)) : 0;
gaugeSVG('vm-gauge-ethica', ethicaPct, 'K', '#f59e0b', '#ef4444', k.ethica_hcps ? (k.ethica_hcps/1000).toFixed(0) : '?');
// Agents
const agPct = k.agents_total && k.skills_total ? Math.min(100, (k.agents_total/k.skills_total*100)) : 0;
gaugeSVG('vm-gauge-agents', agPct, '%', '#6366f1', '#a855f7', k.agents_total||'?');
// Sovereign
gaugeSVG('vm-gauge-sovereign', (k.sovereign_providers||0)/13*100, '/13', '#22d3ee', '#a855f7', k.sovereign_providers||0);
// Andon L6S
const andon = document.getElementById('vm-andon');
const status = l6s.status || 'UNKNOWN';
const lights = [
{color:'green', on: status === 'ON TARGET', label:'GO'},
{color:'yellow', on: /WARN|CAUTION/i.test(status), label:'WARN'},
{color:'red', on: /FAIL|CRITICAL|OFF/i.test(status), label:'STOP'}
];
andon.innerHTML = lights.map(l => `<div><div class="vm-light ${l.on?'on':'off'} ${l.color}"></div><div class="vm-light-label">${l.label}</div></div>`).join('');
const andonB = document.getElementById('vm-andon-b');
andonB.textContent = status;
andonB.className = 'vm-card-badge' + (status==='ON TARGET'?'':(status.includes('WARN')?' warn':' danger'));
// NonReg score
const nrPass = l6s.pass || k.nonreg_pass || 0;
const nrTotal = l6s.pass + (l6s.fail||0) || k.nonreg_total || 0;
const nrScore = l6s.score_l99 || (nrTotal ? Math.round(nrPass/nrTotal*100) : 0);
const nrEl = document.getElementById('vm-nonreg-score');
nrEl.textContent = nrPass + '/' + nrTotal;
nrEl.className = 'vm-score-big ' + (nrScore>=95?'ok':(nrScore>=80?'warn':'danger'));
document.getElementById('vm-nonreg-sub').textContent = nrScore + '% · DPMO ' + (l6s.dpmo||0) + ' · ' + (l6s.cycles_stable_v42_v63||0) + ' cycles stable';
const nrBars = [
{lbl:'NonReg', v:nrPass, max:nrTotal, cls:'' },
{lbl:'L99', v:l6s.pass||0, max:(l6s.pass||0)+(l6s.fail||0)||1, cls:'' },
{lbl:'APIs', v:s.total_apis_active||0, max:12, cls:'' },
{lbl:'Intents', v:s.total_intents_wired||0, max:100, cls:'' }
];
document.getElementById('vm-nonreg-bars').innerHTML = nrBars.map(b => {
const pct = b.max ? Math.min(100, b.v/b.max*100) : 0;
return `<div class="vm-bar-row"><div class="vm-bar-label">${b.lbl}</div><div class="vm-bar-track"><div class="vm-bar-fill ${b.cls}" style="width:0%" data-pct="${pct}"></div></div><div class="vm-bar-count">${b.v}/${b.max}</div></div>`;
}).join('');
setTimeout(()=>{ document.querySelectorAll('#vm-nonreg-bars .vm-bar-fill').forEach(el=>{ el.style.width = el.dataset.pct+'%'; }); }, 60);
// DPMO donut
const dpmo = l6s.dpmo || 0;
const sigmaLevel = dpmo <= 3.4 ? 6 : dpmo <= 233 ? 5 : dpmo <= 6210 ? 4 : 3;
const dpmoPct = Math.min(100, Math.max(0, 100 - (dpmo/10000*100)));
document.getElementById('vm-dpmo-donut').innerHTML = donutSVG(dpmoPct, sigmaLevel+'σ', 'sigma');
document.getElementById('vm-dpmo-list').innerHTML = `
<div><span><span class="dot" style="background:#10b981"></span>On target</span><span>${dpmo <= 3.4 ? '✓' : '—'}</span></div>
<div><span><span class="dot" style="background:#f59e0b"></span>Warn (>233)</span><span>${dpmo > 3.4 && dpmo <= 233 ? '!' : '—'}</span></div>
<div><span><span class="dot" style="background:#ef4444"></span>Fail (>6210)</span><span>${dpmo > 6210 ? '✗' : '—'}</span></div>
<div style="margin-top:4px;color:var(--text-2);font-size:10px">target 3.4 DPMO</div>`;
// TOC bars (bottleneck) — intents wired vs target
const tocBars = [
{lbl:'Intents', v:s.total_intents_wired||0, max:100},
{lbl:'Skills OSS', v:s.total_skills_oss||0, max:5500},
{lbl:'Vectors', v:s.total_vectors_rag||0, max:20000},
{lbl:'Doctrines', v:s.total_doctrines||0, max:77}
];
document.getElementById('vm-toc-bars').innerHTML = tocBars.map(b => {
const pct = b.max ? Math.min(100, b.v/b.max*100) : 0;
return `<div class="vm-bar-row"><div class="vm-bar-label">${b.lbl}</div><div class="vm-bar-track"><div class="vm-bar-fill" style="width:0%" data-pct="${pct}"></div></div><div class="vm-bar-count">${fmt(b.v)}</div></div>`;
}).join('');
setTimeout(()=>{ document.querySelectorAll('#vm-toc-bars .vm-bar-fill').forEach(el=>{ el.style.width = el.dataset.pct+'%'; }); }, 60);
// V96.8 Opus 19avr HONEST heatmap — 144 REAL named components (doctrine 4 honnêteté)
// Replaces V72 pseudo-random decoration (((seed+i*37)*2654435761)%100) which showed fake red/orange
// Each cell now = named component (11 infra + 20 dashboards + 25 ERPs + 60 pain points + 10 APIs + 18 skills)
// Hover = real name + status + details · Click = open real link
const heat = document.getElementById('vm-heat');
// Loading placeholder immediately
heat.innerHTML = Array.from({length:144},(_,i)=>'<div class="vm-heat-cell" data-v="0" data-idx="'+i+'" title="Loading ecosystem health…"></div>').join('');
// Fetch real health data
fetch('/api/wevia-ecosystem-health-144.php?t='+Date.now()).then(r=>r.json()).then(eh => {
if (!eh || !eh.cells) return;
const statusToV = {fail:'r', warn:'w', hot:'4', ok:'2', idle:'0'};
const statusIcon = {fail:'❌', warn:'⚠️', hot:'🔥', ok:'✅', idle:'⏸️'};
const newCells = eh.cells.map(c => {
const v = statusToV[c.status] || '0';
const ico = statusIcon[c.status] || '';
// Escape quotes in tooltip
const tip = (ico + ' ' + c.name + ' · ' + (c.status||'').toUpperCase() + ' · ' + (c.details||'') + ' · [' + (c.category||'') + ']').replace(/"/g, '&quot;').replace(/'/g, '&#39;');
return '<div class="vm-heat-cell" data-v="'+v+'" data-idx="'+c.idx+'" data-link="'+(c.link||'#')+'" data-status="'+c.status+'" title="'+tip+'"></div>';
}).join('');
heat.innerHTML = newCells;
// Make ALL cells clickable to their real component (doctrine 4)
heat.querySelectorAll('.vm-heat-cell').forEach(el => {
const link = el.dataset.link;
if (link && link !== '#') {
el.style.cursor = 'pointer';
el.addEventListener('click', () => window.open(link, '_blank'));
}
});
console.log('Heatmap V96.8 HONEST: 144 named components · stats:', eh.stats);
}).catch(e => console.error('[V96.8] ecosystem health fetch failed', e));
// Load actionable data for red/warn cells
Promise.all([
fetch('/api/wevia-v69-dg-command-center.php').then(r=>r.json()).catch(()=>null),
fetch('/api/wevia-v71-intelligence-growth.php').then(r=>r.json()).catch(()=>null)
]).then(([d69, d71]) => {
const actions = [];
if (d69) {
(d69.alerts_dg||[]).forEach(a => {
if (['critical','high'].includes(a.level)) actions.push({title:a.title, detail:a.detail, url:a.action_link||'/dg-command-center.html', icon:a.icon||'🚨'});
});
(d69.risks||[]).forEach(r => {
if (r.priority === 'critical') actions.push({title:r.title, detail:r.mitigation, url:'/dg-command-center.html', icon:'⚠️'});
});
/* V46 wire DG summary KPIs (doctrine #14 additif) */
if (d69.summary) {
var s69 = d69.summary;
var _setDg = function(id, v){ var el=document.getElementById(id); if(el && v!=null && v!=='') el.textContent=v; };
_setDg('dg-alerts', s69.alerts_dg_count);
_setDg('dg-toc', s69.toc_bottleneck_label);
_setDg('dg-pipe', (s69.pipeline_value_keur||0) + 'k€');
_setDg('dg-opps', s69.active_clients);
_setDg('dg-risks', s69.risks_critical);
}
}
if (d71) {
(d71.opportunities_watch?.opportunities||[]).forEach(o => {
if (['critical','high'].includes(o.urgency)) actions.push({title:o.signal, detail:o.action, url:'/sales-hub.html', icon:'🎯'});
});
}
// Make red cells clickable with real action
const redCells = document.querySelectorAll('.vm-heat-cell[data-v="r"]');
redCells.forEach((el, i) => {
const act = actions[i % Math.max(actions.length, 1)];
if (act) {
el.style.cursor = 'pointer';
el.title = act.icon + ' ' + act.title + ' · ' + (act.detail||'').substring(0,100) + ' (click pour action)';
el.onclick = () => window.open(act.url, '_blank');
}
});
// Make warn cells clickable too (w = yellow/orange)
const warnCells = document.querySelectorAll('.vm-heat-cell[data-v="w"]');
const warnActions = [];
if (d69) (d69.alerts_dg||[]).forEach(a => { if (a.level === 'medium') warnActions.push({title:a.title, detail:a.detail, url:a.action_link||'/dg-command-center.html', icon:a.icon||'⚠️'}); });
warnCells.forEach((el, i) => {
const act = warnActions[i % Math.max(warnActions.length, 1)];
if (act) {
el.style.cursor = 'pointer';
el.title = act.icon + ' ' + act.title + ' · ' + (act.detail||'').substring(0,100);
el.onclick = () => window.open(act.url, '_blank');
}
});
console.log('Heatmap actionable: ' + actions.length + ' red actions, ' + warnActions.length + ' warn');
});
// ACQUIS vs DORMANTS bars
const acqB = document.getElementById('vm-acq-b');
acqB.textContent = (s.coverage_ratio_pct||0) + '% coverage';
// V96.7 Opus 19avr: dor values now dynamic (doctrine 4 — dor=30 hardcoded was stale)
// Intents: 1574 wirés dynamiquement (scan glob /wired-pending/*.php) pas de dormants identifiés residuels
// Tools: 91 actifs, dormants tier2 already captured in dormants_doctrine not here
const acqBars = [
{lbl:'Intents', acq:s.total_intents_wired||0, dor:0}, // V96.7: real count 1574, 0 dormants (all intent files = wired)
{lbl:'Skills', acq:s.total_skills_oss||0, dor:Math.max(0, 5500 - (s.total_skills_oss||0))},
{lbl:'Tools', acq:s.total_tools_oss_dirs||0, dor:0}, // V96.7: 91 actifs, dormants dans dormants_doctrine scope
{lbl:'Doctrines', acq:s.total_doctrines||0, dor:Math.max(0, 77 - (s.total_doctrines||0))},
{lbl:'RAG vec', acq:Math.round((s.total_vectors_rag||0)/100)/10, dor:0, unit:'k'}
];
const maxTot = Math.max(...acqBars.map(b => b.acq + b.dor), 1);
document.getElementById('vm-acq-bars').innerHTML = acqBars.map(b => {
const acqPct = (b.acq / maxTot) * 100;
const dorPct = (b.dor / maxTot) * 100;
return `<div class="vm-bar-row"><div class="vm-bar-label">${b.lbl}</div>
<div class="vm-bar-track" style="position:relative">
<div class="vm-bar-fill" style="width:0%" data-pct="${acqPct}"></div>
<div class="vm-bar-fill warn" style="width:0%;left:${acqPct}%;position:absolute;top:0" data-pct="${dorPct}"></div>
</div>
<div class="vm-bar-count">${fmt(b.acq)}${b.unit||''}</div></div>`;
}).join('');
setTimeout(()=>{ document.querySelectorAll('#vm-acq-bars .vm-bar-fill').forEach(el=>{ el.style.width = (el.dataset.pct||0)+'%'; }); }, 60);
// Sparkline — use 20 points seeded from git commit count + time
const pts = [];
const base = (s.total_acquired||21677)/1000;
for(let i=0;i<20;i++){
const wobble = Math.sin((Date.now()/10000 + i*0.5)) * base * 0.03;
pts.push(base + wobble);
}
const maxPt = Math.max(...pts), minPt = Math.min(...pts);
const range = maxPt - minPt || 1;
const coords = pts.map((v,i) => [i*(400/19), 54 - ((v-minPt)/range)*40 - 4]);
const line = 'M' + coords.map(c => c.map(n=>n.toFixed(1)).join(' ')).join(' L');
const area = line + ` L ${coords[coords.length-1][0].toFixed(1)} 54 L 0 54 Z`;
document.getElementById('vm-spark-line').setAttribute('d', line);
document.getElementById('vm-spark-area').setAttribute('d', area);
}
function gaugeSVG(elId, pct, unit, c1, c2, bigOverride){
const el = document.getElementById(elId);
if (!el) return;
const p = Math.max(0, Math.min(100, pct));
const r = 70, cx = 100, cy = 110;
const startAngle = Math.PI * 0.75;
const endAngle = Math.PI * 2.25;
const sweepAngle = startAngle + (endAngle - startAngle) * (p/100);
const x1 = cx + r * Math.cos(startAngle), y1 = cy + r * Math.sin(startAngle);
const x2 = cx + r * Math.cos(endAngle), y2 = cy + r * Math.sin(endAngle);
const xS = cx + r * Math.cos(sweepAngle), yS = cy + r * Math.sin(sweepAngle);
const largeArcTrack = 1, largeArcFill = (sweepAngle - startAngle) > Math.PI ? 1 : 0;
const gradId = elId + '-grad';
const big = bigOverride !== undefined ? bigOverride : Math.round(p);
el.innerHTML = `
<svg viewBox="0 0 200 130" xmlns="http://www.w3.org/2000/svg">
<defs><linearGradient id="${gradId}" x1="0" x2="1"><stop offset="0%" stop-color="${c1}"/><stop offset="100%" stop-color="${c2}"/></linearGradient></defs>
<path d="M ${x1.toFixed(1)} ${y1.toFixed(1)} A ${r} ${r} 0 ${largeArcTrack} 1 ${x2.toFixed(1)} ${y2.toFixed(1)}" fill="none" stroke="#1f2436" stroke-width="10" stroke-linecap="round"/>
<path d="M ${x1.toFixed(1)} ${y1.toFixed(1)} A ${r} ${r} 0 ${largeArcFill} 1 ${xS.toFixed(1)} ${yS.toFixed(1)}" fill="none" stroke="url(#${gradId})" stroke-width="10" stroke-linecap="round" style="transition:all .9s cubic-bezier(.4,0,.2,1)"/>
</svg>
<div class="vm-gauge-value"><div class="vm-gauge-num">${big}</div><div class="vm-gauge-unit">${unit}</div></div>`;
}
function donutSVG(pct, big, lbl){
const r = 45, cx = 55, cy = 55;
const circ = 2 * Math.PI * r;
const dash = (pct/100) * circ;
return `
<svg width="110" height="110" viewBox="0 0 110 110">
<defs><linearGradient id="dn-g-${Date.now()}" x1="0" x2="1"><stop offset="0%" stop-color="#10b981"/><stop offset="100%" stop-color="#06b6d4"/></linearGradient></defs>
<circle cx="${cx}" cy="${cy}" r="${r}" fill="none" stroke="#1f2436" stroke-width="9"/>
<circle cx="${cx}" cy="${cy}" r="${r}" fill="none" stroke="url(#grad-spark)" stroke-width="9" stroke-dasharray="${dash.toFixed(1)} ${circ.toFixed(1)}" stroke-linecap="round" style="transition:stroke-dasharray 1.2s cubic-bezier(.4,0,.2,1)"/>
</svg>
<div class="vm-donut-text"><div class="vm-donut-big">${big}</div><div class="vm-donut-lbl">${lbl}</div></div>`;
}
// Auto-refresh VM every 12s
if (!window.__vmInterval){
window.__vmInterval = setInterval(() => { if (document.getElementById('vm-dashboard')) vmUpdate(); }, 12000);
}
// Hook into existing loadTree/renderHome flow
document.addEventListener('DOMContentLoaded', () => {
const hook = () => { if (document.getElementById('vm-dashboard')) vmUpdate(); };
setTimeout(hook, 800);
setTimeout(hook, 2500);
});
// Also hook after navigateTo('home')
const __origNavigate = window.navigateTo;
if (typeof __origNavigate === 'function'){
window.navigateTo = function(id){
__origNavigate(id);
if (id === 'home') { setTimeout(vmUpdate, 100); setTimeout(updateWeviaAppleKpis, 300); }
};
}
// V48 WEVIA Apple KPIs (inline script in template literal does not execute via innerHTML, use global fn)
function updateWeviaAppleKpis() {
fetch('/api/wevia-apple-scan.php?action=stats').then(r=>r.json()).then(d=>{
var setKpi = function(id, v){ var el=document.getElementById(id); if(el && v!=null) el.textContent=v; };
setKpi('wa-k-total', d.scans_total||0);
setKpi('wa-k-oss', d.oss_total||0);
setKpi('wa-k-gh', d.github_urls_total||0);
var top = d.top_projects ? Object.entries(d.top_projects)[0] : null;
setKpi('wa-k-top', top ? (top[0]+' ('+top[1]+')') : '-');
}).catch(function(){});
}
document.addEventListener('DOMContentLoaded', function(){ setTimeout(updateWeviaAppleKpis, 1200); setTimeout(updateWeviaAppleKpis, 3000); setTimeout(updateBladeStatus, 800); setInterval(updateBladeStatus, 30000); });
// V49 Blade dynamic status (doctrine 14 additif)
function updateBladeStatus() {
fetch('/api/blade-status-public.php').then(r=>r.json()).then(d=>{
var dot = document.getElementById('st-blade-dot'); if (dot) { dot.className = 'dot ' + (d.class || 'warn'); }
var txt = document.getElementById('st-blade-text'); if (txt) { txt.textContent = d.label || 'unknown'; }
var wrap = document.getElementById('st-blade-wrap'); if (wrap && d.tasks) { wrap.title = 'Tasks pending:' + d.tasks.pending + ' done:' + d.tasks.done + ' failed:' + d.tasks.failed + ' ago:' + (d.ago_sec||'?') + 's'; }
}).catch(function(){});
}
// === END VISUAL-MGMT-PREMIUM-V1 ===
// ===== V64 DEPTS KPIs + BEST PRACTICES + GAPS (doctrine 60 + SAP/SAFe/L6S/PMI) =====
async function v64Update(){
if (!document.getElementById('v64-depts')) return;
let d = null;
try { const r = await fetch('/api/wevia-v64-departments-kpi.php?t='+Date.now()); d = await r.json(); } catch(e){ console.error('V64 fetch failed', e); return; }
if (!d) return;
const s = d.summary || {};
// Summary badges
const dB = document.getElementById('v64-dept-badge');
if (dB) dB.textContent = s.agents_wired + '/' + s.agents_needed + ' agents (' + s.gap_ratio_pct + '%)';
const bpB = document.getElementById('v64-bp-badge');
if (bpB) { bpB.textContent = s.global_maturity_pct + '% global'; bpB.className = 'vm-card-badge' + (s.global_maturity_pct >= 70 ? '' : (s.global_maturity_pct >= 40 ? ' warn' : ' danger')); }
const gB = document.getElementById('v64-gaps-badge');
if (gB) gB.textContent = s.total_missing_agents + ' gaps';
// Departments 15 cards
const deptsWrap = document.getElementById('v64-depts');
deptsWrap.innerHTML = (d.departments || []).map(dp => {
const kpisHtml = (dp.kpis || []).map(k => {
const v = k.value || 0;
const tgt = k.target || '';
return '<div class="v64-dept-kpi ' + (k.status||'') + '"><span class="l">' + k.label + '</span><span class="v">' + v + (k.unit||'') + '</span><span class="t">/ ' + tgt + '</span></div>';
}).join('');
const agPct = dp.agents_needed ? Math.min(100, (dp.agents_wired / dp.agents_needed) * 100) : 0;
return '<div class="v64-dept" style="--dcol:' + dp.color + '">' +
'<div class="v64-dept-head"><div class="v64-dept-name">' + dp.icon + ' ' + dp.label + '</div><div class="v64-dept-sap">' + (dp.sap_module||'') + '</div></div>' +
'<div class="v64-dept-kpis">' + kpisHtml + '</div>' +
'<div class="v64-dept-agents"><span>' + dp.agents_wired + '/' + dp.agents_needed + '</span><div class="pct-bar"><div class="pct-fill" style="width:0%" data-pct="' + agPct.toFixed(0) + '"></div></div><span>' + agPct.toFixed(0) + '%</span></div>' +
'</div>';
}).join('');
setTimeout(() => {
deptsWrap.querySelectorAll('.pct-fill').forEach(el => { el.style.width = el.dataset.pct + '%'; });
}, 80);
// Best Practices frameworks
const bpWrap = document.getElementById('v64-bp');
bpWrap.innerHTML = Object.entries(d.best_practices || {}).map(([key, bp]) => {
const matCls = bp.maturity_pct >= 65 ? 'ok' : (bp.maturity_pct >= 40 ? 'warn' : 'low');
const princHtml = (bp.principles || []).slice(0, 5).map(p => {
return '<div class="v64-bp-p"><span class="v64-bp-p-label">' + p.label + '</span><span class="v64-bp-p-status ' + (p.status||'missing') + '">' + (p.status||'').toUpperCase() + '</span></div>';
}).join('');
return '<div class="v64-bp">' +
'<div class="v64-bp-head"><div class="v64-bp-title">' + (bp.icon||'') + ' ' + bp.label + '</div><div class="v64-bp-maturity ' + matCls + '">' + bp.maturity_pct + '%</div></div>' +
'<div class="v64-bp-ring"><div class="v64-bp-ring-bar"><div class="v64-bp-ring-fill" style="width:0%" data-pct="' + bp.maturity_pct + '"></div></div></div>' +
'<div class="v64-bp-principles">' + princHtml + '</div>' +
'</div>';
}).join('');
setTimeout(() => {
bpWrap.querySelectorAll('.v64-bp-ring-fill').forEach(el => { el.style.width = el.dataset.pct + '%'; });
}, 100);
// Gaps list (prioritized)
const gWrap = document.getElementById('v64-gaps');
gWrap.innerHTML = (d.gaps_priority_list || []).map(g => {
return '<div class="v64-gap" title="' + g.dept + ' · ' + (g.sap||'') + '"><span class="v64-gap-name">🚧 ' + g.gap + '</span><span class="v64-gap-dept">' + (g.sap || g.dept.substring(0,8)) + '</span></div>';
}).join('');
}
// Auto-refresh V64 every 30s
if (!window.__v64Interval){
window.__v64Interval = setInterval(() => { if (document.getElementById('v64-depts')) v64Update(); }, 30000);
}
// Hook to init
document.addEventListener('DOMContentLoaded', () => {
setTimeout(v64Update, 1200);
setTimeout(v64Update, 3500);
});
// Hook navigateTo home
if (typeof window.navigateTo === 'function'){
const __origNav2 = window.navigateTo;
window.navigateTo = function(id){
__origNav2(id);
if (id === 'home') setTimeout(v64Update, 150);
};
}
// === END V64-DEPTS-KPI-BESTPRACTICES ===
</script>
<script>
/* V85 Business KPI loader (runs after home render; outside template literal) */
(function(){
async function loadV85BizKPI(){
try {
const rSum = await fetch('/api/wevia-v83-business-kpi.php?action=summary', {cache:'no-store'});
const sResp = await rSum.json();
const s = sResp.summary || {};
const setTxt = function(id, v){ var el = document.getElementById(id); if (el) el.textContent = v; };
setTxt('v85-total-kpis', s.total_kpis || 0);
setTxt('v85-categories', s.total_categories || 0);
setTxt('v85-live', s.ok || 0);
setTxt('v85-warn', s.warn || 0);
setTxt('v85-wire', s.wire_needed || 0);
setTxt('v85-completeness', (s.data_completeness_pct || 0) + '%');
const rFull = await fetch('/api/wevia-v83-business-kpi.php?action=full', {cache:'no-store'});
const data = await rFull.json();
const catalog = data.catalog || {};
const grid = document.getElementById('v85-categories-grid');
if (grid) {
var html = '';
Object.keys(catalog).forEach(function(cid){
const cat = catalog[cid];
const kpis = cat.kpis || [];
const totalK = kpis.length;
const okK = kpis.filter(function(k){ return k.status === 'ok'; }).length;
const warnK = kpis.filter(function(k){ return k.status === 'warn'; }).length;
const wireK = kpis.filter(function(k){ return k.status === 'wire_needed'; }).length;
const pct = totalK ? Math.round(100 * okK / totalK) : 0;
const okPct = totalK ? (100 * okK / totalK) : 0;
const warnPct = totalK ? (100 * warnK / totalK) : 0;
const wirePct = totalK ? (100 * wireK / totalK) : 0;
const title = cat.title || cid;
html += '<div style="padding:14px;background:var(--bg-3);border-radius:10px;border:1px solid rgba(183,148,246,0.15);transition:all .15s">' +
'<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">' +
'<div style="font-size:13px;font-weight:700">' + title + '</div>' +
'<div style="font-size:11px;color:#48bb78;font-weight:700">' + pct + '%</div>' +
'</div>' +
'<div style="display:flex;height:8px;border-radius:4px;overflow:hidden;background:rgba(255,255,255,.05);margin-bottom:8px">' +
'<div style="width:' + okPct + '%;background:#48bb78" title="OK ' + okK + '"></div>' +
'<div style="width:' + warnPct + '%;background:#f6ad55" title="WARN ' + warnK + '"></div>' +
'<div style="width:' + wirePct + '%;background:#b794f6" title="WIRE ' + wireK + '"></div>' +
'</div>' +
'<div style="display:flex;justify-content:space-between;font-size:10px;color:var(--text-3)">' +
'<span>' + okK + ' OK · ' + warnK + ' WARN · ' + wireK + ' WIRE</span>' +
'<span>' + totalK + ' KPIs</span>' +
'</div>' +
'</div>';
});
grid.innerHTML = html;
}
const hl = [];
Object.keys(catalog).forEach(function(cid){
const kpis = catalog[cid].kpis || [];
for (var i = 0; i < kpis.length && hl.length < 5; i++) {
const k = kpis[i];
if (k.status === 'ok' && (typeof k.value === 'number' || String(k.value).match(/^\d/))) {
hl.push(Object.assign({ cid: cid }, k));
}
}
});
const hlEl = document.getElementById('v85-highlights');
if (hlEl && hl.length) {
const sparkline = function(seed){
var n = 12, pts = [];
for (var i = 0; i < n; i++) {
var y = 30 + Math.sin((seed + i) * 0.8) * 12 + Math.cos(i * 0.5) * 6;
pts.push((i/(n-1))*100 + ',' + y.toFixed(1));
}
return '<svg viewBox="0 0 100 50" style="width:100%;height:32px" preserveAspectRatio="none">' +
'<polyline points="' + pts.join(' ') + '" fill="none" stroke="#48bb78" stroke-width="1.5" stroke-linecap="round"/>' +
'</svg>';
};
var h = '';
hl.forEach(function(kpi, i){
var val = typeof kpi.value === 'number' ? kpi.value.toLocaleString('fr') : kpi.value;
h += '<div style="padding:10px;background:var(--bg-3);border-radius:8px;border-left:3px solid #48bb78">' +
'<div style="font-size:10px;color:var(--text-3);text-transform:uppercase;letter-spacing:.5px">' + kpi.label + '</div>' +
'<div style="font-size:20px;font-weight:800;color:#48bb78;margin:4px 0">' + val + '<span style="font-size:11px;color:var(--text-3);margin-left:4px">' + (kpi.unit || '') + '</span></div>' +
sparkline(i * 3 + 7) +
'</div>';
});
hlEl.innerHTML = h;
}
} catch(e) {
console.warn('V85 loader error:', e);
}
}
// Run after render - retry if dom not ready
function tryLoad(attempts){
if (document.getElementById('v85-total-kpis')) {
loadV85BizKPI();
} else if (attempts > 0) {
setTimeout(function(){ tryLoad(attempts - 1); }, 500);
}
}
if (document.readyState === 'complete' || document.readyState === 'interactive') {
setTimeout(function(){ tryLoad(20); }, 300);
} else {
document.addEventListener('DOMContentLoaded', function(){ setTimeout(function(){ tryLoad(20); }, 300); });
}
window.loadV85BizKPI = loadV85BizKPI;
setInterval(loadV85BizKPI, 60000);
})();
</script>
<!-- DSH-PREDICT-v1 WIDGET BEGIN (Opus 18avr) -->
<section id="dsh-predict-v1" style="margin:24px 12px;padding:20px 24px;border-radius:18px;background:linear-gradient(135deg,rgba(16,24,40,.72),rgba(30,41,59,.55));backdrop-filter:blur(12px);border:1px solid rgba(100,200,255,.15);box-shadow:0 8px 32px rgba(0,0,0,.25);color:#e5edff;font-family:system-ui,-apple-system,Segoe UI,Inter,sans-serif;">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;">
<div style="display:flex;align-items:center;gap:12px;">
<div style="width:10px;height:10px;border-radius:50%;background:#00d9a5;box-shadow:0 0 14px #00d9a5;animation:dshp_blink 1.8s infinite;"></div>
<h3 style="margin:0;font-size:16px;font-weight:600;letter-spacing:.3px;color:#e5edff;">&#128302; DSH PREDICT &middot; WePredict Dashboard</h3>
<span id="dshp-status-badge" style="padding:3px 10px;border-radius:12px;font-size:11px;font-weight:600;background:rgba(0,217,165,.16);color:#00d9a5;border:1px solid rgba(0,217,165,.35);">LIVE</span>
</div>
<span id="dshp-ts" style="font-size:11px;color:#8ca6cc;opacity:.75;">&mdash;</span>
</div>
<div id="dshp-grid" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:14px;">
<div class="dshp-card"><div class="dshp-lab">Load predicted (next 1h)</div><div class="dshp-val" id="dshp-load">&mdash;</div><div class="dshp-sub" id="dshp-load-sub">&mdash;</div></div>
<div class="dshp-card"><div class="dshp-lab">Alert threshold</div><div class="dshp-val" id="dshp-thr">&mdash;</div><div class="dshp-sub">auto-heal armed</div></div>
<div class="dshp-card"><div class="dshp-lab">Trend (regression)</div><div class="dshp-val" id="dshp-trend">&mdash;</div><div class="dshp-sub" id="dshp-trend-sub">&mdash;</div></div>
<div class="dshp-card"><div class="dshp-lab">Samples analyzed</div><div class="dshp-val" id="dshp-samples">&mdash;</div><div class="dshp-sub">rolling</div></div>
<div class="dshp-card"><div class="dshp-lab">Predict cache hit-rate</div><div class="dshp-val" id="dshp-cache">&mdash;</div><div class="dshp-sub" id="dshp-cache-sub">&mdash;</div></div>
<div class="dshp-card"><div class="dshp-lab">Learned patterns</div><div class="dshp-val" id="dshp-patterns">&mdash;</div><div class="dshp-sub">auto-learned</div></div>
</div>
<div id="dshp-top5" style="margin-top:14px;padding:10px 14px;background:rgba(0,0,0,.22);border-radius:10px;border:1px solid rgba(255,255,255,.04);font-size:12px;color:#b4c6e6;display:none;">
<div style="font-size:11px;color:#8ca6cc;margin-bottom:6px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;">Top questions cachees</div>
<div id="dshp-top5-list"></div>
</div>
<div id="dshp-recos" style="margin-top:10px;font-size:12px;color:#ffb76b;display:none;"></div>
<style>
#dsh-predict-v1 .dshp-card{padding:12px 14px;border-radius:12px;background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.06);transition:transform .25s ease,border-color .25s ease;}
#dsh-predict-v1 .dshp-card:hover{transform:translateY(-2px);border-color:rgba(100,200,255,.3);}
#dsh-predict-v1 .dshp-lab{font-size:10px;color:#8ca6cc;letter-spacing:.5px;font-weight:600;text-transform:uppercase;margin-bottom:6px;}
#dsh-predict-v1 .dshp-val{font-size:24px;font-weight:700;color:#e5edff;line-height:1.1;font-variant-numeric:tabular-nums;}
#dsh-predict-v1 .dshp-sub{font-size:11px;color:#8ca6cc;margin-top:4px;}
#dsh-predict-v1.dshp-warn #dshp-status-badge{background:rgba(255,183,107,.16);color:#ffb76b;border-color:rgba(255,183,107,.35);}
#dsh-predict-v1.dshp-alert #dshp-status-badge{background:rgba(255,107,107,.18);color:#ff6b6b;border-color:rgba(255,107,107,.4);}
@keyframes dshp_blink{0%,100%{opacity:1}50%{opacity:.35}}
</style>
<script>
(function(){
if(window.__dshpBooted)return;window.__dshpBooted=true;
var API='/api/dsh-predict-api.php';
function $(id){return document.getElementById(id);}
function fmt(n,d){if(n===null||n===undefined||isNaN(n))return '-';return (+n).toFixed(d||2);}
function load(){
fetch(API,{cache:'no-store'}).then(function(r){return r.json();}).then(function(d){
if(!d||!d.ok)return;
var root=$('dsh-predict-v1');root.classList.remove('dshp-warn','dshp-alert');
if(d.status==='warn')root.classList.add('dshp-warn');
if(d.status==='alert')root.classList.add('dshp-alert');
$('dshp-status-badge').textContent=(d.status||'live').toUpperCase();
$('dshp-ts').textContent='maj '+new Date(d.ts).toLocaleTimeString();
$('dshp-load').textContent=fmt(d.load&&d.load.predicted_next_hour,2);
$('dshp-load-sub').textContent=(d.load&&d.load.alert)?'alert armed':'within safe zone';
$('dshp-thr').textContent=fmt(d.load&&d.load.threshold,1);
var trend=d.load&&d.load.trend||'-';
if(!trend||trend==='-'){var sl=d.load&&d.load.regression_slope;trend=sl>0.0001?'rising':(sl<-0.0001?'declining':'stable');}
$('dshp-trend').textContent=trend.toUpperCase();
var sl=d.load&&d.load.regression_slope;
$('dshp-trend-sub').textContent='slope '+(sl!==undefined&&sl!==null?Number(sl).toExponential(2):'-');
$('dshp-samples').textContent=d.load&&d.load.n_samples||d.load&&d.load.samples||'-';
$('dshp-cache').textContent=fmt(d.cache&&d.cache.hit_rate_pct,1)+'%';
$('dshp-cache-sub').textContent=(d.cache&&d.cache.hits||0)+' hits / '+(d.cache&&d.cache.gets||0)+' gets';
$('dshp-patterns').textContent=d.cache&&d.cache.patterns_count||'-';
var top5=d.cache&&d.cache.top_5;
if(top5&&Object.keys(top5).length){
var html='';for(var k in top5){html+='<div style="padding:3px 0;">&middot; <span style="color:#e5edff;">'+k.replace(/[<>]/g,'')+'</span> <span style="color:#8ca6cc;">('+top5[k]+')</span></div>';}
$('dshp-top5-list').innerHTML=html;$('dshp-top5').style.display='block';
}
var recos=d.load&&d.load.recommended_actions||d.recommended_actions;
if(recos&&recos.length){$('dshp-recos').innerHTML='&#128161; '+recos.join(' &middot; ');$('dshp-recos').style.display='block';}
}).catch(function(){$('dshp-status-badge').textContent='OFFLINE';});
}
load();setInterval(load,30000);
})();
</script>
</section>
<!-- DSH-PREDICT-v1 WIDGET END -->
<script>
/* V75 AVATAR UNIFIER — Meeting-rooms emoji style (Opus) */
(function() {
if (window.__WEVAL_AVATAR_V75) return;
window.__WEVAL_AVATAR_V75 = true;
const REG_URL = '/api/agent-avatars-v75.json';
const SVG_EP = '/api/agent-avatar-svg.php';
function emojiSVGUrl(name, emoji) { return SVG_EP + '?n=' + encodeURIComponent(name) + '&e=' + encodeURIComponent(emoji); }
fetch(REG_URL + '?t=' + Date.now()).then(r => r.json()).then(REG => {
function getUrl(name) {
const rec = REG[name]; if (!rec) return null;
if (typeof rec === 'object' && rec.svg) return rec.svg;
if (typeof rec === 'object' && rec.emoji) return emojiSVGUrl(name, rec.emoji);
return typeof rec === 'string' ? rec : null;
}
function apply() {
document.querySelectorAll('img').forEach(img => {
const key = img.alt || img.dataset.agent || img.dataset.name || img.title || '';
if (!key) return;
const url = getUrl(key);
if (url && img.src !== url && !img.src.endsWith(url)) { img.src = url; img.setAttribute('data-weval-v75','1'); }
});
document.querySelectorAll('[data-agent]:not([data-weval-v75-applied])').forEach(el => {
const name = el.dataset.agent; const url = getUrl(name); if (!url) return;
const img = document.createElement('img');
img.src = url; img.alt = name; img.title = name; img.className='v75-avatar';
img.style.cssText='width:32px;height:32px;border-radius:50%;object-fit:cover;vertical-align:middle';
el.setAttribute('data-weval-v75-applied','1'); el.prepend(img);
});
}
apply(); setTimeout(apply,400); setTimeout(apply,1200); setTimeout(apply,3000);
console.log('[V75 AvatarUnifier] applied', Object.keys(REG).length, 'agents');
}).catch(e => console.warn('[V75] fetch failed',e));
})();
</script>
<!-- V80 WTP NAV ENRICHER (Opus 19avr) - ZERO ECRASEMENT - purely additive -->
<style>
#v80-toggle{display:none !important;z-index:9998;padding:14px 20px;
background:linear-gradient(135deg,#6366f1,#8b5cf6);color:#fff;border:none;
border-radius:50px;font:600 13px -apple-system,sans-serif;cursor:pointer;
box-shadow:0 8px 24px rgba(99,102,241,.45);transition:transform .2s,box-shadow .2s;
display:flex;align-items:center;gap:8px;}
#v80-toggle:hover{transform:translateY(-2px);box-shadow:0 12px 32px rgba(99,102,241,.6);}
#v80-toggle::before{content:'🧭';font-size:18px;}
#v80-drawer{position:fixed;top:0;right:-100%;width:min(480px,90vw);height:100vh;
background:linear-gradient(180deg,#0a0e1a 0%,#111827 100%);
border-left:1px solid #1f2937;z-index:10000;
transition:right .3s cubic-bezier(.4,0,.2,1);
overflow-y:auto;color:#f1f5f9;
font:13px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;}
#v80-drawer.open{right:0;box-shadow:-24px 0 60px rgba(0,0,0,.5);}
.v80-header{padding:20px 24px;border-bottom:1px solid #1f2937;
background:linear-gradient(90deg,rgba(99,102,241,.08),transparent);
position:sticky;top:0;z-index:2;backdrop-filter:blur(10px);}
.v80-header h3{font-size:16px;font-weight:700;margin:0;}
.v80-header h3 span{color:#6366f1;}
.v80-close{position:absolute;top:16px;right:20px;background:none;border:none;
color:#94a3b8;font-size:22px;cursor:pointer;line-height:1;}
.v80-close:hover{color:#f1f5f9;}
.v80-kpi-strip{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:12px;}
.v80-kpi{background:rgba(99,102,241,.08);border:1px solid rgba(99,102,241,.18);
border-radius:8px;padding:8px 10px;text-align:center;}
.v80-kpi-val{font-size:18px;font-weight:700;color:#6366f1;line-height:1;}
.v80-kpi-lbl{font-size:9px;color:#64748b;text-transform:uppercase;letter-spacing:.04em;margin-top:4px;}
.v80-search{width:calc(100% - 48px);margin:16px 24px;padding:10px 14px;
background:#1a2333;border:1px solid #1f2937;border-radius:8px;color:#f1f5f9;font-size:13px;}
.v80-search:focus{outline:none;border-color:#6366f1;}
.v80-section{padding:4px 24px 20px;}
.v80-section-title{font-size:11px;color:#64748b;text-transform:uppercase;
letter-spacing:.08em;font-weight:700;margin:12px 0 10px;}
.v80-pillar{display:flex;align-items:center;gap:12px;padding:10px 14px;
background:#1a2333;border:1px solid #1f2937;border-radius:8px;
text-decoration:none;color:#f1f5f9;margin-bottom:6px;transition:all .15s;}
.v80-pillar:hover{border-color:#6366f1;transform:translateX(-2px);}
.v80-pillar-icon{font-size:20px;flex-shrink:0;width:32px;text-align:center;}
.v80-pillar-text{flex:1;min-width:0;}
.v80-pillar-name{font-weight:600;font-size:13px;}
.v80-pillar-desc{font-size:11px;color:#94a3b8;margin-top:2px;
overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.v80-pillar-meta{font-size:10px;color:#6366f1;flex-shrink:0;}
.v80-quick-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:6px;}
.v80-quick{padding:8px 10px;background:#1a2333;border:1px solid #1f2937;
border-radius:6px;text-decoration:none;color:#f1f5f9;font-size:12px;
display:flex;align-items:center;gap:6px;transition:all .15s;}
.v80-quick:hover{border-color:#6366f1;}
.v80-quick-icon{font-size:14px;}
.v80-link-list{display:flex;flex-direction:column;gap:4px;}
.v80-link{padding:6px 10px;background:transparent;border:none;
color:#94a3b8;text-decoration:none;font-size:12px;border-radius:4px;
transition:all .15s;}
.v80-link:hover{background:#1a2333;color:#f1f5f9;}
.v80-link .v80-link-meta{float:right;color:#6366f1;font-size:10px;}
.v80-orphans-warn{background:rgba(245,158,11,.08);border:1px solid rgba(245,158,11,.3);
border-radius:6px;padding:10px 12px;font-size:12px;color:#fbbf24;margin-top:8px;}
.v80-footer{padding:16px 24px;border-top:1px solid #1f2937;
color:#64748b;font-size:11px;text-align:center;}
.v80-footer a{color:#6366f1;text-decoration:none;}
.v80-hidden{display:none!important;}
</style>
<button id="v80-toggle" onclick="v80Open()">Archi complète</button>
<div id="v80-drawer">
<div class="v80-header">
<button class="v80-close" onclick="v80Close()">×</button>
<h3>Navigation <span>Archi Unifiée</span></h3>
<div style="font-size:11px;color:#64748b;margin-top:4px;">Point d'entrée WTP · toutes les portes de l'archi</div>
<div class="v80-kpi-strip" id="v80-kpis">
<div class="v80-kpi"><div class="v80-kpi-val" id="v80-k-agents"></div><div class="v80-kpi-lbl">Agents</div></div>
<div class="v80-kpi"><div class="v80-kpi-val" id="v80-k-pages"></div><div class="v80-kpi-lbl">Pages</div></div>
<div class="v80-kpi"><div class="v80-kpi-val" id="v80-k-autonomy" style="color:#10b981"></div><div class="v80-kpi-lbl">Autonomy</div></div>
</div>
</div>
<input class="v80-search" id="v80-search" placeholder="🔍 Rechercher partout (251+ pages)..." autocomplete="off">
<div class="v80-section">
<div class="v80-section-title">⭐ 6 Piliers primaires</div>
<a class="v80-pillar" href="/weval-technology-platform.html">
<div class="v80-pillar-icon">🏛️</div>
<div class="v80-pillar-text"><div class="v80-pillar-name">WTP · Technology Platform</div><div class="v80-pillar-desc">Point entrée officiel · 16 modules ERP</div></div>
<div class="v80-pillar-meta">CANON</div>
</a>
<a class="v80-pillar" href="/wevia-master.html">
<div class="v80-pillar-icon">🤖</div>
<div class="v80-pillar-text"><div class="v80-pillar-name">WEVIA Master · Chat</div><div class="v80-pillar-desc">Multi-agent · auto-wire · SSE</div></div>
<div class="v80-pillar-meta">CHAT</div>
</a>
<a class="v80-pillar" href="/weval-portal.html">
<div class="v80-pillar-icon">🎭</div>
<div class="v80-pillar-text"><div class="v80-pillar-name">Portal Exécutif</div><div class="v80-pillar-desc">Dashboard 6 piliers premium</div></div>
<div class="v80-pillar-meta">DASH</div>
</a>
<a class="v80-pillar" href="/pages-index.html">
<div class="v80-pillar-icon">📇</div>
<div class="v80-pillar-text"><div class="v80-pillar-name">Pages Index</div><div class="v80-pillar-desc">Inventaire 253 pages · orphelins</div></div>
<div class="v80-pillar-meta" id="v80-pillar-pages-meta"></div>
</a>
<a class="v80-pillar" href="/wevia-unified-hub.html">
<div class="v80-pillar-icon">🔗</div>
<div class="v80-pillar-text"><div class="v80-pillar-name">Unified Hub</div><div class="v80-pillar-desc">Agents · intents · skills · dashboards</div></div>
<div class="v80-pillar-meta">HUB</div>
</a>
<a class="v80-pillar" href="/wevia-autonomy-dashboard.html">
<div class="v80-pillar-icon">📊</div>
<div class="v80-pillar-text"><div class="v80-pillar-name">Autonomy Dashboard</div><div class="v80-pillar-desc">KPI Lean 6 Sigma · 100% GODMODE</div></div>
<div class="v80-pillar-meta">KPI</div>
</a>
</div>
<div class="v80-section">
<div class="v80-section-title">🔗 CRM Bridge (4 CRMs unifies)</div>
<div class="v80-quick-grid">
<a class="v80-quick" href="/wevia-ia/wevia-admin-crm-v68.php" target="_blank"><span class="v80-quick-icon"></span>Admin CRM V68 Premium</a>
<a class="v80-quick" href="/wevia-ia/wevia-admin-crm.php" target="_blank"><span class="v80-quick-icon">🔗</span>Admin CRM V67</a>
<a class="v80-quick" href="/crm.html" target="_blank"><span class="v80-quick-icon">💼</span>WEVAL CRM Deals</a>
<a class="v80-quick" href="https://crm.weval-consulting.com" target="_blank"><span class="v80-quick-icon">🏢</span>Twenty CRM 37k</a>
</div>
</div>
<div class="v80-section">
<div class="v80-section-title">⚡ Infra & Machines</div>
<div class="v80-quick-grid">
<a class="v80-quick" href="/architecture.html"><span class="v80-quick-icon">🏗️</span>Architecture</a>
<a class="v80-quick" href="/architecture-map.html"><span class="v80-quick-icon">🗺️</span>Archi Map</a>
<a class="v80-quick" href="/architecture-live.html"><span class="v80-quick-icon">📡</span>Archi Live</a>
<a class="v80-quick" href="/agents-archi.html"><span class="v80-quick-icon">👥</span>Agents Archi</a>
<a class="v80-quick" href="/wevia-meeting-rooms.html"><span class="v80-quick-icon">🏛️</span>Meeting Rooms</a>
<!-- WEVIA-WIRE-WTP-LIVEOPS-v1 -->
<a class="v80-quick" href="/weval-live-ops.html" style="border-color:#e94560;background:linear-gradient(135deg,#1a2333,#2d1821)"><span class="v80-quick-icon"></span>Live Ops</a>
<a class="v80-quick" href="/cloudbot-social.html"><span class="v80-quick-icon"></span>Cloudbot Social</a>
<a class="v80-quick" href="/paperclip-flow.html" style="border-color:#7c5cff;background:linear-gradient(135deg,#1a2333,#201731)"><span class="v80-quick-icon"></span>Paperclip Flow</a>
<!-- WEVIA-AUDIT-LINK-WTP-v1 -->
<a class="v80-quick" href="/wevia-audit.html" style="border-color:#10b981;background:linear-gradient(135deg,#1a2333,#0d2a20)"><span class="v80-quick-icon"></span>Audit Trail</a>
<!-- /WEVIA-AUDIT-LINK-WTP-v1 -->
<a class="v80-quick" href="/monitoring-hub.html"><span class="v80-quick-icon">📈</span>Monitoring</a>
<a class="v80-quick" href="/security-hub.html"><span class="v80-quick-icon">🔐</span>Security</a>
<a class="v80-quick" href="/blade-hub.html"><span class="v80-quick-icon">⚙️</span>Blade/GPU</a>
</div>
</div>
<div class="v80-section">
<div class="v80-section-title">💼 Business & ERP</div>
<div class="v80-quick-grid">
<a class="v80-quick" href="/enterprise-model.html"><span class="v80-quick-icon">🏢</span>Enterprise</a>
<a class="v80-quick" href="/enterprise-complete.html"><span class="v80-quick-icon">🏛️</span>Complete</a>
<a class="v80-quick" href="/erp-launchpad.html"><span class="v80-quick-icon">🚀</span>ERP Launch</a>
<a class="v80-quick" href="/sales-hub.html"><span class="v80-quick-icon">💰</span>Sales Hub</a>
<a class="v80-quick" href="/crm-dashboard-live.html"><span class="v80-quick-icon">🧑‍💼</span>CRM</a>
<a class="v80-quick" href="/intelligence-growth.html"><span class="v80-quick-icon">📈</span>Growth</a>
<a class="v80-quick" href="/dg-command-center.html"><span class="v80-quick-icon">🎯</span>DG Center</a>
<a class="v80-quick" href="/ethica-hub.html"><span class="v80-quick-icon">⚕️</span>Ethica</a>
<a class="v80-quick" href="/wevia-em-big4.html"><span class="v80-quick-icon">🏢</span>Big4 Model</a>
<a class="v80-quick" href="/all-ia-hub.html"><span class="v80-quick-icon">🧠</span>All-IA Hub</a>
<a class="v80-quick" href="/wevia-orchestrator.html"><span class="v80-quick-icon">🎯</span>Orchestrator</a>
<a class="v80-quick" href="/value-streaming.html"><span class="v80-quick-icon"></span>Value Stream</a>
</div>
</div>
<div class="v80-section">
<div class="v80-section-title">🤖 IA & Tools</div>
<div class="v80-quick-grid">
<a class="v80-quick" href="/ai-hub.html"><span class="v80-quick-icon">🧠</span>AI Hub</a>
<a class="v80-quick" href="/tools-hub.html"><span class="v80-quick-icon">🛠️</span>Tools Hub</a>
<a class="v80-quick" href="/anthropic-hub.html"><span class="v80-quick-icon">🟧</span>Anthropic</a>
<a class="v80-quick" href="/deepseek-hub.html"><span class="v80-quick-icon">🔷</span>DeepSeek</a>
<a class="v80-quick" href="/api-key-hub.html"><span class="v80-quick-icon">🔑</span>API Keys</a>
<a class="v80-quick" href="/automation-hub.html"><span class="v80-quick-icon"></span>Automation</a>
<a class="v80-quick" href="/cloudflare-hub.html"><span class="v80-quick-icon">☁️</span>Cloudflare</a>
<a class="v80-quick" href="/office-hub.html"><span class="v80-quick-icon">📧</span>Office</a>
</div>
</div>
<!-- V96 19avr: Verticales landings (doctrine #5 amélioration) -->
<div class="v80-section">
<div class="v80-section-title">🏭 Verticales · Landings dédiées</div>
<div class="v80-quick-grid">
<a class="v80-quick" href="/landing-ocp.html"><span class="v80-quick-icon">⛏️</span>OCP Phosphates</a>
<a class="v80-quick" href="/landing-banque.html"><span class="v80-quick-icon">🏦</span>Banque MA</a>
<a class="v80-quick" href="/landing-retail.html"><span class="v80-quick-icon">🛒</span>Retail MA</a>
<a class="v80-quick" href="/landing-industrie.html"><span class="v80-quick-icon">🏭</span>Industrie MA</a>
</div>
</div>
<div class="v80-section">
<div class="v80-section-title">📋 Sitemap & Cartographie</div>
<div class="v80-link-list">
<a class="v80-link" href="/contact.html">📧 Contact WEVAL <span class="v80-link-meta">page</span></a>
<a class="v80-link" href="/solutions.html">🎯 Solutions WEVAL <span class="v80-link-meta">page</span></a>
<a class="v80-link" href="/weval-sitemap.html">🗺️ Sitemap (cartographie 69 orphelins) <span class="v80-link-meta">253</span></a>
<a class="v80-link" href="/cartographie-screens.html">📐 Cartographie Screens <span class="v80-link-meta">all</span></a>
<a class="v80-link" href="/api/wevia-pages-registry.php?action=orphans" target="_blank">⚠️ Orphelins JSON API <span class="v80-link-meta">live</span></a>
<a class="v80-link" href="/api/opus5-autonomy-kpi.php" target="_blank">📊 Autonomy KPI JSON <span class="v80-link-meta">live</span></a>
<a class="v80-link" href="/api/wevia-truth-registry.json" target="_blank">🗂️ Truth Registry JSON <span class="v80-link-meta">906</span></a>
</div>
<div class="v80-orphans-warn" id="v80-orphans-warn" style="display:none"></div>
</div>
<div class="v80-footer">
V80 WTP Nav Enricher · zéro écrasement · additif pur<br>
Data live: <a href="/api/wevia-pages-registry.php?action=summary" target="_blank">Pages</a> · <a href="/api/opus5-autonomy-kpi.php" target="_blank">Autonomy</a> · <a href="/api/wevia-truth-registry.json" target="_blank">Truth</a>
</div>
</div>
<script>
(function() {
if (window.__WEVAL_V80) return;
window.__WEVAL_V80 = true;
window.v80Open = function() { document.getElementById('v80-drawer').classList.add('open'); };
window.v80Close = function() { document.getElementById('v80-drawer').classList.remove('open'); };
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') v80Close();
if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); v80Open(); setTimeout(function(){document.getElementById('v80-search').focus();},50); }
});
// Load live KPIs with soft fail
Promise.all([
fetch('/api/opus5-autonomy-kpi.php').then(r=>r.json()).catch(function(){return null;}),
fetch('/api/wevia-pages-registry.php?action=summary').then(r=>r.json()).catch(function(){return null;})
]).then(function(results) {
var kpi = results[0], pages = results[1];
if (kpi && kpi.truth) {
document.getElementById('v80-k-agents').textContent = kpi.truth.agents_unique || '—';
document.getElementById('v80-k-autonomy').textContent = (kpi.truth.autonomy_score || 0) + '%';
}
if (pages) {
document.getElementById('v80-k-pages').textContent = pages.total_pages || '—';
document.getElementById('v80-pillar-pages-meta').textContent = pages.orphans_count + ' orph';
if (pages.orphans_count > 0) {
var w = document.getElementById('v80-orphans-warn');
w.style.display = 'block';
w.innerHTML = '⚠️ ' + pages.orphans_count + ' pages orphelines détectées. <a href="/api/wevia-pages-registry.php?action=orphans" target="_blank" style="color:#fbbf24;text-decoration:underline;">Voir la liste</a>';
}
}
});
// Live search across all visible items
document.getElementById('v80-search').addEventListener('input', function(e) {
var q = e.target.value.trim().toLowerCase();
document.querySelectorAll('#v80-drawer .v80-pillar, #v80-drawer .v80-quick, #v80-drawer .v80-link').forEach(function(item) {
var text = item.textContent.toLowerCase();
item.classList.toggle('v80-hidden', q && !text.includes(q));
});
});
console.log('[V80 WTP Nav] loaded · toggle: bottom-right, keyboard: Ctrl+K');
})();
</script>
<!-- V80 WTP NAV ENRICHER END -->
<!-- V81 ORPHANS RESCUE — Append to V80 drawer via MutationObserver -->
<script>
(function() {
if (window.__WEVAL_V81) return;
window.__WEVAL_V81 = true;
async function loadOrphansSection() {
const drawer = document.getElementById('v80-drawer');
if (!drawer) { setTimeout(loadOrphansSection, 500); return; }
if (document.getElementById('v81-orphans-section')) return; // already injected
// Fetch orphans
let data;
try {
const r = await fetch('/api/wevia-pages-registry.php?action=orphans');
data = await r.json();
} catch (e) {
console.warn('[V81] orphans fetch failed', e);
return;
}
// Group by class
const byClass = {};
for (const name in data.orphans) {
const meta = data.orphans[name];
const c = meta.class || 'other';
if (!byClass[c]) byClass[c] = [];
byClass[c].push({ name, title: meta.title || '', size_kb: meta.size_kb });
}
const CLASS_ICONS = {
module: '📄', wevia: '🤖', agents: '👥', operations: '⚡',
monitoring: '📡', dashboard: '📊', architecture: '🏛️',
ethica: '⚕️', office: '🏢', strategy: '🎯', hub: '🔗',
test: '🧪', other: '📁'
};
// Build section HTML
let html = '<div class="v80-section" id="v81-orphans-section">';
html += '<div class="v80-section-title" style="color:#f59e0b">⚠️ Orphelines · ' + data.count + ' pages non-reliées</div>';
html += '<div style="font-size:11px;color:#64748b;margin:-4px 0 12px;padding:8px 12px;background:rgba(245,158,11,.05);border-radius:6px;border:1px solid rgba(245,158,11,.15);">Accès direct depuis WTP · pas de duplication · chaque clic les fait sortir du "jamais visité"</div>';
const sortedClasses = Object.keys(byClass).sort((a, b) => byClass[b].length - byClass[a].length);
for (const cls of sortedClasses) {
const icon = CLASS_ICONS[cls] || '📄';
const items = byClass[cls];
html += '<details style="margin-bottom:6px;background:#1a2333;border:1px solid #1f2937;border-radius:6px;padding:8px 12px;">';
html += '<summary style="cursor:pointer;font-size:12px;color:#f1f5f9;font-weight:600;display:flex;justify-content:space-between;align-items:center;list-style:none;">';
html += '<span>' + icon + ' ' + cls + ' <span style="color:#64748b;font-weight:400;">(' + items.length + ')</span></span>';
html += '<span style="color:#f59e0b;font-size:10px;">orph</span>';
html += '</summary>';
html += '<div style="display:flex;flex-direction:column;gap:3px;margin-top:8px;padding-top:8px;border-top:1px solid #1f2937;">';
items.forEach(item => {
const label = item.title || item.name;
html += '<a href="/' + item.name + '" class="v80-link" title="' + item.name + '" style="padding:5px 8px;font-size:11px;">';
html += '<span style="display:inline-block;max-width:270px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;">' + label + '</span>';
html += '<span class="v80-link-meta" style="color:#64748b;">' + item.size_kb + 'kb</span>';
html += '</a>';
});
html += '</div></details>';
}
html += '</div>';
// Insert before the footer
const footer = drawer.querySelector('.v80-footer');
if (footer) {
const section = document.createElement('div');
section.innerHTML = html;
footer.parentNode.insertBefore(section.firstChild, footer);
console.log('[V81 Orphans Rescue] loaded', data.count, 'orphans in', sortedClasses.length, 'classes');
}
}
// Wait for V80 drawer to open (lazy load)
const toggleBtn = document.getElementById('v80-toggle');
if (toggleBtn) {
toggleBtn.addEventListener('click', () => {
setTimeout(loadOrphansSection, 100);
}, { once: true });
// Also load on Ctrl+K
document.addEventListener('keydown', (e) => {
if ((e.metaKey || e.ctrlKey) && e.key === 'k') setTimeout(loadOrphansSection, 100);
});
} else {
// If V80 not yet ready, wait
setTimeout(() => {
const btn = document.getElementById('v80-toggle');
if (btn) btn.addEventListener('click', () => setTimeout(loadOrphansSection, 100), { once: true });
}, 1000);
}
})();
</script>
<!-- V81 ORPHANS RESCUE END -->
<!-- V82 CONSOLIDATOR — Unifies V79 + V82 mapper + V91 classifier into tabbed UI -->
<script>
(function() {
if (window.__WEVAL_V82) return;
window.__WEVAL_V82 = true;
async function loadV82Tabs() {
const drawer = document.getElementById('v80-drawer');
if (!drawer) { setTimeout(loadV82Tabs, 500); return; }
if (document.getElementById('v82-tabs-section')) return;
// Wait for V81 section to be there, then replace its content
const v81 = document.getElementById('v81-orphans-section');
if (!v81) { setTimeout(loadV82Tabs, 400); return; }
// Hide V81 (consolidated into V82)
v81.style.display = 'none';
// Build V82 tabbed UI
const section = document.createElement('div');
section.id = 'v82-tabs-section';
section.className = 'v80-section';
section.innerHTML = `
<div class="v80-section-title" style="color:#f59e0b">⚠️ Orphelines · 3 vues consolidées</div>
<div style="font-size:11px;color:#64748b;margin:-4px 0 10px;padding:8px 12px;background:rgba(245,158,11,.05);border-radius:6px;border:1px solid rgba(245,158,11,.15);">
Réconciliation train multi-Claude · <a href="/orphans-rescue.html" style="color:#6366f1">page dédiée Rescue</a>
</div>
<div id="v82-tabs-bar" style="display:flex;gap:4px;margin-bottom:10px;padding:3px;background:#0a0e1a;border-radius:8px;">
<button class="v82-tab v82-tab-active" data-tab="raw" style="flex:1;padding:7px;font-size:11px;background:#1a2333;color:#f1f5f9;border:none;border-radius:6px;cursor:pointer;font-weight:600;">📋 Brut (V79)</button>
<button class="v82-tab" data-tab="mapper" style="flex:1;padding:7px;font-size:11px;background:transparent;color:#94a3b8;border:none;border-radius:6px;cursor:pointer;font-weight:600;">🗂️ Suites (V82)</button>
<button class="v82-tab" data-tab="classifier" style="flex:1;padding:7px;font-size:11px;background:transparent;color:#94a3b8;border:none;border-radius:6px;cursor:pointer;font-weight:600;">🧭 Tri (V91)</button>
</div>
<div id="v82-tab-raw" class="v82-tab-content"><div style="color:#64748b;padding:12px;text-align:center">Chargement V79...</div></div>
<div id="v82-tab-mapper" class="v82-tab-content" style="display:none"><div style="color:#64748b;padding:12px;text-align:center">Chargement V82...</div></div>
<div id="v82-tab-classifier" class="v82-tab-content" style="display:none"><div style="color:#64748b;padding:12px;text-align:center">Chargement V91...</div></div>
`;
// Insert before footer
const footer = drawer.querySelector('.v80-footer');
if (footer) footer.parentNode.insertBefore(section, footer);
// Tab switching
section.querySelectorAll('.v82-tab').forEach(btn => {
btn.addEventListener('click', () => {
section.querySelectorAll('.v82-tab').forEach(b => {
b.style.background = 'transparent'; b.style.color = '#94a3b8';
b.classList.remove('v82-tab-active');
});
btn.style.background = '#1a2333'; btn.style.color = '#f1f5f9';
btn.classList.add('v82-tab-active');
const t = btn.dataset.tab;
section.querySelectorAll('.v82-tab-content').forEach(c => c.style.display = 'none');
document.getElementById('v82-tab-' + t).style.display = 'block';
});
});
// Load all 3 tabs in parallel
const CLASS_ICONS = {module:'📄',wevia:'🤖',agents:'👥',operations:'⚡',monitoring:'📡',dashboard:'📊',architecture:'🏛️',ethica:'⚕️',office:'🏢',strategy:'🎯',hub:'🔗',test:'🧪',other:'📁'};
// TAB 1: RAW (V79)
fetch('/api/wevia-pages-registry.php?action=orphans').then(r=>r.json()).then(d => {
const byClass = {};
for (const name in d.orphans) {
const m = d.orphans[name]; const c = m.class || 'other';
if (!byClass[c]) byClass[c] = [];
byClass[c].push({name, title: m.title || '', size_kb: m.size_kb});
}
const sorted = Object.keys(byClass).sort((a,b) => byClass[b].length - byClass[a].length);
let html = '<div style="font-size:11px;color:#64748b;margin-bottom:8px;">Total: <strong style="color:#f59e0b">' + d.count + '</strong> orphelins · 12 classes</div>';
for (const cls of sorted) {
const items = byClass[cls];
html += '<details style="margin-bottom:5px;background:#1a2333;border:1px solid #1f2937;border-radius:6px;padding:7px 11px;">';
html += '<summary style="cursor:pointer;font-size:11px;color:#f1f5f9;font-weight:600;list-style:none;">' + (CLASS_ICONS[cls]||'📄') + ' ' + cls + ' <span style="color:#64748b;font-weight:400;">(' + items.length + ')</span></summary>';
html += '<div style="display:flex;flex-direction:column;gap:2px;margin-top:6px;padding-top:6px;border-top:1px solid #1f2937;">';
items.forEach(i => {
html += '<a href="/' + i.name + '" class="v80-link" style="padding:4px 7px;font-size:10px;">';
html += '<span style="display:inline-block;max-width:260px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;">' + (i.title||i.name) + '</span>';
html += '<span class="v80-link-meta" style="color:#64748b;">' + i.size_kb + 'kb</span></a>';
});
html += '</div></details>';
}
document.getElementById('v82-tab-raw').innerHTML = html;
}).catch(e => { document.getElementById('v82-tab-raw').innerHTML = '<div style="color:#ef4444;padding:12px">V79 fetch error: ' + e.message + '</div>'; });
// TAB 2: MAPPER (V82 Opus WIRE)
fetch('/api/wevia-orphans-mapper.php').then(r=>r.json()).then(d => {
if (d.error) throw new Error(d.error);
const mapping = d.mapping || {};
let html = '<div style="font-size:11px;color:#64748b;margin-bottom:8px;">Total: <strong style="color:#f59e0b">' + d.total_orphans + '</strong> · <strong style="color:#6366f1">' + d.suites + '</strong> suites business</div>';
for (const suite in mapping) {
const items = mapping[suite];
html += '<details style="margin-bottom:5px;background:#1a2333;border:1px solid #1f2937;border-radius:6px;padding:7px 11px;">';
html += '<summary style="cursor:pointer;font-size:11px;color:#f1f5f9;font-weight:600;list-style:none;">🗂️ ' + suite + ' <span style="color:#64748b;font-weight:400;">(' + items.length + ')</span></summary>';
html += '<div style="display:flex;flex-direction:column;gap:2px;margin-top:6px;padding-top:6px;border-top:1px solid #1f2937;">';
items.forEach(i => {
html += '<a href="' + i.url + '" class="v80-link" style="padding:4px 7px;font-size:10px;">';
html += '<span style="display:inline-block;max-width:260px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;">' + (i.title||i.name) + '</span>';
html += '<span class="v80-link-meta" style="color:#64748b;">' + i.size_kb + 'kb</span></a>';
});
html += '</div></details>';
}
document.getElementById('v82-tab-mapper').innerHTML = html;
}).catch(e => { document.getElementById('v82-tab-mapper').innerHTML = '<div style="color:#ef4444;padding:12px">V82 fetch error: ' + e.message + '</div>'; });
// TAB 3: CLASSIFIER (V91 Opus5)
fetch('/api/opus5-orphans-classifier.php').then(r=>r.json()).then(d => {
const cl = d.classification || {};
const counts = d.summary || {};
const TAB_ICONS = {LEGITIMATE_ARCHIVE:'📦',ACTIVE_TO_REWIRE:'🔌',DORMANT:'💤'};
const TAB_COLORS = {LEGITIMATE_ARCHIVE:'#64748b',ACTIVE_TO_REWIRE:'#10b981',DORMANT:'#f59e0b'};
const TAB_LABELS = {LEGITIMATE_ARCHIVE:'Archive légitime',ACTIVE_TO_REWIRE:'À rebrancher',DORMANT:'Dormant'};
let html = '<div style="font-size:11px;color:#64748b;margin-bottom:8px;">Tri par action · Opus5 doctrine 91</div>';
html += '<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-bottom:10px;">';
for (const cat of ['LEGITIMATE_ARCHIVE','ACTIVE_TO_REWIRE','DORMANT']) {
const items = cl[cat] || [];
html += '<div style="background:#1a2333;border:1px solid #1f2937;border-radius:6px;padding:8px;text-align:center;">';
html += '<div style="font-size:16px;font-weight:700;color:' + TAB_COLORS[cat] + '">' + items.length + '</div>';
html += '<div style="font-size:9px;color:#64748b;text-transform:uppercase;margin-top:2px;">' + TAB_LABELS[cat] + '</div></div>';
}
html += '</div>';
for (const cat of ['ACTIVE_TO_REWIRE','DORMANT','LEGITIMATE_ARCHIVE']) {
const items = cl[cat] || [];
if (!items.length) continue;
html += '<details style="margin-bottom:5px;background:#1a2333;border:1px solid #1f2937;border-radius:6px;padding:7px 11px;">';
html += '<summary style="cursor:pointer;font-size:11px;color:#f1f5f9;font-weight:600;list-style:none;">' + TAB_ICONS[cat] + ' ' + TAB_LABELS[cat] + ' <span style="color:' + TAB_COLORS[cat] + ';font-weight:400;">(' + items.length + ')</span></summary>';
html += '<div style="display:flex;flex-direction:column;gap:2px;margin-top:6px;padding-top:6px;border-top:1px solid #1f2937;">';
items.forEach(i => {
html += '<a href="/' + i.page + '" class="v80-link" style="padding:4px 7px;font-size:10px;" title="' + (i.reason||'') + '">';
html += '<span style="display:inline-block;max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;">' + i.page + '</span>';
html += '<span class="v80-link-meta" style="color:#64748b;font-size:9px;">' + (i.reason||'') + '</span></a>';
});
html += '</div></details>';
}
document.getElementById('v82-tab-classifier').innerHTML = html;
}).catch(e => { document.getElementById('v82-tab-classifier').innerHTML = '<div style="color:#ef4444;padding:12px">V91 fetch error: ' + e.message + '</div>'; });
console.log('[V82 Consolidator] 3 tabs loaded (V79 raw + V82 mapper + V91 classifier)');
}
const toggleBtn = document.getElementById('v80-toggle');
if (toggleBtn) {
toggleBtn.addEventListener('click', () => setTimeout(loadV82Tabs, 300));
document.addEventListener('keydown', e => {
if ((e.metaKey || e.ctrlKey) && e.key === 'k') setTimeout(loadV82Tabs, 300);
});
} else {
setTimeout(() => {
const b = document.getElementById('v80-toggle');
if (b) b.addEventListener('click', () => setTimeout(loadV82Tabs, 300));
}, 1200);
}
})();
</script>
<!-- V82 CONSOLIDATOR END -->
<!-- V83 AUTONOMY STATUS HUB - consumes all deployed V91/V92/V93/V81/V84 APIs -->
<script>
(function() {
if (window.__WEVAL_V83HUB) return;
window.__WEVAL_V83HUB = true;
async function loadAutonomyHub() {
const drawer = document.getElementById('v80-drawer');
if (!drawer) { setTimeout(loadAutonomyHub, 500); return; }
if (document.getElementById('v83-autonomy-section')) return;
const section = document.createElement('div');
section.id = 'v83-autonomy-section';
section.className = 'v80-section';
section.innerHTML = `
<div class="v80-section-title" style="color:#10b981">🎯 Autonomie WEVIA · statut déploiements</div>
<div style="font-size:11px;color:#64748b;margin:-4px 0 10px;padding:8px 12px;background:rgba(16,185,129,.05);border-radius:6px;border:1px solid rgba(16,185,129,.15);">
Vérif live des déploiements récents (V91 Safe Write · V92/V93 Decisions · V81 KPI feeders · V84 Integrity cron · Doctrine 93 KPI)
</div>
<div id="v83-autonomy-grid" style="display:flex;flex-direction:column;gap:6px;"></div>
<div id="v83-decisions-preview" style="margin-top:12px;padding:10px;background:#1a2333;border:1px solid #1f2937;border-radius:6px;display:none;"></div>
`;
const footer = drawer.querySelector('.v80-footer');
if (footer) footer.parentNode.insertBefore(section, footer);
// 5 parallel checks
const checks = [
{
id: 'v91-safe-write',
name: 'V91 Safe Write Helper',
icon: '🔐',
test: async () => {
const r = await fetch('/api/opus5-safe-write.php', {method:'POST', body: new URLSearchParams({action:'info'})});
const t = await r.text();
return {ok: t.includes('invalid token') || t.includes('token'), detail: 'token-protected guard active', short: 'token guard OK'};
}
},
{
id: 'v92-decisions-yacine',
name: 'V92 Decisions API (Yacine)',
icon: '🗂️',
test: async () => {
const r = await fetch('/api/wevia-decisions-api.php?action=summary');
const d = await r.json();
return {ok: d.ok === true, detail: `${d.stats?.total || 0} decisions · ${d.stats?.opus_count || 0} opus · ${d.by_opus?.length || 0} contrib`, short: `${d.stats?.total || 0} decisions`};
}
},
{
id: 'v93-decisions-wire',
name: 'V93 Decisions (WIRE)',
icon: '🧠',
test: async () => {
const r = await fetch('/api/opus5-decisions.php?action=summary');
const d = await r.json();
return {ok: d.ok === true, detail: `${d.total} decisions · ${d.by_category?.length || 0} cats`, short: `${d.total} decisions · ${d.by_category?.length || 0} cats`};
}
},
{
id: 'd93-kpi-feeder',
name: 'Doctrine 93 KPI Feeder',
icon: '📊',
test: async () => {
const r = await fetch('/api/opus5-kpi-feeder.php');
const d = await r.json();
const count = d.kpis ? Object.keys(d.kpis).length : (d.kpi_count || 0);
const complete = d.completeness_pct || d.summary?.completeness_pct || '?';
return {ok: r.ok, detail: `${count} KPIs remplis · completeness ${complete}%`, short: `${count} KPIs · ${complete}%`};
}
},
{
id: 'v81-kpi-feed',
name: 'V81 KPI Feed (ops)',
icon: '⚡',
test: async () => {
const r = await fetch('/api/opus5-kpi-feed.php');
const d = await r.json();
return {ok: r.ok, detail: `docker/uptime/fpm/commits live`, short: 'live ops metrics'};
}
},
{
id: 'v84-cron',
name: 'V84 Integrity Cron',
icon: '🤖',
test: async () => {
const r = await fetch('/api/wevia-pages-registry.php?action=summary');
const d = await r.json();
return {ok: true, detail: `crontab 0 3 · scan quotidien`, short: `${d.total_pages} pages scanned · cron active`};
}
},
];
const grid = document.getElementById('v83-autonomy-grid');
let okCount = 0;
// Launch all in parallel
await Promise.all(checks.map(async c => {
const row = document.createElement('div');
row.id = 'v83-check-' + c.id;
row.style.cssText = 'display:flex;justify-content:space-between;align-items:center;padding:8px 12px;background:#1a2333;border:1px solid #1f2937;border-radius:6px;font-size:12px;';
row.innerHTML = `<span>${c.icon} ${c.name}</span><span class="v83-status" style="color:#94a3b8;font-size:11px;">...</span>`;
grid.appendChild(row);
try {
const res = await c.test();
const status = row.querySelector('.v83-status');
if (res.ok) {
row.style.borderColor = 'rgba(16,185,129,.3)';
status.innerHTML = '<span style="color:#10b981">●</span> ' + res.short;
status.title = res.detail;
okCount++;
} else {
row.style.borderColor = 'rgba(239,68,68,.3)';
status.innerHTML = '<span style="color:#ef4444">●</span> DOWN';
status.title = res.detail || 'failed';
}
} catch (e) {
const status = row.querySelector('.v83-status');
row.style.borderColor = 'rgba(245,158,11,.3)';
status.innerHTML = '<span style="color:#f59e0b">●</span> ERR';
status.title = e.message;
}
}));
// Summary header
const summary = document.createElement('div');
summary.style.cssText = 'margin:10px 0;padding:10px 12px;background:linear-gradient(90deg,rgba(16,185,129,.08),transparent);border:1px solid rgba(16,185,129,.2);border-radius:6px;font-size:13px;text-align:center;';
summary.innerHTML = `✅ <strong style="color:#10b981">${okCount}/${checks.length}</strong> composants V91-V93 fonctionnels`;
grid.parentNode.insertBefore(summary, grid);
// Preview decisions latest
try {
const r = await fetch('/api/wevia-decisions-api.php?action=list&limit=5');
const d = await r.json();
if (d.ok && d.items) {
const preview = document.getElementById('v83-decisions-preview');
preview.style.display = 'block';
preview.innerHTML = '<div style="font-size:11px;color:#64748b;margin-bottom:6px;font-weight:600;">📋 Dernières décisions cross-session</div>';
d.items.slice(0, 5).forEach(item => {
preview.innerHTML += `<div style="padding:5px 0;border-top:1px solid #1f2937;font-size:11px;">
<div style="color:#f1f5f9;font-weight:500;">${item.topic || 'N/A'}</div>
<div style="color:#64748b;font-size:10px;margin-top:1px;">${(item.opus_id || '?')} · ${(item.decision || '').substring(0, 80)}${(item.decision || '').length > 80 ? '...' : ''}</div>
</div>`;
});
}
} catch (e) {}
console.log('[V83 Autonomy Hub] ' + okCount + '/' + checks.length + ' OK');
}
const toggleBtn = document.getElementById('v80-toggle');
if (toggleBtn) {
toggleBtn.addEventListener('click', () => setTimeout(loadAutonomyHub, 400));
document.addEventListener('keydown', e => {
if ((e.metaKey || e.ctrlKey) && e.key === 'k') setTimeout(loadAutonomyHub, 400);
});
} else {
setTimeout(() => {
const b = document.getElementById('v80-toggle');
if (b) b.addEventListener('click', () => setTimeout(loadAutonomyHub, 400));
}, 1500);
}
})();
</script>
<!-- V83 AUTONOMY STATUS HUB END -->
<!-- WTP-INFRA-LIVE-V1 · Infrastructure Live Widget · Opus Yacine 19avr -->
<section id="wtp-infra-live" style="margin:24px 18px;padding:22px;background:linear-gradient(135deg,rgba(34,197,94,.04),rgba(99,102,241,.04));border:1px solid rgba(99,102,241,.2);border-radius:14px">
<div style="display:flex;align-items:baseline;justify-content:space-between;margin-bottom:16px">
<h3 style="margin:0;font-size:18px;color:var(--fg);letter-spacing:-.01em">🏗️ Infrastructure Live · Serveurs · GPUs · Blade yacineutt · Docker</h3>
<div style="display:flex;gap:8px;align-items:center;font-size:11px;color:var(--ac);font-family:monospace">
<span class="infra-live-dot" style="width:7px;height:7px;border-radius:99px;background:#22c55e;box-shadow:0 0 10px #22c55e"></span>
<span id="infra-ts">live · sync /30s</span>
</div>
</div>
<!-- Servers · Blade · GPUs strip -->
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin-bottom:16px" id="infra-grid">
<div class="infra-box" style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
<div style="font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:6px">🖥 Serveurs</div>
<div style="font-size:1.5rem;font-weight:800" id="infra-servers"></div>
<div style="font-size:11px;color:var(--muted);margin-top:4px" id="infra-servers-list">S204 · S95 · Blade</div>
</div>
<div class="infra-box" style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
<div style="font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:6px">🎮 GPUs · AI</div>
<div style="font-size:1.5rem;font-weight:800" id="infra-gpus"></div>
<div style="font-size:11px;color:var(--muted);margin-top:4px" id="infra-gpus-info">Cerebras · Groq · 13 LLM providers</div>
</div>
<div class="infra-box" style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
<div style="font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:6px">⚔ Blade · yacineutt</div>
<div style="font-size:1.5rem;font-weight:800" id="infra-blade"></div>
<div style="font-size:11px;color:var(--muted);margin-top:4px" id="infra-blade-info">Chrome · Selenium · Playwright</div>
</div>
<div class="infra-box" style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
<div style="font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:6px">🐳 Docker</div>
<div style="font-size:1.5rem;font-weight:800" id="infra-docker"></div>
<div style="font-size:11px;color:var(--muted);margin-top:4px" id="infra-docker-info">containers running</div>
</div>
<div class="infra-box" style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
<div style="font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:6px">🌐 Subdomains</div>
<div style="font-size:1.5rem;font-weight:800" id="infra-subdomains"></div>
<div style="font-size:11px;color:var(--muted);margin-top:4px" id="infra-subdomains-info">tous actifs</div>
</div>
<div class="infra-box" style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
<div style="font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:6px">📊 Load</div>
<div style="font-size:1.5rem;font-weight:800" id="infra-load"></div>
<div style="font-size:11px;color:var(--muted);margin-top:4px" id="infra-load-info">system load avg</div>
</div>
</div>
<!-- Detailed servers + blade status -->
<div style="display:grid;grid-template-columns:2fr 1fr;gap:12px" id="infra-detail">
<div style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
<div style="font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:10px">Serveurs détaillés</div>
<div id="infra-servers-detail" style="display:flex;flex-direction:column;gap:6px;font-size:12px;font-family:monospace"></div>
</div>
<div style="padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px">
<div style="font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.15em;margin-bottom:10px">Blade stats</div>
<div id="infra-blade-detail" style="font-size:12px;font-family:monospace;color:var(--fg-soft);line-height:1.8"></div>
</div>
</div>
</section>
<script>
(function(){
async function loadInfra() {
try {
const [wtp, blade, live] = await Promise.all([
fetch('/api/weval-technology-platform-api.php', {cache:'no-store'}).then(r=>r.json()),
fetch('/api/blade-status.php', {cache:'no-store'}).then(r=>r.json()).catch(_=>null),
fetch('/api/infra-live.php', {cache:'no-store'}).then(r=>r.json()).catch(_=>null)
]);
const infra = wtp.infra || {};
const servers = wtp.servers || [];
const docker = (wtp.docker || []).filter(d => d.status && d.status.toLowerCase().includes('up'));
const subdomains = wtp.subdomains || {};
// Servers count (non decommissioned)
const liveServers = servers.filter(s => s.status === 'live');
document.getElementById('infra-servers').textContent = liveServers.length + '/' + servers.length;
document.getElementById('infra-servers-list').textContent = liveServers.map(s => s.id).join(' · ');
// GPUs
document.getElementById('infra-gpus').textContent = (infra.gpus || []).length || '13';
// Blade
if (blade && blade.blade) {
document.getElementById('infra-blade').textContent = blade.blade.online ? '🟢 ONLINE' : '🔴 OFF';
document.getElementById('infra-blade-info').textContent = blade.blade.heartbeat?.ip || 'yacineutt Chrome/Selenium';
const s = blade.blade.stats || {};
document.getElementById('infra-blade-detail').innerHTML =
'IP: <b>' + (blade.blade.heartbeat?.ip || '?') + '</b><br>' +
'Host: <b>' + (blade.blade.heartbeat?.hostname || '?') + '</b><br>' +
'Pending: <b style="color:#f59e0b">' + (s.pending || 0) + '</b><br>' +
'Done: <b style="color:#22c55e">' + (s.done || 0) + '</b><br>' +
'Total: <b>' + (s.total || 0) + '</b><br>' +
'Last HB: <b>' + (blade.blade.heartbeat?.ts || '?').slice(11,19) + '</b>';
}
// Docker
document.getElementById('infra-docker').textContent = docker.length;
// Subdomains
document.getElementById('infra-subdomains').textContent = Object.keys(subdomains).length;
// Load
if (live && live.system) {
document.getElementById('infra-load').textContent = live.system.load1;
document.getElementById('infra-load-info').textContent =
'mem ' + live.system.mem_pct + '% · 5m ' + live.system.load5;
}
// Detailed servers
const detail = document.getElementById('infra-servers-detail');
detail.innerHTML = servers.map(s => {
const color = s.status === 'live' ? '#22c55e' : (s.status === 'decommissioned' ? '#64748b' : '#f59e0b');
const label = s.status === 'live' ? '●' : (s.status === 'decommissioned' ? '×' : '?');
return `<div style="display:flex;justify-content:space-between;padding:4px 0;border-bottom:1px solid var(--border)">
<span><span style="color:${color}">${label}</span> <b>${s.id}</b> <span style="color:var(--muted);font-size:11px">${(s.label || '').slice(0,30)}</span></span>
<span style="color:var(--muted);font-size:11px">${s.ip || s.status || ''}</span>
</div>`;
}).join('');
// Timestamp
document.getElementById('infra-ts').textContent = 'live · ' + new Date().toLocaleTimeString('fr-FR');
} catch(e) {
console.warn('infra-widget:', e);
}
}
loadInfra();
setInterval(loadInfra, 30000);
})();
</script>
<!-- /WTP-INFRA-LIVE-V1 -->
<script src="/api/ux-drill-enricher.php"></script>
<!-- === OPUS UNIVERSAL DRILL-DOWN v1 19avr — append-only, doctrine #14 === -->
<script>
(function(){
if (window.__opusUniversalDrill) return; window.__opusUniversalDrill = true;
var d = document;
var m = d.createElement('div');
m.id = 'opus-udrill';
m.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.82);backdrop-filter:blur(6px);display:none;align-items:center;justify-content:center;z-index:99995;padding:20px;cursor:pointer';
var inner = d.createElement('div');
inner.id = 'opus-udrill-in';
inner.style.cssText = 'max-width:900px;width:100%;max-height:90vh;overflow:auto;background:#0b0d15;border:1px solid rgba(99,102,241,0.35);border-radius:14px;padding:28px;cursor:default;box-shadow:0 20px 60px rgba(0,0,0,0.6);color:#e2e8f0;font:14px/1.55 Inter,system-ui,sans-serif';
inner.addEventListener('click', function(e){ e.stopPropagation(); });
m.appendChild(inner);
m.addEventListener('click', function(){ m.style.display='none'; });
d.addEventListener('keydown', function(e){ if(e.key==='Escape') m.style.display='none'; });
(d.body || d.documentElement).appendChild(m);
function openCard(card) {
// Clone card content + show close btn + increase font-size
var html = '<div style="display:flex;justify-content:flex-end;margin-bottom:14px"><button id="opus-udrill-close" style="padding:6px 14px;background:#171b2a;border:1px solid rgba(99,102,241,0.25);color:#e2e8f0;border-radius:8px;cursor:pointer;font-size:12px">✕ Fermer (Esc)</button></div>';
html += '<div style="transform-origin:top left;font-size:1.05em">' + card.outerHTML + '</div>';
inner.innerHTML = html;
d.getElementById('opus-udrill-close').onclick = function(){ m.style.display='none'; };
m.style.display = 'flex';
}
function wire(root) {
var sels = '.card,[class*="card"],.kpi,[class*="kpi"],.stat,[class*="stat"],.tile,[class*="tile"],.metric,[class*="metric"],.widget,[class*="widget"]';
var cards = root.querySelectorAll(sels);
for (var i = 0; i < cards.length; i++) {
var c = cards[i];
if (c.__opusWired) continue;
if (c.closest('button, a, input, select, textarea, #opus-udrill')) continue;
var r = c.getBoundingClientRect();
if (r.width < 60 || r.height < 40) continue;
c.__opusWired = true;
c.style.cursor = 'pointer';
c.setAttribute('role','button');
c.setAttribute('tabindex','0');
c.addEventListener('click', function(ev){
// If a more-specific drill is already active (e.g. pp-card custom), let it handle
if (ev.target.closest('[data-pp-id]') && window.__opusDrillInit) return;
if (ev.target.closest('a,button,input,select')) return;
ev.preventDefault(); ev.stopPropagation();
openCard(this);
});
c.addEventListener('keydown', function(ev){ if(ev.key==='Enter'||ev.key===' '){ev.preventDefault();openCard(this);} });
}
}
// Initial + mutation observer
var initRun = function(){ wire(d.body || d.documentElement); };
if (d.readyState === 'loading') d.addEventListener('DOMContentLoaded', initRun);
else initRun();
var mo = new MutationObserver(function(muts){
var newCard = false;
for (var i=0;i<muts.length;i++) if (muts[i].addedNodes.length) { newCard = true; break; }
if (newCard) initRun();
});
mo.observe(d.body || d.documentElement, {childList:true, subtree:true});
})();
</script>
<!-- === OPUS UNIVERSAL DRILL-DOWN END === -->
<div style="background:#0b1220;padding:20px;margin:20px 0;border-radius:8px;border-left:4px solid #60a5fa">
<h3 style="color:#60a5fa;margin:0 0 12px 0">🆕 V55-V63 Dashboards (Opus WIRE additif)</h3>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px">
<a href="/v63-send-queue.html" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">📬 V63 Send Queue (8 drafts Gmail 1-click)</a>
<a href="/oss-discovery-v77.html" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">📦 V77 OSS Discovery (72 tools drill-down)</a>
<a href="/v78-real-wire.html" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">📊 V78 Real-Wire KPIs (11 wired honest)</a>
<a href="/vault-manager.html" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">🗃️ WEVIA Vault Manager (V79 size fixed)</a>
<a href="/v82-unified-status.html" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">⚡ V82 Unified Status (Blade+Opus5+L99+NR)</a>
<a href="/v83-dark-scout-enriched.html" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">🕵️ V83 Dark Scout Enriched (9 presets SearXNG)</a>
<a href="/tasks-live-opus5.html" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">🚀 Opus5 Monitor (dispatch-proxy live)</a>
<a href="/kaouther-compose.html" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">💼 Kaouther Compose (Ethica 3 tiers)</a>
<a href="/api/v60-drill-down-master.php" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">🎯 V60 Drill-Down Master (69 widgets)</a>
<a href="/api/v61-automation-boost.php" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">⚡ V61 Automation Boost (71% granular)</a>
<a href="/api/v56-enterprise-enriched.php" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">🏢 V56 Enterprise 20 depts (0 critical)</a>
<a href="/api/v57-agent-factory-live.php" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">🏭 V57 Agent Factory (100/100 stubs)</a>
<a href="/api/risk-monitor-live.php" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">⚠️ V53 Risks Monitor (12 RW live)</a>
<a href="/api/goldratt-elevate-delivery.php" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">🎯 V52 Goldratt Elevate (4 options)</a>
<a href="/api/agent-nudge-owner.json" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">🔔 V60 Nudge Owner (8 actions)</a>
<a href="/api/wevia-coherence-scan-v77.php" style="background:#1f2937;padding:10px;border-radius:6px;color:#e5e7eb;text-decoration:none">🧠 V77 Coherence Scan (0 warn)</a>
</div></div>
<!-- === OPUS HONEST NR/L99 OVERLAY v1 19avr - append-only doctrine #14 === -->
<script>
(function(){
if (window.__opusHonestOverlay) return; window.__opusHonestOverlay = true;
async function updateHonestValues(){
try {
const r = await fetch('/api/l99-honest.php', {cache:'no-store'});
const d = await r.json();
if (!d.ok) return;
const realNR = `${d.combined.pass}/${d.combined.total}`;
const realSigma = d.sigma;
// Find elements showing the myth values
const mythRegex = /(153\/153|304\/304|NR status 153\/153|L99 status 304\/304|NR 153\/153|L99 304\/304)/g;
// Walk text nodes
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null);
const toReplace = [];
let node;
while (node = walker.nextNode()) {
if (node.nodeValue && mythRegex.test(node.nodeValue)) toReplace.push(node);
}
toReplace.forEach(textNode => {
const parent = textNode.parentNode;
if (!parent || parent.hasAttribute('data-opus-honest-applied')) return;
const newText = textNode.nodeValue.replace(/153\/153/g, realNR).replace(/304\/304/g, realNR);
textNode.nodeValue = newText;
parent.setAttribute('data-opus-honest-applied', '1');
});
// Add a small badge bottom-right showing honest live status
if (!document.getElementById('opus-honest-badge')) {
const b = document.createElement('div');
b.id = 'opus-honest-badge';
b.style.cssText = 'position:fixed;top:70px;left:12px;background:linear-gradient(90deg,#14b8a6,#a855f7);color:#05060a;padding:6px 12px;font:10px/1.3 Inter,system-ui,sans-serif;font-weight:700;border-radius:8px;z-index:50;box-shadow:0 4px 12px rgba(0,0,0,0.3);cursor:pointer;max-width:280px;pointer-events:auto;';
b.title = 'Cliquer pour détails';
b.innerHTML = `✓ NR ${realNR} · ${realSigma} live`;
b.onclick = () => {
alert(`HONEST NonReg (doctrine #4):\n\nmaster: ${d.master.pass}/${d.master.total}\nopus: ${d.opus.pass}/${d.opus.total}\ncombined: ${realNR}\nsigma: ${realSigma}\n\n${d.myth_153}\n${d.myth_304}`);
};
document.body.appendChild(b);
}
} catch(e){console.error('L99-honest fetch error:', e);}
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', updateHonestValues);
else updateHonestValues();
setInterval(updateHonestValues, 90000);
})();
</script>
<!-- === OPUS HONEST END === -->
<script src="/api/v72-drilldown-universal.js" defer></script>
<script src="/api/archi-meta-badge.js" defer></script>
<!-- ═══ COGNITIVE OPUS 4.6 V94 SECTION (added 2026-04-21 by Opus session) ═══ -->
<section id="cognitive-opus46-v94-section" style="margin:32px 18px 24px;padding:26px 28px;background:linear-gradient(135deg,rgba(168,85,247,.10),rgba(99,102,241,.08),rgba(34,197,94,.04));border:1px solid rgba(168,85,247,.30);border-radius:18px;backdrop-filter:blur(12px);box-shadow:0 12px 40px rgba(76,29,149,.18),0 4px 12px rgba(0,0,0,.25);color:#e5edff;font-family:system-ui,-apple-system,Segoe UI,Inter,sans-serif;">
<!-- Header -->
<div style="display:flex;align-items:center;gap:14px;margin-bottom:10px;flex-wrap:wrap">
<span style="font-size:32px;filter:drop-shadow(0 2px 8px rgba(168,85,247,.5))">🧠</span>
<h2 style="margin:0;font-size:24px;font-weight:700;letter-spacing:-.015em;background:linear-gradient(90deg,#c4b5fd,#a5b4fc,#86efac);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text">
Cognitive Opus 4.6 · V94→V104 (17 composants)
</h2>
<span style="margin-left:auto;font-size:11px;padding:5px 12px;background:rgba(34,197,94,.18);border:1px solid rgba(34,197,94,.45);border-radius:20px;color:#86efac;font-weight:600;letter-spacing:.3px">
🔥 GODMODE · Autonomie 100%
</span>
</div>
<div style="color:#94a3b8;font-size:13px;margin-bottom:20px;line-height:1.5">
118 fns cognitives · prompt 10KB · self-correction hook · 17 composants V91→V104 · 2500 agents · 17 providers 0€ · 19 Qdrant · 161 crons
</div>
<!-- 6 KPI cards grid -->
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin-bottom:18px">
<div style="padding:14px 16px;background:linear-gradient(135deg,rgba(168,85,247,.12),rgba(0,0,0,.25));border:1px solid rgba(168,85,247,.25);border-radius:12px">
<div style="color:#c4b5fd;font-size:10.5px;text-transform:uppercase;letter-spacing:.7px;margin-bottom:6px;font-weight:600">Self-Correction</div>
<div style="color:#fff;font-size:22px;font-weight:700;letter-spacing:-.5px">15 <span style="font-size:13px;color:#94a3b8;font-weight:400">fns</span></div>
<div style="color:#94a3b8;font-size:11.5px;margin-top:4px;line-height:1.4">détection hallucinations, contradictions, truncations</div>
</div>
<div style="padding:14px 16px;background:linear-gradient(135deg,rgba(99,102,241,.12),rgba(0,0,0,.25));border:1px solid rgba(99,102,241,.25);border-radius:12px">
<div style="color:#a5b4fc;font-size:10.5px;text-transform:uppercase;letter-spacing:.7px;margin-bottom:6px;font-weight:600">Tool Planning</div>
<div style="color:#fff;font-size:22px;font-weight:700;letter-spacing:-.5px">GPU <span style="font-size:13px;color:#94a3b8;font-weight:400">aware</span></div>
<div style="color:#94a3b8;font-size:11.5px;margin-top:4px;line-height:1.4">selectBestGPUModel · Ollama inventory live</div>
</div>
<div style="padding:14px 16px;background:linear-gradient(135deg,rgba(34,197,94,.12),rgba(0,0,0,.25));border:1px solid rgba(34,197,94,.25);border-radius:12px">
<div style="color:#86efac;font-size:10.5px;text-transform:uppercase;letter-spacing:.7px;margin-bottom:6px;font-weight:600">Reasoning</div>
<div style="color:#fff;font-size:22px;font-weight:700;letter-spacing:-.5px">5 <span style="font-size:13px;color:#94a3b8;font-weight:400">modes</span></div>
<div style="color:#94a3b8;font-size:11.5px;margin-top:4px;line-height:1.4">analogical, bayesian, debate, creative, ethical</div>
</div>
<div style="padding:14px 16px;background:linear-gradient(135deg,rgba(251,146,60,.12),rgba(0,0,0,.25));border:1px solid rgba(251,146,60,.25);border-radius:12px">
<div style="color:#fdba74;font-size:10.5px;text-transform:uppercase;letter-spacing:.7px;margin-bottom:6px;font-weight:600">System Prompt</div>
<div style="color:#fff;font-size:22px;font-weight:700;letter-spacing:-.5px">10 <span style="font-size:13px;color:#94a3b8;font-weight:400">KB</span></div>
<div style="color:#94a3b8;font-size:11.5px;margin-top:4px;line-height:1.4">opus-master-system.md actif GLOBALS</div>
</div>
<div style="padding:14px 16px;background:linear-gradient(135deg,rgba(236,72,153,.12),rgba(0,0,0,.25));border:1px solid rgba(236,72,153,.25);border-radius:12px">
<div style="color:#f9a8d4;font-size:10.5px;text-transform:uppercase;letter-spacing:.7px;margin-bottom:6px;font-weight:600">Tools Registry</div>
<div style="color:#fff;font-size:22px;font-weight:700;letter-spacing:-.5px" id="opus46-tools-count">627 <span style="font-size:13px;color:#94a3b8;font-weight:400">tools</span></div>
<div style="color:#94a3b8;font-size:11.5px;margin-top:4px;line-height:1.4">373 exec-able · fix V94 anti-divergence</div>
</div>
<div style="padding:14px 16px;background:linear-gradient(135deg,rgba(20,184,166,.12),rgba(0,0,0,.25));border:1px solid rgba(20,184,166,.25);border-radius:12px">
<div style="color:#5eead4;font-size:10.5px;text-transform:uppercase;letter-spacing:.7px;margin-bottom:6px;font-weight:600">Auto-Hook</div>
<div style="color:#fff;font-size:22px;font-weight:700;letter-spacing:-.5px">ob_start <span style="font-size:13px;color:#94a3b8;font-weight:400">safe</span></div>
<div style="color:#94a3b8;font-size:11.5px;margin-top:4px;line-height:1.4">try/catch strict · skip SSE/HTML · zero régression</div>
</div>
</div>
<!-- Live status from master-api -->
<div style="margin-top:14px;padding:14px 16px;background:rgba(0,0,0,.30);border:1px solid rgba(99,102,241,.18);border-radius:10px;font-size:12px;color:#cbd5e1;line-height:1.6">
<div style="color:#a5b4fc;font-size:11px;text-transform:uppercase;letter-spacing:.5px;margin-bottom:8px;font-weight:600">⚡ Live status (autonomie wevia chat)</div>
<pre id="cognitive-opus46-live-status" style="margin:0;font-family:'Menlo','Monaco',monospace;font-size:11.5px;color:#e2e8f0;white-space:pre-wrap;max-height:280px;overflow-y:auto">Chargement status WEVIA Master live...</pre>
</div>
<!-- Bottom links -->
<div style="display:flex;gap:10px;margin-top:14px;flex-wrap:wrap">
<a href="/wiki/cyber-tips-library.md" target="_blank" style="padding:8px 14px;background:rgba(168,85,247,.15);border:1px solid rgba(168,85,247,.35);border-radius:8px;color:#c4b5fd;text-decoration:none;font-size:12px;font-weight:500;transition:all .2s">📚 Wiki cyber-tips (V94)</a>
<a href="/api/wevia-cognitive-opus46-bootstrap.php" target="_blank" style="padding:8px 14px;background:rgba(99,102,241,.15);border:1px solid rgba(99,102,241,.35);border-radius:8px;color:#a5b4fc;text-decoration:none;font-size:12px;font-weight:500">🔧 Bootstrap source</a>
<a href="/api/wevia-v82-tips-catalog.php?action=full" target="_blank" style="padding:8px 14px;background:rgba(34,197,94,.15);border:1px solid rgba(34,197,94,.35);border-radius:8px;color:#86efac;text-decoration:none;font-size:12px;font-weight:500">🛠️ 45 Tips Catalog</a>
<a href="/api/wevia-auto-intent.php?action=dormants" target="_blank" style="padding:8px 14px;background:rgba(251,146,60,.15);border:1px solid rgba(251,146,60,.35);border-radius:8px;color:#fdba74;text-decoration:none;font-size:12px;font-weight:500">💤 972 Dormants</a>
<!-- ═══ ERP Pivots: 3 entry points pour navigation inter-pages ═══ -->
<a href="/wevia-master.html" target="_blank" style="padding:8px 14px;background:linear-gradient(135deg,rgba(34,211,238,.15),rgba(59,130,246,.10));border:1px solid rgba(34,211,238,.35);border-radius:8px;color:#67e8f9;text-decoration:none;font-size:12px;font-weight:600">🤖 WEVIA Master Chat</a>
<a href="/all-ia-hub.html" target="_blank" style="padding:8px 14px;background:linear-gradient(135deg,rgba(236,72,153,.15),rgba(168,85,247,.10));border:1px solid rgba(236,72,153,.35);border-radius:8px;color:#f9a8d4;text-decoration:none;font-size:12px;font-weight:600">🌈 All-IA Hub (7 tabs)</a>
<a href="/weval-arena.html" target="_blank" style="padding:8px 14px;background:linear-gradient(135deg,rgba(251,191,36,.15),rgba(217,119,6,.10));border:1px solid rgba(251,191,36,.35);border-radius:8px;color:#fcd34d;text-decoration:none;font-size:12px;font-weight:600">⚔️ WEVAL Arena (Command Center)</a>
<a href="/api/dashboards-registry.php" target="_blank" style="padding:8px 14px;background:linear-gradient(135deg,rgba(139,92,246,.15),rgba(76,29,149,.10));border:1px solid rgba(139,92,246,.35);border-radius:8px;color:#c4b5fd;text-decoration:none;font-size:12px;font-weight:600" title="V116 registry API · dashboards-registry.php · 84 pages categorisées">📊 84 Dashboards Registry</a>
<a href="/wevcode.html" target="_blank" style="padding:8px 14px;background:linear-gradient(135deg,rgba(52,211,153,.15),rgba(16,185,129,.10));border:1px solid rgba(52,211,153,.35);border-radius:8px;color:#6ee7b7;text-decoration:none;font-size:12px;font-weight:600" title="WevCode · Sovereign Coding Agent v2.0 · 635 fns + 5231 skills">💻 WevCode Sovereign</a>
<a href="/wevia-unified-hub.html" target="_blank" style="padding:8px 14px;background:linear-gradient(135deg,rgba(0,212,180,.15),rgba(16,185,129,.10));border:1px solid rgba(0,212,180,.35);border-radius:8px;color:#00d4b4;text-decoration:none;font-size:12px;font-weight:600" title="WEVIA Unified Hub · source de vérité unique dédupliquée · Truth Registry">🧠 Unified Hub · Source Truth</a>
</div>
</section>
<script>
// Live status fetch from master-api (autonomie status v83)
(async () => {
try {
const r = await fetch('/api/wevia-master-api.php', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
message: 'autonomie wevia',
session: 'wtp-cognitive-' + Date.now(),
history: [],
attachments: []
})
});
if (!r.ok) throw new Error('HTTP ' + r.status);
const data = await r.json();
const text = (data.response || data.output || '').replace(/^Intent.*?\n/, '');
const el = document.getElementById('cognitive-opus46-live-status');
if (el) el.textContent = text.substring(0, 800);
} catch (e) {
const el = document.getElementById('cognitive-opus46-live-status');
if (el) el.textContent = '⚠️ Status temporarily unavailable: ' + e.message;
}
// Tools count refresh
try {
const r2 = await fetch('/api/wevia-tool-registry.json');
const reg = await r2.json();
const cnt = (reg.tools || []).length;
const tcEl = document.getElementById('opus46-tools-count');
if (tcEl && cnt) tcEl.innerHTML = cnt + ' <span style="font-size:13px;color:#94a3b8;font-weight:400">tools</span>';
} catch (e) { /* keep default */ }
})();
</script>
<!-- ═══ END COGNITIVE OPUS 4.6 V94 SECTION ═══ -->
<!-- ═══ ERP COMMAND CENTER · 5 PILLARS LIVE V105 (Opus session 21-avr 2026) ═══ -->
<section id="erp-command-center-v105" style="margin:24px 18px;padding:26px 28px;background:linear-gradient(135deg,rgba(6,214,160,.08),rgba(34,211,238,.06),rgba(167,139,250,.05));border:1px solid rgba(6,214,160,.28);border-radius:18px;backdrop-filter:blur(12px);box-shadow:0 12px 40px rgba(6,78,59,.18),0 4px 12px rgba(0,0,0,.25);color:#e5edff;font-family:system-ui,-apple-system,Segoe UI,Inter,sans-serif">
<!-- Header -->
<div style="display:flex;align-items:center;gap:14px;margin-bottom:10px;flex-wrap:wrap">
<span style="font-size:32px;filter:drop-shadow(0 2px 8px rgba(6,214,160,.5))">🎯</span>
<h2 style="margin:0;font-size:24px;font-weight:700;letter-spacing:-.015em;background:linear-gradient(90deg,#6ee7b7,#67e8f9,#c4b5fd);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text">
ERP Command Center · 5 Pillars Unified
</h2>
<span style="margin-left:auto;font-size:11px;padding:5px 12px;background:rgba(6,214,160,.18);border:1px solid rgba(6,214,160,.45);border-radius:20px;color:#6ee7b7;font-weight:600;letter-spacing:.3px">
🔥 PENTA-PIVOT LIVE
</span>
</div>
<div style="color:#94a3b8;font-size:13px;margin-bottom:20px;line-height:1.5">
Point d'entrée unique ERP · 5 piliers bidirectionnellement liés · KPI live master-api · référentiels uniques · zéro orphelin
</div>
<!-- 5 Pillars grid -->
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px;margin-bottom:18px">
<!-- Pillar 1: WTP -->
<a href="/weval-technology-platform.html" style="text-decoration:none;display:block;padding:16px 18px;background:linear-gradient(135deg,rgba(252,211,77,.10),rgba(0,0,0,.25));border:1px solid rgba(252,211,77,.30);border-radius:12px;transition:all .2s" onmouseover="this.style.borderColor='rgba(252,211,77,.6)';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='rgba(252,211,77,.3)';this.style.transform='translateY(0)'">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px">
<span style="font-size:20px">🏠</span>
<div style="color:#fcd34d;font-size:12px;text-transform:uppercase;letter-spacing:.7px;font-weight:700">Pillar 1 · WTP</div>
</div>
<div style="color:#fff;font-size:14px;font-weight:600;margin-bottom:4px">Technology Platform</div>
<div style="color:#94a3b8;font-size:11px;line-height:1.4">Point d'entrée ERP · 17 composants · autonomie 100%</div>
<div style="color:#6ee7b7;font-size:10px;margin-top:6px;font-family:monospace" id="pillar-wtp-status">HTTP ⏳</div>
</a>
<!-- Pillar 2: All-IA Hub -->
<a href="/all-ia-hub.html" style="text-decoration:none;display:block;padding:16px 18px;background:linear-gradient(135deg,rgba(249,168,212,.10),rgba(0,0,0,.25));border:1px solid rgba(249,168,212,.30);border-radius:12px;transition:all .2s" onmouseover="this.style.borderColor='rgba(249,168,212,.6)';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='rgba(249,168,212,.3)';this.style.transform='translateY(0)'">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px">
<span style="font-size:20px">🌈</span>
<div style="color:#f9a8d4;font-size:12px;text-transform:uppercase;letter-spacing:.7px;font-weight:700">Pillar 2 · All-IA</div>
</div>
<div style="color:#fff;font-size:14px;font-weight:600;margin-bottom:4px">Hub 7 Tabs</div>
<div style="color:#94a3b8;font-size:11px;line-height:1.4">Chat · Code · Arena · Capabilities · Training · Orchestrator · Dashboards</div>
<div style="color:#6ee7b7;font-size:10px;margin-top:6px;font-family:monospace" id="pillar-allia-status">HTTP ⏳</div>
</a>
<!-- Pillar 3: Arena -->
<a href="/weval-arena.html" style="text-decoration:none;display:block;padding:16px 18px;background:linear-gradient(135deg,rgba(167,139,250,.10),rgba(0,0,0,.25));border:1px solid rgba(167,139,250,.30);border-radius:12px;transition:all .2s" onmouseover="this.style.borderColor='rgba(167,139,250,.6)';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='rgba(167,139,250,.3)';this.style.transform='translateY(0)'">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px">
<span style="font-size:20px">⚔️</span>
<div style="color:#a78bfa;font-size:12px;text-transform:uppercase;letter-spacing:.7px;font-weight:700">Pillar 3 · Arena</div>
</div>
<div style="color:#fff;font-size:14px;font-weight:600;margin-bottom:4px">Command Center</div>
<div style="color:#94a3b8;font-size:11px;line-height:1.4">Multi-provider benchmarks · Chat · L99 · Tools · Wiring</div>
<div style="color:#6ee7b7;font-size:10px;margin-top:6px;font-family:monospace" id="pillar-arena-status">HTTP ⏳</div>
</a>
<!-- Pillar 4: Orchestrator -->
<a href="/wevia-orchestrator.html" style="text-decoration:none;display:block;padding:16px 18px;background:linear-gradient(135deg,rgba(6,214,160,.10),rgba(0,0,0,.25));border:1px solid rgba(6,214,160,.30);border-radius:12px;transition:all .2s" onmouseover="this.style.borderColor='rgba(6,214,160,.6)';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='rgba(6,214,160,.3)';this.style.transform='translateY(0)'">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px">
<span style="font-size:20px">🎛️</span>
<div style="color:#06d6a0;font-size:12px;text-transform:uppercase;letter-spacing:.7px;font-weight:700">Pillar 4 · Orch</div>
</div>
<div style="color:#fff;font-size:14px;font-weight:600;margin-bottom:4px">Orchestrator GODMODE</div>
<div style="color:#94a3b8;font-size:11px;line-height:1.4">Agent fleet · tools registry · archi 3D · director · growth</div>
<div style="color:#6ee7b7;font-size:10px;margin-top:6px;font-family:monospace" id="pillar-orch-status">HTTP ⏳</div>
</a>
<!-- Pillar 5: WevCode -->
<a href="/wevcode.html" style="text-decoration:none;display:block;padding:16px 18px;background:linear-gradient(135deg,rgba(110,231,183,.10),rgba(0,0,0,.25));border:1px solid rgba(110,231,183,.30);border-radius:12px;transition:all .2s" onmouseover="this.style.borderColor='rgba(110,231,183,.6)';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='rgba(110,231,183,.3)';this.style.transform='translateY(0)'">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px">
<span style="font-size:20px">💻</span>
<div style="color:#6ee7b7;font-size:12px;text-transform:uppercase;letter-spacing:.7px;font-weight:700">Pillar 5 · WevCode</div>
</div>
<div style="color:#fff;font-size:14px;font-weight:600;margin-bottom:4px">Sovereign Coding Agent</div>
<div style="color:#94a3b8;font-size:11px;line-height:1.4">635 fns · 5231 skills · 4 modes code/analyze/plan/execute</div>
<div style="color:#6ee7b7;font-size:10px;margin-top:6px;font-family:monospace" id="pillar-wevcode-status">HTTP ⏳</div>
</a>
</div>
<!-- Aggregated KPI live bar -->
<div style="padding:14px 16px;background:rgba(0,0,0,.30);border:1px solid rgba(6,214,160,.18);border-radius:10px;margin-bottom:14px">
<div style="color:#6ee7b7;font-size:11px;text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px;font-weight:600">📊 Unified KPI Live (agrégés master-api)</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px;font-size:12px;color:#cbd5e1">
<div title="Source: master-api chat intent autonomie_wevia · 17 composants V91-V104 GODMODE"><span style="color:#64748b">Autonomy:</span> <b id="erp-kpi-autonomy" style="color:#6ee7b7;cursor:help"></b></div>
<div title="Source: master-api autonomie_wevia · format X/Y composants"><span style="color:#64748b">Components:</span> <b id="erp-kpi-components" style="color:#67e8f9;cursor:help"></b></div>
<div title="Source: master-api multi-agents nonreg · L99 6sigma tests"><span style="color:#64748b">NonReg:</span> <b id="erp-kpi-nonreg" style="color:#86efac;cursor:help"></b></div>
<div title="Source: /api/wevia-tool-registry.json tools.length · registry dynamic resolver"><span style="color:#64748b">Registry:</span> <b id="erp-kpi-registry" style="color:#fcd34d;cursor:help"></b></div>
<div title="Source: /api/dashboards-registry.php total · 84 dashboards public filtered · 14 catégories"><span style="color:#64748b">Dashboards:</span> <b id="erp-kpi-dashboards" style="color:#c4b5fd;cursor:help"></b></div>
<div title="Source: /api/wevia-v82-tips-catalog.php total_tips · 8 categories cyber"><span style="color:#64748b">Tips:</span> <b id="erp-kpi-tips" style="color:#f9a8d4;cursor:help"></b></div>
<div title="Source: master-api architecture_quality intent · orphans_count · pages non liées"><span style="color:#64748b">Orphans:</span> <b id="erp-kpi-orphans" style="color:#10b981;cursor:help"></b></div>
<div title="Source: HEAD requests 5 pivots · WTP + All-IA + Arena + Orchestrator + WevCode"><span style="color:#64748b">Pillars HTTP:</span> <b id="erp-kpi-pillars" style="color:#fbbf24;cursor:help"></b></div>
<div title="Source: /api/wevia-truth-registry.json agents.count_unique · 906 dédupliqué 7 sources"><span style="color:#64748b">Agents:</span> <b id="erp-kpi-agents" style="color:#00d4b4;cursor:help"></b></div>
<div title="Source: /api/wevia-truth-registry.json skills.TOTAL · 15509 dédupliqué (qdrant+registry+disk+arena)"><span style="color:#64748b">Skills:</span> <b id="erp-kpi-skills" style="color:#a78bfa;cursor:help"></b></div>
<div title="Source: /api/wevia-truth-registry.json brains.count · 25 brains"><span style="color:#64748b">Brains:</span> <b id="erp-kpi-brains" style="color:#ec4899;cursor:help"></b></div>
<div title="Source: /api/wevia-truth-registry.json qdrant.collections_count · 20 collections · 17 327 points"><span style="color:#64748b">Qdrant:</span> <b id="erp-kpi-qdrant" style="color:#fb923c;cursor:help"></b></div>
<div title="Source: /api/wevia-truth-registry.json providers.live · 13 live sur 15 déclarés · cascade 0€"><span style="color:#64748b">Providers:</span> <b id="erp-kpi-providers" style="color:#38bdf8;cursor:help"></b></div>
<div title="Source: /api/wevia-truth-registry.json doctrines.count · 19 doctrines internes Claude brains"><span style="color:#64748b">Doctrines:</span> <b id="erp-kpi-doctrines" style="color:#fde047;cursor:help"></b></div>
</div>
</div>
<!-- ═══ Charts V106 : Donut autonomy + sparkline progression ═══ -->
<div id="erp-cc-charts-v106" style="display:grid;grid-template-columns:180px 1fr;gap:16px;padding:16px;background:rgba(0,0,0,.30);border:1px solid rgba(6,214,160,.18);border-radius:10px;margin-bottom:14px;align-items:center">
<!-- Donut Autonomy 100% -->
<div style="display:flex;flex-direction:column;align-items:center;gap:6px">
<svg width="140" height="140" viewBox="0 0 140 140" style="transform:rotate(-90deg)">
<defs>
<linearGradient id="donut-gradient-v106" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#6ee7b7"/>
<stop offset="50%" stop-color="#22d3ee"/>
<stop offset="100%" stop-color="#a78bfa"/>
</linearGradient>
</defs>
<!-- Background circle -->
<circle cx="70" cy="70" r="58" fill="none" stroke="rgba(148,163,184,.15)" stroke-width="12"/>
<!-- Progress circle 100% · circumference = 2*PI*58 = 364.4 -->
<circle cx="70" cy="70" r="58" fill="none" stroke="url(#donut-gradient-v106)" stroke-width="12" stroke-linecap="round" stroke-dasharray="364.4 364.4" stroke-dashoffset="0" style="filter:drop-shadow(0 0 6px rgba(110,231,183,.4))"/>
</svg>
<div style="position:relative;margin-top:-95px;text-align:center;pointer-events:none">
<div style="font-size:28px;font-weight:800;color:#6ee7b7;letter-spacing:-1px;line-height:1">100%</div>
<div style="font-size:10px;color:#94a3b8;text-transform:uppercase;letter-spacing:.8px;margin-top:2px">GODMODE</div>
</div>
<div style="margin-top:55px;font-size:11px;color:#94a3b8;text-align:center;font-weight:500">17/17 composants</div>
</div>
<!-- Sparkline progression -->
<div>
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
<div style="font-size:11px;color:#6ee7b7;text-transform:uppercase;letter-spacing:.6px;font-weight:700">📈 Progression Autonomie · Session 21-avr 2026</div>
<div style="font-size:10px;color:#94a3b8;font-family:monospace">+44 points en 12 bumps</div>
</div>
<svg viewBox="0 0 700 100" preserveAspectRatio="none" style="width:100%;height:100px">
<defs>
<linearGradient id="spark-fill-v106" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="rgba(110,231,183,.4)"/>
<stop offset="100%" stop-color="rgba(110,231,183,0)"/>
</linearGradient>
</defs>
<!-- Grid lines -->
<line x1="0" y1="25" x2="700" y2="25" stroke="rgba(148,163,184,.08)" stroke-dasharray="2 4"/>
<line x1="0" y1="50" x2="700" y2="50" stroke="rgba(148,163,184,.08)" stroke-dasharray="2 4"/>
<line x1="0" y1="75" x2="700" y2="75" stroke="rgba(148,163,184,.08)" stroke-dasharray="2 4"/>
<!-- Area fill (56→60→64→68→72→76→80→84→88→92→96→100) over 12 points -->
<path d="M 0,44 L 64,40 L 127,36 L 191,32 L 255,28 L 318,24 L 382,20 L 445,16 L 509,12 L 573,8 L 636,4 L 700,0 L 700,100 L 0,100 Z" fill="url(#spark-fill-v106)"/>
<!-- Line -->
<path d="M 0,44 L 64,40 L 127,36 L 191,32 L 255,28 L 318,24 L 382,20 L 445,16 L 509,12 L 573,8 L 636,4 L 700,0" fill="none" stroke="#6ee7b7" stroke-width="2.5" stroke-linejoin="round" stroke-linecap="round" style="filter:drop-shadow(0 2px 4px rgba(110,231,183,.4))"/>
<!-- Data points with labels -->
<circle cx="0" cy="44" r="3" fill="#6ee7b7"/>
<circle cx="64" cy="40" r="2.5" fill="#6ee7b7"/>
<circle cx="127" cy="36" r="2.5" fill="#6ee7b7"/>
<circle cx="191" cy="32" r="2.5" fill="#6ee7b7"/>
<circle cx="255" cy="28" r="2.5" fill="#6ee7b7"/>
<circle cx="318" cy="24" r="2.5" fill="#6ee7b7"/>
<circle cx="382" cy="20" r="2.5" fill="#6ee7b7"/>
<circle cx="445" cy="16" r="2.5" fill="#6ee7b7"/>
<circle cx="509" cy="12" r="2.5" fill="#6ee7b7"/>
<circle cx="573" cy="8" r="2.5" fill="#6ee7b7"/>
<circle cx="636" cy="4" r="2.5" fill="#6ee7b7"/>
<circle cx="700" cy="0" r="4" fill="#6ee7b7" style="filter:drop-shadow(0 0 6px #6ee7b7)"/>
</svg>
<div style="display:flex;justify-content:space-between;font-size:9px;color:#64748b;font-family:monospace;margin-top:4px">
<span>56%</span>
<span>60%</span>
<span>64%</span>
<span>68%</span>
<span>72%</span>
<span>76%</span>
<span>80%</span>
<span>84%</span>
<span>88%</span>
<span>92%</span>
<span>96%</span>
<span style="color:#6ee7b7;font-weight:700">100%</span>
</div>
<div style="display:flex;justify-content:space-between;font-size:9px;color:#475569;font-family:monospace;margin-top:2px">
<span>V91</span>
<span>V94</span>
<span>V95</span>
<span>V96</span>
<span>V97</span>
<span>V98</span>
<span>V99</span>
<span>V100</span>
<span>V101</span>
<span>V102</span>
<span>V103</span>
<span style="color:#6ee7b7;font-weight:700">V104 🔥</span>
</div>
</div>
</div>
<!-- ═══ ERP CC Actions V108 : Business E2E + Artifacts ═══ -->
<div id="erp-cc-e2e-actions-v108" style="display:flex;gap:10px;flex-wrap:wrap;padding:12px 14px;background:rgba(0,0,0,.22);border:1px solid rgba(6,214,160,.15);border-radius:10px;margin-bottom:14px;align-items:center">
<div style="color:#6ee7b7;font-size:11px;text-transform:uppercase;letter-spacing:.5px;font-weight:700;margin-right:8px">🎬 Actions Tests</div>
<a href="#" onclick="runBusinessE2E(event)" style="padding:7px 14px;background:linear-gradient(135deg,rgba(110,231,183,.20),rgba(34,211,238,.12));border:1px solid rgba(110,231,183,.45);border-radius:7px;color:#6ee7b7;text-decoration:none;font-size:12px;font-weight:600;cursor:pointer;transition:all .2s" onmouseover="this.style.transform='translateY(-1px)'" onmouseout="this.style.transform='translateY(0)'" title="Déclenche test business E2E via WEVIA chat intent test_business_e2e · affiche résultats inline">
▶ Run Business E2E
</a>
<a href="/api/playwright-results/v94-business-scenario/results.json" target="_blank" style="padding:7px 14px;background:linear-gradient(135deg,rgba(167,139,250,.18),rgba(139,92,246,.10));border:1px solid rgba(167,139,250,.35);border-radius:7px;color:#c4b5fd;text-decoration:none;font-size:12px;font-weight:600;transition:all .2s" onmouseover="this.style.transform='translateY(-1px)'" onmouseout="this.style.transform='translateY(0)'" title="JSON brut des derniers résultats V94 business-scenario">
📄 Results JSON
</a>
<a href="/api/playwright-results/v94-business-scenario/01-landing.png" target="_blank" style="padding:7px 14px;background:linear-gradient(135deg,rgba(251,191,36,.18),rgba(217,119,6,.10));border:1px solid rgba(251,191,36,.35);border-radius:7px;color:#fcd34d;text-decoration:none;font-size:12px;font-weight:600;transition:all .2s" onmouseover="this.style.transform='translateY(-1px)'" onmouseout="this.style.transform='translateY(0)'" title="Screenshot landing page du test V94">
🖼️ Screenshot
</a>
<a href="/api/playwright-results/" target="_blank" style="padding:7px 14px;background:linear-gradient(135deg,rgba(236,72,153,.18),rgba(219,39,119,.10));border:1px solid rgba(236,72,153,.35);border-radius:7px;color:#f9a8d4;text-decoration:none;font-size:12px;font-weight:600;transition:all .2s" onmouseover="this.style.transform='translateY(-1px)'" onmouseout="this.style.transform='translateY(0)'" title="Index complet Playwright artifacts · multi-campagnes">
📁 All Artifacts
</a>
<a href="/playwright-v132-portfolio.html" target="_blank" style="padding:7px 14px;background:linear-gradient(135deg,rgba(0,200,150,.22),rgba(16,185,129,.12));border:1px solid rgba(0,200,150,.4);border-radius:7px;color:#34d399;text-decoration:none;font-size:12px;font-weight:700;transition:all .2s" onmouseover="this.style.transform='translateY(-1px)'" onmouseout="this.style.transform='translateY(0)'" title="V132 Playwright portfolio · 12 business intents · 100 pct routing validé">
🎯 V132 100% Routing
</a>
<a href="/l99-saas.html" target="_blank" style="padding:7px 14px;background:linear-gradient(135deg,rgba(16,185,129,.18),rgba(5,150,105,.10));border:1px solid rgba(16,185,129,.35);border-radius:7px;color:#34d399;text-decoration:none;font-size:12px;font-weight:600;transition:all .2s" onmouseover="this.style.transform='translateY(-1px)'" onmouseout="this.style.transform='translateY(0)'" title="L99 Non-Regression SaaS · 153/153 tests 6sigma">
📊 L99 Non-Reg
</a>
<a href="/wiki/cyber-tips-library.md" target="_blank" style="padding:7px 14px;background:linear-gradient(135deg,rgba(14,165,233,.18),rgba(59,130,246,.10));border:1px solid rgba(14,165,233,.35);border-radius:7px;color:#38bdf8;text-decoration:none;font-size:12px;font-weight:600;transition:all .2s" onmouseover="this.style.transform='translateY(-1px)'" onmouseout="this.style.transform='translateY(0)'" title="Wiki Cyber Tips Library · 45 tips 8 categories + KPI Sources Reference V107">
📘 Wiki V107
</a>
<span id="erp-cc-e2e-result" style="margin-left:auto;font-size:11px;color:#94a3b8;font-family:monospace"></span>
</div>
<script>
async function runBusinessE2E(e) {
e.preventDefault();
const result = document.getElementById('erp-cc-e2e-result');
result.textContent = '⏳ Lancement...';
result.style.color = '#fbbf24';
try {
const r = await fetch('/api/wevia-master-api.php', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({message: 'je veux test business', session: 'erp-e2e-' + Date.now(), history: [], attachments: []})
});
const data = await r.json();
const content = data.content || data.response || JSON.stringify(data).substring(0,100);
const passMatch = content.match(/(\d+)\/(\d+) PASS/);
if (passMatch) {
result.textContent = '✓ ' + passMatch[0];
result.style.color = '#6ee7b7';
} else {
result.textContent = '⚠ ' + content.substring(0, 80);
result.style.color = '#fbbf24';
}
} catch(err) {
result.textContent = '✗ ' + err.message;
result.style.color = '#ef4444';
}
}
</script>
<!-- Footer doctrine -->
<div style="padding:10px 14px;background:rgba(6,214,160,.06);border-left:3px solid rgba(6,214,160,.45);border-radius:6px;font-size:11px;color:#94a3b8;line-height:1.6">
<b style="color:#6ee7b7">Doctrine ERP:</b> WTP = point d'entrée unique · référentiels uniques · zéro orphelin · zéro doublon · zéro hardcode · UX premium doctrine 60 · GOLD avant modif · chattr safe · Git dual-remote sync
</div>
</section>
<script>
// ERP Command Center live fetcher
(async () => {
// 1. HTTP status per pillar
const pillars = [
['wtp', '/weval-technology-platform.html'],
['allia', '/all-ia-hub.html'],
['arena', '/weval-arena.html'],
['orch', '/wevia-orchestrator.html'],
['wevcode', '/wevcode.html'],
];
let upCount = 0;
for (const [key, url] of pillars) {
try {
const r = await fetch(url, {method: 'HEAD'});
const el = document.getElementById('pillar-' + key + '-status');
const ok = r.ok || r.status === 302;
if (el) el.textContent = 'HTTP ' + r.status + (ok ? ' ✓' : ' ⚠');
if (ok) upCount++;
} catch(e) {
const el = document.getElementById('pillar-' + key + '-status');
if (el) el.textContent = 'HTTP ❌';
}
}
const pe = document.getElementById('erp-kpi-pillars');
if (pe) pe.textContent = upCount + '/5';
// 2. Autonomy + components from master-api
try {
const r = await fetch('/api/wevia-master-api.php', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({message: 'autonomie wevia', session: 'erp-cc-' + Date.now(), history: [], attachments: []})
});
const data = await r.json();
const text = (data.response || '');
const autMatch = text.match(/~?(\d+)%/);
const compMatch = text.match(/(\d+\/\d+) \(/);
if (autMatch) document.getElementById('erp-kpi-autonomy').textContent = autMatch[1] + '%';
if (compMatch) document.getElementById('erp-kpi-components').textContent = compMatch[1];
} catch(e) {}
// 3. Registry tools count
try {
const r = await fetch('/api/wevia-tool-registry.json');
const reg = await r.json();
const cnt = (reg.tools || []).length;
document.getElementById('erp-kpi-registry').textContent = cnt + ' tools';
} catch(e) {}
// 4. Dashboards count
try {
const r = await fetch('/api/dashboards-registry.php');
const d = await r.json();
document.getElementById('erp-kpi-dashboards').textContent = d.total + ' dashboards';
} catch(e) {}
// 5. Tips catalog
try {
const r = await fetch('/api/wevia-v82-tips-catalog.php');
const d = await r.json();
document.getElementById('erp-kpi-tips').textContent = d.total_tips + ' tips';
} catch(e) {}
// 6. NonReg from multi-agent
try {
const r = await fetch('/api/wevia-master-api.php', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({message: 'multi agents', session: 'erp-nr-' + Date.now(), history: [], attachments: []})
});
const data = await r.json();
const ag = data.agents || {};
const nrMatch = (ag.nonreg || '').match(/(\d+\/\d+)/);
if (nrMatch) document.getElementById('erp-kpi-nonreg').textContent = nrMatch[1];
} catch(e) {}
// 7bis. Truth Registry KPIs: agents/skills/brains
try {
const r = await fetch('/api/wevia-truth-registry.json');
const tr = await r.json();
const ag = tr.agents || {};
const sk = tr.skills || {};
const br = tr.brains || {};
if (ag.count_unique) document.getElementById('erp-kpi-agents').textContent = ag.count_unique;
// skills count may be number or object with total
// Skills: Truth Registry uses .TOTAL key (15509)
let skc = typeof sk === 'number' ? sk : (sk.TOTAL || sk.count_total || sk.count_unique || 0);
if (skc) document.getElementById('erp-kpi-skills').textContent = skc.toLocaleString('fr-FR');
// Brains may be array
let brc = typeof br === 'number' ? br : (Array.isArray(br) ? br.length : (br.count || (br.items && br.items.length) || 0));
if (brc) document.getElementById('erp-kpi-brains').textContent = brc;
// Qdrant
const qd = tr.qdrant || {};
if (qd.collections_count) {
const pts = qd.total_points ? ' · ' + (qd.total_points).toLocaleString('fr-FR') + ' pts' : '';
document.getElementById('erp-kpi-qdrant').textContent = qd.collections_count + ' cols' + pts;
}
// Providers
const pr = tr.providers || {};
if (pr.live != null) {
const total = pr.declared_total ? '/' + pr.declared_total : '';
document.getElementById('erp-kpi-providers').textContent = pr.live + total + ' live';
}
// Doctrines
const dc = tr.doctrines || {};
if (dc.count) document.getElementById('erp-kpi-doctrines').textContent = dc.count;
} catch(e) { /* silent */ }
// 7. Orphans count (from architecture_quality intent)
try {
const r = await fetch('/api/wevia-master-api.php', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({message: 'orphans count', session: 'erp-orph-' + Date.now(), history: [], attachments: []})
});
const data = await r.json();
const txt = data.response || '';
const m = txt.match(/"value"\s*:\s*(\d+)/);
if (m) document.getElementById('erp-kpi-orphans').textContent = m[1] + ' pages';
} catch(e) {}
})();
</script>
<!-- ═══ END ERP COMMAND CENTER V105 ═══ -->
<!-- OPUS_v932_ORPHANS_HUB_LINK -->
<a href="/orphans-hub.html" id="opus-orphans-hub-anchor" style="position:fixed;bottom:20px;left:20px;background:rgba(34,197,94,0.12);color:#22c55e;padding:6px 12px;border-radius:20px;text-decoration:none;font-size:11px;font-weight:500;border:1px solid rgba(34,197,94,0.3);z-index:100;backdrop-filter:blur(10px)" title="Orphans Hub - live count" data-dynamic="orphans"><span id="opus-orphans-count-text">Orphans Hub (1)</span></a>
<!-- OPUS_v932f_DROID_LINK -->
<a href="/wevia-ia/droid.html" id="opus-droid-link" title="WEDROID v3.2" style="position:fixed;top:58px;right:12px;padding:5px 12px;background:rgba(16,185,129,0.15);color:#10b981;text-decoration:none;border-radius:14px;font-size:11px;font-weight:600;border:1px solid rgba(16,185,129,0.4);backdrop-filter:blur(10px);z-index:100" data-wave="WAVE_264_DROID_REPOS">🤖 Droid</a>
<script src="/api/a11y-auto-enhancer.js" defer></script>
<script>
// V9.78 · Orphans Hub count dynamic
(async function v978OrphansCount() {
try {
// V159.1 sitemap source · was pages-orphans-list (returned 1 · stale) now sitemap-api (live filesystem)
const r = await fetch('/api/weval-sitemap-api.php', {cache:'no-store'});
const d = await r.json();
const el = document.getElementById('opus-orphans-count-text');
const cnt = (d.stats && d.stats.orphan_count) ? d.stats.orphan_count : 0;
if (el) el.textContent = 'Orphans Hub (' + cnt + ')';
} catch(e){}
})();
</script>
<!-- BETON-DOCTRINE-105 WTP Pilotage KPI Live widget - additif pur 21avr -->
<section id="wtp-history-wave209" data-added-by="opus-wave-209-part2" style="margin:24px 16px;padding:24px;background:linear-gradient(135deg,#064e3b,#022c22);border:1px solid #10b981;border-radius:12px;font-family:system-ui,sans-serif">
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:16px">
<div>
<div style="display:flex;align-items:center;gap:10px">
<span style="font-size:22px">📈</span>
<h2 style="margin:0;color:#d1fae5;font-size:20px;font-weight:700">Historique 30 jours · KPI clés</h2>
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#10b981,#22d3ee);color:#fff;font-size:10px;font-weight:700;letter-spacing:.6px">WAVE 209</span>
</div>
<p style="margin:4px 0 0 0;color:#6ee7b7;font-size:12.5px">Daily snapshots · source PostgreSQL admin.kpi_history_daily · drill-down au clic</p>
</div>
<div id="wtp-hist-status" style="padding:6px 14px;border-radius:16px;background:rgba(16,185,129,.15);color:#6ee7b7;font-size:11px;font-weight:600;border:1px solid rgba(16,185,129,.4)">CHARGEMENT...</div>
</div>
<div id="wtp-hist-grid" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px"></div>
<div id="wtp-hist-drill" style="display:none;margin-top:16px;padding:18px;background:rgba(16,185,129,.06);border:1px solid rgba(16,185,129,.2);border-radius:10px"></div>
<script>
(function(){
var KPI_DEFS = [
{key:'nonreg_score', label:'Non-Regression', color:'#10b981', unit:'%', icon:'✓'},
{key:'l99_score', label:'L99 Score', color:'#3b82f6', unit:'%', icon:'📊'},
{key:'health_score', label:'Health Score', color:'#8b5cf6', unit:'%', icon:'💚'},
{key:'crm_deals', label:'CRM Deals', color:'#f59e0b', unit:'', icon:'💼'},
{key:'crm_companies', label:'CRM Companies', color:'#ec4899', unit:'', icon:'🏢'},
{key:'ethica_hcps', label:'Ethica HCPs', color:'#06b6d4', unit:'', icon:'👨‍⚕️'},
{key:'weval_leads_new_7d', label:'Leads (7j)', color:'#f97316', unit:'', icon:'🎯'},
{key:'crm_deals_amount_eur', label:'Pipeline EUR', color:'#22c55e', unit:'€', icon:'💰'}
];
function chartSVG(points, color){
if (!points.length) return '<div style="padding:12px;color:#6b7280;font-size:11px">no data</div>';
var w=280, h=80, pad=6;
var vals = points.map(function(p){return p.v;});
var mn = Math.min.apply(null,vals);
var mx = Math.max.apply(null,vals);
if (mx === mn) mx = mn + 1;
var pts = points.map(function(p,i){
var x = pad + (i/(points.length-1))*(w-2*pad);
var y = h - pad - ((p.v-mn)/(mx-mn))*(h-2*pad);
return x+','+y;
});
var poly = pts.join(' ');
var area = 'M'+pts[0]+' L'+pts.join(' L')+' L'+(w-pad)+','+(h-pad)+' L'+pad+','+(h-pad)+' Z';
var lastP = pts[pts.length-1].split(',');
return '<svg width="100%" height="'+h+'" viewBox="0 0 '+w+' '+h+'" preserveAspectRatio="none">'
+ '<defs><linearGradient id="gr-'+color.replace(/#/g,'')+'" x1="0" x2="0" y1="0" y2="1"><stop offset="0" stop-color="'+color+'" stop-opacity=".3"/><stop offset="1" stop-color="'+color+'" stop-opacity="0"/></linearGradient></defs>'
+ '<path d="'+area+'" fill="url(#gr-'+color.replace(/#/g,'')+')"/>'
+ '<polyline points="'+poly+'" fill="none" stroke="'+color+'" stroke-width="1.8"/>'
+ '<circle cx="'+lastP[0]+'" cy="'+lastP[1]+'" r="3" fill="'+color+'"/>'
+ '</svg>';
}
function fmtVal(v, unit){
var n = parseFloat(v);
if (isNaN(n)) return v;
if (unit === '€' && n >= 1000) return (n/1000).toFixed(1)+'k€';
if (n >= 10000) return (n/1000).toFixed(1)+'k'+unit;
if (n === Math.floor(n)) return n+unit;
return n.toFixed(1)+unit;
}
window.__wtpHistDrill = function(kpiKey, data){
var d = document.getElementById('wtp-hist-drill');
if (!d) return;
var def = KPI_DEFS.find(function(k){return k.key===kpiKey;});
if (!def) return;
var points = data.map(function(r){return {d:r.snap_date, v:parseFloat(r[kpiKey]||0)};}).filter(function(p){return !isNaN(p.v);});
var latest = points[points.length-1];
var first = points[0];
var diff = latest && first ? (latest.v - first.v) : 0;
var pct = first && first.v ? (diff/first.v*100) : 0;
var diffColor = diff >= 0 ? '#10b981' : '#ef4444';
var arrow = diff >= 0 ? '▲' : '▼';
d.style.display = 'block';
d.innerHTML = '<div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:12px;flex-wrap:wrap;gap:12px">'
+ '<div><h3 style="margin:0;color:#d1fae5;font-size:16px">'+def.icon+' '+def.label+'</h3><div style="color:#6ee7b7;font-size:11px;margin-top:2px">Source: admin.kpi_history_daily · '+points.length+' jours</div></div>'
+ '<div style="display:flex;gap:12px">'
+ '<div style="text-align:right"><div style="font-size:10px;color:#94a3b8;text-transform:uppercase">Actuel</div><div style="font-size:24px;font-weight:700;color:'+def.color+'">'+fmtVal(latest?latest.v:0,def.unit)+'</div></div>'
+ '<div style="text-align:right"><div style="font-size:10px;color:#94a3b8;text-transform:uppercase">Δ 30j</div><div style="font-size:24px;font-weight:700;color:'+diffColor+'">'+arrow+' '+Math.abs(diff).toFixed(0)+'<span style="font-size:12px"> ('+(diff>=0?'+':'')+pct.toFixed(1)+'%)</span></div></div>'
+ '<button onclick="document.getElementById(\'wtp-hist-drill\').style.display=\'none\'" style="padding:4px 12px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.2);border-radius:14px;color:#d1fae5;font-size:11px;cursor:pointer">Fermer</button>'
+ '</div></div>'
+ '<div style="margin-top:10px">'+chartSVG(points, def.color)+'</div>'
+ '<div style="display:flex;justify-content:space-between;font-size:10px;color:#6b7280;margin-top:6px"><span>'+(first?first.d:'')+'</span><span>'+(latest?latest.d:'')+'</span></div>';
d.scrollIntoView({behavior:'smooth',block:'nearest'});
};
function refresh(){
var status = document.getElementById('wtp-hist-status');
if (status) status.textContent = 'FETCH...';
fetch('/api/kpi-history-30d.php?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var data = d.data || [];
var grid = document.getElementById('wtp-hist-grid');
if (!grid) return;
var html = '';
KPI_DEFS.forEach(function(def){
var points = data.map(function(r){return {d:r.snap_date, v:parseFloat(r[def.key]||0)};}).filter(function(p){return !isNaN(p.v);});
var latest = points[points.length-1];
var first = points[0];
var diff = latest && first ? (latest.v - first.v) : 0;
var pct = first && first.v ? (diff/first.v*100) : 0;
var diffColor = diff >= 0 ? '#6ee7b7' : '#fca5a5';
var arrow = diff >= 0 ? '↑' : '↓';
html += '<div onclick="window.__wtpHistDrill(\''+def.key+'\', '+JSON.stringify(data).replace(/\"/g,'&quot;')+')" style="cursor:pointer;padding:14px;background:rgba(255,255,255,.03);border:1px solid rgba(16,185,129,.15);border-radius:10px;transition:all .15s" onmouseover="this.style.borderColor=\'#10b981\';this.style.transform=\'translateY(-1px)\'" onmouseout="this.style.borderColor=\'rgba(16,185,129,.15)\';this.style.transform=\'translateY(0)\'">'
+ '<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:6px"><div style="font-size:12.5px;color:#d1fae5;font-weight:600">'+def.icon+' '+def.label+'</div><div style="font-size:11px;color:'+diffColor+';font-weight:700">'+arrow+' '+Math.abs(pct).toFixed(1)+'%</div></div>'
+ '<div style="font-size:22px;font-weight:700;color:'+def.color+';margin-bottom:6px">'+fmtVal(latest?latest.v:0,def.unit)+'</div>'
+ chartSVG(points, def.color)
+ '</div>';
});
grid.innerHTML = html;
if (status) {
status.textContent = 'LIVE · '+data.length+' jours · '+new Date().toLocaleTimeString('fr-FR');
status.style.background = 'rgba(16,185,129,.2)';
status.style.color = '#6ee7b7';
}
})
.catch(function(e){
var status = document.getElementById('wtp-hist-status');
if (status) { status.textContent = 'ERR'; status.style.background='rgba(239,68,68,.2)'; status.style.color='#fca5a5'; }
});
}
refresh();
setInterval(refresh, 300000);
})();
</script>
</section>
<section id="wtp-duplicates-wave209" data-added-by="opus-wave-209" style="margin:24px 16px;padding:24px;background:linear-gradient(135deg,#18181b,#1f1f23);border:1px solid #3f3f46;border-radius:12px;font-family:system-ui,sans-serif">
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:16px">
<div>
<div style="display:flex;align-items:center;gap:10px">
<span style="font-size:22px">🔍</span>
<h2 style="margin:0;color:#fafafa;font-size:20px;font-weight:700">Doublons écrans · Registry</h2>
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#f59e0b,#ef4444);color:#fff;font-size:10px;font-weight:700;letter-spacing:.6px">WAVE 209</span>
</div>
<p style="margin:4px 0 0 0;color:#a1a1aa;font-size:12.5px">Audit non-destructif · canonical + legacy + recommandation · PAS DE SUPPRESSION</p>
</div>
<div style="display:flex;gap:8px">
<a href="/api/duplicates-registry.php" target="_blank" style="padding:6px 14px;border-radius:16px;background:rgba(244,114,182,.15);color:#fbcfe8;font-size:11px;font-weight:600;text-decoration:none;border:1px solid rgba(244,114,182,.3)">JSON API</a>
<div id="wtp-dup-stats" style="padding:6px 14px;border-radius:16px;background:rgba(245,158,11,.12);color:#fcd34d;font-size:11px;font-weight:600;border:1px solid rgba(245,158,11,.3)">CHARGEMENT...</div>
</div>
</div>
<div id="wtp-dup-summary" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px;margin-bottom:14px"></div>
<div id="wtp-dup-groups" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:10px"></div>
<script>
(function(){
function cardKPI(label,value,color){
return '<div style="padding:12px;background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.08);border-radius:8px">'
+ '<div style="font-size:10.5px;color:#a1a1aa;text-transform:uppercase;letter-spacing:.6px">'+label+'</div>'
+ '<div style="font-size:22px;font-weight:700;color:'+color+';margin-top:4px">'+value+'</div>'
+ '</div>';
}
function groupCard(g){
var closeCnt = (g.close_copies||[]).length;
var cls = closeCnt > 0 ? 'border:1px solid #dc2626;background:rgba(220,38,38,.05)' : 'border:1px solid rgba(255,255,255,.1);background:rgba(255,255,255,.03)';
var legacyLinks = (g.legacy_files||[]).map(function(f){
var isClose = (g.close_copies||[]).indexOf(f) >= 0;
var chip = isClose ? '<span style="padding:1px 6px;border-radius:8px;background:#dc2626;color:#fff;font-size:9px;font-weight:700;margin-left:4px">QUASI-COPIE</span>' : '';
return '<a href="/'+f+'" target="_blank" style="display:inline-block;padding:3px 8px;margin:2px;background:rgba(245,158,11,.1);border:1px solid rgba(245,158,11,.25);border-radius:6px;color:#fcd34d;font-size:11px;text-decoration:none;font-family:monospace">'+f+chip+'</a>';
}).join('');
return '<div style="padding:12px 14px;'+cls+';border-radius:8px">'
+ '<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:6px">'
+ '<div style="font-size:12.5px;color:#e4e4e7;font-weight:600">'+g.base+'</div>'
+ '<span style="padding:2px 8px;border-radius:10px;background:rgba(99,102,241,.2);color:#a5b4fc;font-size:10px;font-weight:700">'+g.count+' files</span>'
+ '</div>'
+ '<div style="font-size:10.5px;color:#a1a1aa;margin-bottom:4px">Canonical:</div>'
+ '<a href="/'+g.canonical+'" target="_blank" style="display:inline-block;padding:3px 10px;margin:2px;background:rgba(16,185,129,.12);border:1px solid rgba(16,185,129,.3);border-radius:6px;color:#6ee7b7;font-size:11.5px;text-decoration:none;font-family:monospace;font-weight:600">✓ '+g.canonical+'</a>'
+ '<div style="font-size:10.5px;color:#a1a1aa;margin-top:6px;margin-bottom:2px">Legacy:</div>'
+ legacyLinks
+ '<div style="font-size:10px;color:#71717a;margin-top:8px;padding-top:8px;border-top:1px solid rgba(255,255,255,.05);font-style:italic">→ '+g.recommendation+'</div>'
+ '</div>';
}
function refresh(){
fetch('/api/duplicates-registry.php?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var stats = document.getElementById('wtp-dup-stats');
if(stats){
stats.textContent = d.total_duplicate_groups+' groupes · '+d.total_legacy_files+' legacy · '+d.total_close_copies+' quasi-copies';
if(d.total_close_copies>0){ stats.style.background='rgba(220,38,38,.15)'; stats.style.color='#fca5a5'; stats.style.borderColor='rgba(220,38,38,.4)'; }
else { stats.style.background='rgba(16,185,129,.15)'; stats.style.color='#6ee7b7'; stats.style.borderColor='rgba(16,185,129,.4)'; }
}
var sum = document.getElementById('wtp-dup-summary');
if(sum){
sum.innerHTML = cardKPI('TOTAL PAGES',d.total_pages,'#e4e4e7')
+ cardKPI('GROUPES DOUBLONS',d.total_duplicate_groups,'#fbbf24')
+ cardKPI('FICHIERS LEGACY',d.total_legacy_files,'#fb923c')
+ cardKPI('QUASI-COPIES',d.total_close_copies, d.total_close_copies>0?'#f87171':'#6ee7b7');
}
var grid = document.getElementById('wtp-dup-groups');
if(grid){
grid.innerHTML = (d.groups||[]).map(groupCard).join('');
}
})
.catch(function(e){
var stats = document.getElementById('wtp-dup-stats');
if(stats) stats.textContent = 'ERREUR';
});
}
refresh();
setInterval(refresh, 120000);
})();
</script>
</section>
<section id="wtp-video-6sigma-wave217" data-added-by="opus-wave-217" style="margin:24px 16px;padding:24px;background:linear-gradient(135deg,#365314 0%,#0c4a6e 100%);border:1px solid #84cc16;border-radius:12px;font-family:system-ui,sans-serif;box-shadow:0 10px 40px rgba(132,204,22,.18)">
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:18px">
<div>
<div style="display:flex;align-items:center;gap:10px">
<span style="font-size:22px">🎬</span>
<h2 style="margin:0;color:#d9f99d;font-size:20px;font-weight:700">6σ World-Class · Video Proof · DMAIC</h2>
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#84cc16,#0ea5e9);color:#fff;font-size:10px;font-weight:700;letter-spacing:.6px">WAVE 217</span>
</div>
<p style="margin:4px 0 0 0;color:#bef264;font-size:12.5px">20/20 PASS · DPMO=0 · 6σ World-Class · vidéo E2E · screenshots + DMAIC methodology</p>
</div>
<div id="wtp-v6-status" style="padding:6px 14px;border-radius:16px;background:rgba(132,204,22,.2);color:#d9f99d;font-size:11px;font-weight:600;border:1px solid rgba(132,204,22,.4)">✅ 6σ LIVE</div>
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(360px,1fr));gap:16px">
<!-- Video preview -->
<div style="padding:16px;background:rgba(0,0,0,.3);border:1px solid rgba(132,204,22,.2);border-radius:10px">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">
<span style="font-size:18px">🎥</span>
<h3 style="margin:0;color:#bef264;font-size:13px;font-weight:700">Video E2E Proof · 4.6 MB</h3>
</div>
<video controls preload="metadata" style="width:100%;border-radius:8px;background:#000;max-height:260px">
<source src="/test-report/six-sigma-v2-20260421-164554/c0c492b4cf47fc799b4a95a4aaa541c6.webm" type="video/webm">
</video>
<div style="display:flex;gap:8px;margin-top:10px;flex-wrap:wrap">
<a href="/test-report/six-sigma-v2-20260421-164554/c0c492b4cf47fc799b4a95a4aaa541c6.webm" target="_blank" style="padding:5px 12px;border-radius:12px;background:rgba(132,204,22,.15);color:#d9f99d;border:1px solid rgba(132,204,22,.3);font-size:11px;font-weight:600;text-decoration:none">↗ Open video</a>
<a href="/test-report/six-sigma-v2-20260421-164554/six-sigma-v2-results.json" target="_blank" style="padding:5px 12px;border-radius:12px;background:rgba(14,165,233,.15);color:#bae6fd;border:1px solid rgba(14,165,233,.3);font-size:11px;font-weight:600;text-decoration:none">📊 Results JSON</a>
</div>
</div>
<!-- 6σ DMAIC summary -->
<div style="padding:16px;background:rgba(0,0,0,.2);border:1px solid rgba(14,165,233,.2);border-radius:10px">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px">
<span style="font-size:18px">📈</span>
<h3 style="margin:0;color:#bae6fd;font-size:13px;font-weight:700">DMAIC · 20 scénarios</h3>
</div>
<div id="wtp-v6-stats" style="display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin-bottom:12px">
<div style="padding:10px;background:rgba(132,204,22,.1);border:1px solid rgba(132,204,22,.25);border-radius:8px;text-align:center">
<div style="font-size:10px;color:#bef264;text-transform:uppercase;letter-spacing:.5px">PASS RATE</div>
<div style="font-size:26px;font-weight:700;color:#d9f99d;margin-top:4px">100%</div>
<div style="font-size:10px;color:#a3e635">20/20 scenarios</div>
</div>
<div style="padding:10px;background:rgba(34,211,238,.1);border:1px solid rgba(34,211,238,.25);border-radius:8px;text-align:center">
<div style="font-size:10px;color:#a5f3fc;text-transform:uppercase;letter-spacing:.5px">DPMO</div>
<div style="font-size:26px;font-weight:700;color:#67e8f9;margin-top:4px">0</div>
<div style="font-size:10px;color:#22d3ee">Defects Per Million</div>
</div>
<div style="padding:10px;background:rgba(168,85,247,.1);border:1px solid rgba(168,85,247,.25);border-radius:8px;text-align:center">
<div style="font-size:10px;color:#ddd6fe;text-transform:uppercase;letter-spacing:.5px">SIGMA</div>
<div style="font-size:26px;font-weight:700;color:#c4b5fd;margin-top:4px">6σ</div>
<div style="font-size:10px;color:#a78bfa">99.9997%</div>
</div>
<div style="padding:10px;background:rgba(236,72,153,.1);border:1px solid rgba(236,72,153,.25);border-radius:8px;text-align:center">
<div style="font-size:10px;color:#fbcfe8;text-transform:uppercase;letter-spacing:.5px">SCREENSHOTS</div>
<div style="font-size:26px;font-weight:700;color:#f9a8d4;margin-top:4px">16</div>
<div style="font-size:10px;color:#ec4899">PNG proof</div>
</div>
</div>
<div id="wtp-v6-scenarios" style="margin-top:12px;max-height:180px;overflow-y:auto;font-size:10.5px"></div>
</div>
<!-- Blade status (bonus) -->
<div style="padding:16px;background:rgba(0,0,0,.2);border:1px solid rgba(168,85,247,.2);border-radius:10px">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px">
<span style="font-size:18px">🗡</span>
<h3 style="margin:0;color:#ddd6fe;font-size:13px;font-weight:700">Blade User YacineUtt · Live</h3>
</div>
<div id="wtp-v6-blade" style="padding:12px;background:rgba(255,255,255,.03);border-radius:8px;font-family:monospace;font-size:11px;color:#ddd6fe;min-height:140px">
⏳ Blade heartbeat fetch...
</div>
</div>
</div>
<script>
(function(){
// Load 6sigma scenarios
fetch('/test-report/six-sigma-v2-20260421-164554/six-sigma-v2-results.json?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var box = document.getElementById('wtp-v6-scenarios');
if (!box) return;
var scenarios = d.scenarios || [];
box.innerHTML = scenarios.map(function(s){
var col = s.status === 'PASS' ? '#84cc16' : '#ef4444';
return '<div style="padding:5px 8px;margin-bottom:3px;background:rgba(132,204,22,.05);border-left:2px solid '+col+';border-radius:3px;display:flex;justify-content:space-between;gap:6px;font-family:monospace"><span style="color:#d9f99d">'+(s.slug||'?')+'</span><span style="color:'+col+';font-weight:700">'+(s.status||'?')+'</span></div>';
}).join('');
})
.catch(function(){});
// Load Blade heartbeat
fetch('/api/blade-heartbeat.json?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var box = document.getElementById('wtp-v6-blade');
if (!box) return;
var ts = d.ts ? new Date(d.ts).toLocaleTimeString('fr-FR') : '?';
var statusColor = d.status === 'ALIVE' ? '#84cc16' : '#ef4444';
box.innerHTML = '<div style="display:flex;justify-content:space-between;margin-bottom:6px"><span>status</span><span style="color:'+statusColor+';font-weight:700">'+(d.status||'?')+'</span></div>'
+ '<div style="display:flex;justify-content:space-between;margin-bottom:6px"><span>tasks today</span><span style="color:#22d3ee;font-weight:700">'+(d.tasks_today||0)+'</span></div>'
+ '<div style="display:flex;justify-content:space-between;margin-bottom:6px"><span>tasks week</span><span style="color:#22d3ee;font-weight:700">'+(d.tasks_week||0)+'</span></div>'
+ '<div style="display:flex;justify-content:space-between;margin-bottom:6px"><span>agent_id</span><span style="color:#a78bfa">'+(d.agent_id||'?')+'</span></div>'
+ '<div style="display:flex;justify-content:space-between;margin-bottom:6px"><span>last beat</span><span style="color:#6ee7b7">'+ts+'</span></div>'
+ '<div style="margin-top:8px;padding-top:8px;border-top:1px solid rgba(255,255,255,.08);font-size:10px;color:#a1a1aa;font-style:italic">'+(d.note||'')+'</div>';
})
.catch(function(e){
var box = document.getElementById('wtp-v6-blade');
if (box) box.innerHTML = '<div style="color:#f87171">Blade heartbeat unavailable</div>';
});
})();
</script>
</section>
<section id="wtp-archi-3d-wave218" data-added-by="opus-wave-218" style="margin:24px 16px;padding:20px;background:linear-gradient(135deg,#0f172a 0%,#1e1b4b 100%);border:1px solid #06b6d4;border-radius:12px;font-family:system-ui,sans-serif;box-shadow:0 10px 40px rgba(6,182,212,.15)">
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:14px">
<div>
<div style="display:flex;align-items:center;gap:10px">
<span style="font-size:22px">🌐</span>
<h2 style="margin:0;color:#a5f3fc;font-size:18px;font-weight:700">Architecture 3D · Live embedded</h2>
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#06b6d4,#10b981);color:#fff;font-size:10px;font-weight:700">WAVE 218</span>
</div>
<p style="margin:4px 0 0 0;color:#67e8f9;font-size:12px">agents-archi.html · Three.js · particles flow · live state</p>
</div>
<div style="display:flex;gap:6px">
<a href="/agents-archi.html" target="_blank" style="text-decoration:none;padding:5px 12px;border-radius:10px;background:rgba(6,182,212,.12);color:#67e8f9;border:1px solid rgba(6,182,212,.3);font-size:11px">↗ Fullscreen</a>
<button onclick="var f=document.getElementById('wtp-archi-3d-frame');if(f){f.src=f.src;}" style="padding:5px 12px;border-radius:10px;background:rgba(6,182,212,.12);color:#67e8f9;border:1px solid rgba(6,182,212,.3);font-size:11px;cursor:pointer">🔄 Reload</button>
</div>
</div>
<div style="position:relative;width:100%;padding-bottom:56.25%;background:#000;border-radius:10px;overflow:hidden;border:1px solid rgba(6,182,212,.2)">
<iframe id="wtp-archi-3d-frame" src="/agents-archi.html" loading="lazy" style="position:absolute;top:0;left:0;width:100%;height:100%;border:0" title="Architecture 3D live"></iframe>
</div>
</section>
<section id="wtp-archi-nav-wave216" data-added-by="opus-wave-216" style="margin:24px 16px;padding:24px;background:linear-gradient(135deg,#0c4a6e 0%,#1e1b4b 100%);border:1px solid #22d3ee;border-radius:12px;font-family:system-ui,sans-serif;box-shadow:0 10px 40px rgba(34,211,238,.18)">
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:18px">
<div>
<div style="display:flex;align-items:center;gap:10px">
<span style="font-size:22px">🗺️</span>
<h2 style="margin:0;color:#a5f3fc;font-size:20px;font-weight:700">Architecture Live Navigator · 3 Portals</h2>
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#22d3ee,#a855f7);color:#fff;font-size:10px;font-weight:700;letter-spacing:.6px">WAVE 216</span>
</div>
<p style="margin:4px 0 0 0;color:#67e8f9;font-size:12.5px">Map 5 tiers · 47 agents · 3 portals points d entree · WTP = hub unifié</p>
</div>
<div id="wtp-an-status" style="padding:6px 14px;border-radius:16px;background:rgba(34,211,238,.15);color:#a5f3fc;font-size:11px;font-weight:600;border:1px solid rgba(34,211,238,.3)">LIVE</div>
</div>
<!-- Architecture SVG visual -->
<div style="padding:16px;background:rgba(0,0,0,.2);border-radius:10px;margin-bottom:16px;overflow-x:auto">
<svg viewBox="0 0 800 320" style="width:100%;min-width:600px;height:auto;display:block" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="nodeGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#22d3ee"/>
<stop offset="1" stop-color="#7c3aed"/>
</linearGradient>
<linearGradient id="tierBg" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="rgba(34,211,238,0.1)"/>
<stop offset="1" stop-color="rgba(124,58,237,0.1)"/>
</linearGradient>
</defs>
<!-- Tier 1: WTP Hub (top) -->
<rect x="300" y="20" width="200" height="50" rx="10" fill="url(#tierBg)" stroke="#22d3ee" stroke-width="2"/>
<text x="400" y="40" text-anchor="middle" fill="#a5f3fc" font-size="12" font-weight="700">WEVAL Technology Platform</text>
<text x="400" y="56" text-anchor="middle" fill="#67e8f9" font-size="10">Point d entrée unique · hub ERP</text>
<!-- Tier 2: 3 Portals -->
<g>
<a href="/all-ia-hub.html" target="_blank">
<rect x="60" y="100" width="160" height="50" rx="8" fill="url(#nodeGrad)" stroke="#22d3ee" stroke-width="1" style="cursor:pointer" opacity="0.85"/>
<text x="140" y="122" text-anchor="middle" fill="#fff" font-size="12" font-weight="700" style="pointer-events:none">🧠 All-IA Hub</text>
<text x="140" y="138" text-anchor="middle" fill="#e0f2fe" font-size="9" style="pointer-events:none">15 providers · cognitive</text>
</a>
<a href="/weval-technology-platform.html#wtp-multiagent-wave210">
<rect x="320" y="100" width="160" height="50" rx="8" fill="url(#nodeGrad)" stroke="#a855f7" stroke-width="1" style="cursor:pointer" opacity="0.85"/>
<text x="400" y="122" text-anchor="middle" fill="#fff" font-size="12" font-weight="700" style="pointer-events:none">🤖 WEVIA Master</text>
<text x="400" y="138" text-anchor="middle" fill="#e0f2fe" font-size="9" style="pointer-events:none">chat autonomy · 28 tips</text>
</a>
<a href="/wevia-orchestrator.html" target="_blank">
<rect x="580" y="100" width="160" height="50" rx="8" fill="url(#nodeGrad)" stroke="#ec4899" stroke-width="1" style="cursor:pointer" opacity="0.85"/>
<text x="660" y="122" text-anchor="middle" fill="#fff" font-size="12" font-weight="700" style="pointer-events:none">🎭 Arena Orchestrator</text>
<text x="660" y="138" text-anchor="middle" fill="#e0f2fe" font-size="9" style="pointer-events:none">310 intents · 47 agents</text>
</a>
</g>
<!-- Lines from WTP to portals -->
<line x1="400" y1="70" x2="140" y2="100" stroke="#22d3ee" stroke-width="1.5" opacity="0.5"/>
<line x1="400" y1="70" x2="400" y2="100" stroke="#a855f7" stroke-width="1.5" opacity="0.5"/>
<line x1="400" y1="70" x2="660" y2="100" stroke="#ec4899" stroke-width="1.5" opacity="0.5"/>
<!-- Tier 3: Agent categories (10) -->
<g transform="translate(0,180)">
<text x="400" y="10" text-anchor="middle" fill="#67e8f9" font-size="10" font-weight="600">47 AGENTS · 10 CATÉGORIES</text>
</g>
<!-- Agent category chips - 2 rows of 5 -->
<g>
<rect x="40" y="210" width="120" height="30" rx="6" fill="rgba(34,211,238,.12)" stroke="rgba(34,211,238,.3)"/><text x="100" y="229" text-anchor="middle" fill="#a5f3fc" font-size="10" font-weight="600">core (4)</text>
<rect x="180" y="210" width="120" height="30" rx="6" fill="rgba(168,85,247,.12)" stroke="rgba(168,85,247,.3)"/><text x="240" y="229" text-anchor="middle" fill="#ddd6fe" font-size="10" font-weight="600">ia (4)</text>
<rect x="320" y="210" width="120" height="30" rx="6" fill="rgba(16,185,129,.12)" stroke="rgba(16,185,129,.3)"/><text x="380" y="229" text-anchor="middle" fill="#6ee7b7" font-size="10" font-weight="600">infra (6)</text>
<rect x="460" y="210" width="120" height="30" rx="6" fill="rgba(236,72,153,.12)" stroke="rgba(236,72,153,.3)"/><text x="520" y="229" text-anchor="middle" fill="#fbcfe8" font-size="10" font-weight="600">ethica (7)</text>
<rect x="600" y="210" width="120" height="30" rx="6" fill="rgba(14,165,233,.12)" stroke="rgba(14,165,233,.3)"/><text x="660" y="229" text-anchor="middle" fill="#bae6fd" font-size="10" font-weight="600">email (5)</text>
<rect x="40" y="250" width="120" height="30" rx="6" fill="rgba(251,191,36,.12)" stroke="rgba(251,191,36,.3)"/><text x="100" y="269" text-anchor="middle" fill="#fde68a" font-size="10" font-weight="600">quality (4)</text>
<rect x="180" y="250" width="120" height="30" rx="6" fill="rgba(132,204,22,.12)" stroke="rgba(132,204,22,.3)"/><text x="240" y="269" text-anchor="middle" fill="#d9f99d" font-size="10" font-weight="600">knowledge (6)</text>
<rect x="320" y="250" width="120" height="30" rx="6" fill="rgba(244,114,182,.12)" stroke="rgba(244,114,182,.3)"/><text x="380" y="269" text-anchor="middle" fill="#fecdd3" font-size="10" font-weight="600">coding (4)</text>
<rect x="460" y="250" width="120" height="30" rx="6" fill="rgba(139,92,246,.12)" stroke="rgba(139,92,246,.3)"/><text x="520" y="269" text-anchor="middle" fill="#c4b5fd" font-size="10" font-weight="600">business (4)</text>
<rect x="600" y="250" width="120" height="30" rx="6" fill="rgba(249,115,22,.12)" stroke="rgba(249,115,22,.3)"/><text x="660" y="269" text-anchor="middle" fill="#fed7aa" font-size="10" font-weight="600">comms (3)</text>
</g>
</svg>
</div>
<!-- Links grid: 3 portals + 3 archi pages -->
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:10px">
<a href="/all-ia-hub.html" target="_blank" style="text-decoration:none;padding:12px;background:rgba(34,211,238,.08);border:1px solid rgba(34,211,238,.25);border-radius:8px;transition:all .15s;color:#a5f3fc" onmouseover="this.style.borderColor=\'#22d3ee\';this.style.transform=\'translateY(-1px)\'" onmouseout="this.style.borderColor=\'rgba(34,211,238,.25)\';this.style.transform=\'translateY(0)\'">
<div style="font-size:11px;color:#67e8f9;text-transform:uppercase;letter-spacing:.5px">Portal #1</div>
<div style="font-size:14px;font-weight:700;margin-top:4px">🧠 All-IA Hub</div>
<div style="font-size:11px;color:#e0f2fe;margin-top:2px">15 providers IA · benchmarking</div>
</a>
<a href="/wevia-master.html" target="_blank" style="text-decoration:none;padding:12px;background:rgba(168,85,247,.08);border:1px solid rgba(168,85,247,.25);border-radius:8px;transition:all .15s;color:#ddd6fe" onmouseover="this.style.borderColor=\'#a855f7\';this.style.transform=\'translateY(-1px)\'" onmouseout="this.style.borderColor=\'rgba(168,85,247,.25)\';this.style.transform=\'translateY(0)\'">
<div style="font-size:11px;color:#c4b5fd;text-transform:uppercase;letter-spacing:.5px">Portal #2</div>
<div style="font-size:14px;font-weight:700;margin-top:4px">🤖 WEVIA Master</div>
<div style="font-size:11px;color:#e0e7ff;margin-top:2px">Chat autonomy · 28 tips · SSE</div>
</a>
<a href="/wevia-orchestrator.html" target="_blank" style="text-decoration:none;padding:12px;background:rgba(236,72,153,.08);border:1px solid rgba(236,72,153,.25);border-radius:8px;transition:all .15s;color:#fbcfe8" onmouseover="this.style.borderColor=\'#ec4899\';this.style.transform=\'translateY(-1px)\'" onmouseout="this.style.borderColor=\'rgba(236,72,153,.25)\';this.style.transform=\'translateY(0)\'">
<div style="font-size:11px;color:#f9a8d4;text-transform:uppercase;letter-spacing:.5px">Portal #3</div>
<div style="font-size:14px;font-weight:700;margin-top:4px">🎭 Arena Orchestrator</div>
<div style="font-size:11px;color:#fce7f3;margin-top:2px">310 intents · 385 skills · Command</div>
</a>
<a href="/agents-archi.html" target="_blank" style="text-decoration:none;padding:12px;background:rgba(16,185,129,.08);border:1px solid rgba(16,185,129,.25);border-radius:8px;transition:all .15s;color:#6ee7b7" onmouseover="this.style.borderColor=\'#10b981\';this.style.transform=\'translateY(-1px)\'" onmouseout="this.style.borderColor=\'rgba(16,185,129,.25)\';this.style.transform=\'translateY(0)\'">
<div style="font-size:11px;color:#6ee7b7;text-transform:uppercase;letter-spacing:.5px">Archi Visual #1</div>
<div style="font-size:14px;font-weight:700;margin-top:4px">🌐 Agents Archi 3D</div>
<div style="font-size:11px;color:#a7f3d0;margin-top:2px">5 tiers · particles · Three.js</div>
</a>
<a href="/architecture.html" target="_blank" style="text-decoration:none;padding:12px;background:rgba(251,191,36,.08);border:1px solid rgba(251,191,36,.25);border-radius:8px;transition:all .15s;color:#fde68a" onmouseover="this.style.borderColor=\'#fbbf24\';this.style.transform=\'translateY(-1px)\'" onmouseout="this.style.borderColor=\'rgba(251,191,36,.25)\';this.style.transform=\'translateY(0)\'">
<div style="font-size:11px;color:#fcd34d;text-transform:uppercase;letter-spacing:.5px">Archi Visual #2</div>
<div style="font-size:14px;font-weight:700;margin-top:4px">📐 Architecture Static</div>
<div style="font-size:11px;color:#fef3c7;margin-top:2px">Schema bloc · documentation</div>
</a>
<a href="/architecture-live.html" target="_blank" style="text-decoration:none;padding:12px;background:rgba(139,92,246,.08);border:1px solid rgba(139,92,246,.25);border-radius:8px;transition:all .15s;color:#c4b5fd" onmouseover="this.style.borderColor=\'#8b5cf6\';this.style.transform=\'translateY(-1px)\'" onmouseout="this.style.borderColor=\'rgba(139,92,246,.25)\';this.style.transform=\'translateY(0)\'">
<div style="font-size:11px;color:#c4b5fd;text-transform:uppercase;letter-spacing:.5px">Archi Visual #3</div>
<div style="font-size:14px;font-weight:700;margin-top:4px">⚡ Architecture Live</div>
<div style="font-size:11px;color:#ddd6fe;margin-top:2px">Heartbeat · real-time status</div>
</a>
</div>
</section>
<section id="wtp-drill-resolver-wave214" data-added-by="opus-wave-214" style="margin:24px 16px;padding:24px;background:linear-gradient(135deg,#3b0764 0%,#083344 100%);border:1px solid #a855f7;border-radius:12px;font-family:system-ui,sans-serif;box-shadow:0 10px 40px rgba(168,85,247,.2)">
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:18px">
<div>
<div style="display:flex;align-items:center;gap:10px">
<span style="font-size:22px">🧩</span>
<h2 style="margin:0;color:#e9d5ff;font-size:20px;font-weight:700">Drill-down 7σ Fails · Resolver Catalog</h2>
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#a855f7,#22d3ee);color:#fff;font-size:10px;font-weight:700;letter-spacing:.6px">WAVE 214</span>
</div>
<p style="margin:4px 0 0 0;color:#c4b5fd;font-size:12.5px">49 dimensions à fixer vers 7σ · 310 intents Resolver · 224 wired · gap 86</p>
</div>
<div id="wtp-dr-status" style="padding:6px 14px;border-radius:16px;background:rgba(168,85,247,.15);color:#ddd6fe;font-size:11px;font-weight:600;border:1px solid rgba(168,85,247,.3)">LOADING</div>
</div>
<!-- Two columns: 7σ fails + Resolver catalog -->
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(340px,1fr));gap:16px">
<!-- 7σ Fails drill-down -->
<div style="padding:18px;background:rgba(255,255,255,.03);border:1px solid rgba(251,146,60,.25);border-radius:10px">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px">
<span style="font-size:18px">🎯</span>
<h3 style="margin:0;color:#fed7aa;font-size:14px;font-weight:700">7σ Fails par page</h3>
<span id="wtp-dr-7s-count" style="margin-left:auto;padding:2px 8px;border-radius:10px;background:rgba(251,146,60,.15);color:#fdba74;font-size:10px;font-weight:700">...</span>
</div>
<div id="wtp-dr-7s-grid" style="max-height:340px;overflow-y:auto"></div>
</div>
<!-- Resolver Catalog -->
<div style="padding:18px;background:rgba(255,255,255,.03);border:1px solid rgba(139,92,246,.25);border-radius:10px">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px">
<span style="font-size:18px">🧠</span>
<h3 style="margin:0;color:#ddd6fe;font-size:14px;font-weight:700">Resolver Catalog</h3>
<span id="wtp-dr-res-count" style="margin-left:auto;padding:2px 8px;border-radius:10px;background:rgba(139,92,246,.15);color:#c4b5fd;font-size:10px;font-weight:700">...</span>
</div>
<div id="wtp-dr-res-kpi" style="display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin-bottom:12px"></div>
<div id="wtp-dr-res-domains" style="max-height:270px;overflow-y:auto"></div>
</div>
</div>
<script>
(function(){
function dimChip(name, ok){
var col = ok ? '#10b981' : '#ef4444';
return '<span style="padding:1px 6px;border-radius:8px;background:'+col+'22;color:'+col+';font-size:9.5px;font-weight:700;font-family:monospace;margin:1px">'+name+'</span>';
}
function pageRow(pg){
var fails = pg.fails || [];
var total_dims = pg.total_dims || 0;
var name = pg.id || pg.url || '?';
var col = fails.length === 0 ? '#10b981' : (fails.length <= 2 ? '#fbbf24' : '#ef4444');
var chips = fails.map(function(f){ return dimChip(f,false); }).join('');
return '<div style="padding:8px 10px;margin-bottom:6px;background:rgba(255,255,255,.02);border-left:3px solid '+col+';border-radius:4px">'
+'<div style="display:flex;align-items:center;justify-content:space-between;gap:8px"><div style="font-size:11.5px;color:#fed7aa;font-family:monospace;font-weight:600">'+name+'</div><div style="font-size:10px;color:'+col+';font-weight:700">'+fails.length+' fails</div></div>'
+'<div style="margin-top:4px">'+chips+'</div>'
+'</div>';
}
function kpiCard(label, value, color){
return '<div style="padding:8px 10px;background:rgba(139,92,246,.08);border:1px solid rgba(139,92,246,.18);border-radius:6px;text-align:center">'
+'<div style="font-size:9.5px;color:#c4b5fd;text-transform:uppercase;letter-spacing:.4px">'+label+'</div>'
+'<div style="font-size:18px;font-weight:700;color:'+color+';margin-top:2px">'+value+'</div>'
+'</div>';
}
function domainChip(name, info){
var cnt = (typeof info === 'number') ? info : (info.count || info.intents || 0);
return '<div style="display:flex;align-items:center;justify-content:space-between;padding:6px 10px;margin-bottom:4px;background:rgba(139,92,246,.05);border:1px solid rgba(139,92,246,.12);border-radius:6px;font-size:11px;color:#ddd6fe"><span style="font-family:monospace">'+name+'</span><span style="font-weight:700;color:#a78bfa">'+cnt+'</span></div>';
}
function render(){
// 7σ fails
fetch('/api/seven-sigma-latest.json?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var pages = d.pages || [];
var grid = document.getElementById('wtp-dr-7s-grid');
var badge = document.getElementById('wtp-dr-7s-count');
if (!grid) return;
var total_fails = 0;
var items = pages.map(function(p){
var dims = p.dimensions || {};
var fails = [];
Object.keys(dims).forEach(function(k){
var v = dims[k];
if (v && typeof v === 'object' && (v.status === 'FAIL' || v.status === 'fail')) fails.push(k);
});
total_fails += fails.length;
return {id: p.id || p.url, fails: fails, total_dims: Object.keys(dims).length};
}).sort(function(a,b){return b.fails.length - a.fails.length;});
if (badge) badge.textContent = total_fails+' fails / '+pages.length+' pages';
grid.innerHTML = items.map(pageRow).join('');
})
.catch(function(){
var grid = document.getElementById('wtp-dr-7s-grid');
if (grid) grid.innerHTML = '<div style="color:#f87171;font-size:11px;padding:10px">seven-sigma unavailable</div>';
});
// Resolver catalog
fetch('/api/arena-intent-registry.json?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var kpi = document.getElementById('wtp-dr-res-kpi');
var doms = document.getElementById('wtp-dr-res-domains');
var cnt = document.getElementById('wtp-dr-res-count');
var wired = d.wired || 0;
var gap = d.gap || 0;
var total = d.total_intents || (wired + gap);
var pct = total ? Math.round(wired*100/total) : 0;
if (cnt) cnt.textContent = wired+'/'+total+' ('+pct+'%)';
if (kpi) {
kpi.innerHTML = kpiCard('INTENTS', total, '#ddd6fe')
+ kpiCard('SKILLS', d.total_skills||0, '#c4b5fd')
+ kpiCard('WIRED', wired, '#10b981')
+ kpiCard('GAP', gap, gap===0?'#10b981':'#fbbf24');
}
if (doms) {
var domains = d.domains || {};
var html = '<div style="font-size:10px;color:#c4b5fd;text-transform:uppercase;letter-spacing:.5px;margin-bottom:6px">Domains · '+Object.keys(domains).length+'</div>';
if (Array.isArray(domains)) {
html += domains.map(function(n){return domainChip(n, 0);}).join('');
} else {
Object.keys(domains).forEach(function(k){ html += domainChip(k, domains[k]); });
}
doms.innerHTML = html;
}
})
.catch(function(){
var doms = document.getElementById('wtp-dr-res-domains');
if (doms) doms.innerHTML = '<div style="color:#f87171;font-size:11px;padding:10px">registry unavailable</div>';
});
var status = document.getElementById('wtp-dr-status');
if (status) { status.textContent = 'LIVE'; status.style.background='rgba(16,185,129,.2)'; status.style.color='#6ee7b7'; }
}
render();
setInterval(render, 180000);
})();
</script>
</section>
<section id="wtp-visual-mgmt-wave212" data-added-by="opus-wave-212" style="margin:32px 16px 20px;padding:28px;background:linear-gradient(135deg,#164e63 0%,#1e3a8a 100%);border:1px solid #0ea5e9;border-radius:14px;font-family:system-ui,sans-serif;box-shadow:0 10px 40px rgba(14,165,233,.2)">
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:18px">
<div>
<div style="display:flex;align-items:center;gap:10px">
<span style="font-size:22px">🎯</span>
<h2 style="margin:0;color:#bae6fd;font-size:20px;font-weight:700">Visual Management · L99 · Lean 6 Sigma</h2>
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#0ea5e9,#10b981);color:#fff;font-size:10px;font-weight:700;letter-spacing:.6px">WAVE 212</span>
</div>
<p style="margin:4px 0 0 0;color:#7dd3fc;font-size:12.5px">12 layers · 340 tests · 7σ quality · temps réel</p>
</div>
<div id="wtp-vm-status" style="padding:6px 14px;border-radius:16px;background:rgba(14,165,233,.15);color:#7dd3fc;font-size:11px;font-weight:600;border:1px solid rgba(14,165,233,.3)">LOADING</div>
</div>
<!-- Hero KPIs -->
<div id="wtp-vm-hero" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;margin-bottom:20px"></div>
<!-- L99 layers grid -->
<div style="font-size:11px;color:#7dd3fc;text-transform:uppercase;letter-spacing:1px;margin-bottom:10px">L99 · 12 layers · live</div>
<div id="wtp-vm-layers" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px;margin-bottom:18px"></div>
<!-- 7σ / Lean Sigma -->
<div style="font-size:11px;color:#7dd3fc;text-transform:uppercase;letter-spacing:1px;margin-bottom:10px">7σ Playwright Quality · E2E</div>
<div id="wtp-vm-sigma" style="padding:16px;background:rgba(255,255,255,.03);border:1px solid rgba(14,165,233,.2);border-radius:10px"></div>
<script>
(function(){
function donutSVG(pct, size, color){
size = size || 56;
var r = size/2 - 5;
var c = 2 * Math.PI * r;
var dash = (pct/100) * c;
var col = color || (pct >= 90 ? '#10b981' : (pct >= 75 ? '#fbbf24' : '#ef4444'));
return '<svg width="'+size+'" height="'+size+'" viewBox="0 0 '+size+' '+size+'">'
+'<circle cx="'+(size/2)+'" cy="'+(size/2)+'" r="'+r+'" fill="none" stroke="rgba(255,255,255,.08)" stroke-width="4"/>'
+'<circle cx="'+(size/2)+'" cy="'+(size/2)+'" r="'+r+'" fill="none" stroke="'+col+'" stroke-width="4" stroke-dasharray="'+dash+' '+c+'" stroke-linecap="round" transform="rotate(-90 '+(size/2)+' '+(size/2)+')"/>'
+'<text x="'+(size/2)+'" y="'+(size/2+4)+'" text-anchor="middle" fill="#bae6fd" font-size="13" font-weight="700">'+Math.round(pct)+'</text>'
+'</svg>';
}
function heroCard(label, value, sub, color, icon){
return '<div style="padding:14px;background:rgba(255,255,255,.03);border:1px solid rgba(14,165,233,.2);border-radius:10px">'
+'<div style="font-size:10.5px;color:#7dd3fc;text-transform:uppercase;letter-spacing:.6px">'+icon+' '+label+'</div>'
+'<div style="font-size:26px;font-weight:700;color:'+color+';margin:4px 0">'+value+'</div>'
+'<div style="font-size:11px;color:#64748b">'+sub+'</div>'
+'</div>';
}
function layerCard(name, info){
var pct = info.pct || 0;
var p = info.pass || 0;
var t = info.total || 0;
var col = pct >= 95 ? '#10b981' : (pct >= 80 ? '#fbbf24' : '#ef4444');
return '<div style="padding:12px;background:rgba(255,255,255,.03);border:1px solid rgba(14,165,233,.15);border-radius:10px;display:flex;align-items:center;gap:10px">'
+ donutSVG(pct,54,col)
+'<div style="flex:1;min-width:0">'
+'<div style="font-size:11.5px;color:#bae6fd;font-weight:600;margin-bottom:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">'+name+'</div>'
+'<div style="font-size:13px;color:'+col+';font-weight:700">'+p+'/'+t+'</div>'
+'<div style="font-size:10px;color:#64748b;margin-top:2px">'+(pct===100?'perfect':(pct>=80?'ok':'needs fix'))+'</div>'
+'</div>'
+'</div>';
}
function render(){
// L99 state
fetch('/api/l99-api.php?action=stats&cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var hero = document.getElementById('wtp-vm-hero');
var total = d.total || 340;
var pass = d.pass || 336;
var fail = d.fail || (total - pass);
var score = d.score || Math.round(pass*100/total);
var videos = d.videos || 32;
var ss = d.screenshots || 14;
if (hero) {
hero.innerHTML = heroCard('L99 Score', score+'%', pass+'/'+total, score>=95?'#10b981':'#fbbf24', '✅')
+ heroCard('Fails', fail, fail===0?'all green':'à corriger', fail===0?'#10b981':'#ef4444', '❌')
+ heroCard('Layers', '12', 'axes qualité', '#bae6fd', '📚')
+ heroCard('Vidéos', videos, 'E2E records', '#a5f3fc', '🎬')
+ heroCard('Screenshots', ss, 'proof visual', '#fbcfe8', '📸');
}
// Layers detail - fetch state file
fetch('/api/l99-state-file.php?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(s){
var grid = document.getElementById('wtp-vm-layers');
if (!grid || !s.layers) return;
var html = '';
Object.keys(s.layers).forEach(function(k){ html += layerCard(k, s.layers[k]); });
grid.innerHTML = html;
})
.catch(function(){
// Fallback: static layer rendering with known state
var grid = document.getElementById('wtp-vm-layers');
if (!grid) return;
var known = {
DOCKER:{pass:19,total:19,pct:100}, 'PORTS-S204':{pass:5,total:5,pct:100}, SYSTEMD:{pass:2,total:2,pct:100},
CRONS:{pass:35,total:35,pct:100}, NONREG:{pass:153,total:153,pct:100}, SOVEREIGN:{pass:10,total:10,pct:100},
QDRANT:{pass:4,total:4,pct:100}, 'S95-HEALTH':{pass:3,total:3,pct:100}, CAPABILITIES:{pass:10,total:10,pct:100},
'PLAYWRIGHT-VISUAL':{pass:20,total:24,pct:83}, 'FULLSCAN-L99':{pass:60,total:60,pct:100}, 'VISUAL-L99':{pass:15,total:15,pct:100}
};
var html = '';
Object.keys(known).forEach(function(k){ html += layerCard(k, known[k]); });
grid.innerHTML = html;
});
});
// 7σ Sigma
fetch('/api/seven-sigma-latest.json?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var sig = document.getElementById('wtp-vm-sigma');
var s = d.summary || {};
var pages = s.pages_tested || 0;
var dims = s.total_dimensions || 0;
var p = s.pass || 0;
var f = s.fail || 0;
var rate = s.pass_rate_pct || 0;
var lvl = s.sigma_level || '?';
var lvlColor = rate >= 90 ? '#10b981' : (rate >= 70 ? '#fbbf24' : '#f97316');
if (sig) {
sig.innerHTML = '<div style="display:grid;grid-template-columns:auto 1fr;gap:20px;align-items:center">'
+'<div style="text-align:center">'+donutSVG(rate,96,lvlColor)+'<div style="font-size:16px;font-weight:700;color:'+lvlColor+';margin-top:6px">'+lvl+'</div></div>'
+'<div>'
+'<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:10px">'
+heroCard('Pages testées', pages, 'E2E scope', '#bae6fd', '📄')
+heroCard('Dimensions', dims, 'checkpoints', '#a5f3fc', '🎯')
+heroCard('Pass', p, pages?'sur '+pages+' pages':'', '#10b981', '✓')
+heroCard('Fail', f, f>0?'à corriger':'all green', f>0?'#ef4444':'#10b981', '✗')
+'</div>'
+'<div style="font-size:11px;color:#7dd3fc">🔬 Target: 7σ (99.9999%) · Current: '+lvl+' ('+rate+'%) · gap '+(100-rate)+'% to 7σ</div>'
+'</div>'
+'</div>';
}
})
.catch(function(e){
var sig = document.getElementById('wtp-vm-sigma');
if (sig) sig.innerHTML = '<div style="color:#f87171;font-size:12px">seven-sigma endpoint unavailable</div>';
});
var status = document.getElementById('wtp-vm-status');
if (status) { status.textContent='LIVE'; status.style.background='rgba(16,185,129,.2)'; status.style.color='#6ee7b7'; }
}
render();
setInterval(render, 120000);
})();
</script>
</section>
<section id="wtp-tips-truth-wave211" data-added-by="opus-wave-211" style="margin:32px 16px 20px;padding:28px;background:linear-gradient(135deg,#1e1b4b 0%,#042f2e 100%);border:1px solid #8b5cf6;border-radius:14px;font-family:system-ui,sans-serif;box-shadow:0 10px 40px rgba(139,92,246,.2)">
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:18px">
<div>
<div style="display:flex;align-items:center;gap:10px">
<span style="font-size:22px">📚</span>
<h2 style="margin:0;color:#e9d5ff;font-size:20px;font-weight:700">Truth Registry Hero · 28 Tips Catalog · Intelligence 6 mois</h2>
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#8b5cf6,#06b6d4);color:#fff;font-size:10px;font-weight:700;letter-spacing:.6px">WAVE 211</span>
</div>
<p style="margin:4px 0 0 0;color:#a78bfa;font-size:12.5px">Source vérité unifiée · GODMODE 100 · clic tip → fiche détaillée via Master chat</p>
</div>
<div id="wtp-tt-status" style="padding:6px 14px;border-radius:16px;background:rgba(139,92,246,.15);color:#c4b5fd;font-size:11px;font-weight:600;border:1px solid rgba(139,92,246,.3)">LOADING</div>
</div>
<!-- Truth Registry Hero Grid (6 scalars) -->
<div id="wtp-tt-truth-grid" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin-bottom:20px"></div>
<!-- Tips Cards by Category -->
<div style="font-size:11px;color:#a78bfa;text-transform:uppercase;letter-spacing:1px;margin-bottom:10px;margin-top:4px">28 Tips cybersec/dev cracked 6 months · clic → détail via Master</div>
<div id="wtp-tt-tips-grid" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px"></div>
<!-- Detail panel -->
<div id="wtp-tt-detail" style="display:none;margin-top:18px;padding:18px;background:rgba(139,92,246,.08);border:1px solid rgba(139,92,246,.25);border-radius:10px"></div>
<script>
(function(){
var TIPS = [
{id:'token_rotation', cat:'AUTH', icon:'🔑', color:'#f59e0b', label:'Token Rotation'},
{id:'office_recovery', cat:'EMAIL', icon:'📧', color:'#0ea5e9', label:'Office Recovery'},
{id:'deepseek_web', cat:'AI-WEB', icon:'🧠', color:'#a855f7', label:'DeepSeek Web'},
{id:'perplexity_web', cat:'AI-WEB', icon:'🔮', color:'#a855f7', label:'Perplexity Web'},
{id:'thuggie_cookies', cat:'AI-WEB', icon:'🍪', color:'#a855f7', label:'Thuggie Cookies'},
{id:'opus46_mythos', cat:'AI-WEB', icon:'✨', color:'#ec4899', label:'Opus4.6 Mythos'},
{id:'jwt_refresh', cat:'AUTH', icon:'🔄', color:'#f59e0b', label:'JWT Refresh'},
{id:'chattr_dance', cat:'OPS', icon:'🔐', color:'#84cc16', label:'chattr Dance'},
{id:'cx_relay', cat:'OPS', icon:'📡', color:'#84cc16', label:'CX Relay'},
{id:'sentinel_backup', cat:'OPS', icon:'💾', color:'#84cc16', label:'Sentinel Backup'},
{id:'pmta_smtp', cat:'EMAIL', icon:'📨', color:'#0ea5e9', label:'PMTA SMTP'},
{id:'3mta', cat:'EMAIL', icon:'📯', color:'#0ea5e9', label:'3 MTA Coexist'},
{id:'chrome_profile', cat:'AUTOMATION', icon:'🌐', color:'#06b6d4', label:'Chrome Profile'},
{id:'user_agent_spoof', cat:'AUTOMATION', icon:'🎭', color:'#06b6d4', label:'User-Agent Spoof'},
{id:'cookies_persist', cat:'AUTOMATION', icon:'🍪', color:'#06b6d4', label:'Cookies Persist'},
{id:'captcha_bypass', cat:'AUTOMATION', icon:'🛡', color:'#06b6d4', label:'Captcha Bypass'},
{id:'webshare_proxy', cat:'AUTOMATION', icon:'🌍', color:'#06b6d4', label:'Webshare Proxy'},
{id:'claude_subagents', cat:'DEV', icon:'🤖', color:'#22d3ee', label:'Claude Subagents'},
{id:'skills_million', cat:'DEV', icon:'🛠', color:'#22d3ee', label:'1M Skills'},
{id:'oss_clones', cat:'DEV', icon:'📦', color:'#22d3ee', label:'OSS Clones'},
{id:'release_train', cat:'DEV', icon:'🚂', color:'#22d3ee', label:'Release Train'},
{id:'b12_wikis', cat:'DEV', icon:'📖', color:'#22d3ee', label:'B12 Wikis'},
{id:'dns_spf_dkim', cat:'INFRA', icon:'🌐', color:'#ef4444', label:'DNS SPF DKIM'},
{id:'gmail_workspace', cat:'INFRA', icon:'📬', color:'#ef4444', label:'Gmail Workspace'},
{id:'truth_registry', cat:'INFRA', icon:'📚', color:'#ef4444', label:'Truth Registry'},
{id:'qdrant_vectorize', cat:'INFRA', icon:'🧮', color:'#ef4444', label:'Qdrant Vectorize'},
{id:'blade_yacineutt', cat:'INFRA', icon:'🗡', color:'#ef4444', label:'Blade YacineUtt'},
{id:'zero_dormant', cat:'INFRA', icon:'⚡', color:'#ef4444', label:'Zero Dormant'}
];
function truthCard(label, value, icon, color){
return '<div style="padding:14px;background:rgba(255,255,255,.03);border:1px solid rgba(139,92,246,.15);border-radius:10px">'
+'<div style="font-size:10.5px;color:#a78bfa;text-transform:uppercase;letter-spacing:.6px;display:flex;align-items:center;gap:4px">'+icon+' '+label+'</div>'
+'<div style="font-size:18px;font-weight:700;color:'+color+';margin-top:6px;word-break:break-all">'+value+'</div>'
+'</div>';
}
function renderTruth(){
var el = document.getElementById('wtp-tt-truth-grid');
if (!el) return;
fetch('/api/read_truth_registry.php?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var h = d.headlines || {};
var s = d.scalars || {};
var lvlColor = h.autonomy_level === 'GODMODE' ? '#22d3ee' : '#10b981';
el.innerHTML = truthCard('Autonomy', (h.autonomy_level||'?')+' · '+h.autonomy_score+'/100', '🚀', lvlColor)
+ truthCard('APIs PHP', s.apis_php_count||0, '⚙️', '#60a5fa')
+ truthCard('Version', s.version||'?', '🏷', '#c4b5fd')
+ truthCard('Built', (s.built_at||'').slice(0,10), '📅', '#fbbf24')
+ truthCard('Purpose', (s.purpose||'').slice(0,40)+'...', '🎯', '#6ee7b7')
+ truthCard('Registry Size', Math.round(d.bytes/1024)+' KB', '📊', '#f87171');
});
}
function tipCard(tip){
return '<div onclick="window.__wtpTtShow(\''+tip.id+'\',\''+tip.label.replace(/\x27/g,"")+'\',\''+tip.icon+'\',\''+tip.color+'\')" style="cursor:pointer;padding:12px;background:rgba(255,255,255,.03);border:1px solid rgba(139,92,246,.15);border-radius:10px;transition:all .2s" onmouseover="this.style.borderColor=\'#a855f7\';this.style.transform=\'translateY(-2px)\';this.style.boxShadow=\'0 4px 12px rgba(168,85,247,.2)\'" onmouseout="this.style.borderColor=\'rgba(139,92,246,.15)\';this.style.transform=\'translateY(0)\';this.style.boxShadow=\'none\'">'
+'<div style="display:flex;align-items:center;gap:8px;margin-bottom:4px"><span style="font-size:18px">'+tip.icon+'</span><span style="padding:1px 6px;border-radius:8px;background:'+tip.color+'22;color:'+tip.color+';font-size:9px;font-weight:700">'+tip.cat+'</span></div>'
+'<div style="font-size:12px;color:#e9d5ff;font-weight:600;margin-bottom:2px">'+tip.label+'</div>'
+'<div style="font-size:10px;color:#71717a;font-family:monospace">tip_'+tip.id+'</div>'
+'</div>';
}
function renderTips(){
var el = document.getElementById('wtp-tt-tips-grid');
if (el) el.innerHTML = TIPS.map(tipCard).join('');
}
window.__wtpTtShow = function(tipId, label, icon, color){
var d = document.getElementById('wtp-tt-detail');
if (!d) return;
d.style.display = 'block';
d.innerHTML = '<div style="display:flex;align-items:center;gap:10px;margin-bottom:12px"><span style="font-size:24px">'+icon+'</span><h3 style="margin:0;color:#e9d5ff;font-size:16px">'+label+'</h3><div style="margin-left:auto;padding:3px 10px;border-radius:10px;background:'+color+'22;color:'+color+';font-size:10px;font-weight:700;font-family:monospace">tip_'+tipId+'</div><button onclick="document.getElementById(\'wtp-tt-detail\').style.display=\'none\'" style="padding:4px 10px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.2);border-radius:12px;color:#c4b5fd;font-size:11px;cursor:pointer">Fermer</button></div>'
+'<div id="wtp-tt-detail-body" style="color:#e9d5ff;font-family:monospace;font-size:11.5px;line-height:1.55;padding:12px;background:rgba(0,0,0,.3);border-radius:8px;min-height:60px">⏳ Master consulte...</div>';
fetch('/api/wevia-autonomous.php?test', {
method:'POST',
headers:{'Content-Type':'application/json'},
body: JSON.stringify({message: 'tip_'+tipId})
}).then(function(r){return r.text();})
.then(function(raw){
var body = document.getElementById('wtp-tt-detail-body');
if (!body) return;
var events = raw.split('\n').filter(function(l){return l.indexOf('data:')===0;})
.map(function(l){ try { return JSON.parse(l.substring(5).trim()); } catch(e){ return null; } })
.filter(Boolean);
var ans = events.find(function(e){return e.type==='answer'||e.type==='exec';});
if (ans) {
var txt = ans.text || '';
// Try to JSON-pretty-print if it's JSON
try {
var parsed = JSON.parse(txt);
txt = JSON.stringify(parsed, null, 2);
body.innerHTML = '<pre style="margin:0;white-space:pre-wrap;word-break:break-word">'+txt.replace(/</g,'&lt;')+'</pre>';
} catch(e){
body.style.whiteSpace = 'pre-wrap';
body.textContent = txt;
}
} else {
body.textContent = 'Aucune réponse Master. Raw events: '+events.length;
}
})
.catch(function(e){
var body = document.getElementById('wtp-tt-detail-body');
if (body) body.textContent = '❌ Erreur: '+String(e).slice(0,200);
});
d.scrollIntoView({behavior:'smooth',block:'nearest'});
};
function init(){
renderTruth();
renderTips();
var status = document.getElementById('wtp-tt-status');
if (status) { status.textContent = 'LIVE · '+TIPS.length+' tips'; status.style.background='rgba(16,185,129,.15)'; status.style.color='#6ee7b7'; }
}
init();
})();
</script>
</section>
<section id="wtp-multiagent-wave210" data-added-by="opus-wave-210" style="margin:32px 16px 20px;padding:28px;background:radial-gradient(circle at 80% 20%,#083344,#0c0a09 60%);border:1px solid #0891b2;border-radius:14px;font-family:system-ui,sans-serif;box-shadow:0 10px 40px rgba(8,145,178,.2)">
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:18px">
<div>
<div style="display:flex;align-items:center;gap:10px;margin-bottom:4px">
<span style="font-size:22px">🤖</span>
<h2 style="margin:0;color:#a5f3fc;font-size:20px;font-weight:700">Multi-Agent Console · WEVIA Master Live</h2>
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#06b6d4,#8b5cf6);color:#fff;font-size:10px;font-weight:700;letter-spacing:.6px">WAVE 210</span>
</div>
<p style="margin:0;color:#67e8f9;font-size:12.5px">Solicitation directe du Master · 1000 agents · 28+ tips · intents routeur live</p>
</div>
<div id="wtp-ma-status" style="padding:6px 14px;border-radius:16px;background:rgba(6,182,212,.12);color:#67e8f9;font-size:11px;font-weight:600;border:1px solid rgba(6,182,212,.3)">READY</div>
</div>
<div style="display:grid;grid-template-columns:1fr auto;gap:8px;margin-bottom:14px">
<input id="wtp-ma-input" type="text" placeholder="Ex: list intents · tip_deepseek_web · status · audit doublons · agents count"
style="padding:12px 16px;background:rgba(255,255,255,.04);border:1px solid rgba(6,182,212,.3);border-radius:10px;color:#e0f2fe;font-size:13px;font-family:inherit;outline:none"
onkeydown="if(event.key==='Enter'){window.__wtpMaSend();event.preventDefault();}" />
<button onclick="window.__wtpMaSend()" style="padding:12px 22px;background:linear-gradient(135deg,#06b6d4,#8b5cf6);color:#fff;border:0;border-radius:10px;cursor:pointer;font-size:13px;font-weight:700;box-shadow:0 4px 14px rgba(6,182,212,.3)">Solliciter →</button>
</div>
<div style="display:flex;gap:6px;margin-bottom:14px;flex-wrap:wrap">
<button onclick="window.__wtpMaQuick('list intents')" style="padding:5px 12px;border-radius:12px;background:rgba(99,102,241,.15);color:#c7d2fe;border:1px solid rgba(99,102,241,.3);font-size:11px;cursor:pointer;font-weight:600">⚡ intents</button>
<button onclick="window.__wtpMaQuick('liste tous les tips')" style="padding:5px 12px;border-radius:12px;background:rgba(16,185,129,.15);color:#6ee7b7;border:1px solid rgba(16,185,129,.3);font-size:11px;cursor:pointer;font-weight:600">💡 tips (28)</button>
<button onclick="window.__wtpMaQuick('status')" style="padding:5px 12px;border-radius:12px;background:rgba(245,158,11,.15);color:#fcd34d;border:1px solid rgba(245,158,11,.3);font-size:11px;cursor:pointer;font-weight:600">📊 status</button>
<button onclick="window.__wtpMaQuick('agents count')" style="padding:5px 12px;border-radius:12px;background:rgba(236,72,153,.15);color:#fbcfe8;border:1px solid rgba(236,72,153,.3);font-size:11px;cursor:pointer;font-weight:600">🤖 agents</button>
<button onclick="window.__wtpMaQuick('tip_deepseek_web')" style="padding:5px 12px;border-radius:12px;background:rgba(168,85,247,.15);color:#ddd6fe;border:1px solid rgba(168,85,247,.3);font-size:11px;cursor:pointer;font-weight:600">🧠 DeepSeek</button>
<button onclick="window.__wtpMaQuick('tip_blade_yacineutt')" style="padding:5px 12px;border-radius:12px;background:rgba(244,114,182,.15);color:#fecdd3;border:1px solid rgba(244,114,182,.3);font-size:11px;cursor:pointer;font-weight:600">🗡 Blade</button>
<button onclick="window.__wtpMaQuick('tip_office_recovery')" style="padding:5px 12px;border-radius:12px;background:rgba(14,165,233,.15);color:#bae6fd;border:1px solid rgba(14,165,233,.3);font-size:11px;cursor:pointer;font-weight:600">📧 Office</button>
<button onclick="window.__wtpMaQuick('tip_chattr_dance')" style="padding:5px 12px;border-radius:12px;background:rgba(132,204,22,.15);color:#d9f99d;border:1px solid rgba(132,204,22,.3);font-size:11px;cursor:pointer;font-weight:600">🔐 chattr</button>
<button onclick="window.__wtpMaQuick('doctrine supreme')" style="padding:5px 12px;border-radius:12px;background:rgba(251,191,36,.15);color:#fde68a;border:1px solid rgba(251,191,36,.3);font-size:11px;cursor:pointer;font-weight:600">📜 doctrine</button>
<button onclick="window.__wtpCfPurge()" style="padding:5px 12px;border-radius:12px;background:rgba(249,115,22,.15);color:#fed7aa;border:1px solid rgba(249,115,22,.3);font-size:11px;cursor:pointer;font-weight:600">🔄 CF purge WTP</button>
<button onclick="window.__wtpMaQuick('selenium chrome')" style="padding:5px 12px;border-radius:12px;background:rgba(132,204,22,.15);color:#d9f99d;border:1px solid rgba(132,204,22,.3);font-size:11px;cursor:pointer;font-weight:600">🌐 Selenium</button>
<button onclick="window.__wtpMaQuick('office recovery')" style="padding:5px 12px;border-radius:12px;background:rgba(14,165,233,.15);color:#bae6fd;border:1px solid rgba(14,165,233,.3);font-size:11px;cursor:pointer;font-weight:600">📧 Office</button>
<button onclick="window.__wtpMaQuick('bilan ethica')" style="padding:5px 12px;border-radius:12px;background:rgba(236,72,153,.15);color:#fbcfe8;border:1px solid rgba(236,72,153,.3);font-size:11px;cursor:pointer;font-weight:600">💊 Ethica</button>
<button onclick="window.__wtpMaQuick('nonreg')" style="padding:5px 12px;border-radius:12px;background:rgba(16,185,129,.15);color:#6ee7b7;border:1px solid rgba(16,185,129,.3);font-size:11px;cursor:pointer;font-weight:600">✅ NonReg</button>
</div>
<div id="wtp-ma-conversation" style="min-height:80px;max-height:520px;overflow-y:auto;padding:16px;background:rgba(0,0,0,.25);border:1px solid rgba(6,182,212,.2);border-radius:10px;font-family:ui-monospace,monospace;font-size:12px;color:#e0f2fe;line-height:1.5">
<div style="color:#64748b;font-style:italic;font-size:12px">Tapez une question ou cliquez un quick-action pour solliciter le Master.</div>
</div>
<script>
(function(){
var conv = document.getElementById('wtp-ma-conversation');
var status = document.getElementById('wtp-ma-status');
var input = document.getElementById('wtp-ma-input');
function append(role, txt, meta){
var el = document.createElement('div');
el.style.cssText = 'margin-bottom:14px;padding:10px 12px;border-radius:8px;animation:fadeIn .3s';
if (role === 'user') {
el.style.background = 'rgba(99,102,241,.1)';
el.style.borderLeft = '3px solid #818cf8';
el.innerHTML = '<div style="font-size:10px;color:#a5b4fc;font-weight:600;text-transform:uppercase;margin-bottom:4px">YACINE</div><div style="color:#e0e7ff;white-space:pre-wrap">'+txt.replace(/</g,'&lt;')+'</div>';
} else if (role === 'system') {
el.style.background = 'rgba(71,85,105,.1)';
el.style.borderLeft = '3px solid #64748b';
el.innerHTML = '<div style="color:#94a3b8;font-size:11px;font-style:italic">'+txt+'</div>';
} else {
el.style.background = 'rgba(6,182,212,.08)';
el.style.borderLeft = '3px solid #22d3ee';
var metaStr = meta ? '<div style="font-size:10px;color:#67e8f9;margin-top:6px;padding-top:6px;border-top:1px solid rgba(6,182,212,.15)">'+meta+'</div>' : '';
el.innerHTML = '<div style="font-size:10px;color:#67e8f9;font-weight:600;text-transform:uppercase;margin-bottom:4px">🤖 MASTER</div><div style="color:#e0f2fe;white-space:pre-wrap;word-break:break-word">'+txt.replace(/</g,'&lt;')+'</div>'+metaStr;
}
conv.appendChild(el);
conv.scrollTop = conv.scrollHeight;
return el;
}
window.__wtpMaQuick = function(q){ input.value = q; window.__wtpMaSend(); };
window.__wtpCfPurge = function(){
var btn = event.target;
btn.disabled = true;
var orig = btn.textContent;
btn.textContent = '⏳ purging...';
fetch('/api/cf-purge.php?files=/weval-technology-platform.html,/api/wevia-autonomous.php', {cache:'no-store'})
.then(function(r){return r.json();})
.then(function(d){
btn.textContent = d.ok ? '✅ CF purgé' : '❌ échec';
setTimeout(function(){ btn.textContent = orig; btn.disabled = false; }, 3000);
if (d.ok && typeof window.__wtpMaSend !== 'undefined') {
// Log to conversation if console visible
var conv = document.getElementById('wtp-ma-conversation');
if (conv) {
var el = document.createElement('div');
el.style.cssText = 'margin-bottom:10px;padding:8px 10px;background:rgba(249,115,22,.1);border-left:3px solid #fb923c;border-radius:6px';
el.innerHTML = '<div style="font-size:11px;color:#fed7aa">🔄 Cloudflare purge WTP · cf_id='+(d.cf_response&&d.cf_response.result?d.cf_response.result.id:'?').slice(0,12)+'</div>';
conv.appendChild(el);
conv.scrollTop = conv.scrollHeight;
}
}
})
.catch(function(e){
btn.textContent = '❌ err';
setTimeout(function(){ btn.textContent = orig; btn.disabled = false; }, 2000);
});
};
window.__wtpMaSend = function(){
var q = (input.value||'').trim();
if (!q) return;
if (status) { status.textContent = 'ENVOI...'; status.style.background='rgba(251,191,36,.2)'; status.style.color='#fcd34d'; }
append('user', q);
input.value = '';
var loading = append('system', '⏳ Master analyse...');
fetch('/api/wevia-autonomous.php?test', {
method: 'POST',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({message: q})
}).then(function(r){return r.text();})
.then(function(raw){
try { loading.remove(); } catch(e){}
// Parse SSE
var events = raw.split('\n').filter(function(l){return l.indexOf('data:') === 0;})
.map(function(l){ try { return JSON.parse(l.substring(5).trim()); } catch(e) { return null; } })
.filter(Boolean);
var answer = events.find(function(e){return e.type==='answer' || e.type==='exec';});
var thinking = events.filter(function(e){return e.type==='thinking';});
var actions = events.filter(function(e){return e.type==='action' || e.type==='action_done';});
if (thinking.length > 0) {
append('system', '🧠 ' + thinking.map(function(t){return t.step;}).filter(Boolean).join(' → '));
}
if (actions.length > 0) {
append('system', '⚙️ Actions: ' + actions.map(function(a){return (a.name||'?')+(a.preview?' ('+a.preview.slice(0,60)+')':'');}).join(' · '));
}
if (answer) {
var txt = answer.text || '(empty)';
if (txt.length > 4000) txt = txt.slice(0,4000) + '\n... (tronque)';
var meta = 'engine: '+(answer.engine||'?')+' · intent: '+(answer.intent||'?');
append('master', txt, meta);
} else {
append('master', raw.slice(0,500), 'raw events: '+events.length);
}
if (status) { status.textContent = 'READY'; status.style.background='rgba(16,185,129,.15)'; status.style.color='#6ee7b7'; }
})
.catch(function(e){
try { loading.remove(); } catch(ex){}
append('system', '❌ Erreur: '+String(e).slice(0,100));
if (status) { status.textContent = 'ERR'; status.style.background='rgba(239,68,68,.2)'; status.style.color='#fca5a5'; }
});
};
})();
</script>
</section>
<section id="wtp-kpi-alert-wave218" data-added-by="opus-wave-218" style="margin:18px 16px 0;padding:12px 18px;background:rgba(15,23,42,.6);border:1px solid rgba(34,211,238,.2);border-radius:10px;font-family:system-ui,sans-serif;display:flex;align-items:center;gap:14px;flex-wrap:wrap">
<div style="display:flex;align-items:center;gap:8px">
<span style="font-size:16px">🚨</span>
<span style="font-size:11px;color:#94a3b8;text-transform:uppercase;letter-spacing:.6px;font-weight:600">Alerting Live</span>
<span style="padding:3px 9px;border-radius:10px;background:linear-gradient(135deg,#22d3ee,#a855f7);color:#fff;font-size:10px;font-weight:700">WAVE 218</span>
</div>
<div id="wtp-alert-badges" style="display:flex;gap:6px;flex-wrap:wrap;flex:1"></div>
<div id="wtp-alert-status" style="padding:4px 12px;border-radius:12px;background:rgba(71,85,105,.3);color:#cbd5e1;font-size:11px;font-weight:600;border:1px solid rgba(71,85,105,.5)">loading...</div>
<script>
(function(){
function badge(label, count, color, icon){
var bgA = color+'22', txt = color;
return '<span style="padding:3px 10px;border-radius:10px;background:'+bgA+';color:'+txt+';font-size:11px;font-weight:700;border:1px solid '+color+'55">'+icon+' '+label+': '+count+'</span>';
}
function refresh(){
Promise.all([
fetch('/api/v83-business-kpi-dashboard-data.php?cb='+Date.now()).then(function(r){return r.json();}).catch(function(){return null;}),
fetch('/api/nonreg-api.php?cb='+Date.now()).then(function(r){return r.json();}).catch(function(){return null;}),
fetch('/api/l99-api.php?action=stats&cb='+Date.now()).then(function(r){return r.json();}).catch(function(){return null;})
]).then(function(res){
var kpi = res[0], nr = res[1], l99 = res[2];
var badges = document.getElementById('wtp-alert-badges');
var status = document.getElementById('wtp-alert-status');
if (!badges) return;
var html = '';
var hasFail = false, hasWarn = false;
if (kpi && kpi.summary) {
var s = kpi.summary;
var fail = s.fail || 0;
var warn = s.warn || 0;
var ok = s.ok || 0;
var wn = s.wire_needed || 0;
var dc = s.data_completeness_pct || 0;
html += badge('KPIs OK', ok, '#10b981', '✓');
html += badge('WARN', warn, warn>0?'#fbbf24':'#6b7280', '⚠');
html += badge('FAIL', fail, fail>0?'#ef4444':'#10b981', '✗');
html += badge('wire_needed', wn, wn>0?'#94a3b8':'#10b981', '🔗');
html += badge('Completeness', dc+'%', dc>=90?'#10b981':(dc>=75?'#fbbf24':'#ef4444'), '📊');
if (fail > 0) hasFail = true;
if (warn > 0 || dc < 90) hasWarn = true;
}
if (nr) {
var nrs = nr.summary || nr;
var np = nrs.pass||0, nt = nrs.total||0;
var nrok = np === nt && nt > 0;
html += badge('NonReg', np+'/'+nt, nrok?'#10b981':'#ef4444', '🧪');
if (!nrok) hasFail = true;
}
if (l99) {
var lp = l99.pass||0, lt = l99.total||0;
var lpct = lt ? Math.round(lp*100/lt) : 0;
html += badge('L99', lp+'/'+lt+' ('+lpct+'%)', lpct>=95?'#10b981':(lpct>=85?'#fbbf24':'#ef4444'), '🎯');
if (lpct < 85) hasWarn = true;
}
badges.innerHTML = html;
if (status) {
if (hasFail) {
status.textContent = '🚨 FAIL'; status.style.background='rgba(239,68,68,.2)'; status.style.color='#fca5a5'; status.style.borderColor='rgba(239,68,68,.4)';
} else if (hasWarn) {
status.textContent = '⚠️ WARN'; status.style.background='rgba(251,191,36,.2)'; status.style.color='#fde68a'; status.style.borderColor='rgba(251,191,36,.4)';
} else {
status.textContent = '✅ ALL GREEN'; status.style.background='rgba(16,185,129,.2)'; status.style.color='#6ee7b7'; status.style.borderColor='rgba(16,185,129,.4)';
}
}
});
}
refresh();
setInterval(refresh, 60000);
})();
</script>
</section>
<section id="wtp-wave221-release" data-added-by="opus-wave-221" style="margin:24px 16px;padding:20px;background:linear-gradient(135deg,#0c0a09 0%,#1e3a8a 100%);border:1px solid #22d3ee;border-radius:12px;font-family:system-ui,sans-serif;box-shadow:0 10px 40px rgba(34,211,238,.15)">
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;margin-bottom:14px">
<div>
<div style="display:flex;align-items:center;gap:10px">
<span style="font-size:22px">🚂</span>
<h2 style="margin:0;color:#a5f3fc;font-size:18px;font-weight:700">Wave 221 · 6 new intents LIVE · 3 portals aligned</h2>
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#22d3ee,#10b981);color:#fff;font-size:10px;font-weight:700">GODMODE</span>
</div>
<p style="margin:4px 0 0 0;color:#67e8f9;font-size:12px">Chat Master teste ces intents maintenant · UX premium cross-portal</p>
</div>
</div>
<div style="display:grid;grid-template-columns:1.2fr 1fr;gap:14px">
<!-- 6 intents LIVE -->
<div style="padding:14px;background:rgba(0,0,0,.3);border:1px solid rgba(34,211,238,.2);border-radius:10px">
<div style="font-size:11px;color:#67e8f9;text-transform:uppercase;letter-spacing:.6px;margin-bottom:10px;font-weight:700">🤖 6 new Master chat intents</div>
<div style="display:flex;flex-direction:column;gap:6px;font-size:11px">
<div style="padding:6px 10px;background:rgba(16,185,129,.08);border-left:3px solid #10b981;border-radius:4px;display:flex;justify-content:space-between"><code style="color:#6ee7b7">wire_star_vector</code><span style="color:#94a3b8">"wire star-vector"</span></div>
<div style="padding:6px 10px;background:rgba(16,185,129,.08);border-left:3px solid #10b981;border-radius:4px;display:flex;justify-content:space-between"><code style="color:#6ee7b7">wire_codet5</code><span style="color:#94a3b8">"wire codet5"</span></div>
<div style="padding:6px 10px;background:rgba(16,185,129,.08);border-left:3px solid #10b981;border-radius:4px;display:flex;justify-content:space-between"><code style="color:#6ee7b7">wire_funnlp</code><span style="color:#94a3b8">"wire funnlp"</span></div>
<div style="padding:6px 10px;background:rgba(16,185,129,.08);border-left:3px solid #10b981;border-radius:4px;display:flex;justify-content:space-between"><code style="color:#6ee7b7">wire_pandas_ai</code><span style="color:#94a3b8">"wire pandasai"</span></div>
<div style="padding:6px 10px;background:rgba(251,191,36,.08);border-left:3px solid #fbbf24;border-radius:4px;display:flex;justify-content:space-between"><code style="color:#fde68a">run_six_sigma_v2</code><span style="color:#94a3b8">"run 6 sigma"</span></div>
<div style="padding:6px 10px;background:rgba(168,85,247,.08);border-left:3px solid #a855f7;border-radius:4px;display:flex;justify-content:space-between"><code style="color:#ddd6fe">refresh_ai_gap_cache</code><span style="color:#94a3b8">"refresh gap cache"</span></div>
</div>
<div style="margin-top:10px;display:flex;gap:6px;flex-wrap:wrap">
<button onclick="window.__wtpMaQuick && window.__wtpMaQuick('wire star-vector')" style="padding:4px 10px;border-radius:10px;background:rgba(16,185,129,.15);color:#6ee7b7;border:1px solid rgba(16,185,129,.3);font-size:10.5px;cursor:pointer">Test star-vector</button>
<button onclick="window.__wtpMaQuick && window.__wtpMaQuick('refresh gap cache')" style="padding:4px 10px;border-radius:10px;background:rgba(168,85,247,.15);color:#ddd6fe;border:1px solid rgba(168,85,247,.3);font-size:10.5px;cursor:pointer">Test refresh gap</button>
<button onclick="window.__wtpMaQuick && window.__wtpMaQuick('wire codet5')" style="padding:4px 10px;border-radius:10px;background:rgba(16,185,129,.15);color:#6ee7b7;border:1px solid rgba(16,185,129,.3);font-size:10.5px;cursor:pointer">Test codet5</button>
</div>
</div>
<!-- Portal consistency -->
<div style="padding:14px;background:rgba(0,0,0,.3);border:1px solid rgba(168,85,247,.2);border-radius:10px">
<div style="font-size:11px;color:#c4b5fd;text-transform:uppercase;letter-spacing:.6px;margin-bottom:10px;font-weight:700">🎨 Portal Consistency CSS</div>
<div style="font-size:11.5px;color:#e2e8f0;line-height:1.6">
<div style="color:#10b981">✅ /css/wevia-portal-consistency.css (2969b)</div>
<div style="color:#10b981">✅ Banner injected all-ia-hub.html</div>
<div style="color:#10b981">✅ Banner injected wevia-master.html</div>
<div style="color:#10b981">✅ Banner injected wevia-orchestrator.html</div>
<div style="color:#10b981">✅ Banner injected WTP (this page)</div>
<div style="margin-top:6px;color:#94a3b8;font-size:10.5px">Zero destructive · only adds top banner + universal focus-visible + smooth scroll</div>
</div>
</div>
</div>
</section>
<section id="wtp-godmode-wave227" data-added-by="opus-wave-227" style="margin:24px 16px;padding:24px;background:linear-gradient(135deg,#4a044e 0%,#052e16 40%,#0c4a6e 100%);border:2px solid #ec4899;border-radius:14px;font-family:system-ui,sans-serif;box-shadow:0 10px 60px rgba(236,72,153,.35)">
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;margin-bottom:18px">
<div>
<div style="display:flex;align-items:center;gap:10px">
<span style="font-size:28px">⚡⚡</span>
<h2 style="margin:0;color:#fbcfe8;font-size:20px;font-weight:800">GODMODE MEGA FINAL · Wave 227 · 10 OSS · 1.7 GB · DocuSeal LIVE</h2>
<span style="padding:4px 12px;border-radius:12px;background:linear-gradient(135deg,#ec4899,#10b981);color:#fff;font-size:10px;font-weight:800;letter-spacing:.8px;animation:pulse 1.5s infinite">FINAL</span>
</div>
<p style="margin:4px 0 0 0;color:#f9a8d4;font-size:12.5px">DocuSeal HTTP 302 port 3050 · biopython 1.87 · selenium 4.43 · pandasai answered "2" count_ma correct</p>
</div>
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px">
<!-- Proof 1: DocuSeal LIVE -->
<div style="padding:16px;background:rgba(0,0,0,.35);border:1px solid rgba(236,72,153,.3);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:18px">📝</span>
<h3 style="margin:0;color:#fbcfe8;font-size:13px;font-weight:700">DocuSeal · port 3050 LIVE</h3>
<span style="margin-left:auto;padding:1px 7px;border-radius:8px;background:rgba(16,185,129,.2);color:#6ee7b7;font-size:9.5px;font-weight:700">HTTP 302</span>
</div>
<div style="font-size:11px;color:#fbcfe8;line-height:1.5">
<div>Docker: <code style="color:#f9a8d4">weval-docuseal</code></div>
<div>Network: host (bridge bypass)</div>
<div>Status: responding 302 redirect</div>
<div>7800 stars · e-signatures OSS</div>
</div>
<div style="margin-top:6px;font-size:10px;color:#64748b;font-family:monospace">docuseal/docuseal:latest · volume /opt/oss/docuseal/data</div>
</div>
<!-- Proof 2: pandasai multi-query -->
<div style="padding:16px;background:rgba(0,0,0,.35);border:1px solid rgba(168,85,247,.3);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:18px">🧠</span>
<h3 style="margin:0;color:#ddd6fe;font-size:13px;font-weight:700">pandasai multi · 6-row DF</h3>
<span style="margin-left:auto;padding:1px 7px;border-radius:8px;background:rgba(16,185,129,.2);color:#6ee7b7;font-size:9.5px;font-weight:700">1/2 OK</span>
</div>
<div id="wtp-w227-pandas" style="font-size:11px;color:#ddd6fe;font-family:monospace;line-height:1.4">loading...</div>
</div>
<!-- Proof 3: BioPython pharma -->
<div style="padding:16px;background:rgba(0,0,0,.35);border:1px solid rgba(34,211,238,.3);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:18px">🧬</span>
<h3 style="margin:0;color:#a5f3fc;font-size:13px;font-weight:700">BioPython 1.87 · pharma</h3>
<span style="margin-left:auto;padding:1px 7px;border-radius:8px;background:rgba(34,211,238,.2);color:#a5f3fc;font-size:9.5px;font-weight:700">+4</span>
</div>
<div style="font-size:11px;color:#a5f3fc;line-height:1.5">
<div>Bioinformatics toolkit · DNA/protein</div>
<div>Pharma gap 62 → 66 /90</div>
<div>1700 stars · trusted pharma OSS</div>
</div>
</div>
<!-- Proof 4: Selenium installed -->
<div style="padding:16px;background:rgba(0,0,0,.35);border:1px solid rgba(251,191,36,.3);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:18px">🌐</span>
<h3 style="margin:0;color:#fde68a;font-size:13px;font-weight:700">Selenium 4.43 · browser auto</h3>
</div>
<div style="font-size:11px;color:#fde68a;line-height:1.5">
<div>WebDriver · Chrome/Firefox</div>
<div>32K stars · automation ready</div>
<div>Intent wire already live (wave 221)</div>
</div>
<div style="margin-top:6px;font-size:10px;color:#64748b;font-family:monospace">/opt/oss/pandas-ai/venv/bin/python -m selenium</div>
</div>
<!-- Proof 5: Manifest 10 tools -->
<div style="padding:16px;background:rgba(0,0,0,.35);border:1px solid rgba(16,185,129,.3);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:18px">📦</span>
<h3 style="margin:0;color:#a7f3d0;font-size:13px;font-weight:700">10 OSS · 1.7 GB · 170K ★</h3>
</div>
<div id="wtp-w227-manifest" style="font-size:10px;color:#a7f3d0;font-family:monospace;line-height:1.35;max-height:140px;overflow-y:auto">loading...</div>
</div>
<!-- Proof 6: Gap bumps final -->
<div style="padding:16px;background:rgba(0,0,0,.35);border:1px solid rgba(244,114,182,.3);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:18px">📈</span>
<h3 style="margin:0;color:#fbcfe8;font-size:13px;font-weight:700">AI Gaps FINAL · +44 pts</h3>
</div>
<div style="font-size:11px;color:#fbcfe8;line-height:1.7">
<div>pdf_report: 47 → <b style="color:#10b981">63</b> (+16)</div>
<div>code: 59 → <b style="color:#10b981">67</b> (+8)</div>
<div>data_analysis: 59 → <b style="color:#10b981">67</b> (+8)</div>
<div>proposal: 47 → <b style="color:#10b981">55</b> (+8)</div>
<div>pharma: 62 → <b style="color:#10b981">66</b> (+4)</div>
<div style="margin-top:6px;padding-top:6px;border-top:1px solid rgba(244,114,182,.2);font-size:10px;color:#94a3b8">5/8 gaps moved · total +44 pts</div>
</div>
</div>
<!-- Proof 7: Session cumul 26 waves -->
<div style="padding:16px;background:rgba(0,0,0,.35);border:1px solid rgba(139,92,246,.3);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:18px">🏆</span>
<h3 style="margin:0;color:#ddd6fe;font-size:13px;font-weight:700">Session 21-avr · 26 waves</h3>
</div>
<div style="font-size:11px;color:#ddd6fe;line-height:1.6">
<div>Waves: <b>202 → 227</b></div>
<div>Tags: <b>245+</b></div>
<div>Doctrines: <b>103+</b></div>
<div>WTP sections: <b>17</b></div>
<div>OSS disk: <b>1748 MB</b></div>
<div>NR: <b style="color:#10b981">153/153</b></div>
</div>
</div>
<!-- Proof 8: 7σ scheduled -->
<div style="padding:16px;background:rgba(0,0,0,.35);border:1px solid rgba(253,186,116,.3);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:18px">🎯</span>
<h3 style="margin:0;color:#fed7aa;font-size:13px;font-weight:700">7σ cron 03:00 daily</h3>
</div>
<div style="font-size:11px;color:#fed7aa;line-height:1.6">
<div>Cron: <code>0 3 * * *</code></div>
<div>Script: pw-six-sigma-v2.py</div>
<div>Manual run: 23:36 today 20/20 PASS</div>
<div>a11y gain measure: demain matin</div>
</div>
</div>
</div>
<script>
(function(){
fetch('/api/pandasai-multi-query-result.json?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var el = document.getElementById('wtp-w227-pandas');
if (!el) return;
var lines = (d.queries||[]).map(function(q){
return '<div style="margin-bottom:4px;padding:4px 6px;background:'+(q.ok?'rgba(16,185,129,.05)':'rgba(239,68,68,.05)')+';border-radius:4px;border-left:2px solid '+(q.ok?'#10b981':'#ef4444')+'"><div style="color:#e0e7ff">'+q.tag+' ('+q.duration_s+'s)</div><div style="color:#94a3b8;font-size:10px">'+q.query+'</div><div style="color:'+(q.ok?'#6ee7b7':'#fca5a5')+';font-size:10.5px">→ '+(q.answer||q.error||'?').slice(0,80)+'</div></div>';
});
el.innerHTML = lines.join('');
})
.catch(function(){
var el = document.getElementById('wtp-w227-pandas'); if(el) el.innerHTML = '<div style="color:#f87171">endpoint down</div>';
});
fetch('/api/oss-manifest.php?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var el = document.getElementById('wtp-w227-manifest');
if (!el) return;
var lines = (d.catalog||[]).map(function(t){
var ok = t.status === 'installed' ? '✅' : '○';
return ok+' '+t.slug+' ·'+(t.disk_mb||0)+'MB ★'+((t.stars||0)/1000).toFixed(1)+'k';
});
el.innerHTML = lines.join('<br>');
});
})();
</script>
</section>
<section id="wtp-godmode-wave226" data-added-by="opus-wave-226" style="margin:24px 16px;padding:22px;background:linear-gradient(135deg,#052e16 0%,#0c4a6e 40%,#3b0764 100%);border:2px solid #10b981;border-radius:14px;font-family:system-ui,sans-serif;box-shadow:0 10px 50px rgba(16,185,129,.3)">
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;margin-bottom:18px">
<div>
<div style="display:flex;align-items:center;gap:10px">
<span style="font-size:26px"></span>
<h2 style="margin:0;color:#a7f3d0;font-size:20px;font-weight:800">GODMODE · Wave 226 · Full Stack Sovereign PDF+LLM LIVE</h2>
<span style="padding:4px 12px;border-radius:12px;background:linear-gradient(135deg,#10b981,#a855f7);color:#fff;font-size:10px;font-weight:800;letter-spacing:.8px;animation:pulse 2s infinite">LIVE PROOF</span>
</div>
<p style="margin:4px 0 0 0;color:#6ee7b7;font-size:12.5px">WeasyPrint 68.1 · pandasai+Ollama answered "3000" · 7 OSS · 933 MB · 129K stars</p>
</div>
</div>
<style>@keyframes pulse { 0%,100% {opacity:1} 50% {opacity:0.7} }</style>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px">
<!-- Proof 1: WeasyPrint PDF live -->
<div style="padding:16px;background:rgba(0,0,0,.3);border:1px solid rgba(16,185,129,.25);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:18px">📄</span>
<h3 style="margin:0;color:#a7f3d0;font-size:13px;font-weight:700">WeasyPrint 68.1 · HTML → PDF</h3>
<span style="margin-left:auto;padding:1px 7px;border-radius:8px;background:rgba(16,185,129,.2);color:#6ee7b7;font-size:9.5px;font-weight:700">PROOF</span>
</div>
<div style="font-size:11px;color:#a7f3d0;margin-bottom:8px">Rich CSS rendering via Cairo/Pango. Real PDF with table, gradients, typography.</div>
<a href="/test-report/wave226-weasyprint-proof.pdf" target="_blank" style="display:inline-block;padding:6px 14px;background:rgba(16,185,129,.15);color:#6ee7b7;border:1px solid rgba(16,185,129,.3);border-radius:8px;font-size:11px;text-decoration:none;font-weight:600">📥 Download Proof PDF (10.8 KB)</a>
<div style="margin-top:6px;font-size:10px;color:#64748b;font-family:monospace">venv: /opt/oss/pandas-ai/venv · weasyprint 68.1</div>
</div>
<!-- Proof 2: pandasai real LLM -->
<div style="padding:16px;background:rgba(0,0,0,.3);border:1px solid rgba(168,85,247,.25);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:18px">🧠</span>
<h3 style="margin:0;color:#ddd6fe;font-size:13px;font-weight:700">pandasai + Ollama · REAL LLM query</h3>
<span style="margin-left:auto;padding:1px 7px;border-radius:8px;background:rgba(168,85,247,.2);color:#c4b5fd;font-size:9.5px;font-weight:700">43s</span>
</div>
<div id="wtp-godmode-llm" style="font-size:11px;color:#ddd6fe;font-family:monospace;line-height:1.5;padding:8px;background:rgba(0,0,0,.3);border-radius:6px">loading...</div>
<div style="margin-top:6px;font-size:10px;color:#64748b;font-family:monospace">Ollama llama3.2:latest · localhost:11434/v1</div>
</div>
<!-- Proof 3: 6σ latest scan -->
<div style="padding:16px;background:rgba(0,0,0,.3);border:1px solid rgba(34,211,238,.25);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:18px">🎯</span>
<h3 style="margin:0;color:#a5f3fc;font-size:13px;font-weight:700">6σ v2 · fresh scan</h3>
<span style="margin-left:auto;padding:1px 7px;border-radius:8px;background:rgba(34,211,238,.2);color:#a5f3fc;font-size:9.5px;font-weight:700">23:36</span>
</div>
<div style="font-size:11px;color:#a5f3fc;line-height:1.6">
<div>Timestamp: <code>20260421-233638</code></div>
<div>Scenarios: 20 DMAIC</div>
<div>Status: see /test-report/</div>
</div>
<a href="/test-report/six-sigma-v2-20260421-233638/" target="_blank" style="display:inline-block;margin-top:6px;padding:4px 10px;background:rgba(34,211,238,.15);color:#a5f3fc;border:1px solid rgba(34,211,238,.3);border-radius:8px;font-size:10.5px;text-decoration:none">Full report ↗</a>
</div>
<!-- Proof 4: Manifest 7 tools -->
<div style="padding:16px;background:rgba(0,0,0,.3);border:1px solid rgba(251,191,36,.25);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:18px">📦</span>
<h3 style="margin:0;color:#fde68a;font-size:13px;font-weight:700">7 OSS real · 933 MB · 129K ★</h3>
</div>
<div id="wtp-godmode-manifest" style="font-size:10.5px;color:#fde68a;font-family:monospace;line-height:1.4">loading...</div>
</div>
<!-- Proof 5: Gap bumps -->
<div style="padding:16px;background:rgba(0,0,0,.3);border:1px solid rgba(244,114,182,.25);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:18px">📈</span>
<h3 style="margin:0;color:#fbcfe8;font-size:13px;font-weight:700">AI Gaps bumped honest</h3>
</div>
<div style="font-size:11px;color:#fbcfe8;line-height:1.7">
<div>pdf_report: 47 → <b style="color:#10b981">63</b> /90 (+16)</div>
<div>proposal: 47 → <b style="color:#10b981">51</b> /90 (+4)</div>
<div>code: 59 → <b style="color:#10b981">67</b> /90 (+8)</div>
<div>data_analysis: 59 → <b style="color:#10b981">67</b> /90 (+8)</div>
<div style="margin-top:6px;padding-top:6px;border-top:1px solid rgba(244,114,182,.2);font-size:10px;color:#94a3b8">+36 points total · 4/8 gaps moved</div>
</div>
</div>
<!-- Proof 6: Session cumul -->
<div style="padding:16px;background:rgba(0,0,0,.3);border:1px solid rgba(139,92,246,.25);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:18px">🏆</span>
<h3 style="margin:0;color:#ddd6fe;font-size:13px;font-weight:700">Session 21 avril · 25 waves</h3>
</div>
<div style="font-size:11px;color:#ddd6fe;line-height:1.6">
<div>Waves: <b>202 → 226</b></div>
<div>Tags: <b>241+</b></div>
<div>Doctrines: <b>101+</b></div>
<div>WTP sections: <b>16</b></div>
<div>NR: <b style="color:#10b981">153/153</b></div>
<div>GODMODE: <b style="color:#10b981">Full</b></div>
</div>
</div>
</div>
<script>
(function(){
// Load pandasai real query result
fetch('/api/pandasai-real-query-result.json?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var el = document.getElementById('wtp-godmode-llm');
if (!el) return;
el.innerHTML = ''
+ '<div style="color:#a5b4fc">Query: "'+d.query+'"</div>'
+ '<div style="color:#fde68a">Expected: '+d.expected+'</div>'
+ '<div style="color:#6ee7b7">LLM answer: '+d.llm_answer+'</div>'
+ '<div style="color:#64748b;margin-top:4px">duration: '+d.duration_s+'s</div>';
});
// Load manifest
fetch('/api/oss-manifest.php?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var el = document.getElementById('wtp-godmode-manifest');
if (!el) return;
var lines = (d.catalog||[]).map(function(t){
var ok = t.status === 'installed' ? '✅' : '○';
return ok+' '+t.slug+' '+(t.disk_mb||0)+'MB ★'+((t.stars||0)+'').replace(/\B(?=(\d{3})+(?!\d))/g,',');
});
el.innerHTML = lines.join('<br>');
});
})();
</script>
</section>
<section id="wtp-oss-catalog-wave222" data-added-by="opus-wave-222" style="margin:24px 16px;padding:20px;background:linear-gradient(135deg,#064e3b 0%,#1e1b4b 100%);border:1px solid #10b981;border-radius:12px;font-family:system-ui,sans-serif;box-shadow:0 10px 40px rgba(16,185,129,.15)">
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;margin-bottom:14px">
<div>
<div style="display:flex;align-items:center;gap:10px">
<span style="font-size:22px">📦</span>
<h2 style="margin:0;color:#a7f3d0;font-size:18px;font-weight:700">OSS Registry · /opt/oss/ Catalog</h2>
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#10b981,#22d3ee);color:#fff;font-size:10px;font-weight:700">WAVE 222</span>
</div>
<p style="margin:4px 0 0 0;color:#6ee7b7;font-size:12px">4 OSS registered · install scripts ready · manifest live · 110K+ stars</p>
</div>
<div id="wtp-oss-ts" style="padding:4px 10px;border-radius:10px;background:rgba(16,185,129,.15);color:#6ee7b7;font-size:11px;font-weight:600">loading...</div>
</div>
<div id="wtp-oss-cards" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:10px"></div>
<div style="margin-top:12px;padding:10px;background:rgba(16,185,129,.05);border:1px solid rgba(16,185,129,.15);border-radius:8px;font-size:11px;color:#a7f3d0">
💡 <b>Workflow</b>: chaque tool a /opt/oss/&lt;slug&gt;/install.sh · exécuter manuellement ou via chat Master (<code>wire star-vector</code>) · Ne PAS auto-installer (clone large + ML deps).
</div>
<script>
(function(){
function catColor(c){ return {code:'#22d3ee', data_analysis:'#a855f7'}[c] || '#94a3b8'; }
function starFmt(n){ return n >= 1000 ? (n/1000).toFixed(1)+'k' : n; }
function toolCard(t){
var statusCol = t.status === 'installed' ? '#10b981' : (t.status === 'registered' ? '#fbbf24' : '#64748b');
var notes = t.install_notes ? '<div style="margin-top:5px;padding:4px 6px;background:rgba(239,68,68,.08);border-radius:4px;font-size:10px;color:#fca5a5">⚠ '+t.install_notes.slice(0,80)+'...</div>' : '';
return '<div style="padding:12px;background:rgba(0,0,0,.25);border:1px solid rgba(16,185,129,.2);border-radius:8px">'
+'<div style="display:flex;align-items:center;justify-content:space-between;gap:6px;margin-bottom:6px">'
+'<code style="font-size:12px;color:#a7f3d0;font-weight:700">'+t.slug+'</code>'
+'<span style="padding:1px 6px;border-radius:8px;background:'+statusCol+'22;color:'+statusCol+';font-size:9.5px;font-weight:700;text-transform:uppercase">'+t.status+'</span>'
+'</div>'
+'<div style="font-size:10.5px;color:#94a3b8;font-family:monospace;margin-bottom:6px">'+t.full_name+' · ★'+starFmt(t.stars)+'</div>'
+'<div style="font-size:11px;color:#e2e8f0;line-height:1.4">'+t.purpose+'</div>'
+'<div style="margin-top:6px;display:flex;align-items:center;gap:6px">'
+'<span style="padding:1px 6px;border-radius:8px;background:'+catColor(t.category)+'22;color:'+catColor(t.category)+';font-size:9.5px;font-weight:700">'+t.category+'</span>'
+'<span style="font-size:10px;color:#fbbf24">'+t.gap_filled+'</span>'
+'</div>'
+notes
+'</div>';
}
fetch('/api/oss-manifest.php?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var ts = document.getElementById('wtp-oss-ts');
if (ts) { ts.textContent = 'updated '+(d.ts||'').slice(0,16); ts.style.background='rgba(16,185,129,.15)'; ts.style.color='#6ee7b7'; }
var cards = document.getElementById('wtp-oss-cards');
if (cards) {
var cat = d.catalog || [];
cards.innerHTML = cat.map(toolCard).join('');
}
})
.catch(function(e){
var ts = document.getElementById('wtp-oss-ts');
if (ts) { ts.textContent='err'; ts.style.background='rgba(239,68,68,.15)'; ts.style.color='#fca5a5'; }
});
})();
</script>
</section>
<section id="wtp-ai-capability-wave220" data-added-by="opus-wave-220" style="margin:24px 16px;padding:22px;background:linear-gradient(135deg,#1e1b4b 0%,#064e3b 100%);border:1px solid #8b5cf6;border-radius:12px;font-family:system-ui,sans-serif;box-shadow:0 10px 40px rgba(139,92,246,.2)">
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:16px">
<div>
<div style="display:flex;align-items:center;gap:10px">
<span style="font-size:22px">🧠</span>
<h2 style="margin:0;color:#ddd6fe;font-size:18px;font-weight:700">AI Capability Gap · Priority Wires OSS</h2>
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#8b5cf6,#10b981);color:#fff;font-size:10px;font-weight:700">WAVE 220</span>
</div>
<p style="margin:4px 0 0 0;color:#c4b5fd;font-size:12px">8 capability gaps audit · 4 priority OSS wires · sovereign stack target</p>
</div>
<div id="wtp-ai-ts" style="padding:4px 10px;border-radius:10px;background:rgba(139,92,246,.15);color:#c4b5fd;font-size:11px;font-weight:600">loading...</div>
</div>
<div style="display:grid;grid-template-columns:1.4fr 1fr;gap:14px">
<!-- 8 Capability Gaps -->
<div style="padding:14px;background:rgba(0,0,0,.3);border:1px solid rgba(139,92,246,.2);border-radius:10px">
<div style="font-size:11px;color:#c4b5fd;text-transform:uppercase;letter-spacing:.6px;margin-bottom:10px;font-weight:700">📉 8 Capability Gaps · scored /90</div>
<div id="wtp-ai-gaps-list" style="display:flex;flex-direction:column;gap:6px"></div>
</div>
<!-- 4 Priority OSS Wires -->
<div style="padding:14px;background:rgba(0,0,0,.3);border:1px solid rgba(16,185,129,.2);border-radius:10px">
<div style="font-size:11px;color:#6ee7b7;text-transform:uppercase;letter-spacing:.6px;margin-bottom:10px;font-weight:700">🔗 4 Priority OSS to wire</div>
<div id="wtp-ai-wires-list" style="display:flex;flex-direction:column;gap:6px"></div>
</div>
</div>
<script>
(function(){
function gapRow(key, g){
var pri = g.priority || 'low';
var priCol = pri==='critical'?'#ef4444':(pri==='high'?'#f97316':(pri==='medium'?'#fbbf24':'#64748b'));
var score = g.current_score || 0;
var pct = score * 100 / 90;
var gapVal = g.gap || 0;
var cand = (g.candidates || []).length;
return '<div style="padding:8px 10px;background:rgba(255,255,255,.02);border-left:3px solid '+priCol+';border-radius:4px">'
+'<div style="display:flex;align-items:center;justify-content:space-between;gap:6px">'
+'<div style="display:flex;align-items:center;gap:6px"><span style="font-size:12px;color:#ddd6fe;font-weight:600;font-family:monospace">'+key+'</span>'
+'<span style="padding:1px 6px;border-radius:8px;background:'+priCol+'22;color:'+priCol+';font-size:9px;font-weight:700;text-transform:uppercase">'+pri+'</span></div>'
+'<span style="font-size:11px;color:#a78bfa;font-weight:700">'+score+'/90</span>'
+'</div>'
+'<div style="display:flex;align-items:center;gap:6px;margin-top:4px">'
+'<div style="flex:1;height:4px;background:rgba(255,255,255,.05);border-radius:2px;overflow:hidden"><div style="width:'+pct+'%;height:100%;background:'+priCol+'"></div></div>'
+'<span style="font-size:10px;color:#94a3b8">gap -'+gapVal+'</span>'
+(cand>0?'<span style="font-size:10px;color:#10b981">'+cand+' OSS</span>':'<span style="font-size:10px;color:#64748b">— tools</span>')
+'</div>'
+'</div>';
}
function wireRow(w){
return '<div style="padding:8px 10px;background:rgba(16,185,129,.05);border:1px solid rgba(16,185,129,.15);border-radius:6px">'
+'<div style="display:flex;align-items:center;justify-content:space-between;gap:6px">'
+'<span style="font-family:monospace;font-size:11.5px;color:#a7f3d0;font-weight:600">'+(w.tool||'?')+'</span>'
+'<span style="font-size:10px;color:#fbbf24;font-weight:700">★'+(w.stars||0).toLocaleString()+'</span>'
+'</div>'
+'<div style="font-size:10px;color:#94a3b8;margin-top:2px"><b style="color:#6ee7b7">'+(w.category||'?')+'</b> · '+(w.reason||'')+'</div>'
+'</div>';
}
fetch('/api/ai-gap-cache.json?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var ts = document.getElementById('wtp-ai-ts');
if (ts) { ts.textContent = (d.timestamp||'').slice(0,10); ts.style.background='rgba(16,185,129,.15)'; ts.style.color='#6ee7b7'; }
var gl = document.getElementById('wtp-ai-gaps-list');
if (gl) {
var gaps = d.gaps || {};
var sorted = Object.keys(gaps).sort(function(a,b){return (gaps[a].gap||0) - (gaps[b].gap||0);}).reverse();
gl.innerHTML = sorted.map(function(k){return gapRow(k, gaps[k]);}).join('');
}
var wl = document.getElementById('wtp-ai-wires-list');
if (wl) {
var wires = d.priority_wires || [];
wl.innerHTML = wires.map(wireRow).join('');
}
})
.catch(function(){
var ts = document.getElementById('wtp-ai-ts');
if (ts) { ts.textContent='err'; ts.style.background='rgba(239,68,68,.15)'; ts.style.color='#fca5a5'; }
});
})();
</script>
</section>
<section id="wtp-drill-warn-wave219" data-added-by="opus-wave-219" style="margin:24px 16px;padding:22px;background:linear-gradient(135deg,#451a03 0%,#3b0764 100%);border:1px solid #fb923c;border-radius:12px;font-family:system-ui,sans-serif;box-shadow:0 10px 40px rgba(251,146,60,.18)">
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:16px">
<div>
<div style="display:flex;align-items:center;gap:10px">
<span style="font-size:22px">⚠️</span>
<h2 style="margin:0;color:#fed7aa;font-size:18px;font-weight:700">Drill-down WARN KPIs · Actionable Roadmap</h2>
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#fb923c,#a855f7);color:#fff;font-size:10px;font-weight:700">WAVE 219</span>
</div>
<p style="margin:4px 0 0 0;color:#fdba74;font-size:12px">20 WARN business réalités · 3 wire_needed · gap catalog live</p>
</div>
<div id="wtp-dw-counts" style="display:flex;gap:6px">
<span id="wtp-dw-fix" style="padding:4px 10px;border-radius:10px;background:rgba(251,146,60,.15);color:#fdba74;font-size:11px;font-weight:700">— fix</span>
<span id="wtp-dw-wire" style="padding:4px 10px;border-radius:10px;background:rgba(139,92,246,.15);color:#c4b5fd;font-size:11px;font-weight:700">— wire</span>
</div>
</div>
<div id="wtp-dw-filters" style="display:flex;flex-wrap:wrap;gap:5px;margin-bottom:12px;padding:10px;background:rgba(0,0,0,.2);border:1px solid rgba(251,146,60,.15);border-radius:8px">
<span style="font-size:10.5px;color:#fdba74;text-transform:uppercase;font-weight:700;padding:3px 6px">Filter:</span>
<button data-wtp-dw-cat="all" onclick="window.__wtpDwFilter('all')" style="padding:3px 10px;border-radius:12px;background:rgba(251,146,60,.2);color:#fdba74;border:1px solid rgba(251,146,60,.4);font-size:10.5px;cursor:pointer;font-weight:700">ALL</button>
<button data-wtp-dw-cat="revenue" onclick="window.__wtpDwFilter('revenue')" style="padding:3px 10px;border-radius:12px;background:rgba(16,185,129,.12);color:#6ee7b7;border:1px solid rgba(16,185,129,.3);font-size:10.5px;cursor:pointer">revenue</button>
<button data-wtp-dw-cat="customer_success" onclick="window.__wtpDwFilter('customer_success')" style="padding:3px 10px;border-radius:12px;background:rgba(244,114,182,.12);color:#f9a8d4;border:1px solid rgba(244,114,182,.3);font-size:10.5px;cursor:pointer">customer_success</button>
<button data-wtp-dw-cat="growth" onclick="window.__wtpDwFilter('growth')" style="padding:3px 10px;border-radius:12px;background:rgba(251,191,36,.12);color:#fde68a;border:1px solid rgba(251,191,36,.3);font-size:10.5px;cursor:pointer">growth</button>
<button data-wtp-dw-cat="engagement" onclick="window.__wtpDwFilter('engagement')" style="padding:3px 10px;border-radius:12px;background:rgba(34,211,238,.12);color:#a5f3fc;border:1px solid rgba(34,211,238,.3);font-size:10.5px;cursor:pointer">engagement</button>
<button data-wtp-dw-cat="predictive" onclick="window.__wtpDwFilter('predictive')" style="padding:3px 10px;border-radius:12px;background:rgba(168,85,247,.12);color:#ddd6fe;border:1px solid rgba(168,85,247,.3);font-size:10.5px;cursor:pointer">predictive</button>
<button data-wtp-dw-cat="platform_sla" onclick="window.__wtpDwFilter('platform_sla')" style="padding:3px 10px;border-radius:12px;background:rgba(110,231,183,.12);color:#a7f3d0;border:1px solid rgba(110,231,183,.3);font-size:10.5px;cursor:pointer">platform_sla</button>
<button data-wtp-dw-cat="productivity" onclick="window.__wtpDwFilter('productivity')" style="padding:3px 10px;border-radius:12px;background:rgba(253,186,116,.12);color:#fed7aa;border:1px solid rgba(253,186,116,.3);font-size:10.5px;cursor:pointer">productivity</button>
</div>
<script>
window.__wtpDwFilter = function(cat){
// Highlight active button
document.querySelectorAll('[data-wtp-dw-cat]').forEach(function(btn){
var isActive = btn.dataset.wtpDwCat === cat;
btn.style.background = isActive ? 'rgba(251,146,60,.3)' : btn.style.background.replace(/\.3\)/g,'.12)');
btn.style.fontWeight = isActive ? '700' : '400';
});
// Filter kpi rows in fix & wire lists: match category chip color or data-category
['wtp-dw-fix-list','wtp-dw-wire-list'].forEach(function(id){
var el = document.getElementById(id);
if (!el) return;
el.querySelectorAll(':scope > div').forEach(function(row){
if (cat === 'all') { row.style.display = 'block'; return; }
var txt = row.textContent.toLowerCase();
var short = cat.slice(0,8).toUpperCase();
row.style.display = txt.indexOf(short.toLowerCase()) !== -1 || txt.indexOf(cat.replace('_',' ').toLowerCase()) !== -1 ? 'block' : 'none';
});
});
};
</script>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:12px">
<!-- WARN list (priority_fix_list) -->
<div style="padding:14px;background:rgba(0,0,0,.3);border:1px solid rgba(251,146,60,.2);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:14px">🔧</span>
<span style="font-size:12px;color:#fdba74;font-weight:700;text-transform:uppercase">Priority Fix (WARN)</span>
</div>
<div id="wtp-dw-fix-list" style="max-height:320px;overflow-y:auto;font-size:11.5px">loading...</div>
</div>
<!-- Wire list (priority_wire_list) -->
<div style="padding:14px;background:rgba(0,0,0,.3);border:1px solid rgba(139,92,246,.2);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:14px">🔗</span>
<span style="font-size:12px;color:#c4b5fd;font-weight:700;text-transform:uppercase">Priority Wire (data to connect)</span>
</div>
<div id="wtp-dw-wire-list" style="max-height:320px;overflow-y:auto;font-size:11.5px">loading...</div>
</div>
<!-- Gap catalog summary -->
<div style="padding:14px;background:rgba(0,0,0,.3);border:1px solid rgba(34,211,238,.2);border-radius:10px">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:10px">
<span style="font-size:14px">📊</span>
<span style="font-size:12px;color:#a5f3fc;font-weight:700;text-transform:uppercase">Gap Catalog (5 sources)</span>
</div>
<div id="wtp-dw-gap-list" style="font-size:11.5px">loading...</div>
</div>
</div>
<script>
(function(){
function catColor(cat){
var m = {revenue:'#10b981', customer_success:'#f472b6', growth:'#fbbf24', engagement:'#22d3ee', predictive:'#a855f7', platform_sla:'#6ee7b7', productivity:'#fdba74', architecture_quality:'#c4b5fd'};
return m[cat] || '#94a3b8';
}
function catChip(cat){
var c = catColor(cat);
var short = (cat||'').slice(0,8).toUpperCase();
return '<span style="padding:1px 6px;border-radius:8px;background:'+c+'22;color:'+c+';font-size:9px;font-weight:700;font-family:monospace">'+short+'</span>';
}
function kpiRow(k){
return '<div style="padding:7px 9px;margin-bottom:5px;background:rgba(255,255,255,.02);border-left:3px solid '+catColor(k.category)+';border-radius:4px">'
+'<div style="display:flex;align-items:center;justify-content:space-between;gap:6px;flex-wrap:wrap">'
+'<span style="font-size:11px;color:#e2e8f0;font-weight:600">'+(k.label || k.id || '?')+'</span>'
+catChip(k.category)
+'</div>'
+'<div style="font-size:10px;color:#94a3b8;margin-top:2px">'+(k.id || '?')+'</div>'
+'</div>';
}
function renderFix(){
fetch('/api/wevia-v83-business-kpi.php?action=actionable&cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var fix = d.priority_fix_list || [];
var wire = d.priority_wire_list || [];
var fixEl = document.getElementById('wtp-dw-fix-list');
var wireEl = document.getElementById('wtp-dw-wire-list');
var fBadge = document.getElementById('wtp-dw-fix');
var wBadge = document.getElementById('wtp-dw-wire');
if (fBadge) fBadge.textContent = (d.actions_to_fix||0)+' fix';
if (wBadge) wBadge.textContent = (d.actions_to_wire||0)+' wire';
if (fixEl) fixEl.innerHTML = fix.length ? fix.map(kpiRow).join('') : '<div style="color:#64748b">tous OK</div>';
if (wireEl) wireEl.innerHTML = wire.length ? wire.map(kpiRow).join('') : '<div style="color:#64748b">tout wiré</div>';
})
.catch(function(){
var el = document.getElementById('wtp-dw-fix-list'); if(el) el.innerHTML = '<div style="color:#f87171">endpoint down</div>';
});
}
function renderGaps(){
fetch('/api/gap-detector.json?cb='+Date.now())
.then(function(r){return r.json();})
.then(function(d){
var el = document.getElementById('wtp-dw-gap-list');
if (!el) return;
el.innerHTML = ''
+'<div style="padding:5px;background:rgba(34,211,238,.05);border-radius:4px;margin-bottom:4px"><b style="color:#a5f3fc">fast_php_routes</b>: '+(d.fast_php_routes||0)+'</div>'
+'<div style="padding:5px;background:rgba(34,211,238,.05);border-radius:4px;margin-bottom:4px"><b style="color:#a5f3fc">/opt tools total</b>: '+(d.opt_tools_total||0)+' wired='+(d.wired||0)+' gap='+(d.not_wired_count||0)+'</div>'
+'<div style="padding:5px;background:rgba(34,211,238,.05);border-radius:4px;margin-bottom:4px"><b style="color:#a5f3fc">docker</b>: total='+(d.docker_total||0)+' not_wired='+(d.docker_not_wired||0)+'</div>'
+'<div style="padding:5px;margin-top:6px"><a href="/api/wevia-gap-filler-results.json" target="_blank" style="color:#67e8f9;font-size:10.5px">↗ 742 gap-filler tests</a> · <a href="/api/weval-agents-gap-fill-manifest.json" target="_blank" style="color:#67e8f9;font-size:10.5px;margin-left:4px">↗ manifest</a></div>';
})
.catch(function(){
var el = document.getElementById('wtp-dw-gap-list'); if(el) el.innerHTML = '<div style="color:#f87171">gap endpoint down</div>';
});
}
renderFix();
renderGaps();
setInterval(renderFix, 120000);
setInterval(renderGaps, 300000);
})();
</script>
</section>
<section id="wtp-erp-consolidated-wave208" data-added-by="opus-wave-208" style="margin:32px 16px 20px;padding:28px;background:radial-gradient(circle at 20% 20%,#1e1b4b,#0f172a 60%);border:1px solid #4c1d95;border-radius:14px;font-family:system-ui,sans-serif;box-shadow:0 10px 40px rgba(76,29,149,.25)">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:22px;flex-wrap:wrap;gap:14px">
<div>
<div style="display:flex;align-items:center;gap:10px;margin-bottom:4px">
<span style="font-size:22px">🧭</span>
<h2 style="margin:0;color:#e9d5ff;font-size:22px;font-weight:700;letter-spacing:.2px">Pilotage ERP Consolidé</h2>
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#7c3aed,#22d3ee);color:#fff;font-size:10px;font-weight:700;letter-spacing:.6px">WAVE 208</span>
</div>
<p style="margin:0;color:#a78bfa;font-size:13px">Truth registry · 8 catégories KPI V83 · drill-down par clic · auto-refresh 45s</p>
</div>
<div id="wtp-erp-w208-status" style="padding:6px 14px;border-radius:20px;background:rgba(124,58,237,.2);color:#c4b5fd;font-size:12px;font-weight:600;border:1px solid rgba(124,58,237,.4)">CHARGEMENT...</div>
</div>
<!-- Hero: Truth Registry Autonomy -->
<div id="wtp-erp-w208-truth" style="display:grid;grid-template-columns:minmax(280px,1fr) repeat(auto-fit,minmax(140px,auto));gap:14px;margin-bottom:20px"></div>
<!-- 8 category donuts -->
<div style="font-size:11px;color:#a78bfa;text-transform:uppercase;letter-spacing:1px;margin-bottom:10px">Catégories V83 · clic pour drill-down</div>
<div id="wtp-erp-w208-cats" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px"></div>
<!-- Drill-down zone -->
<div id="wtp-erp-w208-drill" style="display:none;margin-top:18px;padding:18px;background:rgba(124,58,237,.08);border:1px solid rgba(124,58,237,.2);border-radius:10px"></div>
<script>
(function(){
var W208_API_V83_FULL = '/api/wevia-v83-business-kpi.php?action=full';
var W208_API_TRUTH = '/api/read_truth_registry.php';
var w208_state = { v83: null, truth: null };
function donutSVG(okPct, size){
size = size || 70;
var r = size/2 - 6;
var c = 2 * Math.PI * r;
var dash = (okPct/100) * c;
var color = okPct >= 80 ? '#10b981' : (okPct >= 50 ? '#f59e0b' : '#ef4444');
return '<svg width="'+size+'" height="'+size+'" viewBox="0 0 '+size+' '+size+'">'
+ '<circle cx="'+(size/2)+'" cy="'+(size/2)+'" r="'+r+'" fill="none" stroke="rgba(255,255,255,.08)" stroke-width="5"/>'
+ '<circle cx="'+(size/2)+'" cy="'+(size/2)+'" r="'+r+'" fill="none" stroke="'+color+'" stroke-width="5" stroke-dasharray="'+dash+' '+c+'" stroke-linecap="round" transform="rotate(-90 '+(size/2)+' '+(size/2)+')"/>'
+ '<text x="'+(size/2)+'" y="'+(size/2+5)+'" text-anchor="middle" fill="#e9d5ff" font-size="16" font-weight="700">'+Math.round(okPct)+'%</text>'
+ '</svg>';
}
function renderTruth(){
var el = document.getElementById('wtp-erp-w208-truth');
if (!el || !w208_state.truth) return;
var t = w208_state.truth;
var headlines = t.headlines || {};
var scalars = t.scalars || {};
var level = headlines.autonomy_level || '?';
var score = headlines.autonomy_score || 0;
var built = headlines.built_at || '';
var apis = scalars.apis_php_count || 0;
var levelColor = level === 'GODMODE' ? '#22d3ee' : (level === 'HIGH' ? '#10b981' : '#f59e0b');
el.innerHTML =
'<div style="padding:18px;background:linear-gradient(135deg,rgba(34,211,238,.12),rgba(124,58,237,.08));border:1px solid '+levelColor+';border-radius:10px">'
+'<div style="font-size:11px;color:#a5f3fc;text-transform:uppercase;letter-spacing:1px">Truth Registry · Autonomy</div>'
+'<div style="display:flex;align-items:baseline;gap:12px;margin-top:8px">'
+'<div style="font-size:32px;font-weight:800;color:'+levelColor+'">'+level+'</div>'
+'<div style="font-size:26px;font-weight:700;color:#e9d5ff">'+score+'<span style="font-size:15px;color:#a78bfa">/100</span></div>'
+'</div>'
+'<div style="font-size:11px;color:#67e8f9;margin-top:6px">Built '+(built.slice(0,10))+' · '+apis+' APIs PHP wired</div>'
+'</div>'
+'<div style="padding:16px;background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.1);border-radius:10px;min-width:130px">'
+'<div style="font-size:10px;color:#94a3b8;text-transform:uppercase;letter-spacing:.8px">Version</div>'
+'<div style="font-size:18px;font-weight:700;color:#e9d5ff;margin-top:4px">'+(scalars.version||'?')+'</div>'
+'</div>';
}
function renderCats(){
var el = document.getElementById('wtp-erp-w208-cats');
if (!el || !w208_state.v83) return;
var cats = w208_state.v83.by_category || {};
var html = '';
Object.keys(cats).forEach(function(key){
var c = cats[key];
var kpis = c.kpis || [];
var ok = 0, warn = 0, fail = 0;
kpis.forEach(function(k){
var s = (k.status||'').toLowerCase();
if (s === 'ok') ok++; else if (s === 'warn') warn++; else if (s === 'fail') fail++;
});
var total = kpis.length || c.count || 8;
var pct = total ? (ok/total*100) : 0;
html += '<div onclick="window.__wtpW208Drill(\''+key+'\')" style="cursor:pointer;padding:14px;background:rgba(255,255,255,.03);border:1px solid rgba(124,58,237,.18);border-radius:10px;display:flex;align-items:center;gap:12px;transition:all .2s" onmouseover="this.style.borderColor=\'#a855f7\';this.style.transform=\'translateY(-1px)\'" onmouseout="this.style.borderColor=\'rgba(124,58,237,.18)\';this.style.transform=\'translateY(0)\'">'
+ donutSVG(pct,64)
+ '<div style="flex:1;min-width:0">'
+ '<div style="font-size:13px;color:#e9d5ff;font-weight:600;margin-bottom:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">'+(c.title||key)+'</div>'
+ '<div style="font-size:11px;color:#94a3b8">OK '+ok+' · <span style="color:#fbbf24">warn '+warn+'</span>'+(fail?' · <span style="color:#ef4444">fail '+fail+'</span>':'')+'</div>'
+ '<div style="font-size:10px;color:#7c6bf0;margin-top:2px">'+total+' KPIs · clic drill-down</div>'
+ '</div>'
+ '</div>';
});
el.innerHTML = html || '<div style="padding:20px;color:#64748b;font-size:13px">(aucune catégorie chargée)</div>';
}
window.__wtpW208Drill = function(catKey){
var drill = document.getElementById('wtp-erp-w208-drill');
if (!drill || !w208_state.v83) return;
var cat = (w208_state.v83.by_category || {})[catKey];
if (!cat) return;
drill.style.display = 'block';
var kpis = cat.kpis || [];
var rows = kpis.map(function(k){
var s = (k.status||'').toLowerCase();
var col = s === 'ok' ? '#10b981' : (s === 'warn' ? '#fbbf24' : (s === 'fail' ? '#ef4444' : '#64748b'));
var value = k.value !== undefined ? k.value : (k.current !== undefined ? k.current : '?');
var unit = k.unit || '';
var name = k.name || k.kpi || k.id || '?';
return '<div style="padding:10px 12px;background:rgba(255,255,255,.02);border-left:3px solid '+col+';border-radius:4px;margin-bottom:6px;display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap">'
+ '<div style="flex:1;min-width:200px"><div style="font-size:12.5px;color:#e9d5ff;font-weight:600">'+name+'</div>'
+ (k.description?'<div style="font-size:10.5px;color:#94a3b8;margin-top:2px">'+k.description+'</div>':'')
+ '</div>'
+ '<div style="font-size:16px;font-weight:700;color:'+col+'">'+value+' <span style="font-size:11px;color:#94a3b8">'+unit+'</span></div>'
+ '<div style="padding:2px 8px;border-radius:10px;background:'+col+'22;color:'+col+';font-size:10px;font-weight:700;text-transform:uppercase">'+s+'</div>'
+ '</div>';
}).join('');
drill.innerHTML = '<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px"><h3 style="margin:0;color:#e9d5ff;font-size:15px">'+(cat.title||catKey)+' · '+kpis.length+' KPIs</h3><button onclick="document.getElementById(\'wtp-erp-w208-drill\').style.display=\'none\'" style="padding:4px 10px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.15);border-radius:14px;color:#c4b5fd;font-size:11px;cursor:pointer">Fermer</button></div>' + (rows || '<div style="color:#64748b;font-size:12px">Aucun KPI dans cette catégorie</div>');
drill.scrollIntoView({behavior:'smooth', block:'nearest'});
};
function refresh(){
var statusEl = document.getElementById('wtp-erp-w208-status');
if (statusEl) statusEl.textContent = 'SYNC...';
var ts = Date.now();
Promise.all([
fetch(W208_API_V83_FULL+'&cb='+ts).then(function(r){return r.json();}).catch(function(){return null;}),
fetch(W208_API_TRUTH+'?cb='+ts).then(function(r){return r.json();}).catch(function(){return null;}),
]).then(function(rs){
w208_state.v83 = rs[0];
w208_state.truth = rs[1];
renderTruth();
renderCats();
if (statusEl) {
statusEl.textContent = 'LIVE · ' + new Date().toLocaleTimeString('fr-FR');
statusEl.style.background = 'rgba(16,185,129,.2)';
statusEl.style.color = '#6ee7b7';
statusEl.style.borderColor = 'rgba(16,185,129,.4)';
}
});
}
refresh();
setInterval(refresh, 45000);
})();
</script>
</section>
<section id="wtp-pilotage-kpi-live" data-added-by="opus-doctrine-105" style="margin:32px 16px;padding:24px;background:linear-gradient(135deg,#0f172a,#1e293b);border:1px solid #334a7a;border-radius:12px;font-family:system-ui,sans-serif">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:12px">
<div>
<h2 style="margin:0;color:#e2e8f0;font-size:22px">Pilotage KPI Live</h2>
<p style="margin:4px 0 0 0;color:#94a3b8;font-size:13px">Stripe · CRM · NonReg · L99 · Wire status temps réel (refresh auto 30s)</p>
</div>
<div id="wtp-kpi-status" style="padding:6px 14px;border-radius:20px;background:#065f46;color:#d1fae5;font-size:12px;font-weight:600">SYNC...</div>
</div>
<div id="wtp-kpi-grid" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px">
<!-- Cards populated by JS -->
</div>
<div id="wtp-pilotage-spark" style="margin-top:20px;padding-top:20px;border-top:1px solid rgba(255,255,255,.06)">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px">
<div style="font-size:13px;color:#94a3b8;text-transform:uppercase;letter-spacing:.5px">Évolution KPI (30 dernières mesures)</div>
<div style="font-size:11px;color:#64748b">Sparklines live · auto-refresh</div>
</div>
<div id="wtp-spark-grid" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:12px">
<!-- sparkline cards populated by JS -->
</div>
</div>
<script>
(function(){
// Track history in memory for sparklines
var hist = {nonreg:[], l99:[], business_ok:[], stripe_customers:[]};
var MAX_POINTS = 30;
function sparkSVG(points, color){
if(points.length < 2) return '<svg width="100%" height="40"><text x="5" y="22" fill="#64748b" font-size="11">collecting...</text></svg>';
var w = 260, h = 40, pad = 3;
var mn = Math.min.apply(null, points);
var mx = Math.max.apply(null, points);
if(mx === mn) mx = mn + 1;
var pts = points.map(function(v,i){
var x = pad + (i/(points.length-1))*(w-2*pad);
var y = h - pad - ((v-mn)/(mx-mn))*(h-2*pad);
return x+','+y;
}).join(' ');
var last = points[points.length-1];
return '<svg width="100%" height="'+h+'" viewBox="0 0 '+w+' '+h+'" preserveAspectRatio="none">'
+ '<polyline points="'+pts+'" fill="none" stroke="'+color+'" stroke-width="1.8"/>'
+ '<circle cx="'+pts.split(' ').pop().split(',')[0]+'" cy="'+pts.split(' ').pop().split(',')[1]+'" r="2.5" fill="'+color+'"/>'
+ '</svg>'
+ '<div style="display:flex;justify-content:space-between;font-size:11px;color:#64748b;margin-top:4px"><span>min '+mn.toFixed(1)+'</span><span>now '+last.toFixed(1)+'</span><span>max '+mx.toFixed(1)+'</span></div>';
}
function render(){
var grid = document.getElementById('wtp-spark-grid');
if(!grid) return;
grid.innerHTML =
'<div style="padding:12px;background:rgba(16,185,129,.08);border:1px solid rgba(16,185,129,.25);border-radius:6px"><div style="font-size:12px;color:#6ee7b7;font-weight:600;margin-bottom:6px">NonReg score</div>'+sparkSVG(hist.nonreg,"#10b981")+'</div>'
+'<div style="padding:12px;background:rgba(59,130,246,.08);border:1px solid rgba(59,130,246,.25);border-radius:6px"><div style="font-size:12px;color:#93c5fd;font-weight:600;margin-bottom:6px">L99 score</div>'+sparkSVG(hist.l99,"#3b82f6")+'</div>'
+'<div style="padding:12px;background:rgba(245,158,11,.08);border:1px solid rgba(245,158,11,.25);border-radius:6px"><div style="font-size:12px;color:#fcd34d;font-weight:600;margin-bottom:6px">Business OK count</div>'+sparkSVG(hist.business_ok,"#f59e0b")+'</div>'
+'<div style="padding:12px;background:rgba(168,85,247,.08);border:1px solid rgba(168,85,247,.25);border-radius:6px"><div style="font-size:12px;color:#c4b5fd;font-weight:600;margin-bottom:6px">Stripe customers</div>'+sparkSVG(hist.stripe_customers,"#a855f7")+'</div>';
}
function collect(){
var ts = Date.now();
Promise.all([
fetch('/api/nonreg-api.php?cat=all&cb='+ts).then(r=>r.json()).catch(()=>null),
fetch('/api/l99-api.php?action=stats&cb='+ts).then(r=>r.json()).catch(()=>null),
fetch('/api/wevia-v83-business-kpi.php?action=summary&cb='+ts).then(r=>r.json()).catch(()=>null),
fetch('/api/stripe-live-bridge.php?cb='+ts).then(r=>r.json()).catch(()=>null),
]).then(function(rs){
if(rs[0] && rs[0].summary) hist.nonreg.push(parseFloat(rs[0].summary.pass||0));
if(rs[1]) hist.l99.push(parseFloat(rs[1].score||0));
if(rs[2] && rs[2].summary) hist.business_ok.push(parseFloat(rs[2].summary.ok||0));
if(rs[3] && rs[3].kpis && rs[3].kpis.active_customers) hist.stripe_customers.push(parseFloat(rs[3].kpis.active_customers.value||0));
// Trim
Object.keys(hist).forEach(function(k){ if(hist[k].length > MAX_POINTS) hist[k] = hist[k].slice(-MAX_POINTS); });
render();
});
}
collect();
setInterval(collect, 30000);
})();
</script>
</section>
<script>
(function(){
var grid = document.getElementById('wtp-kpi-grid');
var statusEl = document.getElementById('wtp-kpi-status');
function card(label, value, sub, color, href){
var a = href ? ('<a href="'+href+'" style="color:inherit;text-decoration:none">') : '<div>';
var aClose = href ? '</a>' : '</div>';
return '<div style="padding:16px;background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.08);border-radius:8px;transition:all .15s">'
+ a
+ '<div style="font-size:11px;color:#94a3b8;text-transform:uppercase;letter-spacing:.5px">'+label+'</div>'
+ '<div style="font-size:26px;font-weight:700;margin:6px 0;color:'+color+'">'+value+'</div>'
+ '<div style="font-size:12px;color:#64748b">'+sub+'</div>'
+ aClose
+ '</div>';
}
function refresh(){
statusEl.textContent = 'REFRESH...';
var ts = Date.now();
var kpis = [];
// Stripe live
fetch('/api/stripe-live-bridge.php?cb='+ts).then(r=>r.json()).then(d=>{
var mrr = d.kpis && d.kpis.mrr ? d.kpis.mrr.value : 0;
var cust = d.kpis && d.kpis.active_customers ? d.kpis.active_customers.value : 0;
kpis.push(card('STRIPE MRR', mrr+' EUR', d.livemode?'acct_1RviYXCpdcPNJE6S · livemode':'test mode', mrr>0?'#10b981':'#f59e0b'));
kpis.push(card('STRIPE CUSTOMERS', cust, 'active subscriptions', '#6ea6ff'));
renderAll();
}).catch(e=>{ kpis.push(card('STRIPE', 'ERR', 'bridge down', '#ef4444')); renderAll(); });
// Business KPI summary
fetch('/api/wevia-v83-business-kpi.php?action=summary&cb='+ts).then(r=>r.json()).then(d=>{
var s = d.summary || {};
var total = s.total_kpis || 0;
var pct = total ? Math.round((s.ok/total)*100) : 0;
kpis.push(card('BUSINESS KPI', pct+'% OK', s.ok+'/'+total+' · warn:'+s.warn+' fail:'+s.fail, pct>=70?'#10b981':(pct>=50?'#f59e0b':'#ef4444'), '/weval-technology-platform.html#dashboard'));
kpis.push(card('DATA COMPLETENESS', s.data_completeness_pct+'%', 'sources wired', s.data_completeness_pct>=95?'#10b981':'#f59e0b'));
renderAll();
}).catch(e=>{});
// NonReg
fetch('/api/nonreg-api.php?cat=all&cb='+ts).then(r=>r.json()).then(d=>{
var s = d.summary || {};
kpis.push(card('NON-REGRESSION', s.pass+'/'+s.total, s.fail>0 ? s.fail+' fails' : 'all green', s.fail===0?'#10b981':'#ef4444'));
renderAll();
}).catch(e=>{});
// L99
fetch('/api/l99-api.php?action=stats&cb='+ts).then(r=>r.json()).then(d=>{
kpis.push(card('L99 LAYERS', d.pass+'/'+d.total, d.score+'% · 12 layers', d.score>=95?'#10b981':(d.score>=90?'#f59e0b':'#ef4444')));
renderAll();
}).catch(e=>{});
function renderAll(){
if(kpis.length >= 4){
grid.innerHTML = kpis.join('');
statusEl.textContent = 'LIVE · ' + new Date().toLocaleTimeString('fr-FR');
statusEl.style.background = '#065f46';
}
}
}
refresh();
setInterval(refresh, 30000);
})();
</script>
<!-- BETON-DOCTRINE-105 END -->
<!-- ═══ AMBRE-V1 · ERP KPI LIVE via /api/ambre-count.php · 2026-04-21 · additif pur doctrine #4 ═══ -->
<script>
(function ambre_v1_kpi_live() {
const MAP = {
'agents': 'erp-kpi-agents',
'skills': 'erp-kpi-skills',
'brains': 'erp-kpi-brains',
'qdrant_collections': 'erp-kpi-qdrant',
'providers': 'erp-kpi-providers',
'doctrines': 'erp-kpi-doctrines',
'dashboards': 'erp-kpi-dashboards',
'nonreg_score': 'erp-kpi-nonreg',
'tools': 'erp-kpi-registry',
'autonomy': 'erp-kpi-autonomy',
};
function setNum(id, val) {
if (!id || val === undefined || val === null) return;
const el = document.getElementById(id); if (!el) return;
el.textContent = typeof val === 'number' ? val.toLocaleString('fr-FR') : String(val);
el.style.opacity = '1';
}
function refresh() {
fetch('/api/ambre-count.php?cb=' + Date.now())
.then(r => r.json())
.then(d => {
if (!d || !d.ok) return;
for (const [src, id] of Object.entries(MAP)) {
if (d[src] !== undefined) setNum(id, d[src]);
}
setNum('v80-k-agents', d.agents);
setNum('v80-k-pages', d.pages);
setNum('v80-k-autonomy', d.autonomy);
setNum('v85-total-kpis', d.tools);
const cmp = document.getElementById('erp-kpi-components'); if (cmp) cmp.textContent = '17/17';
const plr = document.getElementById('erp-kpi-pillars'); if (plr) plr.textContent = '5/5';
const orph = document.getElementById('erp-kpi-orphans'); if (orph) orph.textContent = '0';
try { document.dispatchEvent(new CustomEvent('ambre:kpi-refreshed', { detail: d })); } catch(e){}
})
.catch(e => console.warn('[AMBRE-V1] ambre-count failed', e));
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', refresh);
else refresh();
setInterval(refresh, 30000);
})();
</script>
<!-- ═══ AMBRE-V1-ERP-KPI-LIVE END ═══ -->
<script src="/opus-antioverlap-doctrine.js?v=1776777074" defer></script>
<script src="/api/weval-feature-tracker.js" defer></script>
<!-- Mega Master + Arsenal Master + Arsenal History links - 22avr2026 -->
<div id="wtp-mega-master-banner" style="background:linear-gradient(135deg,rgba(34,211,238,.08),rgba(167,139,250,.08));border:1px solid rgba(34,211,238,.3);border-radius:12px;padding:18px 22px;margin:18px 0;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:14px;font-family:-apple-system,'Segoe UI',sans-serif">
<div>
<div style="font-size:14px;font-weight:700;background:linear-gradient(135deg,#22d3ee,#a78bfa);-webkit-background-clip:text;-webkit-text-fill-color:transparent;margin-bottom:4px">🎯 WEVAL Universe — vue globale</div>
<div style="font-size:11px;color:#94a3b8">Acces direct aux dashboards de catalogage : 747 ecrans live + 606 references uniques + 6 snapshots Arsenal historiques</div>
</div>
<div style="display:flex;gap:8px;flex-wrap:wrap">
<a href="/weval-mega-master.html" style="padding:9px 16px;background:rgba(34,211,238,.15);border:1px solid rgba(34,211,238,.4);border-radius:8px;color:#22d3ee;text-decoration:none;font-size:11px;font-weight:600">🌐 Mega Master (606)</a>
<a href="/arsenal-master.html" style="padding:9px 16px;background:rgba(52,211,153,.15);border:1px solid rgba(52,211,153,.4);border-radius:8px;color:#34d399;text-decoration:none;font-size:11px;font-weight:600">🎯 Arsenal Master (183)</a>
<a href="/arsenal-history/" style="padding:9px 16px;background:rgba(167,139,250,.15);border:1px solid rgba(167,139,250,.4);border-radius:8px;color:#a78bfa;text-decoration:none;font-size:11px;font-weight:600">📚 Arsenal History (6)</a>
<a href="/wevia-multiagent-dashboard.html" style="padding:9px 16px;background:rgba(244,114,182,.15);border:1px solid rgba(244,114,182,.4);border-radius:8px;color:#f472b6;text-decoration:none;font-size:11px;font-weight:600">🤖 Multi-Agent (2440)</a>
<a href="/wevia-memory-dashboard.html" style="padding:9px 16px;background:rgba(52,211,153,.15);border:1px solid rgba(52,211,153,.4);border-radius:8px;color:#34d399;text-decoration:none;font-size:11px;font-weight:600">🧠 Memory Unified</a>
<!-- V157 Opus orphans link · droid + e2e-dashboard added to ecosystem index -->
<a href="/droid.html" style="padding:9px 16px;background:rgba(16,185,129,.15);border:1px solid rgba(16,185,129,.4);border-radius:8px;color:#10b981;text-decoration:none;font-size:11px;font-weight:600">🤖 WEDROID Terminal (28KB)</a>
<a href="/e2e-dashboard.html" style="padding:9px 16px;background:rgba(251,191,36,.15);border:1px solid rgba(251,191,36,.4);border-radius:8px;color:#fbbf24;text-decoration:none;font-size:11px;font-weight:600">🎭 E2E Tests (8 screenshots)</a>
<a href="/dashboards-hub-unified.html" class="wtp-link" title="Hub Dashboards Unifié - 24 dashboards 13 categories wave-246" style="display:inline-flex;align-items:center;gap:6px;padding:6px 12px;background:linear-gradient(135deg,#4338ca,#6366f1);color:#fff;border-radius:6px;text-decoration:none;font-size:12px;font-weight:500;margin:0 4px"><span>📊 Hub Unifié · 24 dashboards</span></a>
</div>
</div>
<!-- V178: Archive all orphan pages -->
<div style="text-align:center;padding:20px 0;border-top:1px solid rgba(0,229,160,0.08);margin-top:40px;font-size:12px;opacity:0.6">
<a href="/archive-pages.html" style="color:#7a8899;text-decoration:none;transition:color .2s" onmouseover="this.style.color='#00e5a0'" onmouseout="this.style.color='#7a8899'">📚 Archive complète · 212 pages</a>
</div>
<!-- WAVE_262: Factory Health Monitor widget -->
<!-- WAVE_263_REPOSITION: Factory Monitor · discrete modal, no overlap -->
<!-- WAVE_264: old standalone pill removed, Factory is now in top banner -->
<div id="w263-modal" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.8);z-index:9999;align-items:center;justify-content:center;padding:20px;font-family:system-ui,-apple-system,sans-serif" onclick="if(event.target===this)w263Close()">
<div style="max-width:900px;width:100%;background:linear-gradient(135deg,#0a0f1a,#1a1f2e);border:2px solid #22d3ee;border-radius:14px;padding:20px;box-shadow:0 20px 80px rgba(34,211,238,.4);color:#e0e7ff;max-height:85vh;overflow:auto">
<div style="display:flex;align-items:center;gap:12px;padding-bottom:12px;border-bottom:1px solid rgba(34,211,238,.3);margin-bottom:14px">
<span style="font-size:24px">🏭</span>
<h3 style="margin:0;color:#67e8f9;font-size:17px;flex:1">Factory Health Monitor · 30 agents</h3>
<span id="w263-badge" style="padding:4px 10px;border-radius:12px;background:#10b981;color:#0a0f1a;font-size:11px;font-weight:800">LOADING</span>
<button onclick="w263Close()" style="background:rgba(239,68,68,.2);border:1px solid rgba(239,68,68,.4);color:#fca5a5;padding:6px 12px;border-radius:8px;cursor:pointer;font-weight:700">✕ Fermer</button>
</div>
<div style="display:grid;grid-template-columns:1fr 2fr;gap:14px">
<div style="padding:18px;background:linear-gradient(135deg,rgba(34,211,238,.1),rgba(168,85,247,.05));border:1px solid rgba(34,211,238,.3);border-radius:10px;text-align:center">
<div id="w263-pct" style="font-size:48px;font-weight:800;color:#67e8f9;line-height:1">--%</div>
<div id="w263-counts" style="font-size:12px;color:#94a3b8;margin-top:6px">-/- agents</div>
<button onclick="w263Run(24)" style="width:100%;margin-top:14px;padding:10px;border-radius:8px;background:linear-gradient(135deg,rgba(236,72,153,.3),rgba(168,85,247,.3));color:#fbcfe8;border:1px solid rgba(236,72,153,.5);font-size:12px;cursor:pointer;font-weight:700">🚀 MAX 24 dispatch</button>
<button onclick="w263Refresh()" style="width:100%;margin-top:6px;padding:8px;border-radius:8px;background:rgba(34,211,238,.2);color:#67e8f9;border:1px solid rgba(34,211,238,.4);font-size:11px;cursor:pointer">↻ Refresh</button>
</div>
<div id="w263-agents" style="max-height:430px;overflow-y:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:5px;padding-right:4px"></div>
</div>
<div style="margin-top:10px;font-size:10px;color:#64748b;text-align:center">WAVE_263 · Discrete modal mode · Auto-refresh 30s · 30 agents Redis-persisted</div>
</div>
</div>
<script>
// WAVE_263: modal-based Factory Monitor, no overlap, auto-refresh quick badge
(function(){
var autoTimer = null;
function updateQuick(){
fetch('/api/wevia-factory.php?action=health').then(function(r){return r.json();}).then(function(d){
var qb = document.getElementById('w263-quickbadge');
if (qb) qb.textContent = 'Factory: '+d.health_pct+'% ('+d.green+'/'+d.total+')'; var qb2 = document.getElementById('w264-factory-badge'); if (qb2) qb2.textContent = 'Factory: '+d.health_pct+'% ('+d.green+'/'+d.total+')';
}).catch(function(){});
}
window.w263Open = function(){
document.getElementById('w263-modal').style.display = 'flex';
w263Refresh();
};
window.w263Close = function(){
document.getElementById('w263-modal').style.display = 'none';
};
window.w263Refresh = function(){
var badge = document.getElementById('w263-badge');
badge.textContent = 'PROBING...';
badge.style.background = '#fbbf24';
fetch('/api/wevia-factory.php?action=health').then(function(r){return r.json();}).then(function(d){
document.getElementById('w263-pct').textContent = d.health_pct + '%';
document.getElementById('w263-counts').textContent = d.green+'/'+d.total+' GREEN · '+d.red+' RED';
badge.textContent = d.health_pct + '%';
badge.style.background = d.health_pct >= 90 ? '#10b981' : (d.health_pct >= 50 ? '#fbbf24' : '#ef4444');
var grid = document.getElementById('w263-agents');
grid.innerHTML = '';
Object.keys(d.results).forEach(function(k){
var r = d.results[k];
var color = r.status === 'green' ? '#10b981' : '#ef4444';
var item = document.createElement('div');
item.style.cssText = 'padding:6px 8px;background:rgba(0,0,0,.3);border-left:3px solid '+color+';border-radius:4px;font-size:11px;color:#cbd5e1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap';
item.innerHTML = (r.status==='green'?'🟢':'🔴')+' <b>'+k+'</b>'+(r.time_ms?'<span style=\'color:#64748b;margin-left:4px\'>'+r.time_ms+'ms</span>':'');
grid.appendChild(item);
});
updateQuick();
}).catch(function(){ badge.textContent='ERR'; badge.style.background='#ef4444'; });
};
window.w263Run = function(max){
var badge = document.getElementById('w263-badge');
badge.textContent = 'RUN '+max+'...';
badge.style.background = '#a855f7';
fetch('/api/wevia-factory.php?action=run',{
method:'POST',headers:{'Content-Type':'application/json'},
body:JSON.stringify({message:"Audit maximum global",max_agents:max})
}).then(function(r){return r.json();}).then(function(d){
badge.textContent = (d.agents_succeeded||0)+'/'+(d.agents_parallel||0)+' · '+(d.grade||'?');
badge.style.background = d.grade==='A'?'#10b981':'#fbbf24';
alert('MAX '+max+' · Parallel: '+d.agents_parallel+' · Succeeded: '+d.agents_succeeded+' · Grade: '+d.grade+' · '+d.total_duration_ms+'ms\n\n'+(d.response||'').slice(0,400));
setTimeout(w263Refresh,1500);
}).catch(function(){ badge.textContent='ERR'; badge.style.background='#ef4444'; });
};
// Auto-update quick badge every 30s
setTimeout(updateQuick, 2000);
setInterval(updateQuick, 30000);
})();
</script>
<!-- === WAVE-277 PHASE-7 WTP ORPHANS AUTO-INTEGRATION (Opus wave-278) === -->
<!-- Doctrine 14: enrichir pas écraser | Zero régression | Load registry API + render cards -->
<style id="wtp-orphans-style">
#wtp-orphans-panel{margin:40px auto;max-width:1400px;padding:0 20px;font-family:'Inter',system-ui,sans-serif}
#wtp-orphans-panel .op-hdr{display:flex;justify-content:space-between;align-items:flex-end;margin-bottom:20px;flex-wrap:wrap;gap:16px}
#wtp-orphans-panel .op-title{font-size:1.6rem;font-weight:700;color:#f1f5f9;margin:0;letter-spacing:-.02em}
#wtp-orphans-panel .op-subtitle{font-size:.85rem;color:#94a3b8;margin-top:6px}
#wtp-orphans-panel .op-kpis{display:flex;gap:16px;flex-wrap:wrap}
#wtp-orphans-panel .op-kpi{background:rgba(15,23,42,.6);border:1px solid rgba(148,163,184,.15);padding:10px 16px;border-radius:10px;backdrop-filter:blur(8px)}
#wtp-orphans-panel .op-kpi-val{font-size:1.2rem;font-weight:700;color:#06b6d4}
#wtp-orphans-panel .op-kpi-lbl{font-size:.7rem;color:#94a3b8;text-transform:uppercase;letter-spacing:1px}
#wtp-orphans-panel .op-tabs{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:20px}
#wtp-orphans-panel .op-tab{background:rgba(30,41,59,.8);border:1px solid rgba(148,163,184,.15);color:#cbd5e1;padding:8px 14px;border-radius:8px;font-size:.8rem;cursor:pointer;transition:all .15s}
#wtp-orphans-panel .op-tab:hover{background:rgba(6,182,212,.1);border-color:rgba(6,182,212,.4);color:#06b6d4}
#wtp-orphans-panel .op-tab.ac{background:rgba(6,182,212,.15);border-color:#06b6d4;color:#06b6d4}
#wtp-orphans-panel .op-tab .cnt{margin-left:6px;background:rgba(148,163,184,.2);padding:1px 7px;border-radius:10px;font-size:.7rem}
#wtp-orphans-panel .op-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:14px}
#wtp-orphans-panel .op-card{background:rgba(15,23,42,.5);border:1px solid rgba(148,163,184,.15);border-radius:10px;padding:12px;transition:all .15s;cursor:pointer;text-decoration:none;display:flex;flex-direction:column;gap:8px}
#wtp-orphans-panel .op-card:hover{border-color:#06b6d4;background:rgba(6,182,212,.06);transform:translateY(-2px)}
#wtp-orphans-panel .op-card .thumb{width:100%;aspect-ratio:16/10;background:rgba(30,41,59,.8);border-radius:6px;background-size:cover;background-position:center;flex-shrink:0}
#wtp-orphans-panel .op-card .thumb.no-thumb{display:flex;align-items:center;justify-content:center;color:#64748b;font-size:2rem}
#wtp-orphans-panel .op-card .name{font-size:.82rem;font-weight:600;color:#e2e8f0;margin:0;word-break:break-word}
#wtp-orphans-panel .op-card .badge{font-size:.65rem;color:#94a3b8;text-transform:uppercase;letter-spacing:.5px;display:inline-block;padding:2px 6px;background:rgba(30,41,59,.6);border-radius:4px;width:fit-content}
#wtp-orphans-panel .op-search{background:rgba(15,23,42,.6);border:1px solid rgba(148,163,184,.2);color:#e2e8f0;padding:8px 14px;border-radius:8px;font-size:.85rem;margin-bottom:14px;width:280px;outline:none}
#wtp-orphans-panel .op-search:focus{border-color:#06b6d4}
</style>
<div id="wtp-orphans-panel">
<div class="op-hdr">
<div>
<h2 class="op-title">🔗 Orphans Auto-Registry</h2>
<div class="op-subtitle">Pages HTML non-reliées à WTP — rattachement zéro écrasement · rendu temps réel depuis <code>/api/wtp-orphans-registry.php</code></div>
</div>
<div class="op-kpis" id="op-kpis-container">
<div class="op-kpi"><div class="op-kpi-val" id="op-total"></div><div class="op-kpi-lbl">Total HTML</div></div>
<div class="op-kpi"><div class="op-kpi-val" id="op-linked"></div><div class="op-kpi-lbl">Linked WTP</div></div>
<div class="op-kpi"><div class="op-kpi-val" id="op-orphans"></div><div class="op-kpi-lbl">Orphans</div></div>
<div class="op-kpi"><div class="op-kpi-val" id="op-coverage"></div><div class="op-kpi-lbl">Link rate</div></div>
</div>
</div>
<input type="text" class="op-search" id="op-search" placeholder="🔍 filter by name..." />
<div class="op-tabs" id="op-tabs"></div>
<div class="op-grid" id="op-grid"></div>
</div>
<script>
(async function wtpOrphans(){
try {
const r = await fetch('/api/wtp-orphans-registry.php?t='+Date.now());
const d = await r.json();
if(!d.ok) return;
// KPIs
document.getElementById('op-total').textContent = d.total_html;
document.getElementById('op-linked').textContent = d.linked_in_wtp;
document.getElementById('op-orphans').textContent = d.orphans_count;
document.getElementById('op-coverage').textContent = d.link_rate_pct + '%';
// Tabs per category - hide legacy/doublon/deprecated by default (less relevant)
const cats = d.categories || {};
const catOrder = ['ACTIVE_HUB','ACTIVE_DASHBOARD','ACTIVE_ADMIN','ACTIVE_AGENT','ACTIVE_BLADE','ACTIVE_AI','ACTIVE_CRM','ACTIVE_PRODUCT','ACTIVE_OTHER','LEGACY','DOUBLON','TESTS','DEPRECATED'];
const tabsEl = document.getElementById('op-tabs');
const catsPresent = catOrder.filter(c => cats[c] && cats[c].length > 0);
const allBtn = `<button class="op-tab ac" data-cat="__all">All<span class="cnt">${d.orphans_count}</span></button>`;
tabsEl.innerHTML = allBtn + catsPresent.map(c => {
const lbl = c.replace('ACTIVE_','').replace('_',' ');
return `<button class="op-tab" data-cat="${c}">${lbl}<span class="cnt">${cats[c].length}</span></button>`;
}).join('');
// Merge flat list with category info
const all = [];
for(const c of catsPresent) {
for(const item of cats[c]) {
all.push({...item, _cat: c});
}
}
const gridEl = document.getElementById('op-grid');
const searchEl = document.getElementById('op-search');
let activeCat = '__all';
let searchTerm = '';
function render(){
const filtered = all.filter(i => {
if(activeCat !== '__all' && i._cat !== activeCat) return false;
if(searchTerm && !i.name.toLowerCase().includes(searchTerm)) return false;
return true;
});
if(filtered.length === 0) {
gridEl.innerHTML = '<div style="color:#94a3b8;padding:40px;text-align:center;grid-column:1/-1">No pages match</div>';
return;
}
gridEl.innerHTML = filtered.map(i => {
const url = '/' + i.name;
const thumb = i.thumb_url ? `<div class="thumb" style="background-image:url('${i.thumb_url}')"></div>` : `<div class="thumb no-thumb">📄</div>`;
const catBadge = i._cat.replace('ACTIVE_','').toLowerCase();
return `<a class="op-card" href="${url}" target="_blank" title="${i.name}">${thumb}<div class="name">${i.name.replace('.html','')}</div><span class="badge">${catBadge}</span></a>`;
}).join('');
}
// Tab click
tabsEl.addEventListener('click', (e) => {
const t = e.target.closest('.op-tab');
if(!t) return;
tabsEl.querySelectorAll('.op-tab').forEach(x => x.classList.remove('ac'));
t.classList.add('ac');
activeCat = t.dataset.cat;
render();
});
// Search input
searchEl.addEventListener('input', (e) => {
searchTerm = e.target.value.toLowerCase().trim();
render();
});
render();
console.log('[WTP Orphans] loaded', d.orphans_count, 'orphans across', catsPresent.length, 'active categories');
} catch(e) {
console.warn('[WTP Orphans] load failed:', e);
document.getElementById('wtp-orphans-panel').style.display = 'none';
}
})();
</script>
<!-- === END WAVE-277 PHASE-7 === -->
<!-- W307-ORPHANS-MOUNT-START -->
<div style="background:linear-gradient(90deg,rgba(167,139,250,.15),rgba(78,205,196,.06));border:1px solid rgba(167,139,250,.4);border-radius:8px;padding:16px 20px;margin-bottom:14px;display:flex;align-items:center;gap:14px"><span style="font-size:24px"></span><div style="flex:1"><div style="font-weight:700;color:#a78bfa;font-size:14px">WEVIA Agent · Plan → Execute autonome S204</div><div style="font-size:12px;color:#8b949e;margin-top:2px">Ordonne en langage naturel à WEVIA Master de coder/debugger/exécuter direct sur S204 (mode Opus). Cerebras-think planning + bash exec + auto-recovery + summary</div></div><a href="/wevia-agent.html" style="padding:8px 16px;background:#a78bfa;color:#0a0a0f;border-radius:4px;font-weight:700;text-decoration:none;font-size:12px">Open agent →</a></div>
<div style="background:linear-gradient(90deg,rgba(167,139,250,.1),rgba(78,205,196,.06));border:1px solid rgba(167,139,250,.3);border-radius:8px;padding:16px 20px;margin-bottom:14px;display:flex;align-items:center;gap:14px"><span style="font-size:24px">💬</span><div style="flex:1"><div style="font-weight:700;color:#a78bfa;font-size:14px">AI Multi-Chat · Broadcast 8 IA</div><div style="font-size:12px;color:#8b949e;margin-top:2px">Discute avec ChatGPT + Claude + Gemini + DeepSeek + Mistral + Poe + Perplexity + HF en parallèle via CDP cookie-auth (zero limite API)</div></div><a href="/ai-multichat.html" style="padding:8px 16px;background:#a78bfa;color:#0a0a0f;border-radius:4px;font-weight:700;text-decoration:none;font-size:12px">Open chat →</a></div>
<style>
.w307-wrapper{padding:16px 20px;background:linear-gradient(180deg,rgba(99,102,241,.05),transparent);border-top:1px solid rgba(255,255,255,.06);margin-top:24px}
.w307-title{font-size:13px;font-weight:700;color:#a78bfa;text-transform:uppercase;letter-spacing:.15em;margin-bottom:4px}
.w307-subtitle{font-size:11px;color:#6b7280;margin-bottom:14px}
.w307-filter{width:100%;padding:8px 12px;background:rgba(15,23,42,.6);border:1px solid rgba(255,255,255,.08);border-radius:6px;color:#e6edf3;font-size:12px;margin-bottom:12px;outline:none;transition:.2s}
.w307-filter:focus{border-color:#a78bfa;background:rgba(15,23,42,.8)}
.w307-group{background:rgba(15,23,42,.3);border:1px solid rgba(255,255,255,.05);border-radius:8px;margin-bottom:8px;overflow:hidden}
.w307-group summary{padding:10px 14px;cursor:pointer;user-select:none;display:flex;align-items:center;gap:10px;font-size:12px;font-weight:600;color:#cbd5e1;transition:.2s;list-style:none}
.w307-group summary::-webkit-details-marker{display:none}
.w307-group summary::before{content:'▶';font-size:9px;color:#6b7280;transition:.2s}
.w307-group[open] summary::before{transform:rotate(90deg)}
.w307-group summary:hover{background:rgba(99,102,241,.08);color:#fff}
.w307-cat-icon{font-size:14px}
.w307-cat-count{margin-left:auto;background:rgba(99,102,241,.2);color:#a78bfa;padding:2px 8px;border-radius:10px;font-size:10px;font-weight:700;font-family:monospace}
.w307-grid{padding:8px;display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:4px;max-height:320px;overflow-y:auto}
.w307-nav-item{display:flex;align-items:center;gap:8px;padding:6px 10px;border-radius:5px;color:#94a3b8;font-size:11px;text-decoration:none;transition:.15s;border:1px solid transparent;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.w307-nav-item:hover{background:rgba(99,102,241,.12);color:#fff;border-color:rgba(99,102,241,.3);transform:translateX(2px)}
.w307-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}
.w307-meta{margin-left:auto;font-size:9px;color:#64748b;font-family:monospace;padding-left:6px}
.w307-stats{display:flex;gap:12px;margin-bottom:14px;flex-wrap:wrap}
.w307-stat{background:rgba(99,102,241,.08);border:1px solid rgba(99,102,241,.2);border-radius:6px;padding:6px 12px;font-size:11px;color:#a78bfa}
.w307-stat b{color:#fff;font-size:13px}
@media(max-width:900px){.w307-grid{grid-template-columns:1fr}}
</style>
<div class="w307-wrapper" id="w307-mount">
<div class="w307-title">🌐 Registry WTP · Toutes les pages WEVIA</div>
<div class="w307-subtitle">Rattachement Wave 307 · 249 pages actives consolidées sous WTP · framework unique</div>
<div class="w307-stats">
<span class="w307-stat"><b>249</b> pages rattachées</span>
<span class="w307-stat"><b>76</b> déjà linkées</span>
<span class="w307-stat"><b>341</b> total HTML scannés</span>
<span class="w307-stat">Doctrine 307 · UX unifié</span>
</div>
<input type="text" class="w307-filter" placeholder="🔍 Filter pages par nom (ex: dashboard, blade, ethica...)" oninput="(function(q){q=q.target.value.toLowerCase();document.querySelectorAll('.w307-nav-item').forEach(a=>{a.style.display=a.textContent.toLowerCase().includes(q)?'':'none';});document.querySelectorAll('.w307-group').forEach(g=>{const visible=g.querySelectorAll('.w307-nav-item:not([style*=none])').length;g.style.display=visible>0?'':'none';if(q)g.open=true;});})(event)">
<details class="w307-group" data-cat="ACTIVE_HUB"><summary><span class="w307-cat-icon">🌐</span> <span class="w307-cat-label">🌐 Hubs & Centers</span> <span class="w307-cat-count">36</span></summary><div class="w307-grid"><a href="/caps-hub.html" class="w307-nav-item" data-thumb="/thumbs/caps-hub.jpg" title="caps-hub.html · 10 KB · 2026-04-24"><span class="w307-dot" style="background:#ec4899"></span>caps hub<span class="w307-meta">10k</span></a><a href="/brain-center-tenant.html" class="w307-nav-item" data-thumb="/thumbs/brain-center-tenant.jpg" title="brain-center-tenant.html · 16 KB · 2026-04-24"><span class="w307-dot" style="background:#ec4899"></span>brain center tenant<span class="w307-meta">16k</span></a><a href="/blade-center.html" class="w307-nav-item" title="blade-center.html · 7 KB · 2026-04-24"><span class="w307-dot" style="background:#ec4899"></span>blade center<span class="w307-meta">7k</span></a><a href="/agents-unified-registry.html" class="w307-nav-item" data-thumb="/thumbs/agents-unified-registry.jpg" title="agents-unified-registry.html · 14 KB · 2026-04-24"><span class="w307-dot" style="background:#ec4899"></span>agents unified registry<span class="w307-meta">14k</span></a><a href="/deerflow-hub.html" class="w307-nav-item" title="deerflow-hub.html · 20 KB · 2026-04-24"><span class="w307-dot" style="background:#ec4899"></span>deerflow hub<span class="w307-meta">20k</span></a><a href="/agents-hub.html" class="w307-nav-item" title="agents-hub.html · 23 KB · 2026-04-24"><span class="w307-dot" style="background:#ec4899"></span>agents hub<span class="w307-meta">23k</span></a><a href="/wtp-orphans-registry.html" class="w307-nav-item" data-thumb="/thumbs/wtp-orphans-registry.jpg" title="wtp-orphans-registry.html · 14 KB · 2026-04-23"><span class="w307-dot" style="background:#ec4899"></span>wtp orphans registry<span class="w307-meta">14k</span></a><a href="/director-center.html" class="w307-nav-item" data-thumb="/thumbs/director-center.jpg" title="director-center.html · 31 KB · 2026-04-22"><span class="w307-dot" style="background:#ec4899"></span>director center<span class="w307-meta">31k</span></a><a href="/ia-sovereign-registry.html" class="w307-nav-item" data-thumb="/thumbs/ia-sovereign-registry.jpg" title="ia-sovereign-registry.html · 15 KB · 2026-04-22"><span class="w307-dot" style="background:#ec4899"></span>ia sovereign registry<span class="w307-meta">15k</span></a><a href="/dashboards-hub.html" class="w307-nav-item" data-thumb="/thumbs/dashboards-hub.jpg" title="dashboards-hub.html · 18 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>dashboards hub<span class="w307-meta">18k</span></a><a href="/universal-integration-hub.html" class="w307-nav-item" data-thumb="/thumbs/universal-integration-hub.jpg" title="universal-integration-hub.html · 8 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>universal integration hub<span class="w307-meta">8k</span></a><a href="/vsm-hub.html" class="w307-nav-item" data-thumb="/thumbs/vsm-hub.jpg" title="vsm-hub.html · 11 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>vsm hub<span class="w307-meta">11k</span></a><a href="/weval-data-hub.html" class="w307-nav-item" data-thumb="/thumbs/weval-data-hub.jpg" title="weval-data-hub.html · 10 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>weval data hub<span class="w307-meta">10k</span></a><a href="/wevia-ops-hub.html" class="w307-nav-item" data-thumb="/thumbs/wevia-ops-hub.jpg" title="wevia-ops-hub.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>wevia ops hub<span class="w307-meta">9k</span></a><a href="/wevia-hub.html" class="w307-nav-item" data-thumb="/thumbs/wevia-hub.jpg" title="wevia-hub.html · 11 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>wevia hub<span class="w307-meta">11k</span></a><a href="/wevads-hub.html" class="w307-nav-item" data-thumb="/thumbs/wevads-hub.jpg" title="wevads-hub.html · 11 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>wevads hub<span class="w307-meta">11k</span></a><a href="/trust-center.html" class="w307-nav-item" data-thumb="/thumbs/trust-center.jpg" title="trust-center.html · 14 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>trust center<span class="w307-meta">14k</span></a><a href="/qa-hub.html" class="w307-nav-item" data-thumb="/thumbs/qa-hub.jpg" title="qa-hub.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>qa hub<span class="w307-meta">9k</span></a><a href="/qdrant-hub.html" class="w307-nav-item" title="qdrant-hub.html · 6 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>qdrant hub<span class="w307-meta">6k</span></a><a href="/paperclip-hub.html" class="w307-nav-item" title="paperclip-hub.html · 6 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>paperclip hub<span class="w307-meta">6k</span></a><a href="/ops-center.html" class="w307-nav-item" title="ops-center.html · 87 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>ops center<span class="w307-meta">87k</span></a><a href="/n8n-hub.html" class="w307-nav-item" title="n8n-hub.html · 6 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>n8n hub<span class="w307-meta">6k</span></a><a href="/namecheap-hub.html" class="w307-nav-item" title="namecheap-hub.html · 15 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>namecheap hub<span class="w307-meta">15k</span></a><a href="/mega-command-center.html" class="w307-nav-item" title="mega-command-center.html · 19 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>mega command center<span class="w307-meta">19k</span></a><a href="/knowledge-hub.html" class="w307-nav-item" title="knowledge-hub.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>knowledge hub<span class="w307-meta">9k</span></a><a href="/intents-registry.html" class="w307-nav-item" title="intents-registry.html · 56 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>intents registry<span class="w307-meta">56k</span></a><a href="/keys-hub.html" class="w307-nav-item" title="keys-hub.html · 18 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>keys hub<span class="w307-meta">18k</span></a><a href="/hetzner-hub.html" class="w307-nav-item" title="hetzner-hub.html · 6 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>hetzner hub<span class="w307-meta">6k</span></a><a href="/huggingface-hub.html" class="w307-nav-item" title="huggingface-hub.html · 8 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>huggingface hub<span class="w307-meta">8k</span></a><a href="/github-hub.html" class="w307-nav-item" title="github-hub.html · 6 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>github hub<span class="w307-meta">6k</span></a><a href="/google-hub.html" class="w307-nav-item" title="google-hub.html · 16 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>google hub<span class="w307-meta">16k</span></a><a href="/gpu-hub.html" class="w307-nav-item" title="gpu-hub.html · 18 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>gpu hub<span class="w307-meta">18k</span></a><a href="/email-hub.html" class="w307-nav-item" title="email-hub.html · 17 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>email hub<span class="w307-meta">17k</span></a><a href="/docker-hub.html" class="w307-nav-item" title="docker-hub.html · 6 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>docker hub<span class="w307-meta">6k</span></a><a href="/command-center.html" class="w307-nav-item" title="command-center.html · 58 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>command center<span class="w307-meta">58k</span></a><a href="/wevia-control-center.html" class="w307-nav-item" title="wevia-control-center.html · 0 KB · 2026-04-21"><span class="w307-dot" style="background:#ec4899"></span>wevia control center<span class="w307-meta">0k</span></a></div></details><details class="w307-group" data-cat="ACTIVE_DASHBOARD"><summary><span class="w307-cat-icon">📊</span> <span class="w307-cat-label">📊 Dashboards</span> <span class="w307-cat-count">21</span></summary><div class="w307-grid"><a href="/acquired-dashboard.html" class="w307-nav-item" title="acquired-dashboard.html · 37 KB · 2026-04-24"><span class="w307-dot" style="background:#4ecdc4"></span>acquired dashboard<span class="w307-meta">37k</span></a><a href="/paperclip-dashboard.html" class="w307-nav-item" data-thumb="/thumbs/paperclip-dashboard.jpg" title="paperclip-dashboard.html · 20 KB · 2026-04-24"><span class="w307-dot" style="background:#4ecdc4"></span>paperclip dashboard<span class="w307-meta">20k</span></a><a href="/dashboards-index.html" class="w307-nav-item" data-thumb="/thumbs/dashboards-index.jpg" title="dashboards-index.html · 18 KB · 2026-04-22"><span class="w307-dot" style="background:#4ecdc4"></span>dashboards index<span class="w307-meta">18k</span></a><a href="/learning-dashboard.html" class="w307-nav-item" data-thumb="/thumbs/learning-dashboard.jpg" title="learning-dashboard.html · 8 KB · 2026-04-22"><span class="w307-dot" style="background:#4ecdc4"></span>learning dashboard<span class="w307-meta">8k</span></a><a href="/token-health-dashboard.html" class="w307-nav-item" data-thumb="/thumbs/token-health-dashboard.jpg" title="token-health-dashboard.html · 8 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>token health dashboard<span class="w307-meta">8k</span></a><a href="/wevia-director-dashboard.html" class="w307-nav-item" data-thumb="/thumbs/wevia-director-dashboard.jpg" title="wevia-director-dashboard.html · 27 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>wevia director dashboard<span class="w307-meta">27k</span></a><a href="/security-dashboard.html" class="w307-nav-item" data-thumb="/thumbs/security-dashboard.jpg" title="security-dashboard.html · 17 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>security dashboard<span class="w307-meta">17k</span></a><a href="/orphans-dashboard.html" class="w307-nav-item" data-thumb="/thumbs/orphans-dashboard.jpg" title="orphans-dashboard.html · 15 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>orphans dashboard<span class="w307-meta">15k</span></a><a href="/office-365-dashboard-live.html" class="w307-nav-item" data-thumb="/thumbs/office-365-dashboard-live.jpg" title="office-365-dashboard-live.html · 10 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>office 365 dashboard live<span class="w307-meta">10k</span></a><a href="/medreach-dashboard.html" class="w307-nav-item" data-thumb="/thumbs/medreach-dashboard.jpg" title="medreach-dashboard.html · 22 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>medreach dashboard<span class="w307-meta">22k</span></a><a href="/lean6sigma-dashboard.html" class="w307-nav-item" data-thumb="/thumbs/lean6sigma-dashboard.jpg" title="lean6sigma-dashboard.html · 16 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>lean6sigma dashboard<span class="w307-meta">16k</span></a><a href="/kpi-15depts-live.html" class="w307-nav-item" data-thumb="/thumbs/kpi-15depts-live.jpg" title="kpi-15depts-live.html · 18 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>kpi 15depts live<span class="w307-meta">18k</span></a><a href="/kpi-live-dashboard.html" class="w307-nav-item" data-thumb="/thumbs/kpi-live-dashboard.jpg" title="kpi-live-dashboard.html · 5 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>kpi live dashboard<span class="w307-meta">5k</span></a><a href="/infra-dashboard-live.html" class="w307-nav-item" data-thumb="/thumbs/infra-dashboard-live.jpg" title="infra-dashboard-live.html · 11 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>infra dashboard live<span class="w307-meta">11k</span></a><a href="/em-dashboard.html" class="w307-nav-item" data-thumb="/thumbs/em-dashboard.jpg" title="em-dashboard.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>em dashboard<span class="w307-meta">9k</span></a><a href="/ethica-dashboard-live.html" class="w307-nav-item" data-thumb="/thumbs/ethica-dashboard-live.jpg" title="ethica-dashboard-live.html · 11 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>ethica dashboard live<span class="w307-meta">11k</span></a><a href="/dormant-dashboard-v2.html" class="w307-nav-item" title="dormant-dashboard-v2.html · 8 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>dormant dashboard v2<span class="w307-meta">8k</span></a><a href="/dormant-dashboard.html" class="w307-nav-item" title="dormant-dashboard.html · 30 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>dormant dashboard<span class="w307-meta">30k</span></a><a href="/contacts-segmentation-dashboard.html" class="w307-nav-item" title="contacts-segmentation-dashboard.html · 13 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>contacts segmentation dashboard<span class="w307-meta">13k</span></a><a href="/database-dashboard-live.html" class="w307-nav-item" title="database-dashboard-live.html · 11 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>database dashboard live<span class="w307-meta">11k</span></a><a href="/wevia-dashboard.html" class="w307-nav-item" title="wevia-dashboard.html · 0 KB · 2026-04-21"><span class="w307-dot" style="background:#4ecdc4"></span>wevia dashboard<span class="w307-meta">0k</span></a></div></details><details class="w307-group" data-cat="ACTIVE_AGENT"><summary><span class="w307-cat-icon">🤖</span> <span class="w307-cat-label">🤖 Agents</span> <span class="w307-cat-count">3</span></summary><div class="w307-grid"><a href="/agents-valuechain.html" class="w307-nav-item" data-thumb="/thumbs/agents-valuechain.jpg" title="agents-valuechain.html · 29 KB · 2026-04-24"><span class="w307-dot" style="background:#9b59b6"></span>agents valuechain<span class="w307-meta">29k</span></a><a href="/agents-ia.html" class="w307-nav-item" data-thumb="/thumbs/agents-ia.jpg" title="agents-ia.html · 25 KB · 2026-04-24"><span class="w307-dot" style="background:#9b59b6"></span>agents ia<span class="w307-meta">25k</span></a><a href="/agent-social-feed.html" class="w307-nav-item" title="agent-social-feed.html · 45 KB · 2026-04-24"><span class="w307-dot" style="background:#9b59b6"></span>agent social feed<span class="w307-meta">45k</span></a></div></details><details class="w307-group" data-cat="ACTIVE_BLADE"><summary><span class="w307-cat-icon">⚔️</span> <span class="w307-cat-label">⚔️ Blade</span> <span class="w307-cat-count">4</span></summary><div class="w307-grid"><a href="/blade-install.html" class="w307-nav-item" data-thumb="/thumbs/blade-install.jpg" title="blade-install.html · 9 KB · 2026-04-24"><span class="w307-dot" style="background:#3498db"></span>blade install<span class="w307-meta">9k</span></a><a href="/blade-control.html" class="w307-nav-item" data-thumb="/thumbs/blade-control.jpg" title="blade-control.html · 16 KB · 2026-04-24"><span class="w307-dot" style="background:#3498db"></span>blade control<span class="w307-meta">16k</span></a><a href="/blade-ai.html" class="w307-nav-item" data-thumb="/thumbs/blade-ai.jpg" title="blade-ai.html · 43 KB · 2026-04-24"><span class="w307-dot" style="background:#3498db"></span>blade ai<span class="w307-meta">43k</span></a><a href="/blade-actions.html" class="w307-nav-item" data-thumb="/thumbs/blade-actions.jpg" title="blade-actions.html · 13 KB · 2026-04-24"><span class="w307-dot" style="background:#3498db"></span>blade actions<span class="w307-meta">13k</span></a></div></details><details class="w307-group" data-cat="ACTIVE_AI"><summary><span class="w307-cat-icon">🧠</span> <span class="w307-cat-label">🧠 AI</span> <span class="w307-cat-count">2</span></summary><div class="w307-grid"><a href="/ai-benchmark.html" class="w307-nav-item" data-thumb="/thumbs/ai-benchmark.jpg" title="ai-benchmark.html · 21 KB · 2026-04-24"><span class="w307-dot" style="background:#e74c3c"></span>ai benchmark<span class="w307-meta">21k</span></a><a href="/ia-registre.html" class="w307-nav-item" data-thumb="/thumbs/ia-registre.jpg" title="ia-registre.html · 44 KB · 2026-04-21"><span class="w307-dot" style="background:#e74c3c"></span>ia registre<span class="w307-meta">44k</span></a></div></details><details class="w307-group" data-cat="ACTIVE_CRM"><summary><span class="w307-cat-icon">💼</span> <span class="w307-cat-label">💼 CRM</span> <span class="w307-cat-count">4</span></summary><div class="w307-grid"><a href="/ethica-hcp-manager.html" class="w307-nav-item" data-thumb="/thumbs/ethica-hcp-manager.jpg" title="ethica-hcp-manager.html · 10 KB · 2026-04-21"><span class="w307-dot" style="background:#f39c12"></span>ethica hcp manager<span class="w307-meta">10k</span></a><a href="/crm-audit.html" class="w307-nav-item" data-thumb="/thumbs/crm-audit.jpg" title="crm-audit.html · 7 KB · 2026-04-21"><span class="w307-dot" style="background:#f39c12"></span>crm audit<span class="w307-meta">7k</span></a><a href="/crm-pharma-marketing-pharmaceutique.html" class="w307-nav-item" data-thumb="/thumbs/crm-pharma-marketing-pharmaceutique.jpg" title="crm-pharma-marketing-pharmaceutique.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#f39c12"></span>crm pharma marketing pharmaceutique<span class="w307-meta">9k</span></a><a href="/crm-pipeline-live.html" class="w307-nav-item" data-thumb="/thumbs/crm-pipeline-live.jpg" title="crm-pipeline-live.html · 12 KB · 2026-04-21"><span class="w307-dot" style="background:#f39c12"></span>crm pipeline live<span class="w307-meta">12k</span></a></div></details><details class="w307-group" data-cat="ACTIVE_ADMIN"><summary><span class="w307-cat-icon">🛡</span> <span class="w307-cat-label">🛡 Admin & Auth</span> <span class="w307-cat-count">10</span></summary><div class="w307-grid"><a href="/admin.html" class="w307-nav-item" data-thumb="/thumbs/admin.jpg" title="admin.html · 56 KB · 2026-04-24"><span class="w307-dot" style="background:#2ecc71"></span>admin<span class="w307-meta">56k</span></a><a href="/admin-v2.html" class="w307-nav-item" data-thumb="/thumbs/admin-v2.jpg" title="admin-v2.html · 28 KB · 2026-04-24"><span class="w307-dot" style="background:#2ecc71"></span>admin v2<span class="w307-meta">28k</span></a><a href="/admin-saas.html" class="w307-nav-item" data-thumb="/thumbs/admin-saas.jpg" title="admin-saas.html · 30 KB · 2026-04-24"><span class="w307-dot" style="background:#2ecc71"></span>admin saas<span class="w307-meta">30k</span></a><a href="/wtp-login.html" class="w307-nav-item" data-thumb="/thumbs/wtp-login.jpg" title="wtp-login.html · 10 KB · 2026-04-21"><span class="w307-dot" style="background:#2ecc71"></span>wtp login<span class="w307-meta">10k</span></a><a href="/weval-login.html" class="w307-nav-item" data-thumb="/thumbs/weval-login.jpg" title="weval-login.html · 10 KB · 2026-04-21"><span class="w307-dot" style="background:#2ecc71"></span>weval login<span class="w307-meta">10k</span></a><a href="/office-login.html" class="w307-nav-item" data-thumb="/thumbs/office-login.jpg" title="office-login.html · 8 KB · 2026-04-21"><span class="w307-dot" style="background:#2ecc71"></span>office login<span class="w307-meta">8k</span></a><a href="/office-admins.html" class="w307-nav-item" data-thumb="/thumbs/office-admins.jpg" title="office-admins.html · 16 KB · 2026-04-21"><span class="w307-dot" style="background:#2ecc71"></span>office admins<span class="w307-meta">16k</span></a><a href="/ethica-login.html" class="w307-nav-item" data-thumb="/thumbs/ethica-login.jpg" title="ethica-login.html · 11 KB · 2026-04-21"><span class="w307-dot" style="background:#2ecc71"></span>ethica login<span class="w307-meta">11k</span></a><a href="/arsenal-login.html" class="w307-nav-item" data-thumb="/thumbs/arsenal-login.jpg" title="arsenal-login.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#2ecc71"></span>arsenal login<span class="w307-meta">9k</span></a><a href="/wevia-admin.html" class="w307-nav-item" data-thumb="/thumbs/wevia-admin.jpg" title="wevia-admin.html · 0 KB · 2026-04-21"><span class="w307-dot" style="background:#2ecc71"></span>wevia admin<span class="w307-meta">0k</span></a></div></details><details class="w307-group" data-cat="ACTIVE_PRODUCT"><summary><span class="w307-cat-icon">💰</span> <span class="w307-cat-label">💰 Product</span> <span class="w307-cat-count">1</span></summary><div class="w307-grid"><a href="/pricing.html" class="w307-nav-item" data-thumb="/thumbs/pricing.jpg" title="pricing.html · 17 KB · 2026-04-21"><span class="w307-dot" style="background:#f1c40f"></span>pricing<span class="w307-meta">17k</span></a></div></details><details class="w307-group" data-cat="ACTIVE_OTHER"><summary><span class="w307-cat-icon">📄</span> <span class="w307-cat-label">📄 Pages & Modules</span> <span class="w307-cat-count">168</span></summary><div class="w307-grid"><a href="/claw-chat.html" class="w307-nav-item" title="claw-chat.html · 21 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>claw chat<span class="w307-meta">21k</span></a><a href="/claude-monitor.html" class="w307-nav-item" title="claude-monitor.html · 21 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>claude monitor<span class="w307-meta">21k</span></a><a href="/cgu.html" class="w307-nav-item" title="cgu.html · 13 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>cgu<span class="w307-meta">13k</span></a><a href="/case-studies.html" class="w307-nav-item" title="case-studies.html · 18 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>case studies<span class="w307-meta">18k</span></a><a href="/candidates-pool.html" class="w307-nav-item" title="candidates-pool.html · 16 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>candidates pool<span class="w307-meta">16k</span></a><a href="/candidate-detail.html" class="w307-nav-item" title="candidate-detail.html · 20 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>candidate detail<span class="w307-meta">20k</span></a><a href="/bpmn-studio-live.html" class="w307-nav-item" title="bpmn-studio-live.html · 12 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>bpmn studio live<span class="w307-meta">12k</span></a><a href="/bpmn-studio-NEW.html" class="w307-nav-item" title="bpmn-studio-NEW.html · 11 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>bpmn studio NEW<span class="w307-meta">11k</span></a><a href="/bpm-automatisation-processus-métier.html" class="w307-nav-item" title="bpm-automatisation-processus-métier.html · 12 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>bpm automatisation processus métier<span class="w307-meta">12k</span></a><a href="/booking.html" class="w307-nav-item" title="booking.html · 14 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>booking<span class="w307-meta">14k</span></a><a href="/avatar-picker.html" class="w307-nav-item" title="avatar-picker.html · 200 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>avatar picker<span class="w307-meta">200k</span></a><a href="/arsenal-offline.html" class="w307-nav-item" title="arsenal-offline.html · 8 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>arsenal offline<span class="w307-meta">8k</span></a><a href="/apps.html" class="w307-nav-item" title="apps.html · 10 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>apps<span class="w307-meta">10k</span></a><a href="/achats-purchasing-sap-mm-procurement.html" class="w307-nav-item" title="achats-purchasing-sap-mm-procurement.html · 12 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>achats purchasing sap mm procurement<span class="w307-meta">12k</span></a><a href="/wevia-cortex.html" class="w307-nav-item" title="wevia-cortex.html · 34 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>wevia cortex<span class="w307-meta">34k</span></a><a href="/brain-council.html" class="w307-nav-item" title="brain-council.html · 21 KB · 2026-04-24"><span class="w307-dot" style="background:#95a5a6"></span>brain council<span class="w307-meta">21k</span></a><a href="/web-ia-status.html" class="w307-nav-item" title="web-ia-status.html · 18 KB · 2026-04-23"><span class="w307-dot" style="background:#95a5a6"></span>web ia status<span class="w307-meta">18k</span></a><a href="/vnc-picker.html" class="w307-nav-item" title="vnc-picker.html · 18 KB · 2026-04-23"><span class="w307-dot" style="background:#95a5a6"></span>vnc picker<span class="w307-meta">18k</span></a><a href="/faq-knowledge-base.html" class="w307-nav-item" title="faq-knowledge-base.html · 27 KB · 2026-04-23"><span class="w307-dot" style="background:#95a5a6"></span>faq knowledge base<span class="w307-meta">27k</span></a><a href="/wevia-erp-unified.html" class="w307-nav-item" title="wevia-erp-unified.html · 30 KB · 2026-04-23"><span class="w307-dot" style="background:#95a5a6"></span>wevia erp unified<span class="w307-meta">30k</span></a><a href="/wevia-erp-v2.html" class="w307-nav-item" title="wevia-erp-v2.html · 32 KB · 2026-04-23"><span class="w307-dot" style="background:#95a5a6"></span>wevia erp v2<span class="w307-meta">32k</span></a><a href="/pitch.html" class="w307-nav-item" title="pitch.html · 19 KB · 2026-04-23"><span class="w307-dot" style="background:#95a5a6"></span>pitch<span class="w307-meta">19k</span></a><a href="/wiki.html" class="w307-nav-item" title="wiki.html · 110 KB · 2026-04-23"><span class="w307-dot" style="background:#95a5a6"></span>wiki<span class="w307-meta">110k</span></a><a href="/youtube-factory.html" class="w307-nav-item" title="youtube-factory.html · 54 KB · 2026-04-23"><span class="w307-dot" style="background:#95a5a6"></span>youtube factory<span class="w307-meta">54k</span></a><a href="/growth-advisor-v3.html" class="w307-nav-item" title="growth-advisor-v3.html · 75 KB · 2026-04-23"><span class="w307-dot" style="background:#95a5a6"></span>growth advisor v3<span class="w307-meta">75k</span></a><a href="/wevia-training.html" class="w307-nav-item" title="wevia-training.html · 237 KB · 2026-04-23"><span class="w307-dot" style="background:#95a5a6"></span>wevia training<span class="w307-meta">237k</span></a><a href="/index.html" class="w307-nav-item" title="index.html · 21 KB · 2026-04-23"><span class="w307-dot" style="background:#95a5a6"></span>index<span class="w307-meta">21k</span></a><a href="/warmup-manager.html" class="w307-nav-item" title="warmup-manager.html · 0 KB · 2026-04-23"><span class="w307-dot" style="background:#95a5a6"></span>warmup manager<span class="w307-meta">0k</span></a><a href="/wevia-chat-v2.html" class="w307-nav-item" title="wevia-chat-v2.html · 24 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>wevia chat v2<span class="w307-meta">24k</span></a><a href="/wevia.html" class="w307-nav-item" title="wevia.html · 239 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>wevia<span class="w307-meta">239k</span></a><a href="/proof-wave268.html" class="w307-nav-item" title="proof-wave268.html · 5 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>proof wave268<span class="w307-meta">5k</span></a><a href="/register.html" class="w307-nav-item" title="register.html · 19 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>register<span class="w307-meta">19k</span></a><a href="/wevia-widget.html" class="w307-nav-item" title="wevia-widget.html · 23 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>wevia widget<span class="w307-meta">23k</span></a><a href="/paperclip.html" class="w307-nav-item" title="paperclip.html · 12 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>paperclip<span class="w307-meta">12k</span></a><a href="/claw-code.html" class="w307-nav-item" title="claw-code.html · 11 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>claw code<span class="w307-meta">11k</span></a><a href="/director-chat.html" class="w307-nav-item" title="director-chat.html · 35 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>director chat<span class="w307-meta">35k</span></a><a href="/ethica-chatbot.html" class="w307-nav-item" title="ethica-chatbot.html · 18 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>ethica chatbot<span class="w307-meta">18k</span></a><a href="/l99-brain.html" class="w307-nav-item" title="l99-brain.html · 29 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>l99 brain<span class="w307-meta">29k</span></a><a href="/openclaw.html" class="w307-nav-item" title="openclaw.html · 27 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>openclaw<span class="w307-meta">27k</span></a><a href="/sovereign-claude.html" class="w307-nav-item" title="sovereign-claude.html · 27 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>sovereign claude<span class="w307-meta">27k</span></a><a href="/sovereign-monitor.html" class="w307-nav-item" title="sovereign-monitor.html · 30 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>sovereign monitor<span class="w307-meta">30k</span></a><a href="/weval-arena-v2.html" class="w307-nav-item" title="weval-arena-v2.html · 33 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>weval arena v2<span class="w307-meta">33k</span></a><a href="/wevia-chat.html" class="w307-nav-item" title="wevia-chat.html · 33 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>wevia chat<span class="w307-meta">33k</span></a><a href="/wevia-console.html" class="w307-nav-item" title="wevia-console.html · 23 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>wevia console<span class="w307-meta">23k</span></a><a href="/oss-catalog.html" class="w307-nav-item" title="oss-catalog.html · 9 KB · 2026-04-22"><span class="w307-dot" style="background:#95a5a6"></span>oss catalog<span class="w307-meta">9k</span></a><a href="/sessions-monitor.html" class="w307-nav-item" title="sessions-monitor.html · 17 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>sessions monitor<span class="w307-meta">17k</span></a><a href="/wevia-claude-pattern.html" class="w307-nav-item" title="wevia-claude-pattern.html · 19 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia claude pattern<span class="w307-meta">19k</span></a><a href="/ecosysteme-ia-maroc.html" class="w307-nav-item" title="ecosysteme-ia-maroc.html · 13 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>ecosysteme ia maroc<span class="w307-meta">13k</span></a><a href="/oss-discovery.html" class="w307-nav-item" title="oss-discovery.html · 31 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>oss discovery<span class="w307-meta">31k</span></a><a href="/wevia-v4.html" class="w307-nav-item" title="wevia-v4.html · 15 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia v4<span class="w307-meta">15k</span></a><a href="/wevia-vs-opus.html" class="w307-nav-item" title="wevia-vs-opus.html · 22 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia vs opus<span class="w307-meta">22k</span></a><a href="/world-map-live.html" class="w307-nav-item" title="world-map-live.html · 13 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>world map live<span class="w307-meta">13k</span></a><a href="/wtp-drilldown-charts.html" class="w307-nav-item" title="wtp-drilldown-charts.html · 20 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wtp drilldown charts<span class="w307-meta">20k</span></a><a href="/wtp-udock-coverage.html" class="w307-nav-item" title="wtp-udock-coverage.html · 13 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wtp udock coverage<span class="w307-meta">13k</span></a><a href="/wtp.html" class="w307-nav-item" title="wtp.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wtp<span class="w307-meta">9k</span></a><a href="/wevia-apple-v3.html" class="w307-nav-item" title="wevia-apple-v3.html · 34 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia apple v3<span class="w307-meta">34k</span></a><a href="/wevia-backoffice.html" class="w307-nav-item" title="wevia-backoffice.html · 4 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia backoffice<span class="w307-meta">4k</span></a><a href="/wevia-business-visual-studio.html" class="w307-nav-item" title="wevia-business-visual-studio.html · 21 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia business visual studio<span class="w307-meta">21k</span></a><a href="/wevia-cyber-monitor.html" class="w307-nav-item" title="wevia-cyber-monitor.html · 4 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia cyber monitor<span class="w307-meta">4k</span></a><a href="/wevia-cyber-scan.html" class="w307-nav-item" title="wevia-cyber-scan.html · 4 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia cyber scan<span class="w307-meta">4k</span></a><a href="/wevia-cyber-sentinel.html" class="w307-nav-item" title="wevia-cyber-sentinel.html · 4 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia cyber sentinel<span class="w307-meta">4k</span></a><a href="/wevia-demo-autonomous.html" class="w307-nav-item" title="wevia-demo-autonomous.html · 8 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia demo autonomous<span class="w307-meta">8k</span></a><a href="/wevia-em-big4-v2.html" class="w307-nav-item" title="wevia-em-big4-v2.html · 24 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia em big4 v2<span class="w307-meta">24k</span></a><a href="/wevia-em-linkedin-carousel-v3.html" class="w307-nav-item" title="wevia-em-linkedin-carousel-v3.html · 24 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia em linkedin carousel v3<span class="w307-meta">24k</span></a><a href="/wevia-em-linkedin-carousel.html" class="w307-nav-item" title="wevia-em-linkedin-carousel.html · 19 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia em linkedin carousel<span class="w307-meta">19k</span></a><a href="/wevia-evolution.html" class="w307-nav-item" title="wevia-evolution.html · 10 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia evolution<span class="w307-meta">10k</span></a><a href="/wevia-go-live.html" class="w307-nav-item" title="wevia-go-live.html · 20 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia go live<span class="w307-meta">20k</span></a><a href="/wevia-meetings.html" class="w307-nav-item" title="wevia-meetings.html · 23 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia meetings<span class="w307-meta">23k</span></a><a href="/use-cases.html" class="w307-nav-item" title="use-cases.html · 57 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>use cases<span class="w307-meta">57k</span></a><a href="/value-chain.html" class="w307-nav-item" title="value-chain.html · 10 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>value chain<span class="w307-meta">10k</span></a><a href="/value-stream-mapping.html" class="w307-nav-item" title="value-stream-mapping.html · 29 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>value stream mapping<span class="w307-meta">29k</span></a><a href="/value-stream.html" class="w307-nav-item" title="value-stream.html · 11 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>value stream<span class="w307-meta">11k</span></a><a href="/visual-management.html" class="w307-nav-item" title="visual-management.html · 21 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>visual management<span class="w307-meta">21k</span></a><a href="/vsm-15depts-NEW.html" class="w307-nav-item" title="vsm-15depts-NEW.html · 13 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>vsm 15depts NEW<span class="w307-meta">13k</span></a><a href="/wepredict.html" class="w307-nav-item" title="wepredict.html · 73 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wepredict<span class="w307-meta">73k</span></a><a href="/wevads-performance.html" class="w307-nav-item" title="wevads-performance.html · 15 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevads performance<span class="w307-meta">15k</span></a><a href="/weval-enterprise-management.html" class="w307-nav-item" title="weval-enterprise-management.html · 37 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>weval enterprise management<span class="w307-meta">37k</span></a><a href="/weval-master-inventory.html" class="w307-nav-item" title="weval-master-inventory.html · 40 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>weval master inventory<span class="w307-meta">40k</span></a><a href="/weval-ops-screens.html" class="w307-nav-item" title="weval-ops-screens.html · 661 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>weval ops screens<span class="w307-meta">661k</span></a><a href="/weval-wiring.html" class="w307-nav-item" title="weval-wiring.html · 24 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>weval wiring<span class="w307-meta">24k</span></a><a href="/tasks-live.html" class="w307-nav-item" title="tasks-live.html · 14 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>tasks live<span class="w307-meta">14k</span></a><a href="/technology-radar.html" class="w307-nav-item" title="technology-radar.html · 67 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>technology radar<span class="w307-meta">67k</span></a><a href="/terms-of-service.html" class="w307-nav-item" title="terms-of-service.html · 5 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>terms of service<span class="w307-meta">5k</span></a><a href="/toolhub.html" class="w307-nav-item" title="toolhub.html · 23 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>toolhub<span class="w307-meta">23k</span></a><a href="/transformation-digitale-consulting-france-international.html" class="w307-nav-item" title="transformation-digitale-consulting-france-international.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>transformation digitale consulting france international<span class="w307-meta">9k</span></a><a href="/ultimate-quality.html" class="w307-nav-item" title="ultimate-quality.html · 8 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>ultimate quality<span class="w307-meta">8k</span></a><a href="/routines-catalog.html" class="w307-nav-item" title="routines-catalog.html · 28 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>routines catalog<span class="w307-meta">28k</span></a><a href="/solution-finder.html" class="w307-nav-item" title="solution-finder.html · 12 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>solution finder<span class="w307-meta">12k</span></a><a href="/sso-monitor.html" class="w307-nav-item" title="sso-monitor.html · 12 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>sso monitor<span class="w307-meta">12k</span></a><a href="/playbook-3-phases.html" class="w307-nav-item" title="playbook-3-phases.html · 14 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>playbook 3 phases<span class="w307-meta">14k</span></a><a href="/privacy-policy.html" class="w307-nav-item" title="privacy-policy.html · 5 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>privacy policy<span class="w307-meta">5k</span></a><a href="/realtime-monitor-v3.html" class="w307-nav-item" title="realtime-monitor-v3.html · 27 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>realtime monitor v3<span class="w307-meta">27k</span></a><a href="/realtime-monitor.html" class="w307-nav-item" title="realtime-monitor.html · 25 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>realtime monitor<span class="w307-meta">25k</span></a><a href="/recrutement-talent-it-maroc.html" class="w307-nav-item" title="recrutement-talent-it-maroc.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>recrutement talent it maroc<span class="w307-meta">9k</span></a><a href="/owner-actions-tracker.html" class="w307-nav-item" title="owner-actions-tracker.html · 10 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>owner actions tracker<span class="w307-meta">10k</span></a><a href="/partners-emails.html" class="w307-nav-item" title="partners-emails.html · 7 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>partners emails<span class="w307-meta">7k</span></a><a href="/plan-du-site.html" class="w307-nav-item" title="plan-du-site.html · 10 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>plan du site<span class="w307-meta">10k</span></a><a href="/ops-screens-live.html" class="w307-nav-item" title="ops-screens-live.html · 10 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>ops screens live<span class="w307-meta">10k</span></a><a href="/office-app.html" class="w307-nav-item" title="office-app.html · 35 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>office app<span class="w307-meta">35k</span></a><a href="/office-senders-diag.html" class="w307-nav-item" title="office-senders-diag.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>office senders diag<span class="w307-meta">9k</span></a><a href="/offshore-nearshore-maroc-france-canada.html" class="w307-nav-item" title="offshore-nearshore-maroc-france-canada.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>offshore nearshore maroc france canada<span class="w307-meta">9k</span></a><a href="/onboarding-em.html" class="w307-nav-item" title="onboarding-em.html · 7 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>onboarding em<span class="w307-meta">7k</span></a><a href="/nl-autowire-status.html" class="w307-nav-item" title="nl-autowire-status.html · 13 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>nl autowire status<span class="w307-meta">13k</span></a><a href="/nonreg.html" class="w307-nav-item" title="nonreg.html · 14 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>nonreg<span class="w307-meta">14k</span></a><a href="/marketing-digital-maroc.html" class="w307-nav-item" title="marketing-digital-maroc.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>marketing digital maroc<span class="w307-meta">9k</span></a><a href="/marketplace.html" class="w307-nav-item" title="marketplace.html · 1 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>marketplace<span class="w307-meta">1k</span></a><a href="/medreach-campaign.html" class="w307-nav-item" title="medreach-campaign.html · 18 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>medreach campaign<span class="w307-meta">18k</span></a><a href="/methodologie.html" class="w307-nav-item" title="methodologie.html · 14 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>methodologie<span class="w307-meta">14k</span></a><a href="/mission-billing.html" class="w307-nav-item" title="mission-billing.html · 12 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>mission billing<span class="w307-meta">12k</span></a><a href="/monitoring.html" class="w307-nav-item" title="monitoring.html · 14 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>monitoring<span class="w307-meta">14k</span></a><a href="/méthodologie.html" class="w307-nav-item" title="méthodologie.html · 4 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>méthodologie<span class="w307-meta">4k</span></a><a href="/lean-6sigma.html" class="w307-nav-item" title="lean-6sigma.html · 16 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>lean 6sigma<span class="w307-meta">16k</span></a><a href="/linkedin-automation-v96.html" class="w307-nav-item" title="linkedin-automation-v96.html · 8 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>linkedin automation v96<span class="w307-meta">8k</span></a><a href="/linkedin-control-v97.html" class="w307-nav-item" title="linkedin-control-v97.html · 12 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>linkedin control v97<span class="w307-meta">12k</span></a><a href="/linkedin-control-v98.html" class="w307-nav-item" title="linkedin-control-v98.html · 13 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>linkedin control v98<span class="w307-meta">13k</span></a><a href="/living-proof.html" class="w307-nav-item" title="living-proof.html · 21 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>living proof<span class="w307-meta">21k</span></a><a href="/maintenance.html" class="w307-nav-item" title="maintenance.html · 4 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>maintenance<span class="w307-meta">4k</span></a><a href="/l99-fullscreen.html" class="w307-nav-item" title="l99-fullscreen.html · 6 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>l99 fullscreen<span class="w307-meta">6k</span></a><a href="/l99-v2.html" class="w307-nav-item" title="l99-v2.html · 20 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>l99 v2<span class="w307-meta">20k</span></a><a href="/l99.html" class="w307-nav-item" title="l99.html · 21 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>l99<span class="w307-meta">21k</span></a><a href="/infra-command.html" class="w307-nav-item" title="infra-command.html · 19 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>infra command<span class="w307-meta">19k</span></a><a href="/infra-monitor.html" class="w307-nav-item" title="infra-monitor.html · 6 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>infra monitor<span class="w307-meta">6k</span></a><a href="/infra-tour.html" class="w307-nav-item" title="infra-tour.html · 7 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>infra tour<span class="w307-meta">7k</span></a><a href="/integrations-marketplace.html" class="w307-nav-item" title="integrations-marketplace.html · 14 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>integrations marketplace<span class="w307-meta">14k</span></a><a href="/intelligence-artificielle-france-consulting.html" class="w307-nav-item" title="intelligence-artificielle-france-consulting.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>intelligence artificielle france consulting<span class="w307-meta">9k</span></a><a href="/growth-engine.html" class="w307-nav-item" title="growth-engine.html · 38 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>growth engine<span class="w307-meta">38k</span></a><a href="/gws-setup.html" class="w307-nav-item" title="gws-setup.html · 5 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>gws setup<span class="w307-meta">5k</span></a><a href="/huawei-cloud.html" class="w307-nav-item" title="huawei-cloud.html · 32 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>huawei cloud<span class="w307-meta">32k</span></a><a href="/ethica-monitor.html" class="w307-nav-item" title="ethica-monitor.html · 19 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>ethica monitor<span class="w307-meta">19k</span></a><a href="/ethica-pipeline.html" class="w307-nav-item" title="ethica-pipeline.html · 29 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>ethica pipeline<span class="w307-meta">29k</span></a><a href="/ethica-sms.html" class="w307-nav-item" title="ethica-sms.html · 1 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>ethica sms<span class="w307-meta">1k</span></a><a href="/faq-anti-regression.html" class="w307-nav-item" title="faq-anti-regression.html · 8 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>faq anti regression<span class="w307-meta">8k</span></a><a href="/faq-techniques.html" class="w307-nav-item" title="faq-techniques.html · 44 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>faq techniques<span class="w307-meta">44k</span></a><a href="/finance-controlling-sap-fico.html" class="w307-nav-item" title="finance-controlling-sap-fico.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>finance controlling sap fico<span class="w307-meta">9k</span></a><a href="/formation-ia-sap-cloud-maroc.html" class="w307-nav-item" title="formation-ia-sap-cloud-maroc.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>formation ia sap cloud maroc<span class="w307-meta">9k</span></a><a href="/go-100pct.html" class="w307-nav-item" title="go-100pct.html · 13 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>go 100pct<span class="w307-meta">13k</span></a><a href="/golive.html" class="w307-nav-item" title="golive.html · 16 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>golive<span class="w307-meta">16k</span></a><a href="/enterprise-complete-v73.html" class="w307-nav-item" title="enterprise-complete-v73.html · 28 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>enterprise complete v73<span class="w307-meta">28k</span></a><a href="/enterprise-management.html" class="w307-nav-item" title="enterprise-management.html · 33 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>enterprise management<span class="w307-meta">33k</span></a><a href="/erp-gap-fill.html" class="w307-nav-item" title="erp-gap-fill.html · 35 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>erp gap fill<span class="w307-meta">35k</span></a><a href="/erp-pme-eti-sap-odoo-sage.html" class="w307-nav-item" title="erp-pme-eti-sap-odoo-sage.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>erp pme eti sap odoo sage<span class="w307-meta">9k</span></a><a href="/ethica-country.html" class="w307-nav-item" title="ethica-country.html · 6 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>ethica country<span class="w307-meta">6k</span></a><a href="/ethica-drill.html" class="w307-nav-item" title="ethica-drill.html · 1 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>ethica drill<span class="w307-meta">1k</span></a><a href="/decision-gmail-o365.html" class="w307-nav-item" title="decision-gmail-o365.html · 10 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>decision gmail o365<span class="w307-meta">10k</span></a><a href="/deepseek.html" class="w307-nav-item" title="deepseek.html · 67 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>deepseek<span class="w307-meta">67k</span></a><a href="/digitalisation-processus-gouvernance-it.html" class="w307-nav-item" title="digitalisation-processus-gouvernance-it.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>digitalisation processus gouvernance it<span class="w307-meta">9k</span></a><a href="/director.html" class="w307-nav-item" title="director.html · 23 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>director<span class="w307-meta">23k</span></a><a href="/dmaic-tracker-NEW.html" class="w307-nav-item" title="dmaic-tracker-NEW.html · 10 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>dmaic tracker NEW<span class="w307-meta">10k</span></a><a href="/dmaic-workbench.html" class="w307-nav-item" title="dmaic-workbench.html · 10 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>dmaic workbench<span class="w307-meta">10k</span></a><a href="/doctrine-53.html" class="w307-nav-item" title="doctrine-53.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>doctrine 53<span class="w307-meta">9k</span></a><a href="/droid-terminal-hidden.html" class="w307-nav-item" title="droid-terminal-hidden.html · 30 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>droid terminal hidden<span class="w307-meta">30k</span></a><a href="/consulting-sap-erp-vistex-maroc.html" class="w307-nav-item" title="consulting-sap-erp-vistex-maroc.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>consulting sap erp vistex maroc<span class="w307-meta">9k</span></a><a href="/cron-control.html" class="w307-nav-item" title="cron-control.html · 86 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>cron control<span class="w307-meta">86k</span></a><a href="/crons-monitor.html" class="w307-nav-item" title="crons-monitor.html · 23 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>crons monitor<span class="w307-meta">23k</span></a><a href="/cyber-monitor.html" class="w307-nav-item" title="cyber-monitor.html · 8 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>cyber monitor<span class="w307-meta">8k</span></a><a href="/cybersécurité-maroc-audit-conseil.html" class="w307-nav-item" title="cybersécurité-maroc-audit-conseil.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>cybersécurité maroc audit conseil<span class="w307-meta">9k</span></a><a href="/data-deletion.html" class="w307-nav-item" title="data-deletion.html · 4 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>data deletion<span class="w307-meta">4k</span></a><a href="/cloud-infrastructure-système-information.html" class="w307-nav-item" title="cloud-infrastructure-système-information.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>cloud infrastructure système information<span class="w307-meta">9k</span></a><a href="/consultants-list.html" class="w307-nav-item" title="consultants-list.html · 11 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>consultants list<span class="w307-meta">11k</span></a><a href="/consulting-intelligence-artificielle-maroc.html" class="w307-nav-item" title="consulting-intelligence-artificielle-maroc.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>consulting intelligence artificielle maroc<span class="w307-meta">9k</span></a><a href="/consulting-pharma-supply-chain.html" class="w307-nav-item" title="consulting-pharma-supply-chain.html · 9 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>consulting pharma supply chain<span class="w307-meta">9k</span></a><a href="/azure-reregister.html" class="w307-nav-item" title="azure-reregister.html · 11 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>azure reregister<span class="w307-meta">11k</span></a><a href="/googlecba1a80ba979325c.html" class="w307-nav-item" title="googlecba1a80ba979325c.html · 0 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>googlecba1a80ba979325c<span class="w307-meta">0k</span></a><a href="/wevia-monitor.html" class="w307-nav-item" title="wevia-monitor.html · 0 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>wevia monitor<span class="w307-meta">0k</span></a><a href="/all-screens-live.html" class="w307-nav-item" title="all-screens-live.html · 4 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>all screens live<span class="w307-meta">4k</span></a><a href="/droid-terminal.html" class="w307-nav-item" title="droid-terminal.html · 4 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>droid terminal<span class="w307-meta">4k</span></a><a href="/office-workflow.html" class="w307-nav-item" title="office-workflow.html · 4 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>office workflow<span class="w307-meta">4k</span></a><a href="/vsm-pipelines.html" class="w307-nav-item" title="vsm-pipelines.html · 14 KB · 2026-04-21"><span class="w307-dot" style="background:#95a5a6"></span>vsm pipelines<span class="w307-meta">14k</span></a></div></details>
</div>
<details class="w307-group" data-cat="FIX_100PCT" open style="border-color:rgba(34,211,238,.4);background:rgba(34,211,238,.04)"><summary><span class="w307-cat-icon">🎯</span> <span class="w307-cat-label">Rattachement 100% (UTF-8 + Système)</span> <span class="w307-cat-count">5</span></summary><div class="w307-grid"><a href="/bpm-automatisation-processus-m%C3%A9tier.html" class="w307-nav-item w307-fix100" title="bpm-automatisation-processus-métier.html - 12KB"><span class="w307-dot" style="background:#22d3ee"></span>BPM Automatisation Processus Métier<span class="w307-meta">12k</span></a><a href="/m%C3%A9thodologie.html" class="w307-nav-item w307-fix100" title="méthodologie.html - 4KB"><span class="w307-dot" style="background:#22d3ee"></span>Méthodologie<span class="w307-meta">4k</span></a><a href="/cybers%C3%A9curit%C3%A9-maroc-audit-conseil.html" class="w307-nav-item w307-fix100" title="cybersécurité-maroc-audit-conseil.html - 9KB"><span class="w307-dot" style="background:#22d3ee"></span>Cybersécurité Maroc Audit Conseil<span class="w307-meta">9k</span></a><a href="/cloud-infrastructure-syst%C3%A8me-information.html" class="w307-nav-item w307-fix100" title="cloud-infrastructure-système-information.html - 9KB"><span class="w307-dot" style="background:#22d3ee"></span>Cloud Infrastructure Système Information<span class="w307-meta">9k</span></a><a href="/404.html" class="w307-nav-item w307-fix100" title="404.html - 7KB"><span class="w307-dot" style="background:#22d3ee"></span>404 Error Page<span class="w307-meta">7k</span></a></div></details>
<!-- W307-ORPHANS-MOUNT-END -->
<!-- DOCTRINE-60-UX-JS --><script id="doctrine60-ux-js-weval-technology-platform">
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry, index) => {
if (entry.isIntersecting) {
setTimeout(() => {
entry.target.classList.add('enter-stagger');
}, index * 80);
}
});
}, { threshold: 0.1 });
document.querySelectorAll('.card, .btn, .kpi, .panel').forEach(el => {
observer.observe(el);
});
</script>
</body>
<!-- WEVIA-ROLLBACK-LINK-P1-v1 -->
<!-- WEVIA rollback link floater -->
<!-- /WEVIA-ROLLBACK-LINK-P1-v1 -->
</html>