/** * WEVIA Enhancement v2 — Radical Fix * 1. Force emojis on ALL bot responses (client-side) * 2. Kill horizontal split (CSS override) * 3. Arabic voice TTS */ (function(){ 'use strict'; // ═══════════════════════════════════════════════ // 1. KILL SPLIT — Force single-column layout // ═══════════════════════════════════════════════ var killSplitCSS = document.createElement('style'); killSplitCSS.textContent = [ // Ensure only active panel shows, full width '.panel{display:none!important;width:100%!important;max-width:100%!important;flex:1!important}', '.panel.a{display:flex!important;flex-direction:column!important;width:100%!important}', // Main area: single column, no side-by-side '.mn{display:flex!important;flex-direction:column!important;width:100%!important;max-width:100%!important}', // Chat takes full width '.chat{width:100%!important;max-width:100%!important}', '.msg{max-width:90%!important}', // Artifacts grid full width when shown '#artGrid{width:100%!important}', // Input area full width '.inp-area{width:100%!important}', '.inp-wrap{max-width:100%!important}', // No unexpected horizontal scrolling 'body,html,.app,.mn{overflow-x:hidden!important}', // Hide horizontal rules in chat '.chat hr,.bub hr{display:none!important}' ].join('\n'); document.head.appendChild(killSplitCSS); // ═══════════════════════════════════════════════ // 2. EMOJI INJECTION — Client-side post-processing // ═══════════════════════════════════════════════ var emojiMap = { greet: ['👋','🤗','😊','🙌'], explain: ['💡','🔍','📝','🎯'], success: ['✅','🎉','🚀','💪'], warn: ['⚠️','🔔','❗','👀'], error: ['❌','🚫','💥','😬'], code: ['💻','🔧','⚙️','🛠️'], list: ['🔹','📌','▶️','💎'], data: ['📊','📈','📉','🗂️'], idea: ['💡','✨','🌟','💎'], doc: ['📄','📋','📝','📑'] }; function pickEmoji(category) { var arr = emojiMap[category] || emojiMap.explain; return arr[Math.floor(Math.random() * arr.length)]; } function detectCategory(text) { var t = text.toLowerCase(); if (/^(bonjour|salut|hello|hi|مرحب|اهلا)/.test(t)) return 'greet'; if (/erreur|error|échoué|fail|bug/.test(t)) return 'error'; if (/attention|warning|⚠|prudence/.test(t)) return 'warn'; if (/terminé|succès|fait|success|réussi|done|✓/.test(t)) return 'success'; if (/code|script|function|var |const |let |def |class /.test(t)) return 'code'; if (/document|pdf|rapport|fichier/.test(t)) return 'doc'; if (/données|data|stat|chiffr|nombre/.test(t)) return 'data'; return 'explain'; } function hasEmoji(text) { return /[\u{1F300}-\u{1FAFF}\u{2600}-\u{27BF}\u{2700}-\u{27BF}]/u.test(text.substring(0, 20)); } function injectEmojis(text) { if (!text || text.length < 3) return text; // Don't double-inject if already has emoji at start if (hasEmoji(text)) return text; var cat = detectCategory(text); var startEmoji = pickEmoji(cat); // Add emoji at start text = startEmoji + ' ' + text; // Replace bullet points with emoji bullets text = text.replace(/^[\s]*[-•]\s/gm, '🔹 '); text = text.replace(/^[\s]*(\d+)\.\s/gm, function(m, n) { var nums = ['0️⃣','1️⃣','2️⃣','3️⃣','4️⃣','5️⃣','6️⃣','7️⃣','8️⃣','9️⃣']; return (nums[parseInt(n)] || n + '.') + ' '; }); // Add closing emoji if none var trimmed = text.trim(); if (!hasEmoji(trimmed.substring(trimmed.length - 5))) { var closers = ['✨','🚀','💡','👍','😊']; text = text.trimEnd() + ' ' + closers[Math.floor(Math.random() * closers.length)]; } return text; } // ═══════════════════════════════════════════════ // 3. ARABIC VOICE TTS // ═══════════════════════════════════════════════ var voiceEnabled = false; var arabicVoice = null; function initVoice() { if (!('speechSynthesis' in window)) return; function loadV() { var voices = speechSynthesis.getVoices(); arabicVoice = voices.find(function(v){return v.lang.startsWith('ar')}) || voices.find(function(v){return v.lang.indexOf('ar') >= 0}) || (voices.length > 0 ? voices[0] : null); } loadV(); speechSynthesis.onvoiceschanged = loadV; } initVoice(); window.toggleWeviaVoice = function() { voiceEnabled = !voiceEnabled; var btns = document.querySelectorAll('.wevia-voice-btn,[id="ttsBtn"],[id="voiceBtn2"]'); btns.forEach(function(b) { b.textContent = voiceEnabled ? '\u{1F50A}' : '\u{1F507}'; b.style.color = voiceEnabled ? '#22d3ee' : ''; b.title = voiceEnabled ? 'Voix Arabe ON' : 'Voix OFF'; }); if (!voiceEnabled) speechSynthesis.cancel(); }; function speakArabic(text) { if (!voiceEnabled || !('speechSynthesis' in window)) return; speechSynthesis.cancel(); // Clean text for speech var clean = text .replace(/[\u{1F300}-\u{1FAFF}\u{2600}-\u{27BF}]/gu, '') .replace(/<[^>]*>/g, '') .replace(/```[\s\S]*?```/g, '') .replace(/\*\*/g, '').replace(/\*/g, '') .replace(/#{1,6}\s/g, '') .replace(/\n+/g, '. ') .replace(/\s+/g, ' ').trim(); if (!clean || clean.length < 2) return; var chunks = clean.match(/.{1,200}[.!?\s]|.{1,200}$/g) || [clean]; var i = 0; (function next() { if (i >= chunks.length || !voiceEnabled) return; var utt = new SpeechSynthesisUtterance(chunks[i]); if (arabicVoice) utt.voice = arabicVoice; utt.lang = 'ar-SA'; utt.rate = 0.95; utt.onend = function(){ i++; next(); }; utt.onerror = function(){ i++; next(); }; speechSynthesis.speak(utt); })(); } // ═══════════════════════════════════════════════ // 4. MONKEY-PATCH message rendering functions // ═══════════════════════════════════════════════ // For FULLSCREEN (addMsg) if (typeof window.addMsg === 'function') { var origAddMsg = window.addMsg; window.addMsg = function(role, content, thinking) { if (role !== 'user' && content) { content = injectEmojis(content); } origAddMsg(role, content, thinking); if (role !== 'user' && voiceEnabled && content) speakArabic(content); }; } // For WIDGET (addMessage) if (typeof window.addMessage === 'function') { var origAddMessage = window.addMessage; window.addMessage = function(content, isUser) { if (!isUser && content) { content = injectEmojis(content); } origAddMessage(content, isUser); if (!isUser && voiceEnabled && content) speakArabic(content); }; } // Retry patching after DOM load (functions may be defined later) function retryPatch() { if (typeof window.addMsg === 'function' && !window._addMsgPatched) { var orig = window.addMsg; window.addMsg = function(role, content, thinking) { if (role !== 'user' && content) content = injectEmojis(content); orig(role, content, thinking); if (role !== 'user' && voiceEnabled && content) speakArabic(content); }; window._addMsgPatched = true; } if (typeof window.addMessage === 'function' && !window._addMessagePatched) { var orig2 = window.addMessage; window.addMessage = function(content, isUser) { if (!isUser && content) content = injectEmojis(content); orig2(content, isUser); if (!isUser && voiceEnabled && content) speakArabic(content); }; window._addMessagePatched = true; } } setTimeout(retryPatch, 500); setTimeout(retryPatch, 1500); setTimeout(retryPatch, 3000); // ═══════════════════════════════════════════════ // 5. FORCE ARTIFACTS TO OPEN IN NEW TAB // ═══════════════════════════════════════════════ if (typeof window.addArtifact === 'function') { window.addArtifact = function(art) { if (!art) return; // Open directly in new window if (art.url) { window.open(art.url, '_blank'); return; } if (!art.content) return; var w = window.open('', '_blank', 'width=900,height=700'); if (!w) { alert('Autorisez les popups pour voir le document'); return; } var css = 'body{font-family:system-ui,sans-serif;padding:24px;margin:0;background:#0a0f1a;color:#e2e8f0;line-height:1.6}pre{background:#111827;padding:16px;border-radius:8px;overflow-x:auto;font-size:13px;white-space:pre-wrap}h1,h2,h3{color:#22d3ee}'; if (art.type === 'html') { w.document.write(art.content); } else if (art.type === 'mermaid') { w.document.write('