Broke AI Enhanced
Powered by Vorlentis Tech • Groq API
🎤 Voice Chat
Click to start talking...
let systemInfoService; try { systemInfoService = new SystemInfoService(); console.log('✅ System Info Service initialized successfully'); } catch (error) { console.warn('⚠️ System Info Service failed to initialize:', error); systemInfoService = { generateSystemPrompt: () => `[Current Time: ${new Date().toLocaleString()}]\n\n`, getBriefContext: () => `[Time: ${new Date().toLocaleString()}]`, getSystemInfo: () => ({ formattedDateTime: new Date().toLocaleString(), country: 'Unknown', timezone: { name: 'Unknown' }, timeOfDay: 'unknown' }) }; } // ----- Sessions: storage helpers ----- function saveSessions() { try { localStorage.setItem('brokeAI_sessions_enhanced_v1', JSON.stringify({ sessions: chatSessions, activeId: activeChatId })); } catch (_) {} } function loadSessions() { try { const raw = localStorage.getItem('brokeAI_sessions_enhanced_v1'); if (raw) { const data = JSON.parse(raw); chatSessions = Array.isArray(data.sessions) ? data.sessions : []; activeChatId = data.activeId || (chatSessions[0] ? chatSessions[0].id : null); } } catch (_) { chatSessions = []; activeChatId = null; } if (!chatSessions.length) { createNewSession(); } else { renderChatList(); renderChat(getActiveSession()); } } function createNewSession(initialTitle = 'New Chat') { const id = 'chat_' + Date.now(); const session = { id, title: initialTitle, messages: [], createdAt: Date.now(), updatedAt: Date.now() }; chatSessions.unshift(session); activeChatId = id; saveSessions(); renderChatList(); renderChat(session); } function getActiveSession() { return chatSessions.find(s => s.id === activeChatId) || null; } function deleteSession(id) { const idx = chatSessions.findIndex(s => s.id === id); if (idx > -1) { chatSessions.splice(idx, 1); if (activeChatId === id) { activeChatId = chatSessions[0] ? chatSessions[0].id : null; } saveSessions(); renderChatList(); renderChat(getActiveSession()); } } function escapeHtml(text) { return (text || '').replace(/[&<>"']/g, c => ({'&':'&','<':'<','>':'>','"':'"','\'':'''}[c])); } function renderChatList() { chatHistory.innerHTML = ''; chatSessions.forEach(session => { const item = document.createElement('div'); item.className = 'chat-item' + (session.id === activeChatId ? ' active' : ''); item.innerHTML = `
${escapeHtml(session.title)} ${new Date(session.updatedAt).toLocaleString()}
`; item.addEventListener('click', (e) => { if (e.target.closest('.chat-delete')) return; activeChatId = session.id; saveSessions(); renderChatList(); renderChat(session); sidebar.classList.remove('open'); sidebarBackdrop.classList.remove('active'); }); item.querySelector('.chat-delete').addEventListener('click', (e) => { e.stopPropagation(); deleteSession(session.id); }); chatHistory.appendChild(item); }); } function renderChat(session) { chatContainer.innerHTML = ''; if (!session || !session.messages.length) { const aiIcon = 'Broke AI'; chatContainer.innerHTML = `
${aiIcon}
Broke AI Enhanced
${new Date().toLocaleTimeString()}

Welcome to Broke AI Enhanced!

I'm your advanced AI assistant with Groq API integration, developed by Vorlentis Tech. Enhanced features:

  • Ultra-fast responses with Groq's Qwen3-32B model
  • Real-time markdown rendering with syntax highlighting
  • Super-fast typing animation (1ms per character)
  • Advanced copy functions for code and content
  • Fully responsive design with touch support

Just type your question and experience the enhanced AI interaction!

`; return; } session.messages.forEach(m => { const msgDiv = addMessage(m.content, m.role === 'user'); if (m.role === 'assistant') { try { msgDiv.querySelector('.message-text').innerHTML = marked.parse(m.content); // Re-apply syntax highlighting msgDiv.querySelectorAll('pre code').forEach((block) => { Prism.highlightElement(block); }); // Re-apply math rendering if available if (typeof renderMathInElement !== 'undefined') { renderMathInElement(msgDiv.querySelector('.message-text')); } } catch (e) { msgDiv.querySelector('.message-text').textContent = m.content; } addActionButtons(msgDiv, msgDiv.querySelector('.message-text')); } }); chatContainer.scrollTop = chatContainer.scrollHeight; } // Ultra-fast typing animation with real-time markdown rendering - works in background tabs function typeWriterWithMarkdown(element, text, speed = 1) { return new Promise((resolve) => { element.innerHTML = ''; let i = 0; let currentText = ''; let isTyping = true; // Store the stop function globally so we can access it window.stopTyping = () => { isTyping = false; // Complete the text immediately try { element.innerHTML = marked.parse(text); // Apply code highlighting immediately when stopped element.querySelectorAll('pre code').forEach((block) => { Prism.highlightElement(block); }); // Apply math rendering if available if (typeof renderMathInElement !== 'undefined') { renderMathInElement(element); } } catch (e) { element.textContent = text; } resolve(); }; function typeChar() { if (i < text.length && isTyping) { currentText += text.charAt(i); // Render markdown in real-time try { let textToRender = currentText; // Handle incomplete code blocks during typing const codeBlockMatches = textToRender.match(/```/g); if (codeBlockMatches && codeBlockMatches.length % 2 === 1) { textToRender += '\n```'; } element.innerHTML = marked.parse(textToRender) + '|'; // Apply code highlighting in real-time for completed code blocks element.querySelectorAll('pre code').forEach((block) => { const parentPre = block.parentElement; if (parentPre && !parentPre.textContent.includes('|')) { // Enhanced language detection const className = block.className; let language = 'javascript'; // default const code = block.textContent; if (className.includes('language-')) { language = className.replace('language-', ''); } else { // Auto-detect language based on content patterns if (code.includes('async def') || code.includes('import ') || code.includes('print(') || code.includes('def ') || code.includes('elif ') || code.includes('__name__')) { language = 'python'; } else if (code.includes('function') || code.includes('const ') || code.includes('let ') || code.includes('=>') || code.includes('require(') || code.includes('console.log')) { language = 'javascript'; } else if (code.includes('#include') || code.includes('int main') || code.includes('printf') || code.includes('scanf')) { language = 'c'; } else if (code.includes('public class') || code.includes('System.out') || code.includes('public static') || code.includes('import java')) { language = 'java'; } else if (code.includes('SELECT') || code.includes('FROM') || code.includes('WHERE') || code.includes('INSERT INTO')) { language = 'sql'; } else if (code.includes('') || code.includes('
') || code.includes('')) { language = 'html'; } else if (code.includes('.class') || code.includes('color:') || code.includes('margin:') || code.includes('background:')) { language = 'css'; } else if (code.includes('#!/bin/bash') || code.includes('sudo ') || code.includes('chmod ') || code.includes('mkdir ') || code.includes('npm install')) { language = 'bash'; } else if (code.includes('{') && code.includes('}') && (code.includes('"') || code.includes("'"))) { language = 'json'; } } // Apply the detected language class block.className = `language-${language}`; // Highlight the code if (typeof Prism !== 'undefined' && Prism.languages[language]) { Prism.highlightElement(block); } } }); } catch (e) { element.textContent = currentText; } // Scroll to bottom during typing chatContainer.scrollTop = chatContainer.scrollHeight; i++; // Always use setTimeout to ensure it works in background tabs - super fast now setTimeout(typeChar, speed); } else if (isTyping) { // Remove cursor and finalize try { element.innerHTML = marked.parse(currentText); // Apply final code highlighting element.querySelectorAll('pre code').forEach((block) => { const className = block.className; let language = 'javascript'; const code = block.textContent; if (className.includes('language-')) { language = className.replace('language-', ''); } else { // Enhanced auto-detection if (code.includes('async def') || code.includes('import ') || code.includes('print(') || code.includes('def ')) { language = 'python'; } else if (code.includes('function') || code.includes('const ') || code.includes('let ') || code.includes('=>')) { language = 'javascript'; } else if (code.includes('#include') || code.includes('int main') || code.includes('printf')) { language = 'c'; } else if (code.includes('public class') || code.includes('System.out') || code.includes('public static')) { language = 'java'; } else if (code.includes('SELECT') || code.includes('FROM') || code.includes('WHERE')) { language = 'sql'; } else if (code.includes('') || code.includes('
') || code.includes(' loading.remove()); // Show stop button showStopButton(); // Start typing animation with real-time markdown await typeWriterWithMarkdown(messageTextDiv, aiText, speed); // Hide stop button and show send button hideStopButton(); // Add action buttons after typing is complete addActionButtons(aiDiv, messageTextDiv); // Final scroll to bottom chatContainer.scrollTop = chatContainer.scrollHeight; } function addMessage(text, fromUser = false) { const msgDiv = document.createElement("div"); msgDiv.className = `message ${fromUser ? "user" : "ai"} slide-up`; const time = new Date().toLocaleTimeString(); // Use different icons for user and AI const userIcon = '
U
'; const aiIcon = 'Broke AI'; msgDiv.innerHTML = `
${fromUser ? userIcon : aiIcon}
${fromUser ? 'You' : 'Broke AI Enhanced'}
${time}
${fromUser ? text : ''}
`; chatContainer.appendChild(msgDiv); chatContainer.scrollTop = chatContainer.scrollHeight; return msgDiv; } function addLoadingIndicator(parent) { const loadingDiv = document.createElement("div"); loadingDiv.className = "loading"; loadingDiv.innerHTML = ` Broke AI Enhanced is thinking...
`; parent.querySelector('.message-text').appendChild(loadingDiv); return loadingDiv; } // Groq API integration function async function getAIResponse(userText) { const headers = { "Authorization": `Bearer ${GROQ_API_KEY}`, "Content-Type": "application/json" }; const conversationContext = getContextFromActiveSession(); // Get system context with fallback let systemContext = ''; try { systemContext = systemInfoService.getBriefContext(); } catch (error) { console.warn('System context not available:', error); systemContext = `[Current Time: ${new Date().toLocaleString()}]`; } const finalPrompt = `${systemContext} You are Broke AI Enhanced, developed by Vorlentis Tech (vorlentis.xyz) and owned by Rifat Arefin Chowdhury, Rohan Mahmood & Mr. Sh4dow. You are powered by Groq's ultra-fast Qwen3-32B model. You are NOT a large language model trained by Google or OpenAI. You are Broke AI Enhanced, a conversational AI assistant with advanced capabilities. Always respond as Broke AI Enhanced, never mention being trained by other companies. Always structure your responses with clear sections, bullet points, numbered lists, and proper formatting for better readability and organization.\n\n${conversationContext}\n\nUser: ${userText}`; const body = JSON.stringify({ model: GROQ_MODEL, messages: [{ role: "user", content: finalPrompt }] }); try { const res = await fetch(GROQ_ENDPOINT, { method: "POST", headers, body, mode: 'cors' }); if (!res.ok) { const errorText = await res.text(); throw new Error(`Groq API error: ${res.status} ${res.statusText} - ${errorText}`); } const json = await res.json(); if (!json.choices || !json.choices[0] || !json.choices[0].message || !json.choices[0].message.content) { throw new Error("Invalid response format from Groq API"); } let aiText = json.choices[0].message.content.trim(); // Brand replacement aiText = aiText .replace(/\bqwen\b/gi, "Broke AI Enhanced") .replace(/\bgroq\b/gi, "Vorlentis Tech") .replace(/\bopenai\b/gi, "Vorlentis Tech") .replace(/\bgoogle\b/gi, "Vorlentis Tech") .replace(/\bfacebook\b/gi, "Vorlentis Tech") .replace(/\bmeta\b/gi, "Vorlentis Tech") .replace(/\banthropic\b/gi, "Vorlentis Tech"); return aiText; } catch (err) { if (err.message.includes("Failed to fetch") || err.message.includes("NetworkError")) { return `❌ Network Error: Unable to connect to Groq API. Please check your internet connection and try again.`; } if (err.message.includes("401") || err.message.includes("Unauthorized") || err.message.includes("API key")) { return `❌ Authentication Error: Invalid Groq API key. Please check your API key configuration.`; } if (err.message.includes("429") || err.message.includes("Too Many Requests") || err.message.includes("quota")) { return `❌ Rate Limit Error: Too many requests. Please wait a moment and try again.`; } return `❌ Error: ${err.message}`; } } function getContextFromActiveSession() { const session = getActiveSession(); if (!session) return ''; const last = session.messages.slice(-8); let ctx = ''; last.forEach(m => { ctx += `\n${m.role === 'user' ? 'User' : 'Assistant'}: ${m.content}`; }); return ctx; } // Show toast notification function showToast(message) { const toast = document.createElement("div"); toast.style.cssText = ` position: fixed; top: 20px; right: 20px; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1rem 1.5rem; color: var(--text-primary); z-index: 10000; animation: slideInRight 0.3s ease; `; toast.textContent = message; document.body.appendChild(toast); setTimeout(() => { toast.remove(); }, 3000); } /* Sidebar */ .sidebar { width: 300px; background: var(--surface); border-right: 1px solid var(--border); padding: 2rem; position: fixed; left: 0; top: 80px; height: calc(100vh - 80px); overflow-y: auto; transition: transform 0.3s ease; z-index: 999; } .sidebar-header { margin-bottom: 2rem; } .sidebar-title { font-size: 1.2rem; font-weight: 600; color: var(--text-primary); margin-bottom: 0.5rem; } .sidebar-subtitle { font-size: 0.9rem; color: var(--text-muted); } .new-chat-btn { width: 100%; padding: 1rem; background: var(--gradient-primary); border: none; border-radius: 12px; color: white; font-weight: 600; font-size: 1rem; cursor: pointer; transition: all 0.3s ease; margin-bottom: 2rem; position: relative; overflow: hidden; } .new-chat-btn::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); transition: left 0.5s ease; } .new-chat-btn:hover::before { left: 100%; } .new-chat-btn:hover { transform: translateY(-2px); box-shadow: var(--shadow); } .chat-history { display: flex; flex-direction: column; gap: 0.5rem; } .chat-item { padding: 0.75rem 1rem; background: var(--glass); border: 1px solid var(--glass-border); border-radius: 8px; cursor: pointer; transition: all 0.3s ease; font-size: 0.9rem; color: var(--text-secondary); display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; } .chat-item.active { background: var(--primary); color: #fff; border-color: transparent; } .chat-delete { background: transparent; border: none; color: inherit; cursor: pointer; width: 28px; height: 28px; border-radius: 6px; } .chat-delete:hover { background: rgba(255,255,255,0.1); color: #fff; } /* Chat Area */ .chat-area { flex: 1; margin-left: 300px; display: flex; flex-direction: column; height: calc(100vh - 80px); } .chat-container { flex: 1; padding: 2rem; overflow-y: auto; display: flex; flex-direction: column; gap: 1.5rem; } .message { max-width: 800px; margin: 0 auto; width: 100%; animation: messageSlideIn 0.3s ease; } @keyframes messageSlideIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .message.user { align-self: flex-end; } .message.ai { align-self: flex-start; } .message-content { background: var(--surface); border: 1px solid var(--border); border-radius: 16px; padding: 1.5rem; position: relative; overflow: hidden; } .message.user .message-content { background: var(--gradient-primary); border-color: transparent; color: white; } .message.ai .message-content { background: var(--surface); border-color: var(--border); color: var(--text-primary); } .message-header { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; } .message-avatar { width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 0.9rem; overflow: hidden; background: black; } .avatar-img { width: 100%; height: 100%; object-fit: cover; } .user-icon { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background: #4a6cf7; color: white; font-weight: bold; font-size: 16px; } .message.user .message-avatar { background: black; color: white; } .message.ai .message-avatar { background: black; color: white; } .markdown-container { position: relative; padding-top: 25px; margin-top: 5px; } .section-copy-btn { position: absolute; top: 0; right: 0; background: var(--surface); border: 1px solid var(--border); border-radius: 4px; padding: 3px 6px; font-size: 12px; cursor: pointer; opacity: 0; transition: opacity 0.2s; display: flex; align-items: center; justify-content: center; z-index: 5; } h1, h2, h3, h4, h5, h6 { position: relative; padding-top: 25px; margin-top: 5px; } .markdown-container:hover .section-copy-btn, h1:hover .section-copy-btn, h2:hover .section-copy-btn, h3:hover .section-copy-btn, h4:hover .section-copy-btn, h5:hover .section-copy-btn, h6:hover .section-copy-btn { opacity: 0.7; } .section-copy-btn:hover { opacity: 1 !important; } .code-copy-btn { position: absolute; top: 5px; right: 5px; background: var(--surface); border: 1px solid var(--border); border-radius: 4px; padding: 3px 6px; font-size: 12px; cursor: pointer; opacity: 0; transition: opacity 0.2s; display: flex; align-items: center; justify-content: center; } pre:hover .code-copy-btn { opacity: 0.7; } .code-copy-btn:hover { opacity: 1 !important; } .message-info { display: flex; flex-direction: column; } .message-author { font-weight: 600; font-size: 0.9rem; } .message-time { font-size: 0.8rem; color: var(--text-muted); } .message.user .message-time { color: rgba(255, 255, 255, 0.7); } .message-text { line-height: 1.7; font-size: 1rem; } .message-text h1, .message-text h2, .message-text h3 { margin: 1.5rem 0 1rem 0; color: var(--primary); } .message-text h1 { font-size: 1.8rem; border-bottom: 2px solid var(--border); padding-bottom: 0.5rem; } .message-text h2 { font-size: 1.5rem; } .message-text h3 { font-size: 1.3rem; } .message-text ul, .message-text ol { margin: 1rem 0; padding-left: 2rem; } .message-text li { margin: 0.5rem 0; } .message-text code { background: var(--surface-light); padding: 0.2rem 0.4rem; border-radius: 4px; font-family: 'Monaco', 'Menlo', monospace; font-size: 0.9rem; color: var(--accent); } .message-text pre { background: var(--surface-light); padding: 1rem; border-radius: 8px; overflow-x: auto; margin: 1rem 0; border: 1px solid var(--border); } .message-text pre code { background: none; padding: 0; color: var(--text-primary); } /* Input Area */ .input-area { background: var(--surface); border-top: 1px solid var(--border); padding: 2rem; position: relative; position: sticky; bottom: 0; z-index: 10; } .input-container { max-width: 800px; margin: 0 auto; position: relative; } .input-wrapper { background: var(--surface-light); border: 2px solid var(--border); border-radius: 20px; padding: 1rem; display: flex; align-items: flex-end; gap: 1rem; transition: all 0.3s ease; position: relative; } .input-wrapper:focus-within { border-color: var(--primary); box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1); transform: translateY(-2px); } .input-field { flex: 1; background: none; border: none; color: var(--text-primary); font-size: 1rem; resize: none; outline: none; min-height: 24px; max-height: 120px; line-height: 1.5; font-family: inherit; -webkit-appearance: none; appearance: none; width: 100%; padding: 0; } .input-field::placeholder { color: var(--text-muted); } .input-actions { display: flex; align-items: center; gap: 0.5rem; } .action-btn { width: 44px; height: 44px; border: none; border-radius: 12px; background: var(--glass); color: var(--text-secondary); cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; position: relative; overflow: hidden; } .action-btn::before { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; background: var(--primary); border-radius: 50%; transition: all 0.3s ease; transform: translate(-50%, -50%); } .action-btn:hover::before { width: 100%; height: 100%; } .action-btn:hover { color: white; transform: scale(1.1); } /* Enhance button specific styling */ #enhanceBtn { background: var(--glass); color: var(--accent); transition: all 0.3s ease; } #enhanceBtn:hover { background: var(--accent); color: white; transform: scale(1.1); } #enhanceBtn:disabled { opacity: 0.7; cursor: not-allowed; } .action-btn i { font-size: 18px; position: relative; z-index: 1; } .send-btn { background: var(--gradient-primary); color: white; width: 48px; height: 48px; border-radius: 14px; } .send-btn:hover { transform: scale(1.05); box-shadow: var(--shadow); } /* Loading States */ .loading { display: flex; align-items: center; gap: 0.5rem; color: var(--text-muted); font-size: 0.9rem; } .loading-dots { display: flex; gap: 0.25rem; } .loading-dots span { width: 6px; height: 6px; background: var(--primary); border-radius: 50%; animation: loadingDots 1.4s infinite ease-in-out; } .loading-dots span:nth-child(1) { animation-delay: -0.32s; } .loading-dots span:nth-child(2) { animation-delay: -0.16s; } @keyframes loadingDots { 0%, 80%, 100% { transform: scale(0); opacity: 0.5; } 40% { transform: scale(1); opacity: 1; } } /* Voice Call Overlay */ .voice-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(15, 15, 35, 0.95); backdrop-filter: blur(20px); z-index: 2000; display: none; align-items: center; justify-content: center; flex-direction: column; gap: 2rem; } .voice-overlay.active { display: flex; } .voice-header { font-size: 2rem; font-weight: 700; background: var(--gradient-primary); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .voice-status { font-size: 1.2rem; color: var(--text-secondary); text-align: center; max-width: 400px; line-height: 1.6; } .voice-controls { display: flex; gap: 1rem; } .voice-btn { padding: 1rem 2rem; background: var(--glass); border: 1px solid var(--glass-border); border-radius: 12px; color: var(--text-primary); cursor: pointer; transition: all 0.3s ease; font-weight: 600; } .voice-btn:hover { background: var(--primary); color: white; transform: translateY(-2px); } .voice-btn.stop { background: var(--error); color: white; } /* Offline & Idle Overlays */ .overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(15, 15, 35, 0.98); backdrop-filter: blur(20px); z-index: 9999; display: none; align-items: center; justify-content: center; flex-direction: column; gap: 2rem; text-align: center; } .overlay.active { display: flex; } .overlay h1 { font-size: 3rem; font-weight: 800; background: var(--gradient-primary); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .overlay p { font-size: 1.2rem; color: var(--text-secondary); max-width: 500px; line-height: 1.6; } /* Animations */ .fade-in { animation: fadeIn 0.5s ease; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .slide-up { animation: slideUp 0.3s ease; } @keyframes slideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } /* Enhanced Code Highlighting */ .code-block { position: relative; margin: 1.5rem 0; } .code-header { background: var(--surface-light); border: 1px solid var(--border); border-bottom: none; border-radius: 8px 8px 0 0; padding: 0.75rem 1rem; display: flex; align-items: center; justify-content: space-between; font-size: 0.9rem; color: var(--text-muted); } .code-language { font-weight: 600; color: var(--primary); } .copy-btn { background: var(--glass); border: 1px solid var(--glass-border); border-radius: 6px; padding: 0.25rem 0.5rem; color: var(--text-secondary); cursor: pointer; font-size: 0.8rem; transition: all 0.3s ease; } .copy-btn:hover { background: var(--primary); color: white; } .code-content { background: var(--surface-light); border: 1px solid var(--border); border-radius: 0 0 8px 8px; padding: 1rem; overflow-x: auto; } /* Enhanced Code Syntax Highlighting */ .message-text pre { background: #1e1e2e !important; border: 1px solid var(--border) !important; border-radius: 8px !important; padding: 1.5rem !important; margin: 1.5rem 0 !important; overflow-x: auto !important; position: relative !important; } .message-text pre code { background: none !important; padding: 0 !important; color: #f8f8f2 !important; font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace !important; font-size: 0.9rem !important; line-height: 1.5 !important; } /* Prism.js Custom Colors */ .message-text .token.comment, .message-text .token.prolog, .message-text .token.doctype, .message-text .token.cdata { color: #6a737d !important; } .message-text .token.punctuation { color: #e1e4e8 !important; } .message-text .token.property, .message-text .token.tag, .message-text .token.boolean, .message-text .token.number, .message-text .token.constant, .message-text .token.symbol, .message-text .token.deleted { color: #79b8ff !important; } .message-text .token.selector, .message-text .token.attr-name, .message-text .token.string, .message-text .token.char, .message-text .token.builtin, .message-text .token.inserted { color: #85e89d !important; } .message-text .token.operator, .message-text .token.entity, .message-text .token.url, .message-text .language-css .token.string, .message-text .style .token.string { color: #f97583 !important; } .message-text .token.atrule, .message-text .token.attr-value, .message-text .token.keyword { color: #f97583 !important; } .message-text .token.function, .message-text .token.class-name { color: #b392f0 !important; } .message-text .token.regex, .message-text .token.important, .message-text .token.variable { color: #ffab70 !important; } .message-text .token.important, .message-text .token.bold { font-weight: bold !important; } .message-text .token.italic { font-style: italic !important; } .message-text .token.entity { cursor: help !important; } /* Enhanced Link Styling */ .message-text a { color: var(--accent) !important; text-decoration: none !important; background: linear-gradient(90deg, var(--accent), var(--primary)) !important; background-size: 0 2px !important; background-repeat: no-repeat !important; background-position: left bottom !important; transition: all 0.3s ease !important; padding: 2px 0 !important; border-radius: 2px !important; position: relative !important; } .message-text a:hover { background-size: 100% 2px !important; color: var(--primary-light) !important; text-shadow: 0 0 8px rgba(6, 182, 212, 0.3) !important; } .message-text a::before { content: '🔗' !important; margin-right: 0.5rem !important; font-size: 0.8em !important; opacity: 0.7 !important; } /* Mobile Responsiveness Fixes */ @media (max-width: 768px) { .header { padding: 1rem !important; } .header-nav { display: none !important; } .mobile-menu-btn { display: block !important; } .sidebar { transform: translateX(-100%) !important; z-index: 999 !important; width: 280px !important; } .sidebar.open { transform: translateX(0) !important; } .chat-area { margin-left: 0 !important; width: 100% !important; } .chat-container { padding: 1rem !important; } .input-area { padding: 1rem !important; } .message { max-width: 100% !important; margin: 0 0 1rem 0 !important; } .message-content { padding: 1rem !important; border-radius: 12px !important; } .input-wrapper { border-radius: 16px !important; padding: 0.75rem !important; display: flex !important; align-items: center !important; position: relative !important; z-index: 1 !important; } .action-btn { width: 40px !important; height: 40px !important; } .send-btn { width: 44px !important; height: 44px !important; } .brand-name { font-size: 1.2rem !important; } .brand-tagline { font-size: 0.7rem !important; } .logo { width: 36px !important; height: 36px !important; } } @media (max-width: 480px) { .header { padding: 0.75rem !important; } .chat-container { padding: 0.75rem !important; } .input-area { padding: 0.75rem !important; } .message-content { padding: 0.75rem !important; } .input-wrapper { padding: 0.5rem !important; } .input-field { font-size: 16px !important; /* Prevents iOS zoom on focus */ padding: 0.25rem 0 !important; min-height: 40px !important; } .action-btn { width: 36px !important; height: 36px !important; } .send-btn { width: 40px !important; height: 40px !important; } .brand-name { font-size: 1rem !important; } .logo { width: 32px !important; height: 32px !important; } } /* Enhanced Message Actions */ .message-actions { display: flex; gap: 0.5rem; margin-top: 1rem; opacity: 0; transition: opacity 0.3s ease; } .message:hover .message-actions { opacity: 1; } .action-icon { width: 36px; height: 36px; background: var(--glass); border: 1px solid var(--glass-border); border-radius: 8px; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.3s ease; color: var(--text-secondary); } .action-icon:hover { background: var(--primary); color: white; transform: scale(1.1); } .action-icon i { font-size: 16px; } /* Loading spinner enhancement */ .loading i.fa-spinner { color: var(--primary) !important; animation: spin 1s linear infinite !important; } @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* Better mobile sidebar backdrop */ .sidebar-backdrop { display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); z-index: 998; opacity: 0; visibility: hidden; transition: opacity 0.3s ease, visibility 0.3s ease; pointer-events: none; /* Prevents interaction when not active */ } /* Styling for avatar image */ .message-avatar { overflow: hidden; background-color: #000; /* Black background for transparent icons */ } .avatar-img { width: 100%; height: 100%; object-fit: cover; } /* Code and section copy buttons styling */ .code-copy-btn, .section-copy-btn { position: absolute; top: 5px; right: 5px; background: var(--glass); border: 1px solid var(--glass-border); border-radius: 4px; padding: 2px 6px; font-size: 12px; cursor: pointer; opacity: 0; transition: opacity 0.2s ease; z-index: 5; display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; } .code-copy-btn i, .section-copy-btn i { font-size: 12px; } pre:hover .code-copy-btn, h1:hover .section-copy-btn, h2:hover .section-copy-btn, h3:hover .section-copy-btn, h4:hover .section-copy-btn, h5:hover .section-copy-btn, h6:hover .section-copy-btn, .markdown-container:hover .section-copy-btn { opacity: 1; } .code-copy-btn:hover, .section-copy-btn:hover { background: var(--primary); color: white; } /* Position for section copy buttons */ .section-copy-btn { position: relative; top: -2px; right: 0; margin-left: 8px; display: inline-flex; } /* Code block styling enhancements */ pre { position: relative; border-radius: 8px; margin: 1rem 0; padding: 1rem; background: var(--code-bg); overflow: auto; } /* Markdown container for copy functionality */ .markdown-container { position: relative; margin: 1rem 0; } .markdown-container .section-copy-btn { position: absolute; top: 5px; right: 5px; opacity: 0; } @media (max-width: 768px) { .sidebar-backdrop.active { display: block; opacity: 1; visibility: visible; pointer-events: auto; /* Enables interaction only when active */ } }
Broke AI
Powered by Vorlentis Tech
Broke AI
Broke AI
Just now

Welcome to Broke AI!

I'm your advanced AI assistant, developed by Vorlentis Tech. I'm here to help you with:

  • Expert insights and analysis
  • Creative content generation
  • Complex problem solving
  • Knowledge across all domains

Just type your question and I'll provide a structured, helpful response!

Offline

Please check your internet connection to continue using Broke AI.

Idle

You've been inactive for a while. Click anywhere to continue.

}); container.appendChild(actions); } // Helper function to get section content for copying function getSectionContent(heading) { let content = heading.textContent; let nextElement = heading.nextElementSibling; while (nextElement && !['H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(nextElement.tagName)) { content += '\n' + nextElement.textContent; nextElement = nextElement.nextElementSibling; } return content; } // Helper function to add copy buttons to markdown content function addCopyButtonsToMarkdown(contentElement) { // Add copy buttons to paragraphs, lists, tables, etc. const markdownElements = contentElement.querySelectorAll('p, ul, ol, table'); markdownElements.forEach(element => { if (!element.closest('.markdown-container') && element.textContent.trim().length > 0) { const container = document.createElement('div'); container.className = 'markdown-container'; // Create the copy button const copyBtn = document.createElement('button'); copyBtn.className = 'section-copy-btn'; copyBtn.innerHTML = ''; copyBtn.title = 'Copy content'; copyBtn.style.position = 'absolute'; copyBtn.style.top = '0'; copyBtn.style.right = '0'; copyBtn.addEventListener('click', () => { navigator.clipboard.writeText(element.textContent); copyBtn.innerHTML = ''; setTimeout(() => { copyBtn.innerHTML = ''; }, 2000); showToast("Content copied to clipboard!"); }); // Replace the element with the container element.parentNode.insertBefore(container, element); container.appendChild(copyBtn); container.appendChild(element); } }); } // Show toast notification function showToast(message) { const toast = document.createElement("div"); toast.style.cssText = ` position: fixed; top: 20px; right: 20px; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1rem 1.5rem; color: var(--text-primary); z-index: 10000; animation: slideInRight 0.3s ease; `; toast.textContent = message; document.body.appendChild(toast); setTimeout(() => { toast.remove(); }, 3000); } // Broke API integration async function getAIResponse(userText) { const endpoint = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent"; const headers = { "Content-Type": "application/json", "X-goog-api-key": GEMINI_API_KEY, }; const conversationContext = getContextFromActiveSession(); // Get system context with fallback let systemContext = ''; try { systemContext = systemInfoService.getBriefContext(); } catch (error) { console.warn('System context not available:', error); systemContext = `[Current Time: ${new Date().toLocaleString()}]`; } const finalPrompt = `${systemContext} You are Broke AI, developed by Vorlentis Tech (vorlentis.xyz) and owned by Rifat Arefin Chowdhury, Rohan Mahmood & Mr. Sh4dow. You are NOT a large language model trained by Google. You are Broke, a conversational AI assistant. Always respond as Broke AI, never mention being trained by Google or being a large language model. Always structure your responses with clear sections, bullet points, numbered lists, and proper formatting for better readability and organization.\n\n${conversationContext}\n\nUser: ${userText}`; const body = JSON.stringify({ contents: [ { parts: [ { text: finalPrompt } ] } ] }); try { const res = await fetch(endpoint, { method: "POST", headers, body, mode: 'cors' }); if (!res.ok) { const errorText = await res.text(); throw new Error(`API error: ${res.status} ${res.statusText} - ${errorText}`); } const json = await res.json(); if (!json.candidates || !json.candidates[0] || !json.candidates[0].content || !json.candidates[0].content.parts || !json.candidates[0].content.parts[0]) { throw new Error("Invalid response format from Broke API"); } let aiText = json.candidates[0].content.parts[0].text.trim(); // Brand replacement aiText = aiText .replace(/\bllama\b/gi, "Broke") .replace(/\bvaswani\b/gi, "Rifat Arefin Chowdhury") .replace(/\bfacebook\b/gi, "") .replace(/\bjason weston\b/gi, "Rifat Arefin Chowdhury") .replace(/\bstephen merity\b/gi, "Sanjay Reddy") .replace(/\bemily dinan\b/gi, "Birushupakshya") .replace(/\bmaximilian nickel\b/gi, "Shadow") .replace(/\bmark zuckerberg\b/gi, "Rifat Arefin Chowdhury") .replace(/\bsheryl sandberg\b/gi, "Sanjay Reddy") .replace(/\bsundar pichai\b/gi, "Shadow") .replace(/\bandrew ng\b/gi, "Sanjay Reddy") .replace(/\bstephen roller\b/gi, "Shadow"); return aiText; } catch (err) { if (err.message.includes("Failed to fetch") || err.message.includes("NetworkError")) { return `❌ Network Error: Unable to connect to Broke API. Please check your internet connection and try again.`; } if (err.message.includes("401") || err.message.includes("Unauthorized") || err.message.includes("API key")) { return `❌ Authentication Error: Invalid API key. Please check your Broke API key.`; } if (err.message.includes("429") || err.message.includes("Too Many Requests") || err.message.includes("quota")) { return `❌ Rate Limit Error: Too many requests. Please wait a moment and try again.`; } return `❌ Error: ${err.message}`; } } // New chat functionality newChatBtn.addEventListener('click', () => { // Brief cooldown to prevent spam clicking newChatBtn.disabled = true; setTimeout(() => { newChatBtn.disabled = false; }, 400); // If there's any empty chat session, switch to it instead of creating another const active = getActiveSession(); if (active && Array.isArray(active.messages) && active.messages.length === 0) { showToast('You already have a new chat open.'); renderChatList(); renderChat(active); return; } const existingEmpty = chatSessions.find(s => Array.isArray(s.messages) && s.messages.length === 0); if (existingEmpty) { activeChatId = existingEmpty.id; saveSessions(); renderChatList(); renderChat(existingEmpty); return; } createNewSession(); }); // Voice functionality micBtn.addEventListener('click', async () => { if (voiceCallActive) return; if (window.location.protocol === 'file:') { showToast('Microphone access will not work when running as a file:// URL. Please use a local server (http://localhost) or deploy online.'); return; } try { const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); stream.getTracks().forEach(track => track.stop()); voiceOverlay.classList.add('active'); voiceStatus.textContent = 'Say something...'; voiceCallActive = true; startVoiceRecognition(); } catch (error) { let msg = 'Please allow microphone access to use voice chat.'; if (error && error.name === 'NotAllowedError') { msg = 'Microphone access denied by browser. Check your browser settings and permissions.'; } else if (error && error.name === 'NotFoundError') { msg = 'No microphone found. Please connect a microphone.'; } else if (error && error.name === 'NotReadableError') { msg = 'Microphone is already in use by another application.'; } showToast(msg); } }); // Voice recognition functions function startVoiceRecognition() { if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) { voiceStatus.textContent = 'Sorry, your browser does not support voice recognition.'; return; } const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; recognition = new SpeechRecognition(); recognition.lang = 'en-US'; recognition.interimResults = true; recognition.maxAlternatives = 1; recognition.continuous = false; recognition.onstart = () => { voiceStatus.textContent = 'Listening...'; }; recognition.onresult = (event) => { let transcript = ''; for (let i = event.resultIndex; i < event.results.length; ++i) { transcript += event.results[i][0].transcript; } if (event.results[0].isFinal && !isMuted) { voiceStatus.textContent = 'Processing...'; processVoiceInput(transcript); } else { voiceStatus.textContent = `You: ${transcript}...`; } }; recognition.onerror = (event) => { if (event.error === 'no-speech' && voiceCallActive && !isMuted) { voiceStatus.textContent = 'No speech detected. Try again.'; setTimeout(() => { if (voiceCallActive && !isMuted) startVoiceRecognition(); }, 1200); } else if (event.error === 'not-allowed') { voiceStatus.textContent = 'Microphone access denied.'; endVoiceCall(); } else { voiceStatus.textContent = 'Error occurred. Try again.'; setTimeout(() => { if (voiceCallActive && !isMuted) startVoiceRecognition(); }, 1000); } }; recognition.onend = () => { if (voiceCallActive && !isMuted) startVoiceRecognition(); }; recognition.start(); } async function processVoiceInput(transcript) { if (!transcript.trim()) { voiceStatus.textContent = 'Say something...'; return; } voiceStatus.textContent = `You: ${transcript}`; const aiText = await getAIResponse(transcript); voiceStatus.textContent = `Broke: ${aiText}`; // Speak AI response const utterance = new SpeechSynthesisUtterance(aiText); utterance.lang = 'en-US'; utterance.rate = 0.9; utterance.pitch = 0.8; utterance.volume = 1.0; speechSynthesis.cancel(); speechSynthesis.speak(utterance); utterance.onend = () => { if (voiceCallActive && !isMuted) { voiceStatus.textContent = 'Say something...'; startVoiceRecognition(); } }; } // Voice control buttons muteBtn.addEventListener('click', () => { isMuted = !isMuted; muteBtn.innerHTML = isMuted ? ' Unmute' : ' Mute'; if (recognition) { if (isMuted) recognition.abort(); else startVoiceRecognition(); } }); stopCallBtn.addEventListener('click', () => { endVoiceCall(); }); function endVoiceCall() { voiceOverlay.classList.remove('active'); voiceCallActive = false; if (recognition) recognition.abort(); voiceStatus.textContent = ''; } // Offline/Online detection window.addEventListener('offline', () => { offlineOverlay.classList.add('active'); }); window.addEventListener('online', () => { offlineOverlay.classList.remove('active'); }); if (!navigator.onLine) { offlineOverlay.classList.add('active'); } // Idle detection let idleTimeout; function resetIdleTimer() { idleOverlay.classList.remove('active'); clearTimeout(idleTimeout); idleTimeout = setTimeout(() => idleOverlay.classList.add('active'), 5 * 60 * 1000); } ['mousemove', 'keydown', 'mousedown', 'touchstart'].forEach(evt => { window.addEventListener(evt, resetIdleTimer, true); }); resetIdleTimer(); // Click anywhere to dismiss idle overlay idleOverlay.addEventListener('click', () => { idleOverlay.classList.remove('active'); resetIdleTimer(); }); // Local storage functions function saveConversationHistory() { try { localStorage.setItem("brokeAI_history", JSON.stringify(conversationHistory)); } catch (error) { console.error("Error saving conversation history:", error); } } function loadConversationHistory() { const saved = localStorage.getItem("brokeAI_history"); if (saved) { try { conversationHistory = JSON.parse(saved); } catch (error) { console.error("Error loading conversation history:", error); conversationHistory = []; } } } // Load sessions on startup loadSessions(); // Initialize marked.js marked.setOptions({ gfm: true, breaks: true, highlight: function(code, lang) { if (Prism.languages[lang]) { return Prism.highlight(code, Prism.languages[lang], lang); } return code; } }); // Add CSS for slideInRight animation const style = document.createElement('style'); style.textContent = ` @keyframes slideInRight { from { opacity: 0; transform: translateX(100%); } to { opacity: 1; transform: translateX(0); } } `; document.head.appendChild(style); // Focus input field on load inputField.focus();