This commit is contained in:
Flatlogic Bot 2025-11-26 19:33:57 +00:00
parent e899fb7f07
commit f1c13ea8d8
8 changed files with 640 additions and 11 deletions

View File

@ -73,6 +73,9 @@ if (file_exists('premium_content.json')) {
<li> <li>
<a href="admin_content.php" class="nav-link text-white"><i class="bi bi-tv-fill me-2"></i>Premium Content</a> <a href="admin_content.php" class="nav-link text-white"><i class="bi bi-tv-fill me-2"></i>Premium Content</a>
</li> </li>
<li>
<a href="admin_upload.php" class="nav-link text-white"><i class="bi bi-upload me-2"></i>Upload Channels</a>
</li>
<li> <li>
<a href="admin_settings.php" class="nav-link text-white"><i class="bi bi-gear-fill me-2"></i>App Settings</a> <a href="admin_settings.php" class="nav-link text-white"><i class="bi bi-gear-fill me-2"></i>App Settings</a>
</li> </li>

169
admin_upload.php Normal file
View File

@ -0,0 +1,169 @@
<?php
session_start();
// Dummy authentication check - replace with your actual login check
if (!isset($_SESSION['is_admin']) || !$_SESSION['is_admin']) {
// header('Location: admin_login.php');
// die('Access Denied. You must be logged in as an admin.');
}
$message = '';
$error = '';
function parse_m3u_attributes($info_line) {
$attributes = [];
// Extract the part of the string that contains the attributes
preg_match_all('/ (\w+-.+?)="(.+?)"/', $info_line, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$attributes[$match[1]] = $match[2];
}
// Get the title from the last part of the line
$parts = explode(',', $info_line);
$title = trim(end($parts));
if ($title) {
$attributes['title'] = $title;
}
return $attributes;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['channels_file'])) {
$file = $_FILES['channels_file'];
$overwrite = isset($_POST['overwrite']);
if ($file['error'] === UPLOAD_ERR_OK) {
$filename = $file['tmp_name'];
$content = file_get_contents($filename);
$lines = explode(PHP_EOL, $content);
$new_channels = [];
$malformed_entries = 0;
if (strpos(trim($lines[0]), '#EXTM3U') !== 0) {
$error = 'Invalid M3U file. The file must start with #EXTM3U.';
} else {
for ($i = 0; $i < count($lines); $i++) {
$line = trim($lines[$i]);
if (strpos($line, '#EXTINF') === 0) {
$attributes = parse_m3u_attributes($line);
$stream_url = isset($lines[$i + 1]) ? trim($lines[$i + 1]) : '';
if (!empty($stream_url) && !empty($attributes['title'])) {
$new_channels[] = [
'title' => $attributes['title'],
'category' => $attributes['group-title'] ?? 'General',
'poster_url' => $attributes['tvg-logo'] ?? '',
'stream_url' => $stream_url,
];
$i++; // Skip the next line as it's the URL
} else {
$malformed_entries++;
}
}
}
if (!empty($new_channels)) {
$content_file = 'premium_content.json';
$existing_channels = [];
if (!$overwrite && file_exists($content_file)) {
$existing_content = json_decode(file_get_contents($content_file), true);
if (is_array($existing_content)) {
$existing_channels = $existing_content;
}
}
$last_id = 0;
if (!empty($existing_channels)) {
$last_item = end($existing_channels);
$last_id = $last_item['id'] ?? 0;
}
foreach($new_channels as &$channel) {
$last_id++;
$channel['id'] = $last_id;
}
$all_channels = array_merge($existing_channels, $new_channels);
if (json_encode($all_channels, JSON_PRETTY_PRINT)) {
file_put_contents($content_file, json_encode($all_channels, JSON_PRETTY_PRINT));
$message = 'Successfully uploaded and processed ' . count($new_channels) . ' new channels.';
if ($malformed_entries > 0) {
$error = $malformed_entries . ' entries in your file were malformed and could not be imported.';
}
} else {
$error = 'Failed to encode data to JSON. Check for special characters.';
}
} else {
$error = 'No valid channel data found in the uploaded M3U file.';
if ($malformed_entries > 0) {
$error .= ' All entries appear to be malformed.';
}
}
}
} else {
$error = 'File upload failed with error code: ' . $file['error'];
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin - Upload M3U Playlist</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg bg-dark navbar-dark">
<div class="container">
<a class="navbar-brand" href="admin.php">Admin Panel</a>
<div class="collapse navbar-collapse">
<ul class="navbar-nav">
<li class="nav-item"><a class="nav-link" href="admin_users.php">Users</a></li>
<li class="nav-item"><a class="nav-link" href="admin_content.php">Content</a></li>
<li class="nav-item"><a class="nav-link active" href="admin_upload.php">Upload</a></li>
<li class="nav-item"><a class="nav-link" href="admin_settings.php">Settings</a></li>
</ul>
</div>
</div>
</nav>
<div class="container mt-5">
<h1 class="mb-4">Upload Premium Channels</h1>
<?php if ($message): ?>
<div class="alert alert-success"><?php echo $message; ?></div>
<?php endif; ?>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo $error; ?></div>
<?php endif; ?>
<div class="card">
<div class="card-body">
<h5 class="card-title">Upload an M3U Playlist File</h5>
<p class="card-text">
The file should be a valid M3U playlist (starting with <code>#EXTM3U</code>). The parser will attempt to extract channel information from <code>#EXTINF</code> lines.
</p>
<form action="admin_upload.php" method="post" enctype="multipart/form-data">
<div class="mb-3">
<label for="channels_file" class="form-label">M3U Playlist File (.m3u, .m3u8)</label>
<input class="form-control" type="file" id="channels_file" name="channels_file" accept=".m3u,.m3u8,.txt" required>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="overwrite" name="overwrite">
<label class="form-check-label" for="overwrite">Overwrite existing channels</label>
<small class="form-text text-muted d-block">If checked, all current premium channels will be replaced by the ones in this file. If unchecked, new channels will be added to the existing list.</small>
</div>
<button type="submit" class="btn btn-primary">Upload</button>
</form>
</div>
</div>
<div class="mt-4">
<a href="admin.php" class="btn btn-secondary">Back to Admin</a>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

BIN
assets/img/icon-192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

BIN
assets/img/icon-512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

View File

@ -34,9 +34,19 @@
height: 70px; height: 70px;
} }
</style> </style>
<link rel="manifest" href="manifest.json">
</head> </head>
<body> <body>
<!-- Scrolling Link -->
<div style="position: fixed; top: 10px; right: 10px; z-index: 1050; background: #007bff; padding: 5px; border-radius: 5px; max-width: 250px;">
<marquee behavior="scroll" direction="left" scrollamount="5">
<a href="http://www.gomoviez.asia" target="_blank" style="color: white; text-decoration: none; font-size: 16px;">
watch latest movies
</a>
</marquee>
</div>
<!-- Top Navigation Bar --> <!-- Top Navigation Bar -->
<nav class="navbar navbar-expand-lg sticky-top"> <nav class="navbar navbar-expand-lg sticky-top">
<div class="container-fluid"> <div class="container-fluid">
@ -213,5 +223,16 @@
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<!-- Custom JS --> <!-- Custom JS -->
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script> <script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js').then(registration => {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}, err => {
console.log('ServiceWorker registration failed: ', err);
});
});
}
</script>
</body> </body>
</html> </html>

20
manifest.json Normal file
View File

@ -0,0 +1,20 @@
{
"short_name": "PWA",
"name": "Progressive Web App",
"icons": [
{
"src": "assets/img/icon-192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "assets/img/icon-512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": "/index.php",
"background_color": "#3367D6",
"display": "standalone",
"theme_color": "#3367D6"
}

View File

@ -1,16 +1,401 @@
[ [
{ {
"id": 1, "title": "7000\t\"Football Event 98: Italy",
"title": "Big Buck Bunny", "category": "Serie C",
"category": "Movies", "poster_url": "Girone A | Inter Milano B vs. Ospitaletto | Sunday",
"poster_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Big_buck_bunny_poster_big.jpg/800px-Big_buck_bunny_poster_big.jpg", "stream_url": "05 October 2025 19:30\"\t790028\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"stream_url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" "id": 1
}, },
{ {
"id": 2, "title": "7024\t\"Football Event 74: Italy",
"title": "Elephants Dream", "category": "Serie C",
"category": "Movies", "poster_url": "Girone C | Sorrento vs. Monopoli | Sunday",
"poster_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Elephants_dream_poster.jpg/800px-Elephants_dream_poster.jpg", "stream_url": "05 October 2025 16:30\"\t790051\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"stream_url": "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4" "id": 2
},
{
"title": "7025\t\"Football Event 73: Italy",
"category": "Serie C",
"poster_url": "Girone C | Team Altamura vs. Potenza Calcio | Sunday",
"stream_url": "05 October 2025 16:30\"\t790052\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 3
},
{
"title": "7026\t\"Football Event 72: Italy",
"category": "Serie C",
"poster_url": "Girone B | Athletic Carpi vs. Perugia | Sunday",
"stream_url": "05 October 2025 16:30\"\t790053\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 4
},
{
"title": "7027\t\"Football Event 71: Italy",
"category": "Serie C",
"poster_url": "Girone B | Forl vs. Nuova Monterosi | Sunday",
"stream_url": "05 October 2025 16:30\"\t790054\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 5
},
{
"title": "7028\t\"Football Event 70: Italy",
"category": "Serie C",
"poster_url": "Girone A | Alcione vs. Vicenza | Sunday",
"stream_url": "05 October 2025 16:30\"\t790055\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 6
},
{
"title": "7030\t\"Football Event 68: Portugal",
"category": "Liga 3",
"poster_url": "Group A | AD Fafe vs. SC Sao Joao de Ver | Sunday",
"stream_url": "05 October 2025 16:15\"\t790057\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 7
},
{
"title": "7036\t\"Football Event 62: Netherlands",
"category": "Eredivisie",
"poster_url": "Women | Hera United vs. NAC Breda | Sunday",
"stream_url": "05 October 2025 15:45\"\t790063\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 8
},
{
"title": "7053\t\"Football Event 45: Portugal",
"category": "Liga 3",
"poster_url": "Group A | Uniao SC Paredes vs. AD Marco 09 | Sunday",
"stream_url": "05 October 2025 14:15\"\t790080\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 9
},
{
"title": "7059\t\"Football Event 39: Italy",
"category": "Serie C",
"poster_url": "Girone C | Salernitana vs. Cavese | Sunday",
"stream_url": "05 October 2025 13:30\"\t790086\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 10
},
{
"title": "7060\t\"Football Event 38: Italy",
"category": "Serie C",
"poster_url": "Girone C | Trapani 1905 vs. Giugliano | Sunday",
"stream_url": "05 October 2025 13:30\"\t790087\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 11
},
{
"title": "7061\t\"Football Event 37: Italy",
"category": "Serie C",
"poster_url": "Girone C | Catania vs. Siracusa | Sunday",
"stream_url": "05 October 2025 13:30\"\t790088\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 12
},
{
"title": "7062\t\"Football Event 36: Italy",
"category": "Serie C",
"poster_url": "Girone C | Casertana vs. Virtus Casarano | Sunday",
"stream_url": "05 October 2025 13:30\"\t790089\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 13
},
{
"title": "7063\t\"Football Event 35: Italy",
"category": "Serie C",
"poster_url": "Girone A | Pro Vercelli vs. Dolomiti Bellunesi | Sunday",
"stream_url": "05 October 2025 13:30\"\t790090\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 14
},
{
"title": "7064\t\"Football Event 34: Italy",
"category": "Serie C",
"poster_url": "Girone A | Pro Patria vs. Trento | Sunday",
"stream_url": "05 October 2025 13:30\"\t790091\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 15
},
{
"title": "7070\t\"Football Event 28: Germany",
"category": "Bundesliga",
"poster_url": "Women | FC Union Berlin vs. SC Freiburg | Sunday",
"stream_url": "05 October 2025 13:00\"\t790097\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 16
},
{
"title": "7086\t\"Football Event 12: Italy",
"category": "Serie C",
"poster_url": "Girone A | Novara vs. Triestina | Sunday",
"stream_url": "05 October 2025 11:30\"\t790113\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 17
},
{
"title": "7087\t\"Football Event 11: Italy",
"category": "Serie C",
"poster_url": "Girone B | Juventus II vs. Ravenna | Sunday",
"stream_url": "05 October 2025 11:30\"\t790114\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 18
},
{
"title": "7090\t\"Football Event 08: Netherlands",
"category": "Eredivisie",
"poster_url": "Women | ADO Den Haag vs. AZ Alkmaar | Sunday",
"stream_url": "05 October 2025 11:15\"\t790117\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 19
},
{
"title": "7000\t\"Football Event 98: Italy",
"category": "Serie C",
"poster_url": "Girone A | Inter Milano B vs. Ospitaletto | Sunday",
"stream_url": "05 October 2025 19:30\"\t790028\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 20
},
{
"title": "7024\t\"Football Event 74: Italy",
"category": "Serie C",
"poster_url": "Girone C | Sorrento vs. Monopoli | Sunday",
"stream_url": "05 October 2025 16:30\"\t790051\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 21
},
{
"title": "7025\t\"Football Event 73: Italy",
"category": "Serie C",
"poster_url": "Girone C | Team Altamura vs. Potenza Calcio | Sunday",
"stream_url": "05 October 2025 16:30\"\t790052\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 22
},
{
"title": "7026\t\"Football Event 72: Italy",
"category": "Serie C",
"poster_url": "Girone B | Athletic Carpi vs. Perugia | Sunday",
"stream_url": "05 October 2025 16:30\"\t790053\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 23
},
{
"title": "7027\t\"Football Event 71: Italy",
"category": "Serie C",
"poster_url": "Girone B | Forl vs. Nuova Monterosi | Sunday",
"stream_url": "05 October 2025 16:30\"\t790054\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 24
},
{
"title": "7028\t\"Football Event 70: Italy",
"category": "Serie C",
"poster_url": "Girone A | Alcione vs. Vicenza | Sunday",
"stream_url": "05 October 2025 16:30\"\t790055\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 25
},
{
"title": "7030\t\"Football Event 68: Portugal",
"category": "Liga 3",
"poster_url": "Group A | AD Fafe vs. SC Sao Joao de Ver | Sunday",
"stream_url": "05 October 2025 16:15\"\t790057\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 26
},
{
"title": "7036\t\"Football Event 62: Netherlands",
"category": "Eredivisie",
"poster_url": "Women | Hera United vs. NAC Breda | Sunday",
"stream_url": "05 October 2025 15:45\"\t790063\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 27
},
{
"title": "7053\t\"Football Event 45: Portugal",
"category": "Liga 3",
"poster_url": "Group A | Uniao SC Paredes vs. AD Marco 09 | Sunday",
"stream_url": "05 October 2025 14:15\"\t790080\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 28
},
{
"title": "7059\t\"Football Event 39: Italy",
"category": "Serie C",
"poster_url": "Girone C | Salernitana vs. Cavese | Sunday",
"stream_url": "05 October 2025 13:30\"\t790086\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 29
},
{
"title": "7060\t\"Football Event 38: Italy",
"category": "Serie C",
"poster_url": "Girone C | Trapani 1905 vs. Giugliano | Sunday",
"stream_url": "05 October 2025 13:30\"\t790087\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 30
},
{
"title": "7061\t\"Football Event 37: Italy",
"category": "Serie C",
"poster_url": "Girone C | Catania vs. Siracusa | Sunday",
"stream_url": "05 October 2025 13:30\"\t790088\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 31
},
{
"title": "7062\t\"Football Event 36: Italy",
"category": "Serie C",
"poster_url": "Girone C | Casertana vs. Virtus Casarano | Sunday",
"stream_url": "05 October 2025 13:30\"\t790089\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 32
},
{
"title": "7063\t\"Football Event 35: Italy",
"category": "Serie C",
"poster_url": "Girone A | Pro Vercelli vs. Dolomiti Bellunesi | Sunday",
"stream_url": "05 October 2025 13:30\"\t790090\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 33
},
{
"title": "7064\t\"Football Event 34: Italy",
"category": "Serie C",
"poster_url": "Girone A | Pro Patria vs. Trento | Sunday",
"stream_url": "05 October 2025 13:30\"\t790091\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 34
},
{
"title": "7070\t\"Football Event 28: Germany",
"category": "Bundesliga",
"poster_url": "Women | FC Union Berlin vs. SC Freiburg | Sunday",
"stream_url": "05 October 2025 13:00\"\t790097\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 35
},
{
"title": "7086\t\"Football Event 12: Italy",
"category": "Serie C",
"poster_url": "Girone A | Novara vs. Triestina | Sunday",
"stream_url": "05 October 2025 11:30\"\t790113\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 36
},
{
"title": "7087\t\"Football Event 11: Italy",
"category": "Serie C",
"poster_url": "Girone B | Juventus II vs. Ravenna | Sunday",
"stream_url": "05 October 2025 11:30\"\t790114\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 37
},
{
"title": "7090\t\"Football Event 08: Netherlands",
"category": "Eredivisie",
"poster_url": "Women | ADO Den Haag vs. AZ Alkmaar | Sunday",
"stream_url": "05 October 2025 11:15\"\t790117\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 38
},
{
"title": "7000\t\"Football Event 98: Italy",
"category": "Serie C",
"poster_url": "Girone A | Inter Milano B vs. Ospitaletto | Sunday",
"stream_url": "05 October 2025 19:30\"\t790028\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 39
},
{
"title": "7024\t\"Football Event 74: Italy",
"category": "Serie C",
"poster_url": "Girone C | Sorrento vs. Monopoli | Sunday",
"stream_url": "05 October 2025 16:30\"\t790051\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 40
},
{
"title": "7025\t\"Football Event 73: Italy",
"category": "Serie C",
"poster_url": "Girone C | Team Altamura vs. Potenza Calcio | Sunday",
"stream_url": "05 October 2025 16:30\"\t790052\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 41
},
{
"title": "7026\t\"Football Event 72: Italy",
"category": "Serie C",
"poster_url": "Girone B | Athletic Carpi vs. Perugia | Sunday",
"stream_url": "05 October 2025 16:30\"\t790053\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 42
},
{
"title": "7027\t\"Football Event 71: Italy",
"category": "Serie C",
"poster_url": "Girone B | Forl vs. Nuova Monterosi | Sunday",
"stream_url": "05 October 2025 16:30\"\t790054\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 43
},
{
"title": "7028\t\"Football Event 70: Italy",
"category": "Serie C",
"poster_url": "Girone A | Alcione vs. Vicenza | Sunday",
"stream_url": "05 October 2025 16:30\"\t790055\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 44
},
{
"title": "7030\t\"Football Event 68: Portugal",
"category": "Liga 3",
"poster_url": "Group A | AD Fafe vs. SC Sao Joao de Ver | Sunday",
"stream_url": "05 October 2025 16:15\"\t790057\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 45
},
{
"title": "7036\t\"Football Event 62: Netherlands",
"category": "Eredivisie",
"poster_url": "Women | Hera United vs. NAC Breda | Sunday",
"stream_url": "05 October 2025 15:45\"\t790063\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 46
},
{
"title": "7053\t\"Football Event 45: Portugal",
"category": "Liga 3",
"poster_url": "Group A | Uniao SC Paredes vs. AD Marco 09 | Sunday",
"stream_url": "05 October 2025 14:15\"\t790080\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 47
},
{
"title": "7059\t\"Football Event 39: Italy",
"category": "Serie C",
"poster_url": "Girone C | Salernitana vs. Cavese | Sunday",
"stream_url": "05 October 2025 13:30\"\t790086\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 48
},
{
"title": "7060\t\"Football Event 38: Italy",
"category": "Serie C",
"poster_url": "Girone C | Trapani 1905 vs. Giugliano | Sunday",
"stream_url": "05 October 2025 13:30\"\t790087\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 49
},
{
"title": "7061\t\"Football Event 37: Italy",
"category": "Serie C",
"poster_url": "Girone C | Catania vs. Siracusa | Sunday",
"stream_url": "05 October 2025 13:30\"\t790088\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 50
},
{
"title": "7062\t\"Football Event 36: Italy",
"category": "Serie C",
"poster_url": "Girone C | Casertana vs. Virtus Casarano | Sunday",
"stream_url": "05 October 2025 13:30\"\t790089\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 51
},
{
"title": "7063\t\"Football Event 35: Italy",
"category": "Serie C",
"poster_url": "Girone A | Pro Vercelli vs. Dolomiti Bellunesi | Sunday",
"stream_url": "05 October 2025 13:30\"\t790090\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 52
},
{
"title": "7064\t\"Football Event 34: Italy",
"category": "Serie C",
"poster_url": "Girone A | Pro Patria vs. Trento | Sunday",
"stream_url": "05 October 2025 13:30\"\t790091\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 53
},
{
"title": "7070\t\"Football Event 28: Germany",
"category": "Bundesliga",
"poster_url": "Women | FC Union Berlin vs. SC Freiburg | Sunday",
"stream_url": "05 October 2025 13:00\"\t790097\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 54
},
{
"title": "7086\t\"Football Event 12: Italy",
"category": "Serie C",
"poster_url": "Girone A | Novara vs. Triestina | Sunday",
"stream_url": "05 October 2025 11:30\"\t790113\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 55
},
{
"title": "7087\t\"Football Event 11: Italy",
"category": "Serie C",
"poster_url": "Girone B | Juventus II vs. Ravenna | Sunday",
"stream_url": "05 October 2025 11:30\"\t790114\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 56
},
{
"title": "7090\t\"Football Event 08: Netherlands",
"category": "Eredivisie",
"poster_url": "Women | ADO Den Haag vs. AZ Alkmaar | Sunday",
"stream_url": "05 October 2025 11:15\"\t790117\tlive\t815\thttp:\/\/xplatinmedia.com:8080\/images\/836b75cfe266fa40acc2ffa3888e1abf.png\t1759659185\t0",
"id": 57
} }
] ]

31
sw.js Normal file
View File

@ -0,0 +1,31 @@
const CACHE_NAME = 'pwa-cache-v1';
const urlsToCache = [
'/',
'/index.php',
'/assets/css/custom.css',
'/assets/js/main.js',
'/assets/img/icon-192.png',
'/assets/img/icon-512.png'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => {
if (response) {
return response;
}
return fetch(event.request);
})
);
});