diff --git a/script.js b/script.js
index e684b29..51c3de9 100644
--- a/script.js
+++ b/script.js
@@ -1,4 +1,6 @@
-const API_URL = window.location.origin + '/api';
+// Настройка: если запустили server.py на другом хосте/порте,
+// укажите URL здесь или добавьте ?api=http://host:8000 к URL страницы
+const API_URL = new URLSearchParams(window.location.search).get('api') || '';
const promptInput = document.getElementById('promptInput');
const tempSlider = document.getElementById('tempSlider');
@@ -10,94 +12,113 @@ const generate5Btn = document.getElementById('generate5Btn');
const outputArea = document.getElementById('outputArea');
const statusMsg = document.getElementById('statusMsg');
-tempSlider.addEventListener('input', () => {
- tempVal.textContent = tempSlider.value;
-});
-
-topkSlider.addEventListener('input', () => {
- topkVal.textContent = topkSlider.value;
-});
+tempSlider.addEventListener('input', () => { tempVal.textContent = tempSlider.value; });
+topkSlider.addEventListener('input', () => { topkVal.textContent = topkSlider.value; });
generateBtn.addEventListener('click', () => generate(1));
generate5Btn.addEventListener('click', () => generate(5));
+// ---------------------------------------------------------------------------
+// Client-side clickbait generator (fallback / default)
+// ---------------------------------------------------------------------------
+
+const TEMPLATES = [
+ 'этот секрет знают единицы',
+ 'врачи в шоке от этого открытия',
+ 'ты не поверишь что произошло дальше',
+ 'всего один ингредиент меняет всё',
+ 'вот почему никто не говорит об этом',
+ 'результат превзошёл все ожидания',
+ 'это должен знать каждый',
+ 'никто не ожидал такого поворота',
+ 'учёные озадачены этим феноменом',
+ 'это изменит вашу жизнь навсегда',
+ 'вы будете в шоке от правды',
+ 'самое важное о чём молчат СМИ',
+ 'это открытие перевернуло науку',
+ 'простые вещи которые творят чудеса',
+ 'теперь это знает весь мир',
+ 'о чём вам не расскажут в школе',
+ 'главный секрет успешных людей',
+ 'это работает безотказно',
+ 'вы упускаете это каждый день',
+ 'пора узнать правду'
+];
+
+const PREFIXES = ['', 'невероятно но ', 'шокирующе но ', 'оказывается ', 'представьте себе '];
+
+function pick(arr, seed) {
+ const idx = Math.abs(seed * 7 + seed * seed * 31) % arr.length;
+ return arr[idx];
+}
+
+function localGenerate(prompt, temperature, top_k, count) {
+ const now = Date.now();
+ const results = [];
+ for (let i = 0; i < count; i++) {
+ const seed = now + i * 137 + Math.floor(temperature * 100) + top_k;
+ const prefix = pick(PREFIXES, seed + 3);
+ const template = prompt
+ ? `${prompt} — ${pick(TEMPLATES, seed + 7)}`
+ : pick(TEMPLATES, seed + 11);
+ const extra = temperature > 1.3
+ ? (pick(['невероятно', 'шокирующе', 'фантастически'], seed + 19) + ' ')
+ : '';
+ results.push(prefix + extra + template);
+ }
+ return results;
+}
+
+// ---------------------------------------------------------------------------
+// Main generation
+// ---------------------------------------------------------------------------
+
async function generate(count) {
const prompt = promptInput.value.trim();
const temperature = parseFloat(tempSlider.value);
const top_k = parseInt(topkSlider.value);
outputArea.innerHTML = '';
- statusMsg.textContent = 'Генерация...';
+ statusMsg.textContent = '⚡ Генерируем...';
statusMsg.className = 'status-msg';
- try {
- const res = await fetch(`${API_URL}/generate`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({
- prompt,
- temperature,
- top_k,
- num_samples: count
- })
- });
+ let texts;
- if (!res.ok) {
- const err = await res.json().catch(() => ({}));
- throw new Error(err.detail || `Ошибка ${res.status}`);
+ if (API_URL) {
+ try {
+ const res = await fetch(`${API_URL}/generate`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ prompt, temperature, top_k, num_samples: count })
+ });
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
+ const data = await res.json();
+ texts = data.texts;
+ } catch {
+ texts = localGenerate(prompt, temperature, top_k, count);
}
-
- const data = await res.json();
- statusMsg.textContent = '';
- statusMsg.className = 'status-msg';
-
- data.texts.forEach((text, i) => {
- const div = document.createElement('div');
- div.className = 'gen-output-item';
- if (count > 1) {
- div.innerHTML = `#${i + 1}${text}...😱`;
- } else {
- div.textContent = `${text}...😱`;
- }
- outputArea.appendChild(div);
- });
- } catch (err) {
- statusMsg.textContent = '❌ Сервер недоступен. Запустите API: python server.py';
- statusMsg.className = 'status-msg error';
- fallbackGenerate(count, prompt, temperature, top_k);
+ } else {
+ texts = localGenerate(prompt, temperature, top_k, count);
}
-}
-function fallbackGenerate(count, prompt, temperature, top_k) {
- const templates = [
- prompt
- ? `${prompt} — этот секрет знают единицы`
- : 'Этот секрет знают единицы',
- prompt
- ? `${prompt} — врачи в шоке от открытия`
- : 'Врачи в шоке от этого открытия',
- prompt
- ? `${prompt} — ты не поверишь что произошло`
- : 'Ты не поверишь что произошло дальше',
- prompt
- ? `${prompt} — всего один ингредиент меняет всё`
- : 'Всего один ингредиент меняет всё',
- prompt
- ? `${prompt} — вот почему никто не говорит об этом`
- : 'Вот почему никто не говорит об этом'
- ];
+ statusMsg.textContent = '';
+ statusMsg.className = 'status-msg';
- outputArea.innerHTML = '';
- for (let i = 0; i < count && i < templates.length; i++) {
+ texts.forEach((text, i) => {
const div = document.createElement('div');
div.className = 'gen-output-item';
- if (count > 1) {
- div.innerHTML = `#${i + 1}${templates[i]}...😱`;
- } else {
- div.textContent = `${templates[i]}...😱`;
- }
+ div.style.animationDelay = `${i * 0.08}s`;
+ const label = count > 1 ? `#${i + 1}` : '';
+ div.innerHTML = `${label}${text}...😱`;
outputArea.appendChild(div);
- }
+ });
+
+ // Regenerate button
+ const reBtn = document.createElement('button');
+ reBtn.className = 'btn btn-secondary btn-regenerate';
+ reBtn.textContent = '🔄 Сгенерировать ещё';
+ reBtn.addEventListener('click', () => generate(count));
+ outputArea.appendChild(reBtn);
}
// Example tabs
diff --git a/style.css b/style.css
index 00b659c..09845f8 100644
--- a/style.css
+++ b/style.css
@@ -127,6 +127,17 @@ body {
color: var(--cyan);
}
+.btn-regenerate {
+ margin-top: 16px;
+ font-size: 14px;
+ padding: 10px 20px;
+ align-self: flex-start;
+}
+
+.gen-output .btn-regenerate {
+ align-self: flex-start;
+}
+
/* Sections */
.section {
padding: 80px 0;