Compare commits
11 Commits
2aff4a4a5b
...
30a1c4ad8e
| Author | SHA1 | Date | |
|---|---|---|---|
| 30a1c4ad8e | |||
| bbe05bd765 | |||
| afadbbc835 | |||
| 6c73455013 | |||
| 76d072bd44 | |||
| 5d15f4bbc8 | |||
| b829f0e479 | |||
| 20c1721f8e | |||
| 2f782a4f6e | |||
| 95dce6b534 | |||
| 405908f48d |
@@ -20,7 +20,7 @@ RewriteEngine on
|
||||
# In some environments it's necessary to
|
||||
# set the RewriteBase to:
|
||||
#
|
||||
# RewriteBase /
|
||||
RewriteBase /
|
||||
|
||||
# block files and folders beginning with a dot, such as .git
|
||||
# except for the .well-known folder, which is used for Let's Encrypt and security.txt
|
||||
@@ -34,6 +34,7 @@ RewriteRule ^site/(.*) index.php [L]
|
||||
|
||||
# block direct access to Kirby and the Panel sources
|
||||
RewriteRule ^kirby/(.*) index.php [L]
|
||||
RewriteRule ^vendor/getkirby/(.*) index.php [L]
|
||||
|
||||
# make site links work
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
|
||||
@@ -67,16 +67,16 @@
|
||||
},
|
||||
{
|
||||
"name": "claviska/simpleimage",
|
||||
"version": "4.2.1",
|
||||
"version": "4.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/claviska/SimpleImage.git",
|
||||
"reference": "ec6d5021e5a7153a2520d64c59b86b6f3c4157c5"
|
||||
"reference": "6d928c779e343100cef40f75bac3e301c32c3741"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/claviska/SimpleImage/zipball/ec6d5021e5a7153a2520d64c59b86b6f3c4157c5",
|
||||
"reference": "ec6d5021e5a7153a2520d64c59b86b6f3c4157c5",
|
||||
"url": "https://api.github.com/repos/claviska/SimpleImage/zipball/6d928c779e343100cef40f75bac3e301c32c3741",
|
||||
"reference": "6d928c779e343100cef40f75bac3e301c32c3741",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -108,7 +108,7 @@
|
||||
"description": "A PHP class that makes working with images as simple as possible.",
|
||||
"support": {
|
||||
"issues": "https://github.com/claviska/SimpleImage/issues",
|
||||
"source": "https://github.com/claviska/SimpleImage/tree/4.2.1"
|
||||
"source": "https://github.com/claviska/SimpleImage/tree/4.4.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -116,7 +116,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-11-22T13:25:03+00:00"
|
||||
"time": "2025-11-20T16:58:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/semver",
|
||||
@@ -268,21 +268,21 @@
|
||||
},
|
||||
{
|
||||
"name": "getkirby/cms",
|
||||
"version": "5.1.1",
|
||||
"version": "5.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/getkirby/kirby.git",
|
||||
"reference": "fb11f5e3ec422e948fb1a52f16988335bb3489b4"
|
||||
"reference": "42cd286dab62d87a331e53abfe103e4fba118dd6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/getkirby/kirby/zipball/fb11f5e3ec422e948fb1a52f16988335bb3489b4",
|
||||
"reference": "fb11f5e3ec422e948fb1a52f16988335bb3489b4",
|
||||
"url": "https://api.github.com/repos/getkirby/kirby/zipball/42cd286dab62d87a331e53abfe103e4fba118dd6",
|
||||
"reference": "42cd286dab62d87a331e53abfe103e4fba118dd6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"christian-riesen/base32": "1.6.0",
|
||||
"claviska/simpleimage": "4.2.1",
|
||||
"claviska/simpleimage": "4.4.0",
|
||||
"composer/semver": "3.4.4",
|
||||
"ext-ctype": "*",
|
||||
"ext-curl": "*",
|
||||
@@ -297,36 +297,31 @@
|
||||
"ext-simplexml": "*",
|
||||
"filp/whoops": "2.18.4",
|
||||
"getkirby/composer-installer": "^1.2.1",
|
||||
"laminas/laminas-escaper": "2.17.0",
|
||||
"laminas/laminas-escaper": "2.18.0",
|
||||
"michelf/php-smartypants": "1.8.1",
|
||||
"php": "~8.2.0 || ~8.3.0 || ~8.4.0",
|
||||
"phpmailer/phpmailer": "6.10.0",
|
||||
"php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0",
|
||||
"phpmailer/phpmailer": "7.0.1",
|
||||
"symfony/polyfill-intl-idn": "1.33.0",
|
||||
"symfony/polyfill-mbstring": "1.33.0",
|
||||
"symfony/yaml": "7.3.3"
|
||||
"symfony/yaml": "7.4.1"
|
||||
},
|
||||
"replace": {
|
||||
"symfony/polyfill-php72": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-PDO": "Support for using databases",
|
||||
"ext-apcu": "Support for the Apcu cache driver",
|
||||
"ext-exif": "Support for exif information from images",
|
||||
"ext-fileinfo": "Improved mime type detection for files",
|
||||
"ext-imagick": "Improved thumbnail generation",
|
||||
"ext-intl": "Improved i18n number formatting",
|
||||
"ext-memcached": "Support for the Memcached cache driver",
|
||||
"ext-pdo": "Support for using databases",
|
||||
"ext-redis": "Support for the Redis cache driver",
|
||||
"ext-sodium": "Support for the crypto class and more robust session handling",
|
||||
"ext-zip": "Support for ZIP archive file functions",
|
||||
"ext-zlib": "Sanitization and validation for svgz files"
|
||||
},
|
||||
"type": "kirby-cms",
|
||||
"extra": {
|
||||
"unused": [
|
||||
"symfony/polyfill-intl-idn"
|
||||
]
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"config/setup.php",
|
||||
@@ -369,7 +364,7 @@
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"time": "2025-09-16T13:06:53+00:00"
|
||||
"time": "2025-12-16T09:23:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "getkirby/composer-installer",
|
||||
@@ -420,32 +415,32 @@
|
||||
},
|
||||
{
|
||||
"name": "laminas/laminas-escaper",
|
||||
"version": "2.17.0",
|
||||
"version": "2.18.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laminas/laminas-escaper.git",
|
||||
"reference": "df1ef9503299a8e3920079a16263b578eaf7c3ba"
|
||||
"reference": "06f211dfffff18d91844c1f55250d5d13c007e18"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/df1ef9503299a8e3920079a16263b578eaf7c3ba",
|
||||
"reference": "df1ef9503299a8e3920079a16263b578eaf7c3ba",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/06f211dfffff18d91844c1f55250d5d13c007e18",
|
||||
"reference": "06f211dfffff18d91844c1f55250d5d13c007e18",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"ext-mbstring": "*",
|
||||
"php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
|
||||
"php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
|
||||
},
|
||||
"conflict": {
|
||||
"zendframework/zend-escaper": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"infection/infection": "^0.29.8",
|
||||
"laminas/laminas-coding-standard": "~3.0.1",
|
||||
"phpunit/phpunit": "^10.5.45",
|
||||
"psalm/plugin-phpunit": "^0.19.2",
|
||||
"vimeo/psalm": "^6.6.2"
|
||||
"infection/infection": "^0.31.0",
|
||||
"laminas/laminas-coding-standard": "~3.1.0",
|
||||
"phpunit/phpunit": "^11.5.42",
|
||||
"psalm/plugin-phpunit": "^0.19.5",
|
||||
"vimeo/psalm": "^6.13.1"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -477,7 +472,7 @@
|
||||
"type": "community_bridge"
|
||||
}
|
||||
],
|
||||
"time": "2025-05-06T19:29:36+00:00"
|
||||
"time": "2025-10-14T18:31:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/color-extractor",
|
||||
@@ -596,16 +591,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpmailer/phpmailer",
|
||||
"version": "v6.10.0",
|
||||
"version": "v7.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPMailer/PHPMailer.git",
|
||||
"reference": "bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144"
|
||||
"reference": "360ae911ce62e25e11249f6140fa58939f556ebe"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144",
|
||||
"reference": "bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/360ae911ce62e25e11249f6140fa58939f556ebe",
|
||||
"reference": "360ae911ce62e25e11249f6140fa58939f556ebe",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -619,13 +614,14 @@
|
||||
"doctrine/annotations": "^1.2.6 || ^1.13.3",
|
||||
"php-parallel-lint/php-console-highlighter": "^1.0.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3.2",
|
||||
"phpcompatibility/php-compatibility": "^9.3.5",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"squizlabs/php_codesniffer": "^3.7.2",
|
||||
"phpcompatibility/php-compatibility": "^10.0.0@dev",
|
||||
"squizlabs/php_codesniffer": "^3.13.5",
|
||||
"yoast/phpunit-polyfills": "^1.0.4"
|
||||
},
|
||||
"suggest": {
|
||||
"decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication",
|
||||
"directorytree/imapengine": "For uploading sent messages via IMAP, see gmail example",
|
||||
"ext-imap": "Needed to support advanced email address parsing according to RFC822",
|
||||
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
|
||||
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
|
||||
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
|
||||
@@ -665,7 +661,7 @@
|
||||
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.10.0"
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v7.0.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -673,7 +669,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-24T15:19:31+00:00"
|
||||
"time": "2025-11-25T07:18:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
@@ -1134,28 +1130,28 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v7.3.3",
|
||||
"version": "v7.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "d4f4a66866fe2451f61296924767280ab5732d9d"
|
||||
"reference": "24dd4de28d2e3988b311751ac49e684d783e2345"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/d4f4a66866fe2451f61296924767280ab5732d9d",
|
||||
"reference": "d4f4a66866fe2451f61296924767280ab5732d9d",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/24dd4de28d2e3988b311751ac49e684d783e2345",
|
||||
"reference": "24dd4de28d2e3988b311751ac49e684d783e2345",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/deprecation-contracts": "^2.5|^3.0",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/polyfill-ctype": "^1.8"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/console": "<6.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/console": "^6.4|^7.0"
|
||||
"symfony/console": "^6.4|^7.0|^8.0"
|
||||
},
|
||||
"bin": [
|
||||
"Resources/bin/yaml-lint"
|
||||
@@ -1186,7 +1182,7 @@
|
||||
"description": "Loads and dumps YAML files",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/yaml/tree/v7.3.3"
|
||||
"source": "https://github.com/symfony/yaml/tree/v7.4.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1206,7 +1202,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-27T11:34:33+00:00"
|
||||
"time": "2025-12-04T18:11:45+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
@@ -1219,5 +1215,5 @@
|
||||
"php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
|
||||
},
|
||||
"platform-dev": {},
|
||||
"plugin-api-version": "2.6.0"
|
||||
"plugin-api-version": "2.9.0"
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 830 KiB |
@@ -0,0 +1,5 @@
|
||||
Uuid: bwjwjg6rtabbwkrt
|
||||
|
||||
----
|
||||
|
||||
Template: blocks/image
|
||||
@@ -0,0 +1,15 @@
|
||||
[Event "A-Klasse 2025/2026 - TSV Bindlach Aktionär 3"]
|
||||
[Site "Bindlach"]
|
||||
[Date "2025.11.30"]
|
||||
[Round "4"]
|
||||
[White "Feigel, Tobias"]
|
||||
[Black "Dederer, Alexej"]
|
||||
[Result "1-0"]
|
||||
[WhiteElo "1358"]
|
||||
[BlackElo "1487"]
|
||||
[EventDate "2025.11.30"]
|
||||
[ECO "B01"]
|
||||
[PlyCount "57"]
|
||||
|
||||
1.e4 d5 2.exd5 Qxd5 3.Nc3 Qe6+ $146 4.Be2 Qg6 5.g3 $2 c6 6.d4 Bf5 7.Bd3 $2 Bxd3 8.cxd3 e6 9.Nf3 Qh5 $1 10.Qe2 Nf6 11.a3 Nbd7 12.Bf4 Nd5 13.Nxd5 Qxd5 14.O-O Nf6 15.Rfe1 Rd8 16.Qd1 Be7 17.Rc1 Qh5 $2 18.Re5 Qh3 19.Ng5 $1 Qg4 $4 20.f3 Qh5 21.Nxe6 $1 Qh3 22.Nxd8 Kxd8 23.Qb3 Qd7 24.Rce1 Qxd4+ $2 25.Kg2 Bc5 26.Rxc5 $1 Qxc5 27.Qxb7 Qa5 28.Re7 Qb6 29.Bc7+ 1-0
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Uuid: zrylk3mmhvof3dy3
|
||||
@@ -0,0 +1,80 @@
|
||||
Title: 20251201-Erfolg-in-Bindlach
|
||||
|
||||
----
|
||||
|
||||
Blocks:
|
||||
|
||||
[
|
||||
{
|
||||
"content": {
|
||||
"text": "<p>Nach drei Niederlagen in Folge fuhren wir am 30.11.2025 mit geringen Erwartungen zur 3.Mannschaft des TSV Bindlach.</p><p>An den Brettern 2 <strong>(Alexander Döge</strong>), 6 (<strong>Rainald Müller</strong>) und 8 (<strong>Reinhardt Schmalz</strong>) waren schnell Remisen vereinbart. Aber am Spitzenbrett konnte <strong>Dominik Döge</strong> in einem Springerendspiel mit Minusbauern das Unentschieden nicht realisieren und <strong>Fred Zimmerbauer</strong> am vierten Brett verlor nach einem missglückten Springerzug Material und schließlich die Partie. Die Bindlacher wähnten sich bei diesem Zwischenstand mit 3,5 zu 1,5 schon auf der Siegerstraße. Alles deutete schon auf eine erneute Niederlage der Spielgemeinschaft SF Bad Steben/TV Reinersreuth hin. </p><p>Aber die drei letzten Partien verliefen hochspannend mit einem glücklichen Finale für die Kurstädter. <strong>Tobias Feigel</strong> konnte mit einem Figurenopfer die schwache Königsstellung seines Gegners aufreißen und auf der 7. Reihe mit konzentriertem Schwerfigurenangriff dann mattsetzen. <strong>Klaus Frommelt</strong> übte mit den weißen Steinen einen großen Druck auf die gegnerische Stellung aus, opferte seine Qualität gegen eine Fünfbauernphalanx am Damenflügel, welche beim Vorrücken trotz großen Widerstandes seines Gegenübers nicht mehr aufzuhalten war. Jetzt lag es an <strong>Dominik Kadlic</strong> den nötigen Gewinnpunkt zum Mannschaftssieg einzufahren. In einer turbulenten Auseinandersetzung mit beiderseitigen Gewinnchancen konnte er nach Abtausch aller Schwerfiguren solide in ein gewonnenes Bauernendspiel abwickeln.</p><p>Ein überraschender Sieg gegen die favorisierten Bindlacher, welchen man eigentlich nicht erwarten konnte. Dies gibt Hoffnung für das neue Jahr, wenn man zum Heimspiel am 11.01.2026 die sehr stark besetzte 2.Vertretung des SC Bayreuth empfängt.</p>"
|
||||
},
|
||||
"id": "dea24cf8-2397-4bf7-83da-f1baab4a3ca8",
|
||||
"isHidden": false,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"fen": "3k3r/pp3ppp/2p2n2/2b1R3/3q1B2/PQ1P1PP1/1P4KP/4R3 w - - 2 26"
|
||||
},
|
||||
"id": "f09ceaf2-6442-4b7f-8846-2df40fe0f6d0",
|
||||
"isHidden": false,
|
||||
"type": "fen"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"text": "<p>Die Stellung stammt aus der Partie an Brett 7 von <strong>Tobias Feige</strong>l gegen <strong>Alexej Dederer</strong>, vor dem 26. Zug von Weiß. Tobias opferte mit 26. Txc5! seine Qualität zurück um dann nach 26. ... Dxc5 mit 27. Dxb7 gefolgt von Te7 und schließlich Lc7 einen gewinnbringenden Mattangriff zu starten, der nur durch Damenverlust aufgehalten werden konnte:</p>"
|
||||
},
|
||||
"id": "36746cbf-384a-4f6c-be7c-ed0233464d22",
|
||||
"isHidden": false,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"fen": "3k3r/pQB1Rppp/1qp2n2/8/8/P2P1PP1/1P4KP/8 b - - 4 29"
|
||||
},
|
||||
"id": "f7e62a19-884e-472f-8f11-bb0e9fdaf9a4",
|
||||
"isHidden": false,
|
||||
"type": "fen"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"text": "<p>Ein schönes Ende der Partie, die Alexej an der Stelle sofort aufgab!</p>"
|
||||
},
|
||||
"id": "7601756e-536a-4ed6-b299-8506ec9d1ae9",
|
||||
"isHidden": false,
|
||||
"type": "text"
|
||||
}
|
||||
]
|
||||
|
||||
----
|
||||
|
||||
Image: - file://bwjwjg6rtabbwkrt
|
||||
|
||||
----
|
||||
|
||||
Headline: Erfolg gegen Bindlach!
|
||||
|
||||
----
|
||||
|
||||
Subheadline: Der erste Sieg der Saison ist eingefahren!
|
||||
|
||||
----
|
||||
|
||||
Summary: Nach drei Niederlagen in Folge fuhren wir am 30.11.2025 mit geringen Erwartungen zur 3.Mannschaft des TSV Bindlach - zu Unrecht, wie sich herausstellen sollte!
|
||||
|
||||
----
|
||||
|
||||
Tags: Spielbericht
|
||||
|
||||
----
|
||||
|
||||
Author: - user://P4aiY3HI
|
||||
|
||||
----
|
||||
|
||||
Date: 2025-12-01
|
||||
|
||||
----
|
||||
|
||||
Uuid: gqvlabgfoko535r9
|
||||
|
After Width: | Height: | Size: 495 KiB |
@@ -0,0 +1 @@
|
||||
Uuid: dgspiwstnipmybks
|
||||
@@ -0,0 +1,48 @@
|
||||
Title: 20251020-Saisonauftakt
|
||||
|
||||
----
|
||||
|
||||
Blocks:
|
||||
|
||||
[
|
||||
{
|
||||
"content": {
|
||||
"text": "<p>Der Start in die neue Saison verläuft für die SG SF Bad Steben/TV Reinersreuth äußerst unglücklich.</p><p>Im ersten Heimspiel setzte es gegen die SG Helmbrechts/Presseck eine 3,5 : 4,5 Niederlage. Dabei gelang es uns nicht, ein vollständiges Team mit acht Spielern zu gewährleisten. Nur sieben Akteure zum Saisonauftakt bedeuteten schon ein Handikap.</p><p>Am 19.10.2025 mussten wir zur ersten Auswärtsbegegnung beim vorläufigen Spitzenreiter SC Pegnitz antreten und es gab ein deutliches 2 : 6. Trotz großer Bemühungen unseres Spielleiters konnte er nur sechs Schachfreunde gegen die Heimmannschaft gewinnen. Mit einem anfänglichen 0 : 2-Rückstand ist es dann fast aussichtslos, auf einen Mannschafts-punktgewinn zu schielen. Nur Dominik Kadlic konnte seine Partie gewinnen, während Jürgen Franz und Rainald Müller ihre Spiele remisierten. Besonders hervorzuheben ist dabei die Punkteteilung unseres Spielleiters (DWZ: 1668), welcher am Spitzenbrett Markus Müller (DWZ: 1988) erfolgreich Paroli bieten konnte.</p><p>Nach den zwei Spieltagen stecken wir schon mitten im Abstiegskampf. Am 09.11.25 gilt es dann in der Heimbegegnung gegen den Aufsteiger ATSV Oberkotzau 2 nicht den Anschluss an das untere Mittelfeld in der Tabelle zu verlieren und endlich mal mit „voller Kapelle“ anzutreten.</p>"
|
||||
},
|
||||
"id": "e9def111-1209-4d1f-be78-985818f8c593",
|
||||
"isHidden": false,
|
||||
"type": "text"
|
||||
}
|
||||
]
|
||||
|
||||
----
|
||||
|
||||
Image: - file://dgspiwstnipmybks
|
||||
|
||||
----
|
||||
|
||||
Headline: Holpriger Saisonauftakt
|
||||
|
||||
----
|
||||
|
||||
Subheadline: Es läuft nicht rund!
|
||||
|
||||
----
|
||||
|
||||
Summary: Der Start in die neue Saison verläuft für die SG SF Bad Steben/TV Reinersreuth äußerst unglücklich.
|
||||
|
||||
----
|
||||
|
||||
Tags: Spielbericht
|
||||
|
||||
----
|
||||
|
||||
Author: - user://P4aiY3HI
|
||||
|
||||
----
|
||||
|
||||
Date: 2025-10-19
|
||||
|
||||
----
|
||||
|
||||
Uuid: 8qlli8wrp1tbkgap
|
||||
@@ -0,0 +1,56 @@
|
||||
Title: 20250922-Engagement
|
||||
|
||||
----
|
||||
|
||||
Blocks:
|
||||
|
||||
[
|
||||
{
|
||||
"content": {
|
||||
"text": "<p>Neben dem Engagement im eigenen Verein wurden bei der Versammlung des Schachkreis Hof-Bayreuth-Kulmbach am vergangenen Freitag zwei SF in die Ämter des Kreisjugendleiter und seines Stellvertreters gewählt.</p>"
|
||||
},
|
||||
"id": "c9741947-2e75-49e6-a4c5-47e35f183528",
|
||||
"isHidden": false,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"text": "**Tobias Feigel** (2. von links im Bild) amtierender Jugendleiter der SF und seit 2017 auch Kreisjugendleiter räumte seinen Posten auf Kreisebene und trat in die zweite Reihe zurück, um Platz zu machen für **Alexander Döge** (2. von rechts im Bild), der Kassenprüfer der SF ist und nun neuer Kreisjugendleiter. Tobias wird Alexander als sein Stellvertreter die nächsten zwei Jahre unterstützen und sich dann ganz aus der Vorstandschaft des Kreises verabschieden. Bei der nächsten Wahl soll dann Alexanders Bruder **Dominik Döge** in den Vorstand des Kreises an die Stelle von Tobias treten.\n\nEs seien mir dazu ein paar persönliche Worte erlaubt: In wenigen Jahren werde ich schachlich gesehen als Senior gewertet und da wird es höchste Zeit, den Posten in jüngere Hände abzugeben! Ich bin mir sicher, dass mit Alexander und Dominik zwei hervorragende Kandidaten für den Posten gefunden wurden und ich werde beide während der Übergangszeit unterstützen!"
|
||||
},
|
||||
"id": "6a2ee75a-db20-4861-80ee-db49f191c16e",
|
||||
"isHidden": false,
|
||||
"type": "markdown"
|
||||
}
|
||||
]
|
||||
|
||||
----
|
||||
|
||||
Image: - file://ioxhz3ujwtl6un8k
|
||||
|
||||
----
|
||||
|
||||
Headline: SF engagieren sich auf Kreisebene
|
||||
|
||||
----
|
||||
|
||||
Subheadline: Zwei SF im Vorstand des Schachkreises
|
||||
|
||||
----
|
||||
|
||||
Summary: Neben dem Engagement im eigenen Verein wurden bei der Versammlung des Schachkreis Hof-Bayreuth-Kulmbach am vergangenen Freitag zwei SF in die Ämter des Kreisjugendleiter und seines Stellvertreters gewählt.
|
||||
|
||||
----
|
||||
|
||||
Tags: Vereinsleben
|
||||
|
||||
----
|
||||
|
||||
Author: - user://KOY9VcGi
|
||||
|
||||
----
|
||||
|
||||
Date: 2025-09-22
|
||||
|
||||
----
|
||||
|
||||
Uuid: kbtd9a8so9mbkvti
|
||||
|
After Width: | Height: | Size: 509 KiB |
@@ -0,0 +1 @@
|
||||
Uuid: ioxhz3ujwtl6un8k
|
||||
@@ -37,7 +37,7 @@ Tags: Spielbericht, Turnierbericht
|
||||
|
||||
----
|
||||
|
||||
Author: - user://myU6sssZ
|
||||
Author: - user://KOY9VcGi
|
||||
|
||||
----
|
||||
|
||||
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 546 KiB After Width: | Height: | Size: 546 KiB |
@@ -1,23 +1,26 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
Crawl-delay: 1
|
||||
|
||||
# Spezielle Erlaubnis für DSGVO/Legal Scanner
|
||||
User-agent: LegalCockpitBot
|
||||
Allow: /
|
||||
Crawl-delay: 0
|
||||
|
||||
User-agent: CookieBot
|
||||
User-agent: cockpit.legal
|
||||
Allow: /
|
||||
Crawl-delay: 0
|
||||
|
||||
User-agent: Mozilla*
|
||||
Allow: /
|
||||
|
||||
User-agent: DataProtectionBot
|
||||
Allow: /
|
||||
|
||||
User-agent: GDPRBot
|
||||
Allow: /
|
||||
|
||||
# Sitemap (falls vorhanden)
|
||||
# Sitemap: https://www.schachfreunde-badsteben.de/sitemap.xml
|
||||
# Sitemap
|
||||
Sitemap: https://www.schachfreunde-badsteben.de/sitemap.xml
|
||||
|
||||
# Wichtige Seiten explizit erlauben
|
||||
Allow: /
|
||||
Allow: /datenschutz
|
||||
Allow: /impressum
|
||||
Allow: /kontakt
|
||||
Allow: /kontakt
|
||||
Allow: /home
|
||||
Allow: /news
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
<?php
|
||||
// URL der öffentlichen ICS-Datei
|
||||
define(
|
||||
@@ -83,13 +82,10 @@ function format_ics_date_with_timezone($date, $timezone = null)
|
||||
}
|
||||
}
|
||||
|
||||
// ICS-Datei laden
|
||||
$ics = @file_get_contents(CAL_URL);
|
||||
if (!$ics) {
|
||||
echo '<div class="text-red-600">Kalender konnte nicht geladen werden.</div>';
|
||||
|
||||
return;
|
||||
}
|
||||
// Cache für 24 Stunden (in Minuten)
|
||||
$cacheDuration = 24 * 60;
|
||||
$cacheId = 'google_calendar_events';
|
||||
$cache = kirby()->cache('pages');
|
||||
|
||||
// Termine parsen
|
||||
function parse_ics($ics)
|
||||
@@ -134,9 +130,26 @@ function parse_ics($ics)
|
||||
return $events;
|
||||
}
|
||||
|
||||
$events = parse_ics($ics);
|
||||
return function () use ($cache, $cacheId, $cacheDuration) {
|
||||
// Versuche Daten aus dem Cache zu laden
|
||||
$events = $cache->get($cacheId);
|
||||
|
||||
if ($events === null) {
|
||||
// Wenn nicht im Cache, neu laden
|
||||
$ics = @file_get_contents(CAL_URL);
|
||||
|
||||
if (!$ics) {
|
||||
// Fehler beim Laden (z.B. 429 Error)
|
||||
return null;
|
||||
}
|
||||
|
||||
// Termine parsen
|
||||
$events = parse_ics($ics);
|
||||
|
||||
// In Cache speichern
|
||||
$cache->set($cacheId, $events, $cacheDuration);
|
||||
}
|
||||
|
||||
return function () use ($events) {
|
||||
return $events;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'debug' => true,
|
||||
'debug' => false,
|
||||
|
||||
// Home-Seite explizit definieren
|
||||
'home' => 'home',
|
||||
|
||||
'panel' => [
|
||||
'vue' => [
|
||||
'compiler' => false
|
||||
]
|
||||
],
|
||||
'routes' => [
|
||||
'routes' => [
|
||||
[
|
||||
'pattern' => '/',
|
||||
'action' => function() {
|
||||
return site()->homePage();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'sitemap.xml',
|
||||
'action' => function() {
|
||||
@@ -29,5 +39,5 @@ return [
|
||||
return go('sitemap.xml', 301);
|
||||
}
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -1,33 +1,40 @@
|
||||
<?php
|
||||
$events = collection('termine');
|
||||
|
||||
if ($events === null): ?>
|
||||
<div class="container mx-auto py-8">
|
||||
<h2>Bevorstehende Termine</h2>
|
||||
<div class="text-red-600">Die Termine können gerade nicht geladen werden.</div>
|
||||
</div>
|
||||
<?php return; endif;
|
||||
|
||||
// Aktuelles Datum - PHP 8.3 kompatibel
|
||||
$today = (new DateTime('now'))->format('Ymd');
|
||||
|
||||
// Nur zukünftige Termine anzeigen
|
||||
$future_events = array_filter($events, function ($event) use ($today) {
|
||||
return isset($event['DTSTART']) && $event['DTSTART'] >= $today;
|
||||
return isset($event['DTSTART']) && $event['DTSTART'] >= $today;
|
||||
});
|
||||
|
||||
// Termine nach DTSTART in aufsteigender Reihenfolge sortieren
|
||||
usort($future_events, function ($a, $b) {
|
||||
return $a['DTSTART'] <=> $b['DTSTART'];
|
||||
return $a['DTSTART'] <=> $b['DTSTART'];
|
||||
});
|
||||
|
||||
// --- Deutsche Monatsnamen ---
|
||||
$de_months = [
|
||||
'01' => 'Jan',
|
||||
'02' => 'Feb',
|
||||
'03' => 'Mrz',
|
||||
'04' => 'Apr',
|
||||
'05' => 'Mai',
|
||||
'06' => 'Jun',
|
||||
'07' => 'Jul',
|
||||
'08' => 'Aug',
|
||||
'09' => 'Sep',
|
||||
'10' => 'Okt',
|
||||
'11' => 'Nov',
|
||||
'12' => 'Dez',
|
||||
'01' => 'Jan',
|
||||
'02' => 'Feb',
|
||||
'03' => 'Mrz',
|
||||
'04' => 'Apr',
|
||||
'05' => 'Mai',
|
||||
'06' => 'Jun',
|
||||
'07' => 'Jul',
|
||||
'08' => 'Aug',
|
||||
'09' => 'Sep',
|
||||
'10' => 'Okt',
|
||||
'11' => 'Nov',
|
||||
'12' => 'Dez',
|
||||
];
|
||||
?>
|
||||
|
||||
@@ -35,8 +42,12 @@ $de_months = [
|
||||
<h2>Bevorstehende Termine</h2>
|
||||
|
||||
<div class="relative flex items-center justify-center">
|
||||
<button id="scroll-left" class="flex-shrink-0 bg-white p-3 rounded-full shadow-lg hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 z-10 hidden md:block mr-4">
|
||||
<svg class="w-6 h-6 text-gray-700" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path></svg>
|
||||
<button id="scroll-left"
|
||||
class="flex-shrink-0 bg-white p-3 rounded-full shadow-lg hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 z-10 hidden md:block mr-4">
|
||||
<svg class="w-6 h-6 text-gray-700" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<div id="termine-wrapper" class="relative w-full max-w-7xl overflow-hidden">
|
||||
@@ -49,18 +60,18 @@ $de_months = [
|
||||
$location = $event['LOCATION'] ?? '';
|
||||
$desc = $event['DESCRIPTION'] ?? '';
|
||||
$timezone = $event['DTSTART_TZID'] ?? null;
|
||||
|
||||
|
||||
// Sichere Funktionsaufrufe mit Null-Checks
|
||||
$date_info = function_exists('format_ics_date_with_timezone')
|
||||
? format_ics_date_with_timezone($start, $timezone)
|
||||
$date_info = function_exists('format_ics_date_with_timezone')
|
||||
? format_ics_date_with_timezone($start, $timezone)
|
||||
: ['display' => '', 'has_time' => false, 'iso' => ''];
|
||||
|
||||
|
||||
$date = $date_info['display'] ?? '';
|
||||
$time = ($date_info['has_time'] ?? false) ? substr($date, 11) : 'ganztägig';
|
||||
$day = substr($date, 0, 2);
|
||||
$month = substr($date, 3, 2);
|
||||
$iso_date = $date_info['iso'] ?? '';
|
||||
|
||||
|
||||
// Sichere Array-Zugriffe
|
||||
$month_name = $de_months[$month] ?? 'Unbek';
|
||||
$event_summary = htmlspecialchars($summary, ENT_QUOTES, 'UTF-8');
|
||||
@@ -69,57 +80,64 @@ $de_months = [
|
||||
$safe_time = htmlspecialchars($time, ENT_QUOTES, 'UTF-8');
|
||||
?>
|
||||
|
||||
<div class="termine-card flex-none w-full md:w-1/2 bg-gradient-to-br from-blue-50 to-blue-100 rounded-2xl transform hover:scale-102 transition-all duration-300 ease-in-out border border-blue-200">
|
||||
<!-- Inhalt der ersten Karte bleibt unverändert -->
|
||||
<div class="p-6 flex flex-col h-full">
|
||||
<div class="flex items-top mb-5">
|
||||
<div class="relative flex-shrink-0 bg-white rounded-lg shadow-md overflow-hidden w-16 h-16 flex flex-col border border-blue-200">
|
||||
<!-- Kopfzeile des Kalenders mit Monat -->
|
||||
<div class="bg-blue-600 text-white text-xs font-semibold py-1 text-center uppercase">
|
||||
<span data-month><?= $month_name ?></span>
|
||||
</div>
|
||||
<div
|
||||
class="termine-card flex-none w-full md:w-1/2 bg-gradient-to-br from-blue-50 to-blue-100 rounded-2xl transform hover:scale-102 transition-all duration-300 ease-in-out border border-blue-200">
|
||||
<!-- Inhalt der ersten Karte bleibt unverändert -->
|
||||
<div class="p-6 flex flex-col h-full">
|
||||
<div class="flex items-top mb-5">
|
||||
<div
|
||||
class="relative flex-shrink-0 bg-white rounded-lg shadow-md overflow-hidden w-16 h-16 flex flex-col border border-blue-200">
|
||||
<!-- Kopfzeile des Kalenders mit Monat -->
|
||||
<div class="bg-blue-600 text-white text-xs font-semibold py-1 text-center uppercase">
|
||||
<span data-month><?= $month_name ?></span>
|
||||
</div>
|
||||
|
||||
<!-- Datumsanzeige -->
|
||||
<div class="flex-grow flex items-center justify-center">
|
||||
<div class="text-3xl font-bold text-sf_grau-800" data-day><?= $safe_day ?></div>
|
||||
</div>
|
||||
<!-- Datumsanzeige -->
|
||||
<div class="flex-grow flex items-center justify-center">
|
||||
<div class="text-3xl font-bold text-sf_grau-800" data-day><?= $safe_day ?></div>
|
||||
</div>
|
||||
|
||||
<!-- Dekorative Elemente - kleine Punkte für Kalendertage -->
|
||||
<div class="absolute bottom-1 left-0 right-0 flex justify-center space-x-0.5 px-1">
|
||||
<div class="w-1 h-1 rounded-full bg-sf_blau-200"></div>
|
||||
<div class="w-1 h-1 rounded-full bg-sf_blau-300"></div>
|
||||
<div class="w-1 h-1 rounded-full bg-sf_blau-400"></div>
|
||||
<div class="w-1 h-1 rounded-full bg-sf_blau-500"></div>
|
||||
<div class="w-1 h-1 rounded-full bg-sf_blau-400"></div>
|
||||
<div class="w-1 h-1 rounded-full bg-sf_blau-300"></div>
|
||||
<div class="w-1 h-1 rounded-full bg-sf_blau-200"></div>
|
||||
<!-- Dekorative Elemente - kleine Punkte für Kalendertage -->
|
||||
<div class="absolute bottom-1 left-0 right-0 flex justify-center space-x-0.5 px-1">
|
||||
<div class="w-1 h-1 rounded-full bg-sf_blau-200"></div>
|
||||
<div class="w-1 h-1 rounded-full bg-sf_blau-300"></div>
|
||||
<div class="w-1 h-1 rounded-full bg-sf_blau-400"></div>
|
||||
<div class="w-1 h-1 rounded-full bg-sf_blau-500"></div>
|
||||
<div class="w-1 h-1 rounded-full bg-sf_blau-400"></div>
|
||||
<div class="w-1 h-1 rounded-full bg-sf_blau-300"></div>
|
||||
<div class="w-1 h-1 rounded-full bg-sf_blau-200"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-5 flex-grow">
|
||||
<p class="text-xl font-medium text-sf_grau-900"><?= $event_summary ?></p>
|
||||
<p class="text-sf_blau-700 text-lg font-medium mt-1">
|
||||
<?php if ($date_info['has_time'] ?? false): ?>
|
||||
ab <span class="local-time"
|
||||
data-iso-date="<?= $safe_iso_date ?>"><?= $safe_time ?></span> Uhr
|
||||
<?php else: ?>
|
||||
ganztägig
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-5 flex-grow">
|
||||
<p class="text-xl font-medium text-sf_grau-900"><?= $event_summary ?></p>
|
||||
<p class="text-sf_blau-700 text-lg font-medium mt-1">
|
||||
<?php if ($date_info['has_time'] ?? false): ?>
|
||||
ab <span class="local-time" data-iso-date="<?= $safe_iso_date ?>"><?= $safe_time ?></span> Uhr
|
||||
<?php else: ?>
|
||||
ganztägig
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button id="scroll-right" class="flex-shrink-0 bg-white p-3 rounded-full shadow-lg hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 z-10 hidden md:block ml-4">
|
||||
<svg class="w-6 h-6 text-gray-700" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
|
||||
<button id="scroll-right"
|
||||
class="flex-shrink-0 bg-white p-3 rounded-full shadow-lg hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 z-10 hidden md:block ml-4">
|
||||
<svg class="w-6 h-6 text-gray-700" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const termineWrapper = document.getElementById('termine-wrapper');
|
||||
const termineContainer = document.getElementById('termine-container');
|
||||
const scrollLeftBtn = document.getElementById('scroll-left');
|
||||
@@ -143,7 +161,7 @@ $de_months = [
|
||||
scrollLeftBtn.classList.remove('opacity-50', 'cursor-not-allowed');
|
||||
scrollLeftBtn.classList.add('hover:bg-gray-100');
|
||||
}
|
||||
|
||||
|
||||
// Rechter Pfeil deaktivieren, wenn es keine weiteren Termine gibt
|
||||
if (currentPosition >= maxPosition) {
|
||||
scrollRightBtn.disabled = true;
|
||||
@@ -200,23 +218,23 @@ $de_months = [
|
||||
// Erstelle ein Date-Objekt aus der ISO-Date
|
||||
// JavaScript erkennt automatisch UTC-Zeiten (mit Z oder +00:00)
|
||||
const date = new Date(isoDate);
|
||||
|
||||
|
||||
// Prüfe ob das Datum gültig ist
|
||||
if (isNaN(date.getTime())) {
|
||||
console.warn('Ungültiges Datum:', isoDate);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Formatiere die Zeit in der lokalen Zeitzone des Browsers
|
||||
const localTime = date.toLocaleTimeString('de-DE', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
});
|
||||
|
||||
|
||||
// Aktualisiere den Text
|
||||
element.textContent = localTime;
|
||||
|
||||
|
||||
// Debug-Information (kann später entfernt werden)
|
||||
console.log('Konvertiert:', isoDate, '->', localTime, 'in Zeitzone:', Intl.DateTimeFormat().resolvedOptions().timeZone);
|
||||
} catch (error) {
|
||||
@@ -250,32 +268,41 @@ $de_months = [
|
||||
<style>
|
||||
/* Versteckt die Scrollbar vollständig, behält aber die Scrollfunktionalität */
|
||||
#termine-container {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none;
|
||||
/* IE and Edge */
|
||||
scrollbar-width: none;
|
||||
/* Firefox */
|
||||
overflow-x: visible;
|
||||
}
|
||||
|
||||
#termine-container::-webkit-scrollbar {
|
||||
display: none; /* Chrome, Safari, Opera */
|
||||
display: none;
|
||||
/* Chrome, Safari, Opera */
|
||||
}
|
||||
|
||||
/* Gleiche Kartenbreiten sicherstellen */
|
||||
@media (min-width: 1280px) {
|
||||
.termine-card {
|
||||
width: 100%; /* 100% minus 2 Gaps (2 * 24px) geteilt durch 3 */
|
||||
width: 100%;
|
||||
/* 100% minus 2 Gaps (2 * 24px) geteilt durch 3 */
|
||||
}
|
||||
|
||||
#termine-container {
|
||||
space-x-0; /* Kein Abstand zwischen Karten nötig */
|
||||
space-x-0;
|
||||
/* Kein Abstand zwischen Karten nötig */
|
||||
}
|
||||
}
|
||||
|
||||
/* Auf mobilen Geräten eine Karte anzeigen */
|
||||
@media (max-width: 1280px) {
|
||||
.termine-card {
|
||||
width: 100%; /* Volle Breite */
|
||||
width: 100%;
|
||||
/* Volle Breite */
|
||||
}
|
||||
|
||||
#termine-container {
|
||||
space-x-0; /* Kein Abstand zwischen Karten nötig */
|
||||
space-x-0;
|
||||
/* Kein Abstand zwischen Karten nötig */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,9 +310,11 @@ $de_months = [
|
||||
.termine-card h3 {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
/* white-space: nowrap; */ /* Diese Zeile entfernen oder kommentieren */
|
||||
/* white-space: nowrap; */
|
||||
/* Diese Zeile entfernen oder kommentieren */
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2; /* Maximal 2 Zeilen anzeigen */
|
||||
-webkit-line-clamp: 2;
|
||||
/* Maximal 2 Zeilen anzeigen */
|
||||
-webkit-box-orient: vertical;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
@@ -2,14 +2,22 @@
|
||||
|
||||
$events = collection('termine');
|
||||
|
||||
if ($events === null): ?>
|
||||
<section class="py-24 bg-sf_grau-50">
|
||||
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-red-600 bg-white p-6 rounded-lg shadow">Die Termine können gerade nicht geladen werden.</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php return; endif;
|
||||
|
||||
// Nur Events mit DTSTART berücksichtigen
|
||||
$events = array_filter($events, function ($event) {
|
||||
return isset($event['DTSTART']) && !empty($event['DTSTART']);
|
||||
return isset($event['DTSTART']) && !empty($event['DTSTART']);
|
||||
});
|
||||
|
||||
// Nach Datum sortieren
|
||||
usort($events, function ($a, $b) {
|
||||
return strcmp($a['DTSTART'], $b['DTSTART']);
|
||||
return strcmp($a['DTSTART'], $b['DTSTART']);
|
||||
});
|
||||
|
||||
// Aktuelles Datum - PHP 8.3 kompatibel
|
||||
@@ -17,44 +25,44 @@ $today = (new DateTime('now'))->format('Ymd');
|
||||
|
||||
// Nur zukünftige Termine anzeigen
|
||||
$future_events = array_filter($events, function ($event) use ($today) {
|
||||
return isset($event['DTSTART']) && $event['DTSTART'] >= $today;
|
||||
return isset($event['DTSTART']) && $event['DTSTART'] >= $today;
|
||||
});
|
||||
|
||||
// --- Deutsche Monatsnamen ---
|
||||
$de_months = [
|
||||
'01' => 'Januar',
|
||||
'02' => 'Februar',
|
||||
'03' => 'März',
|
||||
'04' => 'April',
|
||||
'05' => 'Mai',
|
||||
'06' => 'Juni',
|
||||
'07' => 'Juli',
|
||||
'08' => 'August',
|
||||
'09' => 'September',
|
||||
'10' => 'Oktober',
|
||||
'11' => 'November',
|
||||
'12' => 'Dezember',
|
||||
'01' => 'Januar',
|
||||
'02' => 'Februar',
|
||||
'03' => 'März',
|
||||
'04' => 'April',
|
||||
'05' => 'Mai',
|
||||
'06' => 'Juni',
|
||||
'07' => 'Juli',
|
||||
'08' => 'August',
|
||||
'09' => 'September',
|
||||
'10' => 'Oktober',
|
||||
'11' => 'November',
|
||||
'12' => 'Dezember',
|
||||
];
|
||||
|
||||
// --- Gruppierung aller Termine nach Jahr und Monat für die Sidebar ---
|
||||
function group_events_by_year_month($events)
|
||||
{
|
||||
$grouped = [];
|
||||
foreach ($events as $event) {
|
||||
if (!isset($event['DTSTART'])) {
|
||||
continue;
|
||||
$grouped = [];
|
||||
foreach ($events as $event) {
|
||||
if (!isset($event['DTSTART'])) {
|
||||
continue;
|
||||
}
|
||||
$date = $event['DTSTART'];
|
||||
$year = substr($date, 0, 4);
|
||||
$month = substr($date, 4, 2);
|
||||
$grouped[$year][$month][] = $event;
|
||||
}
|
||||
krsort($grouped); // Jahre absteigend
|
||||
foreach ($grouped as &$months) {
|
||||
krsort($months); // Monate absteigend
|
||||
}
|
||||
$date = $event['DTSTART'];
|
||||
$year = substr($date, 0, 4);
|
||||
$month = substr($date, 4, 2);
|
||||
$grouped[$year][$month][] = $event;
|
||||
}
|
||||
krsort($grouped); // Jahre absteigend
|
||||
foreach ($grouped as &$months) {
|
||||
krsort($months); // Monate absteigend
|
||||
}
|
||||
|
||||
return $grouped;
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
$all_events_grouped = group_events_by_year_month($events);
|
||||
@@ -64,19 +72,19 @@ $filter_jahr = filter_input(INPUT_GET, 'jahr', FILTER_SANITIZE_FULL_SPECIAL_CHAR
|
||||
$filter_monat = filter_input(INPUT_GET, 'monat', FILTER_SANITIZE_FULL_SPECIAL_CHARS) ?? null;
|
||||
|
||||
if ($filter_jahr && $filter_monat) {
|
||||
$filtered_events = array_filter($events, function ($event) use ($filter_jahr, $filter_monat) {
|
||||
$date = $event['DTSTART'] ?? '';
|
||||
$filtered_events = array_filter($events, function ($event) use ($filter_jahr, $filter_monat) {
|
||||
$date = $event['DTSTART'] ?? '';
|
||||
|
||||
return substr($date, 0, 4) === $filter_jahr && substr($date, 4, 2) === $filter_monat;
|
||||
});
|
||||
return substr($date, 0, 4) === $filter_jahr && substr($date, 4, 2) === $filter_monat;
|
||||
});
|
||||
} elseif ($filter_jahr) {
|
||||
$filtered_events = array_filter($events, function ($event) use ($filter_jahr) {
|
||||
$date = $event['DTSTART'] ?? '';
|
||||
$filtered_events = array_filter($events, function ($event) use ($filter_jahr) {
|
||||
$date = $event['DTSTART'] ?? '';
|
||||
|
||||
return substr($date, 0, 4) === $filter_jahr;
|
||||
});
|
||||
return substr($date, 0, 4) === $filter_jahr;
|
||||
});
|
||||
} else {
|
||||
$filtered_events = $future_events;
|
||||
$filtered_events = $future_events;
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -90,33 +98,34 @@ if ($filter_jahr && $filter_monat) {
|
||||
<?php foreach ($all_events_grouped as $year => $months): ?>
|
||||
<li class="mb-2">
|
||||
<div class="flex items-center">
|
||||
<?php
|
||||
<?php
|
||||
$safe_year = htmlspecialchars($year, ENT_QUOTES, 'UTF-8');
|
||||
$is_year_selected = ($filter_jahr === $year && !$filter_monat);
|
||||
?>
|
||||
<a href="?jahr=<?= $safe_year ?>"
|
||||
class="font-bold text-sf_blau-600 focus:outline-none flex items-center group<?= $is_year_selected ? ' underline selected' : '' ?>"
|
||||
onclick="event.stopPropagation(); openYear('<?= $safe_year ?>')">
|
||||
class="font-bold text-sf_blau-600 focus:outline-none flex items-center group<?= $is_year_selected ? ' underline selected' : '' ?>"
|
||||
onclick="event.stopPropagation(); openYear('<?= $safe_year ?>')">
|
||||
<span><?= $safe_year ?></span>
|
||||
</a>
|
||||
<button type="button" class="ml-1 focus:outline-none" onclick="toggleYear('<?= $safe_year ?>')">
|
||||
<svg class="w-4 h-4 transition-transform" id="arrow-<?= $safe_year ?>" fill="none" stroke="currentColor" stroke-width="2"
|
||||
viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/>
|
||||
<button type="button" class="ml-1 focus:outline-none"
|
||||
onclick="toggleYear('<?= $safe_year ?>')">
|
||||
<svg class="w-4 h-4 transition-transform" id="arrow-<?= $safe_year ?>" fill="none"
|
||||
stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<ul class="ml-4 mt-1 hidden" id="months-<?= $safe_year ?>">
|
||||
<?php foreach ($months as $month => $evts): ?>
|
||||
<li>
|
||||
<?php
|
||||
<?php
|
||||
$safe_month = htmlspecialchars($month, ENT_QUOTES, 'UTF-8');
|
||||
$month_name = $de_months[$month] ?? 'Unbekannt';
|
||||
$is_month_selected = ($filter_jahr === $year && $filter_monat === $month);
|
||||
$event_count = count($evts);
|
||||
?>
|
||||
<a href="?jahr=<?= $safe_year ?>&monat=<?= $safe_month ?>"
|
||||
class="text-sf_blau-500 hover:underline<?= $is_month_selected ? ' font-bold underline selected' : '' ?>">
|
||||
<a href="?jahr=<?= $safe_year ?>&monat=<?= $safe_month ?>"
|
||||
class="text-sf_blau-500 hover:underline<?= $is_month_selected ? ' font-bold underline selected' : '' ?>">
|
||||
<?= htmlspecialchars($month_name, ENT_QUOTES, 'UTF-8') ?> (<?= $event_count ?>)
|
||||
</a>
|
||||
</li>
|
||||
@@ -157,50 +166,50 @@ if ($filter_jahr && $filter_monat) {
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full border border-gray-200 bg-white rounded-lg shadow">
|
||||
<thead>
|
||||
<tr class="bg-gray-100">
|
||||
<th class="py-2 px-4 border-b text-left">Datum</th>
|
||||
<th class="py-2 px-4 border-b text-left">Uhrzeit</th>
|
||||
<th class="py-2 px-4 border-b text-left">Titel</th>
|
||||
</tr>
|
||||
<tr class="bg-gray-100">
|
||||
<th class="py-2 px-4 border-b text-left">Datum</th>
|
||||
<th class="py-2 px-4 border-b text-left">Uhrzeit</th>
|
||||
<th class="py-2 px-4 border-b text-left">Titel</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($filtered_events as $event): ?>
|
||||
<?php
|
||||
$start = $event['DTSTART'] ?? '';
|
||||
$end = $event['DTEND'] ?? '';
|
||||
$summary = $event['SUMMARY'] ?? '';
|
||||
$location = $event['LOCATION'] ?? '';
|
||||
$desc = $event['DESCRIPTION'] ?? '';
|
||||
$timezone = $event['DTSTART_TZID'] ?? null;
|
||||
|
||||
// Sichere Funktionsaufrufe mit Null-Checks
|
||||
$date_info = function_exists('format_ics_date_with_timezone')
|
||||
? format_ics_date_with_timezone($start, $timezone)
|
||||
: ['display' => '', 'has_time' => false, 'iso' => ''];
|
||||
|
||||
$date = $date_info['display'] ?? '';
|
||||
$time = ($date_info['has_time'] ?? false) ? substr($date, 11) : 'ganztägig';
|
||||
$date = substr($date, 0, 10);
|
||||
$iso_date = $date_info['iso'] ?? '';
|
||||
|
||||
// Sichere HTML-Ausgabe
|
||||
$safe_date = htmlspecialchars($date, ENT_QUOTES, 'UTF-8');
|
||||
$safe_time = htmlspecialchars($time, ENT_QUOTES, 'UTF-8');
|
||||
$safe_iso_date = htmlspecialchars($iso_date, ENT_QUOTES, 'UTF-8');
|
||||
$safe_summary = htmlspecialchars($summary, ENT_QUOTES, 'UTF-8');
|
||||
?>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="py-2 px-4 border-b whitespace-nowrap"><?= $safe_date ?></td>
|
||||
<td class="py-2 px-4 border-b whitespace-nowrap">
|
||||
<?php if ($date_info['has_time'] ?? false): ?>
|
||||
<span class="local-time" data-iso-date="<?= $safe_iso_date ?>"><?= $safe_time ?></span>
|
||||
<?php else: ?>
|
||||
ganztägig
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="py-2 px-4 border-b"><?= $safe_summary ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php foreach ($filtered_events as $event): ?>
|
||||
<?php
|
||||
$start = $event['DTSTART'] ?? '';
|
||||
$end = $event['DTEND'] ?? '';
|
||||
$summary = $event['SUMMARY'] ?? '';
|
||||
$location = $event['LOCATION'] ?? '';
|
||||
$desc = $event['DESCRIPTION'] ?? '';
|
||||
$timezone = $event['DTSTART_TZID'] ?? null;
|
||||
|
||||
// Sichere Funktionsaufrufe mit Null-Checks
|
||||
$date_info = function_exists('format_ics_date_with_timezone')
|
||||
? format_ics_date_with_timezone($start, $timezone)
|
||||
: ['display' => '', 'has_time' => false, 'iso' => ''];
|
||||
|
||||
$date = $date_info['display'] ?? '';
|
||||
$time = ($date_info['has_time'] ?? false) ? substr($date, 11) : 'ganztägig';
|
||||
$date = substr($date, 0, 10);
|
||||
$iso_date = $date_info['iso'] ?? '';
|
||||
|
||||
// Sichere HTML-Ausgabe
|
||||
$safe_date = htmlspecialchars($date, ENT_QUOTES, 'UTF-8');
|
||||
$safe_time = htmlspecialchars($time, ENT_QUOTES, 'UTF-8');
|
||||
$safe_iso_date = htmlspecialchars($iso_date, ENT_QUOTES, 'UTF-8');
|
||||
$safe_summary = htmlspecialchars($summary, ENT_QUOTES, 'UTF-8');
|
||||
?>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="py-2 px-4 border-b whitespace-nowrap"><?= $safe_date ?></td>
|
||||
<td class="py-2 px-4 border-b whitespace-nowrap">
|
||||
<?php if ($date_info['has_time'] ?? false): ?>
|
||||
<span class="local-time" data-iso-date="<?= $safe_iso_date ?>"><?= $safe_time ?></span>
|
||||
<?php else: ?>
|
||||
ganztägig
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="py-2 px-4 border-b"><?= $safe_summary ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -214,7 +223,7 @@ if ($filter_jahr && $filter_monat) {
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<script>
|
||||
// Zeitzonenkonvertierung für lokale Zeiten
|
||||
function convertTimesToLocal() {
|
||||
@@ -226,23 +235,23 @@ if ($filter_jahr && $filter_monat) {
|
||||
// Erstelle ein Date-Objekt aus der ISO-Date
|
||||
// JavaScript erkennt automatisch UTC-Zeiten (mit Z oder +00:00)
|
||||
const date = new Date(isoDate);
|
||||
|
||||
|
||||
// Prüfe ob das Datum gültig ist
|
||||
if (isNaN(date.getTime())) {
|
||||
console.warn('Ungültiges Datum:', isoDate);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Formatiere die Zeit in der lokalen Zeitzone des Browsers
|
||||
const localTime = date.toLocaleTimeString('de-DE', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
});
|
||||
|
||||
|
||||
// Aktualisiere den Text
|
||||
element.textContent = localTime;
|
||||
|
||||
|
||||
// Debug-Information (kann später entfernt werden)
|
||||
console.log('Konvertiert:', isoDate, '->', localTime, 'in Zeitzone:', Intl.DateTimeFormat().resolvedOptions().timeZone);
|
||||
} catch (error) {
|
||||
@@ -253,7 +262,7 @@ if ($filter_jahr && $filter_monat) {
|
||||
}
|
||||
|
||||
// Zeitzonenkonvertierung beim Laden der Seite
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
convertTimesToLocal();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<?php snippet('layout', slots: true) ?>
|
||||
|
||||
<?php
|
||||
// Filterfunktionalität implementieren
|
||||
$posts = $page->children()->sortBy('date', 'desc');
|
||||
<?php
|
||||
// Filterfunktionalität implementieren
|
||||
$posts = $page->children()->sortBy('date', 'desc')->paginate(5);
|
||||
|
||||
// Nach Kategorie (Tag) filtern
|
||||
if($tag = param('tag')) {
|
||||
$posts = $posts->filterBy('tags', $tag, ',');
|
||||
}
|
||||
?>
|
||||
// Nach Kategorie (Tag) filtern
|
||||
if ($tag = param('tag')) {
|
||||
$posts = $posts->filterBy('tags', $tag, ',');
|
||||
}
|
||||
?>
|
||||
|
||||
<?php foreach($posts as $post): ?>
|
||||
<?php foreach ($posts as $post): ?>
|
||||
<article class="relative flex flex-col gap-8 lg:flex-row py-12">
|
||||
<div class="relative aspect-video sm:aspect-2/1 lg:aspect-square lg:w-64 lg:shrink-0">
|
||||
<img src="<?= $post->image()->url() ?>" alt="" class="absolute inset-0 size-full rounded-xl object-cover" />
|
||||
@@ -22,8 +22,9 @@
|
||||
<time class="text-gray-500"><?= $post->date()->toDate("d.m.Y") ?></time>
|
||||
</div>
|
||||
<div>
|
||||
<?php foreach($post->tags()->split() as $tag): ?>
|
||||
<a href="<?= $page->url(['params' => ['tag' => $tag]]) ?>" class="relative z-10 rounded-full bg-gray-50 px-3 py-1.5 font-medium text-gray-600 hover:bg-gray-100"><?= $tag ?></a>
|
||||
<?php foreach ($post->tags()->split() as $tag): ?>
|
||||
<a href="<?= $page->url(['params' => ['tag' => $tag]]) ?>"
|
||||
class="relative z-10 rounded-full bg-gray-50 px-3 py-1.5 font-medium text-gray-600 hover:bg-gray-100"><?= $tag ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -37,33 +38,62 @@
|
||||
<p><?= $post->summary() ?></p>
|
||||
</div>
|
||||
<?php if ($user = $post->author()->toUser()): ?>
|
||||
<div class="mt-6 flex border-t border-gray-900/5 pt-6">
|
||||
<div class="relative flex items-center gap-x-4">
|
||||
<?php if ($user->avatar()): ?>
|
||||
<img src="<?= $user->avatar()->url() ?>" alt="" class="size-10 rounded-full bg-gray-50" />
|
||||
<?php endif; ?>
|
||||
<div class="text-sm/6">
|
||||
<p>
|
||||
<span class="absolute inset-0"></span>
|
||||
<div class="mt-6 flex border-t border-gray-900/5 pt-6">
|
||||
<div class="relative flex items-center gap-x-4">
|
||||
<?php if ($user->avatar()): ?>
|
||||
<img src="<?= $user->avatar()->url() ?>" alt="" class="size-10 rounded-full bg-gray-50" />
|
||||
<?php endif; ?>
|
||||
<div class="text-sm/6">
|
||||
<p>
|
||||
<span class="absolute inset-0"></span>
|
||||
<div class="text-xl">
|
||||
<?= $user->username() ?>
|
||||
</div>
|
||||
</p>
|
||||
<p class="text-sm"><?= $user->role()->title() ?></p>
|
||||
</p>
|
||||
<p class="text-sm"><?= $user->role()->title() ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</article>
|
||||
<?php endforeach ?>
|
||||
|
||||
<?php if(param('tag')): ?>
|
||||
<?php endforeach ?>
|
||||
<?php $pagination = $posts->pagination(); ?>
|
||||
<?php if ($pagination->hasPages()): ?>
|
||||
<nav class="flex justify-between items-center my-12 border-t border-gray-100 pt-8">
|
||||
<?php if ($pagination->hasPrevPage()): ?>
|
||||
<a href="<?= $pagination->prevPageUrl() ?>"
|
||||
class="flex items-center gap-2 rounded-full bg-gray-50 px-4 py-2 text-sm font-medium text-gray-600 hover:bg-gray-100 transition-colors">
|
||||
← Neuere Beiträge
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<span class="flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium text-gray-300 cursor-not-allowed">
|
||||
← Neuere Beiträge
|
||||
</span>
|
||||
<?php endif ?>
|
||||
|
||||
<span class="text-xs font-medium text-gray-400">
|
||||
Seite <?= $pagination->page() ?> von <?= $pagination->pages() ?>
|
||||
</span>
|
||||
|
||||
<?php if ($pagination->hasNextPage()): ?>
|
||||
<a href="<?= $pagination->nextPageUrl() ?>"
|
||||
class="flex items-center gap-2 rounded-full bg-gray-50 px-4 py-2 text-sm font-medium text-gray-600 hover:bg-gray-100 transition-colors">
|
||||
Ältere Beiträge →
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<span class="flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium text-gray-300 cursor-not-allowed">
|
||||
Ältere Beiträge →
|
||||
</span>
|
||||
<?php endif ?>
|
||||
</nav>
|
||||
<?php endif ?>
|
||||
|
||||
|
||||
<?php if (param('tag')): ?>
|
||||
<div class="my-8">
|
||||
<a href="<?= $page->url() ?>" class="bg-gray-100 hover:bg-gray-200 text-gray-800 font-semibold py-2 px-4 rounded">
|
||||
Alle Beiträge anzeigen
|
||||
</a>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<?php endsnippet() ?>
|
||||
<?php endif ?><?php endsnippet() ?>
|
||||
@@ -1,5 +1,29 @@
|
||||
<?php snippet('layout', slots: true) ?>
|
||||
|
||||
<h1>Hallo Welt!</h1>
|
||||
|
||||
<?php endsnippet() ?>
|
||||
<?php
|
||||
// Wenn dies die Startseite ist, verwende die Home-Vorlage
|
||||
if ($page->isHomePage()) {
|
||||
snippet('layout', slots: true);
|
||||
?>
|
||||
<h1>Herzlich Willkommen!</h1>
|
||||
|
||||
<?= $page->text()->kirbytext() ?>
|
||||
|
||||
<?php snippet('home-news', [
|
||||
'news' => page('news')->children()->limit(3)->sortBy('date', 'desc'),
|
||||
]); ?>
|
||||
|
||||
<?php snippet('home-termine'); ?>
|
||||
|
||||
<?php snippet('puzzle'); ?>
|
||||
<?php
|
||||
endsnippet();
|
||||
} else {
|
||||
// Für andere Seiten
|
||||
snippet('layout', slots: true);
|
||||
?>
|
||||
<h1><?= $page->title()->esc() ?></h1>
|
||||
|
||||
<?= $page->text()->kirbytext() ?>
|
||||
<?php
|
||||
endsnippet();
|
||||
}
|
||||
?>
|
||||
|
||||