Files
website-collection/chess/public/index.html
T

1227 lines
30 KiB
HTML
Raw Normal View History

2026-08-22 17:34:34 +00:00
<!doctype html>
<html lang="ru">
2026-08-23 07:15:23 +00:00
<head>
2026-08-23 07:37:29 +00:00
<meta charset="UTF-8">
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, viewport-fit=cover"
>
<meta
name="theme-color"
content="#0f172a"
>
<meta
name="color-scheme"
content="dark light"
>
<title>Chess Party</title>
2026-08-23 07:15:23 +00:00
<meta
name="description"
content="Chess Party — шахматы против компьютера или с другом."
>
2026-08-23 07:37:29 +00:00
<!-- =====================================================
НАСТРОЙКИ РЕПОЗИТОРИЯ
Здесь меняешь только эти две строки:
1. REPOSITORY_LOGO_URL
URL логотипа твоего репозитория
2026-08-23 07:15:23 +00:00
2026-08-23 07:37:29 +00:00
2. REPOSITORY_URL
URL самого репозитория
====================================================== -->
<script>
window.CHESS_PARTY_CONFIG = {
REPOSITORY_LOGO_URL:
"https://example.com/logo.png",
REPOSITORY_URL:
"https://example.com/repository"
};
</script>
<!-- Favicon -->
2026-08-23 07:15:23 +00:00
<link
rel="icon"
type="image/png"
href="https://cdn-icons-png.flaticon.com/512/823/823301.png"
>
2026-08-23 07:37:29 +00:00
<!-- Основные стили -->
<link
rel="stylesheet"
href="/styles.css"
>
2026-08-23 07:15:23 +00:00
</head>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<body>
<div class="page-shell">
2026-08-23 07:37:29 +00:00
<!-- =====================================================
HEADER
====================================================== -->
2026-08-23 07:15:23 +00:00
<header class="main-header">
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<h1>
2026-08-23 07:37:29 +00:00
<span
class="chess-icon"
aria-hidden="true"
>
</span>
<span>
Chess Party
</span>
2026-08-23 07:15:23 +00:00
</h1>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</header>
2026-08-23 07:37:29 +00:00
<!-- =====================================================
MAIN
====================================================== -->
2026-08-23 07:15:23 +00:00
<main class="app-grid">
2026-08-22 17:34:34 +00:00
2026-08-23 07:37:29 +00:00
<!-- =================================================
BOARD
================================================== -->
2026-08-23 06:39:51 +00:00
<section class="board-panel panel">
2026-08-22 17:34:34 +00:00
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<div class="board-toolbar">
2026-08-22 17:34:34 +00:00
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<div class="mode-info">
2026-08-23 07:37:29 +00:00
<p
class="label"
data-i18n="currentMode"
>
Текущий режим
</p>
<h2 id="modeBadge">
AI Арена
</h2>
2026-08-23 07:15:23 +00:00
</div>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<div class="toolbar-actions">
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<button
id="newGameToolbarButton"
class="secondary-button"
type="button"
2026-08-23 07:37:29 +00:00
data-i18n="newGame"
2026-08-23 07:15:23 +00:00
>
Новая игра
</button>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<button
id="flipBoardButton"
class="icon-button"
type="button"
title="Перевернуть доску"
2026-08-23 07:37:29 +00:00
aria-label="Перевернуть доску"
2026-08-23 07:15:23 +00:00
>
</button>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<button
id="copyInviteButton"
class="secondary-button hidden"
type="button"
2026-08-23 07:37:29 +00:00
data-i18n="invite"
2026-08-23 07:15:23 +00:00
>
Инвайт
</button>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</div>
2026-08-23 07:37:29 +00:00
2026-08-23 06:39:51 +00:00
</div>
2026-08-23 07:15:23 +00:00
2026-08-23 07:37:29 +00:00
<!-- Chess board -->
2026-08-23 07:15:23 +00:00
<div class="board-stage">
<div
id="board"
class="board"
aria-label="Шахматная доска"
></div>
2026-08-23 06:39:51 +00:00
</div>
2026-08-23 07:15:23 +00:00
2026-08-23 07:37:29 +00:00
<!-- Game status -->
2026-08-23 07:15:23 +00:00
<div class="status-strip">
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<div class="status-text">
2026-08-23 07:37:29 +00:00
<p
class="label"
data-i18n="gameStatus"
>
Статус игры
</p>
2026-08-23 07:15:23 +00:00
<p
id="statusMessage"
class="status-message"
>
Выберите режим и начните игру.
</p>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</div>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<div class="status-meta">
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<span
id="turnBadge"
class="status-chip turn-white"
>
Ход белых
</span>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<span
id="connectionBadge"
class="status-chip connection-solo"
>
Соло
</span>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</div>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</div>
2026-08-23 07:37:29 +00:00
2026-08-23 06:39:51 +00:00
</section>
2026-08-23 07:15:23 +00:00
2026-08-23 07:37:29 +00:00
<!-- =================================================
SIDEBAR
================================================== -->
2026-08-23 06:39:51 +00:00
<aside class="sidebar">
2026-08-23 07:37:29 +00:00
<!-- SETTINGS -->
2026-08-23 07:15:23 +00:00
<section class="panel">
2026-08-23 06:39:51 +00:00
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<div class="panel-head">
2026-08-23 07:37:29 +00:00
<p
class="label"
data-i18n="settings"
>
Настройки
</p>
<h3 data-i18n="chooseMode">
Выберите режим
</h3>
2026-08-23 07:15:23 +00:00
</div>
2026-08-23 07:37:29 +00:00
<!-- Mode -->
2026-08-23 07:15:23 +00:00
<div class="mode-switcher">
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<button
id="modeAiButton"
class="mode-button active"
type="button"
2026-08-23 07:37:29 +00:00
data-i18n="computer"
2026-08-23 07:15:23 +00:00
>
С компьютером
</button>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<button
id="modePartyButton"
class="mode-button"
type="button"
2026-08-23 07:37:29 +00:00
data-i18n="friend"
2026-08-23 07:15:23 +00:00
>
С другом
</button>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</div>
2026-08-23 06:39:51 +00:00
2026-08-23 07:37:29 +00:00
<!-- Player name -->
2026-08-23 06:39:51 +00:00
<label class="field">
2026-08-23 07:15:23 +00:00
2026-08-23 07:37:29 +00:00
<span data-i18n="yourName">
Ваше имя
</span>
2026-08-23 07:15:23 +00:00
<input
id="playerNameInput"
type="text"
maxlength="24"
2026-08-23 07:37:29 +00:00
autocomplete="nickname"
2026-08-23 07:15:23 +00:00
placeholder="Введите имя..."
2026-08-23 07:37:29 +00:00
data-i18n-placeholder="namePlaceholder"
2026-08-23 07:15:23 +00:00
>
2026-08-23 06:39:51 +00:00
</label>
2026-08-23 07:37:29 +00:00
<!-- =========================================
AI CONTROLS
========================================== -->
2026-08-23 07:15:23 +00:00
<div id="aiControls">
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<div class="field-grid">
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<label class="field">
2026-08-23 07:37:29 +00:00
<span data-i18n="difficulty">
Сложность
</span>
2026-08-23 07:15:23 +00:00
<select id="aiLevelSelect">
2026-08-23 07:37:29 +00:00
<option
value="easy"
data-i18n="easy"
>
2026-08-23 07:15:23 +00:00
Легкая
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option
value="intermediate"
selected
2026-08-23 07:37:29 +00:00
data-i18n="medium"
2026-08-23 07:15:23 +00:00
>
Средняя
</option>
2026-08-23 07:37:29 +00:00
<option
value="hard"
data-i18n="hard"
>
2026-08-23 07:15:23 +00:00
Сложная
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</select>
</label>
<label class="field">
2026-08-23 07:37:29 +00:00
<span data-i18n="playAs">
Играть за
</span>
2026-08-23 07:15:23 +00:00
<select id="playerColorSelect">
2026-08-23 07:37:29 +00:00
<option
value="w"
selected
data-i18n="white"
>
2026-08-23 07:15:23 +00:00
Белых
</option>
2026-08-23 07:37:29 +00:00
<option
value="b"
data-i18n="black"
>
2026-08-23 07:15:23 +00:00
Черных
</option>
</select>
</label>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</div>
2026-08-23 07:37:29 +00:00
<!-- AI clock -->
2026-08-23 07:15:23 +00:00
<label class="field">
2026-08-23 07:37:29 +00:00
<span data-i18n="timeControl">
Контроль времени
</span>
2026-08-23 07:15:23 +00:00
<select id="aiClockSelect">
2026-08-23 07:37:29 +00:00
<option
value="none"
data-i18n="noLimit"
>
2026-08-23 07:15:23 +00:00
Без лимита
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="1+0">
1 + 0 • Bullet
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="3+0">
3 + 0 • Blitz
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="3+2">
3 + 2 • Blitz
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="5+0">
5 + 0 • Blitz
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="5+3">
5 + 3 • Blitz
</option>
2026-08-23 07:37:29 +00:00
<option
value="10+0"
selected
>
2026-08-23 07:15:23 +00:00
10 + 0 • Rapid
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="15+10">
15 + 10 • Rapid
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="30+0">
30 + 0 • Classical
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="30+20">
30 + 20 • Classical
</option>
</select>
</label>
<button
id="startAiButton"
class="primary-button"
type="button"
2026-08-23 07:37:29 +00:00
data-i18n="startAi"
2026-08-23 07:15:23 +00:00
>
Начать игру с ИИ
</button>
2026-08-23 06:39:51 +00:00
2026-08-23 07:37:29 +00:00
2026-08-23 06:39:51 +00:00
</div>
2026-08-23 07:37:29 +00:00
<!-- =========================================
PARTY CONTROLS
========================================== -->
2026-08-23 07:15:23 +00:00
<div
id="partyControls"
class="hidden"
>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<button
id="createPartyButton"
class="primary-button"
type="button"
2026-08-23 07:37:29 +00:00
data-i18n="createRoom"
2026-08-23 07:15:23 +00:00
>
Создать комнату
</button>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<label class="field">
2026-08-23 07:37:29 +00:00
<span data-i18n="roomCode">
Код комнаты
</span>
2026-08-23 07:15:23 +00:00
<div class="join-row">
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<input
id="partyCodeInput"
type="text"
maxlength="6"
2026-08-23 07:37:29 +00:00
autocomplete="off"
2026-08-23 07:15:23 +00:00
placeholder="ABC123"
>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<button
id="joinPartyButton"
class="secondary-button"
type="button"
2026-08-23 07:37:29 +00:00
data-i18n="join"
2026-08-23 07:15:23 +00:00
>
Войти
</button>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</div>
</label>
<label class="field">
2026-08-23 07:37:29 +00:00
<span data-i18n="timeControl">
Контроль времени
</span>
2026-08-23 07:15:23 +00:00
<select id="partyClockSelect">
2026-08-23 07:37:29 +00:00
<option
value="none"
data-i18n="noLimit"
>
2026-08-23 07:15:23 +00:00
Без лимита
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="1+0">
1 + 0 • Bullet
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="3+0">
3 + 0 • Blitz
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="3+2">
3 + 2 • Blitz
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="5+0">
5 + 0 • Blitz
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="5+3">
5 + 3 • Blitz
</option>
2026-08-23 07:37:29 +00:00
<option
value="10+0"
selected
>
2026-08-23 07:15:23 +00:00
10 + 0 • Rapid
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="15+10">
15 + 10 • Rapid
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="30+0">
30 + 0 • Classical
</option>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<option value="30+20">
30 + 20 • Classical
</option>
</select>
</label>
<button
id="leavePartyButton"
class="ghost-button hidden"
type="button"
2026-08-23 07:37:29 +00:00
data-i18n="leaveRoom"
2026-08-23 07:15:23 +00:00
>
Покинуть комнату
</button>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<p
id="partySummary"
class="muted-copy"
>
Создайте комнату, чтобы играть белыми.
</p>
2026-08-23 06:39:51 +00:00
2026-08-23 07:37:29 +00:00
2026-08-23 06:39:51 +00:00
</div>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</section>
2026-08-23 07:37:29 +00:00
<!-- =================================================
PLAYERS
================================================== -->
2026-08-23 07:15:23 +00:00
<section class="panel">
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<div class="panel-head">
2026-08-23 07:37:29 +00:00
<p
class="label"
data-i18n="players"
>
Участники
</p>
<h3 data-i18n="tableAndSpectators">
Стол и зрители
</h3>
2026-08-23 07:15:23 +00:00
</div>
<div class="roster-grid">
2026-08-23 07:37:29 +00:00
<!-- White -->
2026-08-23 07:15:23 +00:00
<div class="roster-card white-player">
<div class="roster-info">
2026-08-23 07:37:29 +00:00
<span
class="roster-role"
data-i18n="white"
>
2026-08-23 07:15:23 +00:00
Белые
</span>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<strong id="whitePlayerLabel">
Вы
</strong>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</div>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<div
id="whiteClock"
class="player-clock"
>
10:00
</div>
</div>
2026-08-23 07:37:29 +00:00
<!-- Black -->
2026-08-23 07:15:23 +00:00
<div class="roster-card black-player">
<div class="roster-info">
2026-08-23 07:37:29 +00:00
<span
class="roster-role"
data-i18n="black"
>
2026-08-23 07:15:23 +00:00
Черные
</span>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<strong id="blackPlayerLabel">
Компьютер
</strong>
</div>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<div
id="blackClock"
class="player-clock"
>
10:00
</div>
</div>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</div>
2026-08-23 07:37:29 +00:00
<!-- Spectators -->
2026-08-23 07:15:23 +00:00
<div class="spectator-panel">
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<div class="spectator-header">
2026-08-23 07:37:29 +00:00
<p
class="label"
data-i18n="spectators"
>
2026-08-23 07:15:23 +00:00
Зрители
</p>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<span
id="spectatorCount"
class="badge"
>
0 / 20
</span>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</div>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<ul
id="spectatorList"
class="spectator-list"
>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<li class="empty-state">
Пока никого нет
</li>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</ul>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</div>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</section>
2026-08-23 07:37:29 +00:00
2026-08-22 17:34:34 +00:00
</aside>
2026-08-23 07:15:23 +00:00
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</main>
2026-08-23 07:37:29 +00:00
<!-- =====================================================
REPOSITORY FOOTER
Логотип и ссылка берутся из
window.CHESS_PARTY_CONFIG
====================================================== -->
<footer class="site-footer">
<a
id="repositoryLink"
class="repository-link"
href="#"
target="_blank"
rel="noopener noreferrer"
aria-label="Repository"
>
<img
id="repositoryLogo"
class="repository-logo"
src=""
alt="Repository"
loading="lazy"
decoding="async"
>
<span
class="repository-name"
data-i18n="repository"
>
Репозиторий
</span>
</a>
</footer>
2026-08-23 07:15:23 +00:00
</div>
2026-08-23 07:37:29 +00:00
<!-- =========================================================
TOAST
========================================================= -->
2026-08-23 07:15:23 +00:00
<div
id="toastHost"
class="toast-host"
aria-live="polite"
></div>
2026-08-23 07:37:29 +00:00
<!-- =========================================================
PROMOTION
========================================================= -->
2026-08-23 07:15:23 +00:00
<div
id="promotionDialog"
class="modal hidden"
role="dialog"
aria-modal="true"
2026-08-23 07:37:29 +00:00
aria-labelledby="promotionTitle"
2026-08-23 07:15:23 +00:00
>
<div class="modal-card">
2026-08-23 07:37:29 +00:00
<p
class="label"
data-i18n="promotion"
>
2026-08-23 07:15:23 +00:00
Превращение пешки
</p>
2026-08-23 07:37:29 +00:00
<h3
id="promotionTitle"
data-i18n="choosePiece"
>
2026-08-23 07:15:23 +00:00
Выберите фигуру
</h3>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
<div
id="promotionOptions"
class="promotion-options"
></div>
2026-08-23 07:37:29 +00:00
2026-08-23 06:39:51 +00:00
</div>
2026-08-22 17:34:34 +00:00
2026-08-23 07:15:23 +00:00
</div>
2026-08-22 17:34:34 +00:00
2026-08-23 07:37:29 +00:00
<!-- =========================================================
AUTO LANGUAGE + REPOSITORY
========================================================= -->
<script>
(function () {
"use strict";
/* =====================================================
TRANSLATIONS
====================================================== */
const translations = {
ru: {
currentMode: "Текущий режим",
newGame: "Новая игра",
invite: "Инвайт",
gameStatus: "Статус игры",
settings: "Настройки",
chooseMode: "Выберите режим",
computer: "С компьютером",
friend: "С другом",
yourName: "Ваше имя",
namePlaceholder: "Введите имя...",
difficulty: "Сложность",
easy: "Легкая",
medium: "Средняя",
hard: "Сложная",
playAs: "Играть за",
white: "Белые",
black: "Черные",
timeControl: "Контроль времени",
noLimit: "Без лимита",
startAi: "Начать игру с ИИ",
createRoom: "Создать комнату",
roomCode: "Код комнаты",
join: "Войти",
leaveRoom: "Покинуть комнату",
players: "Участники",
tableAndSpectators: "Стол и зрители",
spectators: "Зрители",
repository: "Репозиторий",
promotion: "Превращение пешки",
choosePiece: "Выберите фигуру"
},
en: {
currentMode: "Current mode",
newGame: "New game",
invite: "Invite",
gameStatus: "Game status",
settings: "Settings",
chooseMode: "Choose mode",
computer: "Computer",
friend: "Friend",
yourName: "Your name",
namePlaceholder: "Enter your name...",
difficulty: "Difficulty",
easy: "Easy",
medium: "Medium",
hard: "Hard",
playAs: "Play as",
white: "White",
black: "Black",
timeControl: "Time control",
noLimit: "No limit",
startAi: "Start AI game",
createRoom: "Create room",
roomCode: "Room code",
join: "Join",
leaveRoom: "Leave room",
players: "Players",
tableAndSpectators: "Table & spectators",
spectators: "Spectators",
repository: "Repository",
promotion: "Pawn promotion",
choosePiece: "Choose a piece"
},
de: {
currentMode: "Aktueller Modus",
newGame: "Neues Spiel",
invite: "Einladen",
gameStatus: "Spielstatus",
settings: "Einstellungen",
chooseMode: "Modus wählen",
computer: "Computer",
friend: "Freund",
yourName: "Dein Name",
namePlaceholder: "Name eingeben...",
difficulty: "Schwierigkeit",
easy: "Leicht",
medium: "Mittel",
hard: "Schwer",
playAs: "Spielen als",
white: "Weiß",
black: "Schwarz",
timeControl: "Zeitkontrolle",
noLimit: "Keine Begrenzung",
startAi: "KI-Spiel starten",
createRoom: "Raum erstellen",
roomCode: "Raumcode",
join: "Beitreten",
leaveRoom: "Raum verlassen",
players: "Teilnehmer",
tableAndSpectators: "Tisch & Zuschauer",
spectators: "Zuschauer",
repository: "Repository",
promotion: "Bauernumwandlung",
choosePiece: "Figur auswählen"
},
zh: {
currentMode: "当前模式",
newGame: "新游戏",
invite: "邀请",
gameStatus: "游戏状态",
settings: "设置",
chooseMode: "选择模式",
computer: "电脑",
friend: "好友",
yourName: "你的名字",
namePlaceholder: "输入名字...",
difficulty: "难度",
easy: "简单",
medium: "中等",
hard: "困难",
playAs: "执棋方",
white: "白方",
black: "黑方",
timeControl: "时间控制",
noLimit: "不限时",
startAi: "开始 AI 游戏",
createRoom: "创建房间",
roomCode: "房间代码",
join: "加入",
leaveRoom: "离开房间",
players: "玩家",
tableAndSpectators: "棋桌与观众",
spectators: "观众",
repository: "代码仓库",
promotion: "兵升变",
choosePiece: "选择棋子"
},
ja: {
currentMode: "現在のモード",
newGame: "新しいゲーム",
invite: "招待",
gameStatus: "ゲーム状態",
settings: "設定",
chooseMode: "モードを選択",
computer: "コンピューター",
friend: "友達",
yourName: "名前",
namePlaceholder: "名前を入力...",
difficulty: "難易度",
easy: "簡単",
medium: "普通",
hard: "難しい",
playAs: "プレイヤー",
white: "白",
black: "黒",
timeControl: "時間設定",
noLimit: "時間制限なし",
startAi: "AIゲームを開始",
createRoom: "ルームを作成",
roomCode: "ルームコード",
join: "参加",
leaveRoom: "ルームを退出",
players: "プレイヤー",
tableAndSpectators: "対局者と観戦者",
spectators: "観戦者",
repository: "リポジトリ",
promotion: "昇格",
choosePiece: "駒を選択"
}
};
/* =====================================================
LANGUAGE DETECTION
====================================================== */
function detectLanguage() {
const language =
navigator.language ||
navigator.userLanguage ||
"en";
const normalized =
language.toLowerCase();
if (normalized.startsWith("ru")) {
return "ru";
}
if (
normalized.startsWith("de")
) {
return "de";
}
if (
normalized.startsWith("zh")
) {
return "zh";
}
if (
normalized.startsWith("ja")
) {
return "ja";
}
return "en";
}
const language =
detectLanguage();
document.documentElement.lang =
language;
/* =====================================================
APPLY TRANSLATIONS
====================================================== */
function applyTranslations() {
const dictionary =
translations[language] ||
translations.en;
document
.querySelectorAll("[data-i18n]")
.forEach(function (element) {
const key =
element.dataset.i18n;
if (
dictionary[key]
) {
element.textContent =
dictionary[key];
}
});
document
.querySelectorAll("[data-i18n-placeholder]")
.forEach(function (element) {
const key =
element.dataset.i18nPlaceholder;
if (
dictionary[key]
) {
element.placeholder =
dictionary[key];
}
});
}
applyTranslations();
/* =====================================================
REPOSITORY
====================================================== */
const config =
window.CHESS_PARTY_CONFIG || {};
const repositoryLink =
document.getElementById(
"repositoryLink"
);
const repositoryLogo =
document.getElementById(
"repositoryLogo"
);
if (
repositoryLink &&
config.REPOSITORY_URL
) {
repositoryLink.href =
config.REPOSITORY_URL;
}
if (
repositoryLogo &&
config.REPOSITORY_LOGO_URL
) {
repositoryLogo.src =
config.REPOSITORY_LOGO_URL;
}
/* =====================================================
IF LOGO IS NOT CONFIGURED
====================================================== */
if (
repositoryLogo &&
!config.REPOSITORY_LOGO_URL
) {
repositoryLogo.style.display =
"none";
}
})();
</script>
<!-- =========================================================
APPLICATION
========================================================= -->
2026-08-23 07:15:23 +00:00
<script
type="module"
src="/js/app.js"
></script>
2026-08-23 07:37:29 +00:00
2026-08-23 07:15:23 +00:00
</body>
2026-08-22 17:47:08 +00:00
</html>