Compare commits

..

No commits in common. "main" and "2025-01-12" have entirely different histories.

35 changed files with 2866 additions and 10418 deletions

3
.github/FUNDING.yml vendored
View file

@ -1,3 +0,0 @@
# These are supported funding model platforms
open_collective: carlos61

4
.gitignore vendored
View file

@ -1,4 +0,0 @@
docs/.vitepress/dist
docs/.vitepress/cache
node_modules
tbd.md

View file

@ -1,36 +0,0 @@
### Adult Hosts
| **Service Name** | **AllDebrid** | **RealDebrid** | **TorBox** | **Deepbrid** | **Premiumize** | **Mega-Debrid** | **High-Way** | **LinkSnappy** | **Debrid-Link** |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| Beeg | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Coomer | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Drtuber | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Eporner | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Hanime | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Hentai foundry | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Kemono | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Nhentai | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Pornhub | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Pornoxo | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Redgifs | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Redtube | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Rule34 | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Spankbang | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Stripchat | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Sunporno | ✅ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Xhamster | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Xnxx | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Xvideos | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Xxxymovies | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Youjizz | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Youporn | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| **Total = 22** | **12/22** | **2/22** | **20/22** | **1/22** | **1/22** | **1/22** | **0/22** | **0/22** | **0/22** |
> **Last updated: March 9, 2026**
<div align="center">
### [Back to home](./README.md)
</div>

9
CHANGELOG.md Normal file
View file

@ -0,0 +1,9 @@
# Sunday, January 12, 2025
## Updated:
- Hosts for torbox
- Link for torbox hosts live updates
- Timestamp
## Removed:
- Deduplicated entries in hosts
- Removed Some Adult hosts from file hosts

View file

@ -1,32 +0,0 @@
# Contributing to Debrid Services Comparison
Thank you for your interest in improving this project! Your contributions help keep the comparison accurate and up to date.
## How to Contribute
### Open an Issue
1. Go to the [Issues tab](https://github.com/fynks/debrid-services-comparison/issues)
2. Click **"New Issue"**
3. Include:
- Service name
- Change observed (e.g., "AllDebrid now supports Terabox")
- Proof: **Link to official page or screenshot**
- Date of observation
4. Submit — maintainers will review and update
### Submit a Pull Request
1. Fork the repository
2. Edit the relevant file (`README.md`, `Adult-hosts.md`, etc.)
3. **Update the `Last updated date`** at the bottom
4. Create a pull request with a clear description
## Guidelines
- Keep changes factual and neutral.
- Use clear, concise language.
- Reference official sources when possible.
- Avoid promotional content.
---
**Thanks for helping make this resource better for everyone! 🚀**

21
LICENSE
View file

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2025 Fynks
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

1003
README.md

File diff suppressed because it is too large Load diff

98
convert.sh Executable file
View file

@ -0,0 +1,98 @@
#!/bin/bash
set -euo pipefail
# Error handling
handle_error() {
echo "Error: $1"
cleanup
exit 1
}
# Cleanup function
cleanup() {
rm -f header.html template.html
}
# Check requirements
if ! command -v pandoc &> /dev/null; then
handle_error "pandoc is not installed. Please install it first."
fi
# Create template
cat > template.html << 'EOL'
<!DOCTYPE html>
<html lang="en">
<head>
$header-includes$
<title>Debrid Services Comparison</title>
</head>
<body>
<header role="banner">
<h1 class="title">$title$</h1>
<nav role="navigation" aria-label="Table of contents">
$toc$
</nav>
</header>
<main id="main-content" role="main">
$body$
</main>
<footer role="contentinfo">
<p><a href="https://github.com/fynks/debrid-services-comparison">Source &#8599;</a> | Made with ❤️ by Fynks</p>
</footer>
<script>
document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("available-hosts");if(e){const t=document.createElement("div");t.id="search-container",t.innerHTML='\n <input type="text" id="search-input" placeholder="Search the hosts..." />\n ',e.insertAdjacentElement("afterend",t);const n=document.getElementById("search-input");n.addEventListener("input",(function(){const e=n.value.toLowerCase(),t=document.querySelectorAll("table");if(t.length>1){const n=t[1].getElementsByTagName("tr");for(let t=1;t<n.length;t++){const o=n[t].getElementsByTagName("td");let a=!1;for(let t=0;t<o.length;t++)if(o[t].innerText.toLowerCase().includes(e)){a=!0;break}n[t].style.display=a?"":"none"}}}))}}));
</script>
</body>
</html>
EOL
# Create header with improved meta tags
cat > header.html << 'EOL'
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="A quick comparison of available hosts for AllDebrid, Real-Debrid, LinkSnappy, Premiumize, Debrid-Link, and TorBox.">
<meta name="keywords" content="Debrid services, AllDebrid, Real-Debrid, LinkSnappy, Premiumize, Debrid-Link, TorBox, comparison, pricing, hosts, file hosts, downloading, free downloading, mediafire, mega.nz, mega free download, turbobit free download, rapidgator free download, nitroflare">
<meta name="author" content="Fynks">
<meta name="robots" content="index, follow">
<meta name="theme-color" content="#0366d6">
<link rel="stylesheet" href="styles.css">
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website">
<meta property="og:url" content="https://debrid-services-comparison.netlify.app/">
<meta property="og:title" content="Debrid Services Comparison">
<meta property="og:description" content="A quick comparison of available hosts for AllDebrid, Real-Debrid, LinkSnappy, Premiumize, Debrid-Link, and TorBox.">
<meta property="og:image" content="https://debrid-services-comparison.netlify.app/image.png">
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image">
<meta property="twitter:url" content="https://debrid-services-comparison.netlify.app/">
<meta property="twitter:title" content="Debrid Services Comparison">
<meta property="twitter:description" content="A quick comparison of available hosts for AllDebrid, Real-Debrid, LinkSnappy, Premiumize, Debrid-Link, and TorBox.">
<meta property="twitter:image" content="https://debrid-services-comparison.netlify.app/image.png">
EOL
# Convert markdown with progress
echo "Starting conversion process..."
echo "→ Generating HTML from markdown..."
pandoc README.md \
--from gfm \
--to html5 \
--standalone \
--template=template.html \
--include-in-header=header.html \
--metadata title="Debrid Services Comparison" \
--shift-heading-level-by=-1 \
--toc-depth=2 \
-o docs/index.html || handle_error "Conversion failed"
# Cleanup
cleanup
echo "✓ Conversion complete! Output saved as docs/index.html"

View file

@ -1,4 +0,0 @@
Contact: https://github.com/fynks/debrid-services-comparison/issues
Expires: 2026-12-31T23:59:59.000Z
Preferred-Languages: en
Canonical: https://debridcompare.pages.dev/.well-known/security.txt

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square70x70logo src="/images/favicon-32x32.png"/>
<square150x150logo src="/images/apple-touch-icon.png"/>
<square310x310logo src="/images/apple-touch-icon.png"/>
<TileColor>#2563eb</TileColor>
</tile>
</msapplication>
</browserconfig>

4232
dist/css/styles.css vendored

File diff suppressed because it is too large Load diff

BIN
dist/favicon.ico vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

5
dist/favicon.svg vendored
View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve">
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)">
<path d="M 71.79 34.614 c -0.334 -0.497 -0.926 -0.745 -1.513 -0.63 l -18.311 3.528 l 3.718 -35.877 c 0.071 -0.682 -0.332 -1.32 -0.979 -1.55 c -0.648 -0.229 -1.362 0.011 -1.738 0.585 L 18.202 53.746 c -0.328 0.5 -0.325 1.144 0.008 1.639 c 0.33 0.493 0.922 0.742 1.513 0.632 l 18.312 -3.529 l -3.718 35.876 c -0.071 0.684 0.332 1.322 0.979 1.551 C 35.455 89.971 35.622 90 35.792 90 c 0.502 0 0.965 -0.251 1.241 -0.67 l 34.765 -53.076 C 72.126 35.754 72.122 35.11 71.79 34.614 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(216,159,0); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 924 B

View file

@ -1,99 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 930" style="max-width: 800px;">
<defs>
<style>
/* Light mode (default) */
.box { fill: #fff; stroke: #333; stroke-width: 2; }
.diamond { fill: #fff; stroke: #333; stroke-width: 2; }
.text { font-family: Arial, sans-serif; font-size: 14px; text-anchor: middle; fill: #333; }
.arrow { stroke: #333; stroke-width: 2; fill: none; marker-end: url(#arrowhead-light); }
.label { font-family: Arial, sans-serif; font-size: 12px; text-anchor: middle; fill: #333; }
#arrowhead-light { display: block; }
#arrowhead-dark { display: none; }
/* Dark mode */
@media (prefers-color-scheme: dark) {
.box { fill: #1c1c1c; stroke: #8b949e; stroke-width: 2; }
.diamond { fill: #1c1c1c; stroke: #8b949e; stroke-width: 2; }
.text { fill: #c9d1d9; }
.arrow { stroke: #8b949e; marker-end: url(#arrowhead-dark); }
.label { fill: #8b949e; }
#arrowhead-light { display: none; }
#arrowhead-dark { display: block; }
}
</style>
<marker id="arrowhead-light" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
<polygon points="0 0, 10 3, 0 6" fill="#333" />
</marker>
<marker id="arrowhead-dark" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
<polygon points="0 0, 10 3, 0 6" fill="#8b949e" />
</marker>
</defs>
<!-- Node A -->
<rect x="250" y="20" width="300" height="60" rx="5" class="box"/>
<text x="400" y="55" class="text">User provides file link or torrent</text>
<!-- Arrow A to B -->
<path d="M 400 80 L 400 130" class="arrow"/>
<!-- Node B (Diamond) -->
<path d="M 400 130 L 500 180 L 400 230 L 300 180 Z" class="diamond"/>
<text x="400" y="180" class="text">File on supported</text>
<text x="400" y="195" class="text">host?</text>
<!-- Arrow B to C -->
<path d="M 400 230 L 400 270" class="arrow"/>
<text x="430" y="255" class="label">Yes</text>
<!-- Node C -->
<rect x="275" y="270" width="250" height="60" rx="5" class="box"/>
<text x="400" y="305" class="text">Debrid service fetches file</text>
<!-- Arrow C to D -->
<path d="M 400 330 L 400 370" class="arrow"/>
<!-- Node D -->
<rect x="250" y="370" width="300" height="60" rx="5" class="box"/>
<text x="400" y="405" class="text">File cached on high-speed servers</text>
<!-- Arrow D to E -->
<path d="M 400 430 L 400 480" class="arrow"/>
<!-- Node E (Diamond) -->
<path d="M 400 480 L 500 530 L 400 580 L 300 530 Z" class="diamond"/>
<text x="400" y="530" class="text">Stream or</text>
<text x="400" y="545" class="text">download?</text>
<!-- Arrow E to F (Stream) -->
<path d="M 300 530 L 150 530 L 150 650" class="arrow"/>
<text x="200" y="525" class="label">Stream</text>
<!-- Arrow E to G (Download) -->
<path d="M 500 530 L 650 530 L 650 650" class="arrow"/>
<text x="600" y="525" class="label">Download</text>
<!-- Node F -->
<rect x="25" y="650" width="250" height="60" rx="5" class="box"/>
<text x="150" y="685" class="text">Direct streaming link provided</text>
<!-- Node G -->
<rect x="525" y="650" width="250" height="60" rx="5" class="box"/>
<text x="650" y="685" class="text">High-speed download link provided</text>
<!-- Arrow F to H -->
<path d="M 150 710 L 150 750 L 400 750" class="arrow"/>
<!-- Arrow G to H -->
<path d="M 650 710 L 650 750 L 400 750" class="arrow"/>
<!-- Node H -->
<rect x="275" y="750" width="250" height="60" rx="5" class="box"/>
<text x="400" y="785" class="text">Access file instantly</text>
<!-- Arrow H to I -->
<path d="M 400 810 L 400 850" class="arrow"/>
<!-- Node I -->
<rect x="250" y="850" width="300" height="60" rx="5" class="box"/>
<text x="400" y="885" class="text">File cached for 24-72 hours</text>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

BIN
dist/images/og.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 438 KiB

2342
dist/index.html vendored

File diff suppressed because it is too large Load diff

2390
dist/js/app.js vendored

File diff suppressed because it is too large Load diff

View file

@ -1 +0,0 @@
{"Beeg":{"AllDebrid":"✅","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Coomer":{"AllDebrid":"❌","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Drtuber":{"AllDebrid":"✅","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"✅","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Eporner":{"AllDebrid":"❌","RealDebrid":"❌","TorBox":"❌","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Hanime":{"AllDebrid":"❌","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Hentai foundry":{"AllDebrid":"❌","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Kemono":{"AllDebrid":"❌","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Nhentai":{"AllDebrid":"❌","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Pornhub":{"AllDebrid":"✅","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Pornoxo":{"AllDebrid":"✅","RealDebrid":"❌","TorBox":"❌","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Redgifs":{"AllDebrid":"❌","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Redtube":{"AllDebrid":"✅","RealDebrid":"✅","TorBox":"✅","Deepbrid":"✅","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Rule34":{"AllDebrid":"❌","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Spankbang":{"AllDebrid":"✅","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Stripchat":{"AllDebrid":"❌","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Sunporno":{"AllDebrid":"✅","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"✅","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Xhamster":{"AllDebrid":"✅","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Xnxx":{"AllDebrid":"✅","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Xvideos":{"AllDebrid":"✅","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Xxxymovies":{"AllDebrid":"✅","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Youjizz":{"AllDebrid":"✅","RealDebrid":"❌","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"},"Youporn":{"AllDebrid":"❌","RealDebrid":"✅","TorBox":"✅","Deepbrid":"❌","Premiumize":"❌","Mega-Debrid":"❌","High-Way":"❌","LinkSnappy":"❌","Debrid-Link":"❌"}}

File diff suppressed because one or more lines are too long

25
dist/manifest.json vendored
View file

@ -1,25 +0,0 @@
{
"name": "Debrid Compare",
"short_name": "DSC",
"start_url": "https://debridcompare.pages.dev",
"display": "standalone",
"description": "Compare leading debrid / multi-hoster services for pricing, host coverage, policies & tools.",
"lang": "en",
"dir": "auto",
"theme_color": "#ffffff",
"background_color": "#ffffff",
"orientation": "any",
"icons": [
{
"src": "images/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "images/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}

4
dist/robots.txt vendored
View file

@ -1,4 +0,0 @@
User-agent: *
Allow: /
Sitemap: https://debridcompare.pages.dev/sitemap.xml

View file

@ -1 +0,0 @@
rzd7n8dtydkn3rusq48azrfacbx5zapr

7
dist/sitemap.xml vendored
View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://debridcompare.pages.dev/</loc>
<lastmod>2026-03-22</lastmod>
</url>
</urlset>

BIN
docs/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

2453
docs/index.html Normal file

File diff suppressed because it is too large Load diff

1
docs/styles.css Normal file
View file

@ -0,0 +1 @@
:root{--primary:#2563eb;--text:#1f2937;--text-light:#6b7280;--bg:#ffffff;--bg-alt:#f8fafc;--border:#e2e8f0;--radius:.5rem;--shadow:0 1px 3px rgba(0,0,0,.1);--transition:all .2s ease;}body{font-family:-apple-system,BlinkMacSystemFont,'Inter',system-ui,sans-serif;line-height:1.7;max-width:1100px;margin:0 auto;padding:2rem;color:var(--text);background:var(--bg);}h1,h2,h3,h4{margin-top:2.5rem;margin-bottom:1.5rem;font-weight:600;line-height:1.3;color:var(--text);}h1{font-size:2.25rem}h2{font-size:1.875rem}h3{font-size:1.5rem}a{color:var(--primary);text-decoration:none;transition:var(--transition);}a:hover{opacity:.8;text-decoration:underline;}table{width:100%;border-collapse:separate;border-spacing:0;margin:2rem 0;font-size:.95rem;border:1px solid var(--border);border-radius:var(--radius);}th,td{padding:1rem;text-align:left;border-bottom:1px solid var(--border);}th{background-color:var(--primary);color:white;rgba(107,114,128,.507);font-weight:600;top:0;}tr:nth-child(even){background:var(--bg-alt);}tr:hover{background:rgba(37,99,235,.05);transition:var(--transition);}th:first-child{border-top-left-radius:var(--radius);}th:last-child{border-top-right-radius:var(--radius);}tr:last-child td:first-child{border-bottom-left-radius:var(--radius);}tr:last-child td:last-child{border-bottom-right-radius:var(--radius);}#search-container{margin:2rem 0;top:1rem;z-index:100;background:var(--bg);padding:1rem 0;}#search-input{width:90%;padding:.75rem 1rem;border:1px solid var(--border);border-radius:var(--radius);font-size:1rem;transition:var(--transition);margin:auto;}#search-input:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px rgba(37,99,235,.1);}blockquote{margin:2rem 0;padding:1rem 1.5rem;border-left:4px solid var(--primary);background:var(--bg-alt);border-radius:0 var(--radius) var(--radius) 0;}code{background:var(--bg-alt);padding:.2em .4em;border-radius:var(--radius);font-size:.875em;font-family:ui-monospace,'Cascadia Code','Source Code Pro',Menlo,monospace;}@media (max-width:768px){body{padding:1rem}h1{font-size:1.875rem}h2{font-size:1.5rem}h3{font-size:1.25rem}table{border-radius:0;border-left:none;border-right:none}th,td{padding:.75rem;min-width:120px;font-size:.9rem}th{white-space:nowrap}}

View file

@ -1,25 +0,0 @@
{
"name": "@fynks/debrid-service-comparison",
"version": "2.0.1",
"description": "A concise comparison of pricing and supported hosts for popular debrid services including AllDebrid, Real-Debrid, LinkSnappy, Premiumize, Debrid-Link, TorBox, and Mega-Debrid.",
"main": "index.js",
"homepage": "https://debridcompare.pages.dev/",
"repository": {
"type": "git",
"url": "https://github.com/fynks/debrid-services-comparison"
},
"scripts": {
"minify:css": "cleancss -o dist/css/styles-min.css dist/css/styles.css",
"minify:js": "terser dist/js/app.js -o dist/js/app-min.js --compress --mangle",
"optimize-json": "chmod +x scripts/json-optimizer.sh && scripts/json-optimizer.sh dist/json/file-hosts.json dist/json/file-hosts-optimized.json && scripts/json-optimizer.sh dist/json/adult-hosts.json dist/json/adult-hosts-optimized.json",
"prune-json": "rm -f dist/json/file-hosts.json dist/json/adult-hosts.json",
"build": "npm run minify:css && npm run minify:js && npm run optimize-json && npm run prune-json && workbox generateSW workbox-config.js",
"postbuild": "node scripts/replace-assets.js"
},
"author": "fynks",
"dependencies": {
"clean-css-cli": "^5.6.3",
"terser": "^5.46.0",
"workbox-cli": "^7.4.0"
}
}

View file

@ -1,191 +0,0 @@
#!/bin/bash
# JSON Optimizer Script - Converts host data to indexed format
# Converts ✅/❌ format to compact indexed format for better performance
# Usage: ./scripts/json-optimizer.sh file-hosts.json
# ./scripts/json-optimizer.sh adult-hosts.json
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Default values
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DEFAULT_INPUT_DIR="."
DEFAULT_OUTPUT_DIR="."
# Check if at least one argument is provided
if [ $# -eq 0 ]; then
print_error "No input file specified"
echo "Usage: $0 <input-file.json> [output-file.json]"
echo "Examples:"
echo " $0 file-hosts.json"
echo " $0 ./json/adult-hosts.json"
echo " $0 ./json/file-hosts.json file-hosts-optimized.json"
exit 1
fi
# Get input file
INPUT_FILE="$1"
# Generate output filename if not provided
if [ $# -eq 2 ]; then
OUTPUT_FILE="$2"
else
# Extract filename without path and extension
FILENAME=$(basename "$INPUT_FILE")
NAME="${FILENAME%.*}"
EXT="${FILENAME##*.}"
OUTPUT_FILE="${NAME}-optimized.${EXT}"
fi
# Check if input file exists
if [ ! -f "$INPUT_FILE" ]; then
print_error "Input file '$INPUT_FILE' not found"
exit 1
fi
# Create output directory if it doesn't exist
OUTPUT_DIR=$(dirname "$OUTPUT_FILE")
if [ ! -d "$OUTPUT_DIR" ] && [ "$OUTPUT_DIR" != "." ]; then
print_status "Creating output directory: $OUTPUT_DIR"
mkdir -p "$OUTPUT_DIR"
fi
print_status "Processing: $INPUT_FILE"
print_status "Output will be saved to: $OUTPUT_FILE"
# Python script to handle the conversion
python3 -c "
import json
import sys
import os
from collections import defaultdict
def convert_to_indexed_format(input_file, output_file):
try:
# Read the input JSON
print('Reading input file...')
with open(input_file, 'r') as f:
data = json.load(f)
host_count = len(data)
print(f'Loaded {host_count:,} hosts')
# Handle empty data
if not data:
print('Warning: Input file is empty')
output_data = {'services': [], 'supported': {}}
with open(output_file, 'w') as f:
json.dump(output_data, f, separators=(',', ':'))
return True
# Extract all services (keys from entries)
all_services = set()
for host_data in data.values():
all_services.update(host_data.keys())
services = sorted(list(all_services))
service_count = len(services)
print(f'Found {service_count} services: {\", \".join(services[:5])}{\"...\" if service_count > 5 else \"\"}')
# Create service to index mapping
service_to_index = {service: idx for idx, service in enumerate(services)}
# Convert data to indexed format
print('Converting data to indexed format...')
supported = {}
total_support_instances = 0
for host, host_data in data.items():
# Get indices of services with '✅' values (new format)
supported_indices = [
service_to_index[service]
for service, value in host_data.items()
if str(value) == '✅'
]
supported[host] = sorted(supported_indices)
total_support_instances += len(supported_indices)
# Create output structure
output_data = {
'services': services,
'supported': supported
}
# Write optimized JSON (compact format)
print('Writing optimized JSON...')
with open(output_file, 'w') as f:
json.dump(output_data, f, separators=(',', ':'))
# Get file sizes for comparison
original_size = os.path.getsize(input_file)
new_size = os.path.getsize(output_file)
reduction = ((original_size - new_size) / original_size) * 100 if original_size > 0 else 0
print('✅ Conversion successful!')
print(f'📁 Original size: {original_size:,} bytes')
print(f'📁 New size: {new_size:,} bytes')
print(f'📉 Size reduction: {reduction:.1f}%')
print(f'💾 Output saved to: {output_file}')
# Show statistics
avg_support_per_host = total_support_instances / host_count if host_count > 0 else 0
print('📈 Statistics:')
print(f' - Hosts: {host_count:,}')
print(f' - Services: {service_count:,}')
print(f' - Total support instances: {total_support_instances:,}')
print(f' - Average support per host: {avg_support_per_host:.1f}')
return True
except json.JSONDecodeError as e:
print(f'❌ JSON parsing error: {str(e)}')
return False
except Exception as e:
print(f'❌ Error during conversion: {str(e)}')
return False
# Run the conversion
success = convert_to_indexed_format('$INPUT_FILE', '$OUTPUT_FILE')
if not success:
sys.exit(1)
" || {
print_error "Python conversion failed. Please ensure Python 3 is installed."
exit 1
}
print_success "Conversion completed successfully!"
# Optional: Show file size comparison in bash as well
if command -v stat >/dev/null 2>&1; then
ORIGINAL_SIZE=$(stat -f%z "$INPUT_FILE" 2>/dev/null || stat -c%s "$INPUT_FILE" 2>/dev/null)
NEW_SIZE=$(stat -f%z "$OUTPUT_FILE" 2>/dev/null || stat -c%s "$OUTPUT_FILE" 2>/dev/null)
if [ $? -eq 0 ] && [ $ORIGINAL_SIZE -gt 0 ]; then
REDUCTION_PERCENTAGE=$(( (ORIGINAL_SIZE - NEW_SIZE) * 100 / ORIGINAL_SIZE ))
print_status "Final size reduction: ${REDUCTION_PERCENTAGE}%"
fi
fi

View file

@ -1,143 +0,0 @@
const fs = require('fs');
const path = require('path');
// Improved script with better error handling and focused head tag processing
function replaceAssets() {
const file = path.resolve(__dirname, '..', 'dist', 'index.html');
// Check if dist/index.html exists
if (!fs.existsSync(file)) {
console.error('Error: dist/index.html not found');
process.exit(1);
}
try {
let html = fs.readFileSync(file, 'utf8');
console.log('Original HTML loaded successfully');
// Extract the head section
const headMatch = html.match(/(<head[^>]*>)([\s\S]*?)(<\/head>)/i);
if (!headMatch) {
console.error('Error: Could not find <head> tag in HTML');
process.exit(1);
}
const [fullHeadTag, headStart, headContent, headEnd] = headMatch;
console.log('Head section found, processing assets...');
let updatedHeadContent = headContent;
let cssReplaced = 0;
let jsReplaced = 0;
// Compute simple query hash for cache-busting if files exist
const cssMinPath = path.resolve(__dirname, '..', 'dist', 'css', 'styles-min.css');
const jsMinPath = path.resolve(__dirname, '..', 'dist', 'js', 'app-min.js');
const safeHash = (p) => {
try {
const buf = fs.readFileSync(p);
let hash = 0;
for (let i = 0; i < buf.length; i += Math.ceil(buf.length / 128) || 1) {
hash = (hash * 31 + buf[i]) >>> 0;
}
return hash.toString(36);
} catch {
return null;
}
};
const cssHash = safeHash(cssMinPath);
const jsHash = safeHash(jsMinPath);
const cssTarget = cssHash ? `href="/css/styles-min.css?v=${cssHash}"` : 'href="/css/styles-min.css"';
const jsTarget = jsHash ? `src="/js/app-min.js?v=${jsHash}"` : 'src="/js/app-min.js"';
// Normalize all stylesheet/script/preload references to minified assets with one hash.
const cssHrefPattern = /href=["'](?:\.\/|\/)?css\/(?:styles|styles-min)\.css(?:\?[^"']*)?["']/g;
const jsSrcPattern = /src=["'](?:\.\/|\/)?js\/(?:app|app-min)\.js(?:\?[^"']*)?["']/g;
const jsHrefPattern = /href=["'](?:\.\/|\/)?js\/(?:app|app-min)\.js(?:\?[^"']*)?["']/g;
const cssMatches = updatedHeadContent.match(cssHrefPattern);
if (cssMatches) {
updatedHeadContent = updatedHeadContent.replace(cssHrefPattern, cssTarget);
cssReplaced += cssMatches.length;
}
const jsSrcHeadMatches = updatedHeadContent.match(jsSrcPattern);
if (jsSrcHeadMatches) {
updatedHeadContent = updatedHeadContent.replace(jsSrcPattern, jsTarget);
jsReplaced += jsSrcHeadMatches.length;
}
// Preload script links use href (not src), so normalize them too.
const jsHrefHeadMatches = updatedHeadContent.match(jsHrefPattern);
if (jsHrefHeadMatches) {
const jsHrefTarget = jsHash ? `href="/js/app-min.js?v=${jsHash}"` : 'href="/js/app-min.js"';
updatedHeadContent = updatedHeadContent.replace(jsHrefPattern, jsHrefTarget);
jsReplaced += jsHrefHeadMatches.length;
}
// Also check for script tags at the end of body (common pattern)
const bodyMatch = html.match(/(<body[^>]*>)([\s\S]*?)(<\/body>)/i);
if (bodyMatch) {
const [fullBodyTag, bodyStart, bodyContent, bodyEnd] = bodyMatch;
let updatedBodyContent = bodyContent;
const jsSrcBodyMatches = updatedBodyContent.match(jsSrcPattern);
if (jsSrcBodyMatches) {
updatedBodyContent = updatedBodyContent.replace(jsSrcPattern, jsTarget);
jsReplaced += jsSrcBodyMatches.length;
}
// Reconstruct the body if changes were made
if (updatedBodyContent !== bodyContent) {
html = html.replace(fullBodyTag, bodyStart + updatedBodyContent + bodyEnd);
}
}
// Reconstruct the HTML with updated head
const updatedHeadTag = headStart + updatedHeadContent + headEnd;
html = html.replace(fullHeadTag, updatedHeadTag);
// Log results
console.log(`CSS replacements made: ${cssReplaced}`);
console.log(`JS replacements made: ${jsReplaced}`);
if (cssReplaced === 0 && jsReplaced === 0) {
console.warn('Warning: No asset links were found to replace');
console.log('Checking for existing patterns in head section:');
// Debug: show what's actually in the head
const linkTags = headContent.match(/<link[^>]*>/gi) || [];
const scriptTags = headContent.match(/<script[^>]*>/gi) || [];
console.log('Found link tags:', linkTags);
console.log('Found script tags:', scriptTags);
} else {
console.log('Asset links replaced successfully');
}
// Write the updated HTML back
fs.writeFileSync(file, html, 'utf8');
console.log('Updated dist/index.html saved');
// Verify the minified files exist
const cssFile = path.resolve(__dirname, '..', 'dist', 'css', 'styles-min.css');
const jsFile = path.resolve(__dirname, '..', 'dist', 'js', 'app-min.js');
if (!fs.existsSync(cssFile)) {
console.warn('Warning: styles-min.css not found - CSS minification may have failed');
} else {
console.log('✓ styles-min.css exists');
}
if (!fs.existsSync(jsFile)) {
console.warn('Warning: app-min.js not found - JS minification may have failed');
} else {
console.log('✓ app-min.js exists');
}
} catch (error) {
console.error('Error processing HTML file:', error.message);
process.exit(1);
}
}
replaceAssets();

View file

@ -1,143 +0,0 @@
module.exports = {
// Base directory - still needed for SW generation
globDirectory: "dist/",
// Explicitly disable precaching for lean SW install
globPatterns: [],
// Enhanced runtime caching strategies
runtimeCaching: [
// 1. Navigation routes (for SPAs) - Network first with offline fallback
{
urlPattern: ({ request }) => request.mode === 'navigate',
handler: 'NetworkFirst',
options: {
cacheName: 'navigation-cache',
networkTimeoutSeconds: 3, // Fallback to cache after 3s
expiration: {
maxEntries: 50,
maxAgeSeconds: 24 * 60 * 60 // 24 hours
},
cacheableResponse: {
statuses: [0, 200] // Cache successful responses
}
}
},
// 2. HTML pages - Network first for fresh content
{
urlPattern: /\.html$/i,
handler: 'NetworkFirst',
options: {
cacheName: 'html-cache',
networkTimeoutSeconds: 2,
expiration: {
maxEntries: 50,
maxAgeSeconds: 12 * 60 * 60 // 12 hours
}
}
},
// 3. JS/CSS - StaleWhileRevalidate with versioning awareness
{
urlPattern: /\.(?:js|css)$/i,
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'static-resources',
expiration: {
maxEntries: 60,
maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days
purgeOnQuotaError: true // Auto-cleanup when storage is full
},
cacheableResponse: {
statuses: [0, 200]
}
}
},
// 4. Images - CacheFirst for performance
{
urlPattern: /\.(?:png|jpg|jpeg|gif|webp|svg|ico)$/i,
handler: 'CacheFirst',
options: {
cacheName: 'image-cache',
expiration: {
maxEntries: 200, // More space for images
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
purgeOnQuotaError: true
},
cacheableResponse: {
statuses: [0, 200]
},
plugins: [
{
handlerDidError: async () => {
// Return fallback image on error (use an existing icon)
return caches.match('/favicon.svg');
}
}
]
}
},
// 5. JSON responses (local and API) - NetworkFirst with timeout
{
urlPattern: ({url}) => /\.json$/i.test(url.pathname) || /\/api\//i.test(url.pathname) || /^https:\/\/api\./i.test(url.href),
handler: 'NetworkFirst',
options: {
cacheName: 'api-cache',
networkTimeoutSeconds: 5,
expiration: {
maxEntries: 100,
maxAgeSeconds: 5 * 60 // 5 minutes for fresh API data
},
cacheableResponse: { statuses: [0, 200] },
matchOptions: {
ignoreSearch: false // Consider query params
}
}
},
// 8. Google Fonts - CacheFirst
{
urlPattern: /^https:\/\/fonts\.(?:googleapis|gstatic)\.com/,
handler: 'CacheFirst',
options: {
cacheName: 'google-fonts',
expiration: {
maxEntries: 30,
maxAgeSeconds: 365 * 24 * 60 * 60 // 1 year
},
cacheableResponse: {
statuses: [0, 200]
}
}
}
],
// Service worker output
swDest: "dist/sw.js",
// Disable sourcemaps in production
sourcemap: false,
// Immediate activation
skipWaiting: true,
clientsClaim: true,
// Additional improvements
cleanupOutdatedCaches: true, // Remove old caches automatically
navigateFallback: null, // No fallback since no precaching
// Ignore specific query parameters
ignoreURLParametersMatching: [
/^utm_/, // Marketing params
/^fbclid$/ // Facebook click ID
],
// Maximum file size to cache (15MB)
maximumFileSizeToCacheInBytes: 15 * 1024 * 1024,
// Mode for generated SW
mode: 'production'
};