Backup #1750
| ID | 1750 |
| Dateipfad | /var/www/dev.campus.systemische-tools.de/src/View/chat/index.php |
| Version | 53 |
| Typ |
modified |
| Größe | 38.7 KB |
| Hash | 01f71eb9b8f1387de04ce6c804b28aeef4550a3d4ff52bc541121228f400ca3b |
| Datum | 2025-12-27 12:45:57 |
| Geändert von | claude-code-hook |
| Grund | Claude Code Pre-Hook Backup vor Edit-Operation |
| Datei existiert |
Ja
|
Dateiinhalt
<?php
/**
* Chat - Redesign
* Clean, minimalist, professional
*/
$currentModel = $session['model'] ?? $defaultModel ?? 'claude-opus-4-5-20251101';
$selected = json_decode($session['collections'] ?? '["documents"]', true) ?: ['documents'];
$currentLimit = (int) ($session['context_limit'] ?? 5);
$currentProfileId = (int) ($session['author_profile_id'] ?? 0);
$currentPromptId = (int) ($session['system_prompt_id'] ?? 1);
$currentTemperature = (float) ($session['temperature'] ?? 0.5);
$currentMaxTokens = (int) ($session['max_tokens'] ?? 4096);
?>
<!DOCTYPE html>
<html lang="de" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= htmlspecialchars($session['title'] ?? 'KI-Chat') ?> - Campus</title>
<link rel="icon" type="image/png" href="https://campus-am-see.de/wp-content/uploads/menu-logo.png">
<link rel="stylesheet" href="/css/chat-redesign.css">
<script src="/js/htmx.min.js"></script>
</head>
<body>
<div class="chat-layout">
<!-- Sidebar -->
<aside class="chat-sidebar" id="sidebar">
<div class="chat-sidebar__header">
<a href="/chat" class="chat-sidebar__new">+ Neuer Chat</a>
<button class="chat-sidebar__delete-all" hx-delete="/chat" hx-headers='{"X-CSRF-TOKEN": "<?= $csrfToken ?>"}' hx-confirm="Alle <?= count($sessions ?? []) ?> Chats löschen?" title="Alle löschen">× Alle</button>
</div>
<div class="chat-sidebar__list" id="session-list">
<?php foreach ($sessions ?? [] as $s):
$totalTokens = (int) ($s['total_input_tokens'] ?? 0) + (int) ($s['total_output_tokens'] ?? 0);
$totalCost = ((int) ($s['total_input_tokens'] ?? 0) * 0.000015) + ((int) ($s['total_output_tokens'] ?? 0) * 0.000075);
$isOllama = str_starts_with($s['model'] ?? '', 'ollama:');
$createdAt = $s['created_at'] ?? null;
$dateStr = $createdAt ? (new DateTime($createdAt))->format('d.m. H:i') : '';
?>
<a href="/chat/<?= $s['uuid'] ?>"
class="chat-session <?= ($session['uuid'] ?? '') === $s['uuid'] ? 'chat-session--active' : '' ?>"
data-uuid="<?= $s['uuid'] ?>">
<div class="chat-session__title" id="title-<?= $s['uuid'] ?>"><?= htmlspecialchars($s['title'] ?? 'Neuer Chat') ?></div>
<div class="chat-session__meta">
<span class="chat-session__date"><?= $dateStr ?></span>
<span><?= $s['message_count'] ?? 0 ?> Nachr.</span>
<?php if (!$isOllama && $totalTokens > 0): ?>
<span class="chat-session__cost">~$<?= number_format($totalCost, 2) ?></span>
<?php elseif ($isOllama): ?>
<span class="chat-session__local">lokal</span>
<?php endif; ?>
</div>
<div class="chat-session__actions">
<button class="chat-session__edit" onclick="event.preventDefault(); event.stopPropagation(); editTitle('<?= $s['uuid'] ?>');" title="Bearbeiten">✎</button>
<button class="chat-session__delete" hx-delete="/chat/<?= $s['uuid'] ?>" hx-headers='{"X-CSRF-TOKEN": "<?= $csrfToken ?>"}' hx-confirm="Session löschen?" onclick="event.preventDefault(); event.stopPropagation();">×</button>
</div>
</a>
<?php endforeach; ?>
<?php if (empty($sessions)): ?>
<div class="chat-session chat-session--empty">Keine Sessions</div>
<?php endif; ?>
</div>
</aside>
<!-- Config Panel (50% Screen) -->
<aside class="config-panel" id="configPanel">
<div class="config-panel__header">
<span class="config-panel__title">Einstellungen</span>
<button type="button" class="config-panel__close" id="configPanelClose" aria-label="Panel schliessen">×</button>
</div>
<div class="config-panel__body">
<!-- Modell -->
<div class="config-panel__group">
<label for="configModel" class="config-panel__label">Modell</label>
<select id="configModel" class="config-panel__select" aria-label="Modell waehlen">
<optgroup label="Anthropic">
<?php foreach ($models ?? [] as $modelId => $modelLabel): ?>
<?php if (!str_starts_with($modelId, 'ollama:')): ?>
<option value="<?= htmlspecialchars($modelId) ?>" <?= $currentModel === $modelId ? 'selected' : '' ?>><?= htmlspecialchars($modelLabel) ?></option>
<?php endif; ?>
<?php endforeach; ?>
</optgroup>
<optgroup label="Ollama (lokal)">
<?php foreach ($models ?? [] as $modelId => $modelLabel): ?>
<?php if (str_starts_with($modelId, 'ollama:')): ?>
<option value="<?= htmlspecialchars($modelId) ?>" <?= $currentModel === $modelId ? 'selected' : '' ?>><?= htmlspecialchars($modelLabel) ?></option>
<?php endif; ?>
<?php endforeach; ?>
</optgroup>
</select>
</div>
<!-- Quellen -->
<div class="config-panel__group">
<label for="configContextLimit" class="config-panel__label">Quellen</label>
<select id="configContextLimit" class="config-panel__select" aria-label="Anzahl Quellen">
<option value="3" <?= $currentLimit === 3 ? 'selected' : '' ?>>3 Quellen</option>
<option value="5" <?= $currentLimit === 5 ? 'selected' : '' ?>>5 Quellen</option>
<option value="10" <?= $currentLimit === 10 ? 'selected' : '' ?>>10 Quellen</option>
<option value="15" <?= $currentLimit === 15 ? 'selected' : '' ?>>15 Quellen</option>
</select>
</div>
<!-- Collections -->
<div class="config-panel__group">
<label class="config-panel__label">Sammlungen</label>
<div class="config-panel__collections" id="configCollections">
<?php foreach ($collections ?? [] as $col):
$colId = $col['collection_id'];
$isSelected = in_array($colId, $selected, true);
$points = (int) ($col['points_count'] ?? 0);
?>
<label class="config-panel__checkbox">
<input type="checkbox" name="collections[]" value="<?= htmlspecialchars($colId) ?>" <?= $isSelected ? 'checked' : '' ?>>
<?= htmlspecialchars($col['display_name']) ?> <span class="config-panel__count">(<?= number_format($points) ?>)</span>
</label>
<?php endforeach; ?>
</div>
</div>
<!-- Temperatur & Tokens -->
<div class="config-panel__group">
<label class="config-panel__label">Temperatur: <span id="tempValuePanel"><?= number_format($currentTemperature, 1) ?></span></label>
<input type="range" id="configTemperature" class="config-panel__slider" min="0" max="1" step="0.1" value="<?= $currentTemperature ?>">
<div class="config-panel__presets">
<button type="button" class="config-panel__preset<?= $currentTemperature == 0.3 ? ' config-panel__preset--active' : '' ?>" data-temp="0.3" data-tokens="2048">Präzise</button>
<button type="button" class="config-panel__preset<?= $currentTemperature == 0.5 ? ' config-panel__preset--active' : '' ?>" data-temp="0.5" data-tokens="4096">Ausgewogen</button>
<button type="button" class="config-panel__preset<?= $currentTemperature == 0.9 ? ' config-panel__preset--active' : '' ?>" data-temp="0.9" data-tokens="4096">Kreativ</button>
</div>
</div>
<!-- Max Tokens -->
<div class="config-panel__group">
<label for="configMaxTokens" class="config-panel__label">Max Tokens</label>
<select id="configMaxTokens" class="config-panel__select">
<option value="1024" <?= $currentMaxTokens === 1024 ? 'selected' : '' ?>>1024</option>
<option value="2048" <?= $currentMaxTokens === 2048 ? 'selected' : '' ?>>2048</option>
<option value="4096" <?= $currentMaxTokens === 4096 ? 'selected' : '' ?>>4096</option>
<option value="8192" <?= $currentMaxTokens === 8192 ? 'selected' : '' ?>>8192</option>
</select>
</div>
<!-- Qualitätsprüfung -->
<div class="config-panel__group">
<label class="config-panel__checkbox config-panel__checkbox--large">
<input type="checkbox" id="configQualityCheck" name="quality_check" value="1">
Qualitätsprüfung (LLM-Validierung)
</label>
</div>
<hr class="config-panel__divider">
<!-- System Prompt -->
<div class="config-panel__group">
<label for="configSystemPrompt" class="config-panel__label">System Prompt</label>
<select id="configSystemPrompt" class="config-panel__select" aria-label="System Prompt waehlen">
<?php foreach ($systemPrompts ?? [] as $prompt): ?>
<option value="<?= $prompt['id'] ?>" <?= $currentPromptId === (int) $prompt['id'] ? 'selected' : '' ?>><?= htmlspecialchars($prompt['name']) ?></option>
<?php endforeach; ?>
</select>
<button type="button" class="config-panel__toggle" data-config-type="system_prompt" aria-expanded="false" aria-controls="systemPromptEditor">✎</button>
<div id="systemPromptEditor" class="config-panel__editor config-panel__editor--hidden" aria-hidden="true">
<textarea id="systemPromptContent" class="config-panel__textarea" rows="8"></textarea>
<div class="config-panel__actions">
<span class="config-panel__version" id="systemPromptVersion"></span>
<button type="button" class="config-panel__save" data-config-type="system_prompt">Speichern</button>
</div>
</div>
</div>
<!-- Ausgabeformat -->
<div class="config-panel__group">
<label for="configStructure" class="config-panel__label">Ausgabeformat</label>
<select id="configStructure" class="config-panel__select">
<option value="0">Frei (kein Format)</option>
<?php foreach ($outputStructures ?? [] as $structure): ?>
<option value="<?= $structure['id'] ?>"><?= htmlspecialchars($structure['name']) ?></option>
<?php endforeach; ?>
</select>
<button type="button" class="config-panel__toggle" data-config-type="structure" aria-expanded="false" aria-controls="structureEditor">✎</button>
<div id="structureEditor" class="config-panel__editor config-panel__editor--hidden" aria-hidden="true">
<textarea id="structureContent" class="config-panel__textarea" rows="8"></textarea>
<div class="config-panel__actions">
<span class="config-panel__version" id="structureVersion"></span>
<button type="button" class="config-panel__save" data-config-type="structure">Speichern</button>
</div>
</div>
</div>
<!-- Autorenprofil -->
<div class="config-panel__group">
<label for="configAuthorProfile" class="config-panel__label">Autorenprofil</label>
<select id="configAuthorProfile" class="config-panel__select">
<option value="0">Kein Profil</option>
<?php foreach ($authorProfiles ?? [] as $profile): ?>
<option value="<?= $profile['id'] ?>" <?= $currentProfileId === (int) $profile['id'] ? 'selected' : '' ?>><?= htmlspecialchars($profile['name']) ?></option>
<?php endforeach; ?>
</select>
<button type="button" class="config-panel__toggle" data-config-type="author_profile" aria-expanded="false" aria-controls="authorProfileEditor">✎</button>
<div id="authorProfileEditor" class="config-panel__editor config-panel__editor--hidden" aria-hidden="true">
<textarea id="authorProfileContent" class="config-panel__textarea" rows="8"></textarea>
<div class="config-panel__actions">
<span class="config-panel__version" id="authorProfileVersion"></span>
<button type="button" class="config-panel__save" data-config-type="author_profile">Speichern</button>
</div>
</div>
</div>
<hr class="config-panel__divider">
<!-- Export -->
<div class="config-panel__group">
<label class="config-panel__label">Export</label>
<div class="config-panel__export">
<a href="/chat/<?= $session['uuid'] ?? '' ?>/export?format=markdown" class="config-panel__export-btn">Markdown</a>
<a href="/chat/<?= $session['uuid'] ?? '' ?>/export?format=json" class="config-panel__export-btn">JSON</a>
</div>
</div>
<!-- Theme Toggle -->
<div class="config-panel__group">
<label class="config-panel__label">Design</label>
<button type="button" class="config-panel__theme" id="configThemeToggle">
<span id="configThemeIcon">☾</span> <span id="configThemeText">Light Mode</span>
</button>
</div>
</div>
</aside>
<!-- Config Panel Toggle Button (außerhalb des Panels) -->
<button type="button" class="config-panel__toggle-btn" id="configPanelToggle" aria-expanded="false" aria-controls="configPanel" title="Konfiguration">
<span class="visually-hidden">Konfiguration anzeigen</span>
<span aria-hidden="true">⚙</span>
</button>
<div class="chat-overlay" id="overlay"></div>
<!-- Main -->
<main class="chat-main">
<!-- Header -->
<header class="chat-header">
<button class="chat-toggle" id="toggle" title="Sidebar">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
</button>
<a href="/" class="chat-header__logo" title="Zur Startseite">
<img src="https://campus-am-see.de/wp-content/uploads/menu-logo.png" alt="Campus">
</a>
<div class="chat-header__title">
<h1 id="page-title"><?= htmlspecialchars($session['title'] ?? 'KI-Chat') ?></h1>
</div>
</header>
<!-- Messages -->
<div class="chat-messages" id="messages">
<div class="chat-messages__inner">
<?php if (empty($messages)): ?>
<div class="chat-welcome">
<img src="https://campus-am-see.de/wp-content/uploads/menu-logo.png" alt="Campus am See" class="chat-welcome__logo">
<h2>Campus am See KI Assistent</h2>
</div>
<?php endif; ?>
<?php foreach ($messages ?? [] as $msg): ?>
<div class="chat-msg chat-msg--<?= $msg['role'] ?>">
<div class="chat-msg__content">
<?php if ($msg['role'] === 'user'): ?>
<?= htmlspecialchars($msg['content']) ?>
<?php else: ?>
<?= nl2br(htmlspecialchars($msg['content'])) ?>
<?php if (!empty($msg['sources'])): ?>
<?php $sources = json_decode($msg['sources'], true) ?: []; ?>
<?php if (!empty($sources)): ?>
<div class="chat-sources" id="sources-<?= $msg['id'] ?>">
<button type="button" class="chat-sources__toggle" onclick="this.parentElement.classList.toggle('chat-sources--open')">
<?= count($sources) ?> Quelle<?= count($sources) > 1 ? 'n' : '' ?> ▾
</button>
<div class="chat-sources__list">
<?php foreach ($sources as $source): ?>
<div class="chat-source">
<div class="chat-source__header">
<?php if (!empty($source['collection'])): ?>
<span class="chat-source__collection">[<?= htmlspecialchars($source['collection']) ?>]</span>
<?php endif; ?>
<span class="chat-source__title"><?= htmlspecialchars($source['title'] ?? 'Unbekannt') ?></span>
<span class="chat-source__score"><?= round(($source['score'] ?? 0) * 100) ?>%</span>
</div>
<?php if (!empty($source['content'])): ?>
<div class="chat-source__content">"<?= htmlspecialchars(mb_substr($source['content'], 0, 200)) ?><?= mb_strlen($source['content']) > 200 ? '...' : '' ?>"</div>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<?php endif; ?>
<?php
$inputTokens = (int) ($msg['tokens_input'] ?? 0);
$outputTokens = (int) ($msg['tokens_output'] ?? 0);
$msgCost = ($inputTokens * 0.000015) + ($outputTokens * 0.000075);
$msgModel = $msg['model'] ?? 'claude-opus-4-5-20251101';
$msgIsOllama = str_starts_with($msgModel, 'ollama:');
?>
<div class="chat-msg__meta">
<span><?= $msgIsOllama ? substr($msgModel, 7) : $msgModel ?></span>
<?php if (!$msgIsOllama && ($inputTokens > 0 || $outputTokens > 0)): ?>
<span class="chat-msg__tokens">↓<?= number_format($inputTokens) ?> ↑<?= number_format($outputTokens) ?></span>
<span class="chat-msg__cost">~$<?= number_format($msgCost, 4) ?></span>
<?php elseif ($msgIsOllama): ?>
<span class="chat-msg__local">lokal</span>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<!-- Input Area -->
<div class="chat-input-area">
<div class="chat-input-wrapper">
<form class="chat-form" id="chatForm">
<!-- Hidden inputs (synced from Config Panel) -->
<input type="hidden" name="model" id="hiddenModel" value="<?= $currentModel ?>">
<input type="hidden" name="context_limit" id="hiddenContextLimit" value="<?= $currentLimit ?>">
<input type="hidden" name="temperature" id="hiddenTemperature" value="<?= $currentTemperature ?>">
<input type="hidden" name="max_tokens" id="hiddenMaxTokens" value="<?= $currentMaxTokens ?>">
<input type="hidden" name="author_profile_id" id="hiddenAuthorProfile" value="<?= $currentProfileId ?>">
<input type="hidden" name="system_prompt_id" id="hiddenSystemPrompt" value="<?= $currentPromptId ?>">
<input type="hidden" name="structure_id" id="hiddenStructure" value="0">
<div id="hiddenCollections"></div>
<div class="chat-input-row">
<input type="text" name="message" class="chat-input" placeholder="Nachricht eingeben..." autocomplete="off" required>
<button type="submit" class="chat-send" id="sendBtn">
<span class="chat-send__text">Senden</span>
<span class="chat-send__loading"><span></span><span></span><span></span></span>
</button>
</div>
</form>
</div>
</div>
</main>
</div>
<script>
const sidebar = document.getElementById('sidebar');
const overlay = document.getElementById('overlay');
const toggle = document.getElementById('toggle');
const messages = document.getElementById('messages');
const form = document.getElementById('chatForm');
const sendBtn = document.getElementById('sendBtn');
const html = document.documentElement;
const configPanel = document.getElementById('configPanel');
const configPanelToggle = document.getElementById('configPanelToggle');
const configPanelClose = document.getElementById('configPanelClose');
// ========== THEME ==========
const savedTheme = localStorage.getItem('chat-theme') || 'light';
html.setAttribute('data-theme', savedTheme);
updateThemeUI();
function updateThemeUI() {
const theme = html.getAttribute('data-theme');
const icon = document.getElementById('configThemeIcon');
const text = document.getElementById('configThemeText');
if (icon) icon.textContent = theme === 'dark' ? '☀' : '☽';
if (text) text.textContent = theme === 'dark' ? 'Dark Mode' : 'Light Mode';
}
document.getElementById('configThemeToggle')?.addEventListener('click', () => {
const next = html.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
html.setAttribute('data-theme', next);
localStorage.setItem('chat-theme', next);
updateThemeUI();
});
// ========== SIDEBAR ==========
toggle.addEventListener('click', (e) => {
e.stopPropagation();
sidebar.classList.toggle('chat-sidebar--open');
overlay.classList.toggle('chat-overlay--visible');
});
overlay.addEventListener('click', () => {
sidebar.classList.remove('chat-sidebar--open');
overlay.classList.remove('chat-overlay--visible');
});
// ========== CONFIG PANEL ==========
configPanelToggle.addEventListener('click', () => {
configPanel.classList.toggle('config-panel--open');
configPanelToggle.setAttribute('aria-expanded', configPanel.classList.contains('config-panel--open'));
});
configPanelClose.addEventListener('click', () => {
configPanel.classList.remove('config-panel--open');
configPanelToggle.setAttribute('aria-expanded', 'false');
});
// ========== SYNC CONFIG PANEL TO HIDDEN INPUTS ==========
function syncToHidden(configId, hiddenId) {
const config = document.getElementById(configId);
const hidden = document.getElementById(hiddenId);
if (config && hidden) {
config.addEventListener('change', function() {
hidden.value = this.value;
// Visual feedback
this.classList.add('is-saving');
setTimeout(() => {
this.classList.remove('is-saving');
this.classList.add('is-saved');
setTimeout(() => this.classList.remove('is-saved'), 600);
}, 100);
// Save to localStorage
localStorage.setItem('chat-' + hiddenId, this.value);
});
// Load from localStorage
const saved = localStorage.getItem('chat-' + hiddenId);
if (saved) {
const option = config.querySelector('option[value="' + saved + '"]');
if (option) {
config.value = saved;
hidden.value = saved;
}
}
}
}
syncToHidden('configModel', 'hiddenModel');
syncToHidden('configContextLimit', 'hiddenContextLimit');
syncToHidden('configMaxTokens', 'hiddenMaxTokens');
syncToHidden('configSystemPrompt', 'hiddenSystemPrompt');
syncToHidden('configStructure', 'hiddenStructure');
syncToHidden('configAuthorProfile', 'hiddenAuthorProfile');
// ========== COLLECTIONS SYNC ==========
function syncCollections() {
const container = document.getElementById('hiddenCollections');
container.innerHTML = '';
document.querySelectorAll('#configCollections input[type="checkbox"]:checked').forEach(cb => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'collections[]';
input.value = cb.value;
container.appendChild(input);
});
}
syncCollections();
document.querySelectorAll('#configCollections input[type="checkbox"]').forEach(cb => {
cb.addEventListener('change', syncCollections);
});
// ========== TEMPERATURE ==========
const tempSlider = document.getElementById('configTemperature');
const tempValue = document.getElementById('tempValuePanel');
const hiddenTemp = document.getElementById('hiddenTemperature');
tempSlider?.addEventListener('input', () => {
const val = parseFloat(tempSlider.value).toFixed(1);
tempValue.textContent = val;
hiddenTemp.value = val;
updatePresetHighlight();
});
function updatePresetHighlight() {
const currentTemp = parseFloat(tempSlider.value);
document.querySelectorAll('.config-panel__preset').forEach(btn => {
const btnTemp = parseFloat(btn.dataset.temp);
btn.classList.toggle('config-panel__preset--active', Math.abs(btnTemp - currentTemp) < 0.05);
});
}
// Preset buttons click handler
document.querySelectorAll('.config-panel__preset').forEach(btn => {
btn.addEventListener('click', () => {
const temp = parseFloat(btn.dataset.temp);
const tokens = parseInt(btn.dataset.tokens);
tempSlider.value = temp;
tempValue.textContent = temp.toFixed(1);
hiddenTemp.value = temp;
document.getElementById('configMaxTokens').value = tokens;
document.getElementById('hiddenMaxTokens').value = tokens;
updatePresetHighlight();
// Visual feedback
btn.classList.add('is-saving');
setTimeout(() => {
btn.classList.remove('is-saving');
btn.classList.add('is-saved');
setTimeout(() => btn.classList.remove('is-saved'), 600);
}, 100);
});
});
// Streaming Form Handler with SSE
form.addEventListener('submit', async (e) => {
... (292 weitere Zeilen)
Vollständig herunterladen
Aktionen
Andere Versionen dieser Datei
| ID |
Version |
Typ |
Größe |
Datum |
| 1988 |
58 |
modified |
21.2 KB |
2025-12-28 03:01 |
| 1979 |
57 |
modified |
38.9 KB |
2025-12-28 02:49 |
| 1920 |
56 |
modified |
38.9 KB |
2025-12-28 01:19 |
| 1773 |
55 |
modified |
38.8 KB |
2025-12-27 14:01 |
| 1751 |
54 |
modified |
38.8 KB |
2025-12-27 12:46 |
| 1750 |
53 |
modified |
38.7 KB |
2025-12-27 12:45 |
| 1748 |
52 |
modified |
38.7 KB |
2025-12-27 12:45 |
| 1741 |
51 |
modified |
38.6 KB |
2025-12-27 12:43 |
| 1740 |
50 |
modified |
38.6 KB |
2025-12-27 12:43 |
| 1667 |
49 |
modified |
38.6 KB |
2025-12-27 11:25 |
| 1663 |
48 |
modified |
39.7 KB |
2025-12-27 11:07 |
| 1662 |
47 |
modified |
39.7 KB |
2025-12-27 11:07 |
| 1661 |
46 |
modified |
39.0 KB |
2025-12-27 11:07 |
| 1660 |
45 |
modified |
37.8 KB |
2025-12-27 11:05 |
| 1659 |
44 |
modified |
43.2 KB |
2025-12-27 11:04 |
| 1658 |
43 |
modified |
37.7 KB |
2025-12-27 11:03 |
| 1654 |
42 |
modified |
37.4 KB |
2025-12-27 10:58 |
| 1648 |
41 |
modified |
37.4 KB |
2025-12-27 10:55 |
| 1646 |
40 |
modified |
32.5 KB |
2025-12-27 10:28 |
| 1645 |
39 |
modified |
33.5 KB |
2025-12-27 10:28 |
| 1644 |
38 |
modified |
28.2 KB |
2025-12-27 10:27 |
| 1584 |
37 |
modified |
27.9 KB |
2025-12-26 21:09 |
| 1582 |
36 |
modified |
27.5 KB |
2025-12-26 21:03 |
| 1581 |
35 |
modified |
27.0 KB |
2025-12-26 21:01 |
| 1577 |
34 |
modified |
26.8 KB |
2025-12-26 20:55 |
| 1576 |
33 |
modified |
26.7 KB |
2025-12-26 20:48 |
| 1569 |
32 |
modified |
26.1 KB |
2025-12-26 20:36 |
| 1568 |
31 |
modified |
26.1 KB |
2025-12-26 20:36 |
| 1567 |
30 |
modified |
25.9 KB |
2025-12-26 20:34 |
| 1564 |
29 |
modified |
26.1 KB |
2025-12-26 20:30 |
| 1563 |
28 |
modified |
22.6 KB |
2025-12-26 20:30 |
| 1554 |
27 |
modified |
23.2 KB |
2025-12-26 20:18 |
| 1548 |
26 |
modified |
23.2 KB |
2025-12-26 20:06 |
| 1547 |
25 |
modified |
23.2 KB |
2025-12-26 20:06 |
| 1546 |
24 |
modified |
23.1 KB |
2025-12-26 20:06 |
| 1545 |
23 |
modified |
23.0 KB |
2025-12-26 20:05 |
| 1537 |
22 |
modified |
23.4 KB |
2025-12-26 19:54 |
| 565 |
21 |
modified |
23.0 KB |
2025-12-23 03:36 |
| 552 |
20 |
modified |
22.6 KB |
2025-12-23 02:39 |
| 543 |
19 |
modified |
22.2 KB |
2025-12-22 22:31 |
| 541 |
18 |
modified |
21.4 KB |
2025-12-22 22:31 |
| 537 |
17 |
modified |
21.1 KB |
2025-12-22 22:27 |
| 205 |
16 |
modified |
21.1 KB |
2025-12-21 16:21 |
| 200 |
15 |
modified |
21.9 KB |
2025-12-21 14:44 |
| 184 |
14 |
modified |
21.9 KB |
2025-12-21 14:16 |
| 170 |
13 |
modified |
22.0 KB |
2025-12-21 04:13 |
| 121 |
12 |
modified |
22.2 KB |
2025-12-20 19:27 |
| 120 |
11 |
modified |
22.1 KB |
2025-12-20 19:27 |
| 119 |
10 |
modified |
22.1 KB |
2025-12-20 19:27 |
| 118 |
9 |
modified |
22.2 KB |
2025-12-20 19:27 |
| 90 |
8 |
modified |
21.4 KB |
2025-12-20 19:16 |
| 88 |
7 |
modified |
21.2 KB |
2025-12-20 19:16 |
| 73 |
6 |
modified |
20.9 KB |
2025-12-20 19:04 |
| 72 |
5 |
modified |
20.8 KB |
2025-12-20 19:00 |
| 70 |
4 |
modified |
20.5 KB |
2025-12-20 18:59 |
| 69 |
3 |
modified |
20.5 KB |
2025-12-20 18:49 |
| 62 |
2 |
modified |
18.7 KB |
2025-12-20 18:33 |
| 61 |
1 |
modified |
17.0 KB |
2025-12-20 18:32 |
← Zurück zur Übersicht