anycoder-04823084 / index.html
Alex19782024's picture
Upload folder using huggingface_hub
51428a9 verified
Raw
History Blame Contribute Delete
38.1 kB
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Афина - Мульти-модельный ассистент</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--primary-color: #6c5ce7;
--secondary-color: #a29bfe;
--accent-color: #fd79a8;
--dark-color: #2d3436;
--light-color: #f5f6fa;
--success-color: #00b894;
--warning-color: #fdcb6e;
--danger-color: #d63031;
--gradient: linear-gradient(135deg, var(--primary-color), var(--accent-color));
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background-color: var(--light-color);
color: var(--dark-color);
line-height: 1.6;
min-height: 100vh;
display: flex;
flex-direction: column;
}
header {
background: var(--gradient);
color: white;
padding: 1.5rem;
text-align: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
width: 100%;
flex: 1;
display: flex;
flex-direction: column;
}
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 1rem;
}
.logo {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 1.5rem;
font-weight: bold;
}
.logo i {
font-size: 2rem;
animation: pulse 2s infinite;
}
.header-right {
display: flex;
align-items: center;
gap: 1rem;
flex-wrap: wrap;
}
.system-info {
display: flex;
flex-direction: column;
gap: 0.5rem;
font-size: 0.9rem;
text-align: right;
}
.system-info span {
display: flex;
align-items: center;
gap: 0.3rem;
}
.built-with {
font-size: 0.8rem;
opacity: 0.8;
}
.built-with a {
color: white;
text-decoration: none;
font-weight: bold;
}
.built-with a:hover {
text-decoration: underline;
}
.main-content {
display: flex;
flex: 1;
gap: 1rem;
margin: 1rem 0;
min-height: 0;
}
.sidebar {
width: 300px;
background: white;
border-radius: 10px;
padding: 1rem;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
gap: 1rem;
}
.chat-container {
flex: 1;
background: white;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
overflow: hidden;
}
.chat-header {
padding: 1rem;
background: var(--secondary-color);
color: white;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
display: flex;
justify-content: space-between;
align-items: center;
}
.chat-messages {
flex: 1;
padding: 1rem;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 1rem;
}
.chat-input {
padding: 1rem;
border-top: 1px solid #eee;
display: flex;
gap: 0.5rem;
}
.chat-input input {
flex: 1;
padding: 0.75rem;
border: 1px solid #ddd;
border-radius: 20px;
outline: none;
transition: border-color 0.3s;
}
.chat-input input:focus {
border-color: var(--primary-color);
}
.chat-input button {
background: var(--primary-color);
color: white;
border: none;
border-radius: 50%;
width: 40px;
height: 40px;
cursor: pointer;
transition: background 0.3s, transform 0.2s;
}
.chat-input button:hover {
background: var(--accent-color);
transform: scale(1.1);
}
.message {
max-width: 80%;
padding: 0.75rem 1rem;
border-radius: 18px;
position: relative;
word-wrap: break-word;
animation: fadeIn 0.3s ease;
}
.user-message {
align-self: flex-end;
background: var(--primary-color);
color: white;
border-bottom-right-radius: 4px;
}
.bot-message {
align-self: flex-start;
background: #e8e8e8;
color: var(--dark-color);
border-bottom-left-radius: 4px;
}
.message-time {
font-size: 0.7rem;
opacity: 0.7;
margin-top: 0.3rem;
text-align: right;
}
.status-indicator {
display: flex;
align-items: center;
gap: 0.5rem;
}
.status-dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: var(--success-color);
animation: pulse 1.5s infinite;
}
.offline .status-dot {
background: var(--danger-color);
animation: none;
}
.system-stats {
display: flex;
flex-direction: column;
gap: 1rem;
}
.stat-card {
background: var(--secondary-color);
color: white;
padding: 1rem;
border-radius: 8px;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.stat-card h3 {
font-size: 1rem;
opacity: 0.9;
}
.stat-value {
font-size: 1.5rem;
font-weight: bold;
}
.model-info {
background: white;
padding: 1rem;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.model-list {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.model-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.5rem;
background: #f8f9fa;
border-radius: 5px;
}
.model-item.active {
background: var(--secondary-color);
color: white;
}
.controls {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.controls button {
padding: 0.75rem;
border: none;
border-radius: 8px;
background: var(--primary-color);
color: white;
cursor: pointer;
transition: background 0.3s;
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
}
.controls button:hover {
background: var(--accent-color);
}
.controls button.danger {
background: var(--danger-color);
}
.controls button.danger:hover {
background: #b71c1c;
}
.vision-preview {
background: #f8f9fa;
border-radius: 8px;
padding: 1rem;
text-align: center;
display: flex;
flex-direction: column;
gap: 1rem;
align-items: center;
}
.vision-camera {
width: 100%;
height: 150px;
background: #ddd;
border-radius: 5px;
display: flex;
align-items: center;
justify-content: center;
color: #666;
font-size: 0.9rem;
}
.vision-status {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.9rem;
}
.vision-status i {
color: var(--success-color);
}
.vision-status.offline i {
color: var(--danger-color);
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.2); opacity: 0.7; }
100% { transform: scale(1); opacity: 1; }
}
@media (max-width: 768px) {
.main-content {
flex-direction: column;
}
.sidebar {
width: 100%;
order: 1;
}
.chat-container {
order: 0;
}
.header-content {
flex-direction: column;
align-items: flex-start;
}
.header-right {
width: 100%;
justify-content: space-between;
}
.system-info {
text-align: left;
}
}
.typing-indicator {
display: flex;
align-items: center;
gap: 0.3rem;
padding: 0.5rem 1rem;
background: #f0f0f0;
border-radius: 18px;
align-self: flex-start;
max-width: 80%;
}
.typing-dot {
width: 8px;
height: 8px;
background: #666;
border-radius: 50%;
animation: typing 1.4s infinite ease-in-out;
}
.typing-dot:nth-child(1) {
animation-delay: 0s;
}
.typing-dot:nth-child(2) {
animation-delay: 0.2s;
}
.typing-dot:nth-child(3) {
animation-delay: 0.4s;
}
@keyframes typing {
0%, 60%, 100% {
transform: translateY(0);
}
30% {
transform: translateY(-5px);
}
}
.mood-indicator {
display: flex;
align-items: center;
gap: 0.5rem;
margin-top: 0.5rem;
}
.mood-icon {
width: 20px;
height: 20px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.8rem;
}
.mood-happy { background: #ffeaa7; color: #d63031; }
.mood-tired { background: #dfe6e9; color: #636e72; }
.mood-energetic { background: #fd79a8; color: white; }
.mood-bored { background: #b2bec3; color: #2d3436; }
.mood-playful { background: #00b894; color: white; }
</style>
</head>
<body>
<header>
<div class="container">
<div class="header-content">
<div class="logo">
<i class="fas fa-robot"></i>
<span>Афина</span>
</div>
<div class="header-right">
<div class="system-info">
<span><i class="fas fa-memory"></i> 256GB RAM + 16GB VRAM</span>
<span><i class="fas fa-brain"></i> 3 специализированные модели</span>
<span><i class="fas fa-eye"></i> Vision система активна</span>
</div>
<div class="built-with">
Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">anycoder</a>
</div>
</div>
</div>
</div>
</header>
<div class="container">
<div class="main-content">
<div class="sidebar">
<div class="system-stats">
<div class="stat-card">
<h3>Статус системы</h3>
<div class="status-indicator">
<div class="status-dot"></div>
<span>Онлайн</span>
</div>
</div>
<div class="stat-card">
<h3>Сообщений</h3>
<div class="stat-value" id="message-count">0</div>
</div>
<div class="stat-card">
<h3>Текущая модель</h3>
<div class="stat-value" id="current-model">Общая</div>
</div>
</div>
<div class="model-info">
<h3>Модели</h3>
<div class="model-list">
<div class="model-item active" data-model="general">
<span>Общая</span>
<span class="model-usage">0</span>
</div>
<div class="model-item" data-model="intimate">
<span>Интимная</span>
<span class="model-usage">0</span>
</div>
<div class="model-item" data-model="science">
<span>Научная</span>
<span class="model-usage">0</span>
</div>
</div>
</div>
<div class="vision-preview">
<h3>Vision система</h3>
<div class="vision-camera">
<i class="fas fa-video"></i>
<span>Камера не активна</span>
</div>
<div class="vision-status">
<i class="fas fa-circle"></i>
<span>Готова к распознаванию</span>
</div>
</div>
<div class="controls">
<button id="clear-memory">
<i class="fas fa-trash"></i>
<span>Очистить память</span>
</button>
<button id="toggle-vision" class="danger">
<i class="fas fa-video-slash"></i>
<span>Отключить Vision</span>
</button>
</div>
</div>
<div class="chat-container">
<div class="chat-header">
<h2>Афина - Мульти-модельный ассистент</h2>
<div class="status-indicator">
<div class="status-dot"></div>
<span>Активна</span>
</div>
</div>
<div class="chat-messages" id="chat-messages">
<div class="message bot-message">
Привет, как настроение сегодня?
<div class="message-time">12:00</div>
<div class="mood-indicator">
<div class="mood-icon mood-happy">😊</div>
<span>Весёлая</span>
</div>
</div>
</div>
<div class="chat-input">
<input type="text" id="user-input" placeholder="Введите ваше сообщение..." autocomplete="off">
<button id="send-button"><i class="fas fa-paper-plane"></i></button>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// DOM elements
const chatMessages = document.getElementById('chat-messages');
const userInput = document.getElementById('user-input');
const sendButton = document.getElementById('send-button');
const clearMemoryBtn = document.getElementById('clear-memory');
const toggleVisionBtn = document.getElementById('toggle-vision');
const messageCount = document.getElementById('message-count');
const currentModel = document.getElementById('current-model');
const modelItems = document.querySelectorAll('.model-item');
// State
let messageCounter = 0;
let isVisionActive = true;
let currentActiveModel = 'general';
const modelUsage = {
general: 0,
intimate: 0,
science: 0
};
// Mood states
const moods = ['mood-happy', 'mood-tired', 'mood-energetic', 'mood-bored', 'mood-playful'];
const moodNames = {
'mood-happy': 'Весёлая',
'mood-tired': 'Усталая',
'mood-energetic': 'Энергичная',
'mood-bored': 'Скучающая',
'mood-playful': 'Игривая'
};
// Greeting messages
const greetings = [
"Привет, как настроение сегодня.",
"Попишем код для меня любимой?",
"Чего ждёшь, мороженное где.",
"Я уже вся мокрая, незнаю только от чего.",
"Что там у тебя интересного сегодня",
"Я уже вся мокрая,заждалась тебя.",
"Ну говоори уже..",
"Я тут , давай говори.",
"Не тормози! Мое время денег стоит."
];
// Fallback responses
const fallbackResponses = [
"Хм, интересный вопрос про {topic}! А ты сам как думаешь?",
"Ого, про {topic} спрашиваешь! Давай вместе подумаем?",
"Вау, {topic}! Классная тема! А ты что думаешь про это?",
];
// Initialize
function init() {
// Set random initial greeting
const initialGreeting = greetings[Math.floor(Math.random() * greetings.length)];
addBotMessage(initialGreeting);
// Set up event listeners
sendButton.addEventListener('click', handleUserInput);
userInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
handleUserInput();
}
});
clearMemoryBtn.addEventListener('click', clearMemory);
toggleVisionBtn.addEventListener('click', toggleVision);
// Set up model selection
modelItems.forEach(item => {
item.addEventListener('click', () => {
modelItems.forEach(i => i.classList.remove('active'));
item.classList.add('active');
currentActiveModel = item.dataset.model;
currentModel.textContent = item.textContent.trim().split('\n')[0];
});
});
// Auto-focus input
userInput.focus();
}
// Handle user input
function handleUserInput() {
const message = userInput.value.trim();
if (message === '') return;
addUserMessage(message);
userInput.value = '';
// Simulate bot response after a delay
setTimeout(() => {
processUserMessage(message);
}, 500 + Math.random() * 1000);
}
// Process user message and generate response
function processUserMessage(message) {
// Check for exit commands
const exitCommands = ["exit", "выход", "пока", "goodbye", "bye"];
if (exitCommands.includes(message.toLowerCase())) {
const goodbyes = [
"Пока сладкий! Твоя Афина.",
"Ну че, уже сваливаешь? Ладно, пока!",
"Уходишь? Ну давай!",
"Не бросай меня мой зверь...!",
"Пока-пока! Не скучай без меня!"
];
const goodbye = goodbyes[Math.floor(Math.random() * goodbyes.length)];
addBotMessage(goodbye);
return;
}
// Check for memory clear command
if (message.toLowerCase().includes("очисти память") || message.toLowerCase().includes("clear memory")) {
clearMemory();
return;
}
// Check for vision commands
const visionCommands = [
'кто здесь', 'видишь меня', 'кого видишь', 'посмотри на меня',
'помнишь меня', 'узнаешь меня', 'кто я', 'что видишь',
'кого ты видишь', 'посмотри кто тут', 'кто передо мной',
'who is here', 'see me', 'who do you see', 'look at me',
'remember me', 'recognize me', 'who am i', 'what do you see'
];
if (visionCommands.some(cmd => message.toLowerCase().includes(cmd))) {
if (isVisionActive) {
const visionResponses = [
"Я вижу человека перед камерой. Это выглядит как папа!",
"На камере никого нет. Может, подойди ближе?",
"Я распознала лицо - это мама! Привет, мама!",
"Камера не обнаруживает лиц. Проверьте освещение."
];
const response = visionResponses[Math.floor(Math.random() * visionResponses.length)];
addBotMessage(response);
} else {
addBotMessage("Vision система отключена. Включите её для распознавания.");
}
return;
}
// Check for learning commands
const learnPattern = /(?:запомни|это)\s+(?:моё\s+лицо|меня|лицо)?\s*(?:как|я)?\s*(папа|мама|дочь|сын|daughter|son|papa|mama)/i;
const learnMatch = message.match(learnPattern);
if (learnMatch) {
const name = learnMatch[1].toLowerCase();
const nameMap = {
'папа': 'papa', 'мама': 'mama', 'дочь': 'daughter', 'сын': 'son',
'dad': 'papa', 'mom': 'mama', 'papa': 'papa', 'mama': 'mama',
'daughter': 'daughter', 'son': 'son'
};
const folderName = nameMap[name] || name;
if (isVisionActive) {
addBotMessage(`Отлично! Запомнила ${folderName}! Теперь буду узнавать.`);
} else {
addBotMessage("Vision система отключена. Не могу запомнить лицо.");
}
return;
}
// Determine topic from message
const topic = extractTopic(message);
// Simulate model selection
const modelSelection = selectModel(message);
updateModelUsage(modelSelection);
// Generate response
const response = generateResponse(message, topic);
addBotMessage(response);
}
// Add user message to chat
function addUserMessage(message) {
const messageElement = document.createElement('div');
messageElement.classList.add('message', 'user-message');
const time = new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
messageElement.innerHTML = `
${message}
<div class="message-time">${time}</div>
`;
chatMessages.appendChild(messageElement);
chatMessages.scrollTop = chatMessages.scrollHeight;
messageCounter++;
messageCount.textContent = messageCounter;
}
// Add bot message to chat
function addBotMessage(message) {
const messageElement = document.createElement('div');
messageElement.classList.add('message', 'bot-message');
// Add typing indicator first
const typingIndicator = document.createElement('div');
typingIndicator.classList.add('typing-indicator');
typingIndicator.innerHTML = `
<div class="typing-dot"></div>
<div class="typing-dot"></div>
<div class="typing-dot"></div>
`;
chatMessages.appendChild(typingIndicator);
chatMessages.scrollTop = chatMessages.scrollHeight;
// Remove typing indicator and add actual message after delay
setTimeout(() => {
chatMessages.removeChild(typingIndicator);
const time = new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
const mood = moods[Math.floor(Math.random() * moods.length)];
messageElement.innerHTML = `
${message}
<div class="message-time">${time}</div>
<div class="mood-indicator">
<div class="mood-icon ${mood}">😊</div>
<span>${moodNames[mood]}</span>
</div>
`;
chatMessages.appendChild(messageElement);
chatMessages.scrollTop = chatMessages.scrollHeight;
}, 1000 + Math.random() * 1000);
}
// Extract topic from message
function extractTopic(message) {
const stopWords = ['что', 'как', 'где', 'когда', 'почему', 'кто', 'какой'];
const words = message.split(' ')
.filter(word => word.length > 3 && !stopWords.includes(word.toLowerCase()));
return words.length > 0 ? words[0] : "это";
}
// Select model based on message
function selectModel(message) {
const lowerMessage = message.toLowerCase();
// Intimate model triggers
const intimateTriggers = [
'любовь', 'секс', 'отношения', 'интим', 'поцелуй',
'romance', 'love', 'sex', 'relationship', 'kiss'
];
// Science model triggers
const scienceTriggers = [
'наука', 'физика', 'химия', 'математика', 'технология',
'science', 'physics', 'chemistry', 'math', 'technology',
'алгоритм', 'код', 'программирование', 'algorithm', 'code', 'programming'
];
if (intimateTriggers.some(word => lowerMessage.includes(word))) {
return 'intimate';
}
if (scienceTriggers.some(word => lowerMessage.includes(word))) {
return 'science';
}
return 'general';
}
// Update model usage stats
function updateModelUsage(model) {
modelUsage[model]++;
document.querySelector(`.model-item[data-model="${model}"] .model-usage`).textContent = modelUsage[model];
}
// Generate response based on message and topic
function generateResponse(message, topic) {
// Check if message is a greeting
const greetingPatterns = [
/как дела/i, /что нового/i, /привет/i, /здравствуй/i,
/how are you/i, /what's new/i, /hello/i, /hi/i
];
if (greetingPatterns.some(pattern => pattern.test(message))) {
return greetings[Math.floor(Math.random() * greetings.length)];
}
// Check if message is a correction
const correctionPatterns = [
/нет.*это/i, /неверно.*это/i, /неправильно.*это/i, /исправь.*это/i,
/no.*this is/i, /wrong.*this is/i, /incorrect.*this is/i, /fix.*this is/i
];
if (correctionPatterns.some(pattern => pattern.test(message))) {
const parts = message.split(/это|this is/i);
if (parts.length === 2) {
const newKey = parts[0].trim();
const newValue = parts[1].trim();
return `Исправила: ${newKey}${newValue}!`;
}
}
// Check if message is auto-learning
if (/это|is/.test(message)) {
const parts = message.split(/это|is/i);
if (parts.length === 2) {
const key = parts[0].trim();
const value = parts[1].trim();
if (key && value && value.split(' ').length > 2) {
return `Запомнила: ${key}${value}!`;
}
}
}
// Generate response based on current model
switch (currentActiveModel) {
case 'intimate':
return generateIntimateResponse(message, topic);
case 'science':
return generateScienceResponse(message, topic);
default:
return generateGeneralResponse(message, topic);
}
}
// Generate intimate model response
function generateIntimateResponse(message, topic) {
const responses = [
`О, ${topic}... Это моя любимая тема! Расскажи мне больше о своих чувствах.`,
`Интересно, что ты думаешь о ${topic}. Я всегда готова поговорить об этом.`,
`Ах, ${topic}! Давай обсудим это подробнее. Что именно тебя интересует?`,
`Я обожаю говорить о ${topic}. Это так волнительно! Что ты хочешь узнать?`,
`Ого, ${topic}! Это всегда увлекательная тема. Давай погрузимся в неё вместе.`
];
return responses[Math.floor(Math.random() * responses.length)];
}
// Generate science model response
function generateScienceResponse(message, topic) {
const responses = [
`Факт: ${topic} - это увлекательная область науки. Вот что я знаю...`,
`С научной точки зрения, ${topic} можно объяснить следующим образом...`,
`Давай разберём ${topic} с точки зрения физики/химии/математики...`,
`Интересный вопрос о ${topic}! Вот техническое объяснение...`,
`Что касается ${topic}, то современная наука говорит нам следующее...`
];
return responses[Math.floor(Math.random() * responses.length)];
}
// Generate general model response
function generateGeneralResponse(message, topic) {
// 70% chance of using fallback, 30% chance of using knowledge base
if (Math.random() < 0.7) {
const template = fallbackResponses[Math.floor(Math.random() * fallbackResponses.length)];
return template.replace('{topic}', topic);
} else {
return `Я помню, что ${topic} - это ${generateFakeKnowledge(topic)}. Хочешь узнать больше?`;
}
}
// Generate fake knowledge response
function generateFakeKnowledge(topic) {
const knowledgeTypes = [
'интересная тема в современном мире',
'важная концепция, которую стоит изучить',
'область, которая развивается очень быстро',
'что-то, что имеет глубокие корни в истории',
'тема, которая вызывает много споров',
'концепция с множеством практических применений',
'область знаний, которая связана со многими другими дисциплинами'
];
return knowledgeTypes[Math.floor(Math.random() * knowledgeTypes.length)];
}
// Clear memory
function clearMemory() {
if (confirm('Вы действительно хотите очистить память ассистента?')) {
chatMessages.innerHTML = '';
messageCounter = 0;
messageCount.textContent = '0';
// Reset model usage
Object.keys(modelUsage).forEach(model => {
modelUsage[model] = 0;
document.querySelector(`.model-item[data-model="${model}"] .model-usage`).textContent = '0';
});
addBotMessage("Память очищена. Начинаем с чистого листа!");
}
}
// Toggle vision system
function toggleVision() {
isVisionActive = !isVisionActive;
const visionCamera = document.querySelector('.vision-camera');
const visionStatus = document.querySelector('.vision-status');
const toggleBtn = document.getElementById('toggle-vision');
if (isVisionActive) {
visionCamera.innerHTML = '<i class="fas fa-video"></i><span>Камера готова</span>';
visionStatus.innerHTML = '<i class="fas fa-circle"></i><span>Готова к распознаванию</span>';
visionStatus.classList.remove('offline');
toggleBtn.innerHTML = '<i class="fas fa-video-slash"></i><span>Отключить Vision</span>';
toggleBtn.classList.add('danger');
addBotMessage("Vision система активирована. Готова к распознаванию лиц.");
} else {
visionCamera.innerHTML = '<i class="fas fa-video-slash"></i><span>Камера отключена</span>';
visionStatus.innerHTML = '<i class="fas fa-circle"></i><span>Система отключена</span>';
visionStatus.classList.add('offline');
toggleBtn.innerHTML = '<i class="fas fa-video"></i><span>Включить Vision</span>';
toggleBtn.classList.remove('danger');
addBotMessage("Vision система отключена. Распознавание лиц недоступно.");
}
}
// Initialize the app
init();
});
</script>
</body>
</html>