mirror of
https://github.com/Dvorinka/bizoni.git
synced 2026-06-04 02:32:57 +00:00
Compare commits
18 Commits
516161c1b3
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| a89d6e1a63 | |||
| 60a4b82931 | |||
| efa35518ab | |||
| cc6841e723 | |||
| 4c904a1546 | |||
| 76c447a395 | |||
| a6b47de1a4 | |||
| 2f65bc03e6 | |||
| ac9930767e | |||
| 4f3164956a | |||
| f8a6abf391 | |||
| 45facf7aa0 | |||
| c9c322ff95 | |||
| 3a7c1bbcba | |||
| 03b9abd32d | |||
| 21574a8b30 | |||
| 4773e4cab1 | |||
| 362f55e28a |
Vendored
+2
-2
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"livePreview.defaultPreviewPath": "/ukol.html"
|
||||
{
|
||||
"livePreview.defaultPreviewPath": "/ukol.html"
|
||||
}
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full">
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
# Remote Blog Management - Complete Guide
|
||||
|
||||
## 🎯 Goal
|
||||
Remove local blog files and work exclusively with remote server blogs.
|
||||
|
||||
## 📋 Options Available
|
||||
|
||||
### Option 1: Quick Remove Local Blogs
|
||||
```bash
|
||||
# Run this in your bizoni directory
|
||||
./remove-local-blogs.sh
|
||||
```
|
||||
|
||||
### Option 2: Ubuntu Server Management Script
|
||||
```bash
|
||||
# Upload to your Ubuntu server and run
|
||||
./ubuntu-remote-blogs.sh migrate
|
||||
```
|
||||
|
||||
### Option 3: Backend Configuration (Recommended)
|
||||
Update backend to work with remote blogs only.
|
||||
|
||||
## 🚀 Recommended Deployment Steps
|
||||
|
||||
### Step 1: Remove Local Blogs
|
||||
```bash
|
||||
cd /home/tdvorak/Desktop/HTML_Projekty/bizoni
|
||||
./remove-local-blogs.sh
|
||||
```
|
||||
|
||||
### Step 2: Update Backend Configuration
|
||||
The backend is now configured to work with remote blogs at `/var/www/bizoni/blog`.
|
||||
|
||||
You can set the remote path with environment variable:
|
||||
```bash
|
||||
export REMOTE_BLOG_DIR="/var/www/bizoni/blog"
|
||||
```
|
||||
|
||||
### Step 3: Deploy Backend to Server
|
||||
1. Build the updated backend
|
||||
2. Deploy to your server
|
||||
3. Set REMOTE_BLOG_DIR environment variable
|
||||
|
||||
### Step 4: Run Migration on Server
|
||||
```bash
|
||||
# On your Ubuntu server
|
||||
./ubuntu-remote-blogs.sh migrate
|
||||
```
|
||||
|
||||
## 📁 File Structure After Changes
|
||||
|
||||
### Local (Development)
|
||||
```
|
||||
bizoni/
|
||||
├── backend/main.go # Updated for remote blogs
|
||||
├── admin/new.html # Updated with new fields
|
||||
├── js/admin-auth.js # Login persistence
|
||||
├── tools/migrate_slugs.go # Migration tool
|
||||
├── remove-local-blogs.sh # Local cleanup script
|
||||
└── ubuntu-remote-blogs.sh # Server management script
|
||||
```
|
||||
|
||||
### Server (Production)
|
||||
```
|
||||
/var/www/bizoni/
|
||||
├── blog/
|
||||
│ ├── 0000.html # Original numeric files
|
||||
│ ├── 0001.html
|
||||
│ ├── jdeme-do-finale.html # New slug files
|
||||
│ └── 1-zapas-final-score.html
|
||||
├── img/blog/
|
||||
│ ├── 0000.png
|
||||
│ └── 0001.png
|
||||
└── backend # Updated backend
|
||||
```
|
||||
|
||||
## 🔧 Ubuntu Server Script Usage
|
||||
|
||||
### List All Blogs
|
||||
```bash
|
||||
./ubuntu-remote-blogs.sh list
|
||||
```
|
||||
|
||||
### Migrate All Blogs to Slugs
|
||||
```bash
|
||||
./ubuntu-remote-blogs.sh migrate
|
||||
```
|
||||
|
||||
### Show Blog Info
|
||||
```bash
|
||||
./ubuntu-remote-blogs.sh info 0030
|
||||
```
|
||||
|
||||
### Add Slug to Specific Blog
|
||||
```bash
|
||||
./ubuntu-remote-blogs.sh add-slug 0030
|
||||
```
|
||||
|
||||
### Create Backup
|
||||
```bash
|
||||
./ubuntu-remote-blogs.sh backup
|
||||
```
|
||||
|
||||
## 🌐 URL Structure After Migration
|
||||
|
||||
### Before
|
||||
- `/blog/0030.html`
|
||||
- `/blog/0001.html`
|
||||
|
||||
### After
|
||||
- `/blog/jdeme-do-finale` (clean URL)
|
||||
- `/blog/1-zapas-final-score`
|
||||
- `/blog/0030.html` (still works for backward compatibility)
|
||||
|
||||
## ⚠️ Important Notes
|
||||
|
||||
1. **Backup First**: Always create backup before migration
|
||||
2. **Test Locally**: Test backend with REMOTE_BLOG_DIR set to local copy
|
||||
3. **Deploy Gradually**: Deploy backend first, then run migration
|
||||
4. **Environment Variables**: Use REMOTE_BLOG_DIR for flexibility
|
||||
|
||||
## 🔄 Environment Variables
|
||||
|
||||
Set these on your server:
|
||||
|
||||
```bash
|
||||
# Path to remote blog directory
|
||||
export REMOTE_BLOG_DIR="/var/www/bizoni/blog"
|
||||
|
||||
# Port for backend (if needed)
|
||||
export PORT="8080"
|
||||
|
||||
# Static files path
|
||||
export STATIC_PATH="/var/www/bizoni"
|
||||
```
|
||||
|
||||
## 🚨 Troubleshooting
|
||||
|
||||
### Backend Can't Find Blogs
|
||||
```bash
|
||||
# Check if directory exists
|
||||
ls -la /var/www/bizoni/blog
|
||||
|
||||
# Set correct path
|
||||
export REMOTE_BLOG_DIR="/correct/path/to/blogs"
|
||||
```
|
||||
|
||||
### Migration Script Fails
|
||||
```bash
|
||||
# Make script executable
|
||||
chmod +x ubuntu-remote-blogs.sh
|
||||
|
||||
# Update paths in script
|
||||
nano ubuntu-remote-blogs.sh
|
||||
```
|
||||
|
||||
### Permission Issues
|
||||
```bash
|
||||
# Fix permissions on server
|
||||
sudo chown -R www-data:www-data /var/www/bizoni/blog
|
||||
sudo chmod -R 755 /var/www/bizoni/blog
|
||||
```
|
||||
|
||||
## 📞 Next Steps
|
||||
|
||||
1. **Choose your option** (1, 2, or 3)
|
||||
2. **Remove local blogs** with the provided script
|
||||
3. **Deploy updated backend** to server
|
||||
4. **Run migration** on server
|
||||
5. **Test new URLs** and admin interface
|
||||
|
||||
Your blog system will then work entirely with remote server blogs! 🎉
|
||||
@@ -40,6 +40,7 @@
|
||||
.kpi .it { background:#f3f4f6; border:1px solid var(--border); border-radius:8px; padding:10px; text-align:center; }
|
||||
small.code { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; background:#f3f4f6; border:1px solid var(--border); border-radius:6px; padding:2px 6px; }
|
||||
</style>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="admin-with-sidenav">
|
||||
<aside class="admin-sidenav">
|
||||
@@ -233,7 +234,13 @@
|
||||
s.textContent = 'Načítám…';
|
||||
const res = await fetch('/api/blog/latest?limit=12');
|
||||
if (!res.ok) throw new Error('HTTP '+res.status);
|
||||
const items = await res.json();
|
||||
let items = await res.json();
|
||||
// Defensive sort: numeric ID descending ensures newest first regardless of API ordering
|
||||
items.sort((a,b)=>{
|
||||
const ai = parseInt(a.id,10); const bi = parseInt(b.id,10);
|
||||
if (!isNaN(ai) && !isNaN(bi)) return bi-ai;
|
||||
return (b.id||'').localeCompare(a.id||'');
|
||||
});
|
||||
grid.innerHTML='';
|
||||
if (!Array.isArray(items) || items.length === 0) {
|
||||
grid.innerHTML = '<div class="muted">Žádné příspěvky.</div>';
|
||||
|
||||
+8
-1
@@ -18,6 +18,7 @@
|
||||
header { display:flex; justify-content: space-between; align-items:center; margin-bottom: 16px; }
|
||||
.badge { background: #111827; color: #fff; padding: 6px 10px; border-radius: 999px; font-size: 12px; }
|
||||
</style>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="admin-with-sidenav">
|
||||
<aside class="admin-sidenav">
|
||||
@@ -52,7 +53,13 @@
|
||||
try {
|
||||
const res = await fetch('/api/blog/latest?limit=12');
|
||||
if (!res.ok) throw new Error('HTTP '+res.status);
|
||||
const items = await res.json();
|
||||
let items = await res.json();
|
||||
// Defensive sort: numeric ID descending ensures newest first regardless of API ordering
|
||||
items.sort((a,b)=>{
|
||||
const ai = parseInt(a.id,10); const bi = parseInt(b.id,10);
|
||||
if (!isNaN(ai) && !isNaN(bi)) return bi-ai;
|
||||
return (b.id||'').localeCompare(a.id||'');
|
||||
});
|
||||
status.textContent = `Nalezeno: ${items.length}`;
|
||||
mount.innerHTML = '';
|
||||
if (!Array.isArray(items) || items.length === 0) {
|
||||
|
||||
+114
-4
@@ -32,6 +32,7 @@
|
||||
<link href="https://cdn.jsdelivr.net/npm/quill@1.3.7/dist/quill.snow.css" rel="stylesheet">
|
||||
<script src="https://cdn.jsdelivr.net/npm/quill@1.3.7/dist/quill.min.js"></script>
|
||||
<script src="../js/admin-auth.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="admin-with-sidenav">
|
||||
<aside class="admin-sidenav">
|
||||
@@ -62,6 +63,23 @@
|
||||
<label for="title">Titulek</label>
|
||||
<input type="text" id="title" name="title" placeholder="Např. FC Bizoni vyhráli finále" required />
|
||||
</div>
|
||||
<div>
|
||||
<label for="slug">URL slug (použije se v adrese)</label>
|
||||
<input type="text" id="slug" name="slug" placeholder="napr-fc-bizoni-vyhrali-finale" pattern="[a-z0-9-]+" title="Pouze malá písmena, číslice a pomlčky" />
|
||||
<div class="muted" style="margin-top:6px">Automaticky se vygeneruje z titulku, pokud nezadáte vlastní.</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="annotation">Anotace (krátký popis pro SEO a sociální sítě)</label>
|
||||
<input type="text" id="annotation" name="annotation" placeholder="Krátký popis článku (150-300 znaků)" maxlength="300" />
|
||||
<div class="muted" style="margin-top:6px">Použije se pro SEO description a při sdílení na sociálních sítích.</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="content-mode">Způsob zadávání obsahu</label>
|
||||
<select id="content-mode" name="content-mode" style="width: 100%; padding: 10px; border:1px solid #d1d5db; border-radius: 8px; font-size: 14px;">
|
||||
<option value="visual">Vizuální editor (Quill)</option>
|
||||
<option value="html">HTML kód</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="categories">Kategorie (oddělené čárkou)</label>
|
||||
<input type="text" id="categories" name="categories" placeholder="Zápasy, O nás" />
|
||||
@@ -87,7 +105,12 @@
|
||||
</div>
|
||||
<div>
|
||||
<label for="editor">Obsah (vizuální editor)</label>
|
||||
<div id="editor"></div>
|
||||
<div id="visual-editor-wrapper">
|
||||
<div id="editor"></div>
|
||||
</div>
|
||||
<div id="html-editor-wrapper" style="display: none;">
|
||||
<textarea id="html-content" name="html-content" rows="12" placeholder="Zadejte HTML kód obsahu..." style="width: 100%; padding: 10px; border:1px solid #d1d5db; border-radius: 8px; font-size: 14px; font-family: 'Courier New', monospace;"></textarea>
|
||||
</div>
|
||||
<!-- Hidden textarea to submit HTML (kept focusable-safe by moving offscreen) -->
|
||||
<textarea id="content" name="content" rows="12" style="position:absolute; left:-10000px; width:1px; height:1px; overflow:hidden;"></textarea>
|
||||
<div class="muted">Obsah bude vložen do sekce <code><div class="text lte-text-page clearfix">...</div></code> podle šablony <code>blog/0030.html</code>.</div>
|
||||
@@ -140,6 +163,60 @@
|
||||
const inputId = document.getElementById('post-id');
|
||||
const inputTitle = document.getElementById('title');
|
||||
const inputCats = document.getElementById('categories');
|
||||
const inputSlug = document.getElementById('slug');
|
||||
const inputAnnotation = document.getElementById('annotation');
|
||||
const contentModeSelect = document.getElementById('content-mode');
|
||||
const visualEditorWrapper = document.getElementById('visual-editor-wrapper');
|
||||
const htmlEditorWrapper = document.getElementById('html-editor-wrapper');
|
||||
const htmlContentTextarea = document.getElementById('html-content');
|
||||
|
||||
// Content mode switching
|
||||
contentModeSelect.addEventListener('change', () => {
|
||||
const mode = contentModeSelect.value;
|
||||
if (mode === 'visual') {
|
||||
visualEditorWrapper.style.display = 'block';
|
||||
htmlEditorWrapper.style.display = 'none';
|
||||
} else {
|
||||
visualEditorWrapper.style.display = 'none';
|
||||
htmlEditorWrapper.style.display = 'block';
|
||||
// Sync current content to HTML textarea
|
||||
const currentContent = quill.root.innerHTML;
|
||||
htmlContentTextarea.value = currentContent;
|
||||
}
|
||||
});
|
||||
|
||||
// Sync content from HTML to visual when switching back
|
||||
contentModeSelect.addEventListener('change', () => {
|
||||
if (contentModeSelect.value === 'visual') {
|
||||
const htmlContent = htmlContentTextarea.value;
|
||||
if (htmlContent.trim()) {
|
||||
quill.root.innerHTML = htmlContent;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Auto-generate slug from title
|
||||
function generateSlug(text) {
|
||||
return text
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/[^\w\s-]/g, '') // Remove special characters
|
||||
.replace(/[\s_-]+/g, '-') // Replace spaces and underscores with hyphen
|
||||
.replace(/^-+|-+$/g, ''); // Remove leading/trailing hyphens
|
||||
}
|
||||
|
||||
// Update slug when title changes (if slug is empty)
|
||||
inputTitle.addEventListener('input', () => {
|
||||
if (!inputSlug.value || inputSlug.dataset.autoGenerated === 'true') {
|
||||
inputSlug.value = generateSlug(inputTitle.value);
|
||||
inputSlug.dataset.autoGenerated = 'true';
|
||||
}
|
||||
});
|
||||
|
||||
// Mark slug as manually edited when user types in it
|
||||
inputSlug.addEventListener('input', () => {
|
||||
inputSlug.dataset.autoGenerated = 'false';
|
||||
});
|
||||
|
||||
let pastedBlob = null; // holds clipboard/fetched blob if provided
|
||||
|
||||
@@ -209,8 +286,21 @@
|
||||
const data = await res.json();
|
||||
inputId.value = data.id || id;
|
||||
inputTitle.value = data.title || '';
|
||||
inputSlug.value = data.slug || '';
|
||||
inputAnnotation.value = data.annotation || '';
|
||||
inputCats.value = Array.isArray(data.categories) ? data.categories.join(', ') : '';
|
||||
quill.root.innerHTML = data.content_html || '';
|
||||
|
||||
// Set content mode and load content
|
||||
if (data.content_mode === 'html') {
|
||||
contentModeSelect.value = 'html';
|
||||
htmlContentTextarea.value = data.content_html || '';
|
||||
visualEditorWrapper.style.display = 'none';
|
||||
htmlEditorWrapper.style.display = 'block';
|
||||
} else {
|
||||
contentModeSelect.value = 'visual';
|
||||
quill.root.innerHTML = data.content_html || '';
|
||||
}
|
||||
|
||||
// show current image preview
|
||||
preview.style.display = 'flex';
|
||||
previewImg.src = '/img/blog/' + (data.id || id) + '.png';
|
||||
@@ -245,10 +335,22 @@
|
||||
// Move Quill HTML into the hidden textarea
|
||||
// Merge category checkboxes into text input
|
||||
reconcileCategories();
|
||||
const html = quill.root.innerHTML;
|
||||
|
||||
// Get content based on mode
|
||||
let html;
|
||||
if (contentModeSelect.value === 'html') {
|
||||
html = htmlContentTextarea.value.trim();
|
||||
} else {
|
||||
html = quill.root.innerHTML;
|
||||
}
|
||||
|
||||
document.getElementById('content').value = html;
|
||||
|
||||
// Validate content is not empty (avoid browser required on hidden field)
|
||||
const plain = quill.getText().trim();
|
||||
const plain = contentModeSelect.value === 'html' ?
|
||||
html.replace(/<[^>]*>/g, '').trim() : // Strip HTML for validation
|
||||
quill.getText().trim();
|
||||
|
||||
if (!plain) {
|
||||
result.textContent = 'Vyplňte obsah článku.';
|
||||
result.classList.add('err');
|
||||
@@ -256,6 +358,10 @@
|
||||
return;
|
||||
}
|
||||
const fd = new FormData(form);
|
||||
// Add annotation and content mode to form data
|
||||
fd.set('annotation', inputAnnotation.value);
|
||||
fd.set('content_mode', contentModeSelect.value);
|
||||
|
||||
// Prefer pasted/fetched blob if present when no file was chosen
|
||||
if (pastedBlob && !(imageInput.files && imageInput.files[0])) {
|
||||
const ext = (pastedBlob.type === 'image/jpeg') ? 'jpg' : 'png';
|
||||
@@ -300,6 +406,10 @@
|
||||
result.appendChild(a);
|
||||
form.reset(); preview.style.display = 'none';
|
||||
quill.setContents([]);
|
||||
htmlContentTextarea.value = '';
|
||||
contentModeSelect.value = 'visual';
|
||||
visualEditorWrapper.style.display = 'block';
|
||||
htmlEditorWrapper.style.display = 'none';
|
||||
}
|
||||
} catch (err) {
|
||||
result.textContent = 'Chyba: ' + (err.message || err);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
.search { border:1px solid #d1d5db; padding: 6px 10px; border-radius: 8px; min-width: 260px; }
|
||||
.status { margin: 12px 0; color: #6b7280; }
|
||||
</style>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="admin-with-sidenav">
|
||||
<aside class="admin-sidenav">
|
||||
|
||||
@@ -1,120 +1,120 @@
|
||||
Search Clubs
|
||||
GET /club/search?q=QUERY
|
||||
|
||||
Find clubs on fotbal.cz. Supports football and futsal clubs.
|
||||
|
||||
Example: https://facr.tdvorak.dev/club/search?q=Sparta
|
||||
|
||||
Response shape
|
||||
{
|
||||
"query": "Sparta",
|
||||
"count": 2,
|
||||
"results": [
|
||||
{
|
||||
"name": "AC Sparta Praha",
|
||||
"club_id": "",
|
||||
"club_type": "football",
|
||||
"url": "https://www.fotbal.cz/...",
|
||||
"logo_url": "https://.../logo.png",
|
||||
"category": "Muži",
|
||||
"address": "..."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Club Info + Matches
|
||||
GET /club/{type}/{id} - id must be provided in the setup of the club
|
||||
|
||||
{type}: football
|
||||
{id}: club UUID from fotbal.cz
|
||||
Example: https://facr.tdvorak.dev/club/football/00000000-0000-0000-0000-000000000000
|
||||
|
||||
Response shape
|
||||
{
|
||||
"name": "AC Sparta Praha",
|
||||
"club_id": "00000000-0000-0000-0000-000000000000",
|
||||
"club_type": "football",
|
||||
"club_internal_id": "123456",
|
||||
"url": "https://www.fotbal.cz/...",
|
||||
"logo_url": "https://is1.fotbal.cz/media/kluby/.../logo.jpg",
|
||||
"address": "Milady Horákové 98, 160 00 Praha 6",
|
||||
"category": "Muži A",
|
||||
"competitions": [
|
||||
{
|
||||
"id": "12345",
|
||||
"code": "1. LIGA",
|
||||
"name": "Fortuna Liga",
|
||||
"team_count": "16",
|
||||
"matches_link": "https://www.fotbal.cz/...",
|
||||
"matches": [
|
||||
{
|
||||
"date_time": "12.08.2023 18:00",
|
||||
"home": "AC Sparta Praha",
|
||||
"home_id": "00000000-0000-0000-0000-000000000000",
|
||||
"home_logo_url": "https://.../sparta.png",
|
||||
"away": "SK Slavia Praha",
|
||||
"away_id": "11111111-1111-1111-1111-111111111111",
|
||||
"away_logo_url": "https://.../slavia.png",
|
||||
"score": "2:1",
|
||||
"venue": "Stadion Letná",
|
||||
"match_id": "match12345",
|
||||
"report_url": "https://www.fotbal.cz/..."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Club Tables (Standings)
|
||||
GET /club/{type}/{id}/table - id must be provided in the setup of the club
|
||||
|
||||
Returns standings (overall table) for each competition of the club.
|
||||
|
||||
Example: https://facr.tdvorak.dev/club/football/00000000-0000-0000-0000-000000000000/table
|
||||
|
||||
Response shape
|
||||
{
|
||||
"name": "AC Sparta Praha",
|
||||
"club_id": "00000000-0000-0000-0000-000000000000",
|
||||
"club_type": "football",
|
||||
"club_internal_id": "123456",
|
||||
"url": "https://www.fotbal.cz/...",
|
||||
"logo_url": "https://is1.fotbal.cz/media/kluby/.../logo.jpg",
|
||||
"competitions": [
|
||||
{
|
||||
"id": "12345",
|
||||
"code": "1. LIGA",
|
||||
"name": "Fortuna Liga",
|
||||
"team_count": "16",
|
||||
"matches_link": "https://www.fotbal.cz/...",
|
||||
"table": {
|
||||
"overall": [
|
||||
{
|
||||
"rank": "1",
|
||||
"team": "AC Sparta Praha",
|
||||
"team_id": "00000000-0000-0000-0000-000000000000",
|
||||
"team_logo_url": "https://.../sparta.png",
|
||||
"played": "10",
|
||||
"wins": "8",
|
||||
"draws": "2",
|
||||
"losses": "0",
|
||||
"score": "25:5",
|
||||
"points": "26"
|
||||
},
|
||||
{
|
||||
"rank": "2",
|
||||
"team": "SK Slavia Praha",
|
||||
"team_id": "11111111-1111-1111-1111-111111111111",
|
||||
"team_logo_url": "https://.../slavia.png",
|
||||
"played": "10",
|
||||
"wins": "7",
|
||||
"draws": "2",
|
||||
"losses": "1",
|
||||
"score": "20:8",
|
||||
"points": "23"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
Search Clubs
|
||||
GET /club/search?q=QUERY
|
||||
|
||||
Find clubs on fotbal.cz. Supports football and futsal clubs.
|
||||
|
||||
Example: https://facr.tdvorak.dev/club/search?q=Sparta
|
||||
|
||||
Response shape
|
||||
{
|
||||
"query": "Sparta",
|
||||
"count": 2,
|
||||
"results": [
|
||||
{
|
||||
"name": "AC Sparta Praha",
|
||||
"club_id": "",
|
||||
"club_type": "football",
|
||||
"url": "https://www.fotbal.cz/...",
|
||||
"logo_url": "https://.../logo.png",
|
||||
"category": "Muži",
|
||||
"address": "..."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Club Info + Matches
|
||||
GET /club/{type}/{id} - id must be provided in the setup of the club
|
||||
|
||||
{type}: football
|
||||
{id}: club UUID from fotbal.cz
|
||||
Example: https://facr.tdvorak.dev/club/football/00000000-0000-0000-0000-000000000000
|
||||
|
||||
Response shape
|
||||
{
|
||||
"name": "AC Sparta Praha",
|
||||
"club_id": "00000000-0000-0000-0000-000000000000",
|
||||
"club_type": "football",
|
||||
"club_internal_id": "123456",
|
||||
"url": "https://www.fotbal.cz/...",
|
||||
"logo_url": "https://is1.fotbal.cz/media/kluby/.../logo.jpg",
|
||||
"address": "Milady Horákové 98, 160 00 Praha 6",
|
||||
"category": "Muži A",
|
||||
"competitions": [
|
||||
{
|
||||
"id": "12345",
|
||||
"code": "1. LIGA",
|
||||
"name": "Fortuna Liga",
|
||||
"team_count": "16",
|
||||
"matches_link": "https://www.fotbal.cz/...",
|
||||
"matches": [
|
||||
{
|
||||
"date_time": "12.08.2023 18:00",
|
||||
"home": "AC Sparta Praha",
|
||||
"home_id": "00000000-0000-0000-0000-000000000000",
|
||||
"home_logo_url": "https://.../sparta.png",
|
||||
"away": "SK Slavia Praha",
|
||||
"away_id": "11111111-1111-1111-1111-111111111111",
|
||||
"away_logo_url": "https://.../slavia.png",
|
||||
"score": "2:1",
|
||||
"venue": "Stadion Letná",
|
||||
"match_id": "match12345",
|
||||
"report_url": "https://www.fotbal.cz/..."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Club Tables (Standings)
|
||||
GET /club/{type}/{id}/table - id must be provided in the setup of the club
|
||||
|
||||
Returns standings (overall table) for each competition of the club.
|
||||
|
||||
Example: https://facr.tdvorak.dev/club/football/00000000-0000-0000-0000-000000000000/table
|
||||
|
||||
Response shape
|
||||
{
|
||||
"name": "AC Sparta Praha",
|
||||
"club_id": "00000000-0000-0000-0000-000000000000",
|
||||
"club_type": "football",
|
||||
"club_internal_id": "123456",
|
||||
"url": "https://www.fotbal.cz/...",
|
||||
"logo_url": "https://is1.fotbal.cz/media/kluby/.../logo.jpg",
|
||||
"competitions": [
|
||||
{
|
||||
"id": "12345",
|
||||
"code": "1. LIGA",
|
||||
"name": "Fortuna Liga",
|
||||
"team_count": "16",
|
||||
"matches_link": "https://www.fotbal.cz/...",
|
||||
"table": {
|
||||
"overall": [
|
||||
{
|
||||
"rank": "1",
|
||||
"team": "AC Sparta Praha",
|
||||
"team_id": "00000000-0000-0000-0000-000000000000",
|
||||
"team_logo_url": "https://.../sparta.png",
|
||||
"played": "10",
|
||||
"wins": "8",
|
||||
"draws": "2",
|
||||
"losses": "0",
|
||||
"score": "25:5",
|
||||
"points": "26"
|
||||
},
|
||||
{
|
||||
"rank": "2",
|
||||
"team": "SK Slavia Praha",
|
||||
"team_id": "11111111-1111-1111-1111-111111111111",
|
||||
"team_logo_url": "https://.../slavia.png",
|
||||
"played": "10",
|
||||
"wins": "7",
|
||||
"draws": "2",
|
||||
"losses": "1",
|
||||
"score": "20:8",
|
||||
"points": "23"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+15
-15
@@ -1,15 +1,15 @@
|
||||
FROM golang:1.22-alpine AS build
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN go build -o server ./main.go
|
||||
|
||||
FROM alpine:3.20
|
||||
WORKDIR /app
|
||||
# HTTPS for /img/clean proxy requires CA bundle
|
||||
RUN apk add --no-cache ca-certificates \
|
||||
&& update-ca-certificates
|
||||
# Optional: timezone data for precise Prague time
|
||||
# RUN apk add --no-cache tzdata
|
||||
COPY --from=build /app/server /app/server
|
||||
EXPOSE 8080
|
||||
ENTRYPOINT ["/app/server"]
|
||||
FROM golang:1.22-alpine AS build
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN go build -o server ./main.go
|
||||
|
||||
FROM alpine:3.20
|
||||
WORKDIR /app
|
||||
# HTTPS for /img/clean proxy requires CA bundle
|
||||
RUN apk add --no-cache ca-certificates \
|
||||
&& update-ca-certificates
|
||||
# Optional: timezone data for precise Prague time
|
||||
# RUN apk add --no-cache tzdata
|
||||
COPY --from=build /app/server /app/server
|
||||
EXPOSE 8080
|
||||
ENTRYPOINT ["/app/server"]
|
||||
|
||||
+718
-169
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,170 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TestListLatestBlogsOrdering verifies that listLatestBlogs returns items
|
||||
// sorted by numeric ID descending, regardless of file timestamps or order.
|
||||
func TestListLatestBlogsOrdering(t *testing.T) {
|
||||
// Create a temp directory structure mimicking the remote server
|
||||
tmpDir := t.TempDir()
|
||||
blogDir := filepath.Join(tmpDir, "blog")
|
||||
imgDir := filepath.Join(tmpDir, "img", "blog")
|
||||
if err := os.MkdirAll(blogDir, 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.MkdirAll(imgDir, 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Create numeric blog files with IDs spanning a wide range.
|
||||
// We intentionally create them in non-numeric order and touch
|
||||
// old IDs with newer timestamps to simulate a migration.
|
||||
files := []struct {
|
||||
id string
|
||||
slug string
|
||||
title string
|
||||
}{
|
||||
{"0031", "vstupujeme-spolecne-do-druhe-ligy", "VSTUPUJEME SPOLEČNĚ DO DRUHÉ LIGY!"},
|
||||
{"0032", "nova-mise-pred-nami", "NOVÁ MISE PŘED NÁMI!"},
|
||||
{"0033", "superpohar-divizi-je-zde", "SUPERPOHÁR DIVIZÍ JE ZDE!"},
|
||||
{"0034", "superpohar-je-nas", "SUPERPOHÁR JE NÁŠ!"},
|
||||
{"0035", "fotoreport-1", "FOTOREPORT"},
|
||||
{"0036", "regionalni-finale-je-tady", "REGIONÁLNÍ FINÁLE JE TADY!"},
|
||||
{"0037", "bizoni-slavi-postup", "BIZONI SLAVÍ POSTUP!"},
|
||||
{"0038", "fotoreport-2", "FOTOREPORT"},
|
||||
{"0039", "2-liga-je-tu", "2. LIGA JE TU!"},
|
||||
{"0040", "pred-startem-sezony-1", "PŘED STARTEM SEZONY"},
|
||||
{"0041", "pred-startem-sezony-2", "PŘED STARTEM SEZÓNY"},
|
||||
{"0042", "podpora-futsalu", "Podpora Futsalu"},
|
||||
{"0169", "stepan-stodulka-fanouskum-3", "Štěpán Stodůlka fanouškům: Budujeme klub, který bude dlouhodobě silný"},
|
||||
{"0170", "martin-prokes-fanouskum", "Martin Prokeš fanouškům: První futsalová sezóna přinesla cenné zkušenosti"},
|
||||
{"0171", "andrea-adamikova-fanouskum", "Andrea Adamíková fanouškům: Druhé místo je motivací do další práce"},
|
||||
{"0172", "stepan-stodulka-fanouskum-2", "Štěpán Stodůlka fanouškům: Bizonky jsou hrdou součástí našeho klubu"},
|
||||
{"0173", "martin-lapcik-fanouskum", "Martin Lapčík fanouškům: První rok bizoní mládeže nás všechny nadchl"},
|
||||
{"0174", "marek-stojaspal-fanouskum", "Marek Stojaspal fanouškům: Mládež položila pevné základy budoucnosti"},
|
||||
{"0175", "stepan-stodulka-fanouskum-1", "Štěpán Stodůlka fanouškům: Mládež ukázala velký potenciál"},
|
||||
{"0176", "dekujeme-my-jsme-tu-diky-vam", "DĚKUJEME, MY JSME TU DÍKY VÁM!"},
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
// Create numeric HTML file with slug meta tag
|
||||
htmlContent := fmt.Sprintf(`<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="slug" content="%s">
|
||||
</head>
|
||||
<body>
|
||||
<h1 class="lte-header">%s</h1>
|
||||
<div class="text lte-text-page clearfix">content</div>
|
||||
</body>
|
||||
</html>`, f.slug, f.title)
|
||||
numericPath := filepath.Join(blogDir, f.id+".html")
|
||||
if err := os.WriteFile(numericPath, []byte(htmlContent), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Create corresponding slug file (duplicate content)
|
||||
slugPath := filepath.Join(blogDir, f.slug+".html")
|
||||
if err := os.WriteFile(slugPath, []byte(htmlContent), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Create a dummy image
|
||||
imgPath := filepath.Join(imgDir, f.id+".png")
|
||||
if err := os.WriteFile(imgPath, []byte("fake png"), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Touch some old IDs with a newer timestamp to simulate post-migration
|
||||
// (this is the exact condition that broke the old sorting).
|
||||
// We sleep briefly between creation and touch so the timestamp is definitely newer.
|
||||
importTime := time.Now()
|
||||
for _, oldID := range []string{"0031", "0032", "0042"} {
|
||||
fpath := filepath.Join(blogDir, oldID+".html")
|
||||
if err := os.Chtimes(fpath, importTime, importTime); err != nil {
|
||||
// ignore errors on Chtimes
|
||||
}
|
||||
}
|
||||
|
||||
// Call listLatestBlogs
|
||||
items, err := listLatestBlogs(tmpDir, 12)
|
||||
if err != nil {
|
||||
t.Fatalf("listLatestBlogs error: %v", err)
|
||||
}
|
||||
if len(items) != 12 {
|
||||
t.Fatalf("expected 12 items, got %d", len(items))
|
||||
}
|
||||
|
||||
// Verify IDs are sorted descending (newest first)
|
||||
for i := 0; i < len(items)-1; i++ {
|
||||
curr, _ := strconv.Atoi(items[i].ID)
|
||||
next, _ := strconv.Atoi(items[i+1].ID)
|
||||
if curr <= next {
|
||||
t.Errorf("IDs not sorted descending at index %d: %s (%d) <= %s (%d)",
|
||||
i, items[i].ID, curr, items[i+1].ID, next)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the first item is the newest (0176)
|
||||
if items[0].ID != "0176" {
|
||||
t.Errorf("expected first item ID to be 0176, got %s (title: %s)", items[0].ID, items[0].Title)
|
||||
}
|
||||
if items[1].ID != "0175" {
|
||||
t.Errorf("expected second item ID to be 0175, got %s", items[1].ID)
|
||||
}
|
||||
|
||||
// Verify deduplication: total unique posts should be 20 (not 40)
|
||||
allItems, err := listLatestBlogs(tmpDir, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("listLatestBlogs unlimited error: %v", err)
|
||||
}
|
||||
if len(allItems) != 20 {
|
||||
t.Errorf("expected 20 unique items after dedup, got %d", len(allItems))
|
||||
}
|
||||
|
||||
// Verify all items are sorted descending
|
||||
sorted := sort.SliceIsSorted(allItems, func(i, j int) bool {
|
||||
ii, _ := strconv.Atoi(allItems[i].ID)
|
||||
jj, _ := strconv.Atoi(allItems[j].ID)
|
||||
return ii > jj
|
||||
})
|
||||
if !sorted {
|
||||
t.Error("allItems are not sorted by numeric ID descending")
|
||||
}
|
||||
}
|
||||
|
||||
// TestListLatestBlogsNoSlug verifies numeric-only blogs still sort correctly.
|
||||
func TestListLatestBlogsNoSlug(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
blogDir := filepath.Join(tmpDir, "blog")
|
||||
imgDir := filepath.Join(tmpDir, "img", "blog")
|
||||
os.MkdirAll(blogDir, 0755)
|
||||
os.MkdirAll(imgDir, 0755)
|
||||
|
||||
for _, id := range []string{"0001", "0005", "0010", "0002"} {
|
||||
content := fmt.Sprintf(`<html><head></head><body><h1 class="lte-header">Title %s</h1></body></html>`, id)
|
||||
os.WriteFile(filepath.Join(blogDir, id+".html"), []byte(content), 0644)
|
||||
os.WriteFile(filepath.Join(imgDir, id+".png"), []byte("png"), 0644)
|
||||
}
|
||||
|
||||
items, err := listLatestBlogs(tmpDir, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expected := []string{"0010", "0005", "0002", "0001"}
|
||||
if len(items) != len(expected) {
|
||||
t.Fatalf("expected %d items, got %d", len(expected), len(items))
|
||||
}
|
||||
for i, exp := range expected {
|
||||
if items[i].ID != exp {
|
||||
t.Errorf("index %d: expected %s, got %s", i, exp, items[i].ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
//go:build ignore
|
||||
|
||||
// Migration script to clean up duplicate blog files
|
||||
// Run with: go run migrate_blogs.go <blog_directory>
|
||||
//
|
||||
// This script:
|
||||
// 1. Scans all blog HTML files
|
||||
// 2. Groups numeric files with their slug counterparts
|
||||
// 3. Removes orphan slug files (slugs without matching numeric files)
|
||||
// 4. Reports duplicates for manual review
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Println("Usage: go run migrate_blogs.go <blog_directory>")
|
||||
fmt.Println("Example: go run migrate_blogs.go ../blog")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
blogDir := os.Args[1]
|
||||
|
||||
// Check directory exists
|
||||
if _, err := os.Stat(blogDir); os.IsNotExist(err) {
|
||||
fmt.Printf("Error: blog directory not found: %s\n", blogDir)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Read all files
|
||||
entries, err := os.ReadDir(blogDir)
|
||||
if err != nil {
|
||||
fmt.Printf("Error reading directory: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
numericRe := regexp.MustCompile(`^\d{4}\.html$`)
|
||||
slugRe := regexp.MustCompile(`^[a-z0-9-]+\.html$`)
|
||||
|
||||
// Map: numeric ID -> slug (extracted from file content)
|
||||
numericToSlug := make(map[string]string)
|
||||
// Map: slug -> numeric ID (extracted by matching content)
|
||||
slugToNumeric := make(map[string]string)
|
||||
// List of orphan slug files (no matching numeric file)
|
||||
orphanSlugs := []string{}
|
||||
// List of numeric files
|
||||
numericFiles := []string{}
|
||||
// List of slug files
|
||||
slugFiles := []string{}
|
||||
|
||||
// First pass: categorize files
|
||||
for _, e := range entries {
|
||||
name := e.Name()
|
||||
if numericRe.MatchString(name) {
|
||||
numericFiles = append(numericFiles, name)
|
||||
} else if slugRe.MatchString(name) {
|
||||
slugFiles = append(slugFiles, name)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Found %d numeric files and %d slug files\n", len(numericFiles), len(slugFiles))
|
||||
|
||||
// Extract slugs from numeric files
|
||||
for _, name := range numericFiles {
|
||||
path := filepath.Join(blogDir, name)
|
||||
content, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
slug := extractSlugFromContent(string(content))
|
||||
id := strings.TrimSuffix(name, ".html")
|
||||
if slug != "" {
|
||||
numericToSlug[id] = slug
|
||||
}
|
||||
}
|
||||
|
||||
// Check slug files for matches
|
||||
for _, name := range slugFiles {
|
||||
slug := strings.TrimSuffix(name, ".html")
|
||||
foundMatch := false
|
||||
|
||||
// Check if any numeric file has this slug
|
||||
for numericID, numericSlug := range numericToSlug {
|
||||
if numericSlug == slug {
|
||||
slugToNumeric[slug] = numericID
|
||||
foundMatch = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !foundMatch {
|
||||
orphanSlugs = append(orphanSlugs, name)
|
||||
}
|
||||
}
|
||||
|
||||
// Report findings
|
||||
fmt.Println("\n=== Blog Migration Report ===")
|
||||
fmt.Printf("\nNumeric files with slugs:\n")
|
||||
for id, slug := range numericToSlug {
|
||||
fmt.Printf(" %s -> %s\n", id, slug)
|
||||
}
|
||||
|
||||
fmt.Printf("\nSlug files with matching numeric:\n")
|
||||
for slug, id := range slugToNumeric {
|
||||
fmt.Printf(" %s.html -> %s.html\n", slug, id)
|
||||
}
|
||||
|
||||
if len(orphanSlugs) > 0 {
|
||||
fmt.Printf("\nOrphan slug files (no matching numeric file):\n")
|
||||
for _, name := range orphanSlugs {
|
||||
fmt.Printf(" %s\n", name)
|
||||
}
|
||||
|
||||
fmt.Printf("\nRemove %d orphan slug files? (y/n): ", len(orphanSlugs))
|
||||
var response string
|
||||
fmt.Scanln(&response)
|
||||
if strings.ToLower(response) == "y" {
|
||||
for _, name := range orphanSlugs {
|
||||
path := filepath.Join(blogDir, name)
|
||||
if err := os.Remove(path); err != nil {
|
||||
fmt.Printf(" Error removing %s: %v\n", name, err)
|
||||
} else {
|
||||
fmt.Printf(" Removed: %s\n", name)
|
||||
}
|
||||
}
|
||||
fmt.Println("Migration complete!")
|
||||
} else {
|
||||
fmt.Println("Migration cancelled.")
|
||||
}
|
||||
} else {
|
||||
fmt.Println("\nNo orphan slug files found. Blog directory is clean.")
|
||||
}
|
||||
}
|
||||
|
||||
func extractSlugFromContent(htmlContent string) string {
|
||||
re := regexp.MustCompile(`(?is)<meta name="slug" content="([^"]+)"`)
|
||||
m := re.FindStringSubmatch(htmlContent)
|
||||
if len(m) >= 2 {
|
||||
return m[1]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
+24
-3
@@ -31,6 +31,7 @@
|
||||
<script type="text/javascript" src="js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full">
|
||||
@@ -63,20 +64,40 @@
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-29540" class="menu-item menu-item-type-post_type menu-item-object-page">
|
||||
<a href="">
|
||||
<a href="o-nas.html">
|
||||
<span>O nás</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-59" class="menu-item menu-item-type-custom">
|
||||
<a href="">
|
||||
<a href="blog.html">
|
||||
<span>Blog</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-13613" class="menu-item menu-item-type-post_type menu-item-object-page">
|
||||
<a href="">
|
||||
<a href="kontakt.html">
|
||||
<span>Kontakt</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="vykonny-vybor.html">
|
||||
<span>Výkonný výbor</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="index.html#tym">
|
||||
<span>Tým</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="index.html#sponzori">
|
||||
<span>Sponzoři</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a target="_blank" href="https://eu.zonerama.com/Fcbizoni/1419417">
|
||||
<span>Fotogalerie</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Mobile Menu Toggle -->
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full">
|
||||
@@ -78,6 +79,11 @@
|
||||
<span>Kontakt</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="vykonny-vybor.html">
|
||||
<span>Výkonný výbor</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="index.html#tym">
|
||||
<span>Tým</span>
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos e--ua-blink e--ua-edge e--ua-webkit" data-elementor-device-mode="mobile_extra">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full" style=" min-height: 0px;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
<meta name="category" content="Zápasy">
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
<meta name="category" content="Zápasy">
|
||||
<meta name="category" content="O nás">
|
||||
<meta name="category" content="Novinky">
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
<meta name="category" content="Zápasy">
|
||||
<meta name="category" content="O nás">
|
||||
<meta name="category" content="Novinky">
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
<meta name="category" content="Zápasy">
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
<meta name="category" content="Zápasy">
|
||||
<meta name="category" content="Zápasy">
|
||||
</head>
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
<meta name="category" content="Zápasy">
|
||||
<meta name="category" content="Fotoreport">
|
||||
</head>
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
<meta name="category" content="Zápasy">
|
||||
<meta name="category" content="Zápasy">
|
||||
</head>
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
<meta name="category" content="Zápasy">
|
||||
<meta name="category" content="Zápasy">
|
||||
</head>
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
<meta name="category" content="Zápasy">
|
||||
<meta name="category" content="Fotoreport">
|
||||
<meta name="category" content="Zápasy">
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
<meta name="category" content="Zápasy">
|
||||
<meta name="category" content="Zápasy">
|
||||
</head>
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
<meta name="category" content="Zápasy">
|
||||
<meta name="category" content="Zápasy">
|
||||
</head>
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
<meta name="category" content="Zápasy">
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
<meta name="category" content="Zápasy">
|
||||
<meta name="category" content="O nás">
|
||||
</head>
|
||||
|
||||
+31231
-31231
File diff suppressed because it is too large
Load Diff
Vendored
+4
-4
File diff suppressed because one or more lines are too long
+162
-162
@@ -1,163 +1,163 @@
|
||||
.lt-custom-popup {
|
||||
|
||||
position: fixed;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
z-index: 1000;
|
||||
display: none;
|
||||
|
||||
-webkit-transform: translateY(-50%);
|
||||
-ms-transform: translateY(-50%);
|
||||
transform: translateY(-50%);
|
||||
|
||||
text-align: center;
|
||||
|
||||
border-radius: 64px;
|
||||
|
||||
box-shadow: 0 0 25px rgba(0,0,0,.08);
|
||||
|
||||
padding: 20px 10px 20px 10px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.lt-custom-popup img {
|
||||
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
|
||||
.lt-custom-popup .close {
|
||||
|
||||
font-size: 14px;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
||||
font-size: 20px;
|
||||
color: #CE4F4D;
|
||||
z-index: 20;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: block;
|
||||
opacity: 1;
|
||||
background-color: #EEEEEE;
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed {
|
||||
|
||||
padding: 15px 8px 6px 10px;
|
||||
right: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed:hover {
|
||||
|
||||
padding-right: 14px;
|
||||
}
|
||||
|
||||
.ltx-font-selector:hover {
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed img:hover {
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed .close {
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed div {
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed .img {
|
||||
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed .img img {
|
||||
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.lt-custom-popup .close:hover {
|
||||
|
||||
opacity: 1;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
|
||||
.lt-custom-popup {
|
||||
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ltx-font-selector div,
|
||||
.ltx-color-selector div {
|
||||
border-radius: 50%;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
border: 4px solid #fff;
|
||||
display: block;
|
||||
margin: 4px auto 0;
|
||||
box-shadow: 0 0 5px rgba(0,0,0,.1);
|
||||
cursor: pointer;
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.ltx-font-selector div:hover,
|
||||
.ltx-color-selector div:hover {
|
||||
|
||||
box-shadow: 0 0 5px rgba(0,0,0,.2);
|
||||
}
|
||||
|
||||
.lt-custom-field {
|
||||
|
||||
padding: 0;
|
||||
border: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
|
||||
margin-bottom: 14px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* FACR upcoming mobile visibility overrides */
|
||||
@media (max-width: 767px) {
|
||||
/* Show the Zápasy (x/y) header on phones */
|
||||
.lte-football-upcoming .lte-header-upcoming {
|
||||
display: inline-block !important;
|
||||
font-size: 18px;
|
||||
line-height: 1.2;
|
||||
padding: 2px 8px;
|
||||
}
|
||||
|
||||
/* Ensure countdown line is visible and centered */
|
||||
#facr-countdown.lte-football-date {
|
||||
display: block !important;
|
||||
text-align: center !important;
|
||||
}
|
||||
.lt-custom-popup {
|
||||
|
||||
position: fixed;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
z-index: 1000;
|
||||
display: none;
|
||||
|
||||
-webkit-transform: translateY(-50%);
|
||||
-ms-transform: translateY(-50%);
|
||||
transform: translateY(-50%);
|
||||
|
||||
text-align: center;
|
||||
|
||||
border-radius: 64px;
|
||||
|
||||
box-shadow: 0 0 25px rgba(0,0,0,.08);
|
||||
|
||||
padding: 20px 10px 20px 10px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.lt-custom-popup img {
|
||||
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
|
||||
.lt-custom-popup .close {
|
||||
|
||||
font-size: 14px;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
||||
font-size: 20px;
|
||||
color: #CE4F4D;
|
||||
z-index: 20;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: block;
|
||||
opacity: 1;
|
||||
background-color: #EEEEEE;
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed {
|
||||
|
||||
padding: 15px 8px 6px 10px;
|
||||
right: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed:hover {
|
||||
|
||||
padding-right: 14px;
|
||||
}
|
||||
|
||||
.ltx-font-selector:hover {
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed img:hover {
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed .close {
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed div {
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed .img {
|
||||
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed .img img {
|
||||
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.lt-custom-popup .close:hover {
|
||||
|
||||
opacity: 1;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
|
||||
.lt-custom-popup {
|
||||
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ltx-font-selector div,
|
||||
.ltx-color-selector div {
|
||||
border-radius: 50%;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
border: 4px solid #fff;
|
||||
display: block;
|
||||
margin: 4px auto 0;
|
||||
box-shadow: 0 0 5px rgba(0,0,0,.1);
|
||||
cursor: pointer;
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.ltx-font-selector div:hover,
|
||||
.ltx-color-selector div:hover {
|
||||
|
||||
box-shadow: 0 0 5px rgba(0,0,0,.2);
|
||||
}
|
||||
|
||||
.lt-custom-field {
|
||||
|
||||
padding: 0;
|
||||
border: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
|
||||
margin-bottom: 14px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* FACR upcoming mobile visibility overrides */
|
||||
@media (max-width: 767px) {
|
||||
/* Show the Zápasy (x/y) header on phones */
|
||||
.lte-football-upcoming .lte-header-upcoming {
|
||||
display: inline-block !important;
|
||||
font-size: 18px;
|
||||
line-height: 1.2;
|
||||
padding: 2px 8px;
|
||||
}
|
||||
|
||||
/* Ensure countdown line is visible and centered */
|
||||
#facr-countdown.lte-football-date {
|
||||
display: block !important;
|
||||
text-align: center !important;
|
||||
}
|
||||
}
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+145
-145
@@ -1,146 +1,146 @@
|
||||
.lt-custom-popup {
|
||||
|
||||
position: fixed;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
z-index: 1000;
|
||||
display: none;
|
||||
|
||||
-webkit-transform: translateY(-50%);
|
||||
-ms-transform: translateY(-50%);
|
||||
transform: translateY(-50%);
|
||||
|
||||
text-align: center;
|
||||
|
||||
border-radius: 64px;
|
||||
|
||||
box-shadow: 0 0 25px rgba(0,0,0,.08);
|
||||
|
||||
padding: 20px 10px 20px 10px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.lt-custom-popup img {
|
||||
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
|
||||
.lt-custom-popup .close {
|
||||
|
||||
font-size: 14px;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
||||
font-size: 20px;
|
||||
color: #CE4F4D;
|
||||
z-index: 20;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: block;
|
||||
opacity: 1;
|
||||
background-color: #EEEEEE;
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed {
|
||||
|
||||
padding: 15px 8px 6px 10px;
|
||||
right: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed:hover {
|
||||
|
||||
padding-right: 14px;
|
||||
}
|
||||
|
||||
.ltx-font-selector:hover {
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed img:hover {
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed .close {
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed div {
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed .img {
|
||||
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed .img img {
|
||||
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.lt-custom-popup .close:hover {
|
||||
|
||||
opacity: 1;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
|
||||
.lt-custom-popup {
|
||||
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ltx-font-selector div,
|
||||
.ltx-color-selector div {
|
||||
border-radius: 50%;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
border: 4px solid #fff;
|
||||
display: block;
|
||||
margin: 4px auto 0;
|
||||
box-shadow: 0 0 5px rgba(0,0,0,.1);
|
||||
cursor: pointer;
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.ltx-font-selector div:hover,
|
||||
.ltx-color-selector div:hover {
|
||||
|
||||
box-shadow: 0 0 5px rgba(0,0,0,.2);
|
||||
}
|
||||
|
||||
.lt-custom-field {
|
||||
|
||||
padding: 0;
|
||||
border: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
|
||||
margin-bottom: 14px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
display: block;
|
||||
.lt-custom-popup {
|
||||
|
||||
position: fixed;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
z-index: 1000;
|
||||
display: none;
|
||||
|
||||
-webkit-transform: translateY(-50%);
|
||||
-ms-transform: translateY(-50%);
|
||||
transform: translateY(-50%);
|
||||
|
||||
text-align: center;
|
||||
|
||||
border-radius: 64px;
|
||||
|
||||
box-shadow: 0 0 25px rgba(0,0,0,.08);
|
||||
|
||||
padding: 20px 10px 20px 10px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.lt-custom-popup img {
|
||||
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
|
||||
.lt-custom-popup .close {
|
||||
|
||||
font-size: 14px;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
||||
font-size: 20px;
|
||||
color: #CE4F4D;
|
||||
z-index: 20;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: block;
|
||||
opacity: 1;
|
||||
background-color: #EEEEEE;
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed {
|
||||
|
||||
padding: 15px 8px 6px 10px;
|
||||
right: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed:hover {
|
||||
|
||||
padding-right: 14px;
|
||||
}
|
||||
|
||||
.ltx-font-selector:hover {
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed img:hover {
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed .close {
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed div {
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed .img {
|
||||
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.lt-custom-popup.closed .img img {
|
||||
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.lt-custom-popup .close:hover {
|
||||
|
||||
opacity: 1;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
|
||||
.lt-custom-popup {
|
||||
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ltx-font-selector div,
|
||||
.ltx-color-selector div {
|
||||
border-radius: 50%;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
border: 4px solid #fff;
|
||||
display: block;
|
||||
margin: 4px auto 0;
|
||||
box-shadow: 0 0 5px rgba(0,0,0,.1);
|
||||
cursor: pointer;
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.ltx-font-selector div:hover,
|
||||
.ltx-color-selector div:hover {
|
||||
|
||||
box-shadow: 0 0 5px rgba(0,0,0,.2);
|
||||
}
|
||||
|
||||
.lt-custom-field {
|
||||
|
||||
padding: 0;
|
||||
border: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
|
||||
margin-bottom: 14px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
display: block;
|
||||
}
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+171
-171
@@ -1,172 +1,172 @@
|
||||
.wpcf7 .screen-reader-response {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
clip-path: inset(50%);
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
word-wrap: normal !important;
|
||||
}
|
||||
|
||||
.wpcf7 form .wpcf7-response-output {
|
||||
margin: 2em 0.5em 1em;
|
||||
padding: 0.2em 1em;
|
||||
border: 2px solid #00a0d2; /* Blue */
|
||||
}
|
||||
|
||||
.wpcf7 form.init .wpcf7-response-output,
|
||||
.wpcf7 form.resetting .wpcf7-response-output,
|
||||
.wpcf7 form.submitting .wpcf7-response-output {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wpcf7 form.sent .wpcf7-response-output {
|
||||
border-color: #46b450; /* Green */
|
||||
}
|
||||
|
||||
.wpcf7 form.failed .wpcf7-response-output,
|
||||
.wpcf7 form.aborted .wpcf7-response-output {
|
||||
border-color: #dc3232; /* Red */
|
||||
}
|
||||
|
||||
.wpcf7 form.spam .wpcf7-response-output {
|
||||
border-color: #f56e28; /* Orange */
|
||||
}
|
||||
|
||||
.wpcf7 form.invalid .wpcf7-response-output,
|
||||
.wpcf7 form.unaccepted .wpcf7-response-output,
|
||||
.wpcf7 form.payment-required .wpcf7-response-output {
|
||||
border-color: #ffb900; /* Yellow */
|
||||
}
|
||||
|
||||
.wpcf7-form-control-wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wpcf7-not-valid-tip {
|
||||
color: #dc3232; /* Red */
|
||||
font-size: 1em;
|
||||
font-weight: normal;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.use-floating-validation-tip .wpcf7-not-valid-tip {
|
||||
position: relative;
|
||||
top: -2ex;
|
||||
left: 1em;
|
||||
z-index: 100;
|
||||
border: 1px solid #dc3232;
|
||||
background: #fff;
|
||||
padding: .2em .8em;
|
||||
width: 24em;
|
||||
}
|
||||
|
||||
.wpcf7-list-item {
|
||||
display: inline-block;
|
||||
margin: 0 0 0 1em;
|
||||
}
|
||||
|
||||
.wpcf7-list-item-label::before,
|
||||
.wpcf7-list-item-label::after {
|
||||
content: " ";
|
||||
}
|
||||
|
||||
.wpcf7-spinner {
|
||||
visibility: hidden;
|
||||
display: inline-block;
|
||||
background-color: #23282d; /* Dark Gray 800 */
|
||||
opacity: 0.75;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border: none;
|
||||
border-radius: 100%;
|
||||
padding: 0;
|
||||
margin: 0 24px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
form.submitting .wpcf7-spinner {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.wpcf7-spinner::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background-color: #fbfbfc; /* Light Gray 100 */
|
||||
top: 4px;
|
||||
left: 4px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border: none;
|
||||
border-radius: 100%;
|
||||
transform-origin: 8px 8px;
|
||||
animation-name: spin;
|
||||
animation-duration: 1000ms;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.wpcf7-spinner::before {
|
||||
animation-name: blink;
|
||||
animation-duration: 2000ms;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.wpcf7 [inert] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.wpcf7 input[type="file"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wpcf7 input[type="file"]:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.wpcf7 .wpcf7-submit:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.wpcf7 input[type="url"],
|
||||
.wpcf7 input[type="email"],
|
||||
.wpcf7 input[type="tel"] {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.wpcf7-reflection > output {
|
||||
display: list-item;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.wpcf7-reflection > output[hidden] {
|
||||
display: none;
|
||||
.wpcf7 .screen-reader-response {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
clip-path: inset(50%);
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
word-wrap: normal !important;
|
||||
}
|
||||
|
||||
.wpcf7 form .wpcf7-response-output {
|
||||
margin: 2em 0.5em 1em;
|
||||
padding: 0.2em 1em;
|
||||
border: 2px solid #00a0d2; /* Blue */
|
||||
}
|
||||
|
||||
.wpcf7 form.init .wpcf7-response-output,
|
||||
.wpcf7 form.resetting .wpcf7-response-output,
|
||||
.wpcf7 form.submitting .wpcf7-response-output {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wpcf7 form.sent .wpcf7-response-output {
|
||||
border-color: #46b450; /* Green */
|
||||
}
|
||||
|
||||
.wpcf7 form.failed .wpcf7-response-output,
|
||||
.wpcf7 form.aborted .wpcf7-response-output {
|
||||
border-color: #dc3232; /* Red */
|
||||
}
|
||||
|
||||
.wpcf7 form.spam .wpcf7-response-output {
|
||||
border-color: #f56e28; /* Orange */
|
||||
}
|
||||
|
||||
.wpcf7 form.invalid .wpcf7-response-output,
|
||||
.wpcf7 form.unaccepted .wpcf7-response-output,
|
||||
.wpcf7 form.payment-required .wpcf7-response-output {
|
||||
border-color: #ffb900; /* Yellow */
|
||||
}
|
||||
|
||||
.wpcf7-form-control-wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wpcf7-not-valid-tip {
|
||||
color: #dc3232; /* Red */
|
||||
font-size: 1em;
|
||||
font-weight: normal;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.use-floating-validation-tip .wpcf7-not-valid-tip {
|
||||
position: relative;
|
||||
top: -2ex;
|
||||
left: 1em;
|
||||
z-index: 100;
|
||||
border: 1px solid #dc3232;
|
||||
background: #fff;
|
||||
padding: .2em .8em;
|
||||
width: 24em;
|
||||
}
|
||||
|
||||
.wpcf7-list-item {
|
||||
display: inline-block;
|
||||
margin: 0 0 0 1em;
|
||||
}
|
||||
|
||||
.wpcf7-list-item-label::before,
|
||||
.wpcf7-list-item-label::after {
|
||||
content: " ";
|
||||
}
|
||||
|
||||
.wpcf7-spinner {
|
||||
visibility: hidden;
|
||||
display: inline-block;
|
||||
background-color: #23282d; /* Dark Gray 800 */
|
||||
opacity: 0.75;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border: none;
|
||||
border-radius: 100%;
|
||||
padding: 0;
|
||||
margin: 0 24px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
form.submitting .wpcf7-spinner {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.wpcf7-spinner::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background-color: #fbfbfc; /* Light Gray 100 */
|
||||
top: 4px;
|
||||
left: 4px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border: none;
|
||||
border-radius: 100%;
|
||||
transform-origin: 8px 8px;
|
||||
animation-name: spin;
|
||||
animation-duration: 1000ms;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.wpcf7-spinner::before {
|
||||
animation-name: blink;
|
||||
animation-duration: 2000ms;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.wpcf7 [inert] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.wpcf7 input[type="file"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wpcf7 input[type="file"]:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.wpcf7 .wpcf7-submit:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.wpcf7 input[type="url"],
|
||||
.wpcf7 input[type="email"],
|
||||
.wpcf7 input[type="tel"] {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.wpcf7-reflection > output {
|
||||
display: list-item;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.wpcf7-reflection > output[hidden] {
|
||||
display: none;
|
||||
}
|
||||
+531
-531
File diff suppressed because it is too large
Load Diff
+219
-219
@@ -1,219 +1,219 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<team>
|
||||
<category name="men">
|
||||
<member>
|
||||
<name>Janečka Martin</name>
|
||||
<number>13</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Janečka_Martin_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Hubinka Adam</name>
|
||||
<number>18</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Hubinka_Adam_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Zapletal Martin</name>
|
||||
<number>8</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Zapletal_Martin_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Lapčík Martin</name>
|
||||
<number>5</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Lapcik_Martin_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Drobný Michal</name>
|
||||
<number>3</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Drobný_Michal_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Janečka Radek</name>
|
||||
<number>16</number>
|
||||
<role>Brankář</role>
|
||||
<image>img/muzi/Janečka_Radek_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Mačuda Jakub</name>
|
||||
<number>33</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Mačuda_Jakub_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Příplata Filip</name>
|
||||
<number>9</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Příplata_Filip_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Brázdil Petr</name>
|
||||
<number>12</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Brázdil_Petr_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Svízela Jakub</name>
|
||||
<number>19</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Svízela_Jakub_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Šipka Jan</name>
|
||||
<number>14</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Šipka_Jan_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Polák David</name>
|
||||
<number>11</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Polák_David_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Ohnutek Tomáš</name>
|
||||
<number>21</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Tomas_Ohnutek_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Kočiš Lukáš</name>
|
||||
<number>6</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Kočiš_Lukáš_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Malý Lukáš</name>
|
||||
<number>21</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Malý_Lukáš_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Řičica Jakub</name>
|
||||
<number></number>
|
||||
<role>sekretář klubu</role>
|
||||
<image>img/muzi/Řičica_Jakub_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Moravec David</name>
|
||||
<number>44</number>
|
||||
<role>místopředseda klubu</role>
|
||||
<image>img/muzi/Moravec_David_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Janečková Vladimíra</name>
|
||||
<number></number>
|
||||
<role>vedoucí týmu</role>
|
||||
<image>img/muzi/Janečková_Vladimíra_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Stodůlka Štěpán</name>
|
||||
<number>96</number>
|
||||
<role>PR manažer klubu</role>
|
||||
<image>img/muzi/Stodůlka_Štěpán_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Stojaspal Marek</name>
|
||||
<number></number>
|
||||
<role>Trenér mládeže</role>
|
||||
<image>img/muzi/Stojaspal_Marek_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Puškáč Lubomír</name>
|
||||
<number></number>
|
||||
<role>Vedoucí týmu</role>
|
||||
<image>img/muzi/Puškáč_Lubomír_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Náplava Jaroslav</name>
|
||||
<number>88</number>
|
||||
<role>Předseda klubu</role>
|
||||
<image>img/muzi/Náplava_Jaroslav_1.png</image>
|
||||
</member>
|
||||
</category>
|
||||
|
||||
|
||||
<category name="women">
|
||||
<member>
|
||||
<name>Šrámková Sára</name>
|
||||
<number>12</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Šrámková_Sára_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Baná Barbora</name>
|
||||
<number>21</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Baná_Barbora_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Majerechová Eliška</name>
|
||||
<number>69</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Majerechová_Eliška_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Maleňáková Adriana</name>
|
||||
<number>11</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Maleňáková_Adriana_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Adamíková Andrea</name>
|
||||
<number>6</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Adamíková_Andrea_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Dufková Martina</name>
|
||||
<number>17</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Dufková_Martina_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Gorčíková Anna</name>
|
||||
<number>16</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Gorčíková_Anna_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Mrázková Denisa</name>
|
||||
<number>4</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Mrázková_Denisa_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Prokešová Terezie</name>
|
||||
<number>1</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Prokešová_Terezie_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Sekaninová Markéta</name>
|
||||
<number>7</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Sekaninová_Markéta_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Chudárková Kristýna</name>
|
||||
<number></number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Chudárková_Kristýna_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Štichová Tereza</name>
|
||||
<number>10</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Štichová_Tereza_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Prokeš Martin</name>
|
||||
<number></number>
|
||||
<role>Trenér</role>
|
||||
<image>img/muzi/Prokeš_Martin_1.png</image>
|
||||
</member>
|
||||
</category>
|
||||
</team>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<team>
|
||||
<category name="men">
|
||||
<member>
|
||||
<name>Janečka Martin</name>
|
||||
<number>13</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Janečka_Martin_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Hubinka Adam</name>
|
||||
<number>18</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Hubinka_Adam_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Zapletal Martin</name>
|
||||
<number>8</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Zapletal_Martin_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Lapčík Martin</name>
|
||||
<number>5</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Lapcik_Martin_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Drobný Michal</name>
|
||||
<number>3</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Drobný_Michal_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Janečka Radek</name>
|
||||
<number>16</number>
|
||||
<role>Brankář</role>
|
||||
<image>img/muzi/Janečka_Radek_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Mačuda Jakub</name>
|
||||
<number>33</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Mačuda_Jakub_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Příplata Filip</name>
|
||||
<number>9</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Příplata_Filip_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Brázdil Petr</name>
|
||||
<number>12</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Brázdil_Petr_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Svízela Jakub</name>
|
||||
<number>19</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Svízela_Jakub_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Šipka Jan</name>
|
||||
<number>14</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Šipka_Jan_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Polák David</name>
|
||||
<number>11</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Polák_David_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Ohnutek Tomáš</name>
|
||||
<number>21</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Tomas_Ohnutek_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Kočiš Lukáš</name>
|
||||
<number>6</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Kočiš_Lukáš_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Malý Lukáš</name>
|
||||
<number>21</number>
|
||||
<role>Hráč</role>
|
||||
<image>img/muzi/Malý_Lukáš_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Řičica Jakub</name>
|
||||
<number></number>
|
||||
<role>Člen VV</role>
|
||||
<image>img/muzi/Řičica_Jakub_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Moravec David</name>
|
||||
<number>44</number>
|
||||
<role>Místopředseda</role>
|
||||
<image>img/muzi/Moravec_David_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Janečková Vladimíra</name>
|
||||
<number></number>
|
||||
<role>vedoucí týmu</role>
|
||||
<image>img/muzi/Janečková_Vladimíra_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Stodůlka Štěpán</name>
|
||||
<number>96</number>
|
||||
<role>Předseda</role>
|
||||
<image>img/muzi/Stodůlka_Štěpán_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Stojaspal Marek</name>
|
||||
<number></number>
|
||||
<role>Trenér mládeže</role>
|
||||
<image>img/muzi/Stojaspal_Marek_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Puškáč Lubomír</name>
|
||||
<number></number>
|
||||
<role>Vedoucí týmu</role>
|
||||
<image>img/muzi/Puškáč_Lubomír_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Náplava Jaroslav</name>
|
||||
<number>88</number>
|
||||
<role>Člen VV</role>
|
||||
<image>img/muzi/Náplava_Jaroslav_1.png</image>
|
||||
</member>
|
||||
</category>
|
||||
|
||||
|
||||
<category name="women">
|
||||
<member>
|
||||
<name>Šrámková Sára</name>
|
||||
<number>12</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Šrámková_Sára_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Baná Barbora</name>
|
||||
<number>21</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Baná_Barbora_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Majerechová Eliška</name>
|
||||
<number>69</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Majerechová_Eliška_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Maleňáková Adriana</name>
|
||||
<number>11</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Maleňáková_Adriana_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Adamíková Andrea</name>
|
||||
<number>6</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Adamíková_Andrea_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Dufková Martina</name>
|
||||
<number>17</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Dufková_Martina_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Gorčíková Anna</name>
|
||||
<number>16</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Gorčíková_Anna_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Mrázková Denisa</name>
|
||||
<number>4</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Mrázková_Denisa_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Prokešová Terezie</name>
|
||||
<number>1</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Prokešová_Terezie_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Sekaninová Markéta</name>
|
||||
<number>7</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Sekaninová_Markéta_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Chudárková Kristýna</name>
|
||||
<number></number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Chudárková_Kristýna_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Štichová Tereza</name>
|
||||
<number>10</number>
|
||||
<role>hráč</role>
|
||||
<image>img/zeny/Štichová_Tereza_1.png</image>
|
||||
</member>
|
||||
<member>
|
||||
<name>Prokeš Martin</name>
|
||||
<number></number>
|
||||
<role>Trenér</role>
|
||||
<image>img/muzi/Prokeš_Martin_1.png</image>
|
||||
</member>
|
||||
</category>
|
||||
</team>
|
||||
|
||||
+13
-13
@@ -1,13 +1,13 @@
|
||||
services:
|
||||
app:
|
||||
build: ./backend
|
||||
container_name: bizoni-app
|
||||
environment:
|
||||
- STATIC_PATH=/app/site
|
||||
- PORT=8080
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
- ./:/app/site
|
||||
restart: unless-stopped
|
||||
services:
|
||||
app:
|
||||
build: ./backend
|
||||
container_name: bizoni-app
|
||||
environment:
|
||||
- STATIC_PATH=/app/site
|
||||
- PORT=8080
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
- ./:/app/site
|
||||
restart: unless-stopped
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<script type="text/javascript" src="js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full">
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<script type="text/javascript" src="js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full">
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full">
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.1 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
+41
-7
@@ -30,6 +30,7 @@
|
||||
window.si = window.si || function () { (window.siq = window.siq || []).push(arguments); };
|
||||
</script>
|
||||
<script defer src="/_vercel/speed-insights/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
<link rel="stylesheet" id="bootstrap-css" href="css/bootstrap.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="atleticos-theme-style-css" href="css/bizoni.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" href="css/overrides.css" type="text/css" media="all" />
|
||||
@@ -102,6 +103,11 @@
|
||||
<span>Kontakt</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="vykonny-vybor.html">
|
||||
<span>Výkonný výbor</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="index.html#tym">
|
||||
<span>Tým</span>
|
||||
@@ -1768,13 +1774,6 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-lg-3 col-md-6 col-sm-6 col-ms-6 col-xs-12 partners-wrap center-flex">
|
||||
<div class="partners-item item center-flex">
|
||||
<a href="https://alpacar.pl/" target="_blank">
|
||||
<img decoding="async" src="img/sponzor17.png" class="image">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-lg-3 col-md-6 col-sm-6 col-ms-6 col-xs-12 partners-wrap center-flex">
|
||||
<div class="partners-item item center-flex">
|
||||
<a href="https://vechra.cz/" target="_blank">
|
||||
@@ -1852,6 +1851,41 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sxl-3 col-lg-3 col-md-6 col-sm-6 col-ms-6 col-xs-12 partners-wrap center-flex">
|
||||
<div class="partners-item item center-flex">
|
||||
<a href="https://sbernesurovinyuh.cz/" target="_blank">
|
||||
<img decoding="async" src="img/sponzor29.png" class="image">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sxl-3 col-lg-3 col-md-6 col-sm-6 col-ms-6 col-xs-12 partners-wrap center-flex">
|
||||
<div class="partners-item item center-flex">
|
||||
<a href="https://www.kovosteel.cz/" target="_blank">
|
||||
<img decoding="async" src="img/sponzor30.png" class="image">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sxl-3 col-lg-3 col-md-6 col-sm-6 col-ms-6 col-xs-12 partners-wrap center-flex">
|
||||
<div class="partners-item item center-flex">
|
||||
<a href="http://gracla.cz/" target="_blank">
|
||||
<img decoding="async" src="img/sponzor31.png" class="image">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sxl-3 col-lg-3 col-md-6 col-sm-6 col-ms-6 col-xs-12 partners-wrap center-flex">
|
||||
<div class="partners-item item center-flex">
|
||||
<a href="https://nsa.gov.cz/" target="_blank">
|
||||
<img decoding="async" src="img/sponzor32.png" class="image">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sxl-3 col-lg-3 col-md-6 col-sm-6 col-ms-6 col-xs-12 partners-wrap center-flex">
|
||||
<div class="partners-item item center-flex">
|
||||
<a href="https://zlinskykraj.cz/" target="_blank">
|
||||
<img decoding="async" src="img/sponzor33.png" class="image">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -51,6 +51,12 @@
|
||||
const res = await fetch('/api/blog/latest?limit=12', {credentials: 'omit'});
|
||||
if (!res.ok) throw new Error('HTTP '+res.status);
|
||||
let items = await res.json();
|
||||
// Defensive sort: numeric ID descending ensures newest first regardless of API ordering
|
||||
items.sort((a,b)=>{
|
||||
const ai = parseInt(a.id,10); const bi = parseInt(b.id,10);
|
||||
if (!isNaN(ai) && !isNaN(bi)) return bi-ai;
|
||||
return (b.id||'').localeCompare(a.id||'');
|
||||
});
|
||||
if (primary) primary.innerHTML = '';
|
||||
if (!Array.isArray(items) || items.length === 0) {
|
||||
if (primary) primary.innerHTML = '<div style="width:100%;text-align:center;padding:12px;color:#888;">Žádné příspěvky zatím nejsou.</div>';
|
||||
|
||||
+471
-471
@@ -1,471 +1,471 @@
|
||||
(function(){
|
||||
const DATA_URL_JSON = '/data/club.json';
|
||||
const TZ = 'Europe/Prague';
|
||||
|
||||
let state = {
|
||||
data: null,
|
||||
compIndex: 0,
|
||||
matchIndex: 0,
|
||||
intervalId: null,
|
||||
upcomingTimerId: null,
|
||||
};
|
||||
|
||||
function parseCZDate(s){
|
||||
try{
|
||||
// format: 02.01.2006 15:04
|
||||
const [d, t] = s.split(' ');
|
||||
const [day, month, year] = d.split('.').map(Number);
|
||||
const [hour, minute] = t.split(':').map(Number);
|
||||
// Interpret as local time (Europe/Prague). Using local constructor avoids UTC offset skew.
|
||||
const dt = new Date(year, month-1, day, hour, minute);
|
||||
return dt;
|
||||
}catch(e){ return null; }
|
||||
}
|
||||
|
||||
// using original logo URLs; no cleaning/proxy
|
||||
|
||||
function ensureFacrStyles(){
|
||||
if(document.getElementById('facr-styles')) return;
|
||||
const css = `
|
||||
/* logo background unchanged */
|
||||
.facr-nav{ background:#ffffff22; border:1px solid #ffffff55; color:#fff; padding:6px 10px; border-radius:6px; cursor:pointer; backdrop-filter: blur(2px); }
|
||||
.facr-nav:hover{ background:#ffffff40; }
|
||||
.facr-nav:disabled{ opacity:.5; cursor:default; }
|
||||
.facr-tab{ padding:6px 10px; margin:4px; border-radius:16px; border:1px solid #c42221; color:#c42221; background:#ffffff; font-weight:600; }
|
||||
.facr-tab.active{ background:#c42221; color:#ffffff; }
|
||||
.facr-tab:hover{ background:#c42221cc; color:#ffffff; }
|
||||
.facr-inline-status{ margin-left:8px; font-weight:700; font-size:14px; white-space:nowrap; color:inherit; display:inline-block; vertical-align:middle; }
|
||||
/* Default (desktop): show middle only */
|
||||
#facr-countdown{ display:none !important; }
|
||||
.facr-inline-status{ display:none !important; }
|
||||
.facr-mob-center-score{ display:none; font-weight:700; font-size:24px; line-height:1; }
|
||||
/* Mobile: keep only the bottom countdown by default */
|
||||
@media (max-width: 767px){
|
||||
#facr-mid{ display:none !important; }
|
||||
#facr-countdown{ display:block !important; }
|
||||
.facr-inline-status{ display:none !important; }
|
||||
.facr-mob-center-score{ display:inline-block !important; }
|
||||
/* If finished, hide the bottom countdown */
|
||||
.facr-finished #facr-countdown{ display:none !important; }
|
||||
}
|
||||
@media (max-width: 480px){
|
||||
#facr-mid{ font-size:28px !important; min-width:100px; }
|
||||
.facr-tab{ padding:4px 8px; font-size:14px; }
|
||||
.facr-inline-status{ font-size:12px; margin-left:6px; }
|
||||
.facr-nav{ padding:4px 8px; }
|
||||
}
|
||||
`;
|
||||
const style = document.createElement('style');
|
||||
style.id = 'facr-styles';
|
||||
style.type = 'text/css';
|
||||
style.appendChild(document.createTextNode(css));
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
function fmtCountdown(ms){
|
||||
if(ms <= 0) return '0m';
|
||||
const totalMin = Math.floor(ms/60000);
|
||||
const d = Math.floor(totalMin/(60*24));
|
||||
const h = Math.floor((totalMin - d*60*24)/60);
|
||||
const m = totalMin % 60;
|
||||
const parts = [];
|
||||
if(d) parts.push(`${d}d`);
|
||||
if(h || d) parts.push(`${h}h`);
|
||||
parts.push(`${m}m`);
|
||||
return parts.join(' ');
|
||||
}
|
||||
|
||||
function fmtCountdownLong(ms){
|
||||
if(ms < 0) ms = 0;
|
||||
const totalSec = Math.floor(ms/1000);
|
||||
const d = Math.floor(totalSec / (24*3600));
|
||||
const h = Math.floor((totalSec % (24*3600)) / 3600);
|
||||
const m = Math.floor((totalSec % 3600) / 60);
|
||||
const s = totalSec % 60;
|
||||
const dd = d > 0 ? `${d}d ` : '';
|
||||
const hh = String(h).padStart(2,'0');
|
||||
const mm = String(m).padStart(2,'0');
|
||||
const ss = String(s).padStart(2,'0');
|
||||
return `${dd}${hh}:${mm}:${ss}`.trim();
|
||||
}
|
||||
|
||||
function todayCZ(){
|
||||
const now = new Date();
|
||||
const dd = String(now.getDate()).padStart(2,'0');
|
||||
const mm = String(now.getMonth()+1).padStart(2,'0');
|
||||
const yyyy = now.getFullYear();
|
||||
return `${dd}.${mm}.${yyyy}`;
|
||||
}
|
||||
|
||||
async function fetchData(){
|
||||
const res = await fetch(DATA_URL_JSON, { cache: 'no-cache' });
|
||||
if(!res.ok) throw new Error('Failed to fetch data');
|
||||
const data = await res.json();
|
||||
state.data = data;
|
||||
return data;
|
||||
}
|
||||
|
||||
function escapeHTML(s){
|
||||
if(s == null) return '';
|
||||
return String(s)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
|
||||
function truncate(s, max){
|
||||
const str = s == null ? '' : String(s);
|
||||
if(max <= 0) return '';
|
||||
return str.length > max ? str.slice(0, max - 1) + '…' : str;
|
||||
}
|
||||
|
||||
function isWithinMatchWindow(){
|
||||
if(!state.data) return false;
|
||||
const now = new Date();
|
||||
for(const comp of state.data.club_detail.competitions || []){
|
||||
for(const m of comp.matches || []){
|
||||
const dt = parseCZDate(m.date_time);
|
||||
if(!dt) continue;
|
||||
const diffMs = Math.abs(now - dt);
|
||||
if(diffMs <= 2*60*60*1000) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function upcomingMatchesAll(){
|
||||
const list = [];
|
||||
if(!state.data) return list;
|
||||
const now = new Date();
|
||||
const windowStart = new Date(now.getTime() - 3*24*60*60*1000);
|
||||
for(const comp of state.data.club_detail.competitions || []){
|
||||
const candidates = (comp.matches || [])
|
||||
.map(m=>({ comp, match: m, dt: parseCZDate(m.date_time) }))
|
||||
.filter(x=> x.dt && x.dt >= windowStart)
|
||||
.sort((a,b)=> a.dt - b.dt);
|
||||
if(candidates.length === 0) continue;
|
||||
// Prefer the latest recently finished match within the 3-day window;
|
||||
// if none, then choose the next upcoming; if none, fall back to the latest overall in window
|
||||
let pick = null;
|
||||
// find latest finished (dt < now) within window
|
||||
for(let i = candidates.length - 1; i >= 0; i--){
|
||||
if(candidates[i].dt < now){ pick = candidates[i]; break; }
|
||||
}
|
||||
if(!pick){
|
||||
pick = candidates.find(x=> x.dt >= now) || candidates[candidates.length - 1];
|
||||
}
|
||||
list.push(pick);
|
||||
}
|
||||
// sort resulting per-competition picks by time ascending for navigation
|
||||
list.sort((a,b)=> a.dt - b.dt);
|
||||
return list;
|
||||
}
|
||||
|
||||
function renderUpcoming(){
|
||||
const root = document.getElementById('facr-upcoming');
|
||||
if(!root) return;
|
||||
ensureFacrStyles();
|
||||
|
||||
// clear any previous per-second timer
|
||||
if(state.upcomingTimerId){
|
||||
clearInterval(state.upcomingTimerId);
|
||||
state.upcomingTimerId = null;
|
||||
}
|
||||
|
||||
const items = upcomingMatchesAll();
|
||||
if(items.length === 0){
|
||||
root.innerHTML = '<div class="lte-football-upcoming"><span class="lte-header lte-header-upcoming">Žádné nadcházející zápasy</span></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Selection policy:
|
||||
// 1) If there is any finished match within the last 3 days across competitions,
|
||||
// show the latest such finished match (keep result visible for 3 days)
|
||||
// 2) Otherwise, show the first future match
|
||||
// 3) If none, show the latest overall (shouldn't happen as items filtered by 3d window per-comp)
|
||||
const now = new Date();
|
||||
const threeDms = 3*24*60*60*1000;
|
||||
let latestRecentIdx = -1;
|
||||
let latestRecentTime = -Infinity;
|
||||
items.forEach((it, i) => {
|
||||
const dtms = it.dt.getTime();
|
||||
if(dtms <= now.getTime() && now.getTime() - dtms <= threeDms){
|
||||
if(dtms > latestRecentTime){ latestRecentTime = dtms; latestRecentIdx = i; }
|
||||
}
|
||||
});
|
||||
let preferredIdx = latestRecentIdx;
|
||||
if(preferredIdx === -1){
|
||||
preferredIdx = items.findIndex(it => it.dt >= now);
|
||||
if(preferredIdx === -1) preferredIdx = items.length - 1;
|
||||
}
|
||||
const idx = Math.min(state.matchIndex || preferredIdx, items.length-1);
|
||||
const { comp, match:m } = items[idx];
|
||||
const compName = truncate(escapeHTML(comp.name || comp.code || 'Soutěž'), 60);
|
||||
|
||||
const homeLogo = m.home_logo_url || 'img/logo.png';
|
||||
const awayLogo = m.away_logo_url || 'img/logo.png';
|
||||
const facrLink = m.facr_link || comp.matches_link || state.data.club_detail.url || '#';
|
||||
const UP_MAX = 24;
|
||||
const homeName = truncate(escapeHTML(m.home), UP_MAX);
|
||||
const awayName = truncate(escapeHTML(m.away), UP_MAX);
|
||||
const dateVenue = truncate(escapeHTML(m.date_time + (m.venue?`, ${m.venue}`:'')), 40);
|
||||
|
||||
// Determine if match is today (CZ date) and precompute mid display text
|
||||
const matchDayCZ = (m.date_time || '').split(' ')[0];
|
||||
const isToday = matchDayCZ === todayCZ();
|
||||
const startDt = m.date_time ? parseCZDate(m.date_time) : null;
|
||||
const diffMsPre = startDt ? (startDt.getTime() - new Date().getTime()) : 0;
|
||||
const midText = (diffMsPre > 0) ? `Za ${fmtCountdownLong(diffMsPre)}` : (m.score || '-');
|
||||
|
||||
// Determine status flags and parse score parts if any
|
||||
const now2_forTpl = new Date();
|
||||
const startMs_forTpl = m.date_time ? parseCZDate(m.date_time).getTime() : 0;
|
||||
const diff_forTpl = startMs_forTpl - now2_forTpl.getTime();
|
||||
const twoH_forTpl = 2*60*60*1000;
|
||||
const threeD_forTpl = 3*24*60*60*1000;
|
||||
const isFuture = diff_forTpl > 0;
|
||||
const isLive = Math.abs(diff_forTpl) <= twoH_forTpl;
|
||||
const isRecentFinished = (!isFuture && !isLive && -diff_forTpl < threeD_forTpl);
|
||||
const scoreStr = m.score || '';
|
||||
const s1 = scoreStr && scoreStr.includes(':') ? escapeHTML(scoreStr.split(':')[0]) : '';
|
||||
const s2 = scoreStr && scoreStr.includes(':') ? escapeHTML(scoreStr.split(':')[1]) : '';
|
||||
// Date/time formatting for display lines
|
||||
const dtForDisp = startDt || (m.date_time ? parseCZDate(m.date_time) : null);
|
||||
const dd = dtForDisp ? String(dtForDisp.getDate()).padStart(1,'') : '';
|
||||
const mm = dtForDisp ? String(dtForDisp.getMonth()+1).padStart(1,'') : '';
|
||||
const yyyy = dtForDisp ? dtForDisp.getFullYear() : '';
|
||||
const HH = dtForDisp ? String(dtForDisp.getHours()).padStart(2,'0') : '';
|
||||
const MM = dtForDisp ? String(dtForDisp.getMinutes()).padStart(2,'0') : '';
|
||||
const dateOnly = dtForDisp ? `${dd}. ${mm}. ${yyyy}` : '';
|
||||
const timeToken = (m.date_time || '').split(' ')[1] || '';
|
||||
const timeOnly = dtForDisp ? `${HH}:${MM}` : '';
|
||||
const timeDisplay = dtForDisp ? ((timeToken === '' || timeToken === '00:00') ? 'Bude upřesněno' : timeOnly) : '';
|
||||
const venue = m.venue || '';
|
||||
const wrapperExtraClass = (isRecentFinished && s1 && s2) ? ' facr-finished' : '';
|
||||
|
||||
const headerLabel = isLive ? 'Aktuální zápas' : (isFuture ? 'Nadcházející zápas' : (isRecentFinished ? 'Poslední zápas' : `Zápasy (${idx+1}/${items.length})`));
|
||||
|
||||
root.innerHTML = `
|
||||
<div class="lte-football-upcoming${wrapperExtraClass}">
|
||||
<div class="facr-comp-title lte-football-date" style="text-align:center; margin-bottom:6px;">${compName}</div>
|
||||
<div class="facr-upcoming-header">
|
||||
<button id="facr-prev" class="facr-nav">◀</button>
|
||||
<span class="lte-header lte-header-upcoming">${headerLabel}</span>
|
||||
<button id="facr-next" class="facr-nav">▶</button>
|
||||
</div>
|
||||
<div class="lte-teams">
|
||||
<span class="lte-team-name lte-team-1 lte-header" title="${escapeHTML(m.home)}">
|
||||
<span class="lte-team-logo"><img decoding="async" src="${homeLogo}" alt="${escapeHTML(m.home)}"></span>${homeName}
|
||||
<span id="facr-inline-status" class="facr-inline-status" aria-live="polite"></span>
|
||||
${isRecentFinished && s1 ? `<span class="lte-team-count-mob">${s1}</span>` : ''}
|
||||
</span>
|
||||
<span class="lte-team-count">
|
||||
<span id="facr-mid" style="font-size:32px; line-height:1; font-weight:700; display:inline-block; min-width:120px; text-align:center;">${midText}</span>
|
||||
${isRecentFinished && s1 && s2 ? `<span class="facr-mob-center-score">${s1}<span>:</span>${s2}</span>` : ''}
|
||||
</span>
|
||||
<span class="lte-team-name lte-team-2 lte-header" title="${escapeHTML(m.away)}">
|
||||
${isRecentFinished && s2 ? `<span class=\"lte-team-count-mob\">${s2}</span>` : ''}${awayName}<span class="lte-team-logo"><img decoding="async" src="${awayLogo}" alt="${escapeHTML(m.away)}"></span>
|
||||
</span>
|
||||
</div>
|
||||
<span class="lte-football-date" style="text-align:center;" title="${escapeHTML(m.date_time + (m.venue?`, ${m.venue}`:''))}">${escapeHTML(dateOnly + (venue?`, ${venue}`:''))}</span>
|
||||
${timeDisplay ? `<span class="lte-football-time" style="display:block; text-align:center;">${escapeHTML(timeDisplay)}</span>` : ''}
|
||||
<span id="facr-countdown" class="lte-football-date" style="display:block; text-align:center;"></span>
|
||||
<br>
|
||||
<a class="lte-football-date" target="_blank" href="${facrLink}" style="text-align:center; background-color:#c42221; color:#ffffff; opacity:1;">Detail na FACR</a>
|
||||
<span style="display:block; margin-top:6px;"></span>
|
||||
<a class="lte-football-date" href="#tabulka" style="text-align:center; background-color:#ffffff43; color:#ffffff; opacity:1; width:49%; display:inline-block;">Tabulka bodů</a>
|
||||
<a class="lte-football-date" href="/zapasy/vsechny.html" style="text-align:center; background-color:#ffffff43; color:#ffffff; opacity:1; width:49%; display:inline-block;">Všechny zápasy</a>
|
||||
</div>`;
|
||||
|
||||
const prev = document.getElementById('facr-prev');
|
||||
const next = document.getElementById('facr-next');
|
||||
if(prev) prev.onclick = ()=>{ state.matchIndex = (idx - 1 + items.length) % items.length; renderUpcoming(); };
|
||||
if(next) next.onclick = ()=>{ state.matchIndex = (idx + 1) % items.length; renderUpcoming(); };
|
||||
|
||||
// setup countdown / status text
|
||||
const cd = document.getElementById('facr-countdown');
|
||||
const inlineStatus = document.getElementById('facr-inline-status');
|
||||
if(cd || inlineStatus){
|
||||
const now2 = new Date();
|
||||
const startMs = m.date_time ? parseCZDate(m.date_time).getTime() : 0;
|
||||
const diff = startMs - now2.getTime();
|
||||
const twoH = 2*60*60*1000;
|
||||
const threeD = 3*24*60*60*1000;
|
||||
let text = '';
|
||||
if(diff > 0){
|
||||
text = `Začátek za ${fmtCountdown(diff)}`;
|
||||
}else if(Math.abs(diff) <= twoH){
|
||||
text = 'Právě probíhá';
|
||||
}else if(-diff < threeD){
|
||||
text = (m.score ? `Výsledek: ${m.score}` : 'Ukončeno');
|
||||
}else{
|
||||
text = '';
|
||||
}
|
||||
if(cd) cd.textContent = text;
|
||||
if(inlineStatus) inlineStatus.textContent = text;
|
||||
}
|
||||
|
||||
// Live countdown in the middle area when future and not today
|
||||
const midEl = document.getElementById('facr-mid');
|
||||
if(midEl){
|
||||
const startTime = m.date_time ? parseCZDate(m.date_time).getTime() : 0;
|
||||
function tick(){
|
||||
const now = Date.now();
|
||||
const diff = startTime - now;
|
||||
if(diff > 0){
|
||||
const longTxt = `Za ${fmtCountdownLong(diff)}`;
|
||||
midEl.textContent = longTxt;
|
||||
const inlineEl = document.getElementById('facr-inline-status');
|
||||
if(inlineEl) inlineEl.textContent = `Začátek za ${fmtCountdown(diff)}`;
|
||||
const cdEl = document.getElementById('facr-countdown');
|
||||
if(cdEl) cdEl.textContent = `Začátek za ${fmtCountdown(diff)}`;
|
||||
}else{
|
||||
// switch to score at/after kickoff
|
||||
const scoreTxt = m.score || '-';
|
||||
midEl.textContent = scoreTxt;
|
||||
const inlineEl = document.getElementById('facr-inline-status');
|
||||
if(inlineEl) inlineEl.textContent = (m.score ? `Výsledek: ${m.score}` : 'Ukončeno');
|
||||
const cdEl = document.getElementById('facr-countdown');
|
||||
if(cdEl) cdEl.textContent = (m.score ? `Výsledek: ${m.score}` : 'Ukončeno');
|
||||
if(state.upcomingTimerId){ clearInterval(state.upcomingTimerId); state.upcomingTimerId = null; }
|
||||
}
|
||||
}
|
||||
// Run live countdown for any future match (including today)
|
||||
if(startTime > Date.now()){
|
||||
tick();
|
||||
state.upcomingTimerId = setInterval(tick, 1000);
|
||||
} else {
|
||||
// Ensure inline status reflects finished state on initial render
|
||||
const inlineEl = document.getElementById('facr-inline-status');
|
||||
if(inlineEl) inlineEl.textContent = (m.score ? `Výsledek: ${m.score}` : 'Ukončeno');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function renderCompetitionTabs(){
|
||||
const tabs = document.getElementById('facr-comp-tabs');
|
||||
if(!tabs || !state.data) return;
|
||||
ensureFacrStyles();
|
||||
const comps = state.data.club_table.competitions || [];
|
||||
tabs.innerHTML = comps.map((c,i)=>
|
||||
`<button class="facr-tab ${i===state.compIndex?'active':''}" data-idx="${i}">${c.name || c.code || 'Soutěž'}</button>`
|
||||
).join('');
|
||||
tabs.querySelectorAll('button').forEach(btn=>{
|
||||
btn.addEventListener('click', ()=>{
|
||||
state.compIndex = Number(btn.dataset.idx)||0;
|
||||
renderCompetitionTabs();
|
||||
renderTable();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function renderTable(){
|
||||
const tbody = document.getElementById('facr-table-body');
|
||||
const badge = document.getElementById('facr-comp-badge');
|
||||
if(!tbody || !state.data) return;
|
||||
const comps = state.data.club_table.competitions || [];
|
||||
if(comps.length === 0){ tbody.innerHTML = ''; return; }
|
||||
const comp = comps[Math.min(state.compIndex, comps.length-1)];
|
||||
if(badge){ badge.textContent = comp.name || comp.code || 'Soutěž'; }
|
||||
const rows = comp.table && comp.table.overall ? comp.table.overall : [];
|
||||
tbody.innerHTML = rows.map(r=>`
|
||||
<tr>
|
||||
<td class="lte-row"><span>${r.rank}</span></td>
|
||||
<td class="lte-club-logo"><img decoding="async" src="${r.team_logo_url || 'img/logo.png'}"></td>
|
||||
<td class="lte-name">${r.team}</td>
|
||||
<td class="lte-rate">${r.played}</td>
|
||||
<td class="lte-rate">${r.wins}</td>
|
||||
<td class="lte-rate">${r.draws}</td>
|
||||
<td class="lte-rate">${r.losses}</td>
|
||||
<td class="lte-rate">${r.score}</td>
|
||||
<td class="lte-summary">${r.points}</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function renderAllMatches(){
|
||||
const container = document.getElementById('facr-all-matches');
|
||||
if(!container || !state.data) return;
|
||||
const comps = state.data.club_detail.competitions || [];
|
||||
const sections = [];
|
||||
for(const comp of comps){
|
||||
const matches = (comp.matches || [])
|
||||
.map(m=>({ m, dt: parseCZDate(m.date_time) }))
|
||||
.filter(x=>!!x.dt)
|
||||
.sort((a,b)=> b.dt - a.dt);
|
||||
if(matches.length === 0) continue;
|
||||
const compName = truncate(escapeHTML(comp.name || comp.code || 'Soutěž'), 40);
|
||||
const itemsHtml = matches.map(({m})=>{
|
||||
const homeLogo = m.home_logo_url || '../img/logo.png';
|
||||
const awayLogo = m.away_logo_url || '../img/logo.png';
|
||||
const facrLink = m.report_url || comp.matches_link || state.data.club_detail.url || '#';
|
||||
const score = m.score || '-';
|
||||
const GRID_MAX = 22;
|
||||
const home = truncate(escapeHTML(m.home), GRID_MAX);
|
||||
const away = truncate(escapeHTML(m.away), GRID_MAX);
|
||||
const dateVenue = truncate(escapeHTML(m.date_time + (m.venue?`, ${m.venue}`:'')), 36);
|
||||
const s1 = escapeHTML((score.split(':')[0]||'-'));
|
||||
const s2 = escapeHTML((score.split(':')[1]||'-'));
|
||||
return `
|
||||
<a href="${facrLink}" target="_blank" class="lte-item swiper-slide">
|
||||
<div class="lte-teams lte-match-time-public">
|
||||
<span class="lte-team-name lte-team-1 lte-header" title="${escapeHTML(m.home)}">
|
||||
<span class="lte-team-logo"><img src="${homeLogo}" alt="${escapeHTML(m.home)}"></span>${home}</span>
|
||||
<span class="lte-score-mob lte-score-1">${s1}</span>
|
||||
<span class="lte-team-count">
|
||||
<span class="lte-c lte-score-1">${s1}</span>
|
||||
<span class="lte-d">:</span>
|
||||
<span class="lte-c lte-score-4">${s2}</span>
|
||||
</span>
|
||||
<span class="lte-team-name lte-team-2 lte-header" title="${escapeHTML(m.away)}">${away}
|
||||
<span class="lte-team-logo"><img src="${awayLogo}" alt="${escapeHTML(m.away)}"></span>
|
||||
</span>
|
||||
<span class="lte-score-mob lte-score-4">${s2}</span>
|
||||
</div>
|
||||
<div class="lte-footer">
|
||||
<span class="lte-football-date" title="${escapeHTML(m.date_time + (m.venue?`, ${m.venue}`:''))}">${dateVenue}</span>
|
||||
</div>
|
||||
</a>`;
|
||||
}).join('');
|
||||
sections.push(`
|
||||
<div class="lte-section">
|
||||
<h3 class="lte-header" style="margin: 20px 0 10px;">${compName}</h3>
|
||||
<div class="lte-football-matches inner-page">${itemsHtml}</div>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
container.innerHTML = sections.join('');
|
||||
}
|
||||
|
||||
function schedule(){
|
||||
if(state.intervalId) clearInterval(state.intervalId);
|
||||
const intervalMs = isWithinMatchWindow() ? 2*60*1000 : 30*60*1000;
|
||||
state.intervalId = setInterval(async ()=>{
|
||||
try{
|
||||
await fetchData();
|
||||
renderUpcoming();
|
||||
renderCompetitionTabs();
|
||||
renderTable();
|
||||
renderAllMatches();
|
||||
schedule(); // reevaluate interval if window changed
|
||||
}catch(e){ console.warn('refresh failed', e); }
|
||||
}, intervalMs);
|
||||
}
|
||||
|
||||
async function init(){
|
||||
try{
|
||||
await fetchData();
|
||||
renderUpcoming();
|
||||
renderCompetitionTabs();
|
||||
renderTable();
|
||||
renderAllMatches();
|
||||
schedule();
|
||||
}catch(e){
|
||||
console.error('FACR init failed', e);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
})();
|
||||
(function(){
|
||||
const DATA_URL_JSON = '/data/club.json';
|
||||
const TZ = 'Europe/Prague';
|
||||
|
||||
let state = {
|
||||
data: null,
|
||||
compIndex: 0,
|
||||
matchIndex: 0,
|
||||
intervalId: null,
|
||||
upcomingTimerId: null,
|
||||
};
|
||||
|
||||
function parseCZDate(s){
|
||||
try{
|
||||
// format: 02.01.2006 15:04
|
||||
const [d, t] = s.split(' ');
|
||||
const [day, month, year] = d.split('.').map(Number);
|
||||
const [hour, minute] = t.split(':').map(Number);
|
||||
// Interpret as local time (Europe/Prague). Using local constructor avoids UTC offset skew.
|
||||
const dt = new Date(year, month-1, day, hour, minute);
|
||||
return dt;
|
||||
}catch(e){ return null; }
|
||||
}
|
||||
|
||||
// using original logo URLs; no cleaning/proxy
|
||||
|
||||
function ensureFacrStyles(){
|
||||
if(document.getElementById('facr-styles')) return;
|
||||
const css = `
|
||||
/* logo background unchanged */
|
||||
.facr-nav{ background:#ffffff22; border:1px solid #ffffff55; color:#fff; padding:6px 10px; border-radius:6px; cursor:pointer; backdrop-filter: blur(2px); }
|
||||
.facr-nav:hover{ background:#ffffff40; }
|
||||
.facr-nav:disabled{ opacity:.5; cursor:default; }
|
||||
.facr-tab{ padding:6px 10px; margin:4px; border-radius:16px; border:1px solid #c42221; color:#c42221; background:#ffffff; font-weight:600; }
|
||||
.facr-tab.active{ background:#c42221; color:#ffffff; }
|
||||
.facr-tab:hover{ background:#c42221cc; color:#ffffff; }
|
||||
.facr-inline-status{ margin-left:8px; font-weight:700; font-size:14px; white-space:nowrap; color:inherit; display:inline-block; vertical-align:middle; }
|
||||
/* Default (desktop): show middle only */
|
||||
#facr-countdown{ display:none !important; }
|
||||
.facr-inline-status{ display:none !important; }
|
||||
.facr-mob-center-score{ display:none; font-weight:700; font-size:24px; line-height:1; }
|
||||
/* Mobile: keep only the bottom countdown by default */
|
||||
@media (max-width: 767px){
|
||||
#facr-mid{ display:none !important; }
|
||||
#facr-countdown{ display:block !important; }
|
||||
.facr-inline-status{ display:none !important; }
|
||||
.facr-mob-center-score{ display:inline-block !important; }
|
||||
/* If finished, hide the bottom countdown */
|
||||
.facr-finished #facr-countdown{ display:none !important; }
|
||||
}
|
||||
@media (max-width: 480px){
|
||||
#facr-mid{ font-size:28px !important; min-width:100px; }
|
||||
.facr-tab{ padding:4px 8px; font-size:14px; }
|
||||
.facr-inline-status{ font-size:12px; margin-left:6px; }
|
||||
.facr-nav{ padding:4px 8px; }
|
||||
}
|
||||
`;
|
||||
const style = document.createElement('style');
|
||||
style.id = 'facr-styles';
|
||||
style.type = 'text/css';
|
||||
style.appendChild(document.createTextNode(css));
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
function fmtCountdown(ms){
|
||||
if(ms <= 0) return '0m';
|
||||
const totalMin = Math.floor(ms/60000);
|
||||
const d = Math.floor(totalMin/(60*24));
|
||||
const h = Math.floor((totalMin - d*60*24)/60);
|
||||
const m = totalMin % 60;
|
||||
const parts = [];
|
||||
if(d) parts.push(`${d}d`);
|
||||
if(h || d) parts.push(`${h}h`);
|
||||
parts.push(`${m}m`);
|
||||
return parts.join(' ');
|
||||
}
|
||||
|
||||
function fmtCountdownLong(ms){
|
||||
if(ms < 0) ms = 0;
|
||||
const totalSec = Math.floor(ms/1000);
|
||||
const d = Math.floor(totalSec / (24*3600));
|
||||
const h = Math.floor((totalSec % (24*3600)) / 3600);
|
||||
const m = Math.floor((totalSec % 3600) / 60);
|
||||
const s = totalSec % 60;
|
||||
const dd = d > 0 ? `${d}d ` : '';
|
||||
const hh = String(h).padStart(2,'0');
|
||||
const mm = String(m).padStart(2,'0');
|
||||
const ss = String(s).padStart(2,'0');
|
||||
return `${dd}${hh}:${mm}:${ss}`.trim();
|
||||
}
|
||||
|
||||
function todayCZ(){
|
||||
const now = new Date();
|
||||
const dd = String(now.getDate()).padStart(2,'0');
|
||||
const mm = String(now.getMonth()+1).padStart(2,'0');
|
||||
const yyyy = now.getFullYear();
|
||||
return `${dd}.${mm}.${yyyy}`;
|
||||
}
|
||||
|
||||
async function fetchData(){
|
||||
const res = await fetch(DATA_URL_JSON, { cache: 'no-cache' });
|
||||
if(!res.ok) throw new Error('Failed to fetch data');
|
||||
const data = await res.json();
|
||||
state.data = data;
|
||||
return data;
|
||||
}
|
||||
|
||||
function escapeHTML(s){
|
||||
if(s == null) return '';
|
||||
return String(s)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
|
||||
function truncate(s, max){
|
||||
const str = s == null ? '' : String(s);
|
||||
if(max <= 0) return '';
|
||||
return str.length > max ? str.slice(0, max - 1) + '…' : str;
|
||||
}
|
||||
|
||||
function isWithinMatchWindow(){
|
||||
if(!state.data) return false;
|
||||
const now = new Date();
|
||||
for(const comp of state.data.club_detail.competitions || []){
|
||||
for(const m of comp.matches || []){
|
||||
const dt = parseCZDate(m.date_time);
|
||||
if(!dt) continue;
|
||||
const diffMs = Math.abs(now - dt);
|
||||
if(diffMs <= 2*60*60*1000) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function upcomingMatchesAll(){
|
||||
const list = [];
|
||||
if(!state.data) return list;
|
||||
const now = new Date();
|
||||
const windowStart = new Date(now.getTime() - 3*24*60*60*1000);
|
||||
for(const comp of state.data.club_detail.competitions || []){
|
||||
const candidates = (comp.matches || [])
|
||||
.map(m=>({ comp, match: m, dt: parseCZDate(m.date_time) }))
|
||||
.filter(x=> x.dt && x.dt >= windowStart)
|
||||
.sort((a,b)=> a.dt - b.dt);
|
||||
if(candidates.length === 0) continue;
|
||||
// Prefer the latest recently finished match within the 3-day window;
|
||||
// if none, then choose the next upcoming; if none, fall back to the latest overall in window
|
||||
let pick = null;
|
||||
// find latest finished (dt < now) within window
|
||||
for(let i = candidates.length - 1; i >= 0; i--){
|
||||
if(candidates[i].dt < now){ pick = candidates[i]; break; }
|
||||
}
|
||||
if(!pick){
|
||||
pick = candidates.find(x=> x.dt >= now) || candidates[candidates.length - 1];
|
||||
}
|
||||
list.push(pick);
|
||||
}
|
||||
// sort resulting per-competition picks by time ascending for navigation
|
||||
list.sort((a,b)=> a.dt - b.dt);
|
||||
return list;
|
||||
}
|
||||
|
||||
function renderUpcoming(){
|
||||
const root = document.getElementById('facr-upcoming');
|
||||
if(!root) return;
|
||||
ensureFacrStyles();
|
||||
|
||||
// clear any previous per-second timer
|
||||
if(state.upcomingTimerId){
|
||||
clearInterval(state.upcomingTimerId);
|
||||
state.upcomingTimerId = null;
|
||||
}
|
||||
|
||||
const items = upcomingMatchesAll();
|
||||
if(items.length === 0){
|
||||
root.innerHTML = '<div class="lte-football-upcoming"><span class="lte-header lte-header-upcoming">Žádné nadcházející zápasy</span></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Selection policy:
|
||||
// 1) If there is any finished match within the last 3 days across competitions,
|
||||
// show the latest such finished match (keep result visible for 3 days)
|
||||
// 2) Otherwise, show the first future match
|
||||
// 3) If none, show the latest overall (shouldn't happen as items filtered by 3d window per-comp)
|
||||
const now = new Date();
|
||||
const threeDms = 3*24*60*60*1000;
|
||||
let latestRecentIdx = -1;
|
||||
let latestRecentTime = -Infinity;
|
||||
items.forEach((it, i) => {
|
||||
const dtms = it.dt.getTime();
|
||||
if(dtms <= now.getTime() && now.getTime() - dtms <= threeDms){
|
||||
if(dtms > latestRecentTime){ latestRecentTime = dtms; latestRecentIdx = i; }
|
||||
}
|
||||
});
|
||||
let preferredIdx = latestRecentIdx;
|
||||
if(preferredIdx === -1){
|
||||
preferredIdx = items.findIndex(it => it.dt >= now);
|
||||
if(preferredIdx === -1) preferredIdx = items.length - 1;
|
||||
}
|
||||
const idx = Math.min(state.matchIndex || preferredIdx, items.length-1);
|
||||
const { comp, match:m } = items[idx];
|
||||
const compName = truncate(escapeHTML(comp.name || comp.code || 'Soutěž'), 60);
|
||||
|
||||
const homeLogo = m.home_logo_url || 'img/logo.png';
|
||||
const awayLogo = m.away_logo_url || 'img/logo.png';
|
||||
const facrLink = m.facr_link || comp.matches_link || state.data.club_detail.url || '#';
|
||||
const UP_MAX = 24;
|
||||
const homeName = truncate(escapeHTML(m.home), UP_MAX);
|
||||
const awayName = truncate(escapeHTML(m.away), UP_MAX);
|
||||
const dateVenue = truncate(escapeHTML(m.date_time + (m.venue?`, ${m.venue}`:'')), 40);
|
||||
|
||||
// Determine if match is today (CZ date) and precompute mid display text
|
||||
const matchDayCZ = (m.date_time || '').split(' ')[0];
|
||||
const isToday = matchDayCZ === todayCZ();
|
||||
const startDt = m.date_time ? parseCZDate(m.date_time) : null;
|
||||
const diffMsPre = startDt ? (startDt.getTime() - new Date().getTime()) : 0;
|
||||
const midText = (diffMsPre > 0) ? `Za ${fmtCountdownLong(diffMsPre)}` : (m.score || '-');
|
||||
|
||||
// Determine status flags and parse score parts if any
|
||||
const now2_forTpl = new Date();
|
||||
const startMs_forTpl = m.date_time ? parseCZDate(m.date_time).getTime() : 0;
|
||||
const diff_forTpl = startMs_forTpl - now2_forTpl.getTime();
|
||||
const twoH_forTpl = 2*60*60*1000;
|
||||
const threeD_forTpl = 3*24*60*60*1000;
|
||||
const isFuture = diff_forTpl > 0;
|
||||
const isLive = Math.abs(diff_forTpl) <= twoH_forTpl;
|
||||
const isRecentFinished = (!isFuture && !isLive && -diff_forTpl < threeD_forTpl);
|
||||
const scoreStr = m.score || '';
|
||||
const s1 = scoreStr && scoreStr.includes(':') ? escapeHTML(scoreStr.split(':')[0]) : '';
|
||||
const s2 = scoreStr && scoreStr.includes(':') ? escapeHTML(scoreStr.split(':')[1]) : '';
|
||||
// Date/time formatting for display lines
|
||||
const dtForDisp = startDt || (m.date_time ? parseCZDate(m.date_time) : null);
|
||||
const dd = dtForDisp ? String(dtForDisp.getDate()).padStart(1,'') : '';
|
||||
const mm = dtForDisp ? String(dtForDisp.getMonth()+1).padStart(1,'') : '';
|
||||
const yyyy = dtForDisp ? dtForDisp.getFullYear() : '';
|
||||
const HH = dtForDisp ? String(dtForDisp.getHours()).padStart(2,'0') : '';
|
||||
const MM = dtForDisp ? String(dtForDisp.getMinutes()).padStart(2,'0') : '';
|
||||
const dateOnly = dtForDisp ? `${dd}. ${mm}. ${yyyy}` : '';
|
||||
const timeToken = (m.date_time || '').split(' ')[1] || '';
|
||||
const timeOnly = dtForDisp ? `${HH}:${MM}` : '';
|
||||
const timeDisplay = dtForDisp ? ((timeToken === '' || timeToken === '00:00') ? 'Bude upřesněno' : timeOnly) : '';
|
||||
const venue = m.venue || '';
|
||||
const wrapperExtraClass = (isRecentFinished && s1 && s2) ? ' facr-finished' : '';
|
||||
|
||||
const headerLabel = isLive ? 'Aktuální zápas' : (isFuture ? 'Nadcházející zápas' : (isRecentFinished ? 'Poslední zápas' : `Zápasy (${idx+1}/${items.length})`));
|
||||
|
||||
root.innerHTML = `
|
||||
<div class="lte-football-upcoming${wrapperExtraClass}">
|
||||
<div class="facr-comp-title lte-football-date" style="text-align:center; margin-bottom:6px;">${compName}</div>
|
||||
<div class="facr-upcoming-header">
|
||||
<button id="facr-prev" class="facr-nav">◀</button>
|
||||
<span class="lte-header lte-header-upcoming">${headerLabel}</span>
|
||||
<button id="facr-next" class="facr-nav">▶</button>
|
||||
</div>
|
||||
<div class="lte-teams">
|
||||
<span class="lte-team-name lte-team-1 lte-header" title="${escapeHTML(m.home)}">
|
||||
<span class="lte-team-logo"><img decoding="async" src="${homeLogo}" alt="${escapeHTML(m.home)}"></span>${homeName}
|
||||
<span id="facr-inline-status" class="facr-inline-status" aria-live="polite"></span>
|
||||
${isRecentFinished && s1 ? `<span class="lte-team-count-mob">${s1}</span>` : ''}
|
||||
</span>
|
||||
<span class="lte-team-count">
|
||||
<span id="facr-mid" style="font-size:32px; line-height:1; font-weight:700; display:inline-block; min-width:120px; text-align:center;">${midText}</span>
|
||||
${isRecentFinished && s1 && s2 ? `<span class="facr-mob-center-score">${s1}<span>:</span>${s2}</span>` : ''}
|
||||
</span>
|
||||
<span class="lte-team-name lte-team-2 lte-header" title="${escapeHTML(m.away)}">
|
||||
${isRecentFinished && s2 ? `<span class=\"lte-team-count-mob\">${s2}</span>` : ''}${awayName}<span class="lte-team-logo"><img decoding="async" src="${awayLogo}" alt="${escapeHTML(m.away)}"></span>
|
||||
</span>
|
||||
</div>
|
||||
<span class="lte-football-date" style="text-align:center;" title="${escapeHTML(m.date_time + (m.venue?`, ${m.venue}`:''))}">${escapeHTML(dateOnly + (venue?`, ${venue}`:''))}</span>
|
||||
${timeDisplay ? `<span class="lte-football-time" style="display:block; text-align:center;">${escapeHTML(timeDisplay)}</span>` : ''}
|
||||
<span id="facr-countdown" class="lte-football-date" style="display:block; text-align:center;"></span>
|
||||
<br>
|
||||
<a class="lte-football-date" target="_blank" href="${facrLink}" style="text-align:center; background-color:#c42221; color:#ffffff; opacity:1;">Detail na FACR</a>
|
||||
<span style="display:block; margin-top:6px;"></span>
|
||||
<a class="lte-football-date" href="#tabulka" style="text-align:center; background-color:#ffffff43; color:#ffffff; opacity:1; width:49%; display:inline-block;">Tabulka bodů</a>
|
||||
<a class="lte-football-date" href="/zapasy/vsechny.html" style="text-align:center; background-color:#ffffff43; color:#ffffff; opacity:1; width:49%; display:inline-block;">Všechny zápasy</a>
|
||||
</div>`;
|
||||
|
||||
const prev = document.getElementById('facr-prev');
|
||||
const next = document.getElementById('facr-next');
|
||||
if(prev) prev.onclick = ()=>{ state.matchIndex = (idx - 1 + items.length) % items.length; renderUpcoming(); };
|
||||
if(next) next.onclick = ()=>{ state.matchIndex = (idx + 1) % items.length; renderUpcoming(); };
|
||||
|
||||
// setup countdown / status text
|
||||
const cd = document.getElementById('facr-countdown');
|
||||
const inlineStatus = document.getElementById('facr-inline-status');
|
||||
if(cd || inlineStatus){
|
||||
const now2 = new Date();
|
||||
const startMs = m.date_time ? parseCZDate(m.date_time).getTime() : 0;
|
||||
const diff = startMs - now2.getTime();
|
||||
const twoH = 2*60*60*1000;
|
||||
const threeD = 3*24*60*60*1000;
|
||||
let text = '';
|
||||
if(diff > 0){
|
||||
text = `Začátek za ${fmtCountdown(diff)}`;
|
||||
}else if(Math.abs(diff) <= twoH){
|
||||
text = 'Právě probíhá';
|
||||
}else if(-diff < threeD){
|
||||
text = (m.score ? `Výsledek: ${m.score}` : 'Ukončeno');
|
||||
}else{
|
||||
text = '';
|
||||
}
|
||||
if(cd) cd.textContent = text;
|
||||
if(inlineStatus) inlineStatus.textContent = text;
|
||||
}
|
||||
|
||||
// Live countdown in the middle area when future and not today
|
||||
const midEl = document.getElementById('facr-mid');
|
||||
if(midEl){
|
||||
const startTime = m.date_time ? parseCZDate(m.date_time).getTime() : 0;
|
||||
function tick(){
|
||||
const now = Date.now();
|
||||
const diff = startTime - now;
|
||||
if(diff > 0){
|
||||
const longTxt = `Za ${fmtCountdownLong(diff)}`;
|
||||
midEl.textContent = longTxt;
|
||||
const inlineEl = document.getElementById('facr-inline-status');
|
||||
if(inlineEl) inlineEl.textContent = `Začátek za ${fmtCountdown(diff)}`;
|
||||
const cdEl = document.getElementById('facr-countdown');
|
||||
if(cdEl) cdEl.textContent = `Začátek za ${fmtCountdown(diff)}`;
|
||||
}else{
|
||||
// switch to score at/after kickoff
|
||||
const scoreTxt = m.score || '-';
|
||||
midEl.textContent = scoreTxt;
|
||||
const inlineEl = document.getElementById('facr-inline-status');
|
||||
if(inlineEl) inlineEl.textContent = (m.score ? `Výsledek: ${m.score}` : 'Ukončeno');
|
||||
const cdEl = document.getElementById('facr-countdown');
|
||||
if(cdEl) cdEl.textContent = (m.score ? `Výsledek: ${m.score}` : 'Ukončeno');
|
||||
if(state.upcomingTimerId){ clearInterval(state.upcomingTimerId); state.upcomingTimerId = null; }
|
||||
}
|
||||
}
|
||||
// Run live countdown for any future match (including today)
|
||||
if(startTime > Date.now()){
|
||||
tick();
|
||||
state.upcomingTimerId = setInterval(tick, 1000);
|
||||
} else {
|
||||
// Ensure inline status reflects finished state on initial render
|
||||
const inlineEl = document.getElementById('facr-inline-status');
|
||||
if(inlineEl) inlineEl.textContent = (m.score ? `Výsledek: ${m.score}` : 'Ukončeno');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function renderCompetitionTabs(){
|
||||
const tabs = document.getElementById('facr-comp-tabs');
|
||||
if(!tabs || !state.data) return;
|
||||
ensureFacrStyles();
|
||||
const comps = state.data.club_table.competitions || [];
|
||||
tabs.innerHTML = comps.map((c,i)=>
|
||||
`<button class="facr-tab ${i===state.compIndex?'active':''}" data-idx="${i}">${c.name || c.code || 'Soutěž'}</button>`
|
||||
).join('');
|
||||
tabs.querySelectorAll('button').forEach(btn=>{
|
||||
btn.addEventListener('click', ()=>{
|
||||
state.compIndex = Number(btn.dataset.idx)||0;
|
||||
renderCompetitionTabs();
|
||||
renderTable();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function renderTable(){
|
||||
const tbody = document.getElementById('facr-table-body');
|
||||
const badge = document.getElementById('facr-comp-badge');
|
||||
if(!tbody || !state.data) return;
|
||||
const comps = state.data.club_table.competitions || [];
|
||||
if(comps.length === 0){ tbody.innerHTML = ''; return; }
|
||||
const comp = comps[Math.min(state.compIndex, comps.length-1)];
|
||||
if(badge){ badge.textContent = comp.name || comp.code || 'Soutěž'; }
|
||||
const rows = comp.table && comp.table.overall ? comp.table.overall : [];
|
||||
tbody.innerHTML = rows.map(r=>`
|
||||
<tr>
|
||||
<td class="lte-row"><span>${r.rank}</span></td>
|
||||
<td class="lte-club-logo"><img decoding="async" src="${r.team_logo_url || 'img/logo.png'}"></td>
|
||||
<td class="lte-name">${r.team}</td>
|
||||
<td class="lte-rate">${r.played}</td>
|
||||
<td class="lte-rate">${r.wins}</td>
|
||||
<td class="lte-rate">${r.draws}</td>
|
||||
<td class="lte-rate">${r.losses}</td>
|
||||
<td class="lte-rate">${r.score}</td>
|
||||
<td class="lte-summary">${r.points}</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function renderAllMatches(){
|
||||
const container = document.getElementById('facr-all-matches');
|
||||
if(!container || !state.data) return;
|
||||
const comps = state.data.club_detail.competitions || [];
|
||||
const sections = [];
|
||||
for(const comp of comps){
|
||||
const matches = (comp.matches || [])
|
||||
.map(m=>({ m, dt: parseCZDate(m.date_time) }))
|
||||
.filter(x=>!!x.dt)
|
||||
.sort((a,b)=> b.dt - a.dt);
|
||||
if(matches.length === 0) continue;
|
||||
const compName = truncate(escapeHTML(comp.name || comp.code || 'Soutěž'), 40);
|
||||
const itemsHtml = matches.map(({m})=>{
|
||||
const homeLogo = m.home_logo_url || '../img/logo.png';
|
||||
const awayLogo = m.away_logo_url || '../img/logo.png';
|
||||
const facrLink = m.report_url || comp.matches_link || state.data.club_detail.url || '#';
|
||||
const score = m.score || '-';
|
||||
const GRID_MAX = 22;
|
||||
const home = truncate(escapeHTML(m.home), GRID_MAX);
|
||||
const away = truncate(escapeHTML(m.away), GRID_MAX);
|
||||
const dateVenue = truncate(escapeHTML(m.date_time + (m.venue?`, ${m.venue}`:'')), 36);
|
||||
const s1 = escapeHTML((score.split(':')[0]||'-'));
|
||||
const s2 = escapeHTML((score.split(':')[1]||'-'));
|
||||
return `
|
||||
<a href="${facrLink}" target="_blank" class="lte-item swiper-slide">
|
||||
<div class="lte-teams lte-match-time-public">
|
||||
<span class="lte-team-name lte-team-1 lte-header" title="${escapeHTML(m.home)}">
|
||||
<span class="lte-team-logo"><img src="${homeLogo}" alt="${escapeHTML(m.home)}"></span>${home}</span>
|
||||
<span class="lte-score-mob lte-score-1">${s1}</span>
|
||||
<span class="lte-team-count">
|
||||
<span class="lte-c lte-score-1">${s1}</span>
|
||||
<span class="lte-d">:</span>
|
||||
<span class="lte-c lte-score-4">${s2}</span>
|
||||
</span>
|
||||
<span class="lte-team-name lte-team-2 lte-header" title="${escapeHTML(m.away)}">${away}
|
||||
<span class="lte-team-logo"><img src="${awayLogo}" alt="${escapeHTML(m.away)}"></span>
|
||||
</span>
|
||||
<span class="lte-score-mob lte-score-4">${s2}</span>
|
||||
</div>
|
||||
<div class="lte-footer">
|
||||
<span class="lte-football-date" title="${escapeHTML(m.date_time + (m.venue?`, ${m.venue}`:''))}">${dateVenue}</span>
|
||||
</div>
|
||||
</a>`;
|
||||
}).join('');
|
||||
sections.push(`
|
||||
<div class="lte-section">
|
||||
<h3 class="lte-header" style="margin: 20px 0 10px;">${compName}</h3>
|
||||
<div class="lte-football-matches inner-page">${itemsHtml}</div>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
container.innerHTML = sections.join('');
|
||||
}
|
||||
|
||||
function schedule(){
|
||||
if(state.intervalId) clearInterval(state.intervalId);
|
||||
const intervalMs = isWithinMatchWindow() ? 2*60*1000 : 30*60*1000;
|
||||
state.intervalId = setInterval(async ()=>{
|
||||
try{
|
||||
await fetchData();
|
||||
renderUpcoming();
|
||||
renderCompetitionTabs();
|
||||
renderTable();
|
||||
renderAllMatches();
|
||||
schedule(); // reevaluate interval if window changed
|
||||
}catch(e){ console.warn('refresh failed', e); }
|
||||
}, intervalMs);
|
||||
}
|
||||
|
||||
async function init(){
|
||||
try{
|
||||
await fetchData();
|
||||
renderUpcoming();
|
||||
renderCompetitionTabs();
|
||||
renderTable();
|
||||
renderAllMatches();
|
||||
schedule();
|
||||
}catch(e){
|
||||
console.error('FACR init failed', e);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
})();
|
||||
|
||||
+552
-552
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,12 @@
|
||||
if (!res.ok) throw new Error('HTTP '+res.status);
|
||||
let items = await res.json();
|
||||
if (!Array.isArray(items) || items.length === 0) items = [];
|
||||
// Defensive sort: numeric ID descending ensures newest first regardless of API ordering
|
||||
items.sort((a,b)=>{
|
||||
const ai = parseInt(a.id,10); const bi = parseInt(b.id,10);
|
||||
if (!isNaN(ai) && !isNaN(bi)) return bi-ai;
|
||||
return (b.id||'').localeCompare(a.id||'');
|
||||
});
|
||||
|
||||
// Update background images of zoom slider slides if present
|
||||
const slides = document.querySelectorAll('.lte-slider-zoom .zs-slides .zs-slide');
|
||||
|
||||
+237
-237
@@ -1,238 +1,238 @@
|
||||
/**
|
||||
* jQuery plugin paroller.js v1.4.7
|
||||
* https://github.com/tgomilar/paroller.js
|
||||
* preview: https://tgomilar.github.io/paroller/
|
||||
* author: Tanja Gomilar
|
||||
**/
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define('parollerjs', ['jquery'], factory);
|
||||
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||
module.exports = factory(require('jquery'));
|
||||
}
|
||||
else {
|
||||
factory(jQuery);
|
||||
}
|
||||
})(function ($) {
|
||||
'use strict';
|
||||
|
||||
var working = false;
|
||||
var scrollAction = function() {
|
||||
working = false;
|
||||
};
|
||||
|
||||
var setDirection = {
|
||||
bgVertical: function (elem, bgOffset) {
|
||||
return elem.css({'background-position': 'center ' + -bgOffset + 'px'});
|
||||
},
|
||||
bgHorizontal: function (elem, bgOffset) {
|
||||
return elem.css({'background-position': -bgOffset + 'px' + ' center'});
|
||||
},
|
||||
vertical: function (elem, elemOffset, transition, oldTransform) {
|
||||
(oldTransform === 'none' ? oldTransform = '' : true);
|
||||
return elem.css({
|
||||
'-webkit-transform': 'translateY(' + elemOffset + 'px)' + oldTransform,
|
||||
'-moz-transform': 'translateY(' + elemOffset + 'px)' + oldTransform,
|
||||
'transform': 'translateY(' + elemOffset + 'px)' + oldTransform,
|
||||
'transition': transition,
|
||||
'will-change': 'transform'
|
||||
});
|
||||
},
|
||||
horizontal: function (elem, elemOffset, transition, oldTransform) {
|
||||
(oldTransform === 'none' ? oldTransform = '' : true);
|
||||
return elem.css({
|
||||
'-webkit-transform': 'translateX(' + elemOffset + 'px)' + oldTransform,
|
||||
'-moz-transform': 'translateX(' + elemOffset + 'px)' + oldTransform,
|
||||
'transform': 'translateX(' + elemOffset + 'px)' + oldTransform,
|
||||
'transition': transition,
|
||||
'will-change': 'transform'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var setMovement = {
|
||||
factor: function (elem, width, options) {
|
||||
var dataFactor = elem.data('paroller-factor');
|
||||
var factor = (dataFactor) ? dataFactor : options.factor;
|
||||
if (width < 576) {
|
||||
var dataFactorXs = elem.data('paroller-factor-xs');
|
||||
var factorXs = (dataFactorXs) ? dataFactorXs : options.factorXs;
|
||||
return (factorXs) ? factorXs : factor;
|
||||
}
|
||||
else if (width <= 768) {
|
||||
var dataFactorSm = elem.data('paroller-factor-sm');
|
||||
var factorSm = (dataFactorSm) ? dataFactorSm : options.factorSm;
|
||||
return (factorSm) ? factorSm : factor;
|
||||
}
|
||||
else if (width <= 1024) {
|
||||
var dataFactorMd = elem.data('paroller-factor-md');
|
||||
var factorMd = (dataFactorMd) ? dataFactorMd : options.factorMd;
|
||||
return (factorMd) ? factorMd : factor;
|
||||
}
|
||||
else if (width <= 1200) {
|
||||
var dataFactorLg = elem.data('paroller-factor-lg');
|
||||
var factorLg = (dataFactorLg) ? dataFactorLg : options.factorLg;
|
||||
return (factorLg) ? factorLg : factor;
|
||||
} else if (width <= 1920) {
|
||||
var dataFactorXl = elem.data('paroller-factor-xl');
|
||||
var factorXl = (dataFactorXl) ? dataFactorXl : options.factorXl;
|
||||
return (factorXl) ? factorXl : factor;
|
||||
} else {
|
||||
return factor;
|
||||
}
|
||||
},
|
||||
bgOffset: function (offset, factor) {
|
||||
return Math.round(offset * factor);
|
||||
},
|
||||
transform: function (offset, factor, windowHeight, height) {
|
||||
return Math.round((offset - (windowHeight / 2) + height) * factor);
|
||||
}
|
||||
};
|
||||
|
||||
var clearPositions = {
|
||||
background: function (elem) {
|
||||
return elem.css({'background-position': 'unset'});
|
||||
},
|
||||
foreground: function (elem) {
|
||||
return elem.css({
|
||||
'transform' : 'unset',
|
||||
'transition' : 'unset'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.paroller = function (options) {
|
||||
var windowHeight = $(window).height();
|
||||
var documentHeight = $(document).height();
|
||||
|
||||
// default options
|
||||
var options = $.extend({
|
||||
factor: 0, // - to +
|
||||
factorXs: 0, // - to +
|
||||
factorSm: 0, // - to +
|
||||
factorMd: 0, // - to +
|
||||
factorLg: 0, // - to +
|
||||
factorXl: 0, // - to +
|
||||
transition: 'translate 0.1s ease', // CSS transition
|
||||
type: 'background', // foreground
|
||||
direction: 'vertical', // horizontal
|
||||
offsetVal : 0, // horizontal
|
||||
}, options);
|
||||
|
||||
|
||||
return this.each(function () {
|
||||
var $this = $(this);
|
||||
var width = $(window).width();
|
||||
var offset = $this.offset().top;
|
||||
var height = $this.outerHeight();
|
||||
|
||||
var dataType = $this.data('paroller-type');
|
||||
var dataDirection = $this.data('paroller-direction');
|
||||
var dataTransition = $this.data('paroller-transition');
|
||||
var oldTransform = $this.css('transform');
|
||||
var offsetVal = parseInt($this.data('offset'));
|
||||
|
||||
var transition = (dataTransition) ? dataTransition : options.transition;
|
||||
var type = (dataType) ? dataType : options.type;
|
||||
var direction = (dataDirection) ? dataDirection : options.direction;
|
||||
var factor = 0;
|
||||
var bgOffset = setMovement.bgOffset(offset, factor);
|
||||
var transform = setMovement.transform(offset, factor, windowHeight, height);
|
||||
|
||||
if (type === 'background') {
|
||||
if (direction === 'vertical') {
|
||||
setDirection.bgVertical($this, bgOffset);
|
||||
}
|
||||
else if (direction === 'horizontal') {
|
||||
setDirection.bgHorizontal($this, bgOffset);
|
||||
}
|
||||
}
|
||||
else if (type === 'foreground') {
|
||||
if (direction === 'vertical') {
|
||||
setDirection.vertical($this, transform, transition, oldTransform);
|
||||
}
|
||||
else if (direction === 'horizontal') {
|
||||
setDirection.horizontal($this, transform, transition, oldTransform);
|
||||
}
|
||||
}
|
||||
|
||||
$(window).on('resize', function () {
|
||||
var scrolling = $(this).scrollTop();
|
||||
width = $(window).width();
|
||||
offset = $this.offset().top;
|
||||
height = $this.outerHeight();
|
||||
factor = setMovement.factor($this, width, options);
|
||||
bgOffset = Math.round(offset * factor);
|
||||
transform = Math.round((offset - (windowHeight / 2) + height) * factor);
|
||||
|
||||
/*if ( offsetVal != 0 )*/
|
||||
|
||||
offset = offset - 400;
|
||||
|
||||
|
||||
|
||||
if (! working) {
|
||||
window.requestAnimationFrame(scrollAction);
|
||||
working = true;
|
||||
}
|
||||
|
||||
if (type === 'background') {
|
||||
clearPositions.background($this);
|
||||
if (direction === 'vertical') {
|
||||
setDirection.bgVertical($this, bgOffset);
|
||||
}
|
||||
else if (direction === 'horizontal') {
|
||||
setDirection.bgHorizontal($this, bgOffset);
|
||||
}
|
||||
}
|
||||
else if ((type === 'foreground') && (scrolling <= documentHeight)) {
|
||||
clearPositions.foreground($this);
|
||||
if (direction === 'vertical') {
|
||||
setDirection.vertical($this, transform, transition);
|
||||
}
|
||||
else if (direction === 'horizontal') {
|
||||
setDirection.horizontal($this, transform, transition);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(window).on('scroll', function () {
|
||||
var scrolling = $(this).scrollTop();
|
||||
var scrollTop = $(document).scrollTop();
|
||||
|
||||
if (scrollTop === 0) {
|
||||
factor = 0;
|
||||
} else {
|
||||
factor = setMovement.factor($this, width, options);
|
||||
}
|
||||
|
||||
bgOffset = Math.round((offset - scrolling) * factor);
|
||||
transform = Math.round(((offset - (windowHeight / 2) + height) - scrolling) * factor);
|
||||
|
||||
if (! working) {
|
||||
window.requestAnimationFrame(scrollAction);
|
||||
working = true;
|
||||
}
|
||||
|
||||
if (type === 'background') {
|
||||
if (direction === 'vertical') {
|
||||
setDirection.bgVertical($this, bgOffset);
|
||||
}
|
||||
else if (direction === 'horizontal') {
|
||||
setDirection.bgHorizontal($this, bgOffset);
|
||||
}
|
||||
}
|
||||
else if ((type === 'foreground') && (scrolling <= documentHeight)) {
|
||||
if (direction === 'vertical') {
|
||||
setDirection.vertical($this, transform, transition, oldTransform);
|
||||
}
|
||||
else if (direction === 'horizontal') {
|
||||
setDirection.horizontal($this, transform, transition, oldTransform);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* jQuery plugin paroller.js v1.4.7
|
||||
* https://github.com/tgomilar/paroller.js
|
||||
* preview: https://tgomilar.github.io/paroller/
|
||||
* author: Tanja Gomilar
|
||||
**/
|
||||
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define('parollerjs', ['jquery'], factory);
|
||||
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||
module.exports = factory(require('jquery'));
|
||||
}
|
||||
else {
|
||||
factory(jQuery);
|
||||
}
|
||||
})(function ($) {
|
||||
'use strict';
|
||||
|
||||
var working = false;
|
||||
var scrollAction = function() {
|
||||
working = false;
|
||||
};
|
||||
|
||||
var setDirection = {
|
||||
bgVertical: function (elem, bgOffset) {
|
||||
return elem.css({'background-position': 'center ' + -bgOffset + 'px'});
|
||||
},
|
||||
bgHorizontal: function (elem, bgOffset) {
|
||||
return elem.css({'background-position': -bgOffset + 'px' + ' center'});
|
||||
},
|
||||
vertical: function (elem, elemOffset, transition, oldTransform) {
|
||||
(oldTransform === 'none' ? oldTransform = '' : true);
|
||||
return elem.css({
|
||||
'-webkit-transform': 'translateY(' + elemOffset + 'px)' + oldTransform,
|
||||
'-moz-transform': 'translateY(' + elemOffset + 'px)' + oldTransform,
|
||||
'transform': 'translateY(' + elemOffset + 'px)' + oldTransform,
|
||||
'transition': transition,
|
||||
'will-change': 'transform'
|
||||
});
|
||||
},
|
||||
horizontal: function (elem, elemOffset, transition, oldTransform) {
|
||||
(oldTransform === 'none' ? oldTransform = '' : true);
|
||||
return elem.css({
|
||||
'-webkit-transform': 'translateX(' + elemOffset + 'px)' + oldTransform,
|
||||
'-moz-transform': 'translateX(' + elemOffset + 'px)' + oldTransform,
|
||||
'transform': 'translateX(' + elemOffset + 'px)' + oldTransform,
|
||||
'transition': transition,
|
||||
'will-change': 'transform'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var setMovement = {
|
||||
factor: function (elem, width, options) {
|
||||
var dataFactor = elem.data('paroller-factor');
|
||||
var factor = (dataFactor) ? dataFactor : options.factor;
|
||||
if (width < 576) {
|
||||
var dataFactorXs = elem.data('paroller-factor-xs');
|
||||
var factorXs = (dataFactorXs) ? dataFactorXs : options.factorXs;
|
||||
return (factorXs) ? factorXs : factor;
|
||||
}
|
||||
else if (width <= 768) {
|
||||
var dataFactorSm = elem.data('paroller-factor-sm');
|
||||
var factorSm = (dataFactorSm) ? dataFactorSm : options.factorSm;
|
||||
return (factorSm) ? factorSm : factor;
|
||||
}
|
||||
else if (width <= 1024) {
|
||||
var dataFactorMd = elem.data('paroller-factor-md');
|
||||
var factorMd = (dataFactorMd) ? dataFactorMd : options.factorMd;
|
||||
return (factorMd) ? factorMd : factor;
|
||||
}
|
||||
else if (width <= 1200) {
|
||||
var dataFactorLg = elem.data('paroller-factor-lg');
|
||||
var factorLg = (dataFactorLg) ? dataFactorLg : options.factorLg;
|
||||
return (factorLg) ? factorLg : factor;
|
||||
} else if (width <= 1920) {
|
||||
var dataFactorXl = elem.data('paroller-factor-xl');
|
||||
var factorXl = (dataFactorXl) ? dataFactorXl : options.factorXl;
|
||||
return (factorXl) ? factorXl : factor;
|
||||
} else {
|
||||
return factor;
|
||||
}
|
||||
},
|
||||
bgOffset: function (offset, factor) {
|
||||
return Math.round(offset * factor);
|
||||
},
|
||||
transform: function (offset, factor, windowHeight, height) {
|
||||
return Math.round((offset - (windowHeight / 2) + height) * factor);
|
||||
}
|
||||
};
|
||||
|
||||
var clearPositions = {
|
||||
background: function (elem) {
|
||||
return elem.css({'background-position': 'unset'});
|
||||
},
|
||||
foreground: function (elem) {
|
||||
return elem.css({
|
||||
'transform' : 'unset',
|
||||
'transition' : 'unset'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.paroller = function (options) {
|
||||
var windowHeight = $(window).height();
|
||||
var documentHeight = $(document).height();
|
||||
|
||||
// default options
|
||||
var options = $.extend({
|
||||
factor: 0, // - to +
|
||||
factorXs: 0, // - to +
|
||||
factorSm: 0, // - to +
|
||||
factorMd: 0, // - to +
|
||||
factorLg: 0, // - to +
|
||||
factorXl: 0, // - to +
|
||||
transition: 'translate 0.1s ease', // CSS transition
|
||||
type: 'background', // foreground
|
||||
direction: 'vertical', // horizontal
|
||||
offsetVal : 0, // horizontal
|
||||
}, options);
|
||||
|
||||
|
||||
return this.each(function () {
|
||||
var $this = $(this);
|
||||
var width = $(window).width();
|
||||
var offset = $this.offset().top;
|
||||
var height = $this.outerHeight();
|
||||
|
||||
var dataType = $this.data('paroller-type');
|
||||
var dataDirection = $this.data('paroller-direction');
|
||||
var dataTransition = $this.data('paroller-transition');
|
||||
var oldTransform = $this.css('transform');
|
||||
var offsetVal = parseInt($this.data('offset'));
|
||||
|
||||
var transition = (dataTransition) ? dataTransition : options.transition;
|
||||
var type = (dataType) ? dataType : options.type;
|
||||
var direction = (dataDirection) ? dataDirection : options.direction;
|
||||
var factor = 0;
|
||||
var bgOffset = setMovement.bgOffset(offset, factor);
|
||||
var transform = setMovement.transform(offset, factor, windowHeight, height);
|
||||
|
||||
if (type === 'background') {
|
||||
if (direction === 'vertical') {
|
||||
setDirection.bgVertical($this, bgOffset);
|
||||
}
|
||||
else if (direction === 'horizontal') {
|
||||
setDirection.bgHorizontal($this, bgOffset);
|
||||
}
|
||||
}
|
||||
else if (type === 'foreground') {
|
||||
if (direction === 'vertical') {
|
||||
setDirection.vertical($this, transform, transition, oldTransform);
|
||||
}
|
||||
else if (direction === 'horizontal') {
|
||||
setDirection.horizontal($this, transform, transition, oldTransform);
|
||||
}
|
||||
}
|
||||
|
||||
$(window).on('resize', function () {
|
||||
var scrolling = $(this).scrollTop();
|
||||
width = $(window).width();
|
||||
offset = $this.offset().top;
|
||||
height = $this.outerHeight();
|
||||
factor = setMovement.factor($this, width, options);
|
||||
bgOffset = Math.round(offset * factor);
|
||||
transform = Math.round((offset - (windowHeight / 2) + height) * factor);
|
||||
|
||||
/*if ( offsetVal != 0 )*/
|
||||
|
||||
offset = offset - 400;
|
||||
|
||||
|
||||
|
||||
if (! working) {
|
||||
window.requestAnimationFrame(scrollAction);
|
||||
working = true;
|
||||
}
|
||||
|
||||
if (type === 'background') {
|
||||
clearPositions.background($this);
|
||||
if (direction === 'vertical') {
|
||||
setDirection.bgVertical($this, bgOffset);
|
||||
}
|
||||
else if (direction === 'horizontal') {
|
||||
setDirection.bgHorizontal($this, bgOffset);
|
||||
}
|
||||
}
|
||||
else if ((type === 'foreground') && (scrolling <= documentHeight)) {
|
||||
clearPositions.foreground($this);
|
||||
if (direction === 'vertical') {
|
||||
setDirection.vertical($this, transform, transition);
|
||||
}
|
||||
else if (direction === 'horizontal') {
|
||||
setDirection.horizontal($this, transform, transition);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(window).on('scroll', function () {
|
||||
var scrolling = $(this).scrollTop();
|
||||
var scrollTop = $(document).scrollTop();
|
||||
|
||||
if (scrollTop === 0) {
|
||||
factor = 0;
|
||||
} else {
|
||||
factor = setMovement.factor($this, width, options);
|
||||
}
|
||||
|
||||
bgOffset = Math.round((offset - scrolling) * factor);
|
||||
transform = Math.round(((offset - (windowHeight / 2) + height) - scrolling) * factor);
|
||||
|
||||
if (! working) {
|
||||
window.requestAnimationFrame(scrollAction);
|
||||
working = true;
|
||||
}
|
||||
|
||||
if (type === 'background') {
|
||||
if (direction === 'vertical') {
|
||||
setDirection.bgVertical($this, bgOffset);
|
||||
}
|
||||
else if (direction === 'horizontal') {
|
||||
setDirection.bgHorizontal($this, bgOffset);
|
||||
}
|
||||
}
|
||||
else if ((type === 'foreground') && (scrolling <= documentHeight)) {
|
||||
if (direction === 'vertical') {
|
||||
setDirection.vertical($this, transform, transition, oldTransform);
|
||||
}
|
||||
else if (direction === 'horizontal') {
|
||||
setDirection.horizontal($this, transform, transition, oldTransform);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
});
|
||||
+409
-409
@@ -1,409 +1,409 @@
|
||||
/*
|
||||
* zoomSlider - v1.0.2 Fork
|
||||
* CSS3 background zoom slideshow
|
||||
* http://mingthings.com
|
||||
*
|
||||
* Made by Ming Yeung
|
||||
* Under MIT License
|
||||
*/
|
||||
|
||||
;(function ( $, window, document, undefined ) {
|
||||
|
||||
var pluginName = "zoomSlider",
|
||||
defaults = {
|
||||
src: null,
|
||||
src2: null,
|
||||
speed: 8000,
|
||||
initzoom: 1.2,
|
||||
switchSpeed: 1000,
|
||||
interval: 4600,
|
||||
autoplay: true,
|
||||
bullets: true,
|
||||
overlay: 'plain' // false, plain, dots
|
||||
};
|
||||
|
||||
// The actual plugin constructor
|
||||
function Plugin ( element, options ) {
|
||||
this.element = element;
|
||||
this.$el = $(element);
|
||||
this._defaults = defaults;
|
||||
this._name = pluginName;
|
||||
|
||||
var elData = this.$el.data();
|
||||
var elDataObj = {};
|
||||
for (var key in elData) {
|
||||
if ( elData.hasOwnProperty(key) ) {
|
||||
if ( key.match(/zs[A-Z]/) ) {
|
||||
var keyName = key.substr(2);
|
||||
keyName = keyName.charAt(0).toLowerCase() + keyName.slice(1);
|
||||
elDataObj[keyName] = elData[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
this.settings = $.extend( {}, defaults, elDataObj, options );
|
||||
|
||||
if ( this.settings.src == null || this.settings.src.length < 1 ) {
|
||||
console.log('ZoomSlider terminated - invalid input.');
|
||||
return;
|
||||
}
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
// Avoid Plugin.prototype conflicts
|
||||
$.extend(Plugin.prototype, {
|
||||
init: function () {
|
||||
// Place initialization logic here
|
||||
// You already have access to the DOM element and
|
||||
// the options via the instance, e.g. this.element
|
||||
// and this.settings
|
||||
// you can add more functions like the one below and
|
||||
// call them like so: this.yourOtherFunction(this.element, this.settings).
|
||||
|
||||
// make sure src is an Array
|
||||
if ($.isArray(this.settings.src) == false) {
|
||||
this.settings.src = [this.settings.src];
|
||||
}
|
||||
|
||||
if ($.isArray(this.settings.src2) == false) {
|
||||
this.settings.src2 = [this.settings.src2];
|
||||
}
|
||||
|
||||
// https://github.com/twitter/bootstrap/issues/2870
|
||||
this.transEndEventNames = {
|
||||
'WebkitTransition' : 'webkitTransitionEnd',
|
||||
'MozTransition' : 'transitionend',
|
||||
'OTransition' : 'oTransitionEnd',
|
||||
'msTransition' : 'MSTransitionEnd',
|
||||
'transition' : 'transitionend'
|
||||
};
|
||||
this.transEndEventName = this.transEndEventNames[ Modernizr.prefixed( 'transition' ) ];
|
||||
|
||||
// suport for css transforms and css transitions
|
||||
this.support = Modernizr.csstransitions && Modernizr.csstransforms;
|
||||
|
||||
// set inline CSS3 transition properties
|
||||
var transformPrefixed = Modernizr.prefixed('transform');
|
||||
transformPrefixed = transformPrefixed.replace(/([A-Z])/g, function(transformPrefixed,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
|
||||
this.transitionProp = {
|
||||
'transition': transformPrefixed+' '+this.settings.speed+'ms ease-out, opacity '+this.settings.switchSpeed+'ms'
|
||||
};
|
||||
|
||||
this.numSlides = this.settings.src.length;
|
||||
|
||||
// make sure the container is not [position: static]
|
||||
switch(this.$el.css('position')) {
|
||||
case 'relative':
|
||||
case 'absolute':
|
||||
case 'fixed':
|
||||
break;
|
||||
default:
|
||||
this.$el.css('position', 'relative');
|
||||
break;
|
||||
}
|
||||
|
||||
// make sure the first image has been loaded.
|
||||
var self = this;
|
||||
var $img = $('<img />');
|
||||
//$img.load( function() {
|
||||
if (self.numSlides == 1) {
|
||||
self.initSingle();
|
||||
} else {
|
||||
self.initSlideshow();
|
||||
}
|
||||
//});
|
||||
|
||||
$img.attr('src', this.settings.src[0]);
|
||||
},
|
||||
initSlideshow: function () {
|
||||
|
||||
var self = this;
|
||||
var $slideshow = $('<div class="zs-slideshow"></div>'),
|
||||
$slidesWrap = $('<div class="zs-slides"></div>'),
|
||||
$arrowsWrap = $('<div class="zs-arrows"></div>'),
|
||||
$zslayer = $('<div class="zs-layer"></div>'),
|
||||
$bulletsWrap = $('<div class="zs-bullets"></div>'),
|
||||
$ww = $(window).width();
|
||||
|
||||
for (i = 0; i < this.numSlides; i++) {
|
||||
|
||||
var $slide = $('<div class="zs-slide zs-slide-' + i + '"></div>');
|
||||
if ( $ww <= 767 && this.settings.src2[i].length ) {
|
||||
|
||||
$slide.css({ 'background-image': "url('" + this.settings.src2[i] + "')" }).appendTo( $slidesWrap );
|
||||
}
|
||||
else {
|
||||
|
||||
$slide.css({ 'background-image': "url('" + this.settings.src[i] + "')" }).appendTo( $slidesWrap );
|
||||
}
|
||||
|
||||
var $bullet = $('<div class="zs-bullet zs-bullet-' + i + '"></div>')
|
||||
$bullet.appendTo( $bulletsWrap );
|
||||
|
||||
if (i == 0) {
|
||||
|
||||
$slide.addClass('active').css('opacity', 1);
|
||||
$bullet.addClass('active');
|
||||
|
||||
$('.zs-enabled .lte-zs-slider-inner.lte-zs-slide-' + i).addClass('visible');
|
||||
}
|
||||
}
|
||||
|
||||
self._promoteChildren();
|
||||
|
||||
$slideshow.append( $zslayer );
|
||||
|
||||
$slideshow.append( $slidesWrap ).prependTo( this.$el );
|
||||
|
||||
if ( this.settings.bullets != false || this.settings.bullets == 'outside' ) {
|
||||
|
||||
if ( this.settings.bullets == 'outside' ) {
|
||||
|
||||
$slideshow.after( $bulletsWrap );
|
||||
}
|
||||
else {
|
||||
|
||||
$slideshow.append( $bulletsWrap );
|
||||
}
|
||||
|
||||
$slideshow.on('click', '.zs-bullet', function(e){
|
||||
self.jump( $(this).index() );
|
||||
});
|
||||
}
|
||||
|
||||
if ( this.settings.arrows == true || this.settings.arrows == 'right' || this.settings.arrows == 'bottom' ) {
|
||||
|
||||
var container_class = '';
|
||||
if ( this.settings.arrows == 'bottom' ) {
|
||||
|
||||
container_class = 'container';
|
||||
}
|
||||
|
||||
$('<div class="'+container_class+'"><span class="lte-arrow-left">'+this.settings.prev+'</span><span class="lte-arrow-right">'+this.settings.next+'</span></div>').appendTo( $arrowsWrap );
|
||||
this.$el.append( $arrowsWrap );
|
||||
|
||||
this.$el.on('click', '.lte-arrow-left', function(e){
|
||||
self.prev();
|
||||
});
|
||||
|
||||
this.$el.on('click', '.lte-arrow-right', function(e){
|
||||
self.next() ;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
this.pos = 0;
|
||||
this.pending = null;
|
||||
this.switching = false;
|
||||
this.$slideshow = $slideshow;
|
||||
this.$slides = $slidesWrap.children( '.zs-slide' );
|
||||
this.$bullets = $bulletsWrap.children( '.zs-bullet' );
|
||||
this.$el.addClass('zs-enabled');
|
||||
|
||||
var $firstBlock = $('.zs-enabled .lte-zs-slider-inner');
|
||||
|
||||
$('.zs-enabled .lte-zs-slider-inner').css('opacity', '');
|
||||
|
||||
var minHeight = 0;
|
||||
$('.lte-zs-slider-inner').each(function(i, el) {
|
||||
|
||||
if ( $(el).height() > minHeight ) {
|
||||
|
||||
minHeight = $(el).height();
|
||||
}
|
||||
});
|
||||
|
||||
if (this.support) {
|
||||
var $firstSlide = this.$slides.eq(0);
|
||||
var $initzoom = this.settings.initzoom;
|
||||
$firstSlide.css('opacity', 0).css( this.transitionProp );
|
||||
|
||||
$('.lte-zs-slider-wrapper').css('min-height', (minHeight ) + 'px' );
|
||||
$('.zs-slideshow').css('min-height', (minHeight - 2 ) + 'px' );
|
||||
jQuery(window).on('resize', function(){
|
||||
|
||||
var minHeight = 0;
|
||||
$('.lte-zs-slider-inner').each(function(i, el) {
|
||||
|
||||
if ( $(el).height() > minHeight ) {
|
||||
|
||||
minHeight = $(el).height();
|
||||
}
|
||||
});
|
||||
|
||||
$('.lte-zs-slider-wrapper').css('min-height', (minHeight ) + 'px' );
|
||||
$('.zs-slideshow').css('min-height', (minHeight - 2 ) + 'px' );
|
||||
});
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
$firstSlide.css( { 'opacity': 1.0, 'transform': 'scale('+ $initzoom +', '+ $initzoom +')', 'z-index': 2 } );
|
||||
}, 50);
|
||||
}
|
||||
|
||||
if (this.settings.autoplay == true) {
|
||||
this.play();
|
||||
}
|
||||
},
|
||||
initSingle: function() {
|
||||
var self = this;
|
||||
var $slideshow = $('<div class="zs-slideshow"></div>'),
|
||||
$slidesWrap = $('<div class="zs-slides"></div>'),
|
||||
$slide = $('<div class="zs-slide zs-slide-0"></div>');
|
||||
|
||||
$slide.css({ 'background-image': "url('" + this.settings.src[0] + "')" }).appendTo( $slidesWrap );
|
||||
$slide.addClass('active').css('opacity', 1);
|
||||
|
||||
$('.zs-enabled .lte-zs-slider-inner.lte-zs-slide-0').addClass('visible').addClass('single');
|
||||
|
||||
self._promoteChildren();
|
||||
|
||||
$slideshow.append( $slidesWrap ).prependTo( this.$el );
|
||||
this.$el.addClass('zs-enabled');
|
||||
|
||||
if (this.settings.overlay == 'dots') {
|
||||
this.$el.addClass('overlay-dots');
|
||||
} else if (this.settings.overlay == 'plain') {
|
||||
this.$el.addClass('overlay-plain')
|
||||
}
|
||||
|
||||
if (this.support) {
|
||||
$slide.css('opacity', 1).css( this.transitionProp );
|
||||
|
||||
if (this.settings) {
|
||||
|
||||
setTimeout(function(){
|
||||
$slide.css( { 'opacity': 1.0, 'transform': 'scale(1)', 'z-index': 2 } )
|
||||
}, 50);
|
||||
}
|
||||
}
|
||||
},
|
||||
_promoteChildren: function() {
|
||||
// make sure every children have high enough z-index
|
||||
this.$el.children().each(function(index){
|
||||
$this = $(this);
|
||||
if ($this.css('z-index') == 'auto') {
|
||||
$this.css('z-index', 2);
|
||||
}
|
||||
if ($this.css('position') == 'static') {
|
||||
$this.css('position', 'relative');
|
||||
}
|
||||
});
|
||||
},
|
||||
jump: function( pos ) {
|
||||
if ( pos >= this.numSlides ) {
|
||||
console.log('ZoomSlider: jump(pos) aborted. supplied index out of range.');
|
||||
return;
|
||||
}
|
||||
|
||||
if ( this.pos == pos ) return;
|
||||
|
||||
if ( this.switching ) {
|
||||
this.pending = pos;
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var $lastSlide = this.$slides.eq( this.pos );
|
||||
var $nowSlide = this.$slides.eq( pos );
|
||||
|
||||
$('.zs-enabled .lte-zoompages .current').html(pos + 1);
|
||||
$('.zs-enabled .lte-zs-slider-inner.visible').removeClass('visible');
|
||||
$('.zs-enabled .lte-zs-slider-inner.lte-zs-slide-' + pos).addClass('visible');
|
||||
|
||||
if ( this.support ) {
|
||||
|
||||
this.switching = true;
|
||||
$lastSlide.css('z-index', 1);
|
||||
$nowSlide.addClass('active')
|
||||
.css( this.transitionProp )
|
||||
.css( { 'opacity': 1.0, 'transform': 'scale('+this.settings.initzoom+', '+this.settings.initzoom+')', 'z-index': 2 } )
|
||||
.on( this.transEndEventName, function(e) {
|
||||
if (e.originalEvent.propertyName == 'opacity') {
|
||||
lastSlideBg = $lastSlide.css('background-image');
|
||||
$lastSlide.removeClass('active')
|
||||
.removeAttr('style')
|
||||
.css('background-image', lastSlideBg);
|
||||
$nowSlide.off( self.transEndEventName );
|
||||
self.switching = false;
|
||||
if ( self.pending != null ) {
|
||||
setTimeout(function(){
|
||||
var newPos = self.pending;
|
||||
self.pending = null;
|
||||
self.$bullets.eq(newPos).click();
|
||||
}, 30)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
$lastSlide.removeClass('active');
|
||||
$nowSlide.addClass('active');
|
||||
}
|
||||
this.$bullets.eq(this.pos).removeClass('active');
|
||||
this.$bullets.eq(pos).addClass('active');
|
||||
this.pos = pos;
|
||||
|
||||
if (this.settings.autoplay) {
|
||||
this.play();
|
||||
}
|
||||
},
|
||||
prev: function() {
|
||||
var posPrev = this.pos - 1;
|
||||
if (posPrev < 0) posPrev = this.numSlides - 1;
|
||||
this.jump( posPrev );
|
||||
},
|
||||
next: function() {
|
||||
var posNext = this.pos + 1;
|
||||
if (posNext >= this.numSlides) posNext = 0;
|
||||
this.jump( posNext );
|
||||
},
|
||||
play: function() {
|
||||
// clear any existing timer
|
||||
if (this.timer != null) {
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
var self = this;
|
||||
this.settings.autoplay = true;
|
||||
// add timer
|
||||
|
||||
this.timer = setInterval( function(){
|
||||
self.next();
|
||||
}, this.settings.interval );
|
||||
},
|
||||
stop: function() {
|
||||
this.settings.autoplay = false;
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
});
|
||||
|
||||
// A really lightweight plugin wrapper around the constructor,
|
||||
// preventing against multiple instantiations
|
||||
$.fn[ pluginName ] = function ( options ) {
|
||||
return this.each(function() {
|
||||
if ( !$.data( this, "plugin_" + pluginName ) ) {
|
||||
$.data( this, "plugin_" + pluginName, new Plugin( this, options ) );
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var WidgetZoomsliderHandler = function ($scope, $) {
|
||||
|
||||
// auto create slideshow on [data-zs-enabled] instances.
|
||||
var $instances = $('[data-zs-src]');
|
||||
if ($instances.length > 0) {
|
||||
$instances.each( function(index) {
|
||||
var $this = $(this);
|
||||
$this.zoomSlider();
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$(window).on('elementor/frontend/init', function () {
|
||||
|
||||
elementorFrontend.hooks.addAction('frontend/element_ready/lte-zoomslider.default', WidgetZoomsliderHandler);
|
||||
});
|
||||
|
||||
})( jQuery, window, document );
|
||||
/*
|
||||
* zoomSlider - v1.0.2 Fork
|
||||
* CSS3 background zoom slideshow
|
||||
* http://mingthings.com
|
||||
*
|
||||
* Made by Ming Yeung
|
||||
* Under MIT License
|
||||
*/
|
||||
|
||||
;(function ( $, window, document, undefined ) {
|
||||
|
||||
var pluginName = "zoomSlider",
|
||||
defaults = {
|
||||
src: null,
|
||||
src2: null,
|
||||
speed: 8000,
|
||||
initzoom: 1.2,
|
||||
switchSpeed: 1000,
|
||||
interval: 4600,
|
||||
autoplay: true,
|
||||
bullets: true,
|
||||
overlay: 'plain' // false, plain, dots
|
||||
};
|
||||
|
||||
// The actual plugin constructor
|
||||
function Plugin ( element, options ) {
|
||||
this.element = element;
|
||||
this.$el = $(element);
|
||||
this._defaults = defaults;
|
||||
this._name = pluginName;
|
||||
|
||||
var elData = this.$el.data();
|
||||
var elDataObj = {};
|
||||
for (var key in elData) {
|
||||
if ( elData.hasOwnProperty(key) ) {
|
||||
if ( key.match(/zs[A-Z]/) ) {
|
||||
var keyName = key.substr(2);
|
||||
keyName = keyName.charAt(0).toLowerCase() + keyName.slice(1);
|
||||
elDataObj[keyName] = elData[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
this.settings = $.extend( {}, defaults, elDataObj, options );
|
||||
|
||||
if ( this.settings.src == null || this.settings.src.length < 1 ) {
|
||||
console.log('ZoomSlider terminated - invalid input.');
|
||||
return;
|
||||
}
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
// Avoid Plugin.prototype conflicts
|
||||
$.extend(Plugin.prototype, {
|
||||
init: function () {
|
||||
// Place initialization logic here
|
||||
// You already have access to the DOM element and
|
||||
// the options via the instance, e.g. this.element
|
||||
// and this.settings
|
||||
// you can add more functions like the one below and
|
||||
// call them like so: this.yourOtherFunction(this.element, this.settings).
|
||||
|
||||
// make sure src is an Array
|
||||
if ($.isArray(this.settings.src) == false) {
|
||||
this.settings.src = [this.settings.src];
|
||||
}
|
||||
|
||||
if ($.isArray(this.settings.src2) == false) {
|
||||
this.settings.src2 = [this.settings.src2];
|
||||
}
|
||||
|
||||
// https://github.com/twitter/bootstrap/issues/2870
|
||||
this.transEndEventNames = {
|
||||
'WebkitTransition' : 'webkitTransitionEnd',
|
||||
'MozTransition' : 'transitionend',
|
||||
'OTransition' : 'oTransitionEnd',
|
||||
'msTransition' : 'MSTransitionEnd',
|
||||
'transition' : 'transitionend'
|
||||
};
|
||||
this.transEndEventName = this.transEndEventNames[ Modernizr.prefixed( 'transition' ) ];
|
||||
|
||||
// suport for css transforms and css transitions
|
||||
this.support = Modernizr.csstransitions && Modernizr.csstransforms;
|
||||
|
||||
// set inline CSS3 transition properties
|
||||
var transformPrefixed = Modernizr.prefixed('transform');
|
||||
transformPrefixed = transformPrefixed.replace(/([A-Z])/g, function(transformPrefixed,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
|
||||
this.transitionProp = {
|
||||
'transition': transformPrefixed+' '+this.settings.speed+'ms ease-out, opacity '+this.settings.switchSpeed+'ms'
|
||||
};
|
||||
|
||||
this.numSlides = this.settings.src.length;
|
||||
|
||||
// make sure the container is not [position: static]
|
||||
switch(this.$el.css('position')) {
|
||||
case 'relative':
|
||||
case 'absolute':
|
||||
case 'fixed':
|
||||
break;
|
||||
default:
|
||||
this.$el.css('position', 'relative');
|
||||
break;
|
||||
}
|
||||
|
||||
// make sure the first image has been loaded.
|
||||
var self = this;
|
||||
var $img = $('<img />');
|
||||
//$img.load( function() {
|
||||
if (self.numSlides == 1) {
|
||||
self.initSingle();
|
||||
} else {
|
||||
self.initSlideshow();
|
||||
}
|
||||
//});
|
||||
|
||||
$img.attr('src', this.settings.src[0]);
|
||||
},
|
||||
initSlideshow: function () {
|
||||
|
||||
var self = this;
|
||||
var $slideshow = $('<div class="zs-slideshow"></div>'),
|
||||
$slidesWrap = $('<div class="zs-slides"></div>'),
|
||||
$arrowsWrap = $('<div class="zs-arrows"></div>'),
|
||||
$zslayer = $('<div class="zs-layer"></div>'),
|
||||
$bulletsWrap = $('<div class="zs-bullets"></div>'),
|
||||
$ww = $(window).width();
|
||||
|
||||
for (i = 0; i < this.numSlides; i++) {
|
||||
|
||||
var $slide = $('<div class="zs-slide zs-slide-' + i + '"></div>');
|
||||
if ( $ww <= 767 && this.settings.src2[i].length ) {
|
||||
|
||||
$slide.css({ 'background-image': "url('" + this.settings.src2[i] + "')" }).appendTo( $slidesWrap );
|
||||
}
|
||||
else {
|
||||
|
||||
$slide.css({ 'background-image': "url('" + this.settings.src[i] + "')" }).appendTo( $slidesWrap );
|
||||
}
|
||||
|
||||
var $bullet = $('<div class="zs-bullet zs-bullet-' + i + '"></div>')
|
||||
$bullet.appendTo( $bulletsWrap );
|
||||
|
||||
if (i == 0) {
|
||||
|
||||
$slide.addClass('active').css('opacity', 1);
|
||||
$bullet.addClass('active');
|
||||
|
||||
$('.zs-enabled .lte-zs-slider-inner.lte-zs-slide-' + i).addClass('visible');
|
||||
}
|
||||
}
|
||||
|
||||
self._promoteChildren();
|
||||
|
||||
$slideshow.append( $zslayer );
|
||||
|
||||
$slideshow.append( $slidesWrap ).prependTo( this.$el );
|
||||
|
||||
if ( this.settings.bullets != false || this.settings.bullets == 'outside' ) {
|
||||
|
||||
if ( this.settings.bullets == 'outside' ) {
|
||||
|
||||
$slideshow.after( $bulletsWrap );
|
||||
}
|
||||
else {
|
||||
|
||||
$slideshow.append( $bulletsWrap );
|
||||
}
|
||||
|
||||
$slideshow.on('click', '.zs-bullet', function(e){
|
||||
self.jump( $(this).index() );
|
||||
});
|
||||
}
|
||||
|
||||
if ( this.settings.arrows == true || this.settings.arrows == 'right' || this.settings.arrows == 'bottom' ) {
|
||||
|
||||
var container_class = '';
|
||||
if ( this.settings.arrows == 'bottom' ) {
|
||||
|
||||
container_class = 'container';
|
||||
}
|
||||
|
||||
$('<div class="'+container_class+'"><span class="lte-arrow-left">'+this.settings.prev+'</span><span class="lte-arrow-right">'+this.settings.next+'</span></div>').appendTo( $arrowsWrap );
|
||||
this.$el.append( $arrowsWrap );
|
||||
|
||||
this.$el.on('click', '.lte-arrow-left', function(e){
|
||||
self.prev();
|
||||
});
|
||||
|
||||
this.$el.on('click', '.lte-arrow-right', function(e){
|
||||
self.next() ;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
this.pos = 0;
|
||||
this.pending = null;
|
||||
this.switching = false;
|
||||
this.$slideshow = $slideshow;
|
||||
this.$slides = $slidesWrap.children( '.zs-slide' );
|
||||
this.$bullets = $bulletsWrap.children( '.zs-bullet' );
|
||||
this.$el.addClass('zs-enabled');
|
||||
|
||||
var $firstBlock = $('.zs-enabled .lte-zs-slider-inner');
|
||||
|
||||
$('.zs-enabled .lte-zs-slider-inner').css('opacity', '');
|
||||
|
||||
var minHeight = 0;
|
||||
$('.lte-zs-slider-inner').each(function(i, el) {
|
||||
|
||||
if ( $(el).height() > minHeight ) {
|
||||
|
||||
minHeight = $(el).height();
|
||||
}
|
||||
});
|
||||
|
||||
if (this.support) {
|
||||
var $firstSlide = this.$slides.eq(0);
|
||||
var $initzoom = this.settings.initzoom;
|
||||
$firstSlide.css('opacity', 0).css( this.transitionProp );
|
||||
|
||||
$('.lte-zs-slider-wrapper').css('min-height', (minHeight ) + 'px' );
|
||||
$('.zs-slideshow').css('min-height', (minHeight - 2 ) + 'px' );
|
||||
jQuery(window).on('resize', function(){
|
||||
|
||||
var minHeight = 0;
|
||||
$('.lte-zs-slider-inner').each(function(i, el) {
|
||||
|
||||
if ( $(el).height() > minHeight ) {
|
||||
|
||||
minHeight = $(el).height();
|
||||
}
|
||||
});
|
||||
|
||||
$('.lte-zs-slider-wrapper').css('min-height', (minHeight ) + 'px' );
|
||||
$('.zs-slideshow').css('min-height', (minHeight - 2 ) + 'px' );
|
||||
});
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
$firstSlide.css( { 'opacity': 1.0, 'transform': 'scale('+ $initzoom +', '+ $initzoom +')', 'z-index': 2 } );
|
||||
}, 50);
|
||||
}
|
||||
|
||||
if (this.settings.autoplay == true) {
|
||||
this.play();
|
||||
}
|
||||
},
|
||||
initSingle: function() {
|
||||
var self = this;
|
||||
var $slideshow = $('<div class="zs-slideshow"></div>'),
|
||||
$slidesWrap = $('<div class="zs-slides"></div>'),
|
||||
$slide = $('<div class="zs-slide zs-slide-0"></div>');
|
||||
|
||||
$slide.css({ 'background-image': "url('" + this.settings.src[0] + "')" }).appendTo( $slidesWrap );
|
||||
$slide.addClass('active').css('opacity', 1);
|
||||
|
||||
$('.zs-enabled .lte-zs-slider-inner.lte-zs-slide-0').addClass('visible').addClass('single');
|
||||
|
||||
self._promoteChildren();
|
||||
|
||||
$slideshow.append( $slidesWrap ).prependTo( this.$el );
|
||||
this.$el.addClass('zs-enabled');
|
||||
|
||||
if (this.settings.overlay == 'dots') {
|
||||
this.$el.addClass('overlay-dots');
|
||||
} else if (this.settings.overlay == 'plain') {
|
||||
this.$el.addClass('overlay-plain')
|
||||
}
|
||||
|
||||
if (this.support) {
|
||||
$slide.css('opacity', 1).css( this.transitionProp );
|
||||
|
||||
if (this.settings) {
|
||||
|
||||
setTimeout(function(){
|
||||
$slide.css( { 'opacity': 1.0, 'transform': 'scale(1)', 'z-index': 2 } )
|
||||
}, 50);
|
||||
}
|
||||
}
|
||||
},
|
||||
_promoteChildren: function() {
|
||||
// make sure every children have high enough z-index
|
||||
this.$el.children().each(function(index){
|
||||
$this = $(this);
|
||||
if ($this.css('z-index') == 'auto') {
|
||||
$this.css('z-index', 2);
|
||||
}
|
||||
if ($this.css('position') == 'static') {
|
||||
$this.css('position', 'relative');
|
||||
}
|
||||
});
|
||||
},
|
||||
jump: function( pos ) {
|
||||
if ( pos >= this.numSlides ) {
|
||||
console.log('ZoomSlider: jump(pos) aborted. supplied index out of range.');
|
||||
return;
|
||||
}
|
||||
|
||||
if ( this.pos == pos ) return;
|
||||
|
||||
if ( this.switching ) {
|
||||
this.pending = pos;
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var $lastSlide = this.$slides.eq( this.pos );
|
||||
var $nowSlide = this.$slides.eq( pos );
|
||||
|
||||
$('.zs-enabled .lte-zoompages .current').html(pos + 1);
|
||||
$('.zs-enabled .lte-zs-slider-inner.visible').removeClass('visible');
|
||||
$('.zs-enabled .lte-zs-slider-inner.lte-zs-slide-' + pos).addClass('visible');
|
||||
|
||||
if ( this.support ) {
|
||||
|
||||
this.switching = true;
|
||||
$lastSlide.css('z-index', 1);
|
||||
$nowSlide.addClass('active')
|
||||
.css( this.transitionProp )
|
||||
.css( { 'opacity': 1.0, 'transform': 'scale('+this.settings.initzoom+', '+this.settings.initzoom+')', 'z-index': 2 } )
|
||||
.on( this.transEndEventName, function(e) {
|
||||
if (e.originalEvent.propertyName == 'opacity') {
|
||||
lastSlideBg = $lastSlide.css('background-image');
|
||||
$lastSlide.removeClass('active')
|
||||
.removeAttr('style')
|
||||
.css('background-image', lastSlideBg);
|
||||
$nowSlide.off( self.transEndEventName );
|
||||
self.switching = false;
|
||||
if ( self.pending != null ) {
|
||||
setTimeout(function(){
|
||||
var newPos = self.pending;
|
||||
self.pending = null;
|
||||
self.$bullets.eq(newPos).click();
|
||||
}, 30)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
$lastSlide.removeClass('active');
|
||||
$nowSlide.addClass('active');
|
||||
}
|
||||
this.$bullets.eq(this.pos).removeClass('active');
|
||||
this.$bullets.eq(pos).addClass('active');
|
||||
this.pos = pos;
|
||||
|
||||
if (this.settings.autoplay) {
|
||||
this.play();
|
||||
}
|
||||
},
|
||||
prev: function() {
|
||||
var posPrev = this.pos - 1;
|
||||
if (posPrev < 0) posPrev = this.numSlides - 1;
|
||||
this.jump( posPrev );
|
||||
},
|
||||
next: function() {
|
||||
var posNext = this.pos + 1;
|
||||
if (posNext >= this.numSlides) posNext = 0;
|
||||
this.jump( posNext );
|
||||
},
|
||||
play: function() {
|
||||
// clear any existing timer
|
||||
if (this.timer != null) {
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
var self = this;
|
||||
this.settings.autoplay = true;
|
||||
// add timer
|
||||
|
||||
this.timer = setInterval( function(){
|
||||
self.next();
|
||||
}, this.settings.interval );
|
||||
},
|
||||
stop: function() {
|
||||
this.settings.autoplay = false;
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
});
|
||||
|
||||
// A really lightweight plugin wrapper around the constructor,
|
||||
// preventing against multiple instantiations
|
||||
$.fn[ pluginName ] = function ( options ) {
|
||||
return this.each(function() {
|
||||
if ( !$.data( this, "plugin_" + pluginName ) ) {
|
||||
$.data( this, "plugin_" + pluginName, new Plugin( this, options ) );
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var WidgetZoomsliderHandler = function ($scope, $) {
|
||||
|
||||
// auto create slideshow on [data-zs-enabled] instances.
|
||||
var $instances = $('[data-zs-src]');
|
||||
if ($instances.length > 0) {
|
||||
$instances.each( function(index) {
|
||||
var $this = $(this);
|
||||
$this.zoomSlider();
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$(window).on('elementor/frontend/init', function () {
|
||||
|
||||
elementorFrontend.hooks.addAction('frontend/element_ready/lte-zoomslider.default', WidgetZoomsliderHandler);
|
||||
});
|
||||
|
||||
})( jQuery, window, document );
|
||||
|
||||
+40
-40
@@ -1,41 +1,41 @@
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Get the buttons and the navbar element
|
||||
const openButton = document.getElementById('open-button');
|
||||
const closeButton = document.getElementById('close-button');
|
||||
const navbar = document.getElementById('navbar');
|
||||
|
||||
// Log to check if elements exist
|
||||
console.log('Open button:', openButton);
|
||||
console.log('Close button:', closeButton);
|
||||
console.log('Navbar:', navbar);
|
||||
|
||||
// Ensure that buttons and navbar exist
|
||||
if (openButton && closeButton && navbar) {
|
||||
console.log('Elements found and event listeners ready.');
|
||||
|
||||
// Add event listener to the open button to remove the collapse class
|
||||
openButton.addEventListener('click', function() {
|
||||
console.log('Open button clicked');
|
||||
if (navbar.classList.contains('collapse')) {
|
||||
navbar.classList.remove('collapse');
|
||||
console.log('Collapse class removed');
|
||||
} else {
|
||||
console.log('Navbar is already open (no collapse class).');
|
||||
}
|
||||
});
|
||||
|
||||
// Add event listener to the close button to add the collapse class
|
||||
closeButton.addEventListener('click', function() {
|
||||
console.log('Close button clicked');
|
||||
if (!navbar.classList.contains('collapse')) {
|
||||
navbar.classList.add('collapse');
|
||||
console.log('Collapse class added');
|
||||
} else {
|
||||
console.log('Navbar is already collapsed (collapse class exists).');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error('Error: Buttons or navbar element not found.');
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Get the buttons and the navbar element
|
||||
const openButton = document.getElementById('open-button');
|
||||
const closeButton = document.getElementById('close-button');
|
||||
const navbar = document.getElementById('navbar');
|
||||
|
||||
// Log to check if elements exist
|
||||
console.log('Open button:', openButton);
|
||||
console.log('Close button:', closeButton);
|
||||
console.log('Navbar:', navbar);
|
||||
|
||||
// Ensure that buttons and navbar exist
|
||||
if (openButton && closeButton && navbar) {
|
||||
console.log('Elements found and event listeners ready.');
|
||||
|
||||
// Add event listener to the open button to remove the collapse class
|
||||
openButton.addEventListener('click', function() {
|
||||
console.log('Open button clicked');
|
||||
if (navbar.classList.contains('collapse')) {
|
||||
navbar.classList.remove('collapse');
|
||||
console.log('Collapse class removed');
|
||||
} else {
|
||||
console.log('Navbar is already open (no collapse class).');
|
||||
}
|
||||
});
|
||||
|
||||
// Add event listener to the close button to add the collapse class
|
||||
closeButton.addEventListener('click', function() {
|
||||
console.log('Close button clicked');
|
||||
if (!navbar.classList.contains('collapse')) {
|
||||
navbar.classList.add('collapse');
|
||||
console.log('Collapse class added');
|
||||
} else {
|
||||
console.log('Navbar is already collapsed (collapse class exists).');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error('Error: Buttons or navbar element not found.');
|
||||
}
|
||||
});
|
||||
Vendored
+12
-12
File diff suppressed because one or more lines are too long
+328
-328
@@ -1,328 +1,328 @@
|
||||
// team-switcher.js
|
||||
// Loads team data from XML and populates the team slider. Adds a men/women switcher.
|
||||
|
||||
(function () {
|
||||
const XML_URL = 'data/team.xml';
|
||||
const SWITCHER_ID = 'gender-switcher';
|
||||
const WRAPPER_ID = 'team-swiper-wrapper-1';
|
||||
const PRELOADER_ID = 'team-preloader-1';
|
||||
const SECTION_ID = 'team-section-1';
|
||||
|
||||
let teamData = null; // cached parsed XML data
|
||||
let currentGender = 'men';
|
||||
// Autoscroll timers
|
||||
let autoTimer = null;
|
||||
let resumeTimer = null;
|
||||
const AUTO_DELAY = 3500; // 5s
|
||||
const RESUME_AFTER = 10000; // resume 10s after user interaction
|
||||
|
||||
function qs(sel, root = document) { return root.querySelector(sel); }
|
||||
function qsa(sel, root = document) { return Array.from(root.querySelectorAll(sel)); }
|
||||
|
||||
async function loadXML() {
|
||||
if (teamData) return teamData;
|
||||
const res = await fetch(XML_URL, { cache: 'no-cache' });
|
||||
if (!res.ok) throw new Error('Failed to fetch team.xml');
|
||||
const text = await res.text();
|
||||
const parser = new DOMParser();
|
||||
const xml = parser.parseFromString(text, 'application/xml');
|
||||
const parseError = xml.querySelector('parsererror');
|
||||
if (parseError) throw new Error('Invalid XML in team.xml');
|
||||
teamData = xml;
|
||||
return xml;
|
||||
}
|
||||
|
||||
function getMembersByCategory(xml, categoryName) {
|
||||
const cat = Array.from(xml.querySelectorAll('team > category'))
|
||||
.find(c => (c.getAttribute('name') || '').toLowerCase() === categoryName);
|
||||
if (!cat) return [];
|
||||
return Array.from(cat.querySelectorAll('member')).map(m => ({
|
||||
name: (m.querySelector('name')?.textContent || '').trim(),
|
||||
number: (m.querySelector('number')?.textContent || '').trim(),
|
||||
role: (m.querySelector('role')?.textContent || '').trim(),
|
||||
image: (m.querySelector('image')?.textContent || '').trim(),
|
||||
}));
|
||||
}
|
||||
|
||||
function slideHTML(member) {
|
||||
const numHTML = member.number ? `<div class="lte-num">${member.number}</div>` : '<div class="lte-num"></div>';
|
||||
const safeImg = member.image || '';
|
||||
return (
|
||||
`<div class="lte-item swiper-slide">
|
||||
<div class="lte-team-item">
|
||||
<a class="lte-image" style="background-image: url()">
|
||||
<img loading="lazy" decoding="async" width="800" height="1200" src="${safeImg}" class="attachment-full size-full" />
|
||||
</a>
|
||||
<div class="lte-descr">
|
||||
${numHTML}
|
||||
<a href="${safeImg}" target="_blank">
|
||||
<h4 class="lte-header">${member.name}</h4>
|
||||
</a>
|
||||
<p class="lte-subheader" style="color: #c42221">${member.role}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
);
|
||||
}
|
||||
|
||||
function renderMembers(members) {
|
||||
const wrapper = document.getElementById(WRAPPER_ID);
|
||||
if (!wrapper) return;
|
||||
const swiperEl = wrapper.closest('.swiper-container');
|
||||
const swiper = swiperEl && swiperEl.swiper;
|
||||
|
||||
// Use DOM-based rendering to match theme's slider expectations
|
||||
wrapper.innerHTML = members.map(slideHTML).join('');
|
||||
|
||||
// Strong refresh
|
||||
if (swiper) {
|
||||
try {
|
||||
if (typeof swiper.updateSlides === 'function') swiper.updateSlides();
|
||||
if (typeof swiper.updateSize === 'function') swiper.updateSize();
|
||||
if (typeof swiper.updateAutoHeight === 'function') swiper.updateAutoHeight(0);
|
||||
if (typeof swiper.slideTo === 'function') swiper.slideTo(0, 0, false);
|
||||
if (typeof swiper.update === 'function') swiper.update();
|
||||
} catch (e) {}
|
||||
}
|
||||
// Ask the theme to re-init this slider completely so arrows/loop/order are consistent
|
||||
const sliderContainer = wrapper.closest('.lte-swiper-slider');
|
||||
if (sliderContainer) sliderContainer.classList.remove('lte-inited');
|
||||
if (typeof window.initSwiperWrappers === 'function') {
|
||||
try { window.initSwiperWrappers(); } catch (_) {}
|
||||
}
|
||||
// Remove any duplicate arrow bars the theme may have added on re-init
|
||||
cleanupDuplicateArrows();
|
||||
setTimeout(() => window.dispatchEvent(new Event('resize')), 0);
|
||||
|
||||
// Ensure arrows exist and are bound; manual endless wrap
|
||||
setupEndlessNavigation(swiperEl);
|
||||
setupDragWrap(swiper);
|
||||
// Restart autoscroll on fresh render
|
||||
stopAutoScroll();
|
||||
startAutoScroll();
|
||||
}
|
||||
|
||||
// Keep only one arrows bar; prefer the one whose anchors already have our data-ts-bound
|
||||
function cleanupDuplicateArrows() {
|
||||
const wrapper = document.getElementById(WRAPPER_ID);
|
||||
if (!wrapper) return;
|
||||
const slider = wrapper.closest('.lte-swiper-slider');
|
||||
if (!slider) return;
|
||||
|
||||
// Arrows can be siblings of slider or children inside slider depending on theme config
|
||||
const candidates = [];
|
||||
const parent = slider.parentElement;
|
||||
if (parent) {
|
||||
Array.from(parent.children).forEach((el) => { if (el.classList && el.classList.contains('lte-arrows')) candidates.push(el); });
|
||||
}
|
||||
Array.from(slider.children).forEach((el) => { if (el.classList && el.classList.contains('lte-arrows')) candidates.push(el); });
|
||||
|
||||
if (candidates.length <= 1) return;
|
||||
|
||||
// Prefer the one that already has data-ts-bound anchors
|
||||
const hasBound = candidates.find(a => a.querySelector('a[data-ts-bound="1"]'));
|
||||
const keep = hasBound || candidates[0];
|
||||
candidates.forEach((a) => { if (a !== keep && a.parentElement) a.parentElement.removeChild(a); });
|
||||
}
|
||||
|
||||
async function switchGender(gender) {
|
||||
currentGender = gender;
|
||||
try {
|
||||
showPreloader();
|
||||
const xml = await loadXML();
|
||||
// Keep the order as in XML so the first visible is the first listed (e.g., Janečka Martin)
|
||||
const list = getMembersByCategory(xml, gender);
|
||||
renderMembers(list);
|
||||
updateActiveButton();
|
||||
markReady();
|
||||
hidePreloader();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
hidePreloader();
|
||||
}
|
||||
}
|
||||
|
||||
function updateActiveButton() {
|
||||
const container = document.getElementById(SWITCHER_ID);
|
||||
if (!container) return;
|
||||
qsa('button[data-gender]', container).forEach(btn => {
|
||||
btn.classList.toggle('active', btn.dataset.gender === currentGender);
|
||||
});
|
||||
}
|
||||
|
||||
function bindUI() {
|
||||
const container = document.getElementById(SWITCHER_ID);
|
||||
if (!container) return;
|
||||
container.addEventListener('click', (e) => {
|
||||
const btn = e.target.closest('button[data-gender]');
|
||||
if (!btn) return;
|
||||
const gender = btn.dataset.gender;
|
||||
if (gender && gender !== currentGender) switchGender(gender);
|
||||
});
|
||||
}
|
||||
|
||||
function ensureBasicStyles() {
|
||||
const css = `
|
||||
#${SWITCHER_ID}{display:flex;gap:.5rem;justify-content:center;margin:10px 0}
|
||||
#${SWITCHER_ID} .switch-btn{background:#eee;border:1px solid #ccc;border-radius:20px;padding:.35rem .9rem;font-weight:600;cursor:pointer}
|
||||
#${SWITCHER_ID} .switch-btn.active{background:#111;color:#fff;border-color:#111}
|
||||
#${PRELOADER_ID}{display:none;align-items:center;justify-content:center;gap:.6rem;color:#fff;padding:8px 0}
|
||||
#${PRELOADER_ID}.visible{display:flex}
|
||||
#${PRELOADER_ID} .spinner{width:16px;height:16px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:ts-spin .8s linear infinite}
|
||||
@keyframes ts-spin{to{transform:rotate(360deg)}}
|
||||
#${SECTION_ID}.not-ready .lte-swiper-slider-wrapper{visibility:hidden}
|
||||
`;
|
||||
const style = document.createElement('style');
|
||||
style.textContent = css;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
function getSwiperInstance() {
|
||||
const wrapper = document.getElementById(WRAPPER_ID);
|
||||
const swiperEl = wrapper && wrapper.closest('.swiper-container');
|
||||
return swiperEl && swiperEl.swiper ? { el: swiperEl, api: swiperEl.swiper } : null;
|
||||
}
|
||||
|
||||
function setupEndlessNavigation(swiperContainerEl) {
|
||||
const inst = getSwiperInstance();
|
||||
if (!inst) return;
|
||||
const { el, api } = inst;
|
||||
|
||||
// Ensure only one set of arrows remains before binding
|
||||
cleanupDuplicateArrows();
|
||||
|
||||
// Theme uses .lte-arrow-left / .lte-arrow-right (see frontend.js init)
|
||||
let nextBtn = el.parentElement && el.parentElement.querySelector('.lte-arrows .lte-arrow-right');
|
||||
let prevBtn = el.parentElement && el.parentElement.querySelector('.lte-arrows .lte-arrow-left');
|
||||
// Fallback to common Swiper classes if theme structure changes
|
||||
if (!nextBtn) nextBtn = el.querySelector('.swiper-button-next, .lte-swiper-button-next, .lte-next, .lte-arrow-next, .lte-arrow-right');
|
||||
if (!prevBtn) prevBtn = el.querySelector('.swiper-button-prev, .lte-swiper-button-prev, .lte-prev, .lte-arrow-prev, .lte-arrow-left');
|
||||
|
||||
// Do not create fallback arrows; rely on theme arrows only
|
||||
|
||||
function bind(btn, dir) {
|
||||
if (!btn || btn.dataset.tsBound) return;
|
||||
btn.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
if (!api) return;
|
||||
// User override: pause and schedule resume
|
||||
stopAutoScroll();
|
||||
scheduleAutoResume();
|
||||
if (dir === 'next') {
|
||||
if (typeof api.slideNext === 'function') api.slideNext(400);
|
||||
else api.slideTo((api.activeIndex || 0) + 1, 400, false);
|
||||
} else {
|
||||
if (typeof api.slidePrev === 'function') api.slidePrev(400);
|
||||
else api.slideTo(Math.max((api.activeIndex || 0) - 1, 0), 400, false);
|
||||
}
|
||||
});
|
||||
btn.dataset.tsBound = '1';
|
||||
}
|
||||
|
||||
bind(nextBtn, 'next');
|
||||
bind(prevBtn, 'prev');
|
||||
|
||||
// Hover pause/resume on the whole slider area
|
||||
if (el && !el.__tsHoverBound) {
|
||||
el.addEventListener('mouseenter', () => stopAutoScroll());
|
||||
el.addEventListener('mouseleave', () => startAutoScroll());
|
||||
el.__tsHoverBound = true;
|
||||
}
|
||||
}
|
||||
|
||||
function setupDragWrap(swiper) {
|
||||
if (!swiper || !swiper.on) return;
|
||||
if (!swiper.__tsWrapBound) {
|
||||
swiper.on('reachEnd', () => { swiper.slideTo(0, 400, false); });
|
||||
swiper.on('reachBeginning', () => {
|
||||
const last = (swiper.slides && swiper.slides.length ? swiper.slides.length - 1 : 0);
|
||||
swiper.slideTo(last, 400, false);
|
||||
});
|
||||
swiper.__tsWrapBound = true;
|
||||
}
|
||||
|
||||
// Pause autoscroll on user touch/drag and schedule resume on release
|
||||
if (!swiper.__tsAutoBound) {
|
||||
try {
|
||||
swiper.on('touchStart', () => { stopAutoScroll(); });
|
||||
swiper.on('touchEnd', () => { scheduleAutoResume(); });
|
||||
swiper.on('pointerDown', () => { stopAutoScroll(); });
|
||||
swiper.on('pointerUp', () => { scheduleAutoResume(); });
|
||||
} catch (_) {}
|
||||
swiper.__tsAutoBound = true;
|
||||
}
|
||||
}
|
||||
|
||||
function startAutoScroll() {
|
||||
const inst = getSwiperInstance();
|
||||
if (!inst) return;
|
||||
const { api } = inst;
|
||||
stopAutoScroll();
|
||||
autoTimer = window.setInterval(() => {
|
||||
if (!api) return;
|
||||
try {
|
||||
// If not looping, wrap to first when at end
|
||||
const loop = api.params && api.params.loop;
|
||||
if (!loop && api.isEnd) {
|
||||
api.slideTo(0, 600, false);
|
||||
} else if (typeof api.slideNext === 'function') {
|
||||
api.slideNext(600);
|
||||
}
|
||||
} catch (_) {}
|
||||
}, AUTO_DELAY);
|
||||
}
|
||||
|
||||
function stopAutoScroll() {
|
||||
if (autoTimer) {
|
||||
clearInterval(autoTimer);
|
||||
autoTimer = null;
|
||||
}
|
||||
if (resumeTimer) {
|
||||
clearTimeout(resumeTimer);
|
||||
resumeTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
function scheduleAutoResume() {
|
||||
if (resumeTimer) {
|
||||
clearTimeout(resumeTimer);
|
||||
resumeTimer = null;
|
||||
}
|
||||
resumeTimer = window.setTimeout(() => {
|
||||
startAutoScroll();
|
||||
}, RESUME_AFTER);
|
||||
}
|
||||
|
||||
function showPreloader() {
|
||||
const el = document.getElementById(PRELOADER_ID);
|
||||
if (el) el.classList.add('visible');
|
||||
}
|
||||
|
||||
function hidePreloader() {
|
||||
const el = document.getElementById(PRELOADER_ID);
|
||||
if (el) el.classList.remove('visible');
|
||||
}
|
||||
|
||||
function markNotReady() {
|
||||
const sec = document.getElementById(SECTION_ID);
|
||||
if (sec) sec.classList.add('not-ready');
|
||||
}
|
||||
|
||||
function markReady() {
|
||||
const sec = document.getElementById(SECTION_ID);
|
||||
if (sec) sec.classList.remove('not-ready');
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
ensureBasicStyles();
|
||||
markNotReady();
|
||||
showPreloader();
|
||||
bindUI();
|
||||
});
|
||||
|
||||
// Defer initial population until all assets and theme scripts (e.g., sliders) are fully initialized
|
||||
window.addEventListener('load', () => {
|
||||
switchGender(currentGender);
|
||||
});
|
||||
})();
|
||||
// team-switcher.js
|
||||
// Loads team data from XML and populates the team slider. Adds a men/women switcher.
|
||||
|
||||
(function () {
|
||||
const XML_URL = 'data/team.xml';
|
||||
const SWITCHER_ID = 'gender-switcher';
|
||||
const WRAPPER_ID = 'team-swiper-wrapper-1';
|
||||
const PRELOADER_ID = 'team-preloader-1';
|
||||
const SECTION_ID = 'team-section-1';
|
||||
|
||||
let teamData = null; // cached parsed XML data
|
||||
let currentGender = 'men';
|
||||
// Autoscroll timers
|
||||
let autoTimer = null;
|
||||
let resumeTimer = null;
|
||||
const AUTO_DELAY = 3500; // 5s
|
||||
const RESUME_AFTER = 10000; // resume 10s after user interaction
|
||||
|
||||
function qs(sel, root = document) { return root.querySelector(sel); }
|
||||
function qsa(sel, root = document) { return Array.from(root.querySelectorAll(sel)); }
|
||||
|
||||
async function loadXML() {
|
||||
if (teamData) return teamData;
|
||||
const res = await fetch(XML_URL, { cache: 'no-cache' });
|
||||
if (!res.ok) throw new Error('Failed to fetch team.xml');
|
||||
const text = await res.text();
|
||||
const parser = new DOMParser();
|
||||
const xml = parser.parseFromString(text, 'application/xml');
|
||||
const parseError = xml.querySelector('parsererror');
|
||||
if (parseError) throw new Error('Invalid XML in team.xml');
|
||||
teamData = xml;
|
||||
return xml;
|
||||
}
|
||||
|
||||
function getMembersByCategory(xml, categoryName) {
|
||||
const cat = Array.from(xml.querySelectorAll('team > category'))
|
||||
.find(c => (c.getAttribute('name') || '').toLowerCase() === categoryName);
|
||||
if (!cat) return [];
|
||||
return Array.from(cat.querySelectorAll('member')).map(m => ({
|
||||
name: (m.querySelector('name')?.textContent || '').trim(),
|
||||
number: (m.querySelector('number')?.textContent || '').trim(),
|
||||
role: (m.querySelector('role')?.textContent || '').trim(),
|
||||
image: (m.querySelector('image')?.textContent || '').trim(),
|
||||
}));
|
||||
}
|
||||
|
||||
function slideHTML(member) {
|
||||
const numHTML = member.number ? `<div class="lte-num">${member.number}</div>` : '<div class="lte-num"></div>';
|
||||
const safeImg = member.image || '';
|
||||
return (
|
||||
`<div class="lte-item swiper-slide">
|
||||
<div class="lte-team-item">
|
||||
<a class="lte-image" style="background-image: url()">
|
||||
<img loading="lazy" decoding="async" width="800" height="1200" src="${safeImg}" class="attachment-full size-full" />
|
||||
</a>
|
||||
<div class="lte-descr">
|
||||
${numHTML}
|
||||
<a href="${safeImg}" target="_blank">
|
||||
<h4 class="lte-header">${member.name}</h4>
|
||||
</a>
|
||||
<p class="lte-subheader" style="color: #c42221">${member.role}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
);
|
||||
}
|
||||
|
||||
function renderMembers(members) {
|
||||
const wrapper = document.getElementById(WRAPPER_ID);
|
||||
if (!wrapper) return;
|
||||
const swiperEl = wrapper.closest('.swiper-container');
|
||||
const swiper = swiperEl && swiperEl.swiper;
|
||||
|
||||
// Use DOM-based rendering to match theme's slider expectations
|
||||
wrapper.innerHTML = members.map(slideHTML).join('');
|
||||
|
||||
// Strong refresh
|
||||
if (swiper) {
|
||||
try {
|
||||
if (typeof swiper.updateSlides === 'function') swiper.updateSlides();
|
||||
if (typeof swiper.updateSize === 'function') swiper.updateSize();
|
||||
if (typeof swiper.updateAutoHeight === 'function') swiper.updateAutoHeight(0);
|
||||
if (typeof swiper.slideTo === 'function') swiper.slideTo(0, 0, false);
|
||||
if (typeof swiper.update === 'function') swiper.update();
|
||||
} catch (e) {}
|
||||
}
|
||||
// Ask the theme to re-init this slider completely so arrows/loop/order are consistent
|
||||
const sliderContainer = wrapper.closest('.lte-swiper-slider');
|
||||
if (sliderContainer) sliderContainer.classList.remove('lte-inited');
|
||||
if (typeof window.initSwiperWrappers === 'function') {
|
||||
try { window.initSwiperWrappers(); } catch (_) {}
|
||||
}
|
||||
// Remove any duplicate arrow bars the theme may have added on re-init
|
||||
cleanupDuplicateArrows();
|
||||
setTimeout(() => window.dispatchEvent(new Event('resize')), 0);
|
||||
|
||||
// Ensure arrows exist and are bound; manual endless wrap
|
||||
setupEndlessNavigation(swiperEl);
|
||||
setupDragWrap(swiper);
|
||||
// Restart autoscroll on fresh render
|
||||
stopAutoScroll();
|
||||
startAutoScroll();
|
||||
}
|
||||
|
||||
// Keep only one arrows bar; prefer the one whose anchors already have our data-ts-bound
|
||||
function cleanupDuplicateArrows() {
|
||||
const wrapper = document.getElementById(WRAPPER_ID);
|
||||
if (!wrapper) return;
|
||||
const slider = wrapper.closest('.lte-swiper-slider');
|
||||
if (!slider) return;
|
||||
|
||||
// Arrows can be siblings of slider or children inside slider depending on theme config
|
||||
const candidates = [];
|
||||
const parent = slider.parentElement;
|
||||
if (parent) {
|
||||
Array.from(parent.children).forEach((el) => { if (el.classList && el.classList.contains('lte-arrows')) candidates.push(el); });
|
||||
}
|
||||
Array.from(slider.children).forEach((el) => { if (el.classList && el.classList.contains('lte-arrows')) candidates.push(el); });
|
||||
|
||||
if (candidates.length <= 1) return;
|
||||
|
||||
// Prefer the one that already has data-ts-bound anchors
|
||||
const hasBound = candidates.find(a => a.querySelector('a[data-ts-bound="1"]'));
|
||||
const keep = hasBound || candidates[0];
|
||||
candidates.forEach((a) => { if (a !== keep && a.parentElement) a.parentElement.removeChild(a); });
|
||||
}
|
||||
|
||||
async function switchGender(gender) {
|
||||
currentGender = gender;
|
||||
try {
|
||||
showPreloader();
|
||||
const xml = await loadXML();
|
||||
// Keep the order as in XML so the first visible is the first listed (e.g., Janečka Martin)
|
||||
const list = getMembersByCategory(xml, gender);
|
||||
renderMembers(list);
|
||||
updateActiveButton();
|
||||
markReady();
|
||||
hidePreloader();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
hidePreloader();
|
||||
}
|
||||
}
|
||||
|
||||
function updateActiveButton() {
|
||||
const container = document.getElementById(SWITCHER_ID);
|
||||
if (!container) return;
|
||||
qsa('button[data-gender]', container).forEach(btn => {
|
||||
btn.classList.toggle('active', btn.dataset.gender === currentGender);
|
||||
});
|
||||
}
|
||||
|
||||
function bindUI() {
|
||||
const container = document.getElementById(SWITCHER_ID);
|
||||
if (!container) return;
|
||||
container.addEventListener('click', (e) => {
|
||||
const btn = e.target.closest('button[data-gender]');
|
||||
if (!btn) return;
|
||||
const gender = btn.dataset.gender;
|
||||
if (gender && gender !== currentGender) switchGender(gender);
|
||||
});
|
||||
}
|
||||
|
||||
function ensureBasicStyles() {
|
||||
const css = `
|
||||
#${SWITCHER_ID}{display:flex;gap:.5rem;justify-content:center;margin:10px 0}
|
||||
#${SWITCHER_ID} .switch-btn{background:#eee;border:1px solid #ccc;border-radius:20px;padding:.35rem .9rem;font-weight:600;cursor:pointer}
|
||||
#${SWITCHER_ID} .switch-btn.active{background:#111;color:#fff;border-color:#111}
|
||||
#${PRELOADER_ID}{display:none;align-items:center;justify-content:center;gap:.6rem;color:#fff;padding:8px 0}
|
||||
#${PRELOADER_ID}.visible{display:flex}
|
||||
#${PRELOADER_ID} .spinner{width:16px;height:16px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:ts-spin .8s linear infinite}
|
||||
@keyframes ts-spin{to{transform:rotate(360deg)}}
|
||||
#${SECTION_ID}.not-ready .lte-swiper-slider-wrapper{visibility:hidden}
|
||||
`;
|
||||
const style = document.createElement('style');
|
||||
style.textContent = css;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
function getSwiperInstance() {
|
||||
const wrapper = document.getElementById(WRAPPER_ID);
|
||||
const swiperEl = wrapper && wrapper.closest('.swiper-container');
|
||||
return swiperEl && swiperEl.swiper ? { el: swiperEl, api: swiperEl.swiper } : null;
|
||||
}
|
||||
|
||||
function setupEndlessNavigation(swiperContainerEl) {
|
||||
const inst = getSwiperInstance();
|
||||
if (!inst) return;
|
||||
const { el, api } = inst;
|
||||
|
||||
// Ensure only one set of arrows remains before binding
|
||||
cleanupDuplicateArrows();
|
||||
|
||||
// Theme uses .lte-arrow-left / .lte-arrow-right (see frontend.js init)
|
||||
let nextBtn = el.parentElement && el.parentElement.querySelector('.lte-arrows .lte-arrow-right');
|
||||
let prevBtn = el.parentElement && el.parentElement.querySelector('.lte-arrows .lte-arrow-left');
|
||||
// Fallback to common Swiper classes if theme structure changes
|
||||
if (!nextBtn) nextBtn = el.querySelector('.swiper-button-next, .lte-swiper-button-next, .lte-next, .lte-arrow-next, .lte-arrow-right');
|
||||
if (!prevBtn) prevBtn = el.querySelector('.swiper-button-prev, .lte-swiper-button-prev, .lte-prev, .lte-arrow-prev, .lte-arrow-left');
|
||||
|
||||
// Do not create fallback arrows; rely on theme arrows only
|
||||
|
||||
function bind(btn, dir) {
|
||||
if (!btn || btn.dataset.tsBound) return;
|
||||
btn.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
if (!api) return;
|
||||
// User override: pause and schedule resume
|
||||
stopAutoScroll();
|
||||
scheduleAutoResume();
|
||||
if (dir === 'next') {
|
||||
if (typeof api.slideNext === 'function') api.slideNext(400);
|
||||
else api.slideTo((api.activeIndex || 0) + 1, 400, false);
|
||||
} else {
|
||||
if (typeof api.slidePrev === 'function') api.slidePrev(400);
|
||||
else api.slideTo(Math.max((api.activeIndex || 0) - 1, 0), 400, false);
|
||||
}
|
||||
});
|
||||
btn.dataset.tsBound = '1';
|
||||
}
|
||||
|
||||
bind(nextBtn, 'next');
|
||||
bind(prevBtn, 'prev');
|
||||
|
||||
// Hover pause/resume on the whole slider area
|
||||
if (el && !el.__tsHoverBound) {
|
||||
el.addEventListener('mouseenter', () => stopAutoScroll());
|
||||
el.addEventListener('mouseleave', () => startAutoScroll());
|
||||
el.__tsHoverBound = true;
|
||||
}
|
||||
}
|
||||
|
||||
function setupDragWrap(swiper) {
|
||||
if (!swiper || !swiper.on) return;
|
||||
if (!swiper.__tsWrapBound) {
|
||||
swiper.on('reachEnd', () => { swiper.slideTo(0, 400, false); });
|
||||
swiper.on('reachBeginning', () => {
|
||||
const last = (swiper.slides && swiper.slides.length ? swiper.slides.length - 1 : 0);
|
||||
swiper.slideTo(last, 400, false);
|
||||
});
|
||||
swiper.__tsWrapBound = true;
|
||||
}
|
||||
|
||||
// Pause autoscroll on user touch/drag and schedule resume on release
|
||||
if (!swiper.__tsAutoBound) {
|
||||
try {
|
||||
swiper.on('touchStart', () => { stopAutoScroll(); });
|
||||
swiper.on('touchEnd', () => { scheduleAutoResume(); });
|
||||
swiper.on('pointerDown', () => { stopAutoScroll(); });
|
||||
swiper.on('pointerUp', () => { scheduleAutoResume(); });
|
||||
} catch (_) {}
|
||||
swiper.__tsAutoBound = true;
|
||||
}
|
||||
}
|
||||
|
||||
function startAutoScroll() {
|
||||
const inst = getSwiperInstance();
|
||||
if (!inst) return;
|
||||
const { api } = inst;
|
||||
stopAutoScroll();
|
||||
autoTimer = window.setInterval(() => {
|
||||
if (!api) return;
|
||||
try {
|
||||
// If not looping, wrap to first when at end
|
||||
const loop = api.params && api.params.loop;
|
||||
if (!loop && api.isEnd) {
|
||||
api.slideTo(0, 600, false);
|
||||
} else if (typeof api.slideNext === 'function') {
|
||||
api.slideNext(600);
|
||||
}
|
||||
} catch (_) {}
|
||||
}, AUTO_DELAY);
|
||||
}
|
||||
|
||||
function stopAutoScroll() {
|
||||
if (autoTimer) {
|
||||
clearInterval(autoTimer);
|
||||
autoTimer = null;
|
||||
}
|
||||
if (resumeTimer) {
|
||||
clearTimeout(resumeTimer);
|
||||
resumeTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
function scheduleAutoResume() {
|
||||
if (resumeTimer) {
|
||||
clearTimeout(resumeTimer);
|
||||
resumeTimer = null;
|
||||
}
|
||||
resumeTimer = window.setTimeout(() => {
|
||||
startAutoScroll();
|
||||
}, RESUME_AFTER);
|
||||
}
|
||||
|
||||
function showPreloader() {
|
||||
const el = document.getElementById(PRELOADER_ID);
|
||||
if (el) el.classList.add('visible');
|
||||
}
|
||||
|
||||
function hidePreloader() {
|
||||
const el = document.getElementById(PRELOADER_ID);
|
||||
if (el) el.classList.remove('visible');
|
||||
}
|
||||
|
||||
function markNotReady() {
|
||||
const sec = document.getElementById(SECTION_ID);
|
||||
if (sec) sec.classList.add('not-ready');
|
||||
}
|
||||
|
||||
function markReady() {
|
||||
const sec = document.getElementById(SECTION_ID);
|
||||
if (sec) sec.classList.remove('not-ready');
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
ensureBasicStyles();
|
||||
markNotReady();
|
||||
showPreloader();
|
||||
bindUI();
|
||||
});
|
||||
|
||||
// Defer initial population until all assets and theme scripts (e.g., sliders) are fully initialized
|
||||
window.addEventListener('load', () => {
|
||||
switchGender(currentGender);
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full">
|
||||
@@ -78,6 +79,11 @@
|
||||
<span>Kontakt</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="vykonny-vybor.html">
|
||||
<span>Výkonný výbor</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="index.html#tym">
|
||||
<span>Tým</span>
|
||||
|
||||
+23
-23
@@ -1,23 +1,23 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# Serve static assets
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# Proxy data API to backend
|
||||
location /data/ {
|
||||
proxy_pass http://backend:8080/data/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
}
|
||||
|
||||
location /healthz {
|
||||
proxy_pass http://backend:8080/healthz;
|
||||
}
|
||||
}
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# Serve static assets
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# Proxy data API to backend
|
||||
location /data/ {
|
||||
proxy_pass http://backend:8080/data/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
}
|
||||
|
||||
location /healthz {
|
||||
proxy_pass http://backend:8080/healthz;
|
||||
}
|
||||
}
|
||||
|
||||
+839
-805
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full">
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<script type="text/javascript" src="js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full">
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Remove local blog files and keep only remote blogs
|
||||
# Run this in your bizoni directory
|
||||
|
||||
echo "🗑️ Removing local blog files..."
|
||||
|
||||
# Remove all blog files
|
||||
rm -rf blog/
|
||||
|
||||
echo "✅ Local blog files removed!"
|
||||
echo ""
|
||||
echo "📝 Next steps:"
|
||||
echo "1. Deploy updated backend to server"
|
||||
echo "2. Backend will now work with remote blogs only"
|
||||
echo "3. Admin interface will connect to server API"
|
||||
echo ""
|
||||
echo "🌐 Your live blogs will remain untouched on the server"
|
||||
@@ -0,0 +1,300 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🚀 Bizoni Remote Blog Setup - One Command Script
|
||||
# Run this to setup remote blog management
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Bizoni Remote Blog Setup"
|
||||
echo "=========================="
|
||||
|
||||
# Configuration - UPDATE THESE
|
||||
SERVER_USER="your_username" # Your SSH username
|
||||
SERVER_HOST="your_server.com" # Your server domain/IP
|
||||
SERVER_BLOG_DIR="/var/www/bizoni/blog" # Blog directory on server
|
||||
LOCAL_PROJECT_DIR="/home/tdvorak/Desktop/HTML_Projekty/bizoni" # Your local project
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Helper functions
|
||||
print_status() {
|
||||
echo -e "${BLUE}ℹ️ $1${NC}"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
}
|
||||
|
||||
# Check if local blogs exist
|
||||
check_local_blogs() {
|
||||
print_status "Checking local blog files..."
|
||||
|
||||
if [ -d "$LOCAL_PROJECT_DIR/blog" ]; then
|
||||
blog_count=$(find "$LOCAL_PROJECT_DIR/blog" -name "*.html" -type f 2>/dev/null | wc -l)
|
||||
if [ "$blog_count" -gt 0 ]; then
|
||||
print_warning "Found $blog_count local blog files"
|
||||
read -p "Remove local blog files? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
rm -rf "$LOCAL_PROJECT_DIR/blog"
|
||||
print_success "Local blog files removed"
|
||||
else
|
||||
print_warning "Skipping local blog removal"
|
||||
fi
|
||||
else
|
||||
print_success "No local blog files found"
|
||||
fi
|
||||
else
|
||||
print_success "No local blog directory found"
|
||||
fi
|
||||
}
|
||||
|
||||
# Create Ubuntu management script
|
||||
create_server_script() {
|
||||
print_status "Creating server management script..."
|
||||
|
||||
cat > /tmp/ubuntu-blog-manager.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
# Ubuntu Server Blog Management Script
|
||||
set -e
|
||||
|
||||
BLOG_DIR="/var/www/bizoni/blog"
|
||||
BACKUP_DIR="/var/backups/bizoni-blogs"
|
||||
|
||||
# Create backup
|
||||
create_backup() {
|
||||
echo "📦 Creating backup..."
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
timestamp=$(date +%Y%m%d_%H%M%S)
|
||||
tar -czf "$BACKUP_DIR/blogs_backup_$timestamp.tar.gz" -C "$BLOG_DIR" . 2>/dev/null || echo "No files to backup"
|
||||
echo "✅ Backup created"
|
||||
}
|
||||
|
||||
# Generate slug from title
|
||||
generate_slug() {
|
||||
local title="$1"
|
||||
echo "$title" | tr '[:upper:]' '[:lower:]' | \
|
||||
sed 's/á/a/g; s/ä/a/g; s/č/c/g; s/ď/d/g; s/é/e/g; s/ě/e/g; s/í/i/g; s/ľ/l/g; s/ň/n/g; s/ó/o/g; s/ö/o/g; s/ô/o/g; s/ř/r/g; s/š/s/g; s/ť/t/g; s/ú/u/g; s/ů/u/g; s/ý/y/g; s/ž/z/g' | \
|
||||
sed 's/Á/a/g; s/Ä/a/g; s/Č/c/g; s/Ď/d/g; s/É/e/g; s/Ě/e/g; s/Í/i/g; s/Ľ/l/g; s/Ň/n/g; s/Ó/o/g; s/Ö/o/g; s/Ô/o/g; s/Ř/r/g; s/Š/s/g; s/Ť/t/g; s/Ú/u/g; s/Ů/u/g; s/Ý/y/g; s/Ž/z/g' | \
|
||||
sed 's/[^a-z0-9\s-]//g' | \
|
||||
sed 's/[\s-]\+/ -/g' | \
|
||||
sed 's/^-\|-$//g'
|
||||
}
|
||||
|
||||
# Add slug to blog
|
||||
add_slug_to_blog() {
|
||||
local blog_id="$1"
|
||||
local blog_file="$BLOG_DIR/$blog_id.html"
|
||||
|
||||
if [ ! -f "$blog_file" ]; then
|
||||
echo "❌ Blog not found: $blog_id.html"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if slug already exists
|
||||
if grep -q '<meta name="slug"' "$blog_file"; then
|
||||
echo "ℹ️ $blog_id already has slug"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Extract title
|
||||
title=$(grep -o '<h1[^>]*class="[^"]*lte-header[^"]*"[^>]*>.*</h1>' "$blog_file" 2>/dev/null | sed 's/<[^>]*>//g' | xargs || echo "")
|
||||
|
||||
if [ -z "$title" ]; then
|
||||
echo "❌ Could not extract title from $blog_id"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Generate slug
|
||||
slug=$(generate_slug "$title")
|
||||
|
||||
# Check uniqueness
|
||||
counter=2
|
||||
original_slug="$slug"
|
||||
while [ -f "$BLOG_DIR/$slug.html" ]; do
|
||||
slug="$original_slug-$counter"
|
||||
((counter++))
|
||||
done
|
||||
|
||||
echo "📝 $blog_id: $title → $slug"
|
||||
|
||||
# Add slug meta tag
|
||||
sed -i "s|</head>|<meta name=\"slug\" content=\"$slug\">\n</head>|" "$blog_file"
|
||||
|
||||
# Create slug file
|
||||
cp "$blog_file" "$BLOG_DIR/$slug.html"
|
||||
|
||||
echo "✅ Added slug: $slug.html"
|
||||
}
|
||||
|
||||
# Migrate all blogs
|
||||
migrate_all() {
|
||||
echo "🔄 Migrating all blogs..."
|
||||
|
||||
if [ ! -d "$BLOG_DIR" ]; then
|
||||
echo "❌ Blog directory not found: $BLOG_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
create_backup
|
||||
|
||||
count=0
|
||||
for blog_file in "$BLOG_DIR"/*.html; do
|
||||
if [ -f "$blog_file" ]; then
|
||||
filename=$(basename "$blog_file")
|
||||
if [[ "$filename" =~ ^([0-9]{4})\.html$ ]]; then
|
||||
blog_id="${BASH_REMATCH[1]}"
|
||||
add_slug_to_blog "$blog_id"
|
||||
((count++))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo "✅ Migration completed! Processed $count blogs"
|
||||
}
|
||||
|
||||
# List blogs
|
||||
list_blogs() {
|
||||
echo "📋 Blogs on server:"
|
||||
if [ -d "$BLOG_DIR" ]; then
|
||||
for file in "$BLOG_DIR"/*.html; do
|
||||
if [ -f "$file" ]; then
|
||||
filename=$(basename "$file")
|
||||
if [[ "$filename" =~ ^[0-9]{4}\.html$ ]]; then
|
||||
echo " 📄 $filename (numeric)"
|
||||
elif [[ "$filename" =~ ^[a-z0-9-]+\.html$ ]]; then
|
||||
echo " 🔗 $filename (slug)"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo " ❌ Blog directory not found"
|
||||
fi
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
"migrate")
|
||||
migrate_all
|
||||
;;
|
||||
"list")
|
||||
list_blogs
|
||||
;;
|
||||
"backup")
|
||||
create_backup
|
||||
;;
|
||||
*)
|
||||
echo "Ubuntu Blog Manager"
|
||||
echo "=================="
|
||||
echo "Usage: $0 <command>"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " migrate - Add slugs to all blogs"
|
||||
echo " list - List all blogs"
|
||||
echo " backup - Create backup"
|
||||
echo ""
|
||||
echo "Example: $0 migrate"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
EOF
|
||||
|
||||
chmod +x /tmp/ubuntu-blog-manager.sh
|
||||
print_success "Server script created"
|
||||
}
|
||||
|
||||
# Deploy to server
|
||||
deploy_to_server() {
|
||||
print_status "Deploying to server..."
|
||||
|
||||
# Upload server script
|
||||
scp /tmp/ubuntu-blog-manager.sh "$SERVER_USER@$SERVER_HOST:/tmp/"
|
||||
|
||||
# Move script to server location and make executable
|
||||
ssh "$SERVER_USER@$SERVER_HOST" "sudo mv /tmp/ubuntu-blog-manager.sh /usr/local/bin/blog-manager && sudo chmod +x /usr/local/bin/blog-manager"
|
||||
|
||||
print_success "Server script deployed to /usr/local/bin/blog-manager"
|
||||
}
|
||||
|
||||
# Test server connection
|
||||
test_connection() {
|
||||
print_status "Testing server connection..."
|
||||
|
||||
if ssh "$SERVER_USER@$SERVER_HOST" "echo 'Connection successful'" 2>/dev/null; then
|
||||
print_success "Server connection OK"
|
||||
else
|
||||
print_error "Cannot connect to server. Please check:"
|
||||
echo " - Username: $SERVER_USER"
|
||||
echo " - Host: $SERVER_HOST"
|
||||
echo " - SSH key or password setup"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Run migration on server
|
||||
run_migration() {
|
||||
print_status "Running migration on server..."
|
||||
|
||||
ssh "$SERVER_USER@$SERVER_HOST" "sudo blog-manager migrate"
|
||||
|
||||
print_success "Migration completed on server"
|
||||
}
|
||||
|
||||
# Show results
|
||||
show_results() {
|
||||
print_status "Showing results..."
|
||||
|
||||
echo ""
|
||||
ssh "$SERVER_USER@$SERVER_HOST" "blog-manager list"
|
||||
echo ""
|
||||
print_success "Setup completed!"
|
||||
echo ""
|
||||
echo "🌐 Your blogs now have clean URLs:"
|
||||
echo " Old: /blog/0030.html"
|
||||
echo " New: /blog/jdeme-do-finale"
|
||||
echo ""
|
||||
echo "🔧 Server commands you can use:"
|
||||
echo " ssh $SERVER_USER@$SERVER_HOST 'blog-manager list'"
|
||||
echo " ssh $SERVER_USER@$SERVER_HOST 'blog-manager backup'"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
echo ""
|
||||
print_warning "Please update the configuration in this script:"
|
||||
echo " SERVER_USER=\"$SERVER_USER\""
|
||||
echo " SERVER_HOST=\"$SERVER_HOST\""
|
||||
echo " SERVER_BLOG_DIR=\"$SERVER_BLOG_DIR\""
|
||||
echo ""
|
||||
read -p "Continue with current settings? (y/N): " -n 1 -r
|
||||
echo
|
||||
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Please edit the script and run again"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
check_local_blogs
|
||||
test_connection
|
||||
create_server_script
|
||||
deploy_to_server
|
||||
run_migration
|
||||
show_results
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Simple Server Setup Script - Run this ON YOUR SERVER after git push
|
||||
# Usage: ./setup-server.sh
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Bizoni Server Setup Script"
|
||||
echo "============================"
|
||||
|
||||
# Configuration - UPDATE THESE IF NEEDED
|
||||
BLOG_DIR="/var/www/bizoni/blog"
|
||||
IMG_DIR="/var/www/bizoni/img/blog"
|
||||
BACKUP_DIR="/var/backups/bizoni"
|
||||
|
||||
echo "📁 Blog directory: $BLOG_DIR"
|
||||
echo "🖼️ Image directory: $IMG_DIR"
|
||||
echo ""
|
||||
|
||||
# Check if directories exist
|
||||
if [ ! -d "$BLOG_DIR" ]; then
|
||||
echo "❌ Blog directory not found: $BLOG_DIR"
|
||||
echo "Please update BLOG_DIR in this script"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$IMG_DIR" ]; then
|
||||
echo "❌ Image directory not found: $IMG_DIR"
|
||||
echo "Please update IMG_DIR in this script"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Directories found"
|
||||
echo ""
|
||||
|
||||
# Create backup
|
||||
echo "📦 Creating backup..."
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
timestamp=$(date +%Y%m%d_%H%M%S)
|
||||
tar -czf "$BACKUP_DIR/blogs_backup_$timestamp.tar.gz" -C "$(dirname "$BLOG_DIR")" "$(basename "$BLOG_DIR")"
|
||||
echo "✅ Backup created: $BACKUP_DIR/blogs_backup_$timestamp.tar.gz"
|
||||
echo ""
|
||||
|
||||
# Count existing blogs
|
||||
total_blogs=$(ls "$BLOG_DIR"/*.html 2>/dev/null | wc -l)
|
||||
numeric_blogs=$(ls "$BLOG_DIR"/[0-9][0-9][0-9][0-9].html 2>/dev/null | wc -l)
|
||||
slug_blogs=$(ls "$BLOG_DIR"/[a-z]*.html 2>/dev/null | wc -l)
|
||||
|
||||
echo "📊 Current blog status:"
|
||||
echo " Total blogs: $total_blogs"
|
||||
echo " Numeric files: $numeric_blogs"
|
||||
echo " Slug files: $slug_blogs"
|
||||
echo ""
|
||||
|
||||
# Function to generate slug from title
|
||||
generate_slug() {
|
||||
local title="$1"
|
||||
echo "$title" | tr '[:upper:]' '[:lower:]' | \
|
||||
sed 's/á/a/g; s/ä/a/g; s/č/c/g; s/ď/d/g; s/é/e/g; s/ě/e/g; s/í/i/g; s/ľ/l/g; s/ň/n/g; s/ó/o/g; s/ö/o/g; s/ô/o/g; s/ř/r/g; s/š/s/g; s/ť/t/g; s/ú/u/g; s/ů/u/g; s/ý/y/g; s/ž/z/g' | \
|
||||
sed 's/Á/a/g; s/Ä/a/g; s/Č/c/g; s/Ď/d/g; s/É/e/g; s/Ě/e/g; s/Í/i/g; s/Ľ/l/g; s/Ň/n/g; s/Ó/o/g; s/Ö/o/g; s/Ô/o/g; s/Ř/r/g; s/Š/s/g; s/Ť/t/g; s/Ú/u/g; s/Ů/u/g; s/Ý/y/g; s/Ž/z/g' | \
|
||||
iconv -c -f utf-8 -t ascii//TRANSLIT | \
|
||||
sed 's/\s\+/-/g' | \
|
||||
sed 's/[^a-z0-9\-]//g' | \
|
||||
sed 's/-\+/-/g' | \
|
||||
sed 's/^\-\|\-$//g'
|
||||
}
|
||||
|
||||
# Function to extract title from HTML
|
||||
extract_title() {
|
||||
local file="$1"
|
||||
grep -o '<h1[^>]*class="[^"]*lte-header[^"]*"[^>]*>.*</h1>' "$file" | sed 's/<[^>]*>//g' | xargs || echo ""
|
||||
}
|
||||
|
||||
# Function to check if slug exists
|
||||
slug_exists() {
|
||||
local slug="$1"
|
||||
[ -f "$BLOG_DIR/$slug.html" ]
|
||||
}
|
||||
|
||||
# Process numeric blogs that don't have slugs yet
|
||||
echo "🔄 Processing blogs without slugs..."
|
||||
processed=0
|
||||
|
||||
for blog_file in "$BLOG_DIR"/[0-9][0-9][0-9][0-9].html; do
|
||||
if [ ! -f "$blog_file" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
filename=$(basename "$blog_file")
|
||||
blog_id="${filename%.html}"
|
||||
|
||||
# Check if slug meta tag already exists
|
||||
if grep -q '<meta name="slug"' "$blog_file"; then
|
||||
echo " ⏭️ Skipping $filename (slug already exists)"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Extract title
|
||||
title=$(extract_title "$blog_file")
|
||||
if [ -z "$title" ]; then
|
||||
echo " ⚠️ Skipping $filename (no title found)"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Generate slug
|
||||
base_slug=$(generate_slug "$title")
|
||||
slug="$base_slug"
|
||||
|
||||
# Make slug unique
|
||||
counter=2
|
||||
while slug_exists "$slug"; do
|
||||
slug="${base_slug}-${counter}"
|
||||
((counter++))
|
||||
done
|
||||
|
||||
echo " 📝 $filename: '$title' → '$slug'"
|
||||
|
||||
# Add slug meta tag before </head>
|
||||
sed -i "s|</head>|<meta name=\"slug\" content=\"$slug\">\n</head>|" "$blog_file"
|
||||
|
||||
# Create slug file (copy of original)
|
||||
cp "$blog_file" "$BLOG_DIR/$slug.html"
|
||||
|
||||
((processed++))
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "✅ Migration completed!"
|
||||
echo "📊 Processed $processed blogs"
|
||||
echo ""
|
||||
|
||||
# Show final status
|
||||
total_blogs=$(ls "$BLOG_DIR"/*.html 2>/dev/null | wc -l)
|
||||
numeric_blogs=$(ls "$BLOG_DIR"/[0-9][0-9][0-9][0-9].html 2>/dev/null | wc -l)
|
||||
slug_blogs=$(ls "$BLOG_DIR"/[a-z]*.html 2>/dev/null | wc -l)
|
||||
|
||||
echo "📊 Final blog status:"
|
||||
echo " Total blogs: $total_blogs"
|
||||
echo " Numeric files: $numeric_blogs"
|
||||
echo " Slug files: $slug_blogs"
|
||||
echo ""
|
||||
|
||||
# Show some example URLs
|
||||
echo "🌐 Example URLs now available:"
|
||||
echo " /blog/$(ls "$BLOG_DIR"/[a-z]*.html 2>/dev/null | head -1 | xargs basename -s .html || echo 'jdeme-do-finale')"
|
||||
echo " /blog/$(ls "$BLOG_DIR"/[a-z]*.html 2>/dev/null | head -2 | tail -1 | xargs basename -s .html || echo '1-zapas-final-score')"
|
||||
echo ""
|
||||
|
||||
echo "🎉 Setup complete! Your blogs now support:"
|
||||
echo " ✅ Clean URLs (slugs)"
|
||||
echo " ✅ SEO meta tags"
|
||||
echo " ✅ Backward compatibility"
|
||||
echo " ✅ New admin features"
|
||||
echo ""
|
||||
echo "📝 Next steps:"
|
||||
echo " 1. Restart your backend service"
|
||||
echo " 2. Test new URLs in browser"
|
||||
echo " 3. Try admin interface with new features"
|
||||
+11
-11
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset
|
||||
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
|
||||
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
|
||||
<!-- created with Free Online Sitemap Generator www.xml-sitemaps.com -->
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset
|
||||
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
|
||||
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
|
||||
<!-- created with Free Online Sitemap Generator www.xml-sitemaps.com -->
|
||||
|
||||
|
||||
<url>
|
||||
<loc>https://www.bizoniuh.cz/</loc>
|
||||
@@ -166,7 +166,7 @@
|
||||
<loc>https://www.bizoniuh.cz/zapasy/bizoni-hombres2.html</loc>
|
||||
<lastmod>2024-11-13T09:24:05+00:00</lastmod>
|
||||
<priority>0.64</priority>
|
||||
</url>
|
||||
|
||||
|
||||
</url>
|
||||
|
||||
|
||||
</urlset>
|
||||
@@ -0,0 +1,166 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Println("Usage: ./migrate_slugs.go <site_root>")
|
||||
fmt.Println("Example: ./migrate_slugs.go /home/tdvorak/Desktop/HTML_Projekty/bizoni")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
siteRoot := os.Args[1]
|
||||
blogDir := filepath.Join(siteRoot, "blog")
|
||||
|
||||
// Read all blog files
|
||||
entries, err := os.ReadDir(blogDir)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read blog directory: %v", err)
|
||||
}
|
||||
|
||||
// Pattern to match numeric blog files
|
||||
numericPattern := regexp.MustCompile(`^(\d{4})\.html$`)
|
||||
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
filename := entry.Name()
|
||||
matches := numericPattern.FindStringSubmatch(filename)
|
||||
if len(matches) != 2 {
|
||||
continue // Skip non-numeric files
|
||||
}
|
||||
|
||||
blogPath := filepath.Join(blogDir, filename)
|
||||
|
||||
// Read the blog file
|
||||
content, err := os.ReadFile(blogPath)
|
||||
if err != nil {
|
||||
log.Printf("Failed to read %s: %v", filename, err)
|
||||
continue
|
||||
}
|
||||
|
||||
contentStr := string(content)
|
||||
|
||||
// Check if slug already exists
|
||||
slugPattern := regexp.MustCompile(`(?is)<meta name="slug" content="([^"]+)"`)
|
||||
if slugPattern.MatchString(contentStr) {
|
||||
log.Printf("Skipping %s - slug already exists", filename)
|
||||
continue
|
||||
}
|
||||
|
||||
// Extract title
|
||||
titlePattern := regexp.MustCompile(`(?is)<h1[^>]*class="[^"]*\blte-header\b[^"]*"[^>]*>(.*?)</h1>`)
|
||||
titleMatches := titlePattern.FindStringSubmatch(contentStr)
|
||||
if len(titleMatches) < 2 {
|
||||
log.Printf("Skipping %s - could not find title", filename)
|
||||
continue
|
||||
}
|
||||
|
||||
title := titleMatches[1]
|
||||
// Remove any HTML tags from title
|
||||
title = regexp.MustCompile(`(?is)<[^>]+>`).ReplaceAllString(title, "")
|
||||
title = strings.TrimSpace(title)
|
||||
|
||||
// Generate slug
|
||||
slug := generateSlug(title)
|
||||
slug = ensureUniqueSlug(siteRoot, slug)
|
||||
|
||||
// Find where to insert the slug meta tag (before </head>)
|
||||
headPattern := regexp.MustCompile(`(?is)</head>`)
|
||||
if !headPattern.MatchString(contentStr) {
|
||||
log.Printf("Skipping %s - could not find </head> tag", filename)
|
||||
continue
|
||||
}
|
||||
|
||||
// Insert slug meta tag
|
||||
slugMeta := fmt.Sprintf(`<meta name="slug" content="%s">`, slug)
|
||||
newContent := headPattern.ReplaceAllString(contentStr, slugMeta+"\n</head>")
|
||||
|
||||
// Write the updated content to both files
|
||||
err = os.WriteFile(blogPath, []byte(newContent), 0644)
|
||||
if err != nil {
|
||||
log.Printf("Failed to write updated %s: %v", filename, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Create slug-based file
|
||||
slugPath := filepath.Join(blogDir, slug+".html")
|
||||
err = os.WriteFile(slugPath, []byte(newContent), 0644)
|
||||
if err != nil {
|
||||
log.Printf("Failed to create slug file %s: %v", slugPath, err)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Printf("Processed %s: title='%s' -> slug='%s'", filename, title, slug)
|
||||
}
|
||||
|
||||
log.Println("Migration completed!")
|
||||
}
|
||||
|
||||
// generateSlug creates a URL-friendly slug from a title
|
||||
func generateSlug(title string) string {
|
||||
slug := strings.ToLower(title)
|
||||
// Replace Czech characters with their ASCII equivalents
|
||||
replacements := map[string]string{
|
||||
"á": "a", "ä": "a", "č": "c", "ď": "d", "é": "e", "ě": "e", "í": "i", "ľ": "l",
|
||||
"ň": "n", "ó": "o", "ö": "o", "ô": "o", "ř": "r", "š": "s", "ť": "t", "ú": "u",
|
||||
"ů": "u", "ý": "y", "ž": "z",
|
||||
"Á": "a", "Ä": "a", "Č": "c", "Ď": "d", "É": "e", "Ě": "e", "Í": "i", "Ľ": "l",
|
||||
"Ň": "n", "Ó": "o", "Ö": "o", "Ô": "o", "Ř": "r", "Š": "s", "Ť": "t", "Ú": "u",
|
||||
"Ů": "u", "Ý": "y", "Ž": "z",
|
||||
}
|
||||
for czech, ascii := range replacements {
|
||||
slug = strings.ReplaceAll(slug, czech, ascii)
|
||||
}
|
||||
// Remove any character that isn't alphanumeric, space, or hyphen
|
||||
re := regexp.MustCompile(`[^a-z0-9\s-]`)
|
||||
slug = re.ReplaceAllString(slug, "")
|
||||
// Replace spaces and multiple hyphens with a single hyphen
|
||||
re = regexp.MustCompile(`[\s-]+`)
|
||||
slug = re.ReplaceAllString(slug, "-")
|
||||
// Remove leading and trailing hyphens
|
||||
slug = strings.Trim(slug, "-")
|
||||
return slug
|
||||
}
|
||||
|
||||
// ensureUniqueSlug ensures the slug is unique by appending a number if needed
|
||||
func ensureUniqueSlug(siteRoot, baseSlug string) string {
|
||||
blogDir := filepath.Join(siteRoot, "blog")
|
||||
entries, err := os.ReadDir(blogDir)
|
||||
if err != nil {
|
||||
return baseSlug
|
||||
}
|
||||
existingSlugs := make(map[string]bool)
|
||||
for _, e := range entries {
|
||||
if !strings.HasSuffix(e.Name(), ".html") {
|
||||
continue
|
||||
}
|
||||
// Extract slug from filename if it follows the new pattern
|
||||
name := strings.TrimSuffix(e.Name(), ".html")
|
||||
// Check if it's a slug-based filename (contains letters, not just numbers)
|
||||
if regexp.MustCompile(`[a-z]`).MatchString(name) {
|
||||
existingSlugs[name] = true
|
||||
}
|
||||
}
|
||||
if !existingSlugs[baseSlug] {
|
||||
return baseSlug
|
||||
}
|
||||
// Try baseSlug-2, baseSlug-3, etc.
|
||||
for i := 2; i < 100; i++ {
|
||||
testSlug := fmt.Sprintf("%s-%d", baseSlug, i)
|
||||
if !existingSlugs[testSlug] {
|
||||
return testSlug
|
||||
}
|
||||
}
|
||||
// Fallback to timestamp
|
||||
return fmt.Sprintf("%s-%d", baseSlug, 1234567890)
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Ubuntu Server Script: Remote Blog Management
|
||||
# This script manages blogs on the remote server only
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration - UPDATE THESE PATHS
|
||||
SERVER_BLOG_DIR="/var/www/bizoni/blog" # Path to blogs on your server
|
||||
BACKUP_DIR="/var/backups/bizoni-blogs" # Backup location
|
||||
SITE_ROOT="/var/www/bizoni" # Site root on server
|
||||
|
||||
echo "🚀 Bizoni Remote Blog Management Script"
|
||||
echo "====================================="
|
||||
|
||||
# Function to create backup
|
||||
create_backup() {
|
||||
echo "📦 Creating backup..."
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
timestamp=$(date +%Y%m%d_%H%M%S)
|
||||
tar -czf "$BACKUP_DIR/blogs_backup_$timestamp.tar.gz" -C "$SERVER_BLOG_DIR" .
|
||||
echo "✅ Backup created: $BACKUP_DIR/blogs_backup_$timestamp.tar.gz"
|
||||
}
|
||||
|
||||
# Function to list blogs
|
||||
list_blogs() {
|
||||
echo "📋 Current blogs on server:"
|
||||
if [ -d "$SERVER_BLOG_DIR" ]; then
|
||||
ls -la "$SERVER_BLOG_DIR"/*.html | while read line; do
|
||||
filename=$(basename "$line")
|
||||
if [[ "$filename" =~ ^[0-9]{4}\.html$ ]]; then
|
||||
echo " 📄 $filename (numeric)"
|
||||
elif [[ "$filename" =~ ^[a-z0-9-]+\.html$ ]]; then
|
||||
echo " 🔗 $filename (slug)"
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo " ❌ Blog directory not found: $SERVER_BLOG_DIR"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to add slug to existing blog
|
||||
add_slug_to_blog() {
|
||||
local blog_id="$1"
|
||||
local blog_file="$SERVER_BLOG_DIR/$blog_id.html"
|
||||
|
||||
if [ ! -f "$blog_file" ]; then
|
||||
echo "❌ Blog file not found: $blog_file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "🔧 Adding slug to blog: $blog_id"
|
||||
|
||||
# Extract title from blog file
|
||||
title=$(grep -o '<h1[^>]*class="[^"]*lte-header[^"]*"[^>]*>.*</h1>' "$blog_file" | sed 's/<[^>]*>//g' | xargs)
|
||||
|
||||
if [ -z "$title" ]; then
|
||||
echo "❌ Could not extract title from $blog_file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "📝 Title: $title"
|
||||
|
||||
# Generate slug
|
||||
slug=$(echo "$title" | tr '[:upper:]' '[:lower:]' | \
|
||||
sed 's/á/a/g; s/ä/a/g; s/č/c/g; s/ď/d/g; s/é/e/g; s/ě/e/g; s/í/i/g; s/ľ/l/g; s/ň/n/g; s/ó/o/g; s/ö/o/g; s/ô/o/g; s/ř/r/g; s/š/s/g; s/ť/t/g; s/ú/u/g; s/ů/u/g; s/ý/y/g; s/ž/z/g' | \
|
||||
sed 's/Á/a/g; s/Ä/a/g; s/Č/c/g; s/Ď/d/g; s/É/e/g; s/Ě/e/g; s/Í/i/g; s/Ľ/l/g; s/Ň/n/g; s/Ó/o/g; s/Ö/o/g; s/Ô/o/g; s/Ř/r/g; s/Š/s/g; s/Ť/t/g; s/Ú/u/g; s/Ů/u/g; s/Ý/y/g; s/Ž/z/g' | \
|
||||
sed 's/[^a-z0-9\s-]//g' | \
|
||||
sed 's/[\s-]\+/ -/g' | \
|
||||
sed 's/^-\|-$//g')
|
||||
|
||||
# Check if slug file already exists
|
||||
slug_file="$SERVER_BLOG_DIR/$slug.html"
|
||||
if [ -f "$slug_file" ]; then
|
||||
# Add number suffix
|
||||
i=2
|
||||
while [ -f "$SERVER_BLOG_DIR/${slug}-${i}.html" ]; do
|
||||
((i++))
|
||||
done
|
||||
slug="${slug}-${i}"
|
||||
slug_file="$SERVER_BLOG_DIR/${slug}.html"
|
||||
fi
|
||||
|
||||
echo "🔗 Generated slug: $slug"
|
||||
|
||||
# Check if slug meta tag already exists
|
||||
if grep -q '<meta name="slug"' "$blog_file"; then
|
||||
echo "ℹ️ Slug meta tag already exists"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Add slug meta tag before </head>
|
||||
sed -i "s|</head>|<meta name=\"slug\" content=\"$slug\">\n</head>|" "$blog_file"
|
||||
|
||||
# Create slug file (copy of original)
|
||||
cp "$blog_file" "$slug_file"
|
||||
|
||||
echo "✅ Slug added and slug file created: $slug.html"
|
||||
}
|
||||
|
||||
# Function to migrate all blogs to slugs
|
||||
migrate_all_blogs() {
|
||||
echo "🔄 Migrating all blogs to slugs..."
|
||||
|
||||
if [ ! -d "$SERVER_BLOG_DIR" ]; then
|
||||
echo "❌ Blog directory not found: $SERVER_BLOG_DIR"
|
||||
echo "Please update SERVER_BLOG_DIR in this script"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
create_backup
|
||||
|
||||
# Process all numeric blog files
|
||||
for blog_file in "$SERVER_BLOG_DIR"/*.html; do
|
||||
if [ -f "$blog_file" ]; then
|
||||
filename=$(basename "$blog_file")
|
||||
if [[ "$filename" =~ ^([0-9]{4})\.html$ ]]; then
|
||||
blog_id="${BASH_REMATCH[1]}"
|
||||
add_slug_to_blog "$blog_id"
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo "✅ Migration completed!"
|
||||
}
|
||||
|
||||
# Function to show blog info
|
||||
show_blog_info() {
|
||||
local blog_id="$1"
|
||||
local blog_file="$SERVER_BLOG_DIR/$blog_id.html"
|
||||
|
||||
if [ ! -f "$blog_file" ]; then
|
||||
echo "❌ Blog file not found: $blog_file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "📄 Blog Info for: $blog_id"
|
||||
echo "========================"
|
||||
|
||||
# Extract title
|
||||
title=$(grep -o '<h1[^>]*class="[^"]*lte-header[^"]*"[^>]*>.*</h1>' "$blog_file" | sed 's/<[^>]*>//g' | xargs)
|
||||
echo "📝 Title: $title"
|
||||
|
||||
# Extract slug
|
||||
slug=$(grep -o '<meta name="slug" content="[^"]*"' "$blog_file" | sed 's/.*content="\([^"]*\)".*/\1/')
|
||||
echo "🔗 Slug: $slug"
|
||||
|
||||
# Extract categories
|
||||
categories=$(grep -o '<meta name="category" content="[^"]*"' "$blog_file" | sed 's/.*content="\([^"]*\)".*/\1/' | tr '\n' ', ')
|
||||
echo "🏷️ Categories: $categories"
|
||||
|
||||
# File size
|
||||
size=$(du -h "$blog_file" | cut -f1)
|
||||
echo "📊 Size: $size"
|
||||
|
||||
# Check if slug file exists
|
||||
if [ -n "$slug" ] && [ -f "$SERVER_BLOG_DIR/$slug.html" ]; then
|
||||
echo "✅ Slug file exists: $slug.html"
|
||||
else
|
||||
echo "❌ Slug file missing"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main menu
|
||||
case "${1:-}" in
|
||||
"list")
|
||||
list_blogs
|
||||
;;
|
||||
"migrate")
|
||||
migrate_all_blogs
|
||||
;;
|
||||
"info")
|
||||
if [ -z "${2:-}" ]; then
|
||||
echo "Usage: $0 info <blog_id>"
|
||||
echo "Example: $0 info 0030"
|
||||
exit 1
|
||||
fi
|
||||
show_blog_info "$2"
|
||||
;;
|
||||
"add-slug")
|
||||
if [ -z "${2:-}" ]; then
|
||||
echo "Usage: $0 add-slug <blog_id>"
|
||||
echo "Example: $0 add-slug 0030"
|
||||
exit 1
|
||||
fi
|
||||
add_slug_to_blog "$2"
|
||||
;;
|
||||
"backup")
|
||||
create_backup
|
||||
;;
|
||||
*)
|
||||
echo "Bizoni Remote Blog Management"
|
||||
echo "============================"
|
||||
echo ""
|
||||
echo "Usage: $0 <command> [options]"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " list - List all blogs on server"
|
||||
echo " migrate - Migrate all blogs to use slugs"
|
||||
echo " info <blog_id> - Show info about specific blog"
|
||||
echo " add-slug <blog_id> - Add slug to specific blog"
|
||||
echo " backup - Create backup of all blogs"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 list"
|
||||
echo " $0 migrate"
|
||||
echo " $0 info 0030"
|
||||
echo " $0 add-slug 0030"
|
||||
echo ""
|
||||
echo "⚠️ Make sure to update SERVER_BLOG_DIR path in this script!"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,448 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>Bizoni UH - Výkonný výbor</title>
|
||||
<link rel="icon" type="image/x-icon" href="img/logo.png">
|
||||
<!-- Stylesheets -->
|
||||
<link rel="stylesheet" id="swiper-css" href="css/swiper.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="bootstrap-css" href="css/bootstrap.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="atleticos-theme-style-css" href="css/bizoni.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="elementor-icons-css" href="css/elementor-icons.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="elementor-frontend-css" href="css/custom-frontend.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="elementor-post-13200-css" href="css/post-13200.css" type="text/css" media="all" />
|
||||
<!-- External Stylesheets -->
|
||||
<link rel="stylesheet" id="elementor-post-32647-css" href="css/post-32647.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="event-tickets-rsvp-css" href="css/rsvp.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="magnific-popup-css" href="css/magnific-popup.css" type="text/css" media="all" />
|
||||
<script type="text/javascript" src="js/jquery.nicescroll.js" id="nicescroll-js"></script>
|
||||
<link rel="stylesheet" id="atleticos-google-fonts-css" href="//fonts.googleapis.com/css?family=Open+Sans:400,400i,600,700%7CSofia+Sans+Extra+Condensed:800,300i" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="font-awesome-shims-css" href="css/v4-shims.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="lte-font-css" href="css/lte-font-codes.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="google-fonts-1-css" href="https://fonts.googleapis.com/css?family=Open+Sans%3A100%2C100italic%2C200%2C200italic%2C300%2C300italic%2C400%2C400italic%2C500%2C500italic%2C600%2C600italic%2C700%2C700italic%2C800%2C800italic%2C900%2C900italic%7CMarcellus%7CTangerine&display=auto&ver=6.4.5" type="text/css" media="all" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<!-- Scripts -->
|
||||
<script type="module" src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"></script>
|
||||
<script nomodule src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"></script>
|
||||
<script type="text/javascript" src="js/jquery.min.js" id="jquery-core-js"></script>
|
||||
<script type="text/javascript" src="js/jquery-migrate.min.js" id="jquery-migrate-js"></script>
|
||||
<script type="text/javascript" src="js/jquery.blockUI.min.js" id="jquery-blockui-js" defer="defer"></script>
|
||||
<script type="text/javascript" src="js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="js/script.js"></script>
|
||||
<script src="https://rybbit.tdvorak.dev/api/script.js" data-site-id="d40b7ffffffa" defer></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full">
|
||||
<div class="lte-header-wrapper header-h1 header-parallax lte-header-overlay lte-layout-transparent-full lte-pageheader-disabled">
|
||||
<div id="lte-nav-wrapper" class="lte-layout-transparent-full lte-nav-color-white">
|
||||
<nav class="lte-navbar affix" data-spy="affix" data-offset-top="0">
|
||||
<div class="container">
|
||||
<!-- Logo -->
|
||||
<div class="lte-navbar-logo">
|
||||
<a class="lte-logo" href="index.html">
|
||||
<img src="img/logo.png">
|
||||
</a>
|
||||
</div>
|
||||
<!-- Navigation Items -->
|
||||
<div class="lte-navbar-items navbar-mobile-black navbar-collapse collapse" id="navbar" data-mobile-screen-width="1198">
|
||||
<div class="toggle-wrap">
|
||||
<a class="lte-logo" href="index.html">
|
||||
<img src="img/logo.png">
|
||||
</a>
|
||||
<button type="button" class="lte-navbar-toggle collapsed" id="close-button">
|
||||
<span class="close">×</span>
|
||||
</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<!-- Navigation Menu -->
|
||||
<ul id="menu-main-menu" class="lte-ul-nav">
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="index.html">
|
||||
<span>Domů</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-29540" class="menu-item menu-item-type-post_type menu-item-object-page">
|
||||
<a href="o-nas.html">
|
||||
<span>O nás</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-59" class="menu-item menu-item-type-custom">
|
||||
<a href="blog.html">
|
||||
<span>Blog</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-13613" class="menu-item menu-item-type-post_type menu-item-object-page">
|
||||
<a href="kontakt.html">
|
||||
<span>Kontakt</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="vykonny-vybor.html">
|
||||
<span>Výkonný výbor</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="index.html#tym">
|
||||
<span>Tým</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="index.html#sponzori">
|
||||
<span>Sponzoři</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a target="_blank" href="https://eu.zonerama.com/Fcbizoni/1419417">
|
||||
<span>Fotogalerie</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Mobile Menu Toggle -->
|
||||
<button type="button" class="lte-navbar-toggle" id="open-button">
|
||||
<span class="icon-bar top-bar"></span>
|
||||
<span class="icon-bar middle-bar"></span>
|
||||
<span class="icon-bar bottom-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<header class="lte-page-header lte-parallax-yes">
|
||||
<div class="container">
|
||||
<div class="lte-header-h1-wrapper">
|
||||
<h1 class="lte-header">Výkonný výbor</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
<!-- Content -->
|
||||
<div class="lte-text-page margin-default">
|
||||
<div class="row centered">
|
||||
<div class="col-xl-12 col-xs-12">
|
||||
<article id="post-13611" class="post-13611 page type-page status-publish has-post-thumbnail hentry">
|
||||
<div class="entry-content clearfix" id="entry-div">
|
||||
<div data-elementor-type="wp-page" data-elementor-id="13611" class="elementor elementor-13611">
|
||||
<section class="elementor-section elementor-top-section elementor-element elementor-element-3724f34 elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="3724f34" data-element_type="section">
|
||||
<div class="elementor-container elementor-column-gap-no">
|
||||
<div class="elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-9b8c152" data-id="9b8c152" data-element_type="column">
|
||||
<div class="elementor-widget-wrap elementor-element-populated">
|
||||
<div class="elementor-element elementor-element-e42573f lte-contacts-icons lte-icons-align-center lte-style-grid-disabled elementor-widget elementor-widget-lte-icons" data-id="e42573f" data-element_type="widget" data-widget_type="lte-icons.default">
|
||||
<div class="elementor-widget-container">
|
||||
<ul class="lte-block-icon has-descr icons-count-5 lte-icon-space-md lte-icon-shape-default lte-icon-background-disabled lte-icon-color-main lte-icon-divider-dashed lte-icon-size-medium lte-header-color-black lte-icon-type-top lte-icon-align-center layout-cols5 lte-additional-">
|
||||
<li class=" col-lg-12 col-md-12 col-sm-12 col-ms-12 col-xs-12">
|
||||
<div class="lte-inner">
|
||||
<ion-icon name="person-outline" class="ion-icons"></ion-icon>
|
||||
<span class="lte-icon-content">
|
||||
<span class="lte-header lte-h5"> Předseda </span>
|
||||
<span class="lte-descr">Mgr. Štěpán Stodůlka<br />775 247 633</span>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li class=" col-lg-12 col-md-12 col-sm-12 col-ms-12 col-xs-12">
|
||||
<div class="lte-inner">
|
||||
<ion-icon name="person-outline" class="ion-icons"></ion-icon>
|
||||
<span class="lte-icon-content">
|
||||
<span class="lte-header lte-h5"> Místopředseda </span>
|
||||
<span class="lte-descr">David Moravec<br />602 702 129</span>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li class=" col-lg-12 col-md-12 col-sm-12 col-ms-12 col-xs-12">
|
||||
<div class="lte-inner">
|
||||
<ion-icon name="person-outline" class="ion-icons"></ion-icon>
|
||||
<span class="lte-icon-content">
|
||||
<span class="lte-header lte-h5"> Člen VV </span>
|
||||
<span class="lte-descr">Mgr. Martin Janečka<br />605 089 558</span>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li class=" col-lg-12 col-md-12 col-sm-12 col-ms-12 col-xs-12">
|
||||
<div class="lte-inner">
|
||||
<ion-icon name="person-outline" class="ion-icons"></ion-icon>
|
||||
<span class="lte-icon-content">
|
||||
<span class="lte-header lte-h5"> Člen VV </span>
|
||||
<span class="lte-descr">Mgr. Jakub Řičica<br />721 502 700</span>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li class=" col-lg-12 col-md-12 col-sm-12 col-ms-12 col-xs-12">
|
||||
<div class="lte-inner">
|
||||
<ion-icon name="person-outline" class="ion-icons"></ion-icon>
|
||||
<span class="lte-icon-content">
|
||||
<span class="lte-header lte-h5"> Člen VV </span>
|
||||
<span class="lte-descr">Jaroslav Náplava<br />603 950 224</span>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="elementor-element elementor-element-16d0b91 elementor-widget elementor-widget-spacer" data-id="16d0b91" data-element_type="widget" data-widget_type="spacer.default">
|
||||
<div class="elementor-widget-container">
|
||||
<div class="elementor-spacer">
|
||||
<div class="elementor-spacer-inner"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lte-footer-wrapper lte-footer-layout-default">
|
||||
<div class="footer-wrapper">
|
||||
<div class="lte-container">
|
||||
<div class="footer-block lte-footer-widget-area">
|
||||
<div data-elementor-type="wp-post" data-elementor-id="29393" class="elementor elementor-29393">
|
||||
<div class="elementor-element elementor-element-a939976 lte-background-black e-flex e-con-boxed e-con e-parent" data-id="a939976" data-element_type="container" data-settings="{"background_background":"classic"}" data-core-v316-plus="true">
|
||||
<div class="e-con-inner" style="padding-bottom: 92px;">
|
||||
<div class="elementor-element elementor-element-f2b730e e-con-full e-flex e-con e-child" data-id="f2b730e" data-element_type="container">
|
||||
<div class="elementor-element elementor-element-81a7a24 elementor-widget__width-initial elementor-widget elementor-widget-shortcode" data-id="81a7a24" data-element_type="widget" data-widget_type="shortcode.default">
|
||||
<div class="elementor-widget-container">
|
||||
<div class="elementor-shortcode">
|
||||
<a class="lte-logo" href="index.html">
|
||||
<img src="img/logo.png" style="filter: drop-shadow(9px -1px 23px black);">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="elementor-element elementor-element-86345d3 elementor-widget__width-initial elementor-widget elementor-widget-text-editor" data-id="86345d3" data-element_type="widget" data-widget_type="text-editor.default">
|
||||
<div class="elementor-widget-container">
|
||||
<p>
|
||||
<span class="text-sm">
|
||||
<a href="https://maps.app.goo.gl/kEc9CJuXTxqNUhgj8" target="_blank">Stonky 559, 686 01 Uherské Hradiště 1</a>
|
||||
<br>fcbizoni@gmail.com </span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="elementor-element elementor-element-475baf0 elementor-widget elementor-widget-lte-elements" data-id="475baf0" data-element_type="widget" data-widget_type="lte-elements.default">
|
||||
<div class="elementor-widget-container">
|
||||
<div class="lte-social lte-nav-second lte-type-">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://www.facebook.com/bizoniuh" target="_blank">
|
||||
<ion-icon name="logo-facebook" style="height: 22px; width: 22px;"></ion-icon>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.instagram.com/fcbizoni_uh/" target="_blank">
|
||||
<ion-icon name="logo-instagram" style="height: 22px; width: 22px;"></ion-icon>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.youtube.com/@FCBizoniUH" target="_blank">
|
||||
<ion-icon name="logo-youtube" style="height: 22px; width: 22px;"></ion-icon>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="copyright-block copyright-layout-copyright-transparent">
|
||||
<div class="container">
|
||||
<p>
|
||||
<a href="https://tdvorak.dev" target="_blank">TDvorak</a> © Všechna práva vyhrazena - 2024
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<a href="#" class="lte-go-top floating lte-go-top-icon">
|
||||
<span class="go-top-icon-v2 icon">
|
||||
<ion-icon name="football-outline" style="padding-right: 2px;"></ion-icon>
|
||||
</span>
|
||||
<span class="go-top-header">Nahoru</span>
|
||||
</a>
|
||||
<link rel='stylesheet' id='elementor-post-36123-css' href='css/post-36123.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-36124-css' href='css/post-36124.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-35532-css' href='css/post-35532.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-36129-css' href='css/post-36129.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-36131-css' href='css/post-36131.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='lte-zoomslider-css' href='css/zoom-slider.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-20251-css' href='css/post-20251.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-29393-css' href='css/post-29393.css' type='text/css' media='all' />
|
||||
<script type="text/javascript" src="js/parallax-js.js" id="parallax-js-js"></script>
|
||||
<script type="text/javascript" src="js/scripts.js" id="atleticos-scripts-js"></script>
|
||||
<script type="text/javascript" src="js/swiper.min.js" id="swiper-js"></script>
|
||||
<script type="text/javascript" src="js/frontend.js" id="lte-frontend-js"></script>
|
||||
<script type="text/javascript" src="js/jquery.zoomslider.js" id="lte-zoomslider-js"></script>
|
||||
<script type="text/javascript" src="js/webpack.runtime.min.js" id="elementor-webpack-runtime-js"></script>
|
||||
<script type="text/javascript" src="js/frontend-modules.min.js" id="elementor-frontend-modules-js"></script>
|
||||
<script type="text/javascript" src="js/waypoints.min.js" id="elementor-waypoints-js"></script>
|
||||
<script type="text/javascript" src="js/core.min.js" id="jquery-ui-core-js"></script>
|
||||
<script type="text/javascript" id="elementor-frontend-js-before">
|
||||
/*
|
||||
|
||||
<![CDATA[ */
|
||||
var elementorFrontendConfig = {
|
||||
"environmentMode": {
|
||||
"edit": false,
|
||||
"wpPreview": false,
|
||||
"isScriptDebug": false
|
||||
},
|
||||
"i18n": {
|
||||
"shareOnFacebook": "Share on Facebook",
|
||||
"shareOnTwitter": "Share on Twitter",
|
||||
"pinIt": "Pin it",
|
||||
"download": "Download",
|
||||
"downloadImage": "Download image",
|
||||
"fullscreen": "Fullscreen",
|
||||
"zoom": "Zoom",
|
||||
"share": "Share",
|
||||
"playVideo": "Play Video",
|
||||
"previous": "Previous",
|
||||
"next": "Next",
|
||||
"close": "Close",
|
||||
"a11yCarouselWrapperAriaLabel": "Carousel | Horizontal scrolling: Arrow Left & Right",
|
||||
"a11yCarouselPrevSlideMessage": "Previous slide",
|
||||
"a11yCarouselNextSlideMessage": "Next slide",
|
||||
"a11yCarouselFirstSlideMessage": "This is the first slide",
|
||||
"a11yCarouselLastSlideMessage": "This is the last slide",
|
||||
"a11yCarouselPaginationBulletMessage": "Go to slide"
|
||||
},
|
||||
"is_rtl": false,
|
||||
"breakpoints": {
|
||||
"xs": 0,
|
||||
"sm": 480,
|
||||
"md": 768,
|
||||
"lg": 1200,
|
||||
"xl": 1440,
|
||||
"xxl": 1600
|
||||
},
|
||||
"responsive": {
|
||||
"breakpoints": {
|
||||
"mobile": {
|
||||
"label": "Mobile Portrait",
|
||||
"value": 767,
|
||||
"default_value": 767,
|
||||
"direction": "max",
|
||||
"is_enabled": true
|
||||
},
|
||||
"mobile_extra": {
|
||||
"label": "Mobile Landscape",
|
||||
"value": 991,
|
||||
"default_value": 880,
|
||||
"direction": "max",
|
||||
"is_enabled": true
|
||||
},
|
||||
"tablet": {
|
||||
"label": "Tablet Portrait",
|
||||
"value": 1199,
|
||||
"default_value": 1024,
|
||||
"direction": "max",
|
||||
"is_enabled": true
|
||||
},
|
||||
"tablet_extra": {
|
||||
"label": "Tablet Landscape",
|
||||
"value": 1366,
|
||||
"default_value": 1200,
|
||||
"direction": "max",
|
||||
"is_enabled": true
|
||||
},
|
||||
"laptop": {
|
||||
"label": "Laptop",
|
||||
"value": 1599,
|
||||
"default_value": 1366,
|
||||
"direction": "max",
|
||||
"is_enabled": true
|
||||
},
|
||||
"widescreen": {
|
||||
"label": "Widescreen",
|
||||
"value": 1900,
|
||||
"default_value": 2400,
|
||||
"direction": "min",
|
||||
"is_enabled": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": "3.20.1",
|
||||
"is_static": false,
|
||||
"experimentalFeatures": {
|
||||
"e_optimized_assets_loading": true,
|
||||
"additional_custom_breakpoints": true,
|
||||
"container": true,
|
||||
"e_swiper_latest": true,
|
||||
"block_editor_assets_optimize": true,
|
||||
"ai-layout": true,
|
||||
"landing-pages": true,
|
||||
"nested-elements": true,
|
||||
"e_image_loading_optimization": true
|
||||
},
|
||||
"urls": {
|
||||
"assets": "./js/text-editor.2c35aafbe5bf0e127950.bundle.min.js"
|
||||
},
|
||||
"swiperClass": "swiper",
|
||||
"settings": {
|
||||
"page": [],
|
||||
"editorPreferences": []
|
||||
},
|
||||
"kit": {
|
||||
"viewport_tablet": 1199,
|
||||
"viewport_mobile": 767,
|
||||
"active_breakpoints": ["viewport_mobile", "viewport_mobile_extra", "viewport_tablet", "viewport_tablet_extra", "viewport_laptop", "viewport_widescreen"],
|
||||
"viewport_mobile_extra": 991,
|
||||
"viewport_laptop": 1599,
|
||||
"viewport_widescreen": 1900,
|
||||
"viewport_tablet_extra": 1366,
|
||||
"lightbox_enable_counter": "yes",
|
||||
"lightbox_enable_fullscreen": "yes",
|
||||
"lightbox_enable_zoom": "yes",
|
||||
"lightbox_enable_share": "yes",
|
||||
"lightbox_title_src": "title",
|
||||
"lightbox_description_src": "description"
|
||||
},
|
||||
"post": {
|
||||
"id": 32647,
|
||||
"title": "",
|
||||
"excerpt": "",
|
||||
"featuredImage": false
|
||||
}
|
||||
};
|
||||
/* ]]> */
|
||||
</script>
|
||||
<script type="text/javascript" src="js/frontend.min.js" id="elementor-frontend-js"></script>
|
||||
<script>
|
||||
// Ensure the DOM is fully loaded before adding event listeners
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Get the buttons and the navbar element
|
||||
const openButton = document.getElementById('open-button');
|
||||
const closeButton = document.getElementById('close-button');
|
||||
const navbar = document.getElementById('navbar');
|
||||
// Log to check if elements exist
|
||||
console.log('Open button:', openButton);
|
||||
console.log('Close button:', closeButton);
|
||||
console.log('Navbar:', navbar);
|
||||
// Ensure that buttons and navbar exist
|
||||
if (openButton && closeButton && navbar) {
|
||||
console.log('Elements found and event listeners ready.');
|
||||
// Add event listener to the open button
|
||||
openButton.addEventListener('click', function() {
|
||||
console.log('Open button clicked');
|
||||
});
|
||||
// Add event listener to the close button
|
||||
closeButton.addEventListener('click', function() {
|
||||
console.log('Close button clicked');
|
||||
});
|
||||
} else {
|
||||
console.error('Error: Buttons or navbar element not found.');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
+369
-369
@@ -1,370 +1,370 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>Bizoni UH - Zápasy</title>
|
||||
<link rel="icon" type="image/x-icon" href="../img/logo.png">
|
||||
<!-- Stylesheets -->
|
||||
<link rel="stylesheet" id="swiper-css" href="../css/swiper.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="bootstrap-css" href="../css/bootstrap.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="atleticos-theme-style-css" href="../css/bizoni.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="elementor-icons-css" href="../css/elementor-icons.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="elementor-frontend-css" href="../css/custom-frontend.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="elementor-post-13200-css" href="../css/post-13200.css" type="text/css" media="all" />
|
||||
<!-- External Stylesheets -->
|
||||
<link rel="stylesheet" id="elementor-post-32647-css" href="../css/post-32647.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="event-tickets-rsvp-css" href="../css/rsvp.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="magnific-popup-css" href="../css/magnific-popup.css" type="text/css" media="all" />
|
||||
<script type="text/javascript" src="../js/jquery.nicescroll.js" id="nicescroll-js"></script>
|
||||
<link rel="stylesheet" id="atleticos-google-fonts-css" href="//fonts.googleapis.com/css?family=Open+Sans:400,400i,600,700%7CSofia+Sans+Extra+Condensed:800,300i" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="font-awesome-shims-css" href="../css/v4-shims.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="lte-font-css" href="../css/lte-font-codes.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="google-fonts-1-css" href="https://fonts.googleapis.com/css?family=Open+Sans%3A100%2C100italic%2C200%2C200italic%2C300%2C300italic%2C400%2C400italic%2C500%2C500italic%2C600%2C600italic%2C700%2C700italic%2C800%2C800italic%2C900%2C900italic%7CMarcellus%7CTangerine&display=auto&ver=6.4.5" type="text/css" media="all" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<!-- Scripts -->
|
||||
<script type="module" src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"></script>
|
||||
<script nomodule src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"></script>
|
||||
<script type="text/javascript" src="../js/jquery.min.js" id="jquery-core-js"></script>
|
||||
<script type="text/javascript" src="../js/jquery-migrate.min.js" id="jquery-migrate-js"></script>
|
||||
<script type="text/javascript" src="../js/jquery.blockUI.min.js" id="jquery-blockui-js" defer="defer"></script>
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full">
|
||||
<div class="lte-header-wrapper header-h1 header-parallax lte-header-overlay lte-layout-transparent-full lte-pageheader-disabled">
|
||||
<div id="lte-nav-wrapper" class="lte-layout-transparent-full lte-nav-color-white">
|
||||
<nav class="lte-navbar affix" data-spy="affix" data-offset-top="0">
|
||||
<div class="container">
|
||||
<!-- Logo -->
|
||||
<div class="lte-navbar-logo">
|
||||
<a class="lte-logo" href="../index.html">
|
||||
<img src="../img/logo.png">
|
||||
</a>
|
||||
</div>
|
||||
<!-- Navigation Items -->
|
||||
<div class="lte-navbar-items navbar-mobile-black navbar-collapse collapse" id="navbar" data-mobile-screen-width="1198">
|
||||
<div class="toggle-wrap">
|
||||
<a class="lte-logo" href="../index.html">
|
||||
<img src="../img/logo.png">
|
||||
</a>
|
||||
<button type="button" class="lte-navbar-toggle collapsed" id="close-button">
|
||||
<span class="close">×</span>
|
||||
</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<!-- Navigation Menu -->
|
||||
<ul id="menu-main-menu" class="lte-ul-nav">
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="../index.html">
|
||||
<span>Domů</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-29540" class="menu-item menu-item-type-post_type menu-item-object-page">
|
||||
<a href="../o-nas.html">
|
||||
<span>O nás</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-59" class="menu-item menu-item-type-custom">
|
||||
<a href="../blog.html">
|
||||
<span>Blog</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-13613" class="menu-item menu-item-type-post_type menu-item-object-page">
|
||||
<a href="../kontakt.html">
|
||||
<span>Kontakt</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="../index.html#tym">
|
||||
<span>Tým</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="../index.html#sponzori">
|
||||
<span>Sponzoři</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a target="_blank" href="https://eu.zonerama.com/Fcbizoni/1419417">
|
||||
<span>Fotogalerie</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Mobile Menu Toggle -->
|
||||
<button type="button" class="lte-navbar-toggle" id="open-button">
|
||||
<span class="icon-bar top-bar"></span>
|
||||
<span class="icon-bar middle-bar"></span>
|
||||
<span class="icon-bar bottom-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
<header class="lte-page-header lte-parallax-yes">
|
||||
<div class="container">
|
||||
<div class="lte-header-h1-wrapper">
|
||||
<h1 class="lte-header">Všechny zápasy</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
<div class="container main-wrapper">
|
||||
<div class="inner-page margin-default">
|
||||
<div id="facr-all-matches" class="lte-football-matches inner-page"></div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lte-footer-wrapper lte-footer-layout-default">
|
||||
<div class="footer-wrapper">
|
||||
<div class="lte-container">
|
||||
<div class="footer-block lte-footer-widget-area">
|
||||
<div data-elementor-type="wp-post" data-elementor-id="29393" class="elementor elementor-29393">
|
||||
<div class="elementor-element elementor-element-a939976 lte-background-black e-flex e-con-boxed e-con e-parent" data-id="a939976" data-element_type="container" data-settings="{"background_background":"classic"}" data-core-v316-plus="true">
|
||||
<div class="e-con-inner" style="padding-bottom: 92px;">
|
||||
<div class="elementor-element elementor-element-f2b730e e-con-full e-flex e-con e-child" data-id="f2b730e" data-element_type="container">
|
||||
<div class="elementor-element elementor-element-81a7a24 elementor-widget__width-initial elementor-widget elementor-widget-shortcode" data-id="81a7a24" data-element_type="widget" data-widget_type="shortcode.default">
|
||||
<div class="elementor-widget-container">
|
||||
<div class="elementor-shortcode">
|
||||
<a class="lte-logo" href="../index.html">
|
||||
<img src="../img/logo.png" style="filter: drop-shadow(9px -1px 23px black);">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="elementor-element elementor-element-86345d3 elementor-widget__width-initial elementor-widget elementor-widget-text-editor" data-id="86345d3" data-element_type="widget" data-widget_type="text-editor.default">
|
||||
<div class="elementor-widget-container">
|
||||
<p>
|
||||
<span class="text-sm">
|
||||
<a href="https://maps.app.goo.gl/kEc9CJuXTxqNUhgj8" target="_blank">Stonky 559, 686 01 Uherské Hradiště 1</a>
|
||||
<br>fcbizoni@gmail.com </span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="elementor-element elementor-element-475baf0 elementor-widget elementor-widget-lte-elements" data-id="475baf0" data-element_type="widget" data-widget_type="lte-elements.default">
|
||||
<div class="elementor-widget-container">
|
||||
<div class="lte-social lte-nav-second lte-type-">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://www.facebook.com/bizoniuh" target="_blank">
|
||||
<ion-icon name="logo-facebook" style="height: 22px; width: 22px;"></ion-icon>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.instagram.com/fcbizoni_uh/" target="_blank">
|
||||
<ion-icon name="logo-instagram" style="height: 22px; width: 22px;"></ion-icon>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.youtube.com/@FCBizoniUH" target="_blank">
|
||||
<ion-icon name="logo-youtube" style="height: 22px; width: 22px;"></ion-icon>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="copyright-block copyright-layout-copyright-transparent">
|
||||
<div class="container">
|
||||
<p>
|
||||
<a href="https://tdvorak.dev" target="_blank">TDvorak</a> © Všechna práva vyhrazena - 2024
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<a href="#" class="lte-go-top floating lte-go-top-icon">
|
||||
<span class="go-top-icon-v2 icon">
|
||||
<ion-icon name="football-outline" style="padding-right: 2px;"></ion-icon>
|
||||
</span>
|
||||
<span class="go-top-header">Nahoru</span>
|
||||
</a>
|
||||
<script src="../js/facr-frontend.js"></script>
|
||||
<link rel='stylesheet' id='elementor-post-36123-css' href='../css/post-36123.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-36124-css' href='../css/post-36124.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-35532-css' href='../css/post-35532.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-36129-css' href='../css/post-36129.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-36131-css' href='../css/post-36131.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='lte-zoomslider-css' href='../css/zoom-slider.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-20251-css' href='../css/post-20251.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-29393-css' href='../css/post-29393.css' type='text/css' media='all' />
|
||||
<script type="text/javascript" src="../js/parallax-js.js" id="parallax-js-js"></script>
|
||||
<script type="text/javascript" src="../js/scripts.js" id="atleticos-scripts-js"></script>
|
||||
<script type="text/javascript" src="../js/swiper.min.js" id="swiper-js"></script>
|
||||
<script type="text/javascript" src="../js/frontend.js" id="lte-frontend-js"></script>
|
||||
<script type="text/javascript" src="../js/jquery.zoomslider.js" id="lte-zoomslider-js"></script>
|
||||
<script type="text/javascript" src="../js/webpack.runtime.min.js" id="elementor-webpack-runtime-js"></script>
|
||||
<script type="text/javascript" src="../js/frontend-modules.min.js" id="elementor-frontend-modules-js"></script>
|
||||
<script type="text/javascript" src="../js/waypoints.min.js" id="elementor-waypoints-js"></script>
|
||||
<script type="text/javascript" src="../js/core.min.js" id="jquery-ui-core-js"></script>
|
||||
<script type="text/javascript" id="elementor-frontend-js-before">
|
||||
/*
|
||||
|
||||
|
||||
<![CDATA[ */
|
||||
var elementorFrontendConfig = {
|
||||
"environmentMode": {
|
||||
"edit": false,
|
||||
"wpPreview": false,
|
||||
"isScriptDebug": false
|
||||
},
|
||||
"i18n": {
|
||||
"shareOnFacebook": "Share on Facebook",
|
||||
"shareOnTwitter": "Share on Twitter",
|
||||
"pinIt": "Pin it",
|
||||
"download": "Download",
|
||||
"downloadImage": "Download image",
|
||||
"fullscreen": "Fullscreen",
|
||||
"zoom": "Zoom",
|
||||
"share": "Share",
|
||||
"playVideo": "Play Video",
|
||||
"previous": "Previous",
|
||||
"next": "Next",
|
||||
"close": "Close",
|
||||
"a11yCarouselWrapperAriaLabel": "Carousel | Horizontal scrolling: Arrow Left & Right",
|
||||
"a11yCarouselPrevSlideMessage": "Previous slide",
|
||||
"a11yCarouselNextSlideMessage": "Next slide",
|
||||
"a11yCarouselFirstSlideMessage": "This is the first slide",
|
||||
"a11yCarouselLastSlideMessage": "This is the last slide",
|
||||
"a11yCarouselPaginationBulletMessage": "Go to slide"
|
||||
},
|
||||
"is_rtl": false,
|
||||
"breakpoints": {
|
||||
"xs": 0,
|
||||
"sm": 480,
|
||||
"md": 768,
|
||||
"lg": 1200,
|
||||
"xl": 1440,
|
||||
"xxl": 1600
|
||||
},
|
||||
"responsive": {
|
||||
"breakpoints": {
|
||||
"mobile": {
|
||||
"label": "Mobile Portrait",
|
||||
"value": 767,
|
||||
"default_value": 767,
|
||||
"direction": "max",
|
||||
"is_enabled": true
|
||||
},
|
||||
"mobile_extra": {
|
||||
"label": "Mobile Landscape",
|
||||
"value": 991,
|
||||
"default_value": 880,
|
||||
"direction": "max",
|
||||
"is_enabled": true
|
||||
},
|
||||
"tablet": {
|
||||
"label": "Tablet Portrait",
|
||||
"value": 1199,
|
||||
"default_value": 1024,
|
||||
"direction": "max",
|
||||
"is_enabled": true
|
||||
},
|
||||
"tablet_extra": {
|
||||
"label": "Tablet Landscape",
|
||||
"value": 1366,
|
||||
"default_value": 1200,
|
||||
"direction": "max",
|
||||
"is_enabled": true
|
||||
},
|
||||
"laptop": {
|
||||
"label": "Laptop",
|
||||
"value": 1599,
|
||||
"default_value": 1366,
|
||||
"direction": "max",
|
||||
"is_enabled": true
|
||||
},
|
||||
"widescreen": {
|
||||
"label": "Widescreen",
|
||||
"value": 1900,
|
||||
"default_value": 2400,
|
||||
"direction": "min",
|
||||
"is_enabled": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": "3.20.1",
|
||||
"is_static": false,
|
||||
"experimentalFeatures": {
|
||||
"e_optimized_assets_loading": true,
|
||||
"additional_custom_breakpoints": true,
|
||||
"container": true,
|
||||
"e_swiper_latest": true,
|
||||
"block_editor_assets_optimize": true,
|
||||
"ai-layout": true,
|
||||
"landing-pages": true,
|
||||
"nested-elements": true,
|
||||
"e_image_loading_optimization": true
|
||||
},
|
||||
"urls": {
|
||||
"assets": ".../js/text-editor.2c35aafbe5bf0e127950.bundle.min.js"
|
||||
},
|
||||
"swiperClass": "swiper",
|
||||
"settings": {
|
||||
"page": [],
|
||||
"editorPreferences": []
|
||||
},
|
||||
"kit": {
|
||||
"viewport_tablet": 1199,
|
||||
"viewport_mobile": 767,
|
||||
"active_breakpoints": ["viewport_mobile", "viewport_mobile_extra", "viewport_tablet", "viewport_tablet_extra", "viewport_laptop", "viewport_widescreen"],
|
||||
"viewport_mobile_extra": 991,
|
||||
"viewport_laptop": 1599,
|
||||
"viewport_widescreen": 1900,
|
||||
"viewport_tablet_extra": 1366,
|
||||
"lightbox_enable_counter": "yes",
|
||||
"lightbox_enable_fullscreen": "yes",
|
||||
"lightbox_enable_zoom": "yes",
|
||||
"lightbox_enable_share": "yes",
|
||||
"lightbox_title_src": "title",
|
||||
"lightbox_description_src": "description"
|
||||
},
|
||||
"post": {
|
||||
"id": 32647,
|
||||
"title": "",
|
||||
"excerpt": "",
|
||||
"featuredImage": false
|
||||
}
|
||||
};
|
||||
/* ]]> */
|
||||
</script>
|
||||
<script type="text/javascript" src="../js/frontend.min.js" id="elementor-frontend-js"></script>
|
||||
<script>
|
||||
// Ensure the DOM is fully loaded before adding event listeners
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Get the buttons and the navbar element
|
||||
const openButton = document.getElementById('open-button');
|
||||
const closeButton = document.getElementById('close-button');
|
||||
const navbar = document.getElementById('navbar');
|
||||
// Log to check if elements exist
|
||||
console.log('Open button:', openButton);
|
||||
console.log('Close button:', closeButton);
|
||||
console.log('Navbar:', navbar);
|
||||
// Ensure that buttons and navbar exist
|
||||
if (openButton && closeButton && navbar) {
|
||||
console.log('Elements found and event listeners ready.');
|
||||
// Add event listener to the open button
|
||||
openButton.addEventListener('click', function() {
|
||||
console.log('Open button clicked');
|
||||
});
|
||||
// Add event listener to the close button
|
||||
closeButton.addEventListener('click', function() {
|
||||
console.log('Close button clicked');
|
||||
});
|
||||
} else {
|
||||
console.error('Error: Buttons or navbar element not found.');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>Bizoni UH - Zápasy</title>
|
||||
<link rel="icon" type="image/x-icon" href="../img/logo.png">
|
||||
<!-- Stylesheets -->
|
||||
<link rel="stylesheet" id="swiper-css" href="../css/swiper.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="bootstrap-css" href="../css/bootstrap.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="atleticos-theme-style-css" href="../css/bizoni.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="elementor-icons-css" href="../css/elementor-icons.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="elementor-frontend-css" href="../css/custom-frontend.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="elementor-post-13200-css" href="../css/post-13200.css" type="text/css" media="all" />
|
||||
<!-- External Stylesheets -->
|
||||
<link rel="stylesheet" id="elementor-post-32647-css" href="../css/post-32647.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="event-tickets-rsvp-css" href="../css/rsvp.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="magnific-popup-css" href="../css/magnific-popup.css" type="text/css" media="all" />
|
||||
<script type="text/javascript" src="../js/jquery.nicescroll.js" id="nicescroll-js"></script>
|
||||
<link rel="stylesheet" id="atleticos-google-fonts-css" href="//fonts.googleapis.com/css?family=Open+Sans:400,400i,600,700%7CSofia+Sans+Extra+Condensed:800,300i" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="font-awesome-shims-css" href="../css/v4-shims.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="lte-font-css" href="../css/lte-font-codes.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" id="google-fonts-1-css" href="https://fonts.googleapis.com/css?family=Open+Sans%3A100%2C100italic%2C200%2C200italic%2C300%2C300italic%2C400%2C400italic%2C500%2C500italic%2C600%2C600italic%2C700%2C700italic%2C800%2C800italic%2C900%2C900italic%7CMarcellus%7CTangerine&display=auto&ver=6.4.5" type="text/css" media="all" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<!-- Scripts -->
|
||||
<script type="module" src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"></script>
|
||||
<script nomodule src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"></script>
|
||||
<script type="text/javascript" src="../js/jquery.min.js" id="jquery-core-js"></script>
|
||||
<script type="text/javascript" src="../js/jquery-migrate.min.js" id="jquery-migrate-js"></script>
|
||||
<script type="text/javascript" src="../js/jquery.blockUI.min.js" id="jquery-blockui-js" defer="defer"></script>
|
||||
<script type="text/javascript" src="../js/jquery.paroller.js" id="jquery-paroller-js"></script>
|
||||
<script type="text/javascript" src="../js/modernizr-2.6.2.min.js" id="modernizr-js"></script>
|
||||
<script type="text/javascript" src="../js/script.js"></script>
|
||||
</head>
|
||||
<body class="home page-template page-template-page-templates page-template-full-width page page-id-32647 theme-atleticos woocommerce-no-js tribe-no-js tec-no-tickets-on-recurring tec-no-rsvp-on-recurring full-width lte-fw-loaded lte-color-scheme-default lte-body-white lte-background-white paceloader-disabled no-sidebar elementor-default elementor-kit-13200 elementor-page elementor-page-32647 tribe-theme-atleticos">
|
||||
<div class="lte-content-wrapper lte-layout-transparent-full">
|
||||
<div class="lte-header-wrapper header-h1 header-parallax lte-header-overlay lte-layout-transparent-full lte-pageheader-disabled">
|
||||
<div id="lte-nav-wrapper" class="lte-layout-transparent-full lte-nav-color-white">
|
||||
<nav class="lte-navbar affix" data-spy="affix" data-offset-top="0">
|
||||
<div class="container">
|
||||
<!-- Logo -->
|
||||
<div class="lte-navbar-logo">
|
||||
<a class="lte-logo" href="../index.html">
|
||||
<img src="../img/logo.png">
|
||||
</a>
|
||||
</div>
|
||||
<!-- Navigation Items -->
|
||||
<div class="lte-navbar-items navbar-mobile-black navbar-collapse collapse" id="navbar" data-mobile-screen-width="1198">
|
||||
<div class="toggle-wrap">
|
||||
<a class="lte-logo" href="../index.html">
|
||||
<img src="../img/logo.png">
|
||||
</a>
|
||||
<button type="button" class="lte-navbar-toggle collapsed" id="close-button">
|
||||
<span class="close">×</span>
|
||||
</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<!-- Navigation Menu -->
|
||||
<ul id="menu-main-menu" class="lte-ul-nav">
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="../index.html">
|
||||
<span>Domů</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-29540" class="menu-item menu-item-type-post_type menu-item-object-page">
|
||||
<a href="../o-nas.html">
|
||||
<span>O nás</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-59" class="menu-item menu-item-type-custom">
|
||||
<a href="../blog.html">
|
||||
<span>Blog</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-13613" class="menu-item menu-item-type-post_type menu-item-object-page">
|
||||
<a href="../kontakt.html">
|
||||
<span>Kontakt</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="../index.html#tym">
|
||||
<span>Tým</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a href="../index.html#sponzori">
|
||||
<span>Sponzoři</span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="menu-item-20758" class="menu-item menu-item-type-custom current-menu-ancestor current-menu-parent">
|
||||
<a target="_blank" href="https://eu.zonerama.com/Fcbizoni/1419417">
|
||||
<span>Fotogalerie</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Mobile Menu Toggle -->
|
||||
<button type="button" class="lte-navbar-toggle" id="open-button">
|
||||
<span class="icon-bar top-bar"></span>
|
||||
<span class="icon-bar middle-bar"></span>
|
||||
<span class="icon-bar bottom-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
<header class="lte-page-header lte-parallax-yes">
|
||||
<div class="container">
|
||||
<div class="lte-header-h1-wrapper">
|
||||
<h1 class="lte-header">Všechny zápasy</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
<div class="container main-wrapper">
|
||||
<div class="inner-page margin-default">
|
||||
<div id="facr-all-matches" class="lte-football-matches inner-page"></div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lte-footer-wrapper lte-footer-layout-default">
|
||||
<div class="footer-wrapper">
|
||||
<div class="lte-container">
|
||||
<div class="footer-block lte-footer-widget-area">
|
||||
<div data-elementor-type="wp-post" data-elementor-id="29393" class="elementor elementor-29393">
|
||||
<div class="elementor-element elementor-element-a939976 lte-background-black e-flex e-con-boxed e-con e-parent" data-id="a939976" data-element_type="container" data-settings="{"background_background":"classic"}" data-core-v316-plus="true">
|
||||
<div class="e-con-inner" style="padding-bottom: 92px;">
|
||||
<div class="elementor-element elementor-element-f2b730e e-con-full e-flex e-con e-child" data-id="f2b730e" data-element_type="container">
|
||||
<div class="elementor-element elementor-element-81a7a24 elementor-widget__width-initial elementor-widget elementor-widget-shortcode" data-id="81a7a24" data-element_type="widget" data-widget_type="shortcode.default">
|
||||
<div class="elementor-widget-container">
|
||||
<div class="elementor-shortcode">
|
||||
<a class="lte-logo" href="../index.html">
|
||||
<img src="../img/logo.png" style="filter: drop-shadow(9px -1px 23px black);">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="elementor-element elementor-element-86345d3 elementor-widget__width-initial elementor-widget elementor-widget-text-editor" data-id="86345d3" data-element_type="widget" data-widget_type="text-editor.default">
|
||||
<div class="elementor-widget-container">
|
||||
<p>
|
||||
<span class="text-sm">
|
||||
<a href="https://maps.app.goo.gl/kEc9CJuXTxqNUhgj8" target="_blank">Stonky 559, 686 01 Uherské Hradiště 1</a>
|
||||
<br>fcbizoni@gmail.com </span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="elementor-element elementor-element-475baf0 elementor-widget elementor-widget-lte-elements" data-id="475baf0" data-element_type="widget" data-widget_type="lte-elements.default">
|
||||
<div class="elementor-widget-container">
|
||||
<div class="lte-social lte-nav-second lte-type-">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://www.facebook.com/bizoniuh" target="_blank">
|
||||
<ion-icon name="logo-facebook" style="height: 22px; width: 22px;"></ion-icon>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.instagram.com/fcbizoni_uh/" target="_blank">
|
||||
<ion-icon name="logo-instagram" style="height: 22px; width: 22px;"></ion-icon>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.youtube.com/@FCBizoniUH" target="_blank">
|
||||
<ion-icon name="logo-youtube" style="height: 22px; width: 22px;"></ion-icon>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="copyright-block copyright-layout-copyright-transparent">
|
||||
<div class="container">
|
||||
<p>
|
||||
<a href="https://tdvorak.dev" target="_blank">TDvorak</a> © Všechna práva vyhrazena - 2024
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<a href="#" class="lte-go-top floating lte-go-top-icon">
|
||||
<span class="go-top-icon-v2 icon">
|
||||
<ion-icon name="football-outline" style="padding-right: 2px;"></ion-icon>
|
||||
</span>
|
||||
<span class="go-top-header">Nahoru</span>
|
||||
</a>
|
||||
<script src="../js/facr-frontend.js"></script>
|
||||
<link rel='stylesheet' id='elementor-post-36123-css' href='../css/post-36123.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-36124-css' href='../css/post-36124.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-35532-css' href='../css/post-35532.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-36129-css' href='../css/post-36129.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-36131-css' href='../css/post-36131.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='lte-zoomslider-css' href='../css/zoom-slider.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-20251-css' href='../css/post-20251.css' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='elementor-post-29393-css' href='../css/post-29393.css' type='text/css' media='all' />
|
||||
<script type="text/javascript" src="../js/parallax-js.js" id="parallax-js-js"></script>
|
||||
<script type="text/javascript" src="../js/scripts.js" id="atleticos-scripts-js"></script>
|
||||
<script type="text/javascript" src="../js/swiper.min.js" id="swiper-js"></script>
|
||||
<script type="text/javascript" src="../js/frontend.js" id="lte-frontend-js"></script>
|
||||
<script type="text/javascript" src="../js/jquery.zoomslider.js" id="lte-zoomslider-js"></script>
|
||||
<script type="text/javascript" src="../js/webpack.runtime.min.js" id="elementor-webpack-runtime-js"></script>
|
||||
<script type="text/javascript" src="../js/frontend-modules.min.js" id="elementor-frontend-modules-js"></script>
|
||||
<script type="text/javascript" src="../js/waypoints.min.js" id="elementor-waypoints-js"></script>
|
||||
<script type="text/javascript" src="../js/core.min.js" id="jquery-ui-core-js"></script>
|
||||
<script type="text/javascript" id="elementor-frontend-js-before">
|
||||
/*
|
||||
|
||||
|
||||
<![CDATA[ */
|
||||
var elementorFrontendConfig = {
|
||||
"environmentMode": {
|
||||
"edit": false,
|
||||
"wpPreview": false,
|
||||
"isScriptDebug": false
|
||||
},
|
||||
"i18n": {
|
||||
"shareOnFacebook": "Share on Facebook",
|
||||
"shareOnTwitter": "Share on Twitter",
|
||||
"pinIt": "Pin it",
|
||||
"download": "Download",
|
||||
"downloadImage": "Download image",
|
||||
"fullscreen": "Fullscreen",
|
||||
"zoom": "Zoom",
|
||||
"share": "Share",
|
||||
"playVideo": "Play Video",
|
||||
"previous": "Previous",
|
||||
"next": "Next",
|
||||
"close": "Close",
|
||||
"a11yCarouselWrapperAriaLabel": "Carousel | Horizontal scrolling: Arrow Left & Right",
|
||||
"a11yCarouselPrevSlideMessage": "Previous slide",
|
||||
"a11yCarouselNextSlideMessage": "Next slide",
|
||||
"a11yCarouselFirstSlideMessage": "This is the first slide",
|
||||
"a11yCarouselLastSlideMessage": "This is the last slide",
|
||||
"a11yCarouselPaginationBulletMessage": "Go to slide"
|
||||
},
|
||||
"is_rtl": false,
|
||||
"breakpoints": {
|
||||
"xs": 0,
|
||||
"sm": 480,
|
||||
"md": 768,
|
||||
"lg": 1200,
|
||||
"xl": 1440,
|
||||
"xxl": 1600
|
||||
},
|
||||
"responsive": {
|
||||
"breakpoints": {
|
||||
"mobile": {
|
||||
"label": "Mobile Portrait",
|
||||
"value": 767,
|
||||
"default_value": 767,
|
||||
"direction": "max",
|
||||
"is_enabled": true
|
||||
},
|
||||
"mobile_extra": {
|
||||
"label": "Mobile Landscape",
|
||||
"value": 991,
|
||||
"default_value": 880,
|
||||
"direction": "max",
|
||||
"is_enabled": true
|
||||
},
|
||||
"tablet": {
|
||||
"label": "Tablet Portrait",
|
||||
"value": 1199,
|
||||
"default_value": 1024,
|
||||
"direction": "max",
|
||||
"is_enabled": true
|
||||
},
|
||||
"tablet_extra": {
|
||||
"label": "Tablet Landscape",
|
||||
"value": 1366,
|
||||
"default_value": 1200,
|
||||
"direction": "max",
|
||||
"is_enabled": true
|
||||
},
|
||||
"laptop": {
|
||||
"label": "Laptop",
|
||||
"value": 1599,
|
||||
"default_value": 1366,
|
||||
"direction": "max",
|
||||
"is_enabled": true
|
||||
},
|
||||
"widescreen": {
|
||||
"label": "Widescreen",
|
||||
"value": 1900,
|
||||
"default_value": 2400,
|
||||
"direction": "min",
|
||||
"is_enabled": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": "3.20.1",
|
||||
"is_static": false,
|
||||
"experimentalFeatures": {
|
||||
"e_optimized_assets_loading": true,
|
||||
"additional_custom_breakpoints": true,
|
||||
"container": true,
|
||||
"e_swiper_latest": true,
|
||||
"block_editor_assets_optimize": true,
|
||||
"ai-layout": true,
|
||||
"landing-pages": true,
|
||||
"nested-elements": true,
|
||||
"e_image_loading_optimization": true
|
||||
},
|
||||
"urls": {
|
||||
"assets": ".../js/text-editor.2c35aafbe5bf0e127950.bundle.min.js"
|
||||
},
|
||||
"swiperClass": "swiper",
|
||||
"settings": {
|
||||
"page": [],
|
||||
"editorPreferences": []
|
||||
},
|
||||
"kit": {
|
||||
"viewport_tablet": 1199,
|
||||
"viewport_mobile": 767,
|
||||
"active_breakpoints": ["viewport_mobile", "viewport_mobile_extra", "viewport_tablet", "viewport_tablet_extra", "viewport_laptop", "viewport_widescreen"],
|
||||
"viewport_mobile_extra": 991,
|
||||
"viewport_laptop": 1599,
|
||||
"viewport_widescreen": 1900,
|
||||
"viewport_tablet_extra": 1366,
|
||||
"lightbox_enable_counter": "yes",
|
||||
"lightbox_enable_fullscreen": "yes",
|
||||
"lightbox_enable_zoom": "yes",
|
||||
"lightbox_enable_share": "yes",
|
||||
"lightbox_title_src": "title",
|
||||
"lightbox_description_src": "description"
|
||||
},
|
||||
"post": {
|
||||
"id": 32647,
|
||||
"title": "",
|
||||
"excerpt": "",
|
||||
"featuredImage": false
|
||||
}
|
||||
};
|
||||
/* ]]> */
|
||||
</script>
|
||||
<script type="text/javascript" src="../js/frontend.min.js" id="elementor-frontend-js"></script>
|
||||
<script>
|
||||
// Ensure the DOM is fully loaded before adding event listeners
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Get the buttons and the navbar element
|
||||
const openButton = document.getElementById('open-button');
|
||||
const closeButton = document.getElementById('close-button');
|
||||
const navbar = document.getElementById('navbar');
|
||||
// Log to check if elements exist
|
||||
console.log('Open button:', openButton);
|
||||
console.log('Close button:', closeButton);
|
||||
console.log('Navbar:', navbar);
|
||||
// Ensure that buttons and navbar exist
|
||||
if (openButton && closeButton && navbar) {
|
||||
console.log('Elements found and event listeners ready.');
|
||||
// Add event listener to the open button
|
||||
openButton.addEventListener('click', function() {
|
||||
console.log('Open button clicked');
|
||||
});
|
||||
// Add event listener to the close button
|
||||
closeButton.addEventListener('click', function() {
|
||||
console.log('Close button clicked');
|
||||
});
|
||||
} else {
|
||||
console.error('Error: Buttons or navbar element not found.');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user