redone the look from scratch now uses json

This commit is contained in:
fynks 2025-01-19 19:58:38 +05:00
parent 4c0c2ad759
commit 2fc70a794b
5 changed files with 965 additions and 382 deletions

2
docs/app-min.js vendored

File diff suppressed because one or more lines are too long

View file

@ -3,34 +3,33 @@
* Handles data fetching, table generation, search functionality, and comparison features * Handles data fetching, table generation, search functionality, and comparison features
*/ */
// Class to handle table-related operations // Utility to debounce frequent events
const debounce = (func, delay = 300) => {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => func(...args), delay);
};
};
// Class to manage table operations
class TableManager { class TableManager {
/**
* @param {string} containerId - ID of the table container element
* @param {string} searchInputId - ID of the search input element
* @param {string} clearIconId - ID of the clear search icon element
*/
constructor(containerId, searchInputId, clearIconId) { constructor(containerId, searchInputId, clearIconId) {
this.container = document.getElementById(containerId); this.container = document.querySelector(`#${containerId}`);
this.searchInput = document.getElementById(searchInputId); this.searchInput = document.querySelector(`#${searchInputId}`);
this.clearIcon = document.getElementById(clearIconId); this.clearIcon = document.querySelector(`#${clearIconId}`);
this.setupSearchFunctionality(); this._setupSearchFunctionality();
} }
/** generateTable(data = {}) {
* Generates a table from provided data if (!Object.keys(data).length) {
* @param {Object} data - Table data object
* @returns {void}
*/
generateTable(data) {
if (!data || Object.keys(data).length === 0) {
this.container.innerHTML = '<p>No data available.</p>'; this.container.innerHTML = '<p>No data available.</p>';
return; return;
} }
const providers = Object.keys(data[Object.keys(data)[0]]); const providers = Object.keys(data[Object.keys(data)[0]]);
const tableHTML = ` this.container.innerHTML = `
<table id="${this.container.id.replace('-container', '')}"> <table id="${this.container.id.replace('-container', '')}" aria-label="Service Comparison Table">
<thead> <thead>
<tr> <tr>
<th>Service Name</th> <th>Service Name</th>
@ -51,19 +50,12 @@ class TableManager {
</tbody> </tbody>
</table> </table>
`; `;
this.container.innerHTML = tableHTML;
} }
/** _setupSearchFunctionality() {
* Sets up search functionality for the table const handleSearch = debounce(() => {
* @private
*/
setupSearchFunctionality() {
this.searchInput?.addEventListener('input', () => {
const searchTerm = this.searchInput.value.toLowerCase(); const searchTerm = this.searchInput.value.toLowerCase();
const rows = this.container.querySelectorAll('table tbody tr'); const rows = this.container.querySelectorAll('table tbody tr');
this.clearIcon.style.display = searchTerm ? 'block' : 'none'; this.clearIcon.style.display = searchTerm ? 'block' : 'none';
rows.forEach(row => { rows.forEach(row => {
@ -72,38 +64,29 @@ class TableManager {
}); });
}); });
this.searchInput?.addEventListener('input', handleSearch);
this.clearIcon?.addEventListener('click', () => { this.clearIcon?.addEventListener('click', () => {
this.searchInput.value = ''; this.searchInput.value = '';
this.clearIcon.style.display = 'none'; this.clearIcon.style.display = 'none';
this.searchInput.dispatchEvent(new Event('input')); handleSearch();
}); });
} }
} }
// Class to handle comparison functionality // Class to manage comparison operations
class ComparisonManager { class ComparisonManager {
/**
* @param {string} containerId - ID of the comparison container
* @param {string} select1Id - ID of the first provider select element
* @param {string} select2Id - ID of the second provider select element
* @param {Object} data - Comparison data object
*/
constructor(containerId, select1Id, select2Id, data) { constructor(containerId, select1Id, select2Id, data) {
this.container = document.getElementById(containerId); this.container = document.querySelector(`#${containerId}`);
this.select1 = document.getElementById(select1Id); this.select1 = document.querySelector(`#${select1Id}`);
this.select2 = document.getElementById(select2Id); this.select2 = document.querySelector(`#${select2Id}`);
this.data = data; this.data = data;
this.setupEventListeners();
this.populateDropdowns(); this._populateDropdowns();
this._setupEventListeners();
} }
/** _populateDropdowns() {
* Populates provider dropdowns with available options
* @private
*/
populateDropdowns() {
const providers = Object.keys(this.data[Object.keys(this.data)[0]]); const providers = Object.keys(this.data[Object.keys(this.data)[0]]);
[this.select1, this.select2].forEach(select => { [this.select1, this.select2].forEach(select => {
providers.forEach(provider => { providers.forEach(provider => {
const option = document.createElement('option'); const option = document.createElement('option');
@ -114,19 +97,20 @@ class TableManager {
}); });
} }
/** _generateCompareTable() {
* Generates comparison table for selected providers
* @private
*/
generateCompareTable() {
const provider1 = this.select1.value; const provider1 = this.select1.value;
const provider2 = this.select2.value; const provider2 = this.select2.value;
if (!provider1 || !provider2) return; if (!provider1 || !provider2) return;
const tableHTML = ` this.container.innerHTML = `
<button id="close-compare" title="Close Comparison">X</button> <button id="close-compare" title="Close Comparison">
<table id="compare-table"> <span>Close</span>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M18 6L6 18M6 6l12 12"/>
</svg>
</button>
<table id="compare-table" aria-label="Provider Comparison Table">
<thead> <thead>
<tr> <tr>
<th>Service Name</th> <th>Service Name</th>
@ -145,55 +129,38 @@ class TableManager {
</tbody> </tbody>
</table> </table>
`; `;
this.container.innerHTML = tableHTML;
this.container.style.display = 'block'; this.container.style.display = 'block';
this.setupCloseButton(); this._setupCloseButton();
} }
/** _setupEventListeners() {
* Sets up event listeners for comparison functionality
* @private
*/
setupEventListeners() {
[this.select1, this.select2].forEach(select => { [this.select1, this.select2].forEach(select => {
select?.addEventListener('change', () => this.generateCompareTable()); select?.addEventListener('change', () => this._generateCompareTable());
}); });
} }
/** _setupCloseButton() {
* Sets up close button functionality this.container.querySelector('#close-compare')?.addEventListener('click', () => {
* @private
*/
setupCloseButton() {
document.getElementById('close-compare')?.addEventListener('click', () => {
this.container.style.display = 'none'; this.container.style.display = 'none';
}); });
} }
} }
// Class to handle pricing table generation // Class to manage pricing operations
class PricingManager { class PricingManager {
/**
* @param {string} containerId - ID of the pricing section container
*/
constructor(containerId) { constructor(containerId) {
this.container = document.getElementById(containerId); this.container = document.querySelector(`#${containerId}-table-container`);
} }
/** generatePricingTable(data = {}) {
* Generates pricing table from provided data if (!data.plans?.length) {
* @param {Object} data - Pricing data object
*/
generatePricingTable(data) {
if (!data?.plans?.length) {
this.container.innerHTML = '<p>Error: Invalid pricing data structure.</p>'; this.container.innerHTML = '<p>Error: Invalid pricing data structure.</p>';
return; return;
} }
const services = Object.keys(data.plans[0]).filter(key => key !== 'name'); const services = Object.keys(data.plans[0]).filter(key => key !== 'name');
const tableHTML = ` this.container.innerHTML = `
<table> <table id="pricing-table" aria-label="Service Pricing Table">
<thead> <thead>
<tr> <tr>
<th>Plans</th> <th>Plans</th>
@ -202,57 +169,37 @@ class TableManager {
</thead> </thead>
<tbody> <tbody>
${data.plans.map(plan => ` ${data.plans.map(plan => `
<tr class="pricing-tb"> <tr>
<td>${plan.name}</td> <td>${plan.name}</td>
${services.map(service => `<td>${plan[service]}</td>`).join('')} ${services.map(service => `
<td style="text-align: center;">${plan[service]}</td>
`).join('')}
</tr> </tr>
`).join('')} `).join('')}
</tbody> </tbody>
</table> </table>
`; `;
this.container.innerHTML = tableHTML;
} }
} }
// Main application initialization // Main application initialization
document.addEventListener('DOMContentLoaded', async () => { document.addEventListener('DOMContentLoaded', async () => {
// Initialize table managers const fileHostsTable = new TableManager('file-hosts-table-container', 'host-search-input', 'clear-host-search');
const fileHostsTable = new TableManager( const adultHostsTable = new TableManager('adult-hosts-table-container', 'adult-host-search-input', 'clear-adult-host-search');
'file-hosts-table-container',
'host-search-input',
'clear-host-search'
);
const adultHostsTable = new TableManager(
'adult-hosts-table-container',
'adult-host-search-input',
'clear-adult-host-search'
);
const pricingManager = new PricingManager('pricing'); const pricingManager = new PricingManager('pricing');
try { try {
// Fetch all required data concurrently
const [fileHostsData, adultHostsData, pricingData] = await Promise.all([ const [fileHostsData, adultHostsData, pricingData] = await Promise.all([
fetch('./json/file-hosts.json').then(res => res.json()), fetch('./json/file-hosts.json').then(res => res.json()),
fetch('./json/adult-hosts.json').then(res => res.json()), fetch('./json/adult-hosts.json').then(res => res.json()),
fetch('./json/pricing.json').then(res => res.json()) fetch('./json/pricing.json').then(res => res.json())
]); ]);
// Generate tables and initialize comparison
fileHostsTable.generateTable(fileHostsData); fileHostsTable.generateTable(fileHostsData);
adultHostsTable.generateTable(adultHostsData); adultHostsTable.generateTable(adultHostsData);
pricingManager.generatePricingTable(pricingData); pricingManager.generatePricingTable(pricingData);
// Initialize comparison manager new ComparisonManager('compare-table-container', 'provider1', 'provider2', fileHostsData);
new ComparisonManager(
'compare-table-container',
'provider1',
'provider2',
fileHostsData
);
} catch (error) { } catch (error) {
console.error('Error initializing application:', error); console.error('Error initializing application:', error);
const errorMessage = '<p>Error loading data. Please try again later.</p>'; const errorMessage = '<p>Error loading data. Please try again later.</p>';
@ -261,3 +208,20 @@ class TableManager {
pricingManager.container.innerHTML = errorMessage; pricingManager.container.innerHTML = errorMessage;
} }
}); });
document.addEventListener('DOMContentLoaded', () => {
const darkModeToggle = document.getElementById('darkModeToggle');
// Check for saved theme preference
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
document.documentElement.setAttribute('data-theme', savedTheme);
}
darkModeToggle.addEventListener('click', () => {
const currentTheme = document.documentElement.getAttribute('data-theme');
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', newTheme);
localStorage.setItem('theme', newTheme);
});
});

View file

@ -4,11 +4,11 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="../favicon.ico" sizes="any"> <link rel="icon" href="favicon.ico" sizes="any">
<link rel="icon" href="../favicon.svg" type="image/svg+xml"> <link rel="icon" href="favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="images/apple-touch-icon.png"> <link rel="apple-touch-icon" href="apple-touch-icon.png">
<title>Debrid Services Comparison</title> <title>Debrid Services Comparison</title>
<link rel="stylesheet" href="styles.css"> <link rel="stylesheet" href="styles-min.css">
<meta name="description" <meta name="description"
content="A comparison of available hosts and pricing for AllDebrid, Real-Debrid, LinkSnappy, Premiumize, Debrid-Link, TorBox and Mega-Debrid."> content="A comparison of available hosts and pricing for AllDebrid, Real-Debrid, LinkSnappy, Premiumize, Debrid-Link, TorBox and Mega-Debrid.">
<meta name="keywords" <meta name="keywords"
@ -39,23 +39,37 @@
<body> <body>
<header role="banner"> <header class="site-header">
<h1 class="title">Debrid Services Comparison</h1> <div class="container">
<nav role="navigation" aria-label="Table of contents"> <a href="#" class="site-title">Debrid Services Comparison</a>
<button id="darkModeToggle" class="dark-mode-toggle" aria-label="Toggle dark mode">
</nav> <svg class="sun-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path
d="M12 2.25a.75.75 0 0 1 .75.75v2.25a.75.75 0 0 1-1.5 0V3a.75.75 0 0 1 .75-.75zM7.5 12a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0zM12 21.75a.75.75 0 0 1-.75-.75v-2.25a.75.75 0 0 1 1.5 0V21a.75.75 0 0 1-.75.75zM3 12.75a.75.75 0 0 1 0-1.5h2.25a.75.75 0 0 1 0 1.5H3zM21 12.75a.75.75 0 0 1 0-1.5h-2.25a.75.75 0 0 1 0 1.5H21z" />
</svg>
<svg class="moon-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path
d="M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z" />
</svg>
</button>
</div>
</header> </header>
<main id="main-content" role="main"> <main id="main-content" class="container" role="main">
<p>A comparison of available hosts and pricing for <a href="https://alldebrid.com/">AllDebrid</a>, <a <section class="intro-section">
href="https://real-debrid.com/">Real-Debrid</a>, <a <p>A comprehensive comparison of available hosts and pricing for leading debrid services: <a
href="https://alldebrid.com/">AllDebrid</a>, <a href="https://real-debrid.com/">Real-Debrid</a>, <a
href="https://linksnappy.com/myaccount/status">LinkSnappy</a>, href="https://linksnappy.com/myaccount/status">LinkSnappy</a>,
<a href="https://www.premiumize.me/services">Premiumize</a>, <a <a href="https://www.premiumize.me/services">Premiumize</a>, <a
href="https://debrid-link.com/">Debrid-Link</a>, <a href="https://torbox.app/">TorBox</a> and <a href="https://debrid-link.com/">Debrid-Link</a>, <a href="https://torbox.app/">TorBox</a>, and <a
href="https://debrid-link.com">Mega-Debrid</a>. href="https://debrid-link.com">Mega-Debrid</a>.
</p> </p>
<h1 id="contents">Contents:</h1> </section>
<ul>
<section id="contents" class="content-section">
<h2>Table of Contents</h2>
<nav aria-label="Section Navigation">
<ul class="toc-list">
<li><a href="#signing-up">Signing Up</a> <li><a href="#signing-up">Signing Up</a>
<ul> <ul>
<li><a href="#referral-links">Referral Links</a></li> <li><a href="#referral-links">Referral Links</a></li>
@ -75,19 +89,28 @@
</ul> </ul>
</li> </li>
</ul> </ul>
<h1 id="signing-up">Signing Up</h1> </nav>
<h3 id="referral-links">Referral Links</h3> </section>
<p>If you are signing up for any above service, Please consider
buying from my referral link:</p> <section id="signing-up" class="content-section">
<ul> <h2>Signing Up</h2>
<article id="referral-links">
<h3>Referral Links</h3>
<p>If you're considering signing up, please support the site by using the referral links below:</p>
<ul class="link-list">
<li><a href="https://alldebrid.com/?uid=3wvya&lang=en">AllDebrid</a></li> <li><a href="https://alldebrid.com/?uid=3wvya&lang=en">AllDebrid</a></li>
<li><a href="http://real-debrid.com/?id=10990901">Real-Debrid</a></li> <li><a href="http://real-debrid.com/?id=10990901">Real-Debrid</a></li>
<li><a href="https://torbox.app/subscription?referral=47eece72-46b8-483b-8b7a-79d6c16dedf2">TorBox</a></li> <li><a
href="https://torbox.app/subscription?referral=47eece72-46b8-483b-8b7a-79d6c16dedf2">TorBox</a>
</li>
<li><a href="http://linksnappy.com/?ref=774668">LinkSnappy</a></li> <li><a href="http://linksnappy.com/?ref=774668">LinkSnappy</a></li>
<li><a href="https://debrid-link.com/id/7B3BO">Debrid-Link</a></li> <li><a href="https://debrid-link.com/id/7B3BO">Debrid-Link</a></li>
</ul> </ul>
<h3 id="non-referral-links">Non-referral Links</h3> </article>
<ul> <article id="non-referral-links">
<h3>Non-referral Links</h3>
<p>Alternatively, here are direct links to the services:</p>
<ul class="link-list">
<li><a href="https://alldebrid.com/register/">AllDebrid</a></li> <li><a href="https://alldebrid.com/register/">AllDebrid</a></li>
<li><a href="http://real-debrid.com/">Real-Debrid</a></li> <li><a href="http://real-debrid.com/">Real-Debrid</a></li>
<li><a href="https://torbox.app/login">TorBox</a></li> <li><a href="https://torbox.app/login">TorBox</a></li>
@ -96,17 +119,22 @@
<li><a href="https://debrid-link.com/webapp/register">Debrid-Link</a></li> <li><a href="https://debrid-link.com/webapp/register">Debrid-Link</a></li>
<li><a href="https://www.mega-debrid.eu/index.php?page=freeregister">Mega-Debrid</a></li> <li><a href="https://www.mega-debrid.eu/index.php?page=freeregister">Mega-Debrid</a></li>
</ul> </ul>
<h1>Pricing</h1> </article>
<div id="pricing"> </section>
<section id="pricing" class="content-section">
<h2>Pricing</h2>
<div id="pricing-table-container" class="data-table-container">
<!-- Pricing table will be generated here --> <!-- Pricing table will be generated here -->
<div class="loading">Loading pricing data...</div>
</div> </div>
<blockquote> <blockquote class="note">
<p>[ * ] = 7 Days free trail at Alldebrid requires a phone <p>[ * ] = 7 Days free trial at Alldebrid requires phone verification.</p>
verification.</p>
</blockquote> </blockquote>
<h2 id="up-to-date-pricing">Up-to-date Pricing</h2> <article id="up-to-date-pricing">
<p>You can check pricing for each individual service at:</p> <h3>Up-to-date Pricing</h3>
<ul> <p>For the most current pricing details, please visit the official websites:</p>
<ul class="link-list">
<li><a href="https://alldebrid.com/offer/">AllDebrid</a></li> <li><a href="https://alldebrid.com/offer/">AllDebrid</a></li>
<li><a href="https://real-debrid.com/premium">Real-Debrid</a></li> <li><a href="https://real-debrid.com/premium">Real-Debrid</a></li>
<li><a href="https://torbox.app/pricing">TorBox</a></li> <li><a href="https://torbox.app/pricing">TorBox</a></li>
@ -115,19 +143,31 @@
<li><a href="https://debrid-link.com/premium">Debrid-Link</a></li> <li><a href="https://debrid-link.com/premium">Debrid-Link</a></li>
<li><a href="https://www.mega-debrid.eu/index.php?page=offres">Mega-Debrid</a></li> <li><a href="https://www.mega-debrid.eu/index.php?page=offres">Mega-Debrid</a></li>
</ul> </ul>
<h1 id="available-hosts">Available Hosts</h1> </article>
<h2 id="file-hosts">File Hosts</h2> </section>
<section id="available-hosts" class="content-section">
<h2>Available Hosts</h2>
<article id="file-hosts">
<h3>File Hosts</h3>
<div id="search-container" class="search-container"> <div id="search-container" class="search-container">
<input type="text" id="host-search-input" class="search-input" placeholder="Search file hosts..." <input type="text" id="host-search-input" class="search-input" placeholder="Search file hosts..."
aria-label="Search file hosts" /> aria-label="Search file hosts" />
<span id="clear-host-search" class="clear-icon" role="button" title="Clear search">X</span> <button id="clear-host-search" class="clear-icon" aria-label="Clear search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
</svg>
</button>
</div> </div>
<div id="file-hosts-table-container"> <div id="file-hosts-table-container" class="data-table-container">
<!-- File hosts table will be generated here --> <!-- File hosts table will be generated here -->
<div class="loading">Loading file hosts...</div>
</div> </div>
</article>
<h2 id="compare">Compare Providers</h2> <article id="compare">
<h3>Compare Providers</h3>
<div id="compare-container"> <div id="compare-container">
<div class="compare-select-group"> <div class="compare-select-group">
<label for="provider1">Provider 1:</label> <label for="provider1">Provider 1:</label>
@ -138,27 +178,39 @@
<select id="provider2" aria-label="Select second provider to compare"></select> <select id="provider2" aria-label="Select second provider to compare"></select>
</div> </div>
</div> </div>
<div id="compare-table-container"> <div id="compare-table-container" class="data-table-container">
<button id="close-compare" title="Close Comparison" aria-label="Close comparison table">×</button> <div class="compare-header">
<!-- Comparison table will be generated here --> <h3>Comparison</h3>
</div> </div>
<!-- Comparison table content will be dynamically generated -->
<div class="loading">Loading comparison...</div>
</div>
</article>
<h2 id="adult-hosts">Adult Hosts</h2> <article id="adult-hosts">
<div id="adult-hosts-search-wrapper" style="margin-bottom: 10px;"> <h3>Adult Hosts</h3>
<div id="adult-hosts-search-wrapper">
<div id="search-container-adult" class="search-container"> <div id="search-container-adult" class="search-container">
<input type="text" id="adult-host-search-input" class="search-input" placeholder="Search adult hosts..." <input type="text" id="adult-host-search-input" class="search-input"
aria-label="Search adult hosts" /> placeholder="Search adult hosts..." aria-label="Search adult hosts" />
<span id="clear-adult-host-search" class="clear-icon">X</span> <button id="clear-adult-host-search" class="clear-icon" aria-label="Clear search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
</svg>
</button>
</div> </div>
</div> </div>
<div id="adult-hosts-table-container"> <div id="adult-hosts-table-container" class="data-table-container">
<!-- Adult hosts table will be generated here --> <!-- Adult hosts table will be generated here -->
<div class="loading">Loading adult hosts...</div>
</div> </div>
</article>
<h2 id="live-status">Live status</h2> <article id="live-status">
<p>Up-to-date list of hosts for individual services can tracked <h3>Live status</h3>
from:</p> <p>Track the most current host status updates on the official service pages:</p>
<ul> <ul class="link-list">
<li><a href="https://alldebrid.com/status/">AllDebrid</a></li> <li><a href="https://alldebrid.com/status/">AllDebrid</a></li>
<li><a href="https://real-debrid.com/compare">Real-Debrid</a></li> <li><a href="https://real-debrid.com/compare">Real-Debrid</a></li>
<li><a href="https://linksnappy.com/myaccount/status">LinkSnappy</a></li> <li><a href="https://linksnappy.com/myaccount/status">LinkSnappy</a></li>
@ -167,18 +219,20 @@
<li><a href="https://debrid-link.com/webapp/status">Debrid-Link</a></li> <li><a href="https://debrid-link.com/webapp/status">Debrid-Link</a></li>
<li><a href="https://www.mega-debrid.eu/index.php?page=hebergeurs">Mega-Debrid</a></li> <li><a href="https://www.mega-debrid.eu/index.php?page=hebergeurs">Mega-Debrid</a></li>
</ul> </ul>
<hr /> </article>
<div class="last-updated"> </section>
<h4>Last updated: <span class="last-updated-date">January 14, 2025</span></h4>
</div>
</main> </main>
<footer role="contentinfo"> <footer class="site-footer" role="contentinfo">
<div class="last-updated">
<p>Last updated: <span class="last-updated-date">January 14, 2025</span></p>
</div>
<div class="container">
<p><a href="https://github.com/fynks/debrid-services-comparison">Source</a> | Made with ❤️ by Fynks</p> <p><a href="https://github.com/fynks/debrid-services-comparison">Source</a> | Made with ❤️ by Fynks</p>
</div>
</footer> </footer>
<script src="app-min.js"></script> <script src="app-min.js"></script>
</body> </body>
</html> </html>

1
docs/styles-min.css vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long