anycoder-c0dd29b1 / index.html
HI7RAI's picture
Upload folder using huggingface_hub
f13315a verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GGFU Model Chat Interface</title>
<style>
/* --- CSS Variables & Reset --- */
:root {
--bg-body: #343541;
--bg-sidebar: #202123;
--bg-input: #40414f;
--text-primary: #ececf1;
--text-secondary: #c5c5d2;
--accent-color: #10a37f;
--accent-hover: #1a7f64;
--border-color: #4d4d4f;
--user-bubble: #343541;
--bot-bubble: #444654;
--shadow: 0 0 10px rgba(0,0,0,0.1);
--font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
--transition: all 0.3s ease;
}
[data-theme="light"] {
--bg-body: #ffffff;
--bg-sidebar: #f7f7f8;
--bg-input: #ffffff;
--text-primary: #374151;
--text-secondary: #6b7280;
--accent-color: #10a37f;
--accent-hover: #0d8a6a;
--border-color: #e5e7eb;
--user-bubble: #ffffff;
--bot-bubble: #f7f7f8;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: var(--font-family);
background-color: var(--bg-body);
color: var(--text-primary);
height: 100vh;
display: flex;
overflow: hidden;
font-size: 16px;
line-height: 1.5;
}
/* --- Layout --- */
.app-container {
display: flex;
width: 100%;
height: 100%;
position: relative;
}
/* --- Sidebar --- */
.sidebar {
width: 260px;
background-color: var(--bg-sidebar);
display: flex;
flex-direction: column;
padding: 10px;
transition: transform 0.3s ease;
z-index: 100;
border-right: 1px solid var(--border-color);
}
.new-chat-btn {
display: flex;
align-items: center;
gap: 10px;
padding: 12px;
border: 1px solid var(--border-color);
border-radius: 5px;
background: transparent;
color: var(--text-primary);
cursor: pointer;
transition: var(--transition);
text-align: left;
font-size: 0.9rem;
margin-bottom: 20px;
}
.new-chat-btn:hover {
background-color: rgba(255, 255, 255, 0.05);
}
.history-list {
flex: 1;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 5px;
}
.history-item {
padding: 10px;
border-radius: 5px;
cursor: pointer;
color: var(--text-secondary);
font-size: 0.9rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: flex;
align-items: center;
gap: 10px;
}
.history-item:hover {
background-color: rgba(255, 255, 255, 0.05);
}
.sidebar-footer {
border-top: 1px solid var(--border-color);
padding-top: 10px;
margin-top: 10px;
}
.menu-item {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
cursor: pointer;
border-radius: 5px;
color: var(--text-primary);
font-size: 0.9rem;
}
.menu-item:hover {
background-color: rgba(255, 255, 255, 0.05);
}
/* --- Main Chat Area --- */
.main-content {
flex: 1;
display: flex;
flex-direction: column;
position: relative;
background-color: var(--bg-body);
}
.header {
padding: 10px 20px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid var(--border-color);
background-color: var(--bg-body);
}
.model-selector {
font-weight: 600;
display: flex;
align-items: center;
gap: 5px;
cursor: pointer;
padding: 5px 10px;
border-radius: 5px;
}
.model-selector:hover {
background-color: rgba(0,0,0,0.05);
}
.mobile-menu-btn {
display: none;
background: none;
border: none;
color: var(--text-primary);
cursor: pointer;
}
.anycoder-link {
font-size: 0.8rem;
color: var(--text-secondary);
text-decoration: none;
transition: color 0.2s;
}
.anycoder-link:hover {
color: var(--accent-color);
}
.chat-container {
flex: 1;
overflow-y: auto;
padding-bottom: 120px; /* Space for input */
scroll-behavior: smooth;
}
/* --- Messages --- */
.message-row {
display: flex;
padding: 24px 0;
border-bottom: 1px solid rgba(0,0,0,0.05);
width: 100%;
}
.message-row.bot {
background-color: var(--bot-bubble);
}
.message-content-wrapper {
display: flex;
gap: 20px;
max-width: 800px;
margin: 0 auto;
width: 100%;
padding: 0 20px;
}
.avatar {
width: 30px;
height: 30px;
border-radius: 2px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.avatar.user {
background-color: #5436DA;
}
.avatar.bot {
background-color: var(--accent-color);
}
.message-text {
flex: 1;
font-size: 1rem;
line-height: 1.6;
word-wrap: break-word;
}
.message-text p {
margin-bottom: 10px;
}
.message-text p:last-child {
margin-bottom: 0;
}
/* Code Block Styling */
pre {
background-color: #000;
color: #fff;
padding: 15px;
border-radius: 5px;
overflow-x: auto;
margin: 10px 0;
font-family: 'Courier New', Courier, monospace;
font-size: 0.9rem;
}
code {
font-family: 'Courier New', Courier, monospace;
background-color: rgba(0,0,0,0.1);
padding: 2px 4px;
border-radius: 3px;
}
pre code {
background-color: transparent;
padding: 0;
}
/* --- Input Area --- */
.input-container {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
background-image: linear-gradient(180deg, rgba(53,53,65,0), var(--bg-body) 20%);
padding: 20px;
display: flex;
justify-content: center;
}
.input-box-wrapper {
position: relative;
width: 100%;
max-width: 800px;
background-color: var(--bg-input);
border: 1px solid var(--border-color);
border-radius: 12px;
box-shadow: var(--shadow);
display: flex;
flex-direction: column;
}
textarea {
width: 100%;
background: transparent;
border: none;
color: var(--text-primary);
font-family: inherit;
font-size: 1rem;
padding: 12px 45px 12px 15px; /* Right padding for button */
resize: none;
max-height: 200px;
outline: none;
overflow-y: hidden;
border-radius: 12px;
}
.send-btn {
position: absolute;
bottom: 8px;
right: 8px;
background-color: transparent;
border: none;
color: var(--text-secondary);
padding: 5px;
border-radius: 5px;
cursor: pointer;
transition: var(--transition);
}
.send-btn:hover {
background-color: var(--bg-body);
color: var(--accent-color);
}
.send-btn.active {
color: var(--accent-color);
}
.disclaimer {
text-align: center;
font-size: 0.75rem;
color: var(--text-secondary);
margin-top: 10px;
opacity: 0.7;
}
/* --- Typing Indicator --- */
.typing-indicator {
display: flex;
align-items: center;
gap: 5px;
padding: 10px 0;
}
.dot {
width: 8px;
height: 8px;
background-color: var(--text-secondary);
border-radius: 50%;
animation: bounce 1.4s infinite ease-in-out both;
}
.dot:nth-child(1) { animation-delay: -0.32s; }
.dot:nth-child(2) { animation-delay: -0.16s; }
@keyframes bounce {
0%, 80%, 100% { transform: scale(0); }
40% { transform: scale(1); }
}
/* --- Responsive Design --- */
@media (max-width: 768px) {
.sidebar {
position: absolute;
height: 100%;
transform: translateX(-100%);
box-shadow: 2px 0 10px rgba(0,0,0,0.5);
}
.sidebar.open {
transform: translateX(0);
}
.mobile-menu-btn {
display: block;
}
.message-content-wrapper {
padding: 0 10px;
gap: 10px;
}
}
/* Icons */
svg {
width: 20px;
height: 20px;
fill: currentColor;
}
</style>
</head>
<body>
<div class="app-container">
<!-- Sidebar -->
<aside class="sidebar" id="sidebar">
<button class="new-chat-btn" onclick="startNewChat()">
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
New chat
</button>
<div class="history-list" id="historyList">
<!-- History items will be injected here -->
<div class="history-item">
<svg viewBox="0 0 24 24" style="margin-right: 5px;"><path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 9h12v2H6V9zm8 5H6v-2h8v2zm4-6H6V6h12v2z"/></svg>
Previous Conversation 1
</div>
<div class="history-item">
<svg viewBox="0 0 24 24" style="margin-right: 5px;"><path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 9h12v2H6V9zm8 5H6v-2h8v2zm4-6H6V6h12v2z"/></svg>
GGFU Code Generation
</div>
</div>
<div class="sidebar-footer">
<div class="menu-item" onclick="clearChat()">
<svg viewBox="0 0 24 24"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>
Clear conversations
</div>
<div class="menu-item" onclick="toggleTheme()">
<svg viewBox="0 0 24 24"><path d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-3.03 0-5.5-2.47-5.5-5.5 0-1.82.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1z"/></svg>
<span id="themeText">Light mode</span>
</div>
</div>
</aside>
<!-- Main Content -->
<main class="main-content">
<header class="header">
<button class="mobile-menu-btn" onclick="toggleSidebar()">
<svg viewBox="0 0 24 24"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/></svg>
</button>
<div class="model-selector">
GGFU-4 <span style="font-size: 0.8em; opacity: 0.7;"></span>
</div>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">
Built with anycoder
</a>
</header>
<div class="chat-container" id="chatContainer">
<!-- Welcome Message -->
<div class="message-row bot">
<div class="message-content-wrapper">
<div class="avatar bot">
<svg viewBox="0 0 24 24" style="fill: white;"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/></svg>
</div>
<div class="message-text">
<p>Hello! I am GGFU, a simulated AI model. How can I help you today?</p>
</div>
</div>
</div>
</div>
<div class="input-container">
<div class="input-box-wrapper">
<textarea id="userInput" rows="1" placeholder="Send a message..." oninput="autoResize(this)" onkeydown="handleEnter(event)"></textarea>
<button class="send-btn" id="sendBtn" onclick="sendMessage()">
<svg viewBox="0 0 24 24"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>
</button>
</div>
<div class="disclaimer">
GGFU may produce inaccurate information about people, places, or facts.
</div>
</div>
</main>
</div>
<script>
/* --- State & Configuration --- */
const chatContainer = document.getElementById('chatContainer');
const userInput = document.getElementById('userInput');
const sendBtn = document.getElementById('sendBtn');
const sidebar = document.getElementById('sidebar');
let isGenerating = false;
let isDarkMode = true;
/* --- Event Listeners --- */
userInput.addEventListener('input', () => {
sendBtn.classList.toggle('active', userInput.value.trim().length > 0);
});
/* --- Core Functions --- */
function autoResize(textarea) {
textarea.style.height = 'auto';
textarea.style.height = Math.min(textarea.scrollHeight, 200) + 'px';
}
function handleEnter(e) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
sendMessage();
}
}
function toggleSidebar() {
sidebar.classList.toggle('open');
}
function toggleTheme() {
isDarkMode = !isDarkMode;
document.documentElement.setAttribute('data-theme', isDarkMode ? 'dark' : 'light');
document.getElementById('themeText').textContent = isDarkMode ? 'Light mode' : 'Dark mode';
}
function scrollToBottom() {
chatContainer.scrollTop = chatContainer.scrollHeight;
}
function startNewChat() {
// Remove all messages except the first welcome message (simplified for demo)
// In a real app, this would reset state and save current chat to history
const messages = document.querySelectorAll('.message-row');
messages.forEach((msg, index) => {
if (index > 0) msg.remove();
});
if (window.innerWidth <= 768) toggleSidebar();
}
function clearChat() {
const messages = document.querySelectorAll('.message-row');
messages.forEach((msg, index) => {
msg.remove();
});
// Re-add welcome message
const welcomeHTML = `
<div class="message-row bot">
<div class="message-content-wrapper">
<div class="avatar bot">
<svg viewBox="0 0 24 24" style="fill: white;"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/></svg>
</div>
<div class="message-text">
<p>Chat cleared. Ready for a new topic!</p>
</div>
</div>
</div>`;
chatContainer.innerHTML = welcomeHTML;
if (window.innerWidth <= 768) toggleSidebar();
}
/* --- Message Handling --- */
function appendMessage(role, text) {
const row = document.createElement('div');
row.className = `message-row ${role}`;
const avatarSVG = role === 'user'
? '<svg viewBox="0 0 24 24" style="fill: white;"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>'
: '<svg viewBox="0 0 24 24" style="fill: white;"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/></svg>';
row.innerHTML = `
<div class="message-content-wrapper">
<div class="avatar ${role}">${avatarSVG}</div>
<div class="message-text">${role === 'user' ? escapeHtml(text) : ''}</div>
</div>
`;
chatContainer.appendChild(row);
scrollToBottom();
return row.querySelector('.message-text');
}
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
/* --- Simulation Logic --- */
function sendMessage() {
const text = userInput.value.trim();
if (!text || isGenerating) return;
// Add User Message
appendMessage('user', text);
userInput.value = '';
userInput.style.height = 'auto';
sendBtn.classList.remove('active');
// Simulate Bot State
isGenerating = true;
const loadingRow = document.createElement('div');
loadingRow.className = 'message-row bot';
loadingRow.innerHTML = `
<div class="message-content-wrapper">
<div class="avatar bot">
<svg viewBox="0 0 24 24" style="fill: white;"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/></svg>
</div>
<div class="message-text">
<div class="typing-indicator">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
</div>
</div>
`;
chatContainer.appendChild(loadingRow);
scrollToBottom();
// Simulate Network Delay & Response Generation
setTimeout(() => {
loadingRow.remove();
const messageElement = appendMessage('bot', '');
const responseText = generateSimulatedResponse(text);
typeWriter(responseText, messageElement);
}, 1000 + Math.random() * 1000);
}
function generateSimulatedResponse(input) {
const lowerInput = input.toLowerCase();
// Simple heuristic logic for simulation
if (lowerInput.includes('hello') || lowerInput.includes('hi')) {
return "Hello! I'm the GGFU simulation model. I'm ready to assist you with coding, writing, or analysis.";
}
if (lowerInput.includes('code') || lowerInput.includes('function') || lowerInput.includes('html')) {
return "Here is a simple example of a JavaScript function you might find useful:\n\n```javascript\nfunction greet(name) {\n return `Hello, ${name}!`;\n}\n\nconsole.log(greet('User'));\n```\n\nLet me know if you need any specific logic implemented!";
}
if (lowerInput.includes('removr')) {
return "The Removr simulation is active. I am processing your request to simulate real-time interactions as per the GGFU model parameters.";
}
if (lowerInput.includes('who are you')) {
return "I am a simulated AI interface designed to demonstrate advanced CSS and JavaScript capabilities in a single HTML file.";
}
// Generic lorem ipsum generator for other queries
return "That's an interesting point. As a simulated model, I can tell you that modern web development relies heavily on three pillars: **HTML** for structure, **CSS** for styling, and **JavaScript** for interactivity. \n\nIs there anything specific about these technologies you'd like to explore?";
}
function typeWriter(text, element) {
let index = 0;
// Simple parsing for code blocks to render them correctly progressively
// For a real simulation, we'd parse markdown tokens, but here we just stream text
// and do a post-process or simple check.
// Check if response contains code block
const hasCode = text.includes('```');
function type() {
if (index < text.length) {
// Handle newline
if (text.charAt(index) === '\n') {
element.innerHTML += '<br>';
} else {
element.innerHTML += text.charAt(index);
}
index++;
scrollToBottom();
// Random typing speed variation
setTimeout(type, 10 + Math.random() * 20);
} else {
// Finished typing
if (hasCode) {
// Apply basic formatting after typing is done for simplicity in this demo
formatMarkdown(element);
}
isGenerating = false;
}
}
type();
}
function formatMarkdown(element) {
let html = element.innerHTML;
// Replace ```code``` with <pre><code>code</code></pre>
// Note: This is a very basic regex for demonstration
html = html.replace(/```(.*?)\n([\s\S]*?)```/g, function(match, lang, code) {
return `<pre><code>${code.trim()}</code></pre>`;
});
// Bold **text**
html = html.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
element.innerHTML = html;
}
</script>
</body>
</html>