'use strict';
/* ═══════════════════════════════════════════════════════════════
Генератор паролей по фразам — 5 класс
Пароль = 6 букв (первые буквы 6 слов) + цифра + спецсимвол
Цифра встаёт сразу после буквы, соответствующей числительному.
═══════════════════════════════════════════════════════════════ */
// ── 100 фраз. Формат: 6 слов + цифра после числительного + спецсимвол.
const PHRASES = [
// ─── Русские народные сказки ───
'Три 3 Поросёнка Строят Крепкий Дом Дружно !',
'Волк С Семью 7 Козлятами Поёт Песню !',
'Курочка Ряба Снесла Одно 1 Золотое Яичко !',
'Колобок Убежал От Двух 2 Стариков Вместе !',
'Теремок Построили Шесть 6 Зверей Дружно Вместе !',
'Три 3 Медведя Живут В Домике Лесном !',
'Два 2 Мороза Спорят Кто Сильнее Зимой !',
'Маша С Медведем Дружат Очень Крепко Вдвоём 2 !',
'Репку Тянут Дедом Бабкой Внучкой Одну 1 !',
'Лиса Крадёт Петушка Обманом Ночью Один 1 !',
'Журавль С Лисой Дружат Очень Плохо Двое 2 !',
'Ёжик С Зайцем Дружат Возле Норки Двое 2 !',
'Иван Царевич Ищет Одну 1 Василису Долго !',
'Кощей Прячет Смерть В Одном 1 Яйце !',
'Баба Яга Живёт В Одной 1 Избушке Курьей !',
'Змей Горыныч Имеет Три 3 Головы Огненных !',
'Илья Муромец Побеждает Трёх 3 Врагов Родины !',
'Алёша Попович Спасает Одну 1 Любаву Храбро !',
'Добрыня Никитич Бьёт Змея Одним 1 Ударом !',
'Василиса Премудрая Учит Одного 1 Ивана Уму !',
// ─── Советские мультфильмы ───
'Чебурашка Ест Три 3 Апельсина Очень Радостно !',
'Крокодил Гена Играет На Одной 1 Гармошке Друзьям !',
'Старуха Шапокляк Вредит С Одной 1 Крыской Ловко !',
'Карлсон Съел Пять 5 Плюшек За Минуту !',
'Малыш Мечтает Об Одной 1 Собаке Очень Сильно !',
'Фрекен Бок Печёт Пять 5 Плюшек Для Малыша !',
'Винни Пух Идёт К Одному 1 Кролику Утром !',
'Пятачок Дарит Один 1 Шарик Ослу Празднично !',
'Ослик Иа Ищет Один 1 Хвостик Очень Грустно !',
'Кролик Вырастил Одну 1 Морковку В Огороде !',
'Сова Рассказывает Пять 5 Историй Всем Вечером !',
'Тигра Прыгает Высоко Пяти 5 Друзьям Радостно !',
'Кенга Носит Одну 1 Крошку В Кармане Бережно !',
'Маша Печёт Два 2 Пирога Медведю Каждое Утро !',
'Один 1 Медведь Спит В Берлоге Всю Зиму !',
// ─── Смешарики ───
'Два 2 Друга Крош С Ёжиком Бегают Вместе !',
'Ёжик Собирает Пять 5 Грибов И Листья Осенью !',
'Нюша Наряжается В Одно 1 Платье Красивое !',
'Копатыч Работает В Огороде Уже Один 1 День !',
'Совунья Лечит Пять 5 Друзей Мудрыми Советами !',
'Пин Чинит Два 2 Прибора Внутри Домика Ловко !',
'Бараш Сочиняет Три 3 Стиха Про Нюшу !',
// ─── Фиксики ───
'Симка Учит Нолика Двум 2 Правилам Терпеливо !',
'Фиксики Чинят Технику Внутри Трёх 3 Приборов !',
'Дим Димыч Дружит С Двумя 2 Фиксиками Дома !',
'Один 1 Нолик Прыгает В Проводах И Путается !',
// ─── Лунтик ───
'Один 1 Лунтик Родился На Луне И Упал !',
'Кузя Бегает С Одним 1 Сачком По Лугу !',
'Мила Улыбается Пяти 5 Друзьям Возле Пруда !',
'Пчелёнок Учит Лунтика Двум 2 Правилам Дружбы !',
'Корней Корнеич Выращивает Три 3 Корня Подряд !',
// ─── Гарри Поттер ───
'Гарри Поттер Летит На Одной 1 Метле В Хогвартс !',
'Гермиона Читает Пять 5 Книг В Библиотеке !',
'Рон Играет С Двумя 2 Друзьями В Шахматы !',
'Хагрид Выращивает Трёх 3 Драконов В Хижине !',
'Дамблдор Ищет Семь 7 Крестражей В Пещере !',
'Снейп Варит Одно 1 Зелье В Подземелье Хмуро !',
'Хогвартс Имеет Четыре 4 Факультета Очень Древних !',
// ─── Нарния ───
'Люси Входит В Нарнию Через Один 1 Шкаф !',
'Эдмунд Предаёт Родных За Три 3 Сладости !',
'Питер Сражается С Одним 1 Волком Храбро Смело !',
'Сьюзен Стреляет Из Лука Одной 1 Стрелой Точно !',
'Аслан Правит Одной 1 Нарнией Мудро Долго !',
// ─── Хоббит и Властелин колец ───
'Бильбо Находит Одно 1 Кольцо В Пещере !',
'Гэндальф Стучит Посохом Три 3 Раза Громко !',
'Фродо Несёт Одно 1 Кольцо В Мордор Долго !',
'Сэм Помогает Одному 1 Другу В Трудный Час !',
'Голлум Прячет Кольцо В Одной 1 Пещере Долго !',
'Гномы Поют Одну 1 Песню Про Гору Синеву !',
// ─── Мэри Поппинс ───
'Мэри Поппинс Летает С Одним 1 Зонтом Ветром !',
'Джейн Майкл Учатся Двум 2 Правилам У Няни !',
// ─── Симпсоны ───
'Барт Катается На Скейте У Одной 1 Школы !',
'Гомер Ест Пять 5 Пончиков И Спит Диване !',
'Лиза Играет На Одном 1 Саксофоне В Оркестре !',
'Мардж Воспитывает Трёх 3 Детей С Терпением !',
// ─── Том и Джерри ───
'Том С Джерри Бегают По Дому Шумно Двое 2 !',
'Чип С Дейлом Спешат На Помощь Двум 2 !',
// ─── Ну, погоди! ───
'Волк Гонится За Одним 1 Зайцем Очень Долго !',
'Заяц Прячется От Одного 1 Волка В Кустах !',
// ─── Кот Леопольд ───
'Кот Леопольд Терпит Двух 2 Мышей Возле Дома !',
// ─── Простоквашино ───
'Матроскин Заводит Одну 1 Корову Мурку Деревне !',
'Шарик Делает Фотографии На Одну 1 Камеру Ловко !',
'Дядя Фёдор Ищет Один 1 Клад Возле Дома !',
'Печкин Разносит Два 2 Письма В Простоквашино !',
'Галчонок Хватайка Прячет Одну 1 Вещь В Доме !',
// ─── Бременские музыканты ───
'Музыканты Идут В Город Петь Песни Вчетвером 4 !',
'Осёл Собака Кот Петух Дружат Крепко Вчетвером 4 !',
'Трубадур Поёт Одну 1 Серенаду Принцессе Балконе !',
'Принцесса Убегает С Одним 1 Трубадуром Ночью !',
'Атаманша Прячется С Тремя 3 Разбойниками Пещере !',
// ─── Дюймовочка ───
'Дюймовочка Родилась В Одном 1 Красивом Цветке !',
'Жаба Крадёт Одну 1 Дюймовочку На Кувшинке Утром !',
// ─── Холодное сердце ───
'Эльза Строит Один 1 Ледяной Замок В Горах !',
'Анна Ищет Одну 1 Сестру В Лесу Кристофом !',
'Олаф Любит Лето И Одни 1 Тёплые Объятия !',
'Свен Помогает Кристофу Собирать Лёд Дважды 2 !',
// ─── Король Лев ───
'Симба Правит Одним 1 Прайдом Мудро Смело !',
'Муфаса Учит Одного 1 Сына Быть Храбрым Вождём !',
'Скар Плетёт Одну 1 Кознь Против Брата Всегда !',
'Тимон С Пумбой Спасают Одного 1 Симбу Вместе !',
// ─── Моана ───
'Моана Плывёт По Океану К Одному 1 Острову !',
'Мауи Помогает Одной 1 Девушке Вернуть Сердце !',
// ─── Как приручить дракона ───
'Иккинг Учится Дружить С Одним 1 Драконом Беззубиком !',
'Беззубик Летает Высоко Над Морем Каждый Вечер !',
'Астрид Тренируется С Одним 1 Иккингом Очень Усердно !',
// ─── Детские книги ───
'Пеппи Длинныйчулок Живёт В Одной 1 Вилле Курице !',
'Том Сойер Красит Забор Вместо Одного 1 Друга !',
'Гекльберри Финн Плывёт По Миссисипи На Плоту !',
'Джинн Исполняет Три 3 Желания Аладдину Быстро !',
'Аладдин Находит Одну 1 Волшебную Лампу Пещере !',
'Маугли Дружит С Тремя 3 Волками В Джунглях !',
'Багира Учит Маугли Трём 3 Законам Джунглей !',
'Питер Пэн Летает Над Нетландией С Одной 1 Феей !',
'Алиса Падает В Одну 1 Нору За Кроликом !',
'Шляпник Пьёт Чай С Двумя 2 Друзьями Всегда !',
];
// ── Посимвольная транслитерация русских букв в латиницу (1:1) ──
const TRANSLIT = {
'а':'a','б':'b','в':'v','г':'g','д':'d','е':'e','ё':'e','ж':'z','з':'z',
'и':'i','й':'y','к':'k','л':'l','м':'m','н':'n','о':'o','п':'p','р':'r',
'с':'s','т':'t','у':'u','ф':'f','х':'h','ц':'c','ч':'c','ш':'s','щ':'s',
'ъ':'','ы':'y','ь':'','э':'e','ю':'u','я':'a'
};
function translitChar(ch) {
const lower = ch.toLowerCase();
return TRANSLIT[lower] || '';
}
// ── Числительные в разных падежных формах ──────────────────
// Используется в renderPhrase, чтобы подсветить их так же,
// как и цифру, стоящую рядом.
const NUM_WORDS = new Set([
// 1 — один
'один','одна','одно','одну','одной','одного','одному','одним','одном',
'одни','одних','одними','одною',
// 2 — два
'два','две','двух','двум','двумя','двоих','двоим','двоими','вдвоём','вдвоем',
// 3 — три
'три','трёх','трём','тремя','трое','троих','троим','троими','втроём','втроем',
// 4 — четыре
'четыре','четырёх','четырём','четырьмя','четверо','четверых','четверым','четверыми','вчетвером',
// 5 — пять
'пять','пяти','пятью','пятеро','пятерых','пятерым','пятерыми','впятером',
// 6 — шесть
'шесть','шести','шестью','шестеро','шестерых','шестерым','шестерыми','вшестером',
// 7 — семь
'семь','семи','семью','семеро','семерых','семерым','семерыми','всемером',
// 8 — восемь
'восемь','восьми','восемью','восьмеро','восьмерых','восьмерым','восьмерыми','ввосьмером',
// 9 — девять
'девять','девяти','девятью','девятеро','девятерых','девятерым','девятерыми','вдевятером',
// 10 — десять
'десять','десяти','десятью','десятеро','десятерых','десятерым','десятерыми','вдесятером',
// разы / раз
'раз','раза','дважды','трижды',
]);
// ── Разбор строки фразы на слова, цифру и символ ─────────────
function parsePhrase(str) {
const tokens = str.trim().split(/\s+/);
const symbol = tokens[tokens.length - 1];
const digitIdx = tokens.findIndex(t => /^\d$/.test(t));
const digit = digitIdx >= 0 ? tokens[digitIdx] : '';
const words = tokens.filter((t, i) => i !== tokens.length - 1 && i !== digitIdx);
return { words, digit, symbol };
}
// ── Определение индекса числительного среди слов ────────────
function findNumIndex(words) {
const idx = words.findIndex(w => {
const bare = w.replace(/[.,!?;:]+$/, '').toLowerCase();
return NUM_WORDS.has(bare);
});
return idx; // -1, если не найдено
}
// ── Сборка пароля из фразы ───────────────────────────────────
// mode: 'en' — латиница, 'ru' — кириллица
function buildPassword(phraseStr, mode) {
mode = mode || 'en';
const { words, digit, symbol } = parsePhrase(phraseStr);
// 6 первых слов → первые буквы
let letters = words.slice(0, 6).map(w => {
const c = w[0];
if (mode === 'ru') {
// Русский режим: оставляем букву как есть (в нижнем регистре)
return c.toLowerCase();
}
// Английский режим: транслитерируем в латиницу
const t = translitChar(c);
return t || c.toLowerCase();
});
// Если слов меньше 6 — добираем буквами из начала первого слова
if (letters.length < 6 && words.length > 0) {
const firstWord = words[0];
for (let i = 1; i < firstWord.length && letters.length < 6; i++) {
const ch = firstWord[i];
if (mode === 'ru') {
if (/[а-яё]/i.test(ch)) letters.push(ch.toLowerCase());
} else {
const t = translitChar(ch);
if (t) letters.push(t.toLowerCase());
}
}
}
while (letters.length < 6) letters.push(mode === 'ru' ? 'я' : 'x');
// Числительное прописью → позиция для вставки цифры
let numIndex = findNumIndex(words);
if (numIndex < 0 || numIndex > 5) numIndex = 5;
// Первая буква заглавная, остальные строчные
const base = letters
.map((l, i) => i === 0 ? l.toUpperCase() : l.toLowerCase())
.join('');
return { base, digit, symbol, insertAfter: numIndex, mode };
}
// ── Вспомогательные функции ──────────────────────────────────
function escapeHtml(s) {
return String(s).replace(/[&<>"']/g, c => ({
'&':'&','<':'<','>':'>','"':'"',"'":'''
}[c]));
}
// ── Отрисовка фразы с подсветкой ────────────────────────────
function renderPhrase(phraseStr) {
const tokens = phraseStr.trim().split(/\s+/);
const parts = tokens.map(t => {
// Цифра
if (/^\d$/.test(t)) {
return `${escapeHtml(t)}`;
}
// Спецсимвол (нет букв и цифр)
if (!/[а-яёa-z0-9]/i.test(t)) {
return `${escapeHtml(t)}`;
}
// Числительное прописью
const bare = t.replace(/[.,!?;:]+$/, '').toLowerCase();
const cls = NUM_WORDS.has(bare) ? 'pwd-num-word' : 'pwd-word';
return `${escapeHtml(t)}`;
});
return parts.join(' ');
}
// ── Отрисовка пароля с цифрой после нужной буквы ────────────
function renderPassword(pw) {
const chars = pw.base.split('');
const out = [];
for (let i = 0; i < chars.length; i++) {
const cls = i === 0 ? 'cap' : '';
out.push(`${escapeHtml(chars[i])}`);
if (i === pw.insertAfter) {
out.push(`${escapeHtml(pw.digit)}`);
}
}
out.push(`${escapeHtml(pw.symbol)}`);
return out.join('');
}
function plainPassword(pw) {
const chars = pw.base.split('');
return (
chars.slice(0, pw.insertAfter + 1).join('') +
pw.digit +
chars.slice(pw.insertAfter + 1).join('') +
pw.symbol
);
}
// ── Инициализация ────────────────────────────────────────────
function initPasswordGenerator() {
const enBtn = document.getElementById('genEnBtn');
const ruBtn = document.getElementById('genRuBtn');
const result = document.getElementById('result');
const empty = document.getElementById('empty');
const phraseOut = document.getElementById('phraseOut');
const pwdOut = document.getElementById('pwdOut');
if (!enBtn || !ruBtn) return;
let currentPassword = '';
function generate(mode) {
const phrase = PHRASES[Math.floor(Math.random() * PHRASES.length)];
const pw = buildPassword(phrase, mode);
currentPassword = plainPassword(pw);
phraseOut.innerHTML = renderPhrase(phrase);
pwdOut.innerHTML = renderPassword(pw);
result.classList.remove('hidden');
empty.classList.add('hidden');
}
enBtn.addEventListener('click', () => generate('en'));
ruBtn.addEventListener('click', () => generate('ru'));
// Enter — сгенерировать латиницей (по умолчанию)
document.addEventListener('keydown', e => {
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
if (e.key === 'Enter') { e.preventDefault(); generate('en'); }
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initPasswordGenerator);
} else {
initPasswordGenerator();
}