anycoder-cf2786c3 / index.html
Zhjckfd's picture
Upload folder using huggingface_hub
07fc963 verified
Raw
History Blame Contribute Delete
27.6 kB
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Установка GPT Platform</title>
<!-- Подключение иконок FontAwesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--primary-color: #10a37f; /* OpenAI Green-ish */
--primary-hover: #0d8a6c;
--bg-dark: #0f1115;
--bg-card: #1e2128;
--bg-input: #2d313a;
--text-main: #ececf1;
--text-muted: #9ca3af;
--border-color: #353a45;
--accent-glow: rgba(16, 163, 127, 0.2);
--error-color: #ef4444;
--font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
--font-mono: 'Courier New', Courier, monospace;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: var(--font-family);
background-color: var(--bg-dark);
color: var(--text-main);
display: flex;
flex-direction: column;
min-height: 100vh;
background-image: radial-gradient(circle at 50% 0%, #1a2c26 0%, var(--bg-dark) 60%);
}
/* Header */
header {
padding: 1.5rem 2rem;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid var(--border-color);
background: rgba(15, 17, 21, 0.8);
backdrop-filter: blur(10px);
position: sticky;
top: 0;
z-index: 100;
}
.logo {
font-size: 1.5rem;
font-weight: 700;
display: flex;
align-items: center;
gap: 10px;
color: var(--primary-color);
}
.logo i {
font-size: 1.8rem;
}
.brand-link {
color: var(--text-muted);
text-decoration: none;
font-size: 0.9rem;
transition: color 0.3s;
}
.brand-link:hover {
color: var(--primary-color);
}
/* Main Container */
main {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
padding: 2rem;
}
.installer-container {
width: 100%;
max-width: 900px;
background: var(--bg-card);
border-radius: 16px;
box-shadow: 0 20px 50px rgba(0,0,0,0.5);
border: 1px solid var(--border-color);
overflow: hidden;
display: flex;
flex-direction: column;
min-height: 600px;
position: relative;
}
/* Progress Steps (Top Bar) */
.steps-indicator {
display: flex;
justify-content: space-between;
padding: 2rem 3rem;
border-bottom: 1px solid var(--border-color);
background: rgba(0,0,0,0.2);
}
.step-item {
display: flex;
align-items: center;
gap: 12px;
opacity: 0.5;
transition: all 0.3s ease;
position: relative;
}
.step-item.active {
opacity: 1;
color: var(--primary-color);
}
.step-item.completed {
opacity: 1;
color: var(--primary-color);
}
.step-circle {
width: 32px;
height: 32px;
border-radius: 50%;
background: var(--bg-input);
border: 2px solid var(--border-color);
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 0.9rem;
transition: all 0.3s;
}
.step-item.active .step-circle {
border-color: var(--primary-color);
box-shadow: 0 0 15px var(--accent-glow);
}
.step-item.completed .step-circle {
background: var(--primary-color);
border-color: var(--primary-color);
color: #fff;
}
.step-line {
flex: 1;
height: 2px;
background: var(--border-color);
margin: 0 10px;
}
.step-item.completed + .step-line {
background: var(--primary-color);
}
/* Content Area */
.content-area {
flex: 1;
padding: 3rem;
position: relative;
}
.step-content {
display: none;
animation: fadeIn 0.4s ease forwards;
height: 100%;
flex-direction: column;
}
.step-content.active {
display: flex;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
h2 {
font-size: 2rem;
margin-bottom: 1rem;
color: #fff;
}
p.description {
color: var(--text-muted);
margin-bottom: 2rem;
line-height: 1.6;
}
/* Forms */
.form-group {
margin-bottom: 1.5rem;
}
label {
display: block;
margin-bottom: 0.5rem;
color: var(--text-main);
font-weight: 500;
}
input[type="text"],
input[type="password"],
select {
width: 100%;
padding: 12px 16px;
background: var(--bg-input);
border: 1px solid var(--border-color);
border-radius: 8px;
color: white;
font-size: 1rem;
transition: border-color 0.3s, box-shadow 0.3s;
}
input:focus, select:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px var(--accent-glow);
}
.grid-2 {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.5rem;
}
/* Range Slider */
.range-container {
display: flex;
align-items: center;
gap: 15px;
}
input[type="range"] {
flex: 1;
accent-color: var(--primary-color);
cursor: pointer;
}
.range-value {
font-family: var(--font-mono);
background: var(--bg-input);
padding: 4px 8px;
border-radius: 4px;
min-width: 40px;
text-align: center;
}
/* Terminal / Installation View */
.terminal-window {
background: #0d0e12;
border-radius: 8px;
border: 1px solid #333;
font-family: var(--font-mono);
padding: 1.5rem;
flex: 1;
overflow-y: auto;
max-height: 400px;
display: flex;
flex-direction: column;
gap: 8px;
}
.terminal-line {
color: #ccc;
font-size: 0.9rem;
}
.terminal-line.success { color: var(--primary-color); }
.terminal-line.warning { color: #fbbf24; }
.terminal-line.error { color: var(--error-color); }
.terminal-line.info { color: #60a5fa; }
.progress-bar-container {
height: 6px;
background: var(--bg-input);
border-radius: 3px;
margin-top: 1rem;
overflow: hidden;
}
.progress-bar-fill {
height: 100%;
background: var(--primary-color);
width: 0%;
transition: width 0.1s linear;
}
/* Success View */
.success-view {
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
}
.success-icon {
font-size: 5rem;
color: var(--primary-color);
margin-bottom: 1.5rem;
animation: popIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
@keyframes popIn {
0% { transform: scale(0); opacity: 0; }
100% { transform: scale(1); opacity: 1; }
}
/* Footer Navigation */
.footer-nav {
padding: 1.5rem 3rem;
border-top: 1px solid var(--border-color);
display: flex;
justify-content: space-between;
}
.btn {
padding: 12px 24px;
border-radius: 8px;
border: none;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
display: flex;
align-items: center;
gap: 8px;
}
.btn-secondary {
background: transparent;
color: var(--text-muted);
border: 1px solid var(--border-color);
}
.btn-secondary:hover {
background: rgba(255,255,255,0.05);
color: #fff;
}
.btn-primary {
background: var(--primary-color);
color: white;
}
.btn-primary:hover {
background: var(--primary-hover);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(16, 163, 127, 0.3);
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
transform: none !important;
}
/* Responsive */
@media (max-width: 768px) {
.steps-indicator {
padding: 1rem;
}
.step-text {
display: none;
}
.content-area {
padding: 1.5rem;
}
.grid-2 {
grid-template-columns: 1fr;
}
.footer-nav {
padding: 1rem;
}
.terminal-window {
max-height: 250px;
}
}
</style>
</head>
<body>
<header>
<div class="logo">
<i class="fa-solid fa-brain"></i>
<span>GPT Setup</span>
</div>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="brand-link">
Built with anycoder <i class="fa-solid fa-arrow-up-right-from-square" style="font-size: 0.7em;"></i>
</a>
</header>
<main>
<div class="installer-container">
<!-- Шаги -->
<div class="steps-indicator">
<div class="step-item active" id="indicator-1">
<div class="step-circle">1</div>
<span class="step-text">Приветствие</span>
</div>
<div class="step-line"></div>
<div class="step-item" id="indicator-2">
<div class="step-circle">2</div>
<span class="step-text">Конфигурация</span>
</div>
<div class="step-line"></div>
<div class="step-item" id="indicator-3">
<div class="step-circle">3</div>
<span class="step-text">Установка</span>
</div>
<div class="step-line"></div>
<div class="step-item" id="indicator-4">
<div class="step-circle">4</div>
<span class="step-text">Готово</span>
</div>
</div>
<!-- Контент -->
<div class="content-area">
<!-- Шаг 1: Приветствие -->
<div class="step-content active" id="step-1">
<h2>Добро пожаловать в GPT Platform</h2>
<p class="description">
Этот мастер поможет вам настроить локальную среду для работы с моделями GPT.
Мы настроим параметры ядра, подключим API ключи и подготовим нейросеть к работе.
</p>
<div style="background: rgba(16, 163, 127, 0.1); border: 1px solid var(--primary-color); padding: 1.5rem; border-radius: 8px; margin-bottom: 1rem;">
<h3 style="color: var(--primary-color); font-size: 1.1rem; margin-bottom: 0.5rem;"><i class="fa-solid fa-check-circle"></i> Что будет установлено:</h3>
<ul style="margin-left: 1.5rem; color: var(--text-muted);">
<li>GPT-4 Turbo Core Engine</li>
<li>Модули обработки естественного языка (NLP)</li>
<li>Локальный векторный базис данных</li>
<li>Плагин безопасности</li>
</ul>
</div>
</div>
<!-- Шаг 2: Конфигурация -->
<div class="step-content" id="step-2">
<h2>Настройка параметров</h2>
<p class="description">Введите данные для подключения к API или выберите локальный режим.</p>
<div class="form-group">
<label>API OpenAI Key</label>
<div style="position: relative;">
<input type="password" id="api-key" placeholder="sk-..." autocomplete="off">
<i class="fa-solid fa-eye" style="position: absolute; right: 15px; top: 14px; color: var(--text-muted); cursor: pointer;" onclick="togglePassword()"></i>
</div>
<p style="font-size: 0.8rem; color: var(--text-muted); margin-top: 5px;">Оставьте пустым для использования локальных моделей.</p>
</div>
<div class="grid-2">
<div class="form-group">
<label>Модель по умолчанию</label>
<select id="model-select">
<option value="gpt-4">GPT-4 (Omni)</option>
<option value="gpt-3.5">GPT-3.5 Turbo</option>
<option value="local">Llama 3 (Local)</option>
</select>
</div>
<div class="form-group">
<label>Макс. токены</label>
<input type="text" value="4096" id="max-tokens">
</div>
</div>
<div class="form-group">
<label>Температура (Креативность): <span id="temp-val" class="range-value">0.7</span></label>
<div class="range-container">
<span style="font-size: 0.8rem; color: var(--text-muted);">Точный</span>
<input type="range" min="0" max="2" step="0.1" value="0.7" oninput="document.getElementById('temp-val').innerText = this.value">
<span style="font-size: 0.8rem; color: var(--text-muted);">Креативный</span>
</div>
</div>
</div>
<!-- Шаг 3: Установка -->
<div class="step-content" id="step-3">
<h2>Установка системы</h2>
<p class="description">Пожалуйста, подождите, пока компоненты системы загружаются и настраиваются.</p>
<div class="terminal-window" id="terminal">
<div class="terminal-line info">> Инициализация мастера установки...</div>
</div>
<div class="progress-bar-container">
<div class="progress-bar-fill" id="progress-fill"></div>
</div>
<div style="text-align: right; margin-top: 5px; font-size: 0.8rem; color: var(--text-muted);">
<span id="progress-text">0%</span>
</div>
</div>
<!-- Шаг 4: Готово -->
<div class="step-content" id="step-4">
<div class="success-view">
<i class="fa-solid fa-circle-check success-icon"></i>
<h2>Установка завершена!</h2>
<p class="description">
Платформа GPT успешно установлена и настроена.
Теперь вы можете начать создавать новые проекты.
</p>
<div style="display: flex; gap: 1rem;">
<button class="btn btn-secondary" onclick="location.reload()">
<i class="fa-solid fa-rotate-left"></i> Сбросить
</button>
<button class="btn btn-primary" onclick="launchDashboard()">
Перейти к панели <i class="fa-solid fa-arrow-right"></i>
</button>
</div>
</div>
</div>
</div>
<!-- Навигация -->
<div class="footer-nav" id="footer-nav">
<button class="btn btn-secondary" id="btn-back" onclick="changeStep(-1)" disabled>
Назад
</button>
<button class="btn btn-primary" id="btn-next" onclick="changeStep(1)">
Далее <i class="fa-solid fa-chevron-right"></i>
</button>
</div>
</div>
</main>
<script>
let currentStep = 1;
const totalSteps = 4;
function changeStep(direction) {
const nextStep = currentStep + direction;
if (nextStep < 1 || nextStep > totalSteps) return;
// Валидация перед переходом на шаг 3 (Установка)
if (nextStep === 3) {
if (!validateConfig()) return;
startInstallation();
}
// Обновляем UI
updateUI(nextStep);
currentStep = nextStep;
}
function updateUI(step) {
// Скрываем все шаги
document.querySelectorAll('.step-content').forEach(el => el.classList.remove('active'));
// Показываем текущий
document.getElementById(`step-${step}`).classList.add('active');
// Обновляем индикаторы сверху
document.querySelectorAll('.step-item').forEach((el, index) => {
const stepNum = index + 1;
el.classList.remove('active', 'completed');
if (stepNum === step) {
el.classList.add('active');
} else if (stepNum < step) {
el.classList.add('completed');
// Меняем цифру на галочку для завершенных шагов
el.querySelector('.step-circle').innerHTML = '<i class="fa-solid fa-check"></i>';
} else {
el.querySelector('.step-circle').innerText = stepNum;
}
});
// Управление кнопками
const btnBack = document.getElementById('btn-back');
const btnNext = document.getElementById('btn-next');
const footerNav = document.getElementById('footer-nav');
btnBack.disabled = step === 1 || step === 3; // Назад нельзя на 1 шаге и во время установки
if (step === 4) {
footerNav.style.display = 'none'; // Скрываем кнопки на финальном экране
} else if (step === 3) {
btnNext.disabled = true;
btnNext.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> Установка...';
} else {
footerNav.style.display = 'flex';
btnNext.disabled = false;
btnNext.innerHTML = step === 2 ? 'Начать установку <i class="fa-solid fa-download"></i>' : 'Далее <i class="fa-solid fa-chevron-right"></i>';
}
}
function togglePassword() {
const input = document.getElementById('api-key');
const icon = document.querySelector('.fa-eye');
if (input.type === "password") {
input.type = "text";
icon.classList.remove('fa-eye');
icon.classList.add('fa-eye-slash');
} else {
input.type = "password";
icon.classList.remove('fa-eye-slash');
icon.classList.add('fa-eye');
}
}
function validateConfig() {
const apiKey = document.getElementById('api-key').value;
const model = document.getElementById('model-select').value;
// Простая проверка: если выбран облачный режим, нужен ключ
if (model !== 'local' && apiKey.length < 5) {
// Визуальная индикация ошибки без alert()
const input = document.getElementById('api-key');
input.style.borderColor = 'var(--error-color)';
input.focus();
// Добавляем сообщение об ошибке
let msg = document.getElementById('error-msg');
if (!msg) {
msg = document.createElement('p');
msg.id = 'error-msg';
msg.style.color = 'var(--error-color)';
msg.style.fontSize = '0.8rem';
msg.style.marginTop = '5px';
input.parentNode.after(msg);
}
msg.innerText = 'Пожалуйста, введите корректный API Key для облачной модели.';
setTimeout(() => {
input.style.borderColor = 'var(--border-color)';
if(msg) msg.remove();
}, 3000);
return false;
}
return true;
}
// Имитация процесса установки
function startInstallation() {
const terminal = document.getElementById('terminal');
const progressFill = document.getElementById('progress-fill');
const progressText = document.getElementById('progress-text');
const logs = [
{ msg: "Проверка системных требований...", type: "info", delay: 500 },
{ msg: "ОК: CPU (8 cores), RAM (32GB) обнаружены.", type: "success", delay: 800 },
{ msg: "Загрузка базовых зависимостей Python...", type: "info", delay: 1500 },
{ msg: "Установка torch (CUDA 12.1)...", type: "warning", delay: 2500 },
{ msg: "Установка transformers...", type: "info", delay: 3000 },
{ msg: "Настройка модели: " + document.getElementById('model-select').value, type: "info", delay: 3500 },
{ msg: "Инициализация токенизатора...", type: "info", delay: 4000 },
{ msg: "Загрузка весов модели (это может занять время)...", type: "warning", delay: 5000 },
{ msg: "Оптимизация графического процессора...", type: "info", delay: 7000 },
{ msg: "Настройка векторной базы данных...", type: "info", delay: 8000 },
{ msg: "Запуск сервисов...", type: "info", delay: 9000 },
{ msg: "SUCCESS: Система готова к работе.", type: "success", delay: 10000 }
];
let startTime = Date.now();
let totalDuration = 10000; // 10 секунд общее время
// Таймер для обновления прогресс-бара
const progressInterval = setInterval(() => {
let elapsed = Date.now() - startTime;
let percent = Math.min(100, Math.floor((elapsed / totalDuration) * 100));
progressFill.style.width = percent + '%';
progressText.innerText = percent + '%';
if (elapsed >= totalDuration) {
clearInterval(progressInterval);
// Завершаем установку
setTimeout(() => {
changeStep(1);
}, 1000);
}
}, 100);
// Вывод логов
logs.forEach(log => {
setTimeout(() => {
addLog(log.msg, log.type);
}, log.delay);
});
}
function addLog(text, type) {
const terminal = document.getElementById('terminal');
const div = document.createElement('div');
div.className = `terminal-line ${type}`;
// Добавляем временную метку
const time = new Date().toLocaleTimeString('ru-RU', { hour12: false });
div.innerText = `[${time}] ${text}`;
terminal.appendChild(div);
terminal.scrollTop = terminal.scrollHeight; // Автопрокрутка вниз
}
function launchDashboard() {
// Имитация перехода
const btn = event.currentTarget;
btn.innerHTML = '<i class="fa-solid fa-circle-notch fa-spin"></i> Загрузка...';
setTimeout(() => {
// В реальном приложении здесь был бы редирект
document.querySelector('.success-view h2').innerText = "Перенаправление...";
document.querySelector('.success-view p').innerText = "Добро пожаловать в панель управления GPT.";
btn.style.display = 'none';
}, 1500);
}
</script>
</body>
</html>