diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..06b57d5
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,18 @@
+node_modules
+npm-debug.log
+.DS_Store
+.vscode
+screenshots
+streams_cache
+providers/.cache
+utils/user-config.json
+.env
+.git
+.gitignore
+*.log
+*.md
+!README.md
+tests
+coverage
+.github
+docker-compose.yml
diff --git a/.env_example b/.env_example
deleted file mode 100644
index c0c52bb..0000000
--- a/.env_example
+++ /dev/null
@@ -1,2 +0,0 @@
-TMDB_API_KEY="YOUR_TMDB_API_KEY_HERE"
-PORT=3000
\ No newline at end of file
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..7e0491a
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,3 @@
+node_modules/
+public/
+*.log
diff --git a/.eslintrc.cjs b/.eslintrc.cjs
new file mode 100644
index 0000000..8e68b87
--- /dev/null
+++ b/.eslintrc.cjs
@@ -0,0 +1,23 @@
+module.exports = {
+ root: true,
+ env: {
+ node: true,
+ es2022: true,
+ },
+ parserOptions: {
+ ecmaVersion: 2022,
+ sourceType: 'module',
+ },
+ ignorePatterns: ["public/*"],
+ extends: [
+ 'eslint:recommended'
+ ],
+ rules: {
+ 'no-unused-vars': ['warn', { args: 'none', ignoreRestSiblings: true }],
+ 'no-undef': 'error',
+ 'no-console': 'off',
+ 'prefer-const': 'warn',
+ 'eqeqeq': ['warn', 'smart'],
+ 'no-var': 'warn'
+ }
+};
diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml
new file mode 100644
index 0000000..f64f410
--- /dev/null
+++ b/.github/workflows/docker-publish.yml
@@ -0,0 +1,74 @@
+name: Docker Publish
+
+on:
+ push:
+ branches: [ main, master ]
+ tags: [ 'v*' ]
+ workflow_dispatch:
+
+env:
+ IMAGE_NAME: tmdb-embed-api
+
+jobs:
+ build-and-push:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v3
+
+ - name: Set up Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log in to Docker Hub
+ uses: docker/login-action@v3
+ with:
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
+
+ - name: Extract version
+ id: vars
+ run: |
+ PKG_VERSION=$(node -p "require('./package.json').version")
+ echo "pkg_version=$PKG_VERSION" >> $GITHUB_OUTPUT
+ if [[ $GITHUB_REF == refs/tags/v* ]]; then
+ TAG=${GITHUB_REF#refs/tags/}
+ echo "ref_tag=$TAG" >> $GITHUB_OUTPUT
+ fi
+
+ - name: Build & Push (branch)
+ if: startsWith(github.ref, 'refs/heads/')
+ uses: docker/build-push-action@v5
+ with:
+ context: .
+ push: true
+ platforms: linux/amd64,linux/arm64
+ tags: |
+ ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest
+ ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.vars.outputs.pkg_version }}
+ labels: |
+ org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
+ org.opencontainers.image.revision=${{ github.sha }}
+ org.opencontainers.image.version=${{ steps.vars.outputs.pkg_version }}
+
+ - name: Build & Push (tag)
+ if: startsWith(github.ref, 'refs/tags/v')
+ uses: docker/build-push-action@v5
+ with:
+ context: .
+ push: true
+ platforms: linux/amd64,linux/arm64
+ tags: |
+ ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest
+ ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.vars.outputs.pkg_version }}
+ ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.vars.outputs.ref_tag }}
+ labels: |
+ org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
+ org.opencontainers.image.revision=${{ github.sha }}
+ org.opencontainers.image.version=${{ steps.vars.outputs.pkg_version }}
+ org.opencontainers.image.ref.name=${{ steps.vars.outputs.ref_tag }}
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..7f8329a
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,50 @@
+# Changelog
+
+## [1.0.0] - 2025-09-16
+
+### Added
+- Comprehensive `README.md` (features, endpoints, admin UI overview, screenshots gallery, Docker usage, troubleshooting).
+- `LICENSE` (MIT) file.
+- Multi‑TMDB key rotation support (array of keys; random selection per request).
+- Config override system writing to `utils/user-config.json` with live merged view.
+- Session-based authentication (login, logout, session check, password change) with brute-force mitigation.
+- Rate limiting + exponential lockouts for failed login attempts.
+- Provider status & metrics endpoints: `/api/health`, `/api/metrics`, `/api/status`, `/api/providers`.
+- Stream aggregation endpoints (aggregate + provider-specific) with filtering pipeline.
+- Diagnostics instrumentation (intercept `process.exit`, `beforeExit`, unhandled rejection / exception logging, periodic heartbeat interval).
+- Docker assets: multi-stage `Dockerfile`, `.dockerignore`, `docker-compose.yml` with persistent volume for overrides.
+- GitHub Actions workflow (`.github/workflows/docker-publish.yml`) for automatic multi-arch (amd64+arm64) build & push on branch and tag (`v*`).
+- OCI metadata labels and build argument (`VERSION`) in Docker image.
+- Version + (placeholder) Docker pulls badges in README header.
+- VidSrc extractor refactor: removed direct `process.exit` calls; `main()` now returns status code (safer when required as a module).
+
+### Changed
+- Config normalization now clears legacy single `tmdbApiKey` when `tmdbApiKeys` override is explicitly emptied.
+- Dockerfile slimmed: narrowed COPY set, added labels, build arg, retained only necessary runtime artifacts.
+- `.dockerignore` expanded to reduce build context (`.git`, logs, markdown except README, tests, CI configs, caches, compose file, etc.).
+
+### Removed
+- Deprecated `uhdmovies` provider: code file, registry references, UI toggles, documentation mentions.
+
+### Security
+- Hardened auth flow: session cookies (HttpOnly), no-store headers for admin pages, escalating lockouts against brute force.
+
+### CI / Automation
+- Added multi-arch Docker publish workflow using Buildx & QEMU.
+
+### Documentation
+- Added Docker usage section (local build, compose, multi-key usage, env vars table, healthcheck notes).
+- Added screenshots gallery of admin UI.
+- Updated docs to reflect provider removal and new configuration semantics.
+- Added this `CHANGELOG.md`.
+
+### Developer Experience
+- Heartbeat diagnostic interval to aid investigation of unexpected exits.
+- Intercepted premature `process.exit` calls to avoid silent shutdowns during debugging.
+
+## Historical Context
+This 1.0.0 release consolidates modernization work: provider cleanup, configuration clarity, deployment ergonomics (Docker + CI), security hardening, and observability.
+
+---
+
+[1.0.0]: https://github.com/Inside4ndroid/TMDB-Embed-API/releases/1.0.0
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..137ac6f
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,54 @@
+# ---------- Build Stage ----------
+FROM node:20-alpine AS build
+ARG VERSION=dev
+WORKDIR /app
+
+# Install only production dependencies first (leveraging cache)
+COPY package.json package-lock.json ./
+# Using npm install instead of npm ci because lock file appears out-of-sync
+# If you later regenerate lock (npm install locally) you can revert to npm ci for reproducibility
+RUN npm install --omit=dev
+
+# Copy only required source (avoid sending screenshots, node_modules already installed)
+COPY apiServer.js ./
+COPY providers ./providers
+COPY public ./public
+COPY utils ./utils
+COPY README.md ./
+
+# ---------- Runtime Stage ----------
+FROM node:20-alpine AS runtime
+ARG VERSION=dev
+WORKDIR /app
+ENV NODE_ENV=production \
+ API_PORT=8787 \
+ APP_VERSION=${VERSION}
+
+# Create non-root user
+RUN addgroup -S app && adduser -S app -G app
+
+# Copy node_modules from build and necessary source
+COPY --from=build /app/node_modules ./node_modules
+COPY --from=build /app/apiServer.js ./
+COPY --from=build /app/public ./public
+COPY --from=build /app/providers ./providers
+COPY --from=build /app/utils ./utils
+COPY --from=build /app/package.json ./
+COPY --from=build /app/README.md ./
+
+# Expose port (documentational; runtime can override)
+EXPOSE 8787
+
+USER app
+
+# Labels / metadata
+LABEL org.opencontainers.image.title="TMDB Embed API" \
+ org.opencontainers.image.description="Streaming metadata + source aggregation API with multi-key TMDB rotation" \
+ org.opencontainers.image.version="${VERSION}" \
+ org.opencontainers.image.source="https://github.com/Inside4ndroid/TMDB-Embed-API" \
+ org.opencontainers.image.licenses="MIT"
+
+# Healthcheck (simple)
+HEALTHCHECK --interval=30s --timeout=5s --start-period=20s CMD wget -qO- http://localhost:${API_PORT:-8787}/api/health || exit 1
+
+CMD ["node","apiServer.js"]
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..1e309f9
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 Inside4ndroid
+
+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.
diff --git a/README.md b/README.md
index 1f971f0..0eb3620 100644
--- a/README.md
+++ b/README.md
@@ -1,82 +1,329 @@
-# 🍿🎥✮⋆˙ TMDB Embed API! 🍿🎥✮⋆˙
+# 🍿 TMDB Embed API
-Hello! I'm Inside4ndroid, a passionate Software Developer.
+> Modern, configurable streaming metadata + source aggregation API with a secure admin panel and multi-key TMDB rotation.
-- 🐛 Bugs will be found and squashed as soon as possible please report any isues.
-- 🌱 Currently in a state that works and is recieving updates.
+
+
+
+
+
+
+
---
-## ℹ️ Current Embed Providers ℹ️
+## 📸 Screenshots
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-1. embedsu
-2. 2embed
-3. autoembed
-4. vidsrcsu
+---
-## 🤝 Sponsorship / Donations 🤝
+## ✨ Features
+- **Multi‑TMDB Key Rotation** – Supply multiple API keys; one is chosen randomly per request.
+- **Provider Aggregation** – Pluggable providers (Showbox, 4khdhub, MoviesMod, MP4Hydra, VidZee, Vixsrc, Xprime) with per‑provider enable toggles + default selection.
+- **Dynamic Filtering** – Minimum quality presets, custom JSON quality map, codec exclusion rules (presets + JSON).
+- **Runtime Overrides UI** – Fully interactive web admin at `/` (login protected) writing to `utils/user-config.json`.
+- **Session Auth + Rate Limiting** – Login system with brute‑force lockouts, logout, password change.
+- **Status & Health Panel** – Live metrics, provider status, endpoint list, functional provider checks.
+- **Config Propagation** – Overrides mirrored to `process.env` for legacy compatibility (no `.env` required after first save).
+- **Back‑Navigation Safe** – Cache-control + visibility/session revalidation.
+- **Extensible** – Simple provider registry pattern.
-Your sponsorship is vital in helping me achieve this mission. With your support, I can:
+---
-Dedicate more time to developing and improving my projects
-Cover costs for essential tools, services and premium hosting to run public projects
-Provide detailed documentation and support for users
-Every contribution, no matter the size, makes a significant impact.
+## 📦 Quick Start
+```bash
+# 1. Install dependencies
+npm install
-[Sponsor Me!](https://github.com/sponsors/Inside4ndroid)
+# 2. (Optional) Copy example env if you want an initial TMDB key
+cp .env.example .env # then edit TMDB_API_KEY=
-Thank you for considering supporting my work!
+# 3. Start API (production style)
+node apiServer.js
-### ✨ Usage ✨
+# Or with automatic restarts (if you add a dev script)
+# npm run dev:api
-This is an api for id's provided at [TMDB](https://www.themoviedb.org/).
+# 4. Open the Admin UI (login page) in browser
+http://localhost:8787/
-you must use the ID from the tmdb url like this :
-
-```
-🎬 MOVIES:
-
-single provider - localhost:PORT/movie/{PROVIDER}/{TMDBID}
-all providers - localhost:PORT/movie/{TMDBID}
-
-📺 TV SHOWS:
-
-single provider - localhost:PORT/tv/{PROVIDER}/{TMDBID}?s={SEASON}&e={EPISODE}
-all providers - localhost:PORT/tv/{TMDBID}?s={SEASON}&e={EPISODE}
+# 5. Health check
+curl http://localhost:8787/api/health
```
-## 📋 Providers 📋
+---
-The providers are currently :
+## 🐳 Docker Usage
-```
-embedsu
-2embed
-autoembed
-vidsrcsu
+### Pull & Run (Fastest)
+If you just want to run it (no building):
+```bash
+docker pull inside4ndroid/tmdb-embed-api:latest
+docker run --name tmdb-embed-api -p 8787:8787 \
+ -e TMDB_API_KEY=YOUR_TMDB_KEY \
+ inside4ndroid/tmdb-embed-api:latest
```
-## 🚀 Deployment 🚀
+Persist overrides (Windows PowerShell example) by mounting a local file:
+```powershell
+New-Item -ItemType File -Path .\utils\user-config.json -Force | Out-Null
+docker run --name tmdb-embed-api -p 8787:8787 `
+ -e TMDB_API_KEY=YOUR_TMDB_KEY `
+ -v ${PWD}/utils/user-config.json:/app/utils/user-config.json `
+ inside4ndroid/tmdb-embed-api:latest
+```
-You can self host by doing the following :
+### Build Locally
+```bash
+docker build -t tmdb-embed-api .
+docker run --name tmdb-embed -p 8787:8787 \
+ -e TMDB_API_KEY=YOUR_TMDB_KEY \
+ -v "$(pwd)/utils/user-config.json:/app/utils/user-config.json" \
+ tmdb-embed-api
+```
-1. `git clone https://github.com/Inside4ndroid/TMDB-Embed-API.git`
-2. `cd TMDB-Embed-API`
-3. `rename .env_example to .env`
-4. `edit .env and insert your preferred port and your tmdb api key`
-5. `npm install`
-6. `npm run start`
+After first login + save, the UI writes overrides into the mounted `user-config.json` so they persist across container restarts.
-## Contribute
+### docker-compose
+An example `docker-compose.yml` is included. Start with:
+```bash
+docker compose up -d --build
+```
+Environment variables can be supplied via a `.env` file in the same directory (Compose automatically loads it). Example `.env`:
+```
+TMDB_API_KEY=first_key
+FEBBOX_COOKIES=cookie1,cookie2
+```
-If you know how to code then please dont hesitate to conribute to this project by forking and making pull requests with your new providers or edits etc.
+To stop & remove:
+```bash
+docker compose down
+```
-## ⚠️ WARNING ⚠️
+### Switching to Multiple TMDB Keys
+Either set `TMDB_API_KEYS` to a JSON array string:
+```bash
+docker run -p 8787:8787 \
+ -e TMDB_API_KEYS='["KEY1","KEY2","KEY3"]' \
+ tmdb-embed-api
+```
+or add / remove keys inside the Admin UI (Keys panel) and save.
-Using this without a proxy may lead to your server ip being banned there are 3 ways to get around this :
+### Key Environment Variables
+| Variable | Purpose | Notes |
+|----------|---------|-------|
+| `API_PORT` | Port the server listens on | Defaults to 8787 |
+| `TMDB_API_KEY` | Single TMDB key (legacy) | Use if you only have one key |
+| `TMDB_API_KEYS` | JSON array of keys | Overrides single key when present |
+| `FEBBOX_COOKIES` | Comma separated FebBox cookies | Enables Showbox provider immediately |
+| `PASSWORD_HASH` | Pre-seed admin password hash | Optional (UI can set) |
+| `ADMIN_USERNAME` | Override default username | Default: `admin` |
-1. Use a proxy : [Find One Here](https://github.com/search?q=m3u8+proxy&type=repositories).
-2. Get a server with rotating ip addresses or dynamic ip adresses and use the ips at random.
-3. use a cloudflare proxy worker.
+If both `TMDB_API_KEY` and `TMDB_API_KEYS` are provided, rotation uses the array. Clearing the array in the UI also clears the legacy key.
-Some providers need cloudflare resolving and i am working on a method for this. but using correct headers etc in your network request when playing the media urls should suffice for now.
\ No newline at end of file
+---
+
+### Updating the Image
+```bash
+docker compose pull # if using an external registry (future)
+docker compose up -d --build
+```
+
+### Healthcheck
+Container health relies on `GET /api/health`. If you disable or modify that route, adjust the Dockerfile / compose healthcheck accordingly.
+
+---
+
+## �🔐 Authentication
+The root (`/`) serves the login page. After successful login a session cookie (`session`) is issued (HttpOnly; 12h lifetime). All admin pages (e.g. `config.html`) require an active session.
+
+| Endpoint | Method | Purpose |
+|----------|--------|---------|
+| `/auth/login` | POST | Authenticate (JSON: `{ username, password }`) |
+| `/auth/logout` | POST | Destroy session |
+| `/auth/session` | GET | Check session status |
+| `/auth/change-password` | POST | Update password (requires session) |
+
+Repeated failed logins trigger exponential lockouts (Retry-After header emitted).
+
+---
+
+## 🛠 Configuration Model
+All runtime state collapses into a *merged* object displayed in the UI (Live Config panel). Source order:
+1. Initial environment variables / optional `.env`
+2. JSON overrides: `utils/user-config.json`
+
+Saving in the UI writes only changed keys. Setting a field to empty removes the override (reverting to env/default). Removing all TMDB keys (and saving) clears `tmdbApiKeys` and the legacy `tmdbApiKey`.
+
+**Override File:** `utils/user-config.json`
+```json
+{
+ "defaultProviders": ["showbox","4khdhub"],
+ "tmdbApiKeys": ["KEY_A","KEY_B"],
+ "enableShowboxProvider": true
+}
+```
+
+---
+
+## 🎛 Admin UI Sections
+| Panel | Summary |
+|-------|---------|
+| Core | Port, default providers, default region |
+| Quality / Filters | Min quality presets & codec exclusion JSON |
+| Keys | Add/remove TMDB API keys (rotated randomly) |
+| FebBox / PStream | Manage FebBox cookies powering Showbox provider |
+| Advanced | Provider toggles, cache & validation flags, proxy paths |
+| Server Status | Live metrics, provider functional checks |
+| Live Config | View merged + override JSON snapshots |
+
+Session is revalidated on visibility and back/forward navigation to prevent stale access.
+
+---
+
+## 🔌 Providers
+Current built‑in providers:
+- `showbox`
+- `4khdhub`
+- `moviesmod`
+- `mp4hydra`
+- `vidzee`
+- `vixsrc`
+- `xprime`
+
+You can enable/disable and mark defaults via the Provider Matrix in the UI. If **no defaults** are selected, all enabled providers participate in aggregation.
+
+### Adding a New Provider (Outline)
+1. Create `providers/myprovider.js` exporting an async fetch function (see existing files for patterns).
+2. Lazy‑load it in `providers/registry.js` similar to others.
+3. Add a config flag (`enableMyproviderProvider`) if you want toggle support.
+4. Update the provider matrix arrays in `public/index.js`.
+
+---
+
+## 📡 Key Endpoints
+| Endpoint | Description |
+|----------|-------------|
+| `GET /api/health` | Basic heartbeat |
+| `GET /api/metrics` | Runtime counters & summary |
+| `GET /api/status` | Metrics + providers + endpoints list |
+| `GET /api/providers` | Enabled providers summary |
+| `GET /api/providers/:name` | Single provider status |
+| `GET /api/streams/:type/:tmdbId` | Aggregate streams (`type` = movie|series) |
+| `GET /api/streams/:provider/:type/:tmdbId` | Provider-specific streams |
+| `GET /api/config` | `{ merged, override }` |
+| `POST /api/config` | Apply override patch |
+
+Aggregate endpoint auto-resolves IMDb when needed and merges provider output before filtering.
+
+---
+
+## 🧪 Stream Object Shape (Typical)
+```json
+{
+ "title": "Example Title",
+ "url": "https://...",
+ "quality": "1080p",
+ "provider": "showbox",
+ "size": null,
+ "languages": ["en"],
+ "subtitles": [],
+ "codecs": ["H264"],
+ "headers": { "Referer": "..." }
+}
+```
+
+Filtering passes through `applyFilters` to enforce min quality + codec exclusions.
+
+---
+
+## 🧩 Quality & Codec Filtering
+- Presets: `all`, `480p`, `720p`, `1080p`, `1440p`, `2160p`.
+- Custom quality JSON example:
+```json
+{ "default": "900p", "showbox": "1080p" }
+```
+- Codec exclusion JSON example:
+```json
+{ "excludeDV": true, "excludeHDR": false }
+```
+
+---
+
+## 🔐 Security Notes
+- Admin UI requires login; session cookie is HttpOnly.
+- Cache-control headers disable storing sensitive pages.
+- Login is rate limited with escalating lockouts.
+- Password change endpoint enforces minimum length.
+
+---
+
+## 🚀 Deployment Tips
+| Aspect | Recommendation |
+|--------|---------------|
+| Node Version | 18+ LTS |
+| Reverse Proxy | Terminate TLS (e.g., Nginx) and forward to API port |
+| Persistent Config | Mount / persist `utils/user-config.json` |
+| Logs | Pipe stdout to centralized logger |
+| Scaling | Use a single instance unless providers are CPU bound |
+
+For ephemeral platforms (e.g., Vercel) note that some providers use temporary directories; avoid enabling disk-heavy cache directories.
+
+---
+
+## 💡 Troubleshooting
+| Symptom | Cause / Fix |
+|---------|------------|
+| No streams from Showbox | Missing FebBox cookies |
+| TMDB quota issues | Add more keys under Keys panel |
+| Provider missing in matrix | Ensure its enable flag exists & UI updated |
+| Empty merged config after restart | `user-config.json` deleted or unreadable |
+| Streams low quality | Adjust min quality preset or custom JSON |
+
+---
+
+## 🤝 Contributing
+PRs welcome. Keep changes focused and avoid unrelated formatting churn. For new providers include:
+- A short rationale
+- Retry / timeout safeguards
+- Respect for existing filtering structure
+
+---
+
+## ❤️ Sponsorship
+If this project helps you, consider sponsoring to support continued development & maintenance:
+
+➡️ **GitHub Sponsors:** https://github.com/sponsors/Inside4ndroid
+
+Every contribution accelerates feature delivery & sustainability.
+
+---
+
+## 📜 License
+MIT. See `LICENSE`.
+
+---
+
+## 🙏 Acknowledgements
+Inspired by community scraping/stream aggregation efforts. Credits also to the original NuvioStreamsAddon work for earlier concepts.
+
+---
+
+> *Happy streaming & hacking!* ✨
+
+---
diff --git a/apiServer.js b/apiServer.js
new file mode 100644
index 0000000..3857d39
--- /dev/null
+++ b/apiServer.js
@@ -0,0 +1,365 @@
+require('dotenv').config();
+const express = require('express');
+const cors = require('cors');
+const os = require('os');
+const { config, saveConfigPatch, OVERRIDE_PATH } = require('./utils/config');
+const { authenticate, issueSession, requireAuth, getSession, updatePassword, AUTH_FILE } = require('./utils/auth');
+const path = require('path');
+const { listProviders, getProvider, getCookieStats } = require('./providers/registry');
+const { resolveImdbId } = require('./utils/tmdb');
+const { applyFilters } = require('./utils/streamFilters');
+
+const app = express();
+
+// --- Simple In-Memory Rate Limiting for /auth/login ---
+const loginAttempts = new Map(); // key: ip, value: { count, first, last, lockedUntil }
+const MAX_ATTEMPTS_WINDOW = 5; // attempts allowed
+const WINDOW_MS = 10 * 60 * 1000; // 10 minutes window
+const BASE_LOCK_MS = 5 * 60 * 1000; // 5 minutes base lock
+
+function getClientIp(req){
+ return (req.headers['x-forwarded-for'] || req.connection.remoteAddress || '').split(',')[0].trim();
+}
+
+function recordLoginFailure(ip){
+ const now = Date.now();
+ let entry = loginAttempts.get(ip);
+ if (!entry) {
+ entry = { count:1, first: now, last: now, lockedUntil:0 };
+ loginAttempts.set(ip, entry);
+ return entry;
+ }
+ // Reset window if outside timeframe and not locked
+ if (now - entry.first > WINDOW_MS && now > entry.lockedUntil) {
+ entry.count = 1;
+ entry.first = now;
+ } else {
+ entry.count++;
+ }
+ entry.last = now;
+ if (entry.count > MAX_ATTEMPTS_WINDOW) {
+ // Exponential backoff lock: base * 2^(count - limit)
+ const over = entry.count - MAX_ATTEMPTS_WINDOW;
+ const lockMs = BASE_LOCK_MS * Math.min(8, Math.pow(2, over-1));
+ entry.lockedUntil = now + lockMs;
+ }
+ return entry;
+}
+
+function canAttempt(ip){
+ const entry = loginAttempts.get(ip);
+ if (!entry) return { allowed:true };
+ const now = Date.now();
+ if (entry.lockedUntil && now < entry.lockedUntil) {
+ return { allowed:false, retryAfter: Math.ceil((entry.lockedUntil - now)/1000) };
+ }
+ if (now - entry.first > WINDOW_MS) {
+ // Window passed; reset
+ loginAttempts.delete(ip);
+ return { allowed:true };
+ }
+ return { allowed:true };
+}
+
+function recordLoginSuccess(ip){
+ // On success clear state to avoid lingering count
+ loginAttempts.delete(ip);
+}
+
+// Guard against premature process.exit from imported legacy modules
+process.exit = function(code){
+ console.warn('[diagnostic] Intercepted process.exit with code', code, new Error('exit trace').stack);
+ // keep process alive for debugging
+};
+setImmediate(()=>console.log('[diagnostic] post-start setImmediate fired'));
+app.use(cors());
+app.use(express.json());
+
+// --- Auth Routes (login before static serving) ---
+app.post('/auth/login', (req,res) => {
+ const { username, password } = req.body || {};
+ const ip = getClientIp(req);
+ const attemptState = canAttempt(ip);
+ if (!attemptState.allowed) {
+ res.setHeader('Retry-After', String(attemptState.retryAfter));
+ return res.status(429).json({ success:false, error:'TOO_MANY_ATTEMPTS', retryAfter: attemptState.retryAfter });
+ }
+ if (!username || !password) return res.status(400).json({ success:false, error:'MISSING_CREDENTIALS' });
+ if (!authenticate(username, password)) {
+ const entry = recordLoginFailure(ip);
+ if (entry.lockedUntil && Date.now() < entry.lockedUntil) {
+ const retryAfter = Math.ceil((entry.lockedUntil - Date.now())/1000);
+ res.setHeader('Retry-After', String(retryAfter));
+ return res.status(429).json({ success:false, error:'LOCKED', retryAfter });
+ }
+ return res.status(401).json({ success:false, error:'INVALID_CREDENTIALS', remaining: Math.max(0, MAX_ATTEMPTS_WINDOW - entry.count) });
+ }
+ recordLoginSuccess(ip);
+ const token = issueSession(username);
+ res.setHeader('Set-Cookie', `session=${token}; HttpOnly; SameSite=Lax; Path=/; Max-Age=${12*60*60}`);
+ res.json({ success:true, username });
+});
+
+app.post('/auth/logout', (req,res) => {
+ res.setHeader('Set-Cookie', 'session=; HttpOnly; SameSite=Lax; Path=/; Max-Age=0');
+ res.json({ success:true });
+});
+
+app.get('/auth/session', (req,res) => {
+ const sess = getSession(req);
+ if (!sess) return res.json({ authenticated:false });
+ res.json({ authenticated:true, username: sess.u });
+});
+
+app.post('/auth/change-password', requireAuth, (req,res) => {
+ const { oldPassword, newPassword } = req.body || {};
+ if (!oldPassword || !newPassword) return res.status(400).json({ success:false, error:'MISSING_FIELDS' });
+ const sess = req.session;
+ if (!authenticate(sess.u, oldPassword)) return res.status(401).json({ success:false, error:'INVALID_OLD_PASSWORD' });
+ if (newPassword.length < 8) return res.status(400).json({ success:false, error:'PASSWORD_TOO_SHORT' });
+ if (!updatePassword(sess.u, newPassword)) return res.status(500).json({ success:false, error:'UPDATE_FAILED' });
+ res.json({ success:true, message:'PASSWORD_UPDATED' });
+});
+
+// Protect config panel (HTML) explicitly before static middleware
+app.get('/config.html', (req,res,next) => {
+ const sess = getSession(req);
+ if (!sess) return res.redirect(302, '/');
+ res.setHeader('Cache-Control','no-store, must-revalidate');
+ res.setHeader('Pragma','no-cache');
+ res.setHeader('Expires','0');
+ res.sendFile(path.join(process.cwd(),'public','config.html'));
+});
+
+// Explicit root handler for login page to ensure no-store
+app.get('/', (req,res) => {
+ res.setHeader('Cache-Control','no-store, must-revalidate');
+ res.setHeader('Pragma','no-cache');
+ res.setHeader('Expires','0');
+ res.sendFile(path.join(process.cwd(),'public','index.html'));
+});
+
+// Diagnostics for unexpected exits
+process.on('beforeExit', (code) => {
+ console.log('[diagnostic] beforeExit code=', code);
+});
+process.on('exit', (code) => {
+ console.log('[diagnostic] exit code=', code);
+});
+process.on('uncaughtException', (err) => {
+ console.error('[diagnostic] uncaughtException', err);
+});
+process.on('unhandledRejection', (reason) => {
+ console.error('[diagnostic] unhandledRejection', reason);
+});
+// Periodic heartbeat to confirm event loop activity (can be removed later)
+let hbCount = 0;
+setInterval(()=>{
+ hbCount++;
+ if (hbCount % 6 === 0) { // every 60s if interval is 10s
+ console.log('[diagnostic] heartbeat 60s elapsed, process alive');
+ }
+}, 10_000).unref();
+
+
+// --- Metrics (in-memory) ---
+const metrics = {
+ startTime: Date.now(),
+ requestsTotal: 0,
+ streamRequests: 0,
+ providerCalls: {},
+ lastRequestAt: null,
+ lastError: null,
+ streamsReturned: 0,
+ tmdbToImdbLookups: 0
+};
+
+app.use((req,res,next)=>{ metrics.requestsTotal++; metrics.lastRequestAt = Date.now(); next(); });
+// Serve static UI (login page at /)
+app.use(express.static(path.join(process.cwd(),'public')));
+
+// Config API
+app.get('/api/config', (req,res) => {
+ const fs = require('fs');
+ let override = {};
+ try { if (fs.existsSync(OVERRIDE_PATH)) override = JSON.parse(fs.readFileSync(OVERRIDE_PATH,'utf8')); } catch (e) {
+ // ignore JSON parse or fs errors reading override; return base config
+ }
+ res.json({ success:true, merged: config, override, overridePath: OVERRIDE_PATH });
+});
+app.post('/api/config', (req,res) => {
+ const patch = req.body || {};
+ if (patch.port) {
+ const p = Number(patch.port); if (!Number.isFinite(p) || p<=0 || p>65535) return res.status(400).json({ success:false, error:'INVALID_PORT'});
+ patch.port = p;
+ }
+ if (patch.defaultProviders && !Array.isArray(patch.defaultProviders)) return res.status(400).json({ success:false, error:'DEFAULT_PROVIDERS_NOT_ARRAY'});
+ const ok = saveConfigPatch(patch);
+ res.json({ success: ok, merged: config });
+});
+
+// --- Basic informational endpoints ---
+app.get('/api/health', (req, res) => {
+ res.json({ ok: true, service: 'tmdb-embed-api', time: new Date().toISOString() });
+});
+
+// Metrics endpoint
+app.get('/api/metrics', (req,res) => {
+ res.json({
+ uptimeSeconds: Math.round((Date.now()-metrics.startTime)/1000),
+ requestsTotal: metrics.requestsTotal,
+ streamRequests: metrics.streamRequests,
+ providerCalls: metrics.providerCalls,
+ streamsReturned: metrics.streamsReturned,
+ tmdbToImdbLookups: metrics.tmdbToImdbLookups,
+ lastRequestAt: metrics.lastRequestAt,
+ memoryMB: Math.round(process.memoryUsage().rss/1024/1024),
+ loadAvg: os.loadavg ? os.loadavg() : [],
+ nodeVersion: process.version,
+ configDefaults: {
+ region: config.defaultRegion,
+ providers: config.defaultProviders,
+ minQualities: config.minQualities ? Object.keys(config.minQualities).length : 0,
+ excludeCodecs: config.excludeCodecs ? Object.keys(config.excludeCodecs).filter(k=>config.excludeCodecs[k]).length : 0,
+ febboxCookies: config.febboxCookies.length
+ }
+ });
+});
+
+// Consolidated status (metrics + providers + endpoints)
+app.get('/api/status', (req,res) => {
+ const endpoints = [
+ 'GET /api/health',
+ 'GET /api/metrics',
+ 'GET /api/status',
+ 'GET /api/providers',
+ 'GET /api/providers/:name',
+ 'GET /api/streams/:type/:tmdbId',
+ 'GET /api/streams/:provider/:type/:tmdbId',
+ 'POST /api/config',
+ 'GET /api/config'
+ ];
+ // Determine cookie requirement heuristically (currently Showbox / PStream)
+ const cookieRequiredProviders = new Set(['showbox']);
+ const providers = listProviders().map(p => {
+ const cookieRequired = cookieRequiredProviders.has(p.name);
+ const cookieOk = !cookieRequired || (config.febboxCookies && config.febboxCookies.length > 0);
+ return { name: p.name, enabled: p.enabled, cookieRequired, cookieOk };
+ });
+ res.json({ success:true, metrics: {
+ uptimeSeconds: Math.round((Date.now()-metrics.startTime)/1000),
+ requestsTotal: metrics.requestsTotal,
+ streamRequests: metrics.streamRequests,
+ providerCalls: metrics.providerCalls,
+ streamsReturned: metrics.streamsReturned,
+ tmdbToImdbLookups: metrics.tmdbToImdbLookups,
+ lastRequestAt: metrics.lastRequestAt,
+ memoryMB: Math.round(process.memoryUsage().rss/1024/1024)
+ }, endpoints, providers });
+});
+
+// Providers list
+app.get('/api/providers', (req,res) => {
+ res.json({ success: true, providers: listProviders() });
+});
+
+// Debug environment/config endpoint (do not expose publicly in production)
+app.get('/api/debug/env', (req,res) => {
+ const cookieStats = getCookieStats ? getCookieStats() : null;
+ res.json({
+ port: config.port,
+ defaultProviders: config.defaultProviders,
+ febboxCookieCount: config.febboxCookies.length,
+ showboxCacheDir: process.env.SHOWBOX_CACHE_DIR || '(os tmp)',
+ nodeVersion: process.version,
+ cookieStats
+ });
+});
+
+// Single provider info
+app.get('/api/providers/:name', (req,res) => {
+ const p = getProvider(req.params.name);
+ if (!p) return res.status(404).json({ success:false, error:'PROVIDER_NOT_FOUND' });
+ res.json({ success:true, provider:{ name: p.name, enabled: p.enabled } });
+});
+
+// Aggregate streams across all enabled providers
+app.get('/api/streams/:type/:tmdbId', async (req,res) => {
+ const { type, tmdbId } = req.params;
+ if (!['movie','series'].includes(type)) return res.status(400).json({ success:false, error:'INVALID_TYPE' });
+ const season = req.query.season ? Number(req.query.season) : null;
+ const episode = req.query.episode ? Number(req.query.episode) : null;
+ try {
+ metrics.streamRequests++;
+ const tmdbType = type === 'movie' ? 'movie' : 'tv';
+ const imdbId = await resolveImdbId(tmdbType, tmdbId); if (imdbId) metrics.tmdbToImdbLookups++;
+ const selectedProviders = (config.defaultProviders.length ? config.defaultProviders : listProviders().map(p=>p.name));
+ const providerTimings = {};
+ const results = await Promise.all(selectedProviders.map(async name => {
+ const prov = getProvider(name);
+ if (!prov || !prov.enabled) return [];
+ metrics.providerCalls[name] = (metrics.providerCalls[name]||0)+1;
+ try {
+ console.log(`[api] invoking provider ${name} for tmdbId=${tmdbId}`);
+ const t0 = Date.now();
+ const r = await prov.fetch({ tmdbId, type, season, episode, imdbId, filters:{ } });
+ providerTimings[name] = Date.now()-t0;
+ console.log(`[api] provider ${name} returned ${Array.isArray(r)?r.length:0} streams`);
+ return r;
+ } catch (e) {
+ console.error(`[api] provider ${name} failed:`, e.message);
+ providerTimings[name] = null;
+ return [];
+ }
+ }));
+ let streams = results.flat();
+ streams = applyFilters(streams, 'aggregate', config.minQualities, config.excludeCodecs);
+ metrics.streamsReturned += streams.length;
+ res.json({ success:true, tmdbId, imdbId, count: streams.length, providerTimings, streams });
+ } catch (e) {
+ metrics.lastError = e.message;
+ res.status(500).json({ success:false, error:'INTERNAL_ERROR', message:e.message });
+ }
+});
+
+// Provider-specific streams
+app.get('/api/streams/:provider/:type/:tmdbId', async (req,res) => {
+ const { provider, type, tmdbId } = req.params;
+ if (!['movie','series'].includes(type)) return res.status(400).json({ success:false, error:'INVALID_TYPE' });
+ const season = req.query.season ? Number(req.query.season) : null;
+ const episode = req.query.episode ? Number(req.query.episode) : null;
+ const prov = getProvider(provider);
+ if (!prov) return res.status(404).json({ success:false, error:'PROVIDER_NOT_FOUND' });
+ if (!prov.enabled) return res.status(503).json({ success:false, error:'PROVIDER_DISABLED' });
+ try {
+ metrics.streamRequests++;
+ metrics.providerCalls[prov.name] = (metrics.providerCalls[prov.name]||0)+1;
+ const tmdbType = type === 'movie' ? 'movie' : 'tv';
+ const imdbId = await resolveImdbId(tmdbType, tmdbId); if (imdbId) metrics.tmdbToImdbLookups++;
+ const t0 = Date.now();
+ let streams = await prov.fetch({ tmdbId, type, season, episode, imdbId, filters:{} });
+ const providerTimings = { [prov.name]: Date.now()-t0 };
+ streams = applyFilters(streams, prov.name, config.minQualities, config.excludeCodecs);
+ metrics.streamsReturned += streams.length;
+ res.json({ success:true, provider: prov.name, tmdbId, imdbId, count: streams.length, providerTimings, streams });
+ } catch (e) {
+ metrics.lastError = e.message;
+ res.status(500).json({ success:false, error:'INTERNAL_ERROR', message:e.message });
+ }
+});
+
+const PORT = config.port;
+const server = app.listen(PORT, () => {
+ console.log(`TMDB Embed REST API listening on http://localhost:${PORT}`);
+ console.log('Endpoints:');
+ console.log(' GET /api/health');
+ console.log(' GET /api/metrics');
+ console.log(' GET /api/providers');
+ console.log(' GET /api/streams/:type/:id');
+ console.log(' POST /api/streams/:type/:id');
+ if (!config.febboxCookies || config.febboxCookies.length === 0) {
+ console.warn('[startup][warning] No FEBBOX_COOKIES configured. Showbox / PStream related streams may be unavailable. Set FEBBOX_COOKIES in your environment to enable these sources.');
+ }
+});
+
+server.on('error', (err)=>{ console.error('[diagnostic] server error', err); });
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..f4f316f
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,27 @@
+version: '3.9'
+services:
+ tmdb-embed-api:
+ build: .
+ container_name: tmdb-embed-api
+ environment:
+ # Provide at least one TMDB key (comma separated or override via UI later)
+ - TMDB_API_KEY=${TMDB_API_KEY:-}
+ # Alternative: supply JSON array
+ # - TMDB_API_KEYS=["key1","key2"]
+ - API_PORT=8787
+ # FebBox cookies (comma separated) if you want Showbox immediately functional
+ - FEBBOX_COOKIES=${FEBBOX_COOKIES:-}
+ ports:
+ - "8787:8787"
+ volumes:
+ # Persist runtime overrides (created by the admin UI)
+ - user_config_data:/app/utils/user-config.json
+ restart: unless-stopped
+ healthcheck:
+ test: ["CMD-SHELL", "wget -qO- http://localhost:8787/api/health || exit 1"]
+ interval: 30s
+ timeout: 5s
+ start_period: 20s
+ retries: 3
+volumes:
+ user_config_data:
diff --git a/index.js b/index.js
deleted file mode 100644
index bd0bba2..0000000
--- a/index.js
+++ /dev/null
@@ -1,184 +0,0 @@
-import express from "express";
-import { getMovie, getTv } from './src/api.js';
-import { getMovieFromTmdb, getTvFromTmdb } from './src/workers/tmdb.js';
-import cors from "cors";
-
-const PORT = process.env.PORT;
-const app = express();
-
-app.use(cors());
-
-app.get('/', (req, res) => {
- res.status(200).json({
- INTRO: "Welcome to the TMDB Embed API",
- PROVIDERS: "2embed | embedsu | autoembed | vidsrcsu",
- ROUTES: {
- movie: "/movie/{PROVIDER}/{TMDBID}",
- show: "/tv/{PROVIDER}/{TMDBID}?s={SEASON}&e={EPISODE}",
- all_movie_providers: "/movie/{TMDBID}",
- all_show_providers: "/tv/{TMDBID}?s={SEASON}&e={EPISODE}"
- },
- INFORMATION: "This project is for educational purposes only. We do not host any kind of content. We provide only the links to already available content on the internet. We do not host, upload any videos, films or media files. We are not responsible for the accuracy, compliance, copyright, legality, decency, or any other aspect of the content of other linked sites. If you have any legal issues please contact the appropriate media file owners or host sites.",
- SOURCE: "https://github.com/Inside4ndroid/TMDB-Embed-API"
- });
-});
-
-app.get('/movie/:tmdbId', async (req, res) => {
- if (isNaN(parseInt(req.params.tmdbId))) {
- res.status(405).json({
- error: "Invalid movie id",
- hint: "Check the documentation again to see how to use this endpoint"
- });
- return;
- }
-
- const media = await getMovieFromTmdb(req.params.tmdbId);
-
- if (media instanceof Error) {
- res.status(405).json({ error: media.message });
- return;
- }
-
- let output = await getMovie(media);
-
- if (output === null || output instanceof Error) {
- res.status(404).json({
- error: "No sources fond for this movie.",
- hint: "If you know where to find this movie and know programming feel free to join us on GitHub: https://github.com/Inside4ndroid/TMDB-Embed-API to add it."
- });
- } else {
- res.status(200).json(output);
- }
-});
-
-app.get('/movie/:provider/:tmdbId', async (req, res) => {
- const allowedProviders = ['2embed', 'autoembed', 'embedsu', 'vidsrcsu'];
- if (!allowedProviders.includes(req.params.provider)) {
- res.status(400).json({
- error: "Invalid provider",
- hint: `Provider must be one of: ${allowedProviders.join(', ')}`
- });
- return;
- }
-
- if (isNaN(parseInt(req.params.tmdbId))) {
- res.status(400).json({
- error: "Invalid movie id",
- hint: "Check the documentation again to see how to use this endpoint"
- });
- return;
- }
-
- const media = await getMovieFromTmdb(req.params.tmdbId);
-
- if (media instanceof Error) {
- res.status(405).json({ error: media.message });
- return;
- }
-
- let output = await getMovie(media, req.params.provider);
-
- if (output === null || output instanceof Error) {
- res.status(404).json({
- error: "No sources fond for this movie.",
- hint: "If you know where to find this movie and know programming feel free to join us on GitHub: https://github.com/Inside4ndroid/TMDB-Embed-API to add it."
- });
- } else {
- res.status(200).json(output);
- }
-});
-
-app.get('/tv/:tmdbId', async (req, res) => {
- if (!req.params.tmdbId || isNaN(parseInt(req.params.tmdbId)) || !req.query.s || isNaN(parseInt(req.query.s)) || !req.query.e || isNaN(parseInt(req.query.e))) {
- res.status(405).json({
- error: "Invalid show id, season, or episode number",
- hint: "Check the documentation again to see how to use this endpoint"
- });
- return;
- }
-
- const media = await getTvFromTmdb(req.params.tmdbId, req.query.s, req.query.e);
-
- if (media instanceof Error) {
- res.status(405).json({ error: media.message });
- return;
- }
-
- let output = await getTv(media, req.query.s, req.query.e);
-
- if (output === null || output instanceof Error) {
- res.status(404).json({
- error: "No sources found for this show.",
- hint: "If you know where to find this show and know programming feel free to join us on GitHub: https://github.com/Inside4ndroid/TMDB-Embed-API to add it."
- });
- } else {
- res.status(200).json(output);
- }
-});
-
-app.get('/tv/:provider?/:tmdbId', async (req, res) => {
- const allowedProviders = ['2embed', 'autoembed', 'embedsu', 'vidsrcsu'];
- if (!allowedProviders.includes(req.params.provider)) {
- res.status(400).json({
- error: "Invalid provider",
- hint: `Provider must be one of: ${allowedProviders.join(', ')}`
- });
- return;
- }
-
- if (isNaN(parseInt(req.params.tmdbId))) {
- res.status(400).json({
- error: "Invalid show id",
- hint: "Check the documentation again to see how to use this endpoint",
- });
- return;
- }
-
- if (!req.query.s || isNaN(parseInt(req.query.s)) || !req.query.e || isNaN(parseInt(req.query.e))) {
- return res.status(400).json({
- error: "Invalid season, or episode number",
- hint: "Check the documentation again to see how to use this endpoint"
- });
- }
-
- const media = await getTvFromTmdb(req.params.tmdbId, req.query.s, req.query.e);
-
- if (media instanceof Error) {
- return res.status(405).json({ error: media.message });
- }
-
- let output = await getTv(media, req.query.s, req.query.e, req.params.provider);
-
- if (output === null || output instanceof Error) {
- return res.status(404).json({
- error: "No sources found for this show.",
- hint: "If you know where to find this show and know programming feel free to join us on GitHub: https://github.com/Inside4ndroid/TMDB-Embed-API to add it."
- });
- }
-
- return res.status(200).json(output);
-});
-
-app.get('/movie/', (req, res) => {
- res.status(405).json({
- error: "Invalid movie id",
- hint: "Check the documentation again to see how to use this endpoint"
- });
-});
-
-app.get('/tv/', (req, res) => {
- res.status(405).json({
- error: "Invalid show id",
- hint: "Check the documentation again to see how to use this endpoint"
- });
-});
-
-app.get('*', (req, res) => {
- res.status(404).json({ error: 'Not found', hint: 'Go to /' });
-});
-
-export const server = app.listen(PORT, () => {
- console.log(`Server is running on port http://localhost:${PORT}`);
-});
-
-export default app;
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 18175f9..8d62993 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7,2279 +7,465 @@
"": {
"name": "tmdb-embed-api",
"version": "1.0.0",
- "license": "ISC",
"dependencies": {
+ "aromanize": "^0.1.5",
+ "axios": "^1.9.0",
+ "axios-cookiejar-support": "^6.0.2",
+ "body-parser": "^2.2.0",
"cheerio": "^1.0.0",
"cors": "^2.8.5",
- "dotenv": "^16.4.7",
- "express": "^4.18.2",
- "node-fetch": "^3.3.2"
+ "crypto-js": "^4.2.0",
+ "dotenv": "^16.5.0",
+ "express": "^4.21.2",
+ "form-data": "^4.0.3",
+ "hls-parser": "^0.13.5",
+ "jsdom": "^26.1.0",
+ "node-fetch": "^2.7.0",
+ "p-limit": "^6.2.0",
+ "puppeteer": "^24.11.0",
+ "string-similarity": "^4.0.4",
+ "tough-cookie": "^5.1.2",
+ "ttl-cache": "^1.0.2",
+ "vm2": "^3.9.19",
+ "yargs": "^17.7.2"
},
"devDependencies": {
- "@babel/core": "^7.26.10",
- "@babel/preset-env": "^7.26.9",
- "cross-env": "^7.0.3",
- "jest": "^29.7.0",
- "jest-extended": "^3.2.4",
- "jest-junit": "^15.0.0",
- "supertest": "^7.1.0"
- }
- },
- "node_modules/@ampproject/remapping": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
- "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
+ "eslint": "^8.57.0",
+ "nodemon": "^3.1.10"
},
"engines": {
- "node": ">=6.0.0"
+ "node": ">=14.0.0"
}
},
+ "node_modules/@asamuzakjp/css-color": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz",
+ "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==",
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/css-calc": "^2.1.3",
+ "@csstools/css-color-parser": "^3.0.9",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "lru-cache": "^10.4.3"
+ }
+ },
+ "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "license": "ISC"
+ },
"node_modules/@babel/code-frame": {
- "version": "7.26.2",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
- "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
- "dev": true,
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
"license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.27.1",
"js-tokens": "^4.0.0",
- "picocolors": "^1.0.0"
+ "picocolors": "^1.1.1"
},
"engines": {
"node": ">=6.9.0"
}
},
- "node_modules/@babel/compat-data": {
- "version": "7.26.8",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz",
- "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/core": {
- "version": "7.26.10",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz",
- "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.26.2",
- "@babel/generator": "^7.26.10",
- "@babel/helper-compilation-targets": "^7.26.5",
- "@babel/helper-module-transforms": "^7.26.0",
- "@babel/helpers": "^7.26.10",
- "@babel/parser": "^7.26.10",
- "@babel/template": "^7.26.9",
- "@babel/traverse": "^7.26.10",
- "@babel/types": "^7.26.10",
- "convert-source-map": "^2.0.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.3",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/babel"
- }
- },
- "node_modules/@babel/generator": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz",
- "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.27.0",
- "@babel/types": "^7.27.0",
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.25",
- "jsesc": "^3.0.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-annotate-as-pure": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
- "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz",
- "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/compat-data": "^7.26.8",
- "@babel/helper-validator-option": "^7.25.9",
- "browserslist": "^4.24.0",
- "lru-cache": "^5.1.1",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-create-class-features-plugin": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.0.tgz",
- "integrity": "sha512-vSGCvMecvFCd/BdpGlhpXYNhhC4ccxyvQWpbGL4CWbvfEoLFWUZuSuf7s9Aw70flgQF+6vptvgK2IfOnKlRmBg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.25.9",
- "@babel/helper-member-expression-to-functions": "^7.25.9",
- "@babel/helper-optimise-call-expression": "^7.25.9",
- "@babel/helper-replace-supers": "^7.26.5",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
- "@babel/traverse": "^7.27.0",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-create-regexp-features-plugin": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.0.tgz",
- "integrity": "sha512-fO8l08T76v48BhpNRW/nQ0MxfnSdoSKUJBMjubOAYffsVuGG5qOfMq7N6Es7UJvi7Y8goXXo07EfcHZXDPuELQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.25.9",
- "regexpu-core": "^6.2.0",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-define-polyfill-provider": {
- "version": "0.6.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz",
- "integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-compilation-targets": "^7.22.6",
- "@babel/helper-plugin-utils": "^7.22.5",
- "debug": "^4.1.1",
- "lodash.debounce": "^4.0.8",
- "resolve": "^1.14.2"
- },
- "peerDependencies": {
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
- }
- },
- "node_modules/@babel/helper-member-expression-to-functions": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz",
- "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.25.9",
- "@babel/types": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-imports": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
- "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.25.9",
- "@babel/types": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-transforms": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
- "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-imports": "^7.25.9",
- "@babel/helper-validator-identifier": "^7.25.9",
- "@babel/traverse": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-optimise-call-expression": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz",
- "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-plugin-utils": {
- "version": "7.26.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz",
- "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-remap-async-to-generator": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz",
- "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.25.9",
- "@babel/helper-wrap-function": "^7.25.9",
- "@babel/traverse": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-replace-supers": {
- "version": "7.26.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz",
- "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-member-expression-to-functions": "^7.25.9",
- "@babel/helper-optimise-call-expression": "^7.25.9",
- "@babel/traverse": "^7.26.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz",
- "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.25.9",
- "@babel/types": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
- "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
- "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
- "dev": true,
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
+ "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
- "node_modules/@babel/helper-validator-option": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
- "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@csstools/color-helpers": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz",
+ "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
"engines": {
- "node": ">=6.9.0"
+ "node": ">=18"
}
},
- "node_modules/@babel/helper-wrap-function": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz",
- "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==",
- "dev": true,
+ "node_modules/@csstools/css-calc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz",
+ "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-color-parser": {
+ "version": "3.0.10",
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.10.tgz",
+ "integrity": "sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
"license": "MIT",
"dependencies": {
- "@babel/template": "^7.25.9",
- "@babel/traverse": "^7.25.9",
- "@babel/types": "^7.25.9"
+ "@csstools/color-helpers": "^5.0.2",
+ "@csstools/css-calc": "^2.1.4"
},
"engines": {
- "node": ">=6.9.0"
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
}
},
- "node_modules/@babel/helpers": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz",
- "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==",
+ "node_modules/@csstools/css-parser-algorithms": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz",
+ "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-tokenizer": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz",
+ "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
+ "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/template": "^7.27.0",
- "@babel/types": "^7.27.0"
+ "eslint-visitor-keys": "^3.4.3"
},
"engines": {
- "node": ">=6.9.0"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
}
},
- "node_modules/@babel/parser": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz",
- "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==",
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+ "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.27.0"
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@eslint/js": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
+ "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
+ "deprecated": "Use @eslint/config-array instead",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^2.0.3",
+ "debug": "^4.3.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@humanwhocodes/config-array/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@puppeteer/browsers": {
+ "version": "2.10.5",
+ "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.5.tgz",
+ "integrity": "sha512-eifa0o+i8dERnngJwKrfp3dEq7ia5XFyoqB17S4gK8GhsQE4/P8nxOfQSE0zQHxzzLo/cmF+7+ywEQ7wK7Fb+w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "debug": "^4.4.1",
+ "extract-zip": "^2.0.1",
+ "progress": "^2.0.3",
+ "proxy-agent": "^6.5.0",
+ "semver": "^7.7.2",
+ "tar-fs": "^3.0.8",
+ "yargs": "^17.7.2"
},
"bin": {
- "parser": "bin/babel-parser.js"
+ "browsers": "lib/cjs/main-cli.js"
},
"engines": {
- "node": ">=6.0.0"
+ "node": ">=18"
}
},
- "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz",
- "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==",
- "dev": true,
+ "node_modules/@puppeteer/browsers/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9",
- "@babel/traverse": "^7.25.9"
+ "ms": "^2.1.3"
},
"engines": {
- "node": ">=6.9.0"
+ "node": ">=6.0"
},
- "peerDependencies": {
- "@babel/core": "^7.0.0"
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
}
},
- "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz",
- "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz",
- "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz",
- "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
- "@babel/plugin-transform-optional-chaining": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.13.0"
- }
- },
- "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz",
- "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9",
- "@babel/traverse": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/plugin-proposal-private-property-in-object": {
- "version": "7.21.0-placeholder-for-preset-env.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
- "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-async-generators": {
- "version": "7.8.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
- "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-bigint": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
- "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-class-properties": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
- "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.12.13"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-class-static-block": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
- "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-import-assertions": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz",
- "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-import-attributes": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
- "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-import-meta": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
- "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-json-strings": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
- "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-jsx": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz",
- "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
- "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
- "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-numeric-separator": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
- "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-object-rest-spread": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
- "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-optional-catch-binding": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
- "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-optional-chaining": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
- "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-private-property-in-object": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
- "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-top-level-await": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
- "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-typescript": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz",
- "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-unicode-sets-regex": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
- "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/plugin-transform-arrow-functions": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz",
- "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-async-generator-functions": {
- "version": "7.26.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz",
- "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.26.5",
- "@babel/helper-remap-async-to-generator": "^7.25.9",
- "@babel/traverse": "^7.26.8"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-async-to-generator": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz",
- "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-imports": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9",
- "@babel/helper-remap-async-to-generator": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-block-scoped-functions": {
- "version": "7.26.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz",
- "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.26.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-block-scoping": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.0.tgz",
- "integrity": "sha512-u1jGphZ8uDI2Pj/HJj6YQ6XQLZCNjOlprjxB5SVz6rq2T6SwAR+CdrWK0CP7F+9rDVMXdB0+r6Am5G5aobOjAQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.26.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-class-properties": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz",
- "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-class-static-block": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz",
- "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.12.0"
- }
- },
- "node_modules/@babel/plugin-transform-classes": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz",
- "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.25.9",
- "@babel/helper-compilation-targets": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9",
- "@babel/helper-replace-supers": "^7.25.9",
- "@babel/traverse": "^7.25.9",
- "globals": "^11.1.0"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-computed-properties": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz",
- "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9",
- "@babel/template": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-destructuring": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz",
- "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-dotall-regex": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz",
- "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-duplicate-keys": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz",
- "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz",
- "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/plugin-transform-dynamic-import": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz",
- "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-exponentiation-operator": {
- "version": "7.26.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz",
- "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-export-namespace-from": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz",
- "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-for-of": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.26.9.tgz",
- "integrity": "sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.26.5",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-function-name": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz",
- "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-compilation-targets": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9",
- "@babel/traverse": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-json-strings": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz",
- "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-literals": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz",
- "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-logical-assignment-operators": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz",
- "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-member-expression-literals": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz",
- "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-modules-amd": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz",
- "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-transforms": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-modules-commonjs": {
- "version": "7.26.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz",
- "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-transforms": "^7.26.0",
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-modules-systemjs": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz",
- "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-transforms": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9",
- "@babel/helper-validator-identifier": "^7.25.9",
- "@babel/traverse": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-modules-umd": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz",
- "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-transforms": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz",
- "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/plugin-transform-new-target": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz",
- "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
- "version": "7.26.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz",
- "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.26.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-numeric-separator": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz",
- "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-object-rest-spread": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz",
- "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-compilation-targets": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9",
- "@babel/plugin-transform-parameters": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-object-super": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz",
- "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9",
- "@babel/helper-replace-supers": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-optional-catch-binding": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz",
- "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-optional-chaining": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz",
- "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-parameters": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz",
- "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-private-methods": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz",
- "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-private-property-in-object": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz",
- "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.25.9",
- "@babel/helper-create-class-features-plugin": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-property-literals": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz",
- "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-regenerator": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.0.tgz",
- "integrity": "sha512-LX/vCajUJQDqE7Aum/ELUMZAY19+cDpghxrnyt5I1tV6X5PyC86AOoWXWFYFeIvauyeSA6/ktn4tQVn/3ZifsA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.26.5",
- "regenerator-transform": "^0.15.2"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-regexp-modifiers": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz",
- "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/plugin-transform-reserved-words": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz",
- "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-shorthand-properties": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz",
- "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-spread": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz",
- "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-sticky-regex": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz",
- "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-template-literals": {
- "version": "7.26.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.26.8.tgz",
- "integrity": "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.26.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-typeof-symbol": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.0.tgz",
- "integrity": "sha512-+LLkxA9rKJpNoGsbLnAgOCdESl73vwYn+V6b+5wHbrE7OGKVDPHIQvbFSzqE6rwqaCw2RE+zdJrlLkcf8YOA0w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.26.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-unicode-escapes": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz",
- "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-unicode-property-regex": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz",
- "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-unicode-regex": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz",
- "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-unicode-sets-regex": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz",
- "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/preset-env": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.9.tgz",
- "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/compat-data": "^7.26.8",
- "@babel/helper-compilation-targets": "^7.26.5",
- "@babel/helper-plugin-utils": "^7.26.5",
- "@babel/helper-validator-option": "^7.25.9",
- "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9",
- "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9",
- "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9",
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9",
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9",
- "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
- "@babel/plugin-syntax-import-assertions": "^7.26.0",
- "@babel/plugin-syntax-import-attributes": "^7.26.0",
- "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
- "@babel/plugin-transform-arrow-functions": "^7.25.9",
- "@babel/plugin-transform-async-generator-functions": "^7.26.8",
- "@babel/plugin-transform-async-to-generator": "^7.25.9",
- "@babel/plugin-transform-block-scoped-functions": "^7.26.5",
- "@babel/plugin-transform-block-scoping": "^7.25.9",
- "@babel/plugin-transform-class-properties": "^7.25.9",
- "@babel/plugin-transform-class-static-block": "^7.26.0",
- "@babel/plugin-transform-classes": "^7.25.9",
- "@babel/plugin-transform-computed-properties": "^7.25.9",
- "@babel/plugin-transform-destructuring": "^7.25.9",
- "@babel/plugin-transform-dotall-regex": "^7.25.9",
- "@babel/plugin-transform-duplicate-keys": "^7.25.9",
- "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9",
- "@babel/plugin-transform-dynamic-import": "^7.25.9",
- "@babel/plugin-transform-exponentiation-operator": "^7.26.3",
- "@babel/plugin-transform-export-namespace-from": "^7.25.9",
- "@babel/plugin-transform-for-of": "^7.26.9",
- "@babel/plugin-transform-function-name": "^7.25.9",
- "@babel/plugin-transform-json-strings": "^7.25.9",
- "@babel/plugin-transform-literals": "^7.25.9",
- "@babel/plugin-transform-logical-assignment-operators": "^7.25.9",
- "@babel/plugin-transform-member-expression-literals": "^7.25.9",
- "@babel/plugin-transform-modules-amd": "^7.25.9",
- "@babel/plugin-transform-modules-commonjs": "^7.26.3",
- "@babel/plugin-transform-modules-systemjs": "^7.25.9",
- "@babel/plugin-transform-modules-umd": "^7.25.9",
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9",
- "@babel/plugin-transform-new-target": "^7.25.9",
- "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6",
- "@babel/plugin-transform-numeric-separator": "^7.25.9",
- "@babel/plugin-transform-object-rest-spread": "^7.25.9",
- "@babel/plugin-transform-object-super": "^7.25.9",
- "@babel/plugin-transform-optional-catch-binding": "^7.25.9",
- "@babel/plugin-transform-optional-chaining": "^7.25.9",
- "@babel/plugin-transform-parameters": "^7.25.9",
- "@babel/plugin-transform-private-methods": "^7.25.9",
- "@babel/plugin-transform-private-property-in-object": "^7.25.9",
- "@babel/plugin-transform-property-literals": "^7.25.9",
- "@babel/plugin-transform-regenerator": "^7.25.9",
- "@babel/plugin-transform-regexp-modifiers": "^7.26.0",
- "@babel/plugin-transform-reserved-words": "^7.25.9",
- "@babel/plugin-transform-shorthand-properties": "^7.25.9",
- "@babel/plugin-transform-spread": "^7.25.9",
- "@babel/plugin-transform-sticky-regex": "^7.25.9",
- "@babel/plugin-transform-template-literals": "^7.26.8",
- "@babel/plugin-transform-typeof-symbol": "^7.26.7",
- "@babel/plugin-transform-unicode-escapes": "^7.25.9",
- "@babel/plugin-transform-unicode-property-regex": "^7.25.9",
- "@babel/plugin-transform-unicode-regex": "^7.25.9",
- "@babel/plugin-transform-unicode-sets-regex": "^7.25.9",
- "@babel/preset-modules": "0.1.6-no-external-plugins",
- "babel-plugin-polyfill-corejs2": "^0.4.10",
- "babel-plugin-polyfill-corejs3": "^0.11.0",
- "babel-plugin-polyfill-regenerator": "^0.6.1",
- "core-js-compat": "^3.40.0",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/preset-modules": {
- "version": "0.1.6-no-external-plugins",
- "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
- "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.0.0",
- "@babel/types": "^7.4.4",
- "esutils": "^2.0.2"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0"
- }
- },
- "node_modules/@babel/runtime": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
- "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "regenerator-runtime": "^0.14.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/template": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz",
- "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.26.2",
- "@babel/parser": "^7.27.0",
- "@babel/types": "^7.27.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz",
- "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.26.2",
- "@babel/generator": "^7.27.0",
- "@babel/parser": "^7.27.0",
- "@babel/template": "^7.27.0",
- "@babel/types": "^7.27.0",
- "debug": "^4.3.1",
- "globals": "^11.1.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz",
- "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-string-parser": "^7.25.9",
- "@babel/helper-validator-identifier": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@bcoe/v8-coverage": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
- "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
- "dev": true,
+ "node_modules/@puppeteer/browsers/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
- "node_modules/@istanbuljs/load-nyc-config": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
- "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
- "dev": true,
+ "node_modules/@puppeteer/browsers/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"license": "ISC",
- "dependencies": {
- "camelcase": "^5.3.1",
- "find-up": "^4.1.0",
- "get-package-type": "^0.1.0",
- "js-yaml": "^3.13.1",
- "resolve-from": "^5.0.0"
+ "bin": {
+ "semver": "bin/semver.js"
},
"engines": {
- "node": ">=8"
+ "node": ">=10"
}
},
- "node_modules/@istanbuljs/schema": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
- "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/console": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz",
- "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "jest-message-util": "^29.7.0",
- "jest-util": "^29.7.0",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/core": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz",
- "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/console": "^29.7.0",
- "@jest/reporters": "^29.7.0",
- "@jest/test-result": "^29.7.0",
- "@jest/transform": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "ansi-escapes": "^4.2.1",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "exit": "^0.1.2",
- "graceful-fs": "^4.2.9",
- "jest-changed-files": "^29.7.0",
- "jest-config": "^29.7.0",
- "jest-haste-map": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-regex-util": "^29.6.3",
- "jest-resolve": "^29.7.0",
- "jest-resolve-dependencies": "^29.7.0",
- "jest-runner": "^29.7.0",
- "jest-runtime": "^29.7.0",
- "jest-snapshot": "^29.7.0",
- "jest-util": "^29.7.0",
- "jest-validate": "^29.7.0",
- "jest-watcher": "^29.7.0",
- "micromatch": "^4.0.4",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
- },
- "peerDependenciesMeta": {
- "node-notifier": {
- "optional": true
- }
- }
- },
- "node_modules/@jest/environment": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz",
- "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/fake-timers": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "jest-mock": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/expect": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz",
- "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "expect": "^29.7.0",
- "jest-snapshot": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/expect-utils": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz",
- "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "jest-get-type": "^29.6.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/fake-timers": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz",
- "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "@sinonjs/fake-timers": "^10.0.2",
- "@types/node": "*",
- "jest-message-util": "^29.7.0",
- "jest-mock": "^29.7.0",
- "jest-util": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/globals": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz",
- "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/environment": "^29.7.0",
- "@jest/expect": "^29.7.0",
- "@jest/types": "^29.6.3",
- "jest-mock": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/reporters": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz",
- "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@bcoe/v8-coverage": "^0.2.3",
- "@jest/console": "^29.7.0",
- "@jest/test-result": "^29.7.0",
- "@jest/transform": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@jridgewell/trace-mapping": "^0.3.18",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "collect-v8-coverage": "^1.0.0",
- "exit": "^0.1.2",
- "glob": "^7.1.3",
- "graceful-fs": "^4.2.9",
- "istanbul-lib-coverage": "^3.0.0",
- "istanbul-lib-instrument": "^6.0.0",
- "istanbul-lib-report": "^3.0.0",
- "istanbul-lib-source-maps": "^4.0.0",
- "istanbul-reports": "^3.1.3",
- "jest-message-util": "^29.7.0",
- "jest-util": "^29.7.0",
- "jest-worker": "^29.7.0",
- "slash": "^3.0.0",
- "string-length": "^4.0.1",
- "strip-ansi": "^6.0.0",
- "v8-to-istanbul": "^9.0.1"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
- },
- "peerDependenciesMeta": {
- "node-notifier": {
- "optional": true
- }
- }
- },
- "node_modules/@jest/schemas": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
- "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.27.8"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/source-map": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz",
- "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/trace-mapping": "^0.3.18",
- "callsites": "^3.0.0",
- "graceful-fs": "^4.2.9"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/test-result": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz",
- "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/console": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/istanbul-lib-coverage": "^2.0.0",
- "collect-v8-coverage": "^1.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/test-sequencer": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz",
- "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/test-result": "^29.7.0",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.7.0",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/transform": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz",
- "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.11.6",
- "@jest/types": "^29.6.3",
- "@jridgewell/trace-mapping": "^0.3.18",
- "babel-plugin-istanbul": "^6.1.1",
- "chalk": "^4.0.0",
- "convert-source-map": "^2.0.0",
- "fast-json-stable-stringify": "^2.1.0",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.7.0",
- "jest-regex-util": "^29.6.3",
- "jest-util": "^29.7.0",
- "micromatch": "^4.0.4",
- "pirates": "^4.0.4",
- "slash": "^3.0.0",
- "write-file-atomic": "^4.0.2"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/types": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
- "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^3.0.0",
- "@types/node": "*",
- "@types/yargs": "^17.0.8",
- "chalk": "^4.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.8",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
- "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/set-array": "^1.2.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/set-array": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
- "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
- "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
- "dev": true,
+ "node_modules/@tootallnate/quickjs-emscripten": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
+ "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==",
"license": "MIT"
},
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.25",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
- "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
- "dev": true,
+ "node_modules/@types/node": {
+ "version": "24.0.4",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.4.tgz",
+ "integrity": "sha512-ulyqAkrhnuNq9pB76DRBTkcS6YsmDALy6Ua63V8OhrOBgbcYt6IOdzpw5P1+dyRIyMerzLkeYWBeOXPpA9GMAA==",
"license": "MIT",
+ "optional": true,
"dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
+ "undici-types": "~7.8.0"
}
},
- "node_modules/@sinclair/typebox": {
- "version": "0.27.8",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
- "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@sinonjs/commons": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
- "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "type-detect": "4.0.8"
- }
- },
- "node_modules/@sinonjs/fake-timers": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
- "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@sinonjs/commons": "^3.0.0"
- }
- },
- "node_modules/@types/babel__core": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
- "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.20.7",
- "@babel/types": "^7.20.7",
- "@types/babel__generator": "*",
- "@types/babel__template": "*",
- "@types/babel__traverse": "*"
- }
- },
- "node_modules/@types/babel__generator": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
- "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.0.0"
- }
- },
- "node_modules/@types/babel__template": {
- "version": "7.4.4",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
- "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.1.0",
- "@babel/types": "^7.0.0"
- }
- },
- "node_modules/@types/babel__traverse": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz",
- "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.20.7"
- }
- },
- "node_modules/@types/graceful-fs": {
- "version": "4.1.9",
- "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
- "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==",
- "dev": true,
+ "node_modules/@types/yauzl": {
+ "version": "2.10.3",
+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
+ "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
"license": "MIT",
+ "optional": true,
"dependencies": {
"@types/node": "*"
}
},
- "node_modules/@types/istanbul-lib-coverage": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
- "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
+ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
"dev": true,
- "license": "MIT"
- },
- "node_modules/@types/istanbul-lib-report": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
- "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/istanbul-lib-coverage": "*"
- }
- },
- "node_modules/@types/istanbul-reports": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
- "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/istanbul-lib-report": "*"
- }
- },
- "node_modules/@types/node": {
- "version": "22.14.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz",
- "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "undici-types": "~6.21.0"
- }
- },
- "node_modules/@types/stack-utils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
- "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/yargs": {
- "version": "17.0.33",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
- "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/yargs-parser": "*"
- }
- },
- "node_modules/@types/yargs-parser": {
- "version": "21.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
- "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
- "dev": true,
- "license": "MIT"
+ "license": "ISC"
},
"node_modules/accepts": {
"version": "1.3.8",
@@ -2294,27 +480,70 @@
"node": ">= 0.6"
}
},
- "node_modules/ansi-escapes": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
- "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.3.4",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
+ "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.11.0"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
+ "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "type-fest": "^0.21.3"
- },
- "engines": {
- "node": ">=8"
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -2324,7 +553,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
@@ -2351,14 +579,16 @@
}
},
"node_modules/argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "sprintf-js": "~1.0.2"
- }
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "license": "Python-2.0"
+ },
+ "node_modules/aromanize": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/aromanize/-/aromanize-0.1.5.tgz",
+ "integrity": "sha512-fyFsbmpocja8wnYuYjwt2k7WRkBZftZKDDmLgX9tclV94TRn7b29skxU66tTDInNFZ3MwITPdNvb8bLg2rbbDA==",
+ "license": "MIT"
},
"node_modules/array-flatten": {
"version": "1.1.1",
@@ -2366,177 +596,89 @@
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
"license": "MIT"
},
- "node_modules/asap": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
- "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
- "dev": true,
- "license": "MIT"
+ "node_modules/ast-types": {
+ "version": "0.13.4",
+ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
+ "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ast-types/node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
- "dev": true,
"license": "MIT"
},
- "node_modules/babel-jest": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz",
- "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==",
- "dev": true,
+ "node_modules/axios": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
+ "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==",
"license": "MIT",
"dependencies": {
- "@jest/transform": "^29.7.0",
- "@types/babel__core": "^7.1.14",
- "babel-plugin-istanbul": "^6.1.1",
- "babel-preset-jest": "^29.6.3",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "slash": "^3.0.0"
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/axios-cookiejar-support": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/axios-cookiejar-support/-/axios-cookiejar-support-6.0.2.tgz",
+ "integrity": "sha512-UO/g6DKfVoxnZkZz1NN669bMDjGV3snZnAZGZqIwEd8FdvFI17/rXLyMBm1j1cgtb2O6Jyi4MJ7ll49NPBEMNg==",
+ "license": "MIT",
+ "dependencies": {
+ "http-cookie-agent": "^7.0.1"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": ">=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/3846masa"
},
"peerDependencies": {
- "@babel/core": "^7.8.0"
+ "axios": ">=0.20.0",
+ "tough-cookie": ">=4.0.0"
}
},
- "node_modules/babel-plugin-istanbul": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
- "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
- "dev": true,
- "license": "BSD-3-Clause",
+ "node_modules/axios-cookiejar-support/node_modules/http-cookie-agent": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/http-cookie-agent/-/http-cookie-agent-7.0.1.tgz",
+ "integrity": "sha512-lZHFZUdPTw64PdksQac5xbUd4NWjUbyDYnvR//2sbLpcC4UqEUW0x/6O+rDntVzJzJ07QvhtL5XZSC+c5EK+IQ==",
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.0.0",
- "@istanbuljs/load-nyc-config": "^1.0.0",
- "@istanbuljs/schema": "^0.1.2",
- "istanbul-lib-instrument": "^5.0.4",
- "test-exclude": "^6.0.0"
+ "agent-base": "^7.1.3"
},
"engines": {
- "node": ">=8"
- }
- },
- "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
- "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@babel/core": "^7.12.3",
- "@babel/parser": "^7.14.7",
- "@istanbuljs/schema": "^0.1.2",
- "istanbul-lib-coverage": "^3.2.0",
- "semver": "^6.3.0"
+ "node": ">=20.0.0"
},
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/babel-plugin-jest-hoist": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz",
- "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/template": "^7.3.3",
- "@babel/types": "^7.3.3",
- "@types/babel__core": "^7.1.14",
- "@types/babel__traverse": "^7.0.6"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/babel-plugin-polyfill-corejs2": {
- "version": "0.4.13",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz",
- "integrity": "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/compat-data": "^7.22.6",
- "@babel/helper-define-polyfill-provider": "^0.6.4",
- "semver": "^6.3.1"
+ "funding": {
+ "url": "https://github.com/sponsors/3846masa"
},
"peerDependencies": {
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ "tough-cookie": "^4.0.0 || ^5.0.0",
+ "undici": "^7.0.0"
+ },
+ "peerDependenciesMeta": {
+ "undici": {
+ "optional": true
+ }
}
},
- "node_modules/babel-plugin-polyfill-corejs3": {
- "version": "0.11.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz",
- "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.6.3",
- "core-js-compat": "^3.40.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
- }
- },
- "node_modules/babel-plugin-polyfill-regenerator": {
- "version": "0.6.4",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.4.tgz",
- "integrity": "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.6.4"
- },
- "peerDependencies": {
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
- }
- },
- "node_modules/babel-preset-current-node-syntax": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz",
- "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/plugin-syntax-async-generators": "^7.8.4",
- "@babel/plugin-syntax-bigint": "^7.8.3",
- "@babel/plugin-syntax-class-properties": "^7.12.13",
- "@babel/plugin-syntax-class-static-block": "^7.14.5",
- "@babel/plugin-syntax-import-attributes": "^7.24.7",
- "@babel/plugin-syntax-import-meta": "^7.10.4",
- "@babel/plugin-syntax-json-strings": "^7.8.3",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
- "@babel/plugin-syntax-top-level-await": "^7.14.5"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/babel-preset-jest": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz",
- "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "babel-plugin-jest-hoist": "^29.6.3",
- "babel-preset-current-node-syntax": "^1.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
+ "node_modules/b4a": {
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz",
+ "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==",
+ "license": "Apache-2.0"
},
"node_modules/balanced-match": {
"version": "1.0.2",
@@ -2545,57 +687,202 @@
"dev": true,
"license": "MIT"
},
- "node_modules/body-parser": {
- "version": "1.20.3",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
- "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
- "license": "MIT",
+ "node_modules/bare-events": {
+ "version": "2.5.4",
+ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz",
+ "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==",
+ "license": "Apache-2.0",
+ "optional": true
+ },
+ "node_modules/bare-fs": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.5.tgz",
+ "integrity": "sha512-1zccWBMypln0jEE05LzZt+V/8y8AQsQQqxtklqaIyg5nu6OAYFhZxPXinJTSG+kU5qyNmeLgcn9AW7eHiCHVLA==",
+ "license": "Apache-2.0",
+ "optional": true,
"dependencies": {
- "bytes": "3.1.2",
- "content-type": "~1.0.5",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "on-finished": "2.4.1",
- "qs": "6.13.0",
- "raw-body": "2.5.2",
- "type-is": "~1.6.18",
- "unpipe": "1.0.0"
+ "bare-events": "^2.5.4",
+ "bare-path": "^3.0.0",
+ "bare-stream": "^2.6.4"
},
"engines": {
- "node": ">= 0.8",
- "npm": "1.2.8000 || >= 1.4.16"
+ "bare": ">=1.16.0"
+ },
+ "peerDependencies": {
+ "bare-buffer": "*"
+ },
+ "peerDependenciesMeta": {
+ "bare-buffer": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/bare-os": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz",
+ "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "engines": {
+ "bare": ">=1.14.0"
+ }
+ },
+ "node_modules/bare-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz",
+ "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "bare-os": "^3.0.1"
+ }
+ },
+ "node_modules/bare-stream": {
+ "version": "2.6.5",
+ "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz",
+ "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "streamx": "^2.21.0"
+ },
+ "peerDependencies": {
+ "bare-buffer": "*",
+ "bare-events": "*"
+ },
+ "peerDependenciesMeta": {
+ "bare-buffer": {
+ "optional": true
+ },
+ "bare-events": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/basic-ftp": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz",
+ "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/body-parser": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
+ "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "^3.1.2",
+ "content-type": "^1.0.5",
+ "debug": "^4.4.0",
+ "http-errors": "^2.0.0",
+ "iconv-lite": "^0.6.3",
+ "on-finished": "^2.4.1",
+ "qs": "^6.14.0",
+ "raw-body": "^3.0.0",
+ "type-is": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
}
},
"node_modules/body-parser/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
"license": "MIT",
"dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/body-parser/node_modules/iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3"
+ "ms": "^2.1.3"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/body-parser/node_modules/media-typer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/body-parser/node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/body-parser/node_modules/mime-types": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
+ "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "^1.54.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
}
},
"node_modules/body-parser/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
+ "node_modules/body-parser/node_modules/qs": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
+ "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/body-parser/node_modules/type-is": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
+ "license": "MIT",
+ "dependencies": {
+ "content-type": "^1.0.5",
+ "media-typer": "^1.1.0",
+ "mime-types": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
@@ -2603,9 +890,9 @@
"license": "ISC"
},
"node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2626,56 +913,15 @@
"node": ">=8"
}
},
- "node_modules/browserslist": {
- "version": "4.24.4",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
- "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
+ "node_modules/buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
"license": "MIT",
- "dependencies": {
- "caniuse-lite": "^1.0.30001688",
- "electron-to-chromium": "^1.5.73",
- "node-releases": "^2.0.19",
- "update-browserslist-db": "^1.1.1"
- },
- "bin": {
- "browserslist": "cli.js"
- },
"engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ "node": "*"
}
},
- "node_modules/bser": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
- "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "node-int64": "^0.4.0"
- }
- },
- "node_modules/buffer-from": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
- "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@@ -2718,43 +964,11 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
- "node_modules/camelcase": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
- "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/caniuse-lite": {
- "version": "1.0.30001713",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001713.tgz",
- "integrity": "sha512-wCIWIg+A4Xr7NfhTuHdX+/FKh3+Op3LBbSp2N5Pfx6T/LhdQy3GTyoTg48BReaW/MyMNZAkTadsBtai3ldWK0Q==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "CC-BY-4.0"
- },
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -2772,14 +986,27 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "node_modules/char-regex": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
- "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "node_modules/chalk/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=10"
+ "node": ">=8"
+ }
+ },
+ "node_modules/chalk/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
"node_modules/cheerio": {
@@ -2824,34 +1051,48 @@
"url": "https://github.com/sponsors/fb55"
}
},
- "node_modules/ci-info": {
- "version": "3.9.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
- "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/sibiraj-s"
- }
- ],
"license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
"engines": {
- "node": ">=8"
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
}
},
- "node_modules/cjs-module-lexer": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz",
- "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==",
- "dev": true,
- "license": "MIT"
+ "node_modules/chromium-bidi": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-5.1.0.tgz",
+ "integrity": "sha512-9MSRhWRVoRPDG0TgzkHrshFSJJNZzfY5UFqUMuksg7zL1yoZIZ3jLB0YAgHclbiAxPI86pBnwDX1tbzoiV8aFw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "mitt": "^3.0.1",
+ "zod": "^3.24.1"
+ },
+ "peerDependencies": {
+ "devtools-protocol": "*"
+ }
},
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
- "dev": true,
"license": "ISC",
"dependencies": {
"string-width": "^4.2.0",
@@ -2862,29 +1103,33 @@
"node": ">=12"
}
},
- "node_modules/co": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
- "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
- "dev": true,
+ "node_modules/cliui/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"license": "MIT",
"engines": {
- "iojs": ">= 1.0.0",
- "node": ">= 0.12.0"
+ "node": ">=8"
}
},
- "node_modules/collect-v8-coverage": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
- "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==",
- "dev": true,
- "license": "MIT"
+ "node_modules/cliui/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
@@ -2897,14 +1142,12 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true,
"license": "MIT"
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
@@ -2913,16 +1156,6 @@
"node": ">= 0.8"
}
},
- "node_modules/component-emitter": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
- "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -2951,13 +1184,6 @@
"node": ">= 0.6"
}
},
- "node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/cookie": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
@@ -2973,27 +1199,6 @@
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
"license": "MIT"
},
- "node_modules/cookiejar": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
- "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/core-js-compat": {
- "version": "3.41.0",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.41.0.tgz",
- "integrity": "sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "browserslist": "^4.24.4"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/core-js"
- }
- },
"node_modules/cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
@@ -3007,45 +1212,30 @@
"node": ">= 0.10"
}
},
- "node_modules/create-jest": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz",
- "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==",
- "dev": true,
+ "node_modules/cosmiconfig": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
+ "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
"license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
- "chalk": "^4.0.0",
- "exit": "^0.1.2",
- "graceful-fs": "^4.2.9",
- "jest-config": "^29.7.0",
- "jest-util": "^29.7.0",
- "prompts": "^2.0.1"
- },
- "bin": {
- "create-jest": "bin/create-jest.js"
+ "env-paths": "^2.2.1",
+ "import-fresh": "^3.3.0",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.2.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/cross-env": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
- "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cross-spawn": "^7.0.1"
+ "node": ">=14"
},
- "bin": {
- "cross-env": "src/bin/cross-env.js",
- "cross-env-shell": "src/bin/cross-env-shell.js"
+ "funding": {
+ "url": "https://github.com/sponsors/d-fischer"
},
- "engines": {
- "node": ">=10.14",
- "npm": ">=6",
- "yarn": ">=1"
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
}
},
"node_modules/cross-spawn": {
@@ -3063,6 +1253,12 @@
"node": ">= 8"
}
},
+ "node_modules/crypto-js": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
+ "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==",
+ "license": "MIT"
+ },
"node_modules/css-select": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
@@ -3091,63 +1287,115 @@
"url": "https://github.com/sponsors/fb55"
}
},
+ "node_modules/cssstyle": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz",
+ "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==",
+ "license": "MIT",
+ "dependencies": {
+ "@asamuzakjp/css-color": "^3.2.0",
+ "rrweb-cssom": "^0.8.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/data-uri-to-buffer": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
- "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz",
+ "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==",
"license": "MIT",
"engines": {
- "node": ">= 12"
+ "node": ">= 14"
+ }
+ },
+ "node_modules/data-urls": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
+ "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/data-urls/node_modules/tr46": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/data-urls/node_modules/webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/data-urls/node_modules/whatwg-url": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "^5.1.0",
+ "webidl-conversions": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
}
},
"node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "dev": true,
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"license": "MIT",
"dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
+ "ms": "2.0.0"
}
},
- "node_modules/dedent": {
- "version": "1.5.3",
- "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz",
- "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "babel-plugin-macros": "^3.1.0"
- },
- "peerDependenciesMeta": {
- "babel-plugin-macros": {
- "optional": true
- }
- }
+ "node_modules/decimal.js": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
+ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
+ "license": "MIT"
},
- "node_modules/deepmerge": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
- "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
"dev": true,
+ "license": "MIT"
+ },
+ "node_modules/degenerator": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
+ "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",
"license": "MIT",
+ "dependencies": {
+ "ast-types": "^0.13.4",
+ "escodegen": "^2.1.0",
+ "esprima": "^4.0.1"
+ },
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 14"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.4.0"
@@ -3172,35 +1420,23 @@
"npm": "1.2.8000 || >= 1.4.16"
}
},
- "node_modules/detect-newline": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
- "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
+ "node_modules/devtools-protocol": {
+ "version": "0.0.1464554",
+ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1464554.tgz",
+ "integrity": "sha512-CAoP3lYfwAGQTaAXYvA6JZR0fjGUb7qec1qf4mToyoH2TZgUFeIqYcjh6f9jNuhHfuZiEdH+PONHYrLhRQX6aw==",
+ "license": "BSD-3-Clause"
},
- "node_modules/dezalgo": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
- "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
"dev": true,
- "license": "ISC",
+ "license": "Apache-2.0",
"dependencies": {
- "asap": "^2.0.0",
- "wrappy": "1"
- }
- },
- "node_modules/diff-sequences": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
- "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
- "dev": true,
- "license": "MIT",
+ "esutils": "^2.0.2"
+ },
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": ">=6.0.0"
}
},
"node_modules/dom-serializer": {
@@ -3290,31 +1526,10 @@
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
"license": "MIT"
},
- "node_modules/electron-to-chromium": {
- "version": "1.5.136",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.136.tgz",
- "integrity": "sha512-kL4+wUTD7RSA5FHx5YwWtjDnEEkIIikFgWHR4P6fqjw1PPLlqYkxeOb++wAauAssat0YClCy8Y3C5SxgSkjibQ==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/emittery": {
- "version": "0.13.1",
- "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
- "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/emittery?sponsor=1"
- }
- },
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true,
"license": "MIT"
},
"node_modules/encodeurl": {
@@ -3339,6 +1554,15 @@
"url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
}
},
+ "node_modules/end-of-stream": {
+ "version": "1.4.5",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
+ "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
+ "license": "MIT",
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
@@ -3351,11 +1575,19 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"is-arrayish": "^0.2.1"
@@ -3395,7 +1627,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -3411,7 +1642,6 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -3424,20 +1654,186 @@
"license": "MIT"
},
"node_modules/escape-string-regexp": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
- "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=8"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/escodegen": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
+ "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esprima": "^4.0.1",
+ "estraverse": "^5.2.0",
+ "esutils": "^2.0.2"
+ },
+ "bin": {
+ "escodegen": "bin/escodegen.js",
+ "esgenerate": "bin/esgenerate.js"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "optionalDependencies": {
+ "source-map": "~0.6.1"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
+ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.4",
+ "@eslint/js": "8.57.1",
+ "@humanwhocodes/config-array": "^0.13.0",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "@ungap/structured-clone": "^1.2.0",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint/node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/eslint/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
"node_modules/esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
- "dev": true,
"license": "BSD-2-Clause",
"bin": {
"esparse": "bin/esparse.js",
@@ -3447,11 +1843,45 @@
"node": ">=4"
}
},
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
"node_modules/esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
- "dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.10.0"
@@ -3466,56 +1896,6 @@
"node": ">= 0.6"
}
},
- "node_modules/execa": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
- "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cross-spawn": "^7.0.3",
- "get-stream": "^6.0.0",
- "human-signals": "^2.1.0",
- "is-stream": "^2.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^4.0.1",
- "onetime": "^5.1.2",
- "signal-exit": "^3.0.3",
- "strip-final-newline": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/execa?sponsor=1"
- }
- },
- "node_modules/exit": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
- "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
- "dev": true,
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/expect": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz",
- "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/expect-utils": "^29.7.0",
- "jest-get-type": "^29.6.3",
- "jest-matcher-utils": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-util": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
"node_modules/express": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
@@ -3562,19 +1942,111 @@
"url": "https://opencollective.com/express"
}
},
- "node_modules/express/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "node_modules/express/node_modules/body-parser": {
+ "version": "1.20.3",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
+ "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
"license": "MIT",
"dependencies": {
- "ms": "2.0.0"
+ "bytes": "3.1.2",
+ "content-type": "~1.0.5",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.13.0",
+ "raw-body": "2.5.2",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
}
},
- "node_modules/express/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "node_modules/express/node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/express/node_modules/raw-body": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/extract-zip": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "debug": "^4.1.1",
+ "get-stream": "^5.1.0",
+ "yauzl": "^2.10.0"
+ },
+ "bin": {
+ "extract-zip": "cli.js"
+ },
+ "engines": {
+ "node": ">= 10.17.0"
+ },
+ "optionalDependencies": {
+ "@types/yauzl": "^2.9.1"
+ }
+ },
+ "node_modules/extract-zip/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/extract-zip/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-fifo": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
+ "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
"license": "MIT"
},
"node_modules/fast-json-stable-stringify": {
@@ -3584,44 +2056,43 @@
"dev": true,
"license": "MIT"
},
- "node_modules/fast-safe-stringify": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
- "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true,
"license": "MIT"
},
- "node_modules/fb-watchman": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
- "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
"dev": true,
- "license": "Apache-2.0",
+ "license": "ISC",
"dependencies": {
- "bser": "2.1.1"
+ "reusify": "^1.0.4"
}
},
- "node_modules/fetch-blob": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
- "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/jimmywarting"
- },
- {
- "type": "paypal",
- "url": "https://paypal.me/jimmywarting"
- }
- ],
+ "node_modules/fd-slicer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
"license": "MIT",
"dependencies": {
- "node-domexception": "^1.0.0",
- "web-streams-polyfill": "^3.0.3"
+ "pend": "~1.2.0"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^3.0.4"
},
"engines": {
- "node": "^12.20 || >= 14.13"
+ "node": "^10.12.0 || >=12.0.0"
}
},
"node_modules/fill-range": {
@@ -3655,78 +2126,81 @@
"node": ">= 0.8"
}
},
- "node_modules/finalhandler/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/finalhandler/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "license": "MIT"
- },
"node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"dev": true,
"license": "MIT",
"dependencies": {
- "locate-path": "^5.0.0",
+ "locate-path": "^6.0.0",
"path-exists": "^4.0.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
+ "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.3",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
}
},
"node_modules/form-data": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
- "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
- "dev": true,
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz",
+ "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
- "node_modules/formdata-polyfill": {
- "version": "4.0.10",
- "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
- "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
- "license": "MIT",
- "dependencies": {
- "fetch-blob": "^3.1.2"
- },
- "engines": {
- "node": ">=12.20.0"
- }
- },
- "node_modules/formidable": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.2.tgz",
- "integrity": "sha512-Jqc1btCy3QzRbJaICGwKcBfGWuLADRerLzDqi2NwSt/UkXLsHJw2TVResiaoBufHVHy9aSgClOHCeJsSsFLTbg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "dezalgo": "^1.0.4",
- "hexoid": "^2.0.0",
- "once": "^1.4.0"
- },
- "funding": {
- "url": "https://ko-fi.com/tunnckoCore/commissions"
- }
- },
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -3776,21 +2250,10 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/gensync": {
- "version": "1.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "dev": true,
"license": "ISC",
"engines": {
"node": "6.* || 8.* || >= 10.*"
@@ -3820,16 +2283,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/get-package-type": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
- "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8.0.0"
- }
- },
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
@@ -3844,18 +2297,57 @@
}
},
"node_modules/get-stream": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
- "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
- "dev": true,
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"license": "MIT",
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
"engines": {
- "node": ">=10"
+ "node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/get-uri": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz",
+ "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "basic-ftp": "^5.0.2",
+ "data-uri-to-buffer": "^6.0.2",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/get-uri/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/get-uri/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -3878,14 +2370,33 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/globals": {
- "version": "11.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
- "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
"engines": {
- "node": ">=4"
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/gopd": {
@@ -3900,21 +2411,21 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/graceful-fs": {
- "version": "4.2.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
"dev": true,
- "license": "ISC"
+ "license": "MIT"
},
"node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=8"
+ "node": ">=4"
}
},
"node_modules/has-symbols": {
@@ -3933,7 +2444,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
@@ -3957,23 +2467,24 @@
"node": ">= 0.4"
}
},
- "node_modules/hexoid": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-2.0.0.tgz",
- "integrity": "sha512-qlspKUK7IlSQv2o+5I7yhUd7TxlOG2Vr5LTa3ve2XSNVKAL/n/u/7KLvKmFNimomDIKvZFXWHv0T12mv7rT8Aw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/html-escaper": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
- "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
- "dev": true,
+ "node_modules/hls-parser": {
+ "version": "0.13.5",
+ "resolved": "https://registry.npmjs.org/hls-parser/-/hls-parser-0.13.5.tgz",
+ "integrity": "sha512-UJyTCcNZwOdBmEJo86vViEpgtaUhxrgAsBb65+Lk6fjzyOfIDVF9Y0TyE0KJ2Gc5YHfHx7xevuj/RR0itP3vaA==",
"license": "MIT"
},
+ "node_modules/html-encoding-sniffer": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
+ "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-encoding": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/htmlparser2": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
@@ -4009,16 +2520,78 @@
"node": ">= 0.8"
}
},
- "node_modules/human-signals": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
- "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
- "dev": true,
- "license": "Apache-2.0",
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
"engines": {
- "node": ">=10.17.0"
+ "node": ">= 14"
}
},
+ "node_modules/http-proxy-agent/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/http-proxy-agent/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/https-proxy-agent/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/https-proxy-agent/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
@@ -4031,21 +2604,34 @@
"node": ">=0.10.0"
}
},
- "node_modules/import-local": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
- "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
"license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/ignore-by-default": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "license": "MIT",
"dependencies": {
- "pkg-dir": "^4.2.0",
- "resolve-cwd": "^3.0.0"
- },
- "bin": {
- "import-local-fixture": "fixtures/cli.js"
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -4079,6 +2665,19 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"license": "ISC"
},
+ "node_modules/ip-address": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
+ "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
+ "license": "MIT",
+ "dependencies": {
+ "jsbn": "1.1.0",
+ "sprintf-js": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -4092,43 +2691,42 @@
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
- "dev": true,
"license": "MIT"
},
- "node_modules/is-core-module": {
- "version": "2.16.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
- "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "hasown": "^2.0.2"
+ "binary-extensions": "^2.0.0"
},
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "license": "MIT",
"engines": {
"node": ">=8"
}
},
- "node_modules/is-generator-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
- "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=6"
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
}
},
"node_modules/is-number": {
@@ -4141,19 +2739,22 @@
"node": ">=0.12.0"
}
},
- "node_modules/is-stream": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
- "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+ "license": "MIT"
+ },
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -4161,843 +2762,168 @@
"dev": true,
"license": "ISC"
},
- "node_modules/istanbul-lib-coverage": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
- "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-instrument": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz",
- "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@babel/core": "^7.23.9",
- "@babel/parser": "^7.23.9",
- "@istanbuljs/schema": "^0.1.3",
- "istanbul-lib-coverage": "^3.2.0",
- "semver": "^7.5.4"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-lib-instrument/node_modules/semver": {
- "version": "7.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
- "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-lib-report": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
- "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "istanbul-lib-coverage": "^3.0.0",
- "make-dir": "^4.0.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-lib-source-maps": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
- "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "debug": "^4.1.1",
- "istanbul-lib-coverage": "^3.0.0",
- "source-map": "^0.6.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-reports": {
- "version": "3.1.7",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
- "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "html-escaper": "^2.0.0",
- "istanbul-lib-report": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
- "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/core": "^29.7.0",
- "@jest/types": "^29.6.3",
- "import-local": "^3.0.2",
- "jest-cli": "^29.7.0"
- },
- "bin": {
- "jest": "bin/jest.js"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
- },
- "peerDependenciesMeta": {
- "node-notifier": {
- "optional": true
- }
- }
- },
- "node_modules/jest-changed-files": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz",
- "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "execa": "^5.0.0",
- "jest-util": "^29.7.0",
- "p-limit": "^3.1.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-circus": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz",
- "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/environment": "^29.7.0",
- "@jest/expect": "^29.7.0",
- "@jest/test-result": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "co": "^4.6.0",
- "dedent": "^1.0.0",
- "is-generator-fn": "^2.0.0",
- "jest-each": "^29.7.0",
- "jest-matcher-utils": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-runtime": "^29.7.0",
- "jest-snapshot": "^29.7.0",
- "jest-util": "^29.7.0",
- "p-limit": "^3.1.0",
- "pretty-format": "^29.7.0",
- "pure-rand": "^6.0.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-cli": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz",
- "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/core": "^29.7.0",
- "@jest/test-result": "^29.7.0",
- "@jest/types": "^29.6.3",
- "chalk": "^4.0.0",
- "create-jest": "^29.7.0",
- "exit": "^0.1.2",
- "import-local": "^3.0.2",
- "jest-config": "^29.7.0",
- "jest-util": "^29.7.0",
- "jest-validate": "^29.7.0",
- "yargs": "^17.3.1"
- },
- "bin": {
- "jest": "bin/jest.js"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
- },
- "peerDependenciesMeta": {
- "node-notifier": {
- "optional": true
- }
- }
- },
- "node_modules/jest-config": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz",
- "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.11.6",
- "@jest/test-sequencer": "^29.7.0",
- "@jest/types": "^29.6.3",
- "babel-jest": "^29.7.0",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "deepmerge": "^4.2.2",
- "glob": "^7.1.3",
- "graceful-fs": "^4.2.9",
- "jest-circus": "^29.7.0",
- "jest-environment-node": "^29.7.0",
- "jest-get-type": "^29.6.3",
- "jest-regex-util": "^29.6.3",
- "jest-resolve": "^29.7.0",
- "jest-runner": "^29.7.0",
- "jest-util": "^29.7.0",
- "jest-validate": "^29.7.0",
- "micromatch": "^4.0.4",
- "parse-json": "^5.2.0",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "strip-json-comments": "^3.1.1"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "@types/node": "*",
- "ts-node": ">=9.0.0"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "ts-node": {
- "optional": true
- }
- }
- },
- "node_modules/jest-diff": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz",
- "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.0.0",
- "diff-sequences": "^29.6.3",
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-docblock": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz",
- "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "detect-newline": "^3.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-each": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz",
- "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "chalk": "^4.0.0",
- "jest-get-type": "^29.6.3",
- "jest-util": "^29.7.0",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-environment-node": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz",
- "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/environment": "^29.7.0",
- "@jest/fake-timers": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "jest-mock": "^29.7.0",
- "jest-util": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-extended": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/jest-extended/-/jest-extended-3.2.4.tgz",
- "integrity": "sha512-lSEYhSmvXZG/7YXI7KO3LpiUiQ90gi5giwCJNDMMsX5a+/NZhdbQF2G4ALOBN+KcXVT3H6FPVPohAuMXooaLTQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "jest-diff": "^29.0.0",
- "jest-get-type": "^29.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "jest": ">=27.2.5"
- },
- "peerDependenciesMeta": {
- "jest": {
- "optional": true
- }
- }
- },
- "node_modules/jest-get-type": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
- "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-haste-map": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz",
- "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "@types/graceful-fs": "^4.1.3",
- "@types/node": "*",
- "anymatch": "^3.0.3",
- "fb-watchman": "^2.0.0",
- "graceful-fs": "^4.2.9",
- "jest-regex-util": "^29.6.3",
- "jest-util": "^29.7.0",
- "jest-worker": "^29.7.0",
- "micromatch": "^4.0.4",
- "walker": "^1.0.8"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "optionalDependencies": {
- "fsevents": "^2.3.2"
- }
- },
- "node_modules/jest-junit": {
- "version": "15.0.0",
- "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-15.0.0.tgz",
- "integrity": "sha512-Z5sVX0Ag3HZdMUnD5DFlG+1gciIFSy7yIVPhOdGUi8YJaI9iLvvBb530gtQL2CHmv0JJeiwRZenr0VrSR7frvg==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "mkdirp": "^1.0.4",
- "strip-ansi": "^6.0.1",
- "uuid": "^8.3.2",
- "xml": "^1.0.1"
- },
- "engines": {
- "node": ">=10.12.0"
- }
- },
- "node_modules/jest-leak-detector": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz",
- "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-matcher-utils": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz",
- "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.0.0",
- "jest-diff": "^29.7.0",
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-message-util": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
- "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.12.13",
- "@jest/types": "^29.6.3",
- "@types/stack-utils": "^2.0.0",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "micromatch": "^4.0.4",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-mock": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
- "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "jest-util": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-pnp-resolver": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
- "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- },
- "peerDependencies": {
- "jest-resolve": "*"
- },
- "peerDependenciesMeta": {
- "jest-resolve": {
- "optional": true
- }
- }
- },
- "node_modules/jest-regex-util": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
- "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-resolve": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz",
- "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.7.0",
- "jest-pnp-resolver": "^1.2.2",
- "jest-util": "^29.7.0",
- "jest-validate": "^29.7.0",
- "resolve": "^1.20.0",
- "resolve.exports": "^2.0.0",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-resolve-dependencies": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz",
- "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "jest-regex-util": "^29.6.3",
- "jest-snapshot": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-runner": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz",
- "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/console": "^29.7.0",
- "@jest/environment": "^29.7.0",
- "@jest/test-result": "^29.7.0",
- "@jest/transform": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "emittery": "^0.13.1",
- "graceful-fs": "^4.2.9",
- "jest-docblock": "^29.7.0",
- "jest-environment-node": "^29.7.0",
- "jest-haste-map": "^29.7.0",
- "jest-leak-detector": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-resolve": "^29.7.0",
- "jest-runtime": "^29.7.0",
- "jest-util": "^29.7.0",
- "jest-watcher": "^29.7.0",
- "jest-worker": "^29.7.0",
- "p-limit": "^3.1.0",
- "source-map-support": "0.5.13"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-runtime": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz",
- "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/environment": "^29.7.0",
- "@jest/fake-timers": "^29.7.0",
- "@jest/globals": "^29.7.0",
- "@jest/source-map": "^29.6.3",
- "@jest/test-result": "^29.7.0",
- "@jest/transform": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "cjs-module-lexer": "^1.0.0",
- "collect-v8-coverage": "^1.0.0",
- "glob": "^7.1.3",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-mock": "^29.7.0",
- "jest-regex-util": "^29.6.3",
- "jest-resolve": "^29.7.0",
- "jest-snapshot": "^29.7.0",
- "jest-util": "^29.7.0",
- "slash": "^3.0.0",
- "strip-bom": "^4.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-snapshot": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz",
- "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.11.6",
- "@babel/generator": "^7.7.2",
- "@babel/plugin-syntax-jsx": "^7.7.2",
- "@babel/plugin-syntax-typescript": "^7.7.2",
- "@babel/types": "^7.3.3",
- "@jest/expect-utils": "^29.7.0",
- "@jest/transform": "^29.7.0",
- "@jest/types": "^29.6.3",
- "babel-preset-current-node-syntax": "^1.0.0",
- "chalk": "^4.0.0",
- "expect": "^29.7.0",
- "graceful-fs": "^4.2.9",
- "jest-diff": "^29.7.0",
- "jest-get-type": "^29.6.3",
- "jest-matcher-utils": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-util": "^29.7.0",
- "natural-compare": "^1.4.0",
- "pretty-format": "^29.7.0",
- "semver": "^7.5.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-snapshot/node_modules/semver": {
- "version": "7.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
- "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/jest-util": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
- "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "graceful-fs": "^4.2.9",
- "picomatch": "^2.2.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-validate": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz",
- "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "camelcase": "^6.2.0",
- "chalk": "^4.0.0",
- "jest-get-type": "^29.6.3",
- "leven": "^3.1.0",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-validate/node_modules/camelcase": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/jest-watcher": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz",
- "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/test-result": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "ansi-escapes": "^4.2.1",
- "chalk": "^4.0.0",
- "emittery": "^0.13.1",
- "jest-util": "^29.7.0",
- "string-length": "^4.0.1"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-worker": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz",
- "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*",
- "jest-util": "^29.7.0",
- "merge-stream": "^2.0.0",
- "supports-color": "^8.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-worker/node_modules/supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
- }
- },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/js-yaml": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
- "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
- "dev": true,
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"license": "MIT",
"dependencies": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
+ "argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
- "node_modules/jsesc": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
- "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
- "dev": true,
+ "node_modules/jsbn": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
+ "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==",
+ "license": "MIT"
+ },
+ "node_modules/jsdom": {
+ "version": "26.1.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz",
+ "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==",
"license": "MIT",
- "bin": {
- "jsesc": "bin/jsesc"
+ "dependencies": {
+ "cssstyle": "^4.2.1",
+ "data-urls": "^5.0.0",
+ "decimal.js": "^10.5.0",
+ "html-encoding-sniffer": "^4.0.0",
+ "http-proxy-agent": "^7.0.2",
+ "https-proxy-agent": "^7.0.6",
+ "is-potential-custom-element-name": "^1.0.1",
+ "nwsapi": "^2.2.16",
+ "parse5": "^7.2.1",
+ "rrweb-cssom": "^0.8.0",
+ "saxes": "^6.0.0",
+ "symbol-tree": "^3.2.4",
+ "tough-cookie": "^5.1.1",
+ "w3c-xmlserializer": "^5.0.0",
+ "webidl-conversions": "^7.0.0",
+ "whatwg-encoding": "^3.1.1",
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.1.1",
+ "ws": "^8.18.0",
+ "xml-name-validator": "^5.0.0"
},
"engines": {
- "node": ">=6"
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "canvas": "^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
}
},
+ "node_modules/jsdom/node_modules/tr46": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/jsdom/node_modules/webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/jsdom/node_modules/whatwg-url": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "^5.1.0",
+ "webidl-conversions": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true,
"license": "MIT"
},
- "node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
"dev": true,
"license": "MIT",
- "bin": {
- "json5": "lib/cli.js"
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
},
"engines": {
- "node": ">=6"
- }
- },
- "node_modules/kleur": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
- "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/leven": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
- "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
+ "node": ">= 0.8.0"
}
},
"node_modules/lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "dev": true,
"license": "MIT"
},
"node_modules/locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/lodash.debounce": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
- "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "yallist": "^3.0.2"
- }
- },
- "node_modules/make-dir": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
- "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "semver": "^7.5.3"
+ "p-locate": "^5.0.0"
},
"engines": {
"node": ">=10"
@@ -5006,27 +2932,20 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/make-dir/node_modules/semver": {
- "version": "7.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
- "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
+ "license": "MIT"
},
- "node_modules/makeerror": {
- "version": "1.0.12",
- "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
- "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "tmpl": "1.0.5"
+ "node_modules/lru-cache": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
}
},
"node_modules/math-intrinsics": {
@@ -5056,13 +2975,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/merge-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@@ -5072,20 +2984,6 @@
"node": ">= 0.6"
}
},
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
@@ -5119,16 +3017,6 @@
"node": ">= 0.6"
}
},
- "node_modules/mimic-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -5142,23 +3030,16 @@
"node": "*"
}
},
- "node_modules/mkdirp": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "mkdirp": "bin/cmd.js"
- },
- "engines": {
- "node": ">=10"
- }
+ "node_modules/mitt": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
+ "license": "MIT"
},
"node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT"
},
"node_modules/natural-compare": {
@@ -5177,56 +3058,101 @@
"node": ">= 0.6"
}
},
- "node_modules/node-domexception": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
- "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/jimmywarting"
- },
- {
- "type": "github",
- "url": "https://paypal.me/jimmywarting"
- }
- ],
+ "node_modules/netmask": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
+ "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==",
"license": "MIT",
"engines": {
- "node": ">=10.5.0"
+ "node": ">= 0.4.0"
}
},
"node_modules/node-fetch": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
- "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"license": "MIT",
"dependencies": {
- "data-uri-to-buffer": "^4.0.0",
- "fetch-blob": "^3.1.4",
- "formdata-polyfill": "^4.0.10"
+ "whatwg-url": "^5.0.0"
},
"engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/nodemon": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz",
+ "integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^3.5.2",
+ "debug": "^4",
+ "ignore-by-default": "^1.0.1",
+ "minimatch": "^3.1.2",
+ "pstree.remy": "^1.1.8",
+ "semver": "^7.5.3",
+ "simple-update-notifier": "^2.0.0",
+ "supports-color": "^5.5.0",
+ "touch": "^3.1.0",
+ "undefsafe": "^2.0.5"
+ },
+ "bin": {
+ "nodemon": "bin/nodemon.js"
+ },
+ "engines": {
+ "node": ">=10"
},
"funding": {
"type": "opencollective",
- "url": "https://opencollective.com/node-fetch"
+ "url": "https://opencollective.com/nodemon"
}
},
- "node_modules/node-int64": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
- "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
+ "node_modules/nodemon/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/nodemon/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"license": "MIT"
},
- "node_modules/node-releases": {
- "version": "2.0.19",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
- "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
+ "node_modules/nodemon/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true,
- "license": "MIT"
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
},
"node_modules/normalize-path": {
"version": "3.0.0",
@@ -5238,19 +3164,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/npm-run-path": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
- "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "path-key": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/nth-check": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
@@ -5263,6 +3176,12 @@
"url": "https://github.com/fb55/nth-check?sponsor=1"
}
},
+ "node_modules/nwsapi": {
+ "version": "2.2.21",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.21.tgz",
+ "integrity": "sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==",
+ "license": "MIT"
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -5300,29 +3219,61 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "dev": true,
"license": "ISC",
"dependencies": {
"wrappy": "1"
}
},
- "node_modules/onetime": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
- "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "mimic-fn": "^2.1.0"
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
},
"engines": {
- "node": ">=6"
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz",
+ "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==",
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/p-limit": {
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate/node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
@@ -5338,41 +3289,82 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "node_modules/p-locate/node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "p-limit": "^2.2.0"
- },
"engines": {
- "node": ">=8"
- }
- },
- "node_modules/p-locate/node_modules/p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-try": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
+ "node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/p-try": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
- "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
- "dev": true,
+ "node_modules/pac-proxy-agent": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz",
+ "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==",
"license": "MIT",
+ "dependencies": {
+ "@tootallnate/quickjs-emscripten": "^0.23.0",
+ "agent-base": "^7.1.2",
+ "debug": "^4.3.4",
+ "get-uri": "^6.0.1",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.6",
+ "pac-resolver": "^7.0.1",
+ "socks-proxy-agent": "^8.0.5"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/pac-proxy-agent/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/pac-proxy-agent/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/pac-resolver": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz",
+ "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==",
+ "license": "MIT",
+ "dependencies": {
+ "degenerator": "^5.0.0",
+ "netmask": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
"engines": {
"node": ">=6"
}
@@ -5381,7 +3373,6 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.0.0",
@@ -5397,12 +3388,12 @@
}
},
"node_modules/parse5": {
- "version": "7.2.1",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
- "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+ "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
"license": "MIT",
"dependencies": {
- "entities": "^4.5.0"
+ "entities": "^6.0.0"
},
"funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1"
@@ -5433,6 +3424,18 @@
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
+ "node_modules/parse5/node_modules/entities": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz",
+ "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -5472,24 +3475,22 @@
"node": ">=8"
}
},
- "node_modules/path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/path-to-regexp": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
"license": "MIT"
},
+ "node_modules/pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
+ "license": "MIT"
+ },
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
@@ -5505,69 +3506,23 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/pirates": {
- "version": "4.0.7",
- "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
- "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">= 6"
+ "node": ">= 0.8.0"
}
},
- "node_modules/pkg-dir": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
- "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "find-up": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/pretty-format": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
- "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/pretty-format/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
+ "node_modules/progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"license": "MIT",
"engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/prompts": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
- "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "kleur": "^3.0.3",
- "sisteransi": "^1.0.5"
- },
- "engines": {
- "node": ">= 6"
+ "node": ">=0.4.0"
}
},
"node_modules/proxy-addr": {
@@ -5583,21 +3538,139 @@
"node": ">= 0.10"
}
},
- "node_modules/pure-rand": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz",
- "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
- "dev": true,
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/dubzzz"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fast-check"
+ "node_modules/proxy-agent": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz",
+ "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "^4.3.4",
+ "http-proxy-agent": "^7.0.1",
+ "https-proxy-agent": "^7.0.6",
+ "lru-cache": "^7.14.1",
+ "pac-proxy-agent": "^7.1.0",
+ "proxy-from-env": "^1.1.0",
+ "socks-proxy-agent": "^8.0.5"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/proxy-agent/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
}
- ],
+ }
+ },
+ "node_modules/proxy-agent/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
+ },
+ "node_modules/pstree.remy": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
+ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pump": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
+ "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/puppeteer": {
+ "version": "24.11.0",
+ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.11.0.tgz",
+ "integrity": "sha512-7XFpexeYIMen/pfGiDjUpIV7BB9EuVQBtXeQ0cUOmVJTkAuQD3oPHVU7iYeA/mrIJyk79sfOmT20a6SEDwGTLQ==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@puppeteer/browsers": "2.10.5",
+ "chromium-bidi": "5.1.0",
+ "cosmiconfig": "^9.0.0",
+ "devtools-protocol": "0.0.1464554",
+ "puppeteer-core": "24.11.0",
+ "typed-query-selector": "^2.12.0"
+ },
+ "bin": {
+ "puppeteer": "lib/cjs/puppeteer/node/cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/puppeteer-core": {
+ "version": "24.11.0",
+ "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.11.0.tgz",
+ "integrity": "sha512-ncLty0wRjCX67UxzXemmD1mOxb6y1Xzrx1nym8SAQ6cYrcypOVf77CfcZru6P+EiMA9gNDeQNscowKSE9xvhMw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@puppeteer/browsers": "2.10.5",
+ "chromium-bidi": "5.1.0",
+ "debug": "^4.4.1",
+ "devtools-protocol": "0.0.1464554",
+ "typed-query-selector": "^2.12.0",
+ "ws": "^8.18.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/puppeteer-core/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/puppeteer-core/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/qs": {
@@ -5615,6 +3688,27 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -5625,189 +3719,107 @@
}
},
"node_modules/raw-body": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
- "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
+ "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
"license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
+ "iconv-lite": "0.6.3",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
- "node_modules/raw-body/node_modules/iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "safer-buffer": ">= 2.1.2 < 3"
+ "picomatch": "^2.2.1"
},
"engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-is": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/regenerate": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
- "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/regenerate-unicode-properties": {
- "version": "10.2.0",
- "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz",
- "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "regenerate": "^1.4.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/regenerator-runtime": {
- "version": "0.14.1",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
- "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/regenerator-transform": {
- "version": "0.15.2",
- "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz",
- "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.8.4"
- }
- },
- "node_modules/regexpu-core": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz",
- "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "regenerate": "^1.4.2",
- "regenerate-unicode-properties": "^10.2.0",
- "regjsgen": "^0.8.0",
- "regjsparser": "^0.12.0",
- "unicode-match-property-ecmascript": "^2.0.0",
- "unicode-match-property-value-ecmascript": "^2.1.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/regjsgen": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz",
- "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/regjsparser": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz",
- "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "jsesc": "~3.0.2"
- },
- "bin": {
- "regjsparser": "bin/parser"
- }
- },
- "node_modules/regjsparser/node_modules/jsesc": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
- "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=6"
+ "node": ">=8.10.0"
}
},
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/resolve": {
- "version": "1.22.10",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
- "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
"dev": true,
"license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "license": "ISC",
"dependencies": {
- "is-core-module": "^2.16.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
+ "glob": "^7.1.3"
},
"bin": {
- "resolve": "bin/resolve"
- },
- "engines": {
- "node": ">= 0.4"
+ "rimraf": "bin.js"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/resolve-cwd": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
- "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "node_modules/rrweb-cssom": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz",
+ "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==",
+ "license": "MIT"
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
"license": "MIT",
"dependencies": {
- "resolve-from": "^5.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/resolve.exports": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz",
- "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
+ "queue-microtask": "^1.2.2"
}
},
"node_modules/safe-buffer": {
@@ -5836,14 +3848,16 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
},
- "node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "dev": true,
+ "node_modules/saxes": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
+ "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
"license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
+ "dependencies": {
+ "xmlchars": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=v12.22.7"
}
},
"node_modules/send": {
@@ -5870,21 +3884,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/send/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/send/node_modules/debug/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "license": "MIT"
- },
"node_modules/send/node_modules/encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@@ -5894,6 +3893,12 @@
"node": ">= 0.8"
}
},
+ "node_modules/send/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
"node_modules/serve-static": {
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
@@ -6010,71 +4015,109 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/sisteransi": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
- "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "node_modules/simple-update-notifier": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
+ "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
"engines": {
- "node": ">=8"
+ "node": ">=10"
}
},
+ "node_modules/simple-update-notifier/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/smart-buffer": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz",
+ "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==",
+ "license": "MIT",
+ "dependencies": {
+ "ip-address": "^9.0.5",
+ "smart-buffer": "^4.2.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks-proxy-agent": {
+ "version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
+ "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "^4.3.4",
+ "socks": "^2.8.3"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/socks-proxy-agent/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/socks-proxy-agent/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
"license": "BSD-3-Clause",
+ "optional": true,
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/source-map-support": {
- "version": "0.5.13",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
- "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- }
- },
"node_modules/sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
- "dev": true,
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
+ "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
"license": "BSD-3-Clause"
},
- "node_modules/stack-utils": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
- "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "escape-string-regexp": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@@ -6084,40 +4127,30 @@
"node": ">= 0.8"
}
},
- "node_modules/string-length": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
- "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
- "dev": true,
+ "node_modules/streamx": {
+ "version": "2.22.1",
+ "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.1.tgz",
+ "integrity": "sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==",
"license": "MIT",
"dependencies": {
- "char-regex": "^1.0.2",
- "strip-ansi": "^6.0.0"
+ "fast-fifo": "^1.3.2",
+ "text-decoder": "^1.1.0"
},
- "engines": {
- "node": ">=10"
+ "optionalDependencies": {
+ "bare-events": "^2.2.0"
}
},
- "node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
+ "node_modules/string-similarity": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-4.0.4.tgz",
+ "integrity": "sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==",
+ "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
+ "license": "ISC"
},
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@@ -6126,26 +4159,6 @@
"node": ">=8"
}
},
- "node_modules/strip-bom": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
- "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-final-newline": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
- "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -6159,101 +4172,83 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/superagent": {
- "version": "9.0.2",
- "resolved": "https://registry.npmjs.org/superagent/-/superagent-9.0.2.tgz",
- "integrity": "sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "component-emitter": "^1.3.0",
- "cookiejar": "^2.1.4",
- "debug": "^4.3.4",
- "fast-safe-stringify": "^2.1.1",
- "form-data": "^4.0.0",
- "formidable": "^3.5.1",
- "methods": "^1.1.2",
- "mime": "2.6.0",
- "qs": "^6.11.0"
- },
- "engines": {
- "node": ">=14.18.0"
- }
- },
- "node_modules/superagent/node_modules/mime": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
- "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "mime": "cli.js"
- },
- "engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/supertest": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.1.0.tgz",
- "integrity": "sha512-5QeSO8hSrKghtcWEoPiO036fxH0Ii2wVQfFZSP0oqQhmjk8bOLhDFXr4JrvaFmPuEWUoq4znY3uSi8UzLKxGqw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "methods": "^1.1.2",
- "superagent": "^9.0.1"
- },
- "engines": {
- "node": ">=14.18.0"
- }
- },
"node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"license": "MIT",
"dependencies": {
- "has-flag": "^4.0.0"
+ "has-flag": "^3.0.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=4"
}
},
- "node_modules/supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
+ "node_modules/symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+ "license": "MIT"
+ },
+ "node_modules/tar-fs": {
+ "version": "3.0.10",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.10.tgz",
+ "integrity": "sha512-C1SwlQGNLe/jPNqapK8epDsXME7CAJR5RL3GcE6KWx1d9OUByzoHVcbu1VPI8tevg9H8Alae0AApHHFGzrD5zA==",
"license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/test-exclude": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
- "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
- "dev": true,
- "license": "ISC",
"dependencies": {
- "@istanbuljs/schema": "^0.1.2",
- "glob": "^7.1.4",
- "minimatch": "^3.0.4"
+ "pump": "^3.0.0",
+ "tar-stream": "^3.1.5"
},
- "engines": {
- "node": ">=8"
+ "optionalDependencies": {
+ "bare-fs": "^4.0.1",
+ "bare-path": "^3.0.0"
}
},
- "node_modules/tmpl": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
- "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
+ "node_modules/tar-stream": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz",
+ "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==",
+ "license": "MIT",
+ "dependencies": {
+ "b4a": "^1.6.4",
+ "fast-fifo": "^1.2.0",
+ "streamx": "^2.15.0"
+ }
+ },
+ "node_modules/text-decoder": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz",
+ "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "b4a": "^1.6.4"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true,
- "license": "BSD-3-Clause"
+ "license": "MIT"
+ },
+ "node_modules/tldts": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz",
+ "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==",
+ "license": "MIT",
+ "dependencies": {
+ "tldts-core": "^6.1.86"
+ },
+ "bin": {
+ "tldts": "bin/cli.js"
+ }
+ },
+ "node_modules/tldts-core": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz",
+ "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==",
+ "license": "MIT"
},
"node_modules/to-regex-range": {
"version": "5.0.1",
@@ -6277,20 +4272,57 @@
"node": ">=0.6"
}
},
- "node_modules/type-detect": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
- "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "node_modules/touch": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
+ "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "nodetouch": "bin/nodetouch.js"
+ }
+ },
+ "node_modules/tough-cookie": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
+ "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tldts": "^6.1.32"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "license": "MIT"
+ },
+ "node_modules/ttl-cache": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/ttl-cache/-/ttl-cache-1.0.2.tgz",
+ "integrity": "sha512-EALdEXrLnzZ17/I7bZWQ006kj09oZ/3WVe1+12ANe38Ef8uv/flDH+MTrINIir8GTu8O6jRj+9Jz7yoDi4ADPQ==",
+ "license": "CC0"
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
"engines": {
- "node": ">=4"
+ "node": ">= 0.8.0"
}
},
"node_modules/type-fest": {
- "version": "0.21.3",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
- "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"dev": true,
"license": "(MIT OR CC0-1.0)",
"engines": {
@@ -6313,65 +4345,34 @@
"node": ">= 0.6"
}
},
+ "node_modules/typed-query-selector": {
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz",
+ "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==",
+ "license": "MIT"
+ },
+ "node_modules/undefsafe": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
+ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/undici": {
- "version": "6.21.2",
- "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.2.tgz",
- "integrity": "sha512-uROZWze0R0itiAKVPsYhFov9LxrPMHLMEQFszeI2gCN6bnIIZ8twzBCJcN2LJrBBLfrP0t1FW0g+JmKVl8Vk1g==",
+ "version": "6.21.3",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz",
+ "integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==",
"license": "MIT",
"engines": {
"node": ">=18.17"
}
},
"node_modules/undici-types": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
- "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/unicode-canonical-property-names-ecmascript": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz",
- "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==",
- "dev": true,
+ "version": "7.8.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
+ "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
"license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/unicode-match-property-ecmascript": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
- "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "unicode-canonical-property-names-ecmascript": "^2.0.0",
- "unicode-property-aliases-ecmascript": "^2.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/unicode-match-property-value-ecmascript": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz",
- "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/unicode-property-aliases-ecmascript": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
- "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
+ "optional": true
},
"node_modules/unpipe": {
"version": "1.0.0",
@@ -6382,35 +4383,14 @@
"node": ">= 0.8"
}
},
- "node_modules/update-browserslist-db": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
- "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
+ "license": "BSD-2-Clause",
"dependencies": {
- "escalade": "^3.2.0",
- "picocolors": "^1.1.1"
- },
- "bin": {
- "update-browserslist-db": "cli.js"
- },
- "peerDependencies": {
- "browserslist": ">= 4.21.0"
+ "punycode": "^2.1.0"
}
},
"node_modules/utils-merge": {
@@ -6422,31 +4402,6 @@
"node": ">= 0.4.0"
}
},
- "node_modules/uuid": {
- "version": "8.3.2",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
- "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "uuid": "dist/bin/uuid"
- }
- },
- "node_modules/v8-to-istanbul": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
- "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "@jridgewell/trace-mapping": "^0.3.12",
- "@types/istanbul-lib-coverage": "^2.0.1",
- "convert-source-map": "^2.0.0"
- },
- "engines": {
- "node": ">=10.12.0"
- }
- },
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -6456,25 +4411,41 @@
"node": ">= 0.8"
}
},
- "node_modules/walker": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
- "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
- "dev": true,
- "license": "Apache-2.0",
+ "node_modules/vm2": {
+ "version": "3.9.19",
+ "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.19.tgz",
+ "integrity": "sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==",
+ "deprecated": "The library contains critical security issues and should not be used for production! The maintenance of the project has been discontinued. Consider migrating your code to isolated-vm.",
+ "license": "MIT",
"dependencies": {
- "makeerror": "1.0.12"
+ "acorn": "^8.7.0",
+ "acorn-walk": "^8.2.0"
+ },
+ "bin": {
+ "vm2": "bin/vm2"
+ },
+ "engines": {
+ "node": ">=6.0"
}
},
- "node_modules/web-streams-polyfill": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
- "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
+ "node_modules/w3c-xmlserializer": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
+ "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
"license": "MIT",
+ "dependencies": {
+ "xml-name-validator": "^5.0.0"
+ },
"engines": {
- "node": ">= 8"
+ "node": ">=18"
}
},
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "license": "BSD-2-Clause"
+ },
"node_modules/whatwg-encoding": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
@@ -6496,6 +4467,16 @@
"node": ">=18"
}
},
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -6512,11 +4493,20 @@
"node": ">= 8"
}
},
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
@@ -6530,56 +4520,84 @@
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
+ "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "dev": true,
"license": "ISC"
},
- "node_modules/write-file-atomic": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
- "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "imurmurhash": "^0.1.4",
- "signal-exit": "^3.0.7"
- },
+ "node_modules/ws": {
+ "version": "8.18.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz",
+ "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==",
+ "license": "MIT",
"engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
}
},
- "node_modules/xml": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
- "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==",
- "dev": true,
+ "node_modules/xml-name-validator": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
+ "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
"license": "MIT"
},
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
- "dev": true,
"license": "ISC",
"engines": {
"node": ">=10"
}
},
- "node_modules/yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "dev": true,
- "license": "ISC"
- },
"node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
- "dev": true,
"license": "MIT",
"dependencies": {
"cliui": "^8.0.1",
@@ -6598,24 +4616,64 @@
"version": "21.1.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
- "dev": true,
"license": "ISC",
"engines": {
"node": ">=12"
}
},
- "node_modules/yocto-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "dev": true,
+ "node_modules/yargs/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"license": "MIT",
"engines": {
- "node": ">=10"
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.1.0"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz",
+ "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
+ },
+ "node_modules/zod": {
+ "version": "3.25.67",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.67.tgz",
+ "integrity": "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
}
}
}
diff --git a/package.json b/package.json
index d83b096..bb82f3e 100644
--- a/package.json
+++ b/package.json
@@ -1,20 +1,41 @@
{
"name": "tmdb-embed-api",
"version": "1.0.0",
- "description": "An api to get embed sources using tmdbid.",
- "license": "ISC",
- "author": "Inside4ndroid Studios",
- "type": "module",
- "main": "index.js",
+ "description": "Standalone streaming embed source aggregation API (TMDB ID in, streams out)",
+ "main": "apiServer.js",
"scripts": {
- "start": "node --watch index.js"
+ "start": "node apiServer.js",
+ "start:api": "node --watch apiServer.js",
+ "dev:api": "nodemon --ignore providers/.cache --ignore **/tmdb-embed-showbox-cache apiServer.js",
+ "lint": "eslint . --ext .js"
},
"dependencies": {
+ "aromanize": "^0.1.5",
+ "axios": "^1.9.0",
+ "axios-cookiejar-support": "^6.0.2",
+ "body-parser": "^2.2.0",
"cheerio": "^1.0.0",
"cors": "^2.8.5",
- "dotenv": "^16.4.7",
- "express": "^4.18.2",
- "fetch": "^1.1.0",
- "node-fetch": "^3.3.2"
+ "crypto-js": "^4.2.0",
+ "dotenv": "^16.5.0",
+ "express": "^4.21.2",
+ "form-data": "^4.0.3",
+ "hls-parser": "^0.13.5",
+ "jsdom": "^26.1.0",
+ "node-fetch": "^2.7.0",
+ "p-limit": "^6.2.0",
+ "puppeteer": "^24.11.0",
+ "string-similarity": "^4.0.4",
+ "tough-cookie": "^5.1.2",
+ "ttl-cache": "^1.0.2",
+ "vm2": "^3.9.19",
+ "yargs": "^17.7.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "devDependencies": {
+ "nodemon": "^3.1.10",
+ "eslint": "^8.57.0"
}
}
diff --git a/providers/.cache/4khdhub/4khdhub_resolved_urls_v3_1263256_movie.json b/providers/.cache/4khdhub/4khdhub_resolved_urls_v3_1263256_movie.json
new file mode 100644
index 0000000..46714b7
--- /dev/null
+++ b/providers/.cache/4khdhub/4khdhub_resolved_urls_v3_1263256_movie.json
@@ -0,0 +1,14 @@
+{
+ "data": [
+ "https://hubcloud.one/drive/eeltgk7tefggdkw",
+ "https://hubdrive.space/file/2839373447",
+ "https://hubcloud.one/drive/zm1uzufz8wh1zmv",
+ "https://hubdrive.space/file/6441436585",
+ "https://hubcloud.one/drive/dm1sbdubufkkdsv",
+ "https://hubdrive.space/file/3875373190",
+ "https://hubcloud.one/drive/wev1xt17dypotb1",
+ "https://hubdrive.space/file/4216265302",
+ "https://hubcloud.one/drive/mrhza1jqmajrjko",
+ "https://hubdrive.space/file/2736804525"
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/4khdhub/4khdhub_resolved_urls_v3_1399_tv_s1e1.json b/providers/.cache/4khdhub/4khdhub_resolved_urls_v3_1399_tv_s1e1.json
new file mode 100644
index 0000000..ee844da
--- /dev/null
+++ b/providers/.cache/4khdhub/4khdhub_resolved_urls_v3_1399_tv_s1e1.json
@@ -0,0 +1,14 @@
+{
+ "data": [
+ "https://hubcloud.one/drive/2rc17eosl11jalt",
+ "https://hubdrive.space/file/30320495116",
+ "https://hubcloud.one/drive/lb82vul8vwzw8lz",
+ "https://hubdrive.space/file/24320017865",
+ "https://hubcloud.one/drive/ls4j4srjsh228ks",
+ "https://hubdrive.space/file/8303893568",
+ "https://hubcloud.one/drive/cds5rdggp8pwxds",
+ "https://hubdrive.space/file/8032803119",
+ "https://hubcloud.one/drive/gb655ffb5nmzg3g",
+ "https://hubdrive.space/file/2836399263"
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/4khdhub/4khdhub_resolved_urls_v3_293660_movie.json b/providers/.cache/4khdhub/4khdhub_resolved_urls_v3_293660_movie.json
new file mode 100644
index 0000000..d923fc8
--- /dev/null
+++ b/providers/.cache/4khdhub/4khdhub_resolved_urls_v3_293660_movie.json
@@ -0,0 +1,20 @@
+{
+ "data": [
+ "https://hubdrive.space/file/5855904942",
+ "https://hubdrive.space/file/5855904942",
+ "https://hubdrive.space/file/27692865336",
+ "https://hubdrive.space/file/27692865336",
+ "https://hubdrive.space/file/6521988586",
+ "https://hubdrive.space/file/6521988586",
+ "https://hubdrive.space/file/9974112091",
+ "https://hubdrive.space/file/9974112091",
+ "https://hubdrive.space/file/8806133211",
+ "https://hubdrive.space/file/8806133211",
+ "https://hubdrive.space/file/6167785635",
+ "https://hubdrive.space/file/6167785635",
+ "https://hubdrive.space/file/10054935010",
+ "https://hubdrive.space/file/10054935010",
+ "https://hubdrive.space/file/4750964205",
+ "https://hubdrive.space/file/4750964205"
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/dramadrip/dramadrip_final_v13_1263256_movie.json b/providers/.cache/dramadrip/dramadrip_final_v13_1263256_movie.json
new file mode 100644
index 0000000..0637a08
--- /dev/null
+++ b/providers/.cache/dramadrip/dramadrip_final_v13_1263256_movie.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/providers/.cache/moviesdrive/tmdb_movie_1263256.json b/providers/.cache/moviesdrive/tmdb_movie_1263256.json
new file mode 100644
index 0000000..7fff542
--- /dev/null
+++ b/providers/.cache/moviesdrive/tmdb_movie_1263256.json
@@ -0,0 +1,3 @@
+{
+ "data": null
+}
\ No newline at end of file
diff --git a/providers/.cache/moviesmod/moviesmod_final_v13_1263256_movie.json b/providers/.cache/moviesmod/moviesmod_final_v13_1263256_movie.json
new file mode 100644
index 0000000..184675d
--- /dev/null
+++ b/providers/.cache/moviesmod/moviesmod_final_v13_1263256_movie.json
@@ -0,0 +1,64 @@
+{
+ "data": [
+ {
+ "quality": "720p",
+ "driveseedRedirectLinks": [
+ {
+ "server": "✅ Fast Server (G-Drive)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtlZnl5UDZCUGpyd1B0aW1WK01GOERRK0V6MDJ5MFNGbGh1Q1h4Y3VYckNXSDZ2MlIxMDVYMnRyeDMydFBNdWNEajRSbDZXMWlzRjNMaVhMdnhDZkVqK1lkeEFrTFVKcnpBemFRSUJ4NStWTE51aHJIM1pOSUlMK3NxMDMwcUVpZXlPR0dPL2tzQmlWUDFmNkhGR0RSbg==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Z1JOMXJJbTVlVFFIdXcvQ2xRMFZ5ZEtGekMrZk1ISkY1b3d4MUhray8yM2xPVHRGK00zTWtmekhYcjJRQXBLYw=="
+ },
+ {
+ "server": "🚀 Google Drive (Server 2)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpaWllxaHVJQ3JtNmZUb1cyMy92NkpPRWdIekdtNjNwTDJRTEh0Z3Mva1JYTUthaStDUVp3UzlRa0hqVVlyQjZWdExtZG1wTitoMmRzVXpyWHZRZ0tPaFpVR3lQcmFzUVBSb2hkdE1wWlB6d0s5ZGsyb2UwOCtGRWZKQS9wKzhaZVRrTjBCendhZVV3YksrOGNXZkdJdg==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=UkZYTyswOUlYWnRkd3c4UFg5TWEyNkxMRXdFakZNL05CMjYxcElpOGxOZWxJUEVMQXo4b2V6alh0RWJTemJEcg=="
+ }
+ ]
+ },
+ {
+ "quality": "1080p",
+ "driveseedRedirectLinks": [
+ {
+ "server": "✅ Fast Server (G-Drive)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtYaWxrRmU5aEVETnNSaE0veXJXN1VnYXJjZTVyQ2hVNUtzbk85MDI0OC9Edm9EUWVpWHNMYU0rRXp0ZGpUWTdFZG5VQzR6T0x3UmgvUEY5R1lFc2lrRFkxK3B3N1A1V0htN3h3eDJyaTY5REJSK1RjVm00MkNnRk9XQW12eCtRWE5seWxFZC9uelNXWUNOSXpBbllkaw==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=QXhGREliQjNpZitEWFJZY01qdXc4cmt4SnRMNGlGcit0eGNkbDNySHUybnVWZjIycElLZ0VTNGdMV3A1S1lKVw=="
+ },
+ {
+ "server": "🚀 Google Drive (Server 2)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZElqd1lDTmJPOWRrK2tMc0ZTMENiQTFtRkZkUVBZVjArQ1d4NFhvdzhNcnhsalBHbm82dnVTY3ppS1Jla3RWTHVxMmxuemhzWUdEczdnMElYS3lEN1Y4WEp2bXdxb3FndWFJKzVHRWE1Y1ljR3dkamZQR0U4czV3Y0ZKcUVvSFVRVVdIQ1RITnBtTGIvelVIeXljQWd5Sg==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=ZXV0eEdJYlhJcFhad0FSeDQxWFRGajZGZ3NDZG9BQTQ1c0JvWVUyMnFBMjJIam5zdUE4UnE2dlIwRjVVYVBERg=="
+ }
+ ]
+ },
+ {
+ "quality": "720p",
+ "driveseedRedirectLinks": [
+ {
+ "server": "✅ Fast Server (G-Drive)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExIOWo1MEtyUTN4L3dUeW8wbzc3VUFXODNBRFZSaFBpUHNwdTZ4aEF2YVJUdVlodzI0Q0pFU1hnQ0ZaUUFHOVNsaEsrWFI0RkY0SFFhYTEyWjFBdFNwNGlHczdNaXpEOS9qeXdVT2dsMU10anpscjVnN21IdmpCcVoyY2x4djJzVzZXb3ZkM0FxM2Q1SXdvR0o5Q3cvNg==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=K1U1RnhlTVdFc25JakJLVFZlTzlaN0w3V2VFRnVlelBLQWRaOVVpVXNBZWFwWksvREw0QmxWQjFCS0pDYWlXOQ=="
+ },
+ {
+ "server": "🚀 Google Drive (Server 2)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExqUmh2aXFIeEJDWjQwZkpVVUpZWWZUQzZzeVh4L3VMblgyR1F4eGJjSDc1OVBRQ2VxeHZyb21acHh5SzNvRkhneXBPTmdhSGgvTEh4QnNKMlJoVUJSUnpvempYdExaZUZkcWQ5VnN2TXFqRzJwYXRvSDF4bk1iTXZ1UlZ0R0JtQjhXYmNEQVE0emhmVlFOR1NLODh1eA==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=aExxTjRHZk4wY1ZjNDJ2VHhzcjdrcVBweHBJbWhGNitYN1ZlUGR4Z0gxalR1T2orZFBFdTRLMnRuUndiVE5IQg=="
+ }
+ ]
+ },
+ {
+ "quality": "1080p",
+ "driveseedRedirectLinks": [
+ {
+ "server": "✅ Fast Server (G-Drive)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtPNXdWSEEvK1RsbzRDdDJlY0xTd0xlY1FDbHJhK0RjdUlWKzlmZkl6dG1IRWFkTStReXlSUGtXNHhGWG5jZEJDc2ZnUytzK281d3E4VXJVcFdNN0lxZVVjK2F4Y2hhVDAvL2pJRXVHNGMybk5tQW1uSkh5d2p5VlFqTDdaWGdLcUwzMGF6aFNibjkwZTVHd2l5eXRPTg==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Y08zbk11amZCd3NacmxONVJZYlNNN3FIaklVU0lSSXp6VWhVUTkxVzlpWEJWNVFSOXQ5MTFUWmQvUFNCSzQ0WA=="
+ },
+ {
+ "server": "🚀 Google Drive (Server 2)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEozOWlUeUxnd2JuT1l5WHNvQlNVUWpNeGNzTEplSExmN2R4ZDNQVm55Y243VHFicHBVREVZUHQraVZJUmxLeVFYVFArb0Y0ejc2MEUzRE1sL2tsRStKdUNwMW1GSEdkZ0ZrR09Bdzl0ZzN5M3ErU1RCTGdFV1F5UVNiOEtqRVlRcmNNckFZQ0xSbW5vbTRMdW1TOVg5UQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Vk5abDBBaEhiaE9rNE8xTHNwR1BZQVZZUTJ0Qjc2bzFzdHVhVUV5VWdPVnNHOWl0ek40S1FxZ1U3YmUwWTdVNg=="
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/moviesmod/moviesmod_final_v13_1399_tv_s1.json b/providers/.cache/moviesmod/moviesmod_final_v13_1399_tv_s1.json
new file mode 100644
index 0000000..ee41a43
--- /dev/null
+++ b/providers/.cache/moviesmod/moviesmod_final_v13_1399_tv_s1.json
@@ -0,0 +1,224 @@
+{
+ "data": [
+ {
+ "quality": "Season 1 {Hindi-English} 720p 10Bit Esubs [340MB] - Episode Links",
+ "driveseedRedirectLinks": [
+ {
+ "server": "Episode 1",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEw0Y0tZeDhyUmtkbTFtM0tEay90aGM0TmVJNFdxTGk2MVpORURBQUNNaHRKOGJKZlRkdXNnZzMwb1JPaXRrN0VoV1hReFZyNzNUWFBsQ2R6aGkzKy80VXloNGtQZmllUkhMbGdmcXd0Y01LbVRPd1Foc283eFhQL1VKR3pocGZWZEp0bUJTM1VYRzNGTzYxU0VSd0hwbg==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=UnRjNmRSQ3pLV29ONnRUS0kvYmY3RjV6OTRGUCtpbzRLWE81ejgvM0hrYUMzMjM0cEpnSEh3OGVUTGxXY3BrRQ=="
+ },
+ {
+ "server": "Episode 2",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZElRaTlRd1loWlRLNFhDL3UxeEZxRFl5VW93a3h4eTVyYWNRUFJMYnJoTnFzbHZpQ2hFejZEc1N3RHJYd05UODlnN29MZURUN2tRTTdUQVg2cEZGcVBuUHJLNEpPaVpzREd6d0ZyNzBHRzFrc3F0aktLYW1zaEhTM3FaSnRBTjF6b2x0aU5NU2FMdU40aTA0dkxMdzVQTg==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=bkd6amRlRWE0UlhxV0dqRlo4b1B3TmVCZklXTWRMWnNRbXlDYWdFTnJYWHFIQ2lqOWl5K0pCT2pMaWdXQzdpbw=="
+ },
+ {
+ "server": "Episode 3",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtLYmtEYjdWVllPYjZLMm1TMXNZaFl2WXdKUk1kbkR5d0Z3Ylo3TTRNSEo4VWxrZnFQVEMvTzduTDhjNG1ITm4zTVdHc3pzdlhMVFVOOHpOSnNWLzMyOHg0SDdFNi9nSThJaFczRkFMV21NVWZ6Nk0ybUNvejQxanF2OWZZUHhBREY2cWNVcCtyMm1XeDBBdFpYWFFlRQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=azkzOHJGMHR2T2YzRUhwWU8raUJuam9MVzZ2UWNXdUNkVVNMdjgrN3FBM1JEVkhJZFlZajcrd1JERENQQ3pCRA=="
+ },
+ {
+ "server": "Episode 4",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEw5L1JZVWZxK09QMWtxbEFWU2ppdUx2SmhKQVFrK0FNNEY0NkJsUDJjZlprQTI3eTlBRW5kaEpQSlN1Vks5RzRUMFBVL0FvQ1hJa2J2R2JIV2ovYUNNVkdZYm9hQjNPY2hLTVZyZml4SUQ0YmROUDFOZm5HbVc1SWpvaXRPZHM0d1ZFMDFUOFBPR0VGRW5qdy9RbTNDSw==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=QVdhWE5rVkhmV3B3dHJKTUQzNEd2VDM3cVJNMW9pN05qQUNDTnJ3ZGR2WmVKR2FVS25heUlob0ZOSnlUUS9TUA=="
+ },
+ {
+ "server": "Episode 5",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExsVjhoaC83WDZCSDZvUlo2bEtOOTNmUmNzUjlmaHlKS01GK2VmcHVTOGQ5RUlEOFhLTnBtdk9LTHRmSTJjU3NLZHdyZEg0a0Z1ZjFCUGxHbzJ2WGo5TDhmNnhyUTR4WkR4MG9hc3EyOTZadkYzN00xYXRqTGt5YnQrZGFVTUdkWktxV3JJcDdubGpoSVN0SkZzdWZ3dQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Qy9GNFN3U2loNWsyRFVGUUh3RnpmbSs1UURJTVllOEJzNDdwOVhHcUxUci9rZWdOS1JIS0xmVGw5L3QxWGZzSg=="
+ },
+ {
+ "server": "Episode 6",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtGTjA3WlR0MUwvODZqckhBQWFOVUNCUWtQaUVZbzFxTmx6UWpOUFJxMnVCcitiWEtpdGtiSEJSNW5iUG5XSkxwWFZ6a1g2b3BkbFJmN1JYblIweW1xY2R6ZjEvSW9xRU5xZnZTQlRpS3lnU0d1NThhdTZhMFAvUGdYQzl0TWprSkRLa1RwTzVJd1N0N1p0NkhLdkp0cQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=WjhBd0J6a09PUWVYeDlaRG5yNU5qcE5KM09ITks2d2NqTkM1UGxtR0c2T2VBTEhnanByRVdBanN0MzJyNDk4UQ=="
+ },
+ {
+ "server": "Episode 7",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExRVlYyVkpzdWxBWUo3bzBzcWs5d3R3dHNXOWxqUHVlWFdkTlgxSGhaUS9FU1E4NXdCS3laSVlSZUlQTDBFWkxnMGkxOUkzdklmellSR2RyTk9uSXpTWk0vWC9jYkVHdFlQOThjZUs5ckNTNGRraGlFYnRmQ3FhcDdIdEF4ZFdEdjQ0MHJPTytZVUFLRTZVdkhMb2ZUUQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=ZjJqSGRoWUtpMW56VlhwTUpzWFVWSTdMazRDSnZJQlQzb0p6dXdTbU1xc2ZrK0FxMzNHSUQzS0hIMDhuS1NUOQ=="
+ },
+ {
+ "server": "Episode 8",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEkzdVZ2UWpRV01CWWJhczc1VUZiM1A0aWlGSHNPbzFnNmNudkdnUXU2QVVUUTBDUGJjTEJIQ2tMSHAzeExiR2dEbXVYaWNZdWtuUFVFUklFbWFLeWNNb2VDRXJ3aVdubmN0UE14bG5NbTV5TkF3VWtWS2RFU2s3WkszRVJpVEVuY055VjNtNWJLVzhSUHV4U1BDMVJnVQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Tng3MmRaUWFERkFaR3ZnR0ZaSzJDaklkMVZudWFFSkE2TGxEREpDYVFUV2J2M1FpNjc1ZHVQajJtT21QZ2t1TA=="
+ },
+ {
+ "server": "Episode 9",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEp6eS9jcnJib1hHeGRwY0RYbHJoMGhSMTlDNUZvSSt0RUlvK2tjRloraWt4Mm5MYUl1MktxbHU5Ry9pS0FuL21TYkphTnZEaXJGdkx6RG9YR3VwaVVpT2g3UkFhUTZjS1Z1eGZaLzhiWjBtUmlYeWFQL1JWbUMwQmdBRnRkYkRhanhqSjJ0aXNJUTRGQy9LRmk4a3V6WA==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=bDZiZXNON0lNTjRCS0tDbDRlb1dRRTk5NCt1V2ZUV1piNGZ3eExZQVFPRVYweEVkWHMzOEJUUGxlOXRLa0RpbA=="
+ },
+ {
+ "server": "Episode 10",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpFZ1Q4elA2S2x2aTZzQ2tvNXBiMVBHclRJbFMraTBPRHVjQUt0SU8raEg2RWlpZ25leFhlQnNialIyQUJWWWlQMEtWUFJsdTM0Z2NmNGJWOGNLcXRDSzhKNlNUa01WK1grTTRBaGdVT1I2VTE3UEZ6ZDVLVjFkVjdVZFZQU1AxaUtqdVRnNnhNT2tZL1JMMExTcEY0Kw==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=OWRIYzFabCtGM1gzQ3RPRlJreFo5Ykt4MHVKeFYwTW5SRndaQ3NqOEg0UzRiQ2FDZlJ0d0ZEcDA3cTQxSHZzNA=="
+ }
+ ]
+ },
+ {
+ "quality": "Season 1 {Hindi-English} 720p x264 Esubs [500MB] - Episode Links",
+ "driveseedRedirectLinks": [
+ {
+ "server": "Episode 1",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZElNMHVBSFVUOGhqOUdXMGtDeDRzeVMrSHlPblJSSFlEMi9ZY2R3OFNXNGJRRk1MelNBRTR6NGlPU2ozVXd4cFFRaFM1MlV4QXVlTWhTK2F2akZNaTBoYmc2ZFRoRmYvcnJDdUJZdDY2RGlFZFM5ZzdRNmF5WUZRU0xVYjNTS1dIUWZ1S1JXcS8rQXBMTGNnVTRmSE9MMg==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=c2RhVDROL3JOZG5GV3RoWndtbi9RMHFnN1YrSDF6eUtuSlA4WWR5ZXdOV0pIaGcvNC9BTWN4cURMSTlRRzR4WA=="
+ },
+ {
+ "server": "Episode 2",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZElzOHFpOW9YeGlEenVtQkpZUjhkaGFobmhVYnZRLzJDRTQ5SHNBRlowTis1QnpTOXFub1E3ZHE5cGpoUFhDVU1hbHNCbms5YXprWTh0N05UR09vOUN3TWI2WXFGUGh3SkdGUUFzSURPZlFMU3lvbk9LRW91T0xKZ1U5SGMyOUxsSFkySmlyZzBSYVBkbHBiS2dsblpMLw==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=WjJOc2dvVG8yTTlocmRzTXdEZ3NqWTNQa1hOd1ZnRFU1RnV5aWRpR3djaXFZK1IwVXYzYWxLa3lBUDRpSmkrQQ=="
+ },
+ {
+ "server": "Episode 3",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEp3RHNXZUxnK3l2VVVoL2hpLzdBckpCRTF2b1k2ZldidEhJMlpGc213Q0dUb3BIUlMwSW9ibmFtalBKSk9PQXJSRWZ3L3E3Yk1QdVA3NGloN21KVWo2L3hIaWV3QStmWGk3c0tWMS9neVRTU2swalV1bHhFM0ROeVFudTR4T00wSWVPNmpjR0dQK0U5NFl3SWNGRHZHRA==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=YXN0eGVCaVRhL0hndU1JVTFqa3NRQlR0UE9YdEdEY1ZMOGxzRG8wbjQybldkWFc2MkR5MjR3WE9XS3QzZ2tZUA=="
+ },
+ {
+ "server": "Episode 4",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtlSkVSTnJrbWVpZU9GK0lYTXVwV0xBMEtPaU9FTFNwaFJVNlBYWG4zMzYxazRqSkV2c2I2Q2FaSnBWVXNEZFRjMEg5bnVubEFDbnk3VUhxVXh6Sk9lWWhWejFvWmlUeXhrNjBXZ24vcU5pNVdMZ0JvNDZvUHZMS0hid3JYOVJYSENzem9BVUI0dHdCc2RpVjZUTXB1Rg==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Q3IydEdlS0NXbUdkeSttRXdqWk9aZFZGcFVpME9wQXVFMTRKTGpKci9qR2lIKzVOSmlzNHV2VUF1NFF1ekJKZA=="
+ },
+ {
+ "server": "Episode 5",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtZMi8rMURQS1IydSs2UzRmZzBxbTV6cUR5NGxXN0pxVzFzZHhteTN4dG92MUlpZlU0dFBOTTgyRGRiSS9wZStzdmR4SngyVHNkV3kwZkVuS1phTDNBNzZJR2VRQWJ4NmM5MkxISHdvRkZXd3FwcVF6NjhJY2RwR0FRMzlsb2c4WkFaN1BLcUFKcldwVFVnNmpvVDF1cw==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=OWhTdjhaaS9uU2hSSzJTc2V1c0lGQmtFZHZ6eHRjKzFLQmhNNmlUSFJtVEc5dGVEdEFYQkF2aE1weFQrNTU5Rw=="
+ },
+ {
+ "server": "Episode 6",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExFVkQ1Wm5Uc3pRcElVTW9rUE5IVXNHU3Ura0dXRVUzMHNrOWYreFU1WGRxd2wxd1RYYnJ5VnJadjRlM2tPcFVYdmE2dEVkZTRpU1h2TGVBVWhJQ1ZHaDZ4WnNDbVBFNVliWVNwQytPeGF5OEZLWndaZFNTbm1ORFVhZzY1NjhpZitIZ2NLZmYweVFwUnFGTyt4dkFaSA==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=TTlaUm9vQXRjMVg2SXprZlFISDRrVDBpdzNwTUxyeG5RekVoWUp3Y3FGK214SFdTVTdkTzJBMDFHMU8xQ1VXdw=="
+ },
+ {
+ "server": "Episode 7",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEplNERKdG0wYk1xSzRGdVY2cFNQYmN1RTJCTU5BMXUrdFcvN3NsNG9ieWtUMjZaU2FDMytPZWp5V0lkeTBzZkhiZVhaRitwOVB5RWl2R3ZDT3BNTGNBOHFLSzZSN2c0ZmkrVWpQZlhVTWlncXBWVHE5MlpFMmI2a3BKSWhTVVdYeHYzRzJpdllXM0tHU2xRQ2tkb2VqWA==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=SFNGTGpTZE1wTU1DSUwrK3FiOStyU2pzV1V2MWY5NGNyVmVnQ1FRZWRmSGxuQUFVSElGNGVXbU9NNHdTR3hRUw=="
+ },
+ {
+ "server": "Episode 8",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEs2SHp3TDFJcmxUQjBUNGlNYUorck5VMGdqbFlhZFhVRHk3YlRYdlRaVXJWZWtMenEybW8xWU1oNjgrNmJZNXp1cUVDd1BTVjBkbDJKZzh5bzgzamVITGF5Y0szamJwbW9paVYvSTA4OVpWVnV1V2dTZHpoVFJCbWg3R3UrUnd5VWx6VXhOYk95SEE1MXhPMHBnT2xVcQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=SmFzM2NEaTBkSjBBNW1MQkJEYlArdUJSUldGYWhxUlJoL1hQOVNPNUR2NnkycTl2aXhSN3FrMGhDcVJZTW4vVg=="
+ },
+ {
+ "server": "Episode 9",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEl3TVBneUl4Nnc4MDIvQUFCSWk5R1RzSklPS2hjMFZXVncyZGFMYUlZNEFZQzhTNkxFVVhzNDFKREVkQ01TaGJGZWlMNEhZY21vMUVNN0U5cVpicXpaV0g3RG1rUi93clhWcmlubWgvWlBLRGJQdUpOOUlYUWhXMkFubU9OMjRBVk9lMnp2YUtBQlNobDRNWVdBOTdmRQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=djU0OCtyWkdrMC9vRmNnbHdGektUVG5PdUlEaXNKUG9jL0JrV0t3ZzZnUklKUWQ2M3pkYXAxOS9oaU9tYkpmRQ=="
+ },
+ {
+ "server": "Episode 10",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExySXZEUkJUaktxSWlWd3BXOHp1d0tvMlZGekxHa2ZCK3lpYkpzTVVEc2FKcTZjbXl6L2ljaGlCNThSRzVFUEZnUmg5ejd0cm1rZTh4QkRSVmNJd2hVS0wwRW9vYmJicXNVamZRTldDU0V0VGZBTjhmUzhVUm85TnNhbTcrQTRWalVBdUpWbkIwSnhmOHRWTzl4ZVN1bA==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=aEZoSFlxZHRiK0F0OWtCSmxDOVRZdFE1VnlwaUZnOWozYUg2WDNNd0lzcnJ4bjNzVlY5akZ6TmI2NmNNNURrNw=="
+ }
+ ]
+ },
+ {
+ "quality": "Season 1 {Hindi-English} 1080p 10Bit Esubs [970MB] - Episode Links",
+ "driveseedRedirectLinks": [
+ {
+ "server": "Episode 1",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEptWXBMMVZiYzVaZFYwYXp5emZBUjlkcmp5eG9PT1hYQjR2czJ1ME5MVmRyK2JtT0ZXci9uY1NVVEIvTFZ0WjVtUTR3ZzRqSFgwS3hhaWhseHpYWVFzOXpENS9ySlJ3U3AwbkRQdGR5cTVML1p0dzRVcys1V2oxUllZNU1CUXgxN3QxeUgvN01PYjNTN0JncE1nMmhxTA==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=VlFVOVp3RThlc1phanBHdURQdm9HVVo2ZytmT1JqVGxkR0lqUS9ZUXBaLzE3RlhaL2JNbkxQcVV4SkJvNWY2dQ=="
+ },
+ {
+ "server": "Episode 2",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExrc3ZYTXpxNWJoRFJFSWVjTFFTWXB4TWdaTUlhbFJUTW5MVEJhSm1oWDA5SmJLNGhxcjNnbFlHS1o3ZUZZVlE1U1BGaC9CWUlOTmhyWjZYazNsOHZudHkvQTBmNzFXd2NWcnpaUHlrQy96RWYrQ1dBVUVJdmtXelRnNis2ZFM3ZFI5N1FTdVd6VnlPZUF3Znp4ckZJaA==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=czB5SG9hL0ZLaXY4dEJMdy9yQVZvckZTUmNaOU5MWW0yZjgxR3BZeUpIWUFxWHhNOGFwcDU0K1ZJYVdQL0ViUg=="
+ },
+ {
+ "server": "Episode 3",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExFWGtXbkhCbUFBN1Z1ZEZJRXEvQ1BNVUZuZkczWXFVVjVFWjBoc3FqTDlrVklPT0VMNkRTbGpOenA2K3pzTWV2cnpqeUNBb2hsT0FvVmJmZDlSdFYxZkhaZGhPTldVakpBVzlQeXJsVTRMWXZDaHJIdzU2N3RPMDV5M1ZDaCtGQkFneE56QWp4Sk5QWndBUDY1QmZ6Zw==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=K1VYdWloUnluSThFeFJiQkxkWS85VFJvT1JkMyt1MUNDYUZTUkthYXdzMDdDUS83WEZ3VXdiOU9SakRTODg0OQ=="
+ },
+ {
+ "server": "Episode 4",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtlV0Z0ejRaQS9vT0dwMWNGZzhQR2RlSnR2Y09PQy9BTlc3RGVSMjUwMEVJT0lVV2oremZsV0JSd0s1SThqTFJIbEk0SERxM2pDQUZTTEV5R3dsVXk0WnNUbXIrNHl5YmdhS00yRWJRSUpnbDllUzRDWVlZalRjcEZZcGd3UmdvRitabnNTcHlZVWJBZWtTYzlTcjNxMQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=dXZEZFVPeXNnbzkzNjJPMFM5K1dkbGZGNXY5RzZZODYrRTlsZ2lCYzl5UkhWRTZXYTlBbjYvV0RiQUFLNFhoUA=="
+ },
+ {
+ "server": "Episode 5",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEsrVkd1SkIyNnBnTVp2ZEJTcGJTMGNLem1Ja0JuMHlDUHQ1QTJYa20zVWdwL0I4VFhkaVNEdWNDZ2l2RkphWG1OQmYrWmhnRVhVL0V0RDBNRHZhNFNyU0JqWlV6K1FiMmxFVCs5N2p2YlV4eEh2RHUra0lrOGtkY3hRL1k2Sm1qZmlxRkROWEJ5cWw5bVMzYjMrbWt0Yw==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=TUNyZGxZb1NRN3lseTZGRjFFRnhuY0dLUEhNL3VBN0txMElqVWF3eDJrS3ZXUy9GUHIxTXB6ZUduRlB5eHRITQ=="
+ },
+ {
+ "server": "Episode 6",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEwxdklkdSttMFBENTBOTGlkOHE2Qm5zbU1VUlM1WFFqSnB6NkRRd2xTY2F2WVpaNGkzY0xzelZ1Wk9RNXZRTUR0MTJWWDRCZm82bUd2T1RDUllzZzcxNER0cXQyTzlaTlhNWmVCaENhcnRqeDRCM01rbU5UdmpweVl4cnVuWWFjK3NncnBlVlRiTHEvbHZYL3JzSTEwaQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=bzJpL3ptZ1V3UTJEMHRrcGJqVlVEeDJOdFp6S2pGY3VFSjd6ZUNXSmZKT0N5L1pGZFFkMGtnbW0vZlRsN2swbg=="
+ },
+ {
+ "server": "Episode 7",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZElVS0FUQWdMcm5hVTE4Njh5NlVBMTFzMjJxcEsya0ZzT1pRMkZ6N092bWZUbTg5UHJPV1pPdm9YQ0tpNnNJNldnU01BOWppaUdTaW5zWVhQaU9qMXFiMVVISzZZNG8rTzY3WjI4Y2JQZStudzRGa3MxSmtKbWJXRTg0dmp2M0NENTNJaGtYZlUvNzhNemt2RFFsTEhlKw==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=S213TDNGWVduQzE5SnVvS3Y2VWtLeWlkTmpNMlEzMUswb3NiQ1ZUL3h2RGorcXNmQm0xTjBWRzJwSTdxVWkzVQ=="
+ },
+ {
+ "server": "Episode 8",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEl4bG05d2IzR05OLzNhY3VXYjVwL2xtZWNvanhmYVVCVk9mcklVdi96RW5xUW8wODMwZ1YwOEJibjgwaVZreU1ndGgxbzhJUUF4TTNXN2kvRVR5Sm9kY0VDdTlhenp0OGk5M1d1UzhhQTRhWHRNOUo0djNiQzFzNDExMXRuL05zb1Q2Y3ZhckJmcTV6QmhqOGxDRkUvOA==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=SmJudHFnUjBpTnFUUjhDYWZuaU4vSXBrN2xzUUYyb0ZiN3ZTeGlTS1N4UzF4Q0xLc2VHK1FoK1ZGSkQ5dXU5TQ=="
+ },
+ {
+ "server": "Episode 9",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEx1akRqKzRTOXIzNUVzbE1VVEtNSGt4OVJDV0xnTTkyVlo0S09udFcrbmU0cko4R1NWM2hGWmV6UXRvV01lQ3hxN1V3L3VKY3Q3YlMxazRZRHBNRSs4Y1RRQ2owZ1VjelJESGp3WXRiRGdmcGVOc21YVlhuT21QQW94MFhONy9KWTcyVnVtNnExTUlKTHlKNlQ0d1NIUQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=dHNReW9XQTM2emQra05ET3FZbmFrNEN4RzloUkdxQW9sYW16K0NTU2MvTWg2VUxpZTBnYTZNYW92bmdEZmtEdA=="
+ },
+ {
+ "server": "Episode 10",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtpYTJKdlJ3c1F4R3grd1FDV3JpWnhPbEdyWjV2RnhQT2VEQWY4SXE1K0NVajI1aFgvK011am5JUWdPaXo5K0gvRVZGWDJiaGZUZDJPVEZKRWpOOE1oUE03NlgveFlLamNLMXA2UE9seWJma3cwanZmWDFtTy9XVnZyck9DbHRPdVczSVB6K3g2TEI5aCtEa0RnM1pjQg==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Q3Y5TXdaMVpSNHpsVTRnWGpDMncxeVIrNXMxOVVmOGdNUXJadFcyb05GL2FPRFdweWlDNUZiS2srcGxTL2x5aw=="
+ }
+ ]
+ },
+ {
+ "quality": "Season 1 {Hindi-English} 1080p x264 Esubs [1.2GB] - Episode Links",
+ "driveseedRedirectLinks": [
+ {
+ "server": "Episode 1",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExZWXo0Mzh6anRBc1k2OWljeXFiYkdXSHEyV1lYMFdDVk10VTNkNkJCanZoSEtWd2g3aFYxdERITkx6OUlsalErYWRKcGtCVFNUbjFGVWEyLzNva251a2tmODhYZUZOallmN21TVFBVaTEzSWhwbGlVV2ZvSGtSTTBqZk5uMm9hdENIZmI5VjBwRXVSY2xrajQ5Ni9ZVQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=KytGSDUxVkV2Y2RSRUxoTXhwWnNYNlJBa3JWU29EeEs3cFFCZkxOTWQ4Vy9rVkZXV0pOMHU1NEJ5S2JvbVY2VA=="
+ },
+ {
+ "server": "Episode 2",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEx5ME9yM1lWdHIvTGNRejJnSDB1Y0hGVXg5UXMxblU4VEh4aVFBUVFVNk5US3FEYXVEdW1iaEN3NkdyN2FyaDNucGxGbThtQ3VSa0IxN1hmWElsditkRUJpei9aWVA0RWpHd1dOQWQyOVM4Sk1FTzQyYlRYZ2V6eHUrTjVDWVZlTmFmdG5yMjAwdnoyUGs1VHhwWGZYMA==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=VEdRMXJPeHVSZXJTckY0eUxjdDJ1TThKQVNvVUUySWRxdjBwUjNDRGU5SUc5TnlHZzRobWhmay9DOG9Bdnd6OQ=="
+ },
+ {
+ "server": "Episode 3",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpwRStQMTBhangzQkU1MW9lcXB1RUlzMHh1WTBrdmVjaHpqMlpuYkEraDlUQ0gybmV1WlVjQ3cwd3p1ZDM5MmZhV0NIUEpoWWM2dGZxczRIZnZNQkV5VmVZMVF6VWd2STFUM3E1WWdBb2swUCtUUmZzMEoxSTY5OG1Xa29RRlR4bjF4RzBBeHlsSkxGY3hrM0s2WHBEdQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=NDRCaWx1RTM3SWNmN3QrSE9iQ0pKQUJoNzh6VGVlYVBKdmZVUDcwVXJGOGJ6TzIycDI5cnVNY0NzU1lwc1Znbg=="
+ },
+ {
+ "server": "Episode 4",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEwrN2w0MHdjTHpTenJzRjByVlU5eUh1WEhCbDhaYzc5M2I0S1lsS3Z6Qy94OEtkaU1ybnlmNFV1VkFaVVUwMHUwSmkzZzJ1ZjNydkRYQTNFdWpMUWI0cit0S0JHT1Fwd1VibFNxRUNoL0NJVjBBTGpiTGFBUFhvcGQxY2xJT0VnU1o3ejQrQnNzZFVqdHR0MGhHTjRpNA==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=a21MUG5FTFFlZURiZXRRaU5kS0pZYWNodFlMWUl0K09CU080WDhhMnFWbEp0YnF5d0lSaGRJRGw2U2d0bDIxNw=="
+ },
+ {
+ "server": "Episode 5",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpDaTVoNkQvOVI4UnRNRzF3S3BYOWgrV25md0xnUzhINHZQbDZyV0xOallqb1FOeVRWaVpjWExvY0hFejhKVjFxVjJvb3Z2SUc2ZWNiaVowYWdxZVFOVWl3SXV6UlIyaWloOGFmTGx6SGdLWjNBWGZ6N2JRVGVPNDlWSlNpcHN3YkhuMEFpM3hzdjU3cHE1TTd5NzJqRQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=MUMzWENQeGFWUzhlOXpWNkQ0ekNqR0RuQUJPNG5xZktiSlZnbFFodkJpczY4Mm4vbTB0dUU1ZERWcjhvSVhWRg=="
+ },
+ {
+ "server": "Episode 6",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpnd2pDOTBlVWhhUTZzOEJRTWhERVlTWkJ2Z0J1MTRFRisxdGczQ2VXSTY4dmNyeDRxMi9UU1Y2ckRsRllnL0wzN0MrZFVKZWVsQmYxdjFMYmhhVjd5SnplL003bnFlbXRFLzJZSjJSWjR4SVNPUlpULzZNYWd0TG9NWWhmemk2MzZqcHd5Qk9wVENRd0JxeHRzRlRmQg==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=WHByMlZFUCtUVkhMSkFEaTY5UmtmNWQzRWxuRVVsZWZWNzJmVEE5dlg5NjgzUXlKeDNVbnZmVCt2VjZFNnZ0dw=="
+ },
+ {
+ "server": "Episode 7",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEowUFJJRWdlWHl6TGZnUXJuczZhL3RPdVV4R1ZzTEJydE1xTUJxTXFSSmtaWkoxd2lReEl5bER1cmRBQ0ZETisrSHZ3MEp3QXRnRVZCd1dPdEMyWHltUGgwUURMbnhvbEFzY0xZMjhLUWIvMi9FOGNkR20vdnhDOFd4U0s4dXdzTkJxODBJbi9IRzJmVitPTXYxZUZGQQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=VXQzT3VWZ3R3NStPYXlOTDBNSjNEYkpVYmJnM1k1VTg1WXpldUEzMEZoWWtJWXdVUncrUEduWCtWeEp1Qi9nUA=="
+ },
+ {
+ "server": "Episode 8",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpJNzhNdUxFQmM4bXA5Qm51eU14RDdFZzVhSEwwNE1weHZPajRzSEJwQk51djJsVnZJZGZQY1JZQmRvdHdjZ1RyS1RMUVRGZEVwYzdndUE3dUpudDAvMkV2bEo3NW0xRmRLMjVjWHJRR2I1Z2NyVVZPSTQvWkxZQi9neEtPZG4ybXRNdk9xaGUxNVdSNUpyMUhLNmVPUw==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=dTJYSExoSXBjTGZkTTBjZWNINUNuVFVLMlZEazR2SWE2cjdpWFVzd09VY1FpRFFjTytOWVV6MGt4a2pCazgxZg=="
+ },
+ {
+ "server": "Episode 9",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpJSTROcHA5UmV4cXhjYTFmQVMvZUNKZmNtV2lHYnpHakFiaEJLSDRseUdYa3BNdmN6R3loOUEvYlViNlExS3JnM0ZPK1JpSzY1SHpuN2s2MDZuYkh0a256YnhyUnQxU2VaWlVDV1Y5cVo1VUlnMGxIWmRaY2I0TUR1SHJUQ0pvUUNrdys4VWp0TWhha0p2bSs5TjQ2WQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=enB3enJJeE9HeG04cXBoVkJhL1V3ZWQyVlpPU0Q3NHRXUWJiWmlFVGdCZlN0UGtaalFwYnNsMkh5Mm0xT29jRg=="
+ },
+ {
+ "server": "Episode 10",
+ "url": "https://tech.examzculture.in/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtraXJtMzcwWWYzL3F5M2YzcjRFOUxIenVQY3dvTld6Sk9pakxocHpaSDEyNDNOVHZ2WUVUNnRCZTIxVEgwbTBQZzRJSU1BbkozSEpJa0FXbzdPSFlNZzREUVlsaUNDa0Nxak1CSlVlSUN4ZE1kWUNvU2hwVjVwdVJvSjFqcGNPaXplakE5c1lxM0pnNXh5OFEvc09ZVg==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=QmpLVFI1c3U2bnM3bTEwQU4wV3E1WnFMa3RxMVhscS9la2NqQUhjTmhjdXZXVEx5Mm9Xa1lsNjlSVVpZajdvYQ=="
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/moviesmod/moviesmod_final_v13_293660_movie.json b/providers/.cache/moviesmod/moviesmod_final_v13_293660_movie.json
new file mode 100644
index 0000000..835b37e
--- /dev/null
+++ b/providers/.cache/moviesmod/moviesmod_final_v13_293660_movie.json
@@ -0,0 +1,64 @@
+{
+ "data": [
+ {
+ "quality": "720p",
+ "driveseedRedirectLinks": [
+ {
+ "server": "✅ Fast Server (G-Drive)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtpNjQ1ZFhZeDl4NlZVcm9rQ2lsL0hCM0k3VytEUzRpWWMvZ1FBZlNqRDhrTE5wQVdjeHNQYzJiRG5FMDJWd3lGSXc1LzFPT0hVWFlaWTBZOGw3aDN0V1lkNDVpK0NZVjFXLzh0UGZLSzUydUU2VW83U1YwRWJvdkhVMnh1MVk0Sk9tUm9Ra2FHWVpCQXZpS3R1RGdlNA==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=MkR2QTY2K0pua0xqOS9xa0pmNVIycmNiTndtQzBxbGJ5VU5vVnU0eTh3RU9ML3AydUlJU214bUV5cGx6Rlc2cw=="
+ },
+ {
+ "server": "🚀 Google Drive (Server 2)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEo1Qm4wbW1FSnJlWkpuWWoya0JZU3VPbXVCMTdlOFNlTEpycW9nUUpPN1Ric0lnbm5mVGQxS1FGdGFjbHZ5WHN1VllwMS93QXdoNzdYdE15Z1VuQkl5TStmTUpaVzA2dWdxSEZ2WmhxaFZaS3JML0RxQ1pTNlY2eUdzbjcrMFBBSit3TnlGRmNlamxvQXJISTNNS1Y2RQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=RURQY0lpbE1IWlNaZDhkNld1MFFnSEQ4V0xXNFJEeHZNNGFSZ3lnUW54aDZTLzUrRXdhVVRLaEhITno1ejFYdw=="
+ }
+ ]
+ },
+ {
+ "quality": "1080p",
+ "driveseedRedirectLinks": [
+ {
+ "server": "✅ Fast Server (G-Drive)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZElqenM4UmhUeEJKTlpncjJnbVR1aldlTmZIb0kzcStJdm9vMGx6UmtGWUtKMjBWMXdYM1o5U3pseEJJMEMvN29McW9qeXZrZTVEa1F1ejlFbUgwRFBJb3dDTTV5TVoyVktJOGk3eEZYUys3Y29sQW5GcmtqaXZEMk9MSk1JWm9JSVlVTWdoSWdVQWNiQnpEYXp6Q054Vw==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=dHV1dW9KeTlVMEM0UERzaVFaRWVTelN2TlVEUG5IUFdsSFdDYk4vZ29WamhPZThPcTBRRk9oc0lhTnppSlN0ag=="
+ },
+ {
+ "server": "🚀 Google Drive (Server 2)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEtSYVErY0dNVXJDenhFZzFHZ05mR0ZOWWJ1eWJCNEgvdWtFRTlwY3orekF4QS84LzR1enRuTnpxMFZLT0ZGYkxVdXNuTHNWUklUUDh0SEkrYlYrbHI5MUFRcUo1UWNRSm93b2FScnA0YVU5T3dFeENHa2xHcjhYSXNBcXpodkE0alpOMW85L0ZoVS9MSzRFY2trS0NnTQ==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=dVNjL3hNRXhseGRrenJhQzFwQ24yekphRXhyL1JtUzBxUXlCTVgzUVNOSHRmbzhKK05BU3FjT0Q3MFhrMzlRYw=="
+ }
+ ]
+ },
+ {
+ "quality": "720p",
+ "driveseedRedirectLinks": [
+ {
+ "server": "✅ Fast Server (G-Drive)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEsrRk5KdUcxZG1IblE5T2d2cGowNW9mT2dLd3ZHK0tzeXp1TnJVZGs0cGs1Mmp6d1kyK1lMY1lERitNL2dlNUtlMGJxa0JaYncrRFNzeVlZOEo2QUJLc0RWTGtuRVI2TTZ4Mk1hUVZCQTVlTUo2d3FmcUVrbUFOQnY1RUNFd3J1TmxHTnQvVE5yL1BoNkkwaHVrdVBiZA==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=ZjU4U21qeFVnN2x1RDhVbm55VHFJUWU1b2JHVEljRm96QzcySzV0NFZqRU1HU05uSlN5ck00TUs3bnFRS1ljWg=="
+ },
+ {
+ "server": "🔗 Gdrive Links (Login)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZExBSThhUFBxd1BlaE81V0UwOCtVUGphK2lFL00xNXJ1OEQyaGJHckRxSi9SelBiNTFMQ3IzNENPWXhoeDg0SjRGMmo4WTFLMVYyOGhRWXVjSDNkajAramZtMHF6dHFpd2NqZGYwWTE3aUxqcGxYbHJyc2xHWUw0anNXUmpUS3E0SFVZc2cyU0RJVEl0Ky92SThreVVLdg==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Z2luaGp1aXZ4WXkwSnFBU3pyZWxiU21Mb015bldhdTkzd1JTMkY5bU1CVVB3Q05sUTd1NlRKbHZJSUNnanREUA=="
+ }
+ ]
+ },
+ {
+ "quality": "1080p",
+ "driveseedRedirectLinks": [
+ {
+ "server": "✅ Fast Server (G-Drive)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpxbCtGRHB6dmUrTUp2ZUl2R3pHVGhyaDFTVUJCTDhsTnBTbXBmSFRwZ3BVUk5tS0xGRVJJd245eFgzanlKZ0Q4SzlPakFDQzNZZHhBdFVleFNCL1p4UGpxd1hFWUdXNXBWSm5XQ1FQWERXcDE1RSsrTjBVNGVmeHR6aDFwbGNrbkJSL004T1d2dTJ2MHlrYkhGSmlIQg==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=alBtU2J0bGprbXYxbzhJcmwrTXc3ZjhDMFhFV0xxZ25ocUliR2NZbkcxMkp5RER2QmlMNjNBWmxEZXhoeUpaRA=="
+ },
+ {
+ "server": "🔗 Gdrive Links (Login)",
+ "url": "https://tech.unblockedgames.world/?sid=VWNwbWlPV1lMWFcwa1ZDb1dxQVBZcExWbFhIM3l3TExmMjg5TGlNcDcrSmhRZmlMWEs1b0pXRUlnRllnckQ5dWdJTDRiOGNLM3N1WWx5d0Y5Vk16SGl1MHN3ZDkzUnpPVW1vRUM3OFNRZEpPSnl1Ri9xazhmcVUwakZydFg2NFZVUzJRbUxqdjkvSktycFBKWmhML2F5VXpYMCt6c1draXQxVGYvWEhLK0xwNVJVTVZQSlRiWUtHTUd2TmNuSytybHd0czhlcFdwM3cvZnZnZ1YrcmNhTUdDSUxabU1nZ04veXlCYUIrSFIvbkJmSWpmSkFkOFVHTDJMVk5ibkw4Lw==",
+ "driveseedRedirectUrl": "https://driveseed.org/r?key=K09xNUEvbnBzaGh3Ym94RVQ2QW5aakdHV240a1M3RjhuRUViSHlYenpPVT0=&id=Q0o2RUdsdE9iZDhIYlQwMXlRdjEyMlA1NEVKZkRmRUNYZTcwdjNGa3RPa0xHZ29Na0taTkM4T2ZjWGZmRWxkQw=="
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/showbox_final_url/v3_movie_1263256.json b/providers/.cache/showbox_final_url/v3_movie_1263256.json
new file mode 100644
index 0000000..2857bb4
--- /dev/null
+++ b/providers/.cache/showbox_final_url/v3_movie_1263256.json
@@ -0,0 +1,4 @@
+{
+ "showboxUrl": "NO_URL_FOUND",
+ "timestamp": 1757925353144
+}
\ No newline at end of file
diff --git a/providers/.cache/showbox_final_url/v3_movie_1893.json b/providers/.cache/showbox_final_url/v3_movie_1893.json
new file mode 100644
index 0000000..ba724b9
--- /dev/null
+++ b/providers/.cache/showbox_final_url/v3_movie_1893.json
@@ -0,0 +1,4 @@
+{
+ "showboxUrl": "NO_URL_FOUND",
+ "timestamp": 1757926777078
+}
\ No newline at end of file
diff --git a/providers/.cache/showbox_final_url/v3_movie_278.json b/providers/.cache/showbox_final_url/v3_movie_278.json
new file mode 100644
index 0000000..27f2d6f
--- /dev/null
+++ b/providers/.cache/showbox_final_url/v3_movie_278.json
@@ -0,0 +1,4 @@
+{
+ "showboxUrl": "NO_URL_FOUND",
+ "timestamp": 1757926668402
+}
\ No newline at end of file
diff --git a/providers/.cache/showbox_final_url/v3_movie_293660.json b/providers/.cache/showbox_final_url/v3_movie_293660.json
new file mode 100644
index 0000000..2791ed3
--- /dev/null
+++ b/providers/.cache/showbox_final_url/v3_movie_293660.json
@@ -0,0 +1,4 @@
+{
+ "showboxUrl": "NO_URL_FOUND",
+ "timestamp": 1757950186614
+}
\ No newline at end of file
diff --git a/providers/.cache/showbox_search_results/26625ddb20d0988d0b6e7424b1119266.txt b/providers/.cache/showbox_search_results/26625ddb20d0988d0b6e7424b1119266.txt
new file mode 100644
index 0000000..16f4458
--- /dev/null
+++ b/providers/.cache/showbox_search_results/26625ddb20d0988d0b6e7424b1119266.txt
@@ -0,0 +1,4 @@
+{
+ "result": "NO_MATCH_FOUND",
+ "timestamp": 1757950186613
+}
\ No newline at end of file
diff --git a/providers/.cache/showbox_search_results/53df977907f5f20f1eceefca3ccc898a.txt b/providers/.cache/showbox_search_results/53df977907f5f20f1eceefca3ccc898a.txt
new file mode 100644
index 0000000..07a05ea
--- /dev/null
+++ b/providers/.cache/showbox_search_results/53df977907f5f20f1eceefca3ccc898a.txt
@@ -0,0 +1,4 @@
+{
+ "result": "NO_MATCH_FOUND",
+ "timestamp": 1757926668401
+}
\ No newline at end of file
diff --git a/providers/.cache/showbox_search_results/9e500cc99ed9b9a4e816b2646064c346.txt b/providers/.cache/showbox_search_results/9e500cc99ed9b9a4e816b2646064c346.txt
new file mode 100644
index 0000000..72337da
--- /dev/null
+++ b/providers/.cache/showbox_search_results/9e500cc99ed9b9a4e816b2646064c346.txt
@@ -0,0 +1,4 @@
+{
+ "result": "NO_MATCH_FOUND",
+ "timestamp": 1757926777077
+}
\ No newline at end of file
diff --git a/providers/.cache/showbox_search_results/f33b097143b0654432d600639f68b08f.txt b/providers/.cache/showbox_search_results/f33b097143b0654432d600639f68b08f.txt
new file mode 100644
index 0000000..7f9e5c4
--- /dev/null
+++ b/providers/.cache/showbox_search_results/f33b097143b0654432d600639f68b08f.txt
@@ -0,0 +1,4 @@
+{
+ "result": "NO_MATCH_FOUND",
+ "timestamp": 1757925353143
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-1263256-alternatives.json b/providers/.cache/tmdb_api/tmdb-movie-1263256-alternatives.json
new file mode 100644
index 0000000..428a401
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-1263256-alternatives.json
@@ -0,0 +1,10 @@
+{
+ "id": 1263256,
+ "titles": [
+ {
+ "iso_3166_1": "VN",
+ "title": "Chàng Happy Gilmore 2",
+ "type": ""
+ }
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-1263256-external_ids.json b/providers/.cache/tmdb_api/tmdb-movie-1263256-external_ids.json
new file mode 100644
index 0000000..40dd7d4
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-1263256-external_ids.json
@@ -0,0 +1,8 @@
+{
+ "id": 1263256,
+ "imdb_id": "tt31868189",
+ "wikidata_id": "Q130269576",
+ "facebook_id": null,
+ "instagram_id": null,
+ "twitter_id": null
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-1263256-images.json b/providers/.cache/tmdb_api/tmdb-movie-1263256-images.json
new file mode 100644
index 0000000..b47cd29
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-1263256-images.json
@@ -0,0 +1,1224 @@
+{
+ "backdrops": [
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/ihUv6tsZnaBm7WM8oPzJ7zVG3gZ.jpg",
+ "vote_average": 3.334,
+ "vote_count": 2,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "en",
+ "file_path": "/rME9z7Ft1mfQanuoGARFsU97P4e.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/x5dVPttNDZaVRTvbk7pYrtGZoZN.jpg",
+ "vote_average": 2.542,
+ "vote_count": 4,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1350,
+ "iso_639_1": "zh",
+ "file_path": "/m7vBHmPQSokvN4hMQDxdJBdqAtJ.jpg",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 2400
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/mRrOfAJKldUuXfkfHZU5OBlqfss.jpg",
+ "vote_average": 1.562,
+ "vote_count": 8,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1152,
+ "iso_639_1": null,
+ "file_path": "/6WlFTFswrSop08eD0SA6zWTyOEr.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 2048
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/88DDOXggxZLxobBolSRRLkaS8h7.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/3e0l5whLFcVYqC9OLWSVjez7HvB.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/xNKrcUlehKCIv1wSvYsqksSa1JV.jpg",
+ "vote_average": 1.222,
+ "vote_count": 4,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/nKYtIfeF1kPQnk7BkC5UpzgPvX6.jpg",
+ "vote_average": 0.958,
+ "vote_count": 4,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 960,
+ "iso_639_1": null,
+ "file_path": "/iJKgvzGmotmF9ASiDvOmfjSm4kB.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 1707
+ },
+ {
+ "aspect_ratio": 1.777,
+ "height": 1082,
+ "iso_639_1": null,
+ "file_path": "/9yfLUT4ODjbx06wpil9NHTfV0uc.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 1923
+ },
+ {
+ "aspect_ratio": 1.777,
+ "height": 1688,
+ "iso_639_1": null,
+ "file_path": "/p9heMCUK7E0YXqoDsojuAGwvPiy.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 3000
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/gorm72q6sBxfbC0K3hL7HmBMHxx.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2055,
+ "iso_639_1": null,
+ "file_path": "/wjexxhms10TlvHoW5Ie7B68lUJh.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 3653
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2064,
+ "iso_639_1": null,
+ "file_path": "/qrGM5Boooc2re48Q1w049Qys3Ry.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 3669
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2058,
+ "iso_639_1": null,
+ "file_path": "/pPK5Fsbps0DH6DgkesDGtLvKSfU.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 3659
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/stCEYCxA3SknIIne1H4LmaIJ8ii.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": "en",
+ "file_path": "/grVku2u09NSW4PY2Hb47T0Ed1fs.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": "en",
+ "file_path": "/rDq7TsiEMdcSxQHf0WcqA9eG1jq.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": "hi",
+ "file_path": "/72YkyEygmXn4JwQhx681HsZW7wG.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": "en",
+ "file_path": "/s0ncoRPa1Rjt9cYlsw1FLTwXxce.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": "hi",
+ "file_path": "/vTq5FRkWq4QEpyzqNSYf3xj4kvi.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "en",
+ "file_path": "/7bfqmA634d6U7FYtPu17oRC8qkH.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "de",
+ "file_path": "/qIhrIFic9xtyab7PlIoCIL5g9N0.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/vfGNV5Nkg7x4xeEPOl7b7avU7jj.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "ka",
+ "file_path": "/9oiv7u0aa0JEXeeCsobSN3jPFj5.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ }
+ ],
+ "id": 1263256,
+ "logos": [
+ {
+ "aspect_ratio": 8.5,
+ "height": 46,
+ "iso_639_1": "he",
+ "file_path": "/uXjdVSvmgYDaiPL2xQ1tfjzOPer.png",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 391
+ },
+ {
+ "aspect_ratio": 6.132,
+ "height": 53,
+ "iso_639_1": "es",
+ "file_path": "/r6mFJCqr2M9TbR6TwRGmHwgsBOf.png",
+ "vote_average": 3.334,
+ "vote_count": 0,
+ "width": 325
+ },
+ {
+ "aspect_ratio": 8.835,
+ "height": 206,
+ "iso_639_1": "he",
+ "file_path": "/tulJ40JokNBrKCIh8rb7wvLFhOT.png",
+ "vote_average": 3.334,
+ "vote_count": 2,
+ "width": 1820
+ },
+ {
+ "aspect_ratio": 7.395,
+ "height": 172,
+ "iso_639_1": "en",
+ "file_path": "/hdmcbySpSJckkxtJqJ9mP4Ocq1d.png",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 1272
+ },
+ {
+ "aspect_ratio": 2.577,
+ "height": 744,
+ "iso_639_1": "en",
+ "file_path": "/9KVifMt6xExnDszNjFjX4qyjHkp.png",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1917
+ },
+ {
+ "aspect_ratio": 2.606,
+ "height": 307,
+ "iso_639_1": "en",
+ "file_path": "/664JRmHu2idytOr0W95AP5crJj9.png",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 800
+ },
+ {
+ "aspect_ratio": 2.589,
+ "height": 309,
+ "iso_639_1": "en",
+ "file_path": "/bIiO6oSVPraROb3eh4FT1x3dV9V.png",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 800
+ },
+ {
+ "aspect_ratio": 7.103,
+ "height": 185,
+ "iso_639_1": "en",
+ "file_path": "/blh0HC5EXahPOlB19DNujwEKIWM.png",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 1314
+ },
+ {
+ "aspect_ratio": 6.849,
+ "height": 212,
+ "iso_639_1": "zh",
+ "file_path": "/eVmv47zzRQ0xmfU5PWgwkUf9BTk.png",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1452
+ },
+ {
+ "aspect_ratio": 5.651,
+ "height": 63,
+ "iso_639_1": "ar",
+ "file_path": "/twVZ9bFApyNtLmyo85IpqHQNDni.png",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 356
+ },
+ {
+ "aspect_ratio": 11.706,
+ "height": 109,
+ "iso_639_1": "pt",
+ "file_path": "/dL92vYPSlK5V34muqK6h16JvL7F.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1276
+ },
+ {
+ "aspect_ratio": 7.407,
+ "height": 172,
+ "iso_639_1": "en",
+ "file_path": "/zN9Pzh5WxnqsuvC9tdIpJvNYRfp.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1274
+ },
+ {
+ "aspect_ratio": 9.652,
+ "height": 46,
+ "iso_639_1": "uk",
+ "file_path": "/zQiwlvlSAfLXyGdYWvFWVCeR5Pg.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 444
+ },
+ {
+ "aspect_ratio": 4.908,
+ "height": 76,
+ "iso_639_1": "th",
+ "file_path": "/3eKn4bDyo2SGDsnuRMxdDJxv1Xp.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 373
+ },
+ {
+ "aspect_ratio": 11.261,
+ "height": 46,
+ "iso_639_1": "ru",
+ "file_path": "/vF7f41GrcI8tki7OgqyyVuzFbAv.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 518
+ },
+ {
+ "aspect_ratio": 3.897,
+ "height": 87,
+ "iso_639_1": "el",
+ "file_path": "/ttteRuMFzgCgvnj5UEya0SAH3fJ.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 339
+ },
+ {
+ "aspect_ratio": 10.239,
+ "height": 46,
+ "iso_639_1": "it",
+ "file_path": "/6cGPLQaGgBj0wIu1bH52DLxQAT.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 471
+ },
+ {
+ "aspect_ratio": 5.857,
+ "height": 63,
+ "iso_639_1": "hr",
+ "file_path": "/5CrdMSvItb5MJiGef7l52TciE8B.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 369
+ },
+ {
+ "aspect_ratio": 10.674,
+ "height": 46,
+ "iso_639_1": "da",
+ "file_path": "/vGgAF2Ax6wigeoOctJOufhtQOxr.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 491
+ },
+ {
+ "aspect_ratio": 11.261,
+ "height": 46,
+ "iso_639_1": "ru",
+ "file_path": "/eYaWniXSOdp2uAii3850AsxgUBN.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 518
+ },
+ {
+ "aspect_ratio": 6.849,
+ "height": 53,
+ "iso_639_1": "zh",
+ "file_path": "/ju3Mj0XADpTluRvZHQId4XjzyfG.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 363
+ },
+ {
+ "aspect_ratio": 4.724,
+ "height": 76,
+ "iso_639_1": "ja",
+ "file_path": "/3nJzRSrAdMXWUURjvZ0AoJHvfO6.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 359
+ },
+ {
+ "aspect_ratio": 6.132,
+ "height": 53,
+ "iso_639_1": "es",
+ "file_path": "/q2HwfHrfuM3RMjsCwQ4BG1KuP6n.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 325
+ },
+ {
+ "aspect_ratio": 3.586,
+ "height": 87,
+ "iso_639_1": "zh",
+ "file_path": "/fOdanOhGssviLpe0X6TFVfNGjjd.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 312
+ },
+ {
+ "aspect_ratio": 6.849,
+ "height": 53,
+ "iso_639_1": "zh",
+ "file_path": "/aofR79CjciXZBe3wVhtR574m0ew.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 363
+ },
+ {
+ "aspect_ratio": 9.652,
+ "height": 46,
+ "iso_639_1": "uk",
+ "file_path": "/5o2CC0LkTanwqEECa6uRFryihjb.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 444
+ },
+ {
+ "aspect_ratio": 5.968,
+ "height": 63,
+ "iso_639_1": "ko",
+ "file_path": "/wvaNBIugFfDSpEMtaUQ3FJLDUgO.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 376
+ },
+ {
+ "aspect_ratio": 6.849,
+ "height": 53,
+ "iso_639_1": "zh",
+ "file_path": "/aAhZBvE3azFx75K5OCf1ca4ehdN.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 363
+ },
+ {
+ "aspect_ratio": 3.586,
+ "height": 87,
+ "iso_639_1": "zh",
+ "file_path": "/mokjoQV7nBZwWuWWELquGupDHEG.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 312
+ },
+ {
+ "aspect_ratio": 5.048,
+ "height": 63,
+ "iso_639_1": "cs",
+ "file_path": "/jzRhdba9A3E1DHrAho0vcrmRBvT.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 318
+ },
+ {
+ "aspect_ratio": 5.048,
+ "height": 63,
+ "iso_639_1": "cs",
+ "file_path": "/yCeKhWXwV1eCj7cUfwGNjZl9LZN.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 318
+ },
+ {
+ "aspect_ratio": 11.174,
+ "height": 46,
+ "iso_639_1": "pt",
+ "file_path": "/jWAljLSQcW5WM1AKo57k27XeBxf.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 514
+ },
+ {
+ "aspect_ratio": 7.609,
+ "height": 46,
+ "iso_639_1": "ro",
+ "file_path": "/xRBjKLgrCll3dtCJ01ezJx0zqzg.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 350
+ },
+ {
+ "aspect_ratio": 10.587,
+ "height": 46,
+ "iso_639_1": "hu",
+ "file_path": "/cHW9exHZsmqQP0tVah040Lb06N9.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 487
+ },
+ {
+ "aspect_ratio": 10.674,
+ "height": 46,
+ "iso_639_1": "da",
+ "file_path": "/mzJHUuOBen8Z3wQcdouta0e8OCk.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 491
+ },
+ {
+ "aspect_ratio": 9.152,
+ "height": 46,
+ "iso_639_1": "tr",
+ "file_path": "/yYk5nv7mWjwSklECFYPVRxGnJ2z.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 421
+ },
+ {
+ "aspect_ratio": 3.897,
+ "height": 87,
+ "iso_639_1": "el",
+ "file_path": "/4YjpNJ7jQAB1tv9ftmE8WRqch9Z.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 339
+ },
+ {
+ "aspect_ratio": 8.5,
+ "height": 46,
+ "iso_639_1": "he",
+ "file_path": "/utEqHanKE2eGkC9cmu79WFw5odt.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 391
+ },
+ {
+ "aspect_ratio": 4.684,
+ "height": 76,
+ "iso_639_1": "hi",
+ "file_path": "/ye6QUVuObWk1hfYo0UmCyMUOWLM.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 356
+ },
+ {
+ "aspect_ratio": 10.304,
+ "height": 46,
+ "iso_639_1": "pl",
+ "file_path": "/nQlz6XwhAbKcsNrumothZJULXEX.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 474
+ },
+ {
+ "aspect_ratio": 10.587,
+ "height": 46,
+ "iso_639_1": "hu",
+ "file_path": "/bhVLYirt219YfjnZX5gJ1sZqZxI.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 487
+ },
+ {
+ "aspect_ratio": 11.174,
+ "height": 46,
+ "iso_639_1": "pt",
+ "file_path": "/2RwbjCBlW7cIz4Yk6UaEOJ793OW.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 514
+ },
+ {
+ "aspect_ratio": 10.304,
+ "height": 46,
+ "iso_639_1": "pl",
+ "file_path": "/lOMnPYf6x0JsdIpqvVK8YGEDWsq.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 474
+ },
+ {
+ "aspect_ratio": 4.684,
+ "height": 76,
+ "iso_639_1": "hi",
+ "file_path": "/uUY7USS9Wh8Sq1HeCMPH54eLJar.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 356
+ },
+ {
+ "aspect_ratio": 5.857,
+ "height": 63,
+ "iso_639_1": "hr",
+ "file_path": "/ip7t2iKXf0T8kkgyy1gPw6Ru5r4.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 369
+ },
+ {
+ "aspect_ratio": 5.968,
+ "height": 63,
+ "iso_639_1": "ko",
+ "file_path": "/4N7BF9UVEUFUWrIPjbUfuSIR6Hx.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 376
+ },
+ {
+ "aspect_ratio": 7.609,
+ "height": 46,
+ "iso_639_1": "ro",
+ "file_path": "/43M2KWwzOpyLeBd0LP6yFwHSUrG.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 350
+ },
+ {
+ "aspect_ratio": 5.651,
+ "height": 63,
+ "iso_639_1": "ar",
+ "file_path": "/5tREM7M0hnwfTRPItxfDdGaXklu.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 356
+ },
+ {
+ "aspect_ratio": 4.724,
+ "height": 76,
+ "iso_639_1": "ja",
+ "file_path": "/iD5aR1Lm8ubG9MqGoJ2eWTfwo3i.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 359
+ },
+ {
+ "aspect_ratio": 12.087,
+ "height": 46,
+ "iso_639_1": "pt",
+ "file_path": "/59NRe3tgzVK0pTmGUuuijo1TXXT.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 556
+ },
+ {
+ "aspect_ratio": 10.239,
+ "height": 46,
+ "iso_639_1": "it",
+ "file_path": "/peUnI37dY8Lc8rKg5IhbamJuLqY.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 471
+ },
+ {
+ "aspect_ratio": 11.304,
+ "height": 46,
+ "iso_639_1": "vi",
+ "file_path": "/dwM8bXEkvWChOSvkKxGCX0PlkZ3.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 520
+ },
+ {
+ "aspect_ratio": 9.152,
+ "height": 46,
+ "iso_639_1": "tr",
+ "file_path": "/yivaVOVgmR6KT0OM1dEujscoA0h.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 421
+ },
+ {
+ "aspect_ratio": 4.908,
+ "height": 76,
+ "iso_639_1": "th",
+ "file_path": "/eLS9pvfJRH7VXFRonQwYJ9Nqszd.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 373
+ },
+ {
+ "aspect_ratio": 11.304,
+ "height": 46,
+ "iso_639_1": "vi",
+ "file_path": "/zyIa5gFtp9BCpBC0v3esB0qAL5Q.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 520
+ },
+ {
+ "aspect_ratio": 7.407,
+ "height": 172,
+ "iso_639_1": "en",
+ "file_path": "/iFa2IjBerr9dO52BAmH2IRMSVV1.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1274
+ },
+ {
+ "aspect_ratio": 8.111,
+ "height": 72,
+ "iso_639_1": "sl",
+ "file_path": "/31m1br3Vpi7UekmqExvB4I8XsHM.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 584
+ },
+ {
+ "aspect_ratio": 4.205,
+ "height": 205,
+ "iso_639_1": "zh",
+ "file_path": "/uR6cu24P8hFoxM7T9REqTNCRQbb.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 862
+ }
+ ],
+ "posters": [
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "tr",
+ "file_path": "/4fFatsgZWh7a9WljDUfkuSSc25V.jpg",
+ "vote_average": 8.362,
+ "vote_count": 6,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/ynT06XivgBDkg7AtbDbX1dJeBGY.jpg",
+ "vote_average": 6.312,
+ "vote_count": 8,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": null,
+ "file_path": "/wLzfzKoVTfVkyiyWT2IZoVjwWtx.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1665,
+ "iso_639_1": null,
+ "file_path": "/j277mJqoflD9Dunb7fHbLpqr6en.jpg",
+ "vote_average": 3.334,
+ "vote_count": 2,
+ "width": 1110
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "pt",
+ "file_path": "/tUnY14keO33H2QfOQEWRUsccgZo.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "es",
+ "file_path": "/utIg6Vghn65A7rz8tH9ItHUuCzU.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/nRwDPfYUzzzUQarfMxvPlasxzpL.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1801,
+ "iso_639_1": "en",
+ "file_path": "/5o6zMz66lSiMTVj0S4ZluvFfjEY.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1201
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/E3dPHPJigkXwuiE0n1vzz0se8a.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "pt",
+ "file_path": "/cA0K4wca6EZdtcNz5dMjJWMwvvR.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/cytAEwCbbMjXdX5m7XWBU271rwG.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/4ArZUoJObZZXBeFQyaZvJq8YyZw.jpg",
+ "vote_average": 2.542,
+ "vote_count": 4,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "es",
+ "file_path": "/8pEtr2o1aZEIyDaYDZgjbADNL4E.jpg",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1200,
+ "iso_639_1": "en",
+ "file_path": "/d7Viin538Zc9hDnZvJtjnRpcnLr.jpg",
+ "vote_average": 2.066,
+ "vote_count": 5,
+ "width": 800
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1920,
+ "iso_639_1": "en",
+ "file_path": "/1GMz5CGgm7NupnGPjwkEQHxfUcT.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/8B1WyuYiC6Lwz4EFBfgpoviDcC1.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/o11Nnq6WuAMk3qHPzSpSLmstqDL.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 800,
+ "iso_639_1": "en",
+ "file_path": "/3rGS8N0vmjatrvvCYb6NE0mknYW.jpg",
+ "vote_average": 1.066,
+ "vote_count": 5,
+ "width": 533
+ },
+ {
+ "aspect_ratio": 0.672,
+ "height": 1606,
+ "iso_639_1": "en",
+ "file_path": "/2mYFA2v0ja8VVFA1ToOZF7u838p.jpg",
+ "vote_average": 1.066,
+ "vote_count": 5,
+ "width": 1080
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2496,
+ "iso_639_1": "tr",
+ "file_path": "/xB4paIImvj8rjm6vCsBkKBgnOyh.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1664
+ },
+ {
+ "aspect_ratio": 0.675,
+ "height": 2222,
+ "iso_639_1": "en",
+ "file_path": "/pOxzz1dB0PxZhDInRG3V3LKSC1C.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/p8xxeq6flmez6Xz5A9PSUUygecA.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1665,
+ "iso_639_1": "uk",
+ "file_path": "/grlEij3dpGudZGqTvSiAR9h1OzP.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1110
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1457,
+ "iso_639_1": "uk",
+ "file_path": "/djJgoQqchRpAngiehwVlj0IxH3K.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 972
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1350,
+ "iso_639_1": "en",
+ "file_path": "/rgpzDWoHVo8BqcjSAVS2OWnDUaT.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 900
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/hKUDPA6em4UEDE2zquPbE1Xkzsz.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.713,
+ "height": 750,
+ "iso_639_1": "zh",
+ "file_path": "/6dYAxnwRQNdXILx621xdX61fJJB.jpg",
+ "vote_average": 0,
+ "vote_count": 1,
+ "width": 535
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1920,
+ "iso_639_1": "en",
+ "file_path": "/2Ri7KnMcQvleTdHrpyM4eSMZrTj.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 900,
+ "iso_639_1": "th",
+ "file_path": "/x6ExSuFAgeNdjzfiw6xOyatzETo.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1050,
+ "iso_639_1": "it",
+ "file_path": "/2HTLO8U9BWph27QVTKp2Hniyjt9.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 700
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1050,
+ "iso_639_1": "it",
+ "file_path": "/e6kWvwXnhLvj2nlE4zdvFV2S7CK.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 700
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 750,
+ "iso_639_1": "pt",
+ "file_path": "/xTVrJhDxonSaKlggr8R4vH1mYrA.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "zh",
+ "file_path": "/q50q4xc0YiccXMZ9QEsnuGrr1U8.jpg",
+ "vote_average": 0,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "zh",
+ "file_path": "/lgGT2mFCIrt79916G2wc0TG9GKW.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/art75HHKvh1H8LBYbxQwxfFgpd0.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ro",
+ "file_path": "/jLNyzbmMU86Vvu2tOMEF8oAQ8Rf.jpg",
+ "vote_average": 0,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/ftgvq4uSxATZuF5GaiYXLCmFXIp.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "he",
+ "file_path": "/bxwNplYBoJ7G43dJnykAmRPZhFt.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1665,
+ "iso_639_1": "hr",
+ "file_path": "/ixbEygtiPiQaXhsZDxvkoV8PcY.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1110
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 2000,
+ "iso_639_1": "sl",
+ "file_path": "/pulZ1IkvGjG1N7CYqeqLEpkZUMR.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1333
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2222,
+ "iso_639_1": "ru",
+ "file_path": "/5ezAkKMAc6CwXiTI7JljyT1Epc6.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1481
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/eSP5aENJAZV8w8VJ0xCPbwq55NG.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/cT5HicYNtvnDaRVVLbPxIRoJWve.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1801,
+ "iso_639_1": null,
+ "file_path": "/mklEmRlUY0wNwz0nSoViSafydva.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1201
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "bg",
+ "file_path": "/oR3IW31rRCyMvCImZYRDAmN2XXr.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1800,
+ "iso_639_1": "zh",
+ "file_path": "/b2xztxY13mLoZuTZLHdnWQ9YVrc.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1200
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/rH0vnjxVbc8dg1lmV6bQJaMmEri.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.706,
+ "height": 759,
+ "iso_639_1": "ar",
+ "file_path": "/cjoxRBMajRi0Ic1MejbmudKzdbf.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 536
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1665,
+ "iso_639_1": "ka",
+ "file_path": "/2ifImkVwh9OgX7MBowh0u7f5yUv.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1110
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/xIzSCh1MWH7vzgiRYeMWL8Qx0t8.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ }
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-1263256.json b/providers/.cache/tmdb_api/tmdb-movie-1263256.json
new file mode 100644
index 0000000..bda5ceb
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-1263256.json
@@ -0,0 +1,58 @@
+{
+ "adult": false,
+ "backdrop_path": "/x5dVPttNDZaVRTvbk7pYrtGZoZN.jpg",
+ "belongs_to_collection": {
+ "id": 1263259,
+ "name": "Happy Gilmore Collection",
+ "poster_path": "/7nUOrnZHSgnhagLtydIYbD4rrDY.jpg",
+ "backdrop_path": "/mhrE9ij30cIvPFVFRXZSwwTchUg.jpg"
+ },
+ "budget": 152000000,
+ "genres": [
+ {
+ "id": 35,
+ "name": "Comedy"
+ }
+ ],
+ "homepage": "https://www.netflix.com/title/81696722",
+ "id": 1263256,
+ "imdb_id": "tt31868189",
+ "origin_country": [
+ "US"
+ ],
+ "original_language": "en",
+ "original_title": "Happy Gilmore 2",
+ "overview": "Happy Gilmore isn't done with golf — not by a long shot. Since his retirement after his first Tour Championship win, Gilmore returns to finance his daughter's ballet classes.",
+ "popularity": 24.4786,
+ "poster_path": "/ynT06XivgBDkg7AtbDbX1dJeBGY.jpg",
+ "production_companies": [
+ {
+ "id": 878,
+ "logo_path": "/s5j0xnTXvglZoz49CUaQclVv3s9.png",
+ "name": "Happy Madison Productions",
+ "origin_country": "US"
+ }
+ ],
+ "production_countries": [
+ {
+ "iso_3166_1": "US",
+ "name": "United States of America"
+ }
+ ],
+ "release_date": "2025-07-25",
+ "revenue": 0,
+ "runtime": 118,
+ "spoken_languages": [
+ {
+ "english_name": "English",
+ "iso_639_1": "en",
+ "name": "English"
+ }
+ ],
+ "status": "Released",
+ "tagline": "Happy Gilmore returns!",
+ "title": "Happy Gilmore 2",
+ "video": false,
+ "vote_average": 6.673,
+ "vote_count": 712
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-1893-alternatives.json b/providers/.cache/tmdb_api/tmdb-movie-1893-alternatives.json
new file mode 100644
index 0000000..eef00b5
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-1893-alternatives.json
@@ -0,0 +1,305 @@
+{
+ "id": 1893,
+ "titles": [
+ {
+ "iso_3166_1": "US",
+ "title": "Star Wars: Episode I",
+ "type": "working title"
+ },
+ {
+ "iso_3166_1": "US",
+ "title": "Star Wars I: The Phantom Menace",
+ "type": "video box title"
+ },
+ {
+ "iso_3166_1": "CZ",
+ "title": "Skrytá hrozba",
+ "type": "short title"
+ },
+ {
+ "iso_3166_1": "FR",
+ "title": "La menace fantôme",
+ "type": "short title"
+ },
+ {
+ "iso_3166_1": "FI",
+ "title": "Tähtien sota - episodi I: Pimeä uhka",
+ "type": "TV title"
+ },
+ {
+ "iso_3166_1": "DK",
+ "title": "Den usynlige fjende",
+ "type": "short title"
+ },
+ {
+ "iso_3166_1": "RU",
+ "title": "Скрытая угроза",
+ "type": "short title"
+ },
+ {
+ "iso_3166_1": "ES",
+ "title": "Star Wars: Episodio I - La amenaza fantasma",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "US",
+ "title": "The Phantom Menace",
+ "type": "short title"
+ },
+ {
+ "iso_3166_1": "HK",
+ "title": "星球大戰前傳:魅影危機",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "US",
+ "title": "Star Wars: The Phantom Menace",
+ "type": "iTunes Title"
+ },
+ {
+ "iso_3166_1": "TW",
+ "title": "星際大戰首部曲:威脅潛伏",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "KR",
+ "title": "스타워즈 에피소드1 보이지 않는 위험",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "HU",
+ "title": "Bajlós Árnyak",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "BR",
+ "title": "Star Wars: A Ameaça Fantasma",
+ "type": "short title"
+ },
+ {
+ "iso_3166_1": "NO",
+ "title": "Star Wars: Episode I - Den skjulte trussel",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "FR",
+ "title": "Star Wars - Episode I - La Menace Fantôme",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "GR",
+ "title": "Ο Πόλεμος Των Άστρων: Επεισόδιο 1 - Η Αόρατη Απειλή",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "CA",
+ "title": "Star Wars : épisode I - La menace fantôme",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "CZ",
+ "title": "Hvězdné války: Epizoda I - Skrytá hrozba",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "KR",
+ "title": "스타 워즈 에피소드 1, 보이지 않는 위험",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "FR",
+ "title": "Star Wars : La menace fantôme",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "SK",
+ "title": "Star Wars: Skrytá hrozba",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "SK",
+ "title": "Hviezdné vojny: Epizoda I - Skrytá hrozba",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "RU",
+ "title": "Звёздные войны: Эпизод I - Скрытая угроза",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "RU",
+ "title": "Звёздные войны: Скрытая угроза",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "UA",
+ "title": "Зоряні війни: Прихована загроза",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "IT",
+ "title": "Star Wars - Episodio I - La minaccia fantasma",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "DE",
+ "title": "Star Wars Episode 1 - Die dunkle Bedrohung",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "JP",
+ "title": "スター・ウォーズ/ファントム・メナス",
+ "type": "iTunes title"
+ },
+ {
+ "iso_3166_1": "KR",
+ "title": "스타워즈 에피소드 1 보이지 않는 위험",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "US",
+ "title": "Star Wars: The Phantom Menace (Episode I)",
+ "type": "Disney+"
+ },
+ {
+ "iso_3166_1": "CN",
+ "title": "星球大战前传:魅影危机",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "PL",
+ "title": "Gwiezdne Wojny I - Mroczne Widmo",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "TW",
+ "title": "星球大戰前傳:魅影危機",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "FR",
+ "title": "Star Wars, Episode I - La Menace fantôme",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "CN",
+ "title": "星球大战1:幽灵的威胁",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "CN",
+ "title": "星球大战前传1:幽灵的威胁",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "CN",
+ "title": "星球大战前传:幽灵的威胁",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "CN",
+ "title": "星球大战:幽灵的威胁",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "CN",
+ "title": "星球大战前传1:魅影危机",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "CN",
+ "title": "星球大战:魅影危机",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "FR",
+ "title": "Star Wars, épisode I : La Menace fantôme",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "HU",
+ "title": "Csillagok Háborúja I. - Baljós Árnyak",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "GE",
+ "title": "ვარსკვლავური ომები: ფარული საფრთხე (ეპიზოდი I)",
+ "type": "Disney+"
+ },
+ {
+ "iso_3166_1": "GE",
+ "title": "ვარსკვლავური ომები: ეპიზოდი I",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "GE",
+ "title": "ვარსკვლავური ომები I",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "GE",
+ "title": "ვარსკვლავური ომები 1",
+ "type": "short title"
+ },
+ {
+ "iso_3166_1": "GE",
+ "title": "ვარსკვლავური ომები: ეპიზოდი I - ფარული საფრთხე",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "GE",
+ "title": "ვარსკვლავური ომები: ეპიზოდი 1",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "IL",
+ "title": "סטאר וורס פרק I: אימת הפאנטום",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "VN",
+ "title": "Chiến Tranh Giữa Các Vì Sao 1: Hiểm Họa Bóng Ma",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "ES",
+ "title": "La amenaza fantasma",
+ "type": "Titulo abreviado"
+ },
+ {
+ "iso_3166_1": "MX",
+ "title": "Star Wars: La amenaza fantasma",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "JP",
+ "title": "スター・ウォーズ/ファントム・メナス (エピソード1)",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "US",
+ "title": "Star Wars Episode I - The Phantom Menace",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "DE",
+ "title": "Star Wars - Episode 1 - Die dunkle Bedrohung",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "IL",
+ "title": "מלחמת הכוכבים 1: אימת הפנטום",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "SG",
+ "title": "Star Wars Episode I:The Phantom Menace",
+ "type": "HK & Singapore Style English Asian Font Set"
+ },
+ {
+ "iso_3166_1": "UZ",
+ "title": "Yulduzlar jangi-1: Yashirin tahdid",
+ "type": ""
+ }
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-1893-external_ids.json b/providers/.cache/tmdb_api/tmdb-movie-1893-external_ids.json
new file mode 100644
index 0000000..b3e19c3
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-1893-external_ids.json
@@ -0,0 +1,8 @@
+{
+ "id": 1893,
+ "imdb_id": "tt0120915",
+ "wikidata_id": "Q165713",
+ "facebook_id": "StarWars",
+ "instagram_id": "starwars",
+ "twitter_id": "starwars"
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-1893-images.json b/providers/.cache/tmdb_api/tmdb-movie-1893-images.json
new file mode 100644
index 0000000..7db6886
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-1893-images.json
@@ -0,0 +1,3897 @@
+{
+ "backdrops": [
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/wDe8LzwuvHYYiuwyNfxdYQq8ti4.jpg",
+ "vote_average": 5.682,
+ "vote_count": 11,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/5fu7fzy4NZTsL1Jap00UBIInAuB.jpg",
+ "vote_average": 5.25,
+ "vote_count": 22,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/qKnCpQl6ARxbSjw3CLqPlfm43vb.jpg",
+ "vote_average": 5.25,
+ "vote_count": 8,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1606,
+ "iso_639_1": null,
+ "file_path": "/dhkztgCspLkl1bKTdX9lR81PAPG.jpg",
+ "vote_average": 5.25,
+ "vote_count": 10,
+ "width": 2856
+ },
+ {
+ "aspect_ratio": 1.78,
+ "height": 863,
+ "iso_639_1": null,
+ "file_path": "/8MynmjcKSvGdcxjVwsx3TWwOTBa.jpg",
+ "vote_average": 5.25,
+ "vote_count": 8,
+ "width": 1536
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/aTXhYyxx23AGWAqrkrs1fNGhgSO.jpg",
+ "vote_average": 4.884,
+ "vote_count": 13,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/lpz6V7q0IxUQI1Ia6xENuc66zF5.jpg",
+ "vote_average": 4.722,
+ "vote_count": 9,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.779,
+ "height": 839,
+ "iso_639_1": null,
+ "file_path": "/a8SBSwSGcF6JvymKPjegDGrxOo2.jpg",
+ "vote_average": 4.722,
+ "vote_count": 9,
+ "width": 1493
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/fpEYSEpbPAQMppYRyRA66EZoWCX.jpg",
+ "vote_average": 3.954,
+ "vote_count": 11,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "es",
+ "file_path": "/qXulRWB56gUgW5LCBDg1asTlEXq.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/3TeGmKJfkik1D1rIoqGb1aR4k9c.jpg",
+ "vote_average": 3.334,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/h6yb2uoiw5SkoTuQorxgDVOhIym.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "en",
+ "file_path": "/wZaWy1IfKTZEn7oK1ZvVK90ZkrC.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/wujMxlOOIM68XRiSVHC5h2QtCwy.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/suLRx5wRkDyzB13K1FRGW2eRCn9.jpg",
+ "vote_average": 3.334,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.777,
+ "height": 1600,
+ "iso_639_1": null,
+ "file_path": "/k4olhqN9A1q3aDVTe5WC1F9nxTn.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2843
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/h0hTCg2aoG9tpAk8xILHU7aHRC5.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/9YCTvqzELOKyVwgTFnVI5JQGLuv.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/jOIpEbod3uK5wH1kF3NB3d2woQc.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/tJpMCH1jLW5GuJbJ6QHOJ16FtkY.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/qQOv9vs9OJe3gdApxoxnnlReVmW.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/sQUiouw94zhoG6LDEj9h8cPb61N.jpg",
+ "vote_average": 1.75,
+ "vote_count": 6,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/9RFS4KceFxAZX7w0m1Jr2euk8ds.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/dnUUhqSUKuhizUmXO8oqeh8gjJl.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/sHrXdhRmgMvEO0SV8GeHbJITZ7k.jpg",
+ "vote_average": 1.562,
+ "vote_count": 8,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "en",
+ "file_path": "/rxdSNzq3hofvyakEgKt2zfTN5tJ.jpg",
+ "vote_average": 1.562,
+ "vote_count": 8,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/zE7yQPLvDc2G88EOWEgKrIT0rWs.jpg",
+ "vote_average": 1.444,
+ "vote_count": 6,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/9r4IRZUJ564J38EcLRPM9uUZlVp.jpg",
+ "vote_average": 1.444,
+ "vote_count": 9,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/qDEvctVfAheD7x9Rzz8xcFRAGAU.jpg",
+ "vote_average": 1.444,
+ "vote_count": 9,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/qKkNhRpotW2bZjgDd5NvomApt7A.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/iYFvlq53FjhPeB5bjdP5UVeeJl2.jpg",
+ "vote_average": 1.31,
+ "vote_count": 7,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "pt",
+ "file_path": "/36LnijfQCOC89rCMOhn2OINXROI.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/bEw0vP5XMSHsrMDERbWKL6y3AVZ.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/4Z1i1wsrDEtFTsbTJH93WWQSELJ.jpg",
+ "vote_average": 1.13,
+ "vote_count": 9,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "en",
+ "file_path": "/wNmiOU8EQURI2sKT4RsIY6veclC.jpg",
+ "vote_average": 1.066,
+ "vote_count": 5,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 815,
+ "iso_639_1": null,
+ "file_path": "/4X7NkX3sVJrUM2a8uijmg4u7HPl.jpg",
+ "vote_average": 1.066,
+ "vote_count": 5,
+ "width": 1449
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/jFyZR0DTBOUUuQiKTHksepfoLtc.jpg",
+ "vote_average": 1.066,
+ "vote_count": 5,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "en",
+ "file_path": "/IyL7yp2hfSyjwfYO8ZZfpDVfMU.jpg",
+ "vote_average": 0.972,
+ "vote_count": 6,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "en",
+ "file_path": "/ah3stF3tdlcF9BQeQHiDAUX24ko.jpg",
+ "vote_average": 0.972,
+ "vote_count": 6,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/FoZrNOfOdwSu1rq4UzSW2cdG0k.jpg",
+ "vote_average": 0.972,
+ "vote_count": 6,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/oWllTIYytLu54P02L9cXZDi4tsn.jpg",
+ "vote_average": 0.958,
+ "vote_count": 4,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/uHsVLd1najL79okB15T3CwxYUz2.jpg",
+ "vote_average": 0.5,
+ "vote_count": 4,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/4rSHRoP4tIpZWCIe6YjxoqM0v54.jpg",
+ "vote_average": 0.5,
+ "vote_count": 4,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/3nI2QCM7E9wodKGNTODb5simoyf.jpg",
+ "vote_average": 0.5,
+ "vote_count": 4,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/spED0jvA0BFIUcl35CuOv5PzaYn.jpg",
+ "vote_average": 0.5,
+ "vote_count": 4,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/aDViVKtARjq2bRHrdwahuioDeKj.jpg",
+ "vote_average": 0.5,
+ "vote_count": 4,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "en",
+ "file_path": "/gSGlCKabj8YG0MnNBhFvlNpOoQ7.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "en",
+ "file_path": "/eFsAx6qeCfn6nEM94njG8lhR7wI.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/8WObT9Ehx1MOzfbvNgk9RhCwNf6.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/zLbvZB7kk4dIDwn34Aj5S8UIihp.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/zQV6D3sGUPiGjm7SJMRWtMfSmtt.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/6IZFuLDEwgaIIojiypDwkQLhG1u.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "en",
+ "file_path": "/mqHwV2MSnD0eTb9vUK7Lhdyr01M.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/rRAQbgaUiHMGQqENowXh8vxOVou.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "en",
+ "file_path": "/hBgtnpZODcD7Yc04xRCswiHuDQM.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "es",
+ "file_path": "/64weXdeQj6Tn412KHzQQXsCoZPe.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/6lmyyTrKRSRJs1oZ5PE31lumPle.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/w7AmYht7mGk86OD7lQpKJRoann5.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/mXuUoH9zxbWDYLP6RJvWATPnY7c.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/8lWuaA7Y2pjFSnr3uAVZPNsDpWP.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "de",
+ "file_path": "/yW0CKgKmdHTjK32ZHivHByr5T86.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "pt",
+ "file_path": "/gytWWpRCNU5lSM1yAiWkLsR753v.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "pt",
+ "file_path": "/oS3gc0ahjVu4HU7grTmLr6tfUkp.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "hu",
+ "file_path": "/8K8jlcR3e6Pjyqgx68BgB9xwm9b.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "fr",
+ "file_path": "/4jbg2hkbpuZ1YD4RTafHjI6AsGn.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/ylpctivAsymQ7EidIl6Va361asv.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/uNDKAPQnfeaY3BktMKSW2rDm72Y.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "en",
+ "file_path": "/pC4FYVxwyblurrdHfHFtpmI3OfL.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/x1laoiWbdVIyS3WAeKCk7SQUtx9.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/xJRUL4myOrOWMd9CVgh59e5HsGc.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "zh",
+ "file_path": "/s55e62qVIlpoyxhyB64FIVTBVrX.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1440,
+ "iso_639_1": null,
+ "file_path": "/hNFrlJQgbv8bJIeM7GXUca8BP8n.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2560
+ },
+ {
+ "aspect_ratio": 1.776,
+ "height": 964,
+ "iso_639_1": "tr",
+ "file_path": "/vdRp7uUg8a9mU2NiJrfIAi89SAP.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1712
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/yINV04KajivVdIfr6PG9nzAyUtP.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.777,
+ "height": 768,
+ "iso_639_1": null,
+ "file_path": "/lQjLPLDpMVs7hhxcyi51xIXzZgf.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1365
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/b2vrlWEUKtYtte8ZmnoHKtu9Shi.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/fZv5IbgHlSzSWr9dkPIaxNTm8I1.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/y2AwspEjisfVTyThIZWB6tA5bhp.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/uZa8cBcnlFUYzk3RWFeQWbwUcnQ.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/rd4ykNxzdjXzD8yFGlmPl9psZIC.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/wAOdaqBYyrHnV46NSMnDKlcEvAY.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 814,
+ "iso_639_1": null,
+ "file_path": "/aYe6BBTBY4FWRG0fTbL9pjuRNbz.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1447
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": null,
+ "file_path": "/bdU76w0oEj0qccYtbgKKKmE3g2Z.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/plNjCLzInjSi2qv5JJWIssn06u8.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": null,
+ "file_path": "/xzHLbGVB2XpymrkfRp3TwicagPF.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 790,
+ "iso_639_1": null,
+ "file_path": "/5Q8IQhvbZUIOYDt0BgZt2ppp3UO.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1405
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "it",
+ "file_path": "/lcbWfVH1NBe9zkUagNWS6IrgWOf.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "zh",
+ "file_path": "/iwoBzKVGpEkYXxX6sVghuQcezfT.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "zh",
+ "file_path": "/79aPEApIRf9z96prT6mML1A1hyG.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": "ja",
+ "file_path": "/dPpeDcBht2BC3uq8agJ4QRwkX6s.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1728,
+ "iso_639_1": "pt",
+ "file_path": "/cGuBZR7NTHXtnAdPvuvXiFhNzls.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3072
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/jzFzEHC0YLe0s7u2xX4p5qt7Q6o.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1728,
+ "iso_639_1": null,
+ "file_path": "/b9kkaRki4hIxFTFQRmUvtDeXTWj.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3072
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/7lPxEsuINpZrS89xRfsGJfgkXbq.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1350,
+ "iso_639_1": null,
+ "file_path": "/g2qyHBLMimpiSDTti0ySEc6skKK.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2400
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1608,
+ "iso_639_1": null,
+ "file_path": "/7yHeqj1gZAVyGFr2y9cgm8kKXCl.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2859
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1608,
+ "iso_639_1": null,
+ "file_path": "/rbjFN4B7ajPUrYcu7LvCl5hd2du.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2859
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1608,
+ "iso_639_1": null,
+ "file_path": "/CRF8TFzj2hLnOMUkJPPOMwEaat.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2859
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1608,
+ "iso_639_1": null,
+ "file_path": "/wM6LN07bCGg1pn3ADDDebQgi10R.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2859
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1608,
+ "iso_639_1": null,
+ "file_path": "/wYb1Qu1lkioidVRiO37MmdEYkeu.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2859
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1608,
+ "iso_639_1": null,
+ "file_path": "/vldt6TykBdxRoRsRQUeVpWMihxX.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2859
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1608,
+ "iso_639_1": null,
+ "file_path": "/ypIJxcNOdlIa3Tp44Kz3HZbDoQF.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2859
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1608,
+ "iso_639_1": null,
+ "file_path": "/cqxt3nzYRZrp3rTHi8Q15qyklH5.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2859
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "de",
+ "file_path": "/cLTQWAh7qrb0MmMZIjGnAiTjeQU.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ }
+ ],
+ "id": 1893,
+ "logos": [
+ {
+ "aspect_ratio": 2.125,
+ "height": 1299,
+ "iso_639_1": "en",
+ "file_path": "/8bZhu9BzARNvwZ7beBuMk93WE1J.png",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2760
+ },
+ {
+ "aspect_ratio": 3.201,
+ "height": 244,
+ "iso_639_1": "en",
+ "file_path": "/ng7NyKidNO3tpngil1jW6DNMPVx.png",
+ "vote_average": 3.334,
+ "vote_count": 3,
+ "width": 781
+ },
+ {
+ "aspect_ratio": 1.985,
+ "height": 677,
+ "iso_639_1": "de",
+ "file_path": "/s2OPnklfUDQExrhgMAHDrx27JOY.png",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1344
+ },
+ {
+ "aspect_ratio": 2.923,
+ "height": 535,
+ "iso_639_1": "fr",
+ "file_path": "/sEaIX0ETCj1vzPEnYnl5aNRPwA2.png",
+ "vote_average": 3.334,
+ "vote_count": 2,
+ "width": 1564
+ },
+ {
+ "aspect_ratio": 1.483,
+ "height": 300,
+ "iso_639_1": "it",
+ "file_path": "/leivDqFnLgAkw5Cqh9mjPtsR4DE.png",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 445
+ },
+ {
+ "aspect_ratio": 0.873,
+ "height": 1146,
+ "iso_639_1": "zh",
+ "file_path": "/4UySdZVVyoZ289Y3E8ERdY5XUdu.png",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 3.162,
+ "height": 784,
+ "iso_639_1": "he",
+ "file_path": "/lPOUDPEVqGeMCjUke9z7k5ujC8n.png",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2479
+ },
+ {
+ "aspect_ratio": 3.139,
+ "height": 244,
+ "iso_639_1": "en",
+ "file_path": "/eqiNYEn1mIdyYwrHk73y4sakqnw.png",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 766
+ },
+ {
+ "aspect_ratio": 2.421,
+ "height": 297,
+ "iso_639_1": "de",
+ "file_path": "/bPDXMsLXuGitnM1Faif5iKKnIs0.png",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 719
+ },
+ {
+ "aspect_ratio": 2.992,
+ "height": 262,
+ "iso_639_1": "de",
+ "file_path": "/inbmBStYnGaYjM1zF49OMYRqu8V.png",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 784
+ },
+ {
+ "aspect_ratio": 2.914,
+ "height": 269,
+ "iso_639_1": "fr",
+ "file_path": "/kew3bmV7a0HCnuGJFpgOoJJhi5Q.png",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 784
+ },
+ {
+ "aspect_ratio": 2.671,
+ "height": 295,
+ "iso_639_1": "de",
+ "file_path": "/nGjfdALcA1wWq4WDnS8Trhsqwph.png",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 788
+ },
+ {
+ "aspect_ratio": 2.568,
+ "height": 310,
+ "iso_639_1": "de",
+ "file_path": "/tlZ2FsW2HFlwXym6ypqFaVYioKD.png",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 796
+ },
+ {
+ "aspect_ratio": 3.375,
+ "height": 232,
+ "iso_639_1": "de",
+ "file_path": "/oGvrgzI4crgsXugiFxfBUfDDFw4.png",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 783
+ },
+ {
+ "aspect_ratio": 2.101,
+ "height": 1299,
+ "iso_639_1": "de",
+ "file_path": "/bAcPgi3Im2ZU0hPfu0iHEP38jbr.png",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 2729
+ },
+ {
+ "aspect_ratio": 3.365,
+ "height": 233,
+ "iso_639_1": "pl",
+ "file_path": "/dxaMfpBin7YwMPY5Va0mhxRp3go.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 784
+ },
+ {
+ "aspect_ratio": 1.288,
+ "height": 292,
+ "iso_639_1": "fr",
+ "file_path": "/f4mly1dnkmROp5nbygx8gi9o9lg.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 376
+ },
+ {
+ "aspect_ratio": 1.819,
+ "height": 293,
+ "iso_639_1": "es",
+ "file_path": "/b3W3Yqm7FGiNC1TFtkiJ3i6BJF4.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 533
+ },
+ {
+ "aspect_ratio": 2.651,
+ "height": 298,
+ "iso_639_1": "en",
+ "file_path": "/3jFWmTRapw9iazjNRwam2pAiyIb.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 790
+ },
+ {
+ "aspect_ratio": 3.333,
+ "height": 234,
+ "iso_639_1": "en",
+ "file_path": "/P8GGcFyUdZ4IDlcsX7YMJIK6Oj.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 780
+ },
+ {
+ "aspect_ratio": 3.155,
+ "height": 251,
+ "iso_639_1": "ru",
+ "file_path": "/sU6Ypw503Wqi6ALwpaX0986QHYy.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 792
+ },
+ {
+ "aspect_ratio": 3.415,
+ "height": 229,
+ "iso_639_1": "it",
+ "file_path": "/bA9lVFCayOjS2IsHQab4zM85XNk.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 782
+ },
+ {
+ "aspect_ratio": 1.13,
+ "height": 308,
+ "iso_639_1": "es",
+ "file_path": "/87bYKBujSehFI5hRLVSX2MFQsbS.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 348
+ },
+ {
+ "aspect_ratio": 3.004,
+ "height": 261,
+ "iso_639_1": "en",
+ "file_path": "/9Usl47fqsUa8NJBYtN2UGHDJQb0.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 784
+ },
+ {
+ "aspect_ratio": 4.084,
+ "height": 191,
+ "iso_639_1": "en",
+ "file_path": "/47udRs2Cv6rEqqtpLBcgRSsYIFl.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 780
+ },
+ {
+ "aspect_ratio": 1.483,
+ "height": 300,
+ "iso_639_1": "en",
+ "file_path": "/dYoXaCVrtQh8y4hOdnyTQ7CFi8Q.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 445
+ },
+ {
+ "aspect_ratio": 2.528,
+ "height": 309,
+ "iso_639_1": "fr",
+ "file_path": "/5MvmXlAhV9oZfddvUx7CgkVoUdE.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 781
+ },
+ {
+ "aspect_ratio": 3.237,
+ "height": 241,
+ "iso_639_1": "en",
+ "file_path": "/vie575AQVdGCDw61QZDwn6VwPPF.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 780
+ },
+ {
+ "aspect_ratio": 1.819,
+ "height": 299,
+ "iso_639_1": "pl",
+ "file_path": "/neGwSUKgxrmHgfcRe6uwPNO6ciK.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 544
+ },
+ {
+ "aspect_ratio": 2.094,
+ "height": 298,
+ "iso_639_1": "en",
+ "file_path": "/oTX79sMBCHc9t8GQ9qhpDaxy3FZ.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 624
+ },
+ {
+ "aspect_ratio": 2.258,
+ "height": 298,
+ "iso_639_1": "en",
+ "file_path": "/aiPcbXat8pRE76yoR3CNIx22Ef8.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 673
+ },
+ {
+ "aspect_ratio": 3.103,
+ "height": 253,
+ "iso_639_1": "ru",
+ "file_path": "/cmqeULEZhhKOXHYJ6vzMlXibbcZ.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 785
+ },
+ {
+ "aspect_ratio": 2.051,
+ "height": 294,
+ "iso_639_1": "it",
+ "file_path": "/m4waWf0UM1DzZklnTmmtr8E09L6.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 603
+ },
+ {
+ "aspect_ratio": 2.303,
+ "height": 290,
+ "iso_639_1": "ru",
+ "file_path": "/kRMHnL2WzklWd3hDBfO1931mime.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 668
+ },
+ {
+ "aspect_ratio": 2.73,
+ "height": 289,
+ "iso_639_1": "pl",
+ "file_path": "/sH5ABmBvW5se3RDXA9sophxEVTu.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 789
+ },
+ {
+ "aspect_ratio": 2.521,
+ "height": 309,
+ "iso_639_1": "en",
+ "file_path": "/ilphe6LHkTUOXRRfDAGDVKbYB42.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 779
+ },
+ {
+ "aspect_ratio": 2.177,
+ "height": 727,
+ "iso_639_1": "sk",
+ "file_path": "/dwYd6qNWjmNUS0z1xQYCVKkiOzi.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1583
+ },
+ {
+ "aspect_ratio": 1.877,
+ "height": 716,
+ "iso_639_1": "pt",
+ "file_path": "/w2mJvdVm0LorIozVqCQuNALTft8.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1344
+ },
+ {
+ "aspect_ratio": 1.539,
+ "height": 228,
+ "iso_639_1": "hu",
+ "file_path": "/aYZ5vmeD6TDTiwzAyQIR7NCQiEC.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 351
+ },
+ {
+ "aspect_ratio": 1.721,
+ "height": 810,
+ "iso_639_1": "ja",
+ "file_path": "/ifdZxDP40GDJei0qL6SYZFJQWpK.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1394
+ },
+ {
+ "aspect_ratio": 1.83,
+ "height": 853,
+ "iso_639_1": "en",
+ "file_path": "/ixpUM1tb5Agndhaz5Fh8MFUiul7.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1561
+ },
+ {
+ "aspect_ratio": 1.266,
+ "height": 290,
+ "iso_639_1": "fi",
+ "file_path": "/o9O5l07fNa10FFFHkuLTyQIw0Im.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 367
+ },
+ {
+ "aspect_ratio": 4.079,
+ "height": 353,
+ "iso_639_1": "zh",
+ "file_path": "/kdAAjJFcUV0DBeTMYHw8QbRPRFx.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1440
+ },
+ {
+ "aspect_ratio": 3.006,
+ "height": 479,
+ "iso_639_1": "zh",
+ "file_path": "/17pjrC1jdTAYJudHRxywIyxyVR5.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1440
+ },
+ {
+ "aspect_ratio": 1.919,
+ "height": 1299,
+ "iso_639_1": "el",
+ "file_path": "/un6a1qjFebJTl4vnluZC9PKY1cr.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2493
+ },
+ {
+ "aspect_ratio": 1.845,
+ "height": 2076,
+ "iso_639_1": "he",
+ "file_path": "/sJC0LwbRZiW3cXn4j9ltXQeJmyB.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3831
+ },
+ {
+ "aspect_ratio": 3.429,
+ "height": 231,
+ "iso_639_1": "es",
+ "file_path": "/7GZcWmkKb00shSyM3qREEGOdJHJ.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 792
+ },
+ {
+ "aspect_ratio": 1.682,
+ "height": 650,
+ "iso_639_1": "fr",
+ "file_path": "/xQ7UKKyhvth6lEgyzXJjx2wUsQT.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1093
+ },
+ {
+ "aspect_ratio": 2.473,
+ "height": 349,
+ "iso_639_1": "bg",
+ "file_path": "/wthCghAWPFvXZ6oZ8yROXlfjsdM.svg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 863
+ },
+ {
+ "aspect_ratio": 2.72,
+ "height": 917,
+ "iso_639_1": "es",
+ "file_path": "/8uPhhBqgP7Fp4fffaub8aFrDgqE.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2494
+ },
+ {
+ "aspect_ratio": 2.085,
+ "height": 1299,
+ "iso_639_1": "fr",
+ "file_path": "/tAWXblCLDwhmPMQ62Tp5ZggT5yc.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2709
+ },
+ {
+ "aspect_ratio": 4.034,
+ "height": 238,
+ "iso_639_1": "zh",
+ "file_path": "/btyCJPcb5vTYZrxycV0kP7TJbnd.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 960
+ },
+ {
+ "aspect_ratio": 1.884,
+ "height": 292,
+ "iso_639_1": "hu",
+ "file_path": "/uZ2WzrkxbiPKqcyB9Yks6tQv6Ho.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 550
+ },
+ {
+ "aspect_ratio": 3.162,
+ "height": 784,
+ "iso_639_1": "he",
+ "file_path": "/caphvmadWJHJqAwKJ9IlTKfPVu6.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2479
+ },
+ {
+ "aspect_ratio": 1.698,
+ "height": 1300,
+ "iso_639_1": "fr",
+ "file_path": "/apZYsHS3nRbqQvLzcZt9w4URm8J.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2207
+ },
+ {
+ "aspect_ratio": 2.251,
+ "height": 1298,
+ "iso_639_1": "zh",
+ "file_path": "/tDIqxNfa58Jowg8XZ3DNY28RFTj.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2922
+ },
+ {
+ "aspect_ratio": 2.354,
+ "height": 1506,
+ "iso_639_1": "zh",
+ "file_path": "/8tXTLbPfByavI6J1j1kEDNtjz7c.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3545
+ },
+ {
+ "aspect_ratio": 1.714,
+ "height": 1792,
+ "iso_639_1": "pt",
+ "file_path": "/ygTZkCGxOhW0tmBZViPnwVtiZlO.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3072
+ },
+ {
+ "aspect_ratio": 1.993,
+ "height": 1343,
+ "iso_639_1": "pt",
+ "file_path": "/iAbNbkFAAt5EQdz6l6fu13Q9FPS.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2676
+ },
+ {
+ "aspect_ratio": 1.295,
+ "height": 1375,
+ "iso_639_1": "pt",
+ "file_path": "/wJFnyUfaEWqvZd4RWAfgiOO3t9L.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1780
+ },
+ {
+ "aspect_ratio": 3.576,
+ "height": 757,
+ "iso_639_1": "pt",
+ "file_path": "/sYo1yWKw8DUquJMUgueppizKPqf.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2707
+ }
+ ],
+ "posters": [
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fr",
+ "file_path": "/fpEC910v5DrMvZteRNlKzXeHiHY.jpg",
+ "vote_average": 8.596,
+ "vote_count": 7,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "de",
+ "file_path": "/mxhaOjcX1BdWw26s6c8vcZeKqzj.jpg",
+ "vote_average": 7.542,
+ "vote_count": 8,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "zh",
+ "file_path": "/Aa0ZpMF0O653YQHifebdT2MRZvw.jpg",
+ "vote_average": 6.722,
+ "vote_count": 9,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/6wkfovpn7Eq8dYNKaG5PY3q2oq6.jpg",
+ "vote_average": 6.438,
+ "vote_count": 24,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/x5jfgaL2N3TpwUNuMwkfQi6Jev8.jpg",
+ "vote_average": 5.53,
+ "vote_count": 17,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/ytD3zCzQSC89lxfIwm2Seq6hW9S.jpg",
+ "vote_average": 4.934,
+ "vote_count": 15,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "zh",
+ "file_path": "/c9sZHxvxqrS0K10sgxWZ0gOT7v7.jpg",
+ "vote_average": 4.818,
+ "vote_count": 11,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/kzmx6YYSQ85hkLTIoRRjmkBR2y.jpg",
+ "vote_average": 4.818,
+ "vote_count": 11,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/pojM2jS4YOyBJ2acttFmpyEu9gh.jpg",
+ "vote_average": 4.722,
+ "vote_count": 9,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/xQzMnuiv81d0gfUIVstuleNutjA.jpg",
+ "vote_average": 4.722,
+ "vote_count": 9,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2250,
+ "iso_639_1": "en",
+ "file_path": "/uRg9EBTLAPeA3vXfo0vT2pTagHQ.jpg",
+ "vote_average": 4.722,
+ "vote_count": 9,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/njvYovI7hE19OjHsaWBjWNW2wpj.jpg",
+ "vote_average": 4.3,
+ "vote_count": 15,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1845,
+ "iso_639_1": "en",
+ "file_path": "/wFqsNrKru8xw1914kEx84yu651k.jpg",
+ "vote_average": 4.3,
+ "vote_count": 10,
+ "width": 1230
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fr",
+ "file_path": "/qRkOFWx9vJMsvjLk6fYapwmG7Rg.jpg",
+ "vote_average": 3.334,
+ "vote_count": 3,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ja",
+ "file_path": "/l2s53sR2LAFaP5xDot1CvrKPj8V.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "hu",
+ "file_path": "/7Xqynlkz7gb7y2xMXpkuZZaHg4h.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2250,
+ "iso_639_1": "sk",
+ "file_path": "/g0iGEX95UKl1a1b7SGYAQHxTNq1.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fr",
+ "file_path": "/d9CuwMqap3FoELmom1CmNrPqWnE.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.676,
+ "height": 1024,
+ "iso_639_1": "th",
+ "file_path": "/1RtekzgHqvD1tsn7H5vhNVC3NWb.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 692
+ },
+ {
+ "aspect_ratio": 0.7,
+ "height": 2100,
+ "iso_639_1": "ro",
+ "file_path": "/pWHvLQlfVy5D3pq7skqAGDeWe2p.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1470
+ },
+ {
+ "aspect_ratio": 0.75,
+ "height": 907,
+ "iso_639_1": "ro",
+ "file_path": "/o0LoIrIzieKepBXenrBoMJyraTa.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 680
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2400,
+ "iso_639_1": "el",
+ "file_path": "/blj8pEa7Wppxy8QcA2bHMjAaPNd.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1600
+ },
+ {
+ "aspect_ratio": 0.67,
+ "height": 1009,
+ "iso_639_1": "ja",
+ "file_path": "/fJY6GCs4cOtYFdF9ERJMZM1612t.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 676
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "it",
+ "file_path": "/r9239j2aOUkLrVWUSAybmJb5d6c.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "it",
+ "file_path": "/m8v8KKP1ngTleyPKCqiilHMCsIw.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "it",
+ "file_path": "/zGJQmp9NvNHNlI0W93GrSm8SyRu.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "fr",
+ "file_path": "/sLdq2nXI2x8J0wzv4HD1ON9gVcC.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "sv",
+ "file_path": "/sDhwrprRHvxxXuEG3we4EhEab52.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "he",
+ "file_path": "/A1rFFFukt7k7lBpkAlshLih1EOY.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "da",
+ "file_path": "/de1lO2Z60XWC3NlkX0SSOFRICLG.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "it",
+ "file_path": "/rJTIURr5HLheJV3HZGBMsAvkJGj.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2400,
+ "iso_639_1": "pt",
+ "file_path": "/pfC6UU9Dik01e80aUPCHI9idDZ.jpg",
+ "vote_average": 2.542,
+ "vote_count": 4,
+ "width": 1600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "pt",
+ "file_path": "/gNk8UNAumXlfCdtaxDqsQe7ZGlt.jpg",
+ "vote_average": 2.542,
+ "vote_count": 4,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2400,
+ "iso_639_1": null,
+ "file_path": "/x186WhXYsqOAE2gCfYLY71V3a31.jpg",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 1600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ru",
+ "file_path": "/l1LyrhQwDGur18rxRXKQJQhvx7Y.jpg",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "de",
+ "file_path": "/4e0X8XDjgLu3H2iKiCz44WEl7dA.jpg",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2943,
+ "iso_639_1": "en",
+ "file_path": "/lXdrEkSlBL4tK1Zem9HB7lI49vr.jpg",
+ "vote_average": 2.278,
+ "vote_count": 4,
+ "width": 1962
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 900,
+ "iso_639_1": "ru",
+ "file_path": "/9DkEtsmLSIvVpmnzRaldXqImyQw.jpg",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/ty1n7TPiH3XJ4s6aI7Sv79OTbz5.jpg",
+ "vote_average": 2.066,
+ "vote_count": 5,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "it",
+ "file_path": "/1er2Ry42ZdbpOCldUYiwGb9jde2.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "he",
+ "file_path": "/lGsKeSlS19YqjHryzEyDLumxHXA.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/k6tYEdxMfm3rHjiKMe9ySRSsMvU.jpg",
+ "vote_average": 1.75,
+ "vote_count": 7,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 1426,
+ "iso_639_1": "ru",
+ "file_path": "/ettYNNm1eehROqF046LuJ7Ycd4n.jpg",
+ "vote_average": 1.75,
+ "vote_count": 4,
+ "width": 950
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "pt",
+ "file_path": "/noVm3w6RiIftkvLZbi7upH2Ws0S.jpg",
+ "vote_average": 1.75,
+ "vote_count": 6,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2100,
+ "iso_639_1": "pt",
+ "file_path": "/aj8CvBL1eLUEGjFDf9LH5BBLXCg.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1400
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1035,
+ "iso_639_1": "es",
+ "file_path": "/rJwpYgQWfebnNnIIKSUTUx3sBc4.jpg",
+ "vote_average": 1.75,
+ "vote_count": 6,
+ "width": 690
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2250,
+ "iso_639_1": "it",
+ "file_path": "/7ozBHvOoDDi4UcBWbz3N7SGOKdm.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2250,
+ "iso_639_1": "it",
+ "file_path": "/a6BcynBYR1k8myxhzb76SGjoMhr.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2250,
+ "iso_639_1": "it",
+ "file_path": "/PpyS3rX2RviMxmtHnXxWz0aXj1.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "it",
+ "file_path": "/vP0yuokoHVewTeffFN5Qd2O5ZD6.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.657,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/onVDgjoghC31JPdkHki6bRqFRzg.jpg",
+ "vote_average": 1.75,
+ "vote_count": 4,
+ "width": 1971
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1362,
+ "iso_639_1": "el",
+ "file_path": "/iAx1W7XZkl37xDl9gDWM4Rmnavj.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 908
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "tr",
+ "file_path": "/oHVjAucv1yMPIxwBX6WvEMNJvTj.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "es",
+ "file_path": "/sXzr8WEg9cx3m7gyPFKLaLCjINb.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "es",
+ "file_path": "/31NGgjKfHcp9GFe6enVPrNkjHsW.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "es",
+ "file_path": "/lxNRGnV6YHrI1x8ciTbtMdFM357.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/o1HNcvikeCpfCEe0ZlFTf0WCql4.jpg",
+ "vote_average": 1.75,
+ "vote_count": 4,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "uk",
+ "file_path": "/4JlMFS5g0ZOsYs1aWQmXpcTVpnV.jpg",
+ "vote_average": 1.75,
+ "vote_count": 4,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "es",
+ "file_path": "/k1YCqriXqMr3ylOndPvJkpGxb6o.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1426,
+ "iso_639_1": "en",
+ "file_path": "/1uNt0PVd7eU2u4Idnx2pdjiKuhT.jpg",
+ "vote_average": 1.75,
+ "vote_count": 3,
+ "width": 951
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "tr",
+ "file_path": "/rYorGW7FiUWz7G93qZgSXOJjniQ.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.665,
+ "height": 1067,
+ "iso_639_1": "en",
+ "file_path": "/ozM5jylBU1uO5zlN6yybrKoC77C.jpg",
+ "vote_average": 1.75,
+ "vote_count": 4,
+ "width": 710
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 1300,
+ "iso_639_1": "fr",
+ "file_path": "/3aJgTQi5oqVUhZUJmPV1d1dKJUm.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 866
+ },
+ {
+ "aspect_ratio": 0.675,
+ "height": 2000,
+ "iso_639_1": "en",
+ "file_path": "/hacYNfEUEgbNuO9EFUcufOI92MR.jpg",
+ "vote_average": 1.75,
+ "vote_count": 4,
+ "width": 1350
+ },
+ {
+ "aspect_ratio": 0.675,
+ "height": 1559,
+ "iso_639_1": "en",
+ "file_path": "/cu0ddfeY8gSkZs1SMZsZUia4JSX.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1052
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": null,
+ "file_path": "/xHAr8aJr3PitA5GlFet57yjEKs0.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/zJmdZWr68MNjxHOrZo65HWN2Se9.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 2000,
+ "iso_639_1": "es",
+ "file_path": "/ceqY4pkxpMzeqPu2KB22i1APDIr.jpg",
+ "vote_average": 1.75,
+ "vote_count": 4,
+ "width": 1333
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/5SltasuTDYRKERXSvLAVEwLP18d.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "de",
+ "file_path": "/icejFogSa3IFiGskyP6wT5JbAyg.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/uiieY7M3jPMrC8B3HArhxdtDF9c.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.67,
+ "height": 2967,
+ "iso_639_1": "en",
+ "file_path": "/oX2ifeqLkcPdPkUp9zRkYE6o2Cv.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1988
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "de",
+ "file_path": "/mPMLMegnfWc8GEYHrQWJO58XBgO.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2400,
+ "iso_639_1": "en",
+ "file_path": "/ykqIumGYrFhk8G1NW7RCZD69OY6.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/alNrU6nvf9JnnZ1GJJdjP7ILR1L.jpg",
+ "vote_average": 1.714,
+ "vote_count": 7,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2100,
+ "iso_639_1": "es",
+ "file_path": "/iLCabaLrU2xSJ6rgVYCNE0ef0yK.jpg",
+ "vote_average": 1.714,
+ "vote_count": 7,
+ "width": 1400
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/uQiZgiph1ws2KXArHg51qx15pqC.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.647,
+ "height": 1227,
+ "iso_639_1": "en",
+ "file_path": "/7dj5H1bsT3vayTIiBbpyqNZGXC4.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 794
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1920,
+ "iso_639_1": "uk",
+ "file_path": "/wNLNSAjzwXIEGCHorO8PcF1cdtJ.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 0.68,
+ "height": 1000,
+ "iso_639_1": "fr",
+ "file_path": "/cMEyap16nz07KzAAuxg8S0wfSwD.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 680
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/tU9m4SyzhHczlFZJvEPsfoyHymq.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.655,
+ "height": 2963,
+ "iso_639_1": "en",
+ "file_path": "/m2A5oPofyjOla0Mfk3MGpWTwt2G.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 1941
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1200,
+ "iso_639_1": "en",
+ "file_path": "/gFNDuzomx0Cuok9B6tYBVC5aoLN.jpg",
+ "vote_average": 1.31,
+ "vote_count": 7,
+ "width": 800
+ },
+ {
+ "aspect_ratio": 0.694,
+ "height": 1080,
+ "iso_639_1": "zh",
+ "file_path": "/7Dw52Z5IiZpCVu5o5ywD4zYL1U2.jpg",
+ "vote_average": 1.31,
+ "vote_count": 7,
+ "width": 750
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/nuJt3fhl2J9aiCY7PLXYrA0av92.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "pt",
+ "file_path": "/gfAndXRvNCg98dm3ZmN027ogggl.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 1000,
+ "iso_639_1": "en",
+ "file_path": "/nBIM1vh1jDjpg51k8ygKB0Ihk3C.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 666
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/lF0dGH7nyxzEbVzgRrwF7tMDpLN.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": "es",
+ "file_path": "/q81EQKN0ZsqZ1z8gMbhR6Vvtdr3.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/62WhgFn1N6Xgt1F1f5m6yl78vB7.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": null,
+ "file_path": "/3WBuFlQWrGvKihImicuLbAmV9l2.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.649,
+ "height": 1850,
+ "iso_639_1": "en",
+ "file_path": "/pxaPGCQgoTvp9ou1gVIztvxZXqw.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1200
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "es",
+ "file_path": "/saAsRBOJHP6cn4P7BfumHaomdS2.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/sOL4akR5SFsufgMthsILSZWblTJ.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2562,
+ "iso_639_1": "pt",
+ "file_path": "/vAItX7xWJlkfAtPwBvP4rEcPdB0.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1708
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "de",
+ "file_path": "/tyhcgUpyLjtWU9py5nDcke2IzVc.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/5LJd9hCRZnZFerBdt4P12WMu0qw.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.699,
+ "height": 1431,
+ "iso_639_1": "en",
+ "file_path": "/6OffuMP9ZFUIecwzRoMKg99am4D.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1426,
+ "iso_639_1": "en",
+ "file_path": "/2oNYV77iyY0E6xsUdZM8QcQjTfZ.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 951
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": null,
+ "file_path": "/ikVBhc3TqYXKC5AJIOqHzjFWIi9.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1426,
+ "iso_639_1": "en",
+ "file_path": "/tSxFKmfkrnK6hrdbGoO5gHEXehy.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 951
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/4bQSbUcjl1VgEZXWuSzKg4AoGDO.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/m8d5eMFJbnC4qkVIdS31cVcvLEv.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1426,
+ "iso_639_1": "en",
+ "file_path": "/h1oZlAQuT23oJWZnh2KOVOxkAQM.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 951
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1426,
+ "iso_639_1": "en",
+ "file_path": "/obMZoW6sqyV12mUjfOPHfDa04BW.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 951
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1800,
+ "iso_639_1": "en",
+ "file_path": "/vERrNiXd2cGsmOnY8iH1JAbzkPk.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1200
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/fP25i4J7Xk99MKwmnQH9TGiCYzY.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/sDauK0psLmBZ5TmMpgDsN83moHl.jpg",
+ "vote_average": 1.066,
+ "vote_count": 5,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/yjPj7c7tZYRLJJ2ijLMZLvofR4V.jpg",
+ "vote_average": 1.066,
+ "vote_count": 5,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "ru",
+ "file_path": "/g2C6ZhDinwzZ0GjNuZOzq2gRDhB.jpg",
+ "vote_average": 1.066,
+ "vote_count": 5,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/gCtB3mwcgoDkLEEV9nXPav3iY1N.jpg",
+ "vote_average": 1.066,
+ "vote_count": 5,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/imG8fTt9SvQZmustisAVxgJUz3n.jpg",
+ "vote_average": 0.958,
+ "vote_count": 4,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/k3UPNQn75SdyFKHL5Cz0wfQGfFW.jpg",
+ "vote_average": 0.958,
+ "vote_count": 4,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1920,
+ "iso_639_1": "de",
+ "file_path": "/9QUZTdBViVHNgL6JYG7zef9wak8.jpg",
+ "vote_average": 0.958,
+ "vote_count": 4,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/uQ7i643c2uRrmZslySv7b7Nbece.jpg",
+ "vote_average": 0.958,
+ "vote_count": 4,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": "en",
+ "file_path": "/mQqncx4XMYkW1AbtFzFCCn6A8nQ.jpg",
+ "vote_average": 0.958,
+ "vote_count": 4,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/kvMbOQErVY7jYjrvXJ1UuIHE69v.jpg",
+ "vote_average": 0.958,
+ "vote_count": 4,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/pB0iy9c54EomlWc4gmJazLfyCw4.jpg",
+ "vote_average": 0.958,
+ "vote_count": 4,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/lz1VTbZN4DUHFQZhWsgozK2BriI.jpg",
+ "vote_average": 0.958,
+ "vote_count": 4,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": "en",
+ "file_path": "/9RjRyhKUz9reXaaDpVEJXpYtPdV.jpg",
+ "vote_average": 0.904,
+ "vote_count": 7,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.75,
+ "height": 2560,
+ "iso_639_1": "en",
+ "file_path": "/kJj1ZQ9AFuxPGxgZSJd8Uz6FdYf.jpg",
+ "vote_average": 0.5,
+ "vote_count": 4,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "es",
+ "file_path": "/9TXPOUiXKA1uXOtTlBScUu9KiiW.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/jlH7cI4uqV2S7KMzTZ8ljWCFSSb.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": "fr",
+ "file_path": "/uvfyjh6JSIKYbyGwlB6PfvoNwFK.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": "fr",
+ "file_path": "/sso7CWveqUuhllBePXzBPqy9pS0.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "sk",
+ "file_path": "/fpE8P5AhDO8vd2wXHHSB7AmpQbB.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "sk",
+ "file_path": "/w6OEh7vYkig2yXgfjHPLcF0VjF1.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "ja",
+ "file_path": "/wVzY9Lo1b0dM57HGS9ciTgdPVFm.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/rGGbshitsZt6JXLf9StHT8UlUgk.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/2HeYOCwXwWLPtvLvyuKxU54xzBa.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2100,
+ "iso_639_1": "ja",
+ "file_path": "/g7YJGTK4bXuYNDVTIalwcjkglGG.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1400
+ },
+ {
+ "aspect_ratio": 0.665,
+ "height": 753,
+ "iso_639_1": "pt",
+ "file_path": "/aGECnGvJyfIRHQIlYuP56TfUJfN.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 501
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/gDWdsJEQycbuhtZeE6m5lqTpLl6.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": "en",
+ "file_path": "/s3gTZQnmZuDkt2gPwWFwmcZl5zX.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 750,
+ "iso_639_1": "en",
+ "file_path": "/jRUKW5NOlY0UCtwTgnC6Zp6Fznl.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "fr",
+ "file_path": "/39UaMHK4rszoL4Mf3gzyOLHzmH3.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2250,
+ "iso_639_1": "en",
+ "file_path": "/dbqdHitY8bwWMu3u57HEzlNXB0d.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 900,
+ "iso_639_1": "en",
+ "file_path": "/sCNwyRuh9KFgNhyOiP9tgWedvHL.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/vr70waqlh4ffir1prkuMMzz41if.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 999,
+ "iso_639_1": "en",
+ "file_path": "/bZBABmRrbRDyBbtIYVO9E7pW7Nw.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 666
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2700,
+ "iso_639_1": "da",
+ "file_path": "/oJIsJb0jCgHhWv66R4IiBJhytWa.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1800
+ },
+ {
+ "aspect_ratio": 0.705,
+ "height": 1452,
+ "iso_639_1": "de",
+ "file_path": "/nfSLiqfaGZ1dYjwLGJVg6lldXa0.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 1024
+ },
+ {
+ "aspect_ratio": 0.709,
+ "height": 750,
+ "iso_639_1": "de",
+ "file_path": "/zzMXNeQznGXfgNYYH19OGHKm8Tz.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 532
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/60fiAA7HrWxfOy05IUWqhbAY9N6.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fr",
+ "file_path": "/eOrC5XuVULg8i7IbrOPXQlgeH6l.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": "en",
+ "file_path": "/u1NtjwylC9PqiqeYrywo4vIYIww.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1920,
+ "iso_639_1": "en",
+ "file_path": "/n3imUmur8pHufj7jCAqvlTtcAt3.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/a10s37SFMrBDUCmo1NGCkNmlVhZ.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/xkwpfajkJ1ytQ5x2HoM2nslkIMp.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.713,
+ "height": 1860,
+ "iso_639_1": "de",
+ "file_path": "/n3nDPU27LquhbVlCVHf6c8GCeeM.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1326
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/fyH9lo8DpbuHiXanyir3lTvhgcL.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/yqdrkRwfpuJG2uCKGoBGeSzek3.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 960,
+ "iso_639_1": "de",
+ "file_path": "/qxB64T5vs9o7l2egw4mcQAfn8rz.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 640
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "hu",
+ "file_path": "/3FM1YuwLoJitOYlWXBPgNkAojNY.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "es",
+ "file_path": "/iHXUmgttJh7JK991HQDGYySLysX.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/Xjc6YygsO33i1VZvVVl24CMLPZ.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/jfBv4vq25rMcvFcWVnzDP2GdYMf.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1200,
+ "iso_639_1": "de",
+ "file_path": "/eMzTIMJ9RiSRUDBbqxfAIqgUDse.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 800
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/qArqUPsQFrAWLfmOYD1KmfDqEDX.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 1528,
+ "iso_639_1": "de",
+ "file_path": "/kuFdxNkrK5QJIJl65uhsgHTpWGQ.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1018
+ },
+ {
+ "aspect_ratio": 0.71,
+ "height": 845,
+ "iso_639_1": "en",
+ "file_path": "/nzDShcMySru1bvcGsXPkg0jROqG.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 600
+ },
+ {
+ "aspect_ratio": 0.676,
+ "height": 1536,
+ "iso_639_1": "en",
+ "file_path": "/1bPVrijZq9wN7fDuqBl3nqFvoVn.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 1038
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/8qgid4YvaoyNNEp1JMVT0PD6jc6.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/cQoGcwd3SUD0tzNrc9gqbr0bq5F.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fr",
+ "file_path": "/3A8i1DiGKClI7su7bl8AIIJzCI8.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "bg",
+ "file_path": "/1SiegFF674pN3O29Kozb0YF04rL.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1098,
+ "iso_639_1": "en",
+ "file_path": "/37XlDwZi3QMOnCqA6FsqskIUaEw.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 732
+ },
+ {
+ "aspect_ratio": 0.694,
+ "height": 1440,
+ "iso_639_1": "ko",
+ "file_path": "/pt7oxFkvQFzXD0ByCe1uJumL6vD.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "hu",
+ "file_path": "/bcoYmeQDtlEu8MrwM1FlIoWIY7p.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "cs",
+ "file_path": "/g0fFRDE3yrgm44dBY1n4PvnNlhh.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2100,
+ "iso_639_1": "hu",
+ "file_path": "/ta7AQRs9yBAHL3eXXCYil1wfouZ.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1400
+ },
+ {
+ "aspect_ratio": 0.698,
+ "height": 859,
+ "iso_639_1": "it",
+ "file_path": "/A4KquUKtJ7yB9WY0MlD3XZw6F1r.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fr",
+ "file_path": "/9YC9HYu9O1LLf655AOrqrRVnZeR.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.748,
+ "height": 1069,
+ "iso_639_1": "hi",
+ "file_path": "/qgZdwXcjTOkEC4oAOkcNpGB9Jmd.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 800
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "pl",
+ "file_path": "/l1kgucN5ZinWwurSFXH9YdM6QjY.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "pl",
+ "file_path": "/igPuH7GCiYN8p5FUmiWB8OgWGXU.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ru",
+ "file_path": "/oeL5ClBRWl7gJZxFFaxiFsdTV5B.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.69,
+ "height": 1160,
+ "iso_639_1": "zh",
+ "file_path": "/jJBwlLW3gwfewqhnnYLeSfc1ocI.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 800
+ },
+ {
+ "aspect_ratio": 0.692,
+ "height": 1445,
+ "iso_639_1": "bg",
+ "file_path": "/bADF1Px6qwoTIp8idwgz7uqmRBB.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "cs",
+ "file_path": "/j4hW4jO4xfeskglNxQEqjZknaTE.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.707,
+ "height": 2246,
+ "iso_639_1": "it",
+ "file_path": "/1uGmCdmvhiFF72Xspzlq33ECzKL.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1588
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "it",
+ "file_path": "/vTiaQo1aqXNqoTPGiir03tcBHlh.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.699,
+ "height": 2815,
+ "iso_639_1": "ko",
+ "file_path": "/1j2UhKIM2ZYNJ2IWKtHOqjKfqOH.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1969
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "th",
+ "file_path": "/wQ6zi5m0l6c2LmMasNQZGx9HhOA.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2175,
+ "iso_639_1": "de",
+ "file_path": "/5DEIVbU0tUCH0x27KOKe3o6Mxtu.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1450
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1426,
+ "iso_639_1": "hu",
+ "file_path": "/nk64EySpwpA0xICymjmt3lgaT7H.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 951
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "sv",
+ "file_path": "/ph1lGcIDQ8RlDpqdc2aTVeE1Nd8.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1362,
+ "iso_639_1": "el",
+ "file_path": "/oGiXFb3fWTB7oDhdS3RsxDOEnPW.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 908
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 750,
+ "iso_639_1": "hr",
+ "file_path": "/fIpO81njrqXPCJsNPKXXdw8U3vw.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fi",
+ "file_path": "/oeIZYfy98pVqsUs7v1DhrmdE2Dn.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 900,
+ "iso_639_1": "vi",
+ "file_path": "/a0GPS8G1IVOwsfKY8Quc9963RRE.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "tr",
+ "file_path": "/jcyNaqQE7CkSeQW7FDqiwij3bhx.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/p3oslbQr51A6y5mUdPbGDTtaE8b.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/f2h5JDCIS0PKAP9DYD7Twgs0r1b.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2048,
+ "iso_639_1": "en",
+ "file_path": "/b1PrMA3i4FqaXIjM42wiRGNjP14.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1365
+ },
+ {
+ "aspect_ratio": 0.75,
+ "height": 1067,
+ "iso_639_1": "en",
+ "file_path": "/csR9qYmOW2bPNdIuEaeRUH7J3Kj.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 800
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/tVuQB7tV3n4Wv292H9qpmTnXkWW.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/8WfzsM2kOWJK7Re6MNCE3jU2Q3d.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 2000,
+ "iso_639_1": "de",
+ "file_path": "/b4V0HABuhjzWUhYErR20lJqJXfW.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1333
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/bNpXQ3gFTxldFORsQORNmpriCxS.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/sYZANbmAt5KIc80wjT19xG6OqML.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/8GVP3zHXixHcX0WRSRYBBFzN1QC.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 1300,
+ "iso_639_1": "fr",
+ "file_path": "/tMtNBBzpGwk1nvA313wSCEU50fx.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 866
+ },
+ {
+ "aspect_ratio": 0.683,
+ "height": 1300,
+ "iso_639_1": "fr",
+ "file_path": "/4H6EOlMEEQtRj59Ahzt8XInBr1d.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 888
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 1300,
+ "iso_639_1": "fr",
+ "file_path": "/wgQGrfwdJrSygB2MjCVijHgFJQL.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 866
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 1300,
+ "iso_639_1": "fr",
+ "file_path": "/wWzKgPz3PowjnpFYjlmS5cfaWXo.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 866
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 1300,
+ "iso_639_1": "fr",
+ "file_path": "/5N2wKWE2BEcdDZYbnTX8KGSqSmw.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 866
+ },
+ {
+ "aspect_ratio": 0.683,
+ "height": 1300,
+ "iso_639_1": "fr",
+ "file_path": "/63gg9zulkeJmr6NmFGRf5CapFca.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 888
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/34U5VzqJtq9kxeMFGqR73MMUCjh.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": "ru",
+ "file_path": "/j3o90rNUx9VqKPtpebkPwAxduuT.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.702,
+ "height": 1280,
+ "iso_639_1": "ru",
+ "file_path": "/lWPtYHdX2iA79azURpslFRp7j6e.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 898
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2399,
+ "iso_639_1": "en",
+ "file_path": "/tDWqkQePaPVZ6rF6m4L9qVbAasC.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2400,
+ "iso_639_1": "en",
+ "file_path": "/8Ra1TQThFijX85m74VzopyQmWSf.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "el",
+ "file_path": "/huPeNlDbr33hOcB8hT7uf9ykEdo.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "hu",
+ "file_path": "/g1JMPaVb4PeUC3XNP1OkPhr22yc.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.675,
+ "height": 2133,
+ "iso_639_1": "en",
+ "file_path": "/dqQ8iaVjnwfUQ08hbsWqiZGdBEZ.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1440
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "bg",
+ "file_path": "/lP7ibHWrwYF6Re0wntSuxaRRJye.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2943,
+ "iso_639_1": "en",
+ "file_path": "/29lgDxlfUb2uRVLwUzOWlsLs32D.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1962
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2943,
+ "iso_639_1": "en",
+ "file_path": "/hA87FQPNa4tJYBCNMX4Ts4UvlTy.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1962
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/73sJ39KdvYPrXyK10aZMs42lTxT.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.656,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/sFWBbN74UG2pyWEvthk6t6zahR4.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1968
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/ogPKP0wSyTbc4n5uncdLb4YJmEz.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/o7j1sXGxlm9iQsRHn3vzU7lJGQa.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/lG1sX5M39XSJwdzgq3C13DbjRoU.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/dOGPNupQQipf3d5UX3zHdpdQejX.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/k3DalI2fz5nMY6Ds00pW20abM37.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1200,
+ "iso_639_1": "en",
+ "file_path": "/r8N7DH8UOnH8pvVPMUHAEnhFzmz.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 800
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/2BeSKt4uEwJTTdOmmC4lqi9zvCt.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 1211,
+ "iso_639_1": "en",
+ "file_path": "/fevhMH2UI2kV6DaECLTAkQNMB3w.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 807
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 750,
+ "iso_639_1": "en",
+ "file_path": "/9ZvDif6j4bKlIAbMqwnaUuqhaGz.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 500
+ },
+ {
+ "aspect_ratio": 0.679,
+ "height": 920,
+ "iso_639_1": "es",
+ "file_path": "/tGY10vF87nh9AsBOhWdh2gDmqnR.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 625
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/p4eOT5LNYNGm6SznEdleXKIuWoA.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1314,
+ "iso_639_1": null,
+ "file_path": "/jNletvIKtZKQjQhbAhcmmLZ4vrG.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 876
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 750,
+ "iso_639_1": "en",
+ "file_path": "/iAg2Xyzoswk64bbgp84fPQJKqkE.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 900,
+ "iso_639_1": "en",
+ "file_path": "/dGpm2E32pc2hGfyyuxnJEH7x9uB.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2670,
+ "iso_639_1": "en",
+ "file_path": "/cisZBI1s3D5puRAeXozRHA7ppZg.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1780
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1209,
+ "iso_639_1": "en",
+ "file_path": "/hVGTPscQzRpC9i1m1505DzIOWps.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 806
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": null,
+ "file_path": "/amHi3LqwTWrfGukzlfI9D0FI39p.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/q997YT7rZYNs6Ml67Qq9vvyZnRm.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.75,
+ "height": 800,
+ "iso_639_1": "fr",
+ "file_path": "/aicfkI8htpRFQ5GenqkAq0P3Qrd.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2250,
+ "iso_639_1": null,
+ "file_path": "/jaE2w22P6TJDQ2KMcIfWaejoMTK.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "zh",
+ "file_path": "/1SiCdhpBnzEtq94HkkCTRp6gj66.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "he",
+ "file_path": "/t4RwVAzz7U4qJxdfBms72iEoSPW.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "pt",
+ "file_path": "/kZZO7e2zlmDszQkla6zeTstOfFq.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2859,
+ "iso_639_1": "en",
+ "file_path": "/vjtcDMOk2OxlfRPJM3PXT6o47WG.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1906
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1008,
+ "iso_639_1": "en",
+ "file_path": "/ndklvqYnwYFN1HeymvXmHfdNW2x.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 672
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "pt",
+ "file_path": "/g2DMvPDhDisC3IMfAan7lJHsT0K.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "pt",
+ "file_path": "/iITWh6oLU6DQI1oTIpmAg2L3Dal.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.679,
+ "height": 750,
+ "iso_639_1": "zh",
+ "file_path": "/9kzGr45xLLUx0ed2bXmySVZLZyM.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 509
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/kYkeHi1jwTOkBmR03bAmcYEenq4.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "es",
+ "file_path": "/4rjatbWmGGmu0DZs6WNpXaUWqWN.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "es",
+ "file_path": "/kqZhdlwB0iZFrQGmfMoWeywHT4v.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1125,
+ "iso_639_1": null,
+ "file_path": "/e9Pf0x3bZGQL3NSU9BOeWqU1JMZ.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 750
+ },
+ {
+ "aspect_ratio": 0.67,
+ "height": 1044,
+ "iso_639_1": "en",
+ "file_path": "/4dXgACvaZnzDrH7nY1QhS0JRhNp.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 700
+ },
+ {
+ "aspect_ratio": 0.695,
+ "height": 1093,
+ "iso_639_1": "he",
+ "file_path": "/5Y1u3hUUfW3LxJ90e5BkaunOMHz.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 760
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "he",
+ "file_path": "/cBTzOahpl5BypQSZtDItg5mkCLr.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "fr",
+ "file_path": "/npYngi9SysMGPSb9w2dG3rMDJAL.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2048,
+ "iso_639_1": "no",
+ "file_path": "/dv6Pat0R1Puxgkj3cEpKd64iWkk.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1365
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/oopP8cDQexvXS5y6eXdALtucQXc.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 900,
+ "iso_639_1": "en",
+ "file_path": "/9KmvSD8vSAm51lvYXyBzmOZIVyv.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2048,
+ "iso_639_1": "en",
+ "file_path": "/5jTzcAo6A5HBn9O8ItEtuqjVxie.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1365
+ },
+ {
+ "aspect_ratio": 0.699,
+ "height": 2048,
+ "iso_639_1": "en",
+ "file_path": "/5xnghkcJASzPUk3R5wXZwXTDwHx.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1432
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/eDW5qJBMRwL1jYVwijbbtgWvPj9.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.714,
+ "height": 2100,
+ "iso_639_1": "en",
+ "file_path": "/3upRdskGl7ndnjPPKam5Pd7SZ1V.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1920,
+ "iso_639_1": null,
+ "file_path": "/cbdQWgh0oE50pC5I9NKRpRxDi0P.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1920,
+ "iso_639_1": "en",
+ "file_path": "/8E4ct2agpsO8ADo4DcgQ85A9JzZ.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/2pD6Bks4O2bMlcgb6mRvlYLsLN7.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ }
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-1893.json b/providers/.cache/tmdb_api/tmdb-movie-1893.json
new file mode 100644
index 0000000..8f805e3
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-1893.json
@@ -0,0 +1,66 @@
+{
+ "adult": false,
+ "backdrop_path": "/wDe8LzwuvHYYiuwyNfxdYQq8ti4.jpg",
+ "belongs_to_collection": {
+ "id": 10,
+ "name": "Star Wars Collection",
+ "poster_path": "/22dj38IckjzEEUZwN1tPU5VJ1qq.jpg",
+ "backdrop_path": "/4z9ijhgEthfRHShoOvMaBlpciXS.jpg"
+ },
+ "budget": 115000000,
+ "genres": [
+ {
+ "id": 12,
+ "name": "Adventure"
+ },
+ {
+ "id": 28,
+ "name": "Action"
+ },
+ {
+ "id": 878,
+ "name": "Science Fiction"
+ }
+ ],
+ "homepage": "http://www.starwars.com/films/star-wars-episode-i-the-phantom-menace",
+ "id": 1893,
+ "imdb_id": "tt0120915",
+ "origin_country": [
+ "US"
+ ],
+ "original_language": "en",
+ "original_title": "Star Wars: Episode I - The Phantom Menace",
+ "overview": "Anakin Skywalker, a young slave strong with the Force, is discovered on Tatooine. Meanwhile, the evil Sith have returned, enacting their plot for revenge against the Jedi.",
+ "popularity": 7.5815,
+ "poster_path": "/6wkfovpn7Eq8dYNKaG5PY3q2oq6.jpg",
+ "production_companies": [
+ {
+ "id": 1,
+ "logo_path": "/tlVSws0RvvtPBwViUyOFAO0vcQS.png",
+ "name": "Lucasfilm Ltd.",
+ "origin_country": "US"
+ }
+ ],
+ "production_countries": [
+ {
+ "iso_3166_1": "US",
+ "name": "United States of America"
+ }
+ ],
+ "release_date": "1999-05-19",
+ "revenue": 924317558,
+ "runtime": 136,
+ "spoken_languages": [
+ {
+ "english_name": "English",
+ "iso_639_1": "en",
+ "name": "English"
+ }
+ ],
+ "status": "Released",
+ "tagline": "Every saga has a beginning.",
+ "title": "Star Wars: Episode I - The Phantom Menace",
+ "video": false,
+ "vote_average": 6.566,
+ "vote_count": 15219
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-278-alternatives.json b/providers/.cache/tmdb_api/tmdb-movie-278-alternatives.json
new file mode 100644
index 0000000..280c954
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-278-alternatives.json
@@ -0,0 +1,110 @@
+{
+ "id": 278,
+ "titles": [
+ {
+ "iso_3166_1": "SE",
+ "title": "Rita Hayworth - nyckel till flykten",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "CN",
+ "title": "肖申克的救赎",
+ "type": "Mandarin title"
+ },
+ {
+ "iso_3166_1": "GE",
+ "title": "Gaqceva shoushenkidan",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "AZ",
+ "title": "Şouşenkdən qaçış",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "RU",
+ "title": "Искупление Шоушенком",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "AZ",
+ "title": "Shoushenkden Qacish",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "IR",
+ "title": "Rastgari Dar Shawshank",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "IL",
+ "title": "Homot Shel Tikva",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "JP",
+ "title": "Shôshanku no sora ni",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "RS",
+ "title": "Бекство из Шошенка",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "KR",
+ "title": "쇼생크 탈출",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "FR",
+ "title": "Les Évadés",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "PL",
+ "title": "Skazani na Shawshank",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "JP",
+ "title": "ショーシャンクの空に:1994",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "IR",
+ "title": "رستگاری در شاوشنگ",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "KR",
+ "title": "쇼생크탈출",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "BR",
+ "title": "Um Sonho de Liberdade",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "TW",
+ "title": "刺激1995",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "AM",
+ "title": "Փախուստ Շոուշենքից",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "AR",
+ "title": "Sueño de Libertad",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "BY",
+ "title": "Выкупленне з Шаўшэнку",
+ "type": ""
+ }
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-278-external_ids.json b/providers/.cache/tmdb_api/tmdb-movie-278-external_ids.json
new file mode 100644
index 0000000..878dd74
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-278-external_ids.json
@@ -0,0 +1,8 @@
+{
+ "id": 278,
+ "imdb_id": "tt0111161",
+ "wikidata_id": "Q172241",
+ "facebook_id": null,
+ "instagram_id": null,
+ "twitter_id": null
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-278-images.json b/providers/.cache/tmdb_api/tmdb-movie-278-images.json
new file mode 100644
index 0000000..a75d663
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-278-images.json
@@ -0,0 +1,2682 @@
+{
+ "backdrops": [
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "pt",
+ "file_path": "/jFkuJbWsciMwgcpOEkJIlxTElEp.jpg",
+ "vote_average": 10,
+ "vote_count": 5,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/pNjh59JSxChQktamG3LMp9ZoQzp.jpg",
+ "vote_average": 7.19,
+ "vote_count": 7,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/zfbjgQE1uSd9wiPTX4VzsLi0rGG.jpg",
+ "vote_average": 7.076,
+ "vote_count": 13,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/v8xVDqt8uCul3c3mgx4VpGCwxJC.jpg",
+ "vote_average": 6.722,
+ "vote_count": 9,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1440,
+ "iso_639_1": null,
+ "file_path": "/kXfqcdQKsToO0OUXHcrrNCHDBzO.jpg",
+ "vote_average": 6.38,
+ "vote_count": 21,
+ "width": 2560
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/9Xw0I5RV2ZqNLpul6lXKoviYg55.jpg",
+ "vote_average": 5.682,
+ "vote_count": 11,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/72rRSPAZ82p3KXoGLz2ddTioMQl.jpg",
+ "vote_average": 5.682,
+ "vote_count": 11,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.78,
+ "height": 1180,
+ "iso_639_1": null,
+ "file_path": "/avedvodAZUcwqevBfm8p4G2NziQ.jpg",
+ "vote_average": 5.566,
+ "vote_count": 15,
+ "width": 2100
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/irlfhYtHfhZuYpsq2LAoh308NFe.jpg",
+ "vote_average": 5.25,
+ "vote_count": 9,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/wPU78OPN4BYEgWYdXyg0phMee64.jpg",
+ "vote_average": 4.818,
+ "vote_count": 11,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/gZMgEUYbh0DIBNaRJT0ofxLDJ5T.jpg",
+ "vote_average": 4.722,
+ "vote_count": 9,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "pt",
+ "file_path": "/tXHpvlr5F7gV5DwgS7M5HBrUi2C.jpg",
+ "vote_average": 3.666,
+ "vote_count": 15,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1440,
+ "iso_639_1": null,
+ "file_path": "/swmgZbeiR1LeNeN3uJkyjr8bq8p.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2560
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/rvXJYSRoxsC2aezXTR4uLaPrSZ5.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "es",
+ "file_path": "/ftNEUipZUPFMcj87Ffx8MlY1pJs.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/2YYOTdAI7vN4Iid3ckvtfr4NhTE.jpg",
+ "vote_average": 3.334,
+ "vote_count": 2,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/f6YdUroFE8hNuR5EaWrI50Ue8GB.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/ddzwhOgb35Ezu0t1Lo8J7wa2P65.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1152,
+ "iso_639_1": null,
+ "file_path": "/qgOl7k1ZjSOWPccDG4D4eqfAHY7.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2048
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1440,
+ "iso_639_1": null,
+ "file_path": "/6UntLP7o96AbcN2WTcbVEhZpsF2.jpg",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 2560
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1440,
+ "iso_639_1": null,
+ "file_path": "/b8iMOqi9WuNUKgpjvYCUthApAVL.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2560
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/ztijhkmSL0qikzjHiSRWFtJvmr.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/crLfhuTYadl39DucKK8HcEJctIf.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/6ihu1b2OA0aQY1gp95B7644qeyy.jpg",
+ "vote_average": 1.444,
+ "vote_count": 6,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/xXXFdqV965crlxCO3dj3PhtcCAf.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/mor5PrU9cQghuXp7qRw2LedyCRK.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "es",
+ "file_path": "/qCUjQId2jQS53edDKQXBJojd5sd.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.776,
+ "height": 964,
+ "iso_639_1": "de",
+ "file_path": "/wQP54Zdje3NO0xX8CbmzB07NXNp.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1712
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": null,
+ "file_path": "/odJPRSRkfc5M1HpBoIAFe46RlfI.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/gNCqY2Y6e3wV8cnSVy4Xqpdl6oE.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "fr",
+ "file_path": "/xcw36ItqqSyzigq7saC0Cj4W1xI.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/pdKcdpxqgCcI0vhDgUkfnFUkNZO.jpg",
+ "vote_average": 1.066,
+ "vote_count": 5,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": "en",
+ "file_path": "/A8dxAysDvK3tL5Gy6oI3VT5nYNT.jpg",
+ "vote_average": 0.972,
+ "vote_count": 6,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": null,
+ "file_path": "/1c7EVzpMudkPRwqYU1vjrUnxXX2.jpg",
+ "vote_average": 0.958,
+ "vote_count": 4,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "pt",
+ "file_path": "/twUBY8YYVW4pgl6ESfdfooIO2qi.jpg",
+ "vote_average": 0.854,
+ "vote_count": 8,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "en",
+ "file_path": "/7xofUKLihje3kQGOMLpQpVRO0Bf.jpg",
+ "vote_average": 0.5,
+ "vote_count": 4,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "pt",
+ "file_path": "/maMr76DU7lMkHUPt8DGtVT5qAwA.jpg",
+ "vote_average": 0.5,
+ "vote_count": 6,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "de",
+ "file_path": "/dpSypP6IjUXJDSFYJAnNoS5KPKR.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "it",
+ "file_path": "/kIGUJwrRTjiuaDxphhkP1eIeril.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/1bGBTCPC1lcvrNTluh1bgr1dd2F.jpg",
+ "vote_average": 0.166,
+ "vote_count": 3,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/36ewyr1LdwwedDQhrlmhsi1nlnc.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/dNjXm72V84kzKW3qniHzYrBVFoC.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.779,
+ "height": 1536,
+ "iso_639_1": "fr",
+ "file_path": "/mz3bXh1VG4NvAfvAhS4UY2FVaK7.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 2732
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/rkIG2F13j9VXqs3Pez3yL9iXGBS.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "es",
+ "file_path": "/frrvscolmSemAAsDn49dlwhcQF0.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/tumYpUaRYo18cJYVSb89c8XmQE.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "zh",
+ "file_path": "/f8gJAFEUHiiIX7M5BdIEqJKXD2i.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/3YhI0q3TkT6QVIEVditIemlGmsC.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "ru",
+ "file_path": "/gwrLg3hlxS5sW9F4tVFZSx7dOiF.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/yM67XrFH3l0GqDbnGR0Q6UjzJoO.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/nC143EDrfsZaeknYcnsk5mHUAgT.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/79Q3TAF7azTCGXoJqHuzM7IjEZ9.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "fi",
+ "file_path": "/n5QAkWiPPpPSZSMce5rpVb4LxbD.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "fi",
+ "file_path": "/hll6PtBag2KxOaFgIdwtf2qo6bs.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "tr",
+ "file_path": "/76efEiTtqoPWBIgkCPdRnynYZhU.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": null,
+ "file_path": "/qZNxW24zXzOewK369TbgAsE1dCP.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/e9oWuwOPjXNAE2vaOl1DBj2cjvY.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2034,
+ "iso_639_1": null,
+ "file_path": "/yPvBlSMfxbtTlnW4RRdh6VN867F.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3616
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/69JOwL5G1gVxi7734jhj04YNE4l.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "de",
+ "file_path": "/xU1OGe1Lg5UY3I0Eu6s8At41Gnw.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/yMXRZYGdFa8kcJN9ssl0zrmlhY5.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.777,
+ "height": 736,
+ "iso_639_1": null,
+ "file_path": "/hTBYnYBq7h7KdPGlcmfZZjSLc0L.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1308
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "zh",
+ "file_path": "/kBgXUIqO1KytikAR6HtyxVaZFMm.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "zh",
+ "file_path": "/mfMcITepx7XrkwtWmuaVxq5jsFQ.jpg",
+ "vote_average": 0,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1125,
+ "iso_639_1": "es",
+ "file_path": "/8VigOHKluuIJkOnpwE77Vz1lg2N.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/9h5d3eGBeIS8WEEKpeic63sPIDH.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/p8s2itKovPDMziDBCeuA5xwdIT7.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": null,
+ "file_path": "/sPJoiXSCFEUjkZrRqsQlGg1HF.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1280
+ }
+ ],
+ "id": 278,
+ "logos": [
+ {
+ "aspect_ratio": 6.984,
+ "height": 183,
+ "iso_639_1": "pt",
+ "file_path": "/hp0Dbsukf6dOCTltFHeWBEG9nE1.png",
+ "vote_average": 7.542,
+ "vote_count": 8,
+ "width": 1278
+ },
+ {
+ "aspect_ratio": 2.165,
+ "height": 699,
+ "iso_639_1": "zh",
+ "file_path": "/oW78Km1bhNE0awyMRo7YNZyTc3Y.png",
+ "vote_average": 5.87,
+ "vote_count": 23,
+ "width": 1513
+ },
+ {
+ "aspect_ratio": 3.467,
+ "height": 225,
+ "iso_639_1": "zh",
+ "file_path": "/tSrHl8p6hDaQ4PX0ST8x5ZG3BPy.png",
+ "vote_average": 5.024,
+ "vote_count": 21,
+ "width": 780
+ },
+ {
+ "aspect_ratio": 4.516,
+ "height": 847,
+ "iso_639_1": "zh",
+ "file_path": "/ymP8S0nu4mJcqcbNovMzdaOWKgn.png",
+ "vote_average": 4.934,
+ "vote_count": 15,
+ "width": 3825
+ },
+ {
+ "aspect_ratio": 4.517,
+ "height": 847,
+ "iso_639_1": "zh",
+ "file_path": "/kMTMkVwc8eg9lSyitAM56fxhYHg.png",
+ "vote_average": 4.884,
+ "vote_count": 13,
+ "width": 3826
+ },
+ {
+ "aspect_ratio": 4.517,
+ "height": 847,
+ "iso_639_1": "zh",
+ "file_path": "/iUGNARJHJNqkmpE3jWYdpWkuLz7.png",
+ "vote_average": 4.3,
+ "vote_count": 10,
+ "width": 3826
+ },
+ {
+ "aspect_ratio": 4.203,
+ "height": 187,
+ "iso_639_1": "ru",
+ "file_path": "/2FBRJDL06YPtoPTrwU4rTARLs76.png",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 786
+ },
+ {
+ "aspect_ratio": 5.03,
+ "height": 135,
+ "iso_639_1": "fr",
+ "file_path": "/eblAEOleGuhR4xWAGXBTr0rbptu.png",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 679
+ },
+ {
+ "aspect_ratio": 4.266,
+ "height": 94,
+ "iso_639_1": "fr",
+ "file_path": "/4jFpYGcYKqPHvCmZxj7MTqsGxlh.png",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 401
+ },
+ {
+ "aspect_ratio": 4.105,
+ "height": 190,
+ "iso_639_1": "zh",
+ "file_path": "/i3ZntvQU2j2XZCM1GtfcJMUVGyu.png",
+ "vote_average": 3.334,
+ "vote_count": 3,
+ "width": 780
+ },
+ {
+ "aspect_ratio": 4.893,
+ "height": 364,
+ "iso_639_1": "pt",
+ "file_path": "/sUfdYqk5ysAz5eZv5Zn1voDs6r4.png",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 1781
+ },
+ {
+ "aspect_ratio": 5.184,
+ "height": 833,
+ "iso_639_1": "en",
+ "file_path": "/8pPq3gJG4oWYonbL6DaHslJeCaM.png",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 4318
+ },
+ {
+ "aspect_ratio": 4.188,
+ "height": 356,
+ "iso_639_1": "pt",
+ "file_path": "/oHg06qP7D8VIRtu01Q84qrXdKbE.png",
+ "vote_average": 1.31,
+ "vote_count": 7,
+ "width": 1491
+ },
+ {
+ "aspect_ratio": 3.678,
+ "height": 214,
+ "iso_639_1": "pt",
+ "file_path": "/lYAg1CoC4PtnFCv3DhA5HJ5ueki.png",
+ "vote_average": 0.5,
+ "vote_count": 5,
+ "width": 787
+ },
+ {
+ "aspect_ratio": 3.7,
+ "height": 213,
+ "iso_639_1": "pt",
+ "file_path": "/wqBFEKPbpuqWGxfk3J32uXkfU1o.png",
+ "vote_average": 0.5,
+ "vote_count": 5,
+ "width": 788
+ },
+ {
+ "aspect_ratio": 5.133,
+ "height": 746,
+ "iso_639_1": "pt",
+ "file_path": "/wUNlm832MeXjYo9fnDzGtg0ZrQY.png",
+ "vote_average": 0.5,
+ "vote_count": 5,
+ "width": 3829
+ },
+ {
+ "aspect_ratio": 4.547,
+ "height": 137,
+ "iso_639_1": "pt",
+ "file_path": "/xT5X4J23fesyhRdJkGaQrzN5Na1.png",
+ "vote_average": 0.5,
+ "vote_count": 5,
+ "width": 623
+ },
+ {
+ "aspect_ratio": 4.925,
+ "height": 159,
+ "iso_639_1": "it",
+ "file_path": "/hEJz2la3V7w3yMjNWHwIWr5Hp0e.png",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 783
+ },
+ {
+ "aspect_ratio": 5.303,
+ "height": 218,
+ "iso_639_1": "en",
+ "file_path": "/x7nYR0Ep7RwxxCoHidpovmF3qI0.svg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1156
+ },
+ {
+ "aspect_ratio": 5.303,
+ "height": 218,
+ "iso_639_1": "en",
+ "file_path": "/aQWGy7rijv2cs7lUVi0Av3SDedn.svg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1156
+ },
+ {
+ "aspect_ratio": 5.267,
+ "height": 150,
+ "iso_639_1": "fr",
+ "file_path": "/9AQhthshCSlWgL2A3MFZXDdadre.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 790
+ },
+ {
+ "aspect_ratio": 4.4,
+ "height": 180,
+ "iso_639_1": "de",
+ "file_path": "/m01p4bi3FEjQ9VQHkG5lJfvxvhC.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 792
+ },
+ {
+ "aspect_ratio": 2.003,
+ "height": 293,
+ "iso_639_1": "es",
+ "file_path": "/kWaSYmbGzkuln9nK4tmJBLEV0Tt.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 587
+ },
+ {
+ "aspect_ratio": 6.653,
+ "height": 118,
+ "iso_639_1": "pl",
+ "file_path": "/p9cLcbaKyRp6XaT6BbWVwQ5hYqb.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 785
+ },
+ {
+ "aspect_ratio": 5.267,
+ "height": 150,
+ "iso_639_1": "fr",
+ "file_path": "/eJR9LoDkGiUH4Zayp6gcrJewwVI.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 790
+ },
+ {
+ "aspect_ratio": 4.302,
+ "height": 182,
+ "iso_639_1": "en",
+ "file_path": "/9D1HSLHZpTADqk8syKWWg5HSOXU.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 783
+ },
+ {
+ "aspect_ratio": 3.995,
+ "height": 196,
+ "iso_639_1": "it",
+ "file_path": "/98qgchyf4m9MW381hDcenoUWMBC.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 783
+ },
+ {
+ "aspect_ratio": 2.621,
+ "height": 298,
+ "iso_639_1": "es",
+ "file_path": "/iU2fT9lJYQZlquWGE36ULaaOJsw.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 781
+ },
+ {
+ "aspect_ratio": 3.231,
+ "height": 242,
+ "iso_639_1": "fr",
+ "file_path": "/9JGraAI198iJ02os2UFGQqS4MQu.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 782
+ },
+ {
+ "aspect_ratio": 6.429,
+ "height": 266,
+ "iso_639_1": "hu",
+ "file_path": "/yE7TB0jjzYBAecxV439GMfHnjBq.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1710
+ },
+ {
+ "aspect_ratio": 3.545,
+ "height": 220,
+ "iso_639_1": "fi",
+ "file_path": "/hDcbv5DkUUnNBYLGbzHPvYTR0y4.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 780
+ },
+ {
+ "aspect_ratio": 2.518,
+ "height": 228,
+ "iso_639_1": "he",
+ "file_path": "/ywqSjpyD7J3aWzgOT4jiKu2WKlt.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 574
+ },
+ {
+ "aspect_ratio": 2.727,
+ "height": 450,
+ "iso_639_1": "cs",
+ "file_path": "/wuksxoiLKFkdZ9WM03ZjR7Eg9aD.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1227
+ },
+ {
+ "aspect_ratio": 2.727,
+ "height": 450,
+ "iso_639_1": "cs",
+ "file_path": "/rKV6sj4pySfqUlBGV4l8YTqTIQ7.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1227
+ },
+ {
+ "aspect_ratio": 3.16,
+ "height": 257,
+ "iso_639_1": "zh",
+ "file_path": "/iNYFZsbQNsEgKXPRM2NAGlxLoCV.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 812
+ },
+ {
+ "aspect_ratio": 3.076,
+ "height": 409,
+ "iso_639_1": "es",
+ "file_path": "/tCsVQm4fKPT7dSLopKJpjkWLU9h.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1258
+ },
+ {
+ "aspect_ratio": 2.811,
+ "height": 318,
+ "iso_639_1": "he",
+ "file_path": "/bG1JNKgeGUXczskZHaC1KEXuSHS.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 894
+ },
+ {
+ "aspect_ratio": 1.859,
+ "height": 1177,
+ "iso_639_1": "ca",
+ "file_path": "/iso8ykpAgyq7Rx3epSn9DQQMcDn.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2188
+ },
+ {
+ "aspect_ratio": 6.091,
+ "height": 197,
+ "iso_639_1": "fi",
+ "file_path": "/pnXouV02leDv0SX59vSeZO2LYXR.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1200
+ },
+ {
+ "aspect_ratio": 5.662,
+ "height": 225,
+ "iso_639_1": "ro",
+ "file_path": "/1tdLmdgFXk7XhmWTQIN20R3qUqQ.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1274
+ },
+ {
+ "aspect_ratio": 3.464,
+ "height": 788,
+ "iso_639_1": "de",
+ "file_path": "/oHfeBiORzDEVbF0Z3UbYxOqZSMR.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2730
+ },
+ {
+ "aspect_ratio": 4.474,
+ "height": 348,
+ "iso_639_1": "de",
+ "file_path": "/AcZ6lNYPBscPTlrLeXYJOvaackB.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1557
+ },
+ {
+ "aspect_ratio": 5.29,
+ "height": 945,
+ "iso_639_1": "en",
+ "file_path": "/b1ZFSQ1df0LU7UzuWlSpOOe4V8R.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 4999
+ },
+ {
+ "aspect_ratio": 5.29,
+ "height": 945,
+ "iso_639_1": "en",
+ "file_path": "/1K53E8WXQW76Scg8upBObXSrbgN.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 4999
+ },
+ {
+ "aspect_ratio": 3.095,
+ "height": 1051,
+ "iso_639_1": "zh",
+ "file_path": "/p5SdUmfmjp36l78SB0X3ennTDjd.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3253
+ },
+ {
+ "aspect_ratio": 4.778,
+ "height": 734,
+ "iso_639_1": "ru",
+ "file_path": "/3DFboKRcFLz8dbrBzJ9ZsHJOBO2.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3507
+ },
+ {
+ "aspect_ratio": 2.5,
+ "height": 250,
+ "iso_639_1": "fr",
+ "file_path": "/gdT94Bp0Lsxg3OBEkge7qsUkCD9.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 625
+ },
+ {
+ "aspect_ratio": 5.292,
+ "height": 1052,
+ "iso_639_1": "en",
+ "file_path": "/5erjifDR4YGHamcsr4X0P9uTS9q.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 5567
+ }
+ ],
+ "posters": [
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/9cqNxx0GxF0bflZmeSMuL5tnGzr.jpg",
+ "vote_average": 7.5,
+ "vote_count": 19,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "sv",
+ "file_path": "/7JlNQZtNQn4h0iXWZ6rsq3eqMlH.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "uk",
+ "file_path": "/6BRshOK03BnxTedpAhZl2yZBLTY.jpg",
+ "vote_average": 10,
+ "vote_count": 8,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": null,
+ "file_path": "/u5hLebzUOBGbnPikIyxI1159lhc.jpg",
+ "vote_average": 10,
+ "vote_count": 4,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fr",
+ "file_path": "/t30GjttOdb5At1sYy8b3TOwFgWV.jpg",
+ "vote_average": 10,
+ "vote_count": 5,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "ru",
+ "file_path": "/yvmKPlTIi0xdcFQIFcQKQJcI63W.jpg",
+ "vote_average": 8.362,
+ "vote_count": 6,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "es",
+ "file_path": "/uRRTV7p6l2ivtODWJVVAMRrwTn2.jpg",
+ "vote_average": 7.19,
+ "vote_count": 8,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/20f2GThu22hp5MgCA4dg3bZ3gTS.jpg",
+ "vote_average": 6.834,
+ "vote_count": 12,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "zh",
+ "file_path": "/aAdnwqwkKX5PPcr8EdtaiA8AZVl.jpg",
+ "vote_average": 6.834,
+ "vote_count": 16,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "pt",
+ "file_path": "/xSnM4ahmz692msbMTBsfBWHvR3M.jpg",
+ "vote_average": 5.928,
+ "vote_count": 21,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "zh",
+ "file_path": "/lnu10JjbS3dhv38UCg832hmvQj3.jpg",
+ "vote_average": 5.928,
+ "vote_count": 50,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "pt",
+ "file_path": "/umX3lBhHoTV7Lsci140Yr8VpXyN.jpg",
+ "vote_average": 5.82,
+ "vote_count": 26,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1827,
+ "iso_639_1": "zh",
+ "file_path": "/rlEE82K5m03rRZidFKNzCN67xQ2.jpg",
+ "vote_average": 5.788,
+ "vote_count": 106,
+ "width": 1218
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/q6y0Go1tsGEsmtFryDOJo3dEmqu.jpg",
+ "vote_average": 5.682,
+ "vote_count": 55,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/lyQBXzOQSuE59IsHyhrp0qIiPAz.jpg",
+ "vote_average": 5.682,
+ "vote_count": 33,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "zh",
+ "file_path": "/x6cLNyJWKK7jdaqL9UNPlvJJoVD.jpg",
+ "vote_average": 5.628,
+ "vote_count": 113,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "zh",
+ "file_path": "/5YBgcdKcxGJJOULqsFWlU03vm3V.jpg",
+ "vote_average": 5.59,
+ "vote_count": 28,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1350,
+ "iso_639_1": "en",
+ "file_path": "/hBcY0fE9pfXzvVaY4GKarweriG2.jpg",
+ "vote_average": 5.5,
+ "vote_count": 19,
+ "width": 900
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "es",
+ "file_path": "/dc1fX265fZIIY5Hab8I7CdETyJy.jpg",
+ "vote_average": 5.25,
+ "vote_count": 12,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": "en",
+ "file_path": "/hxcHfW0o5QhY6slqGc7dkEkvo6U.jpg",
+ "vote_average": 5.25,
+ "vote_count": 14,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.675,
+ "height": 1600,
+ "iso_639_1": "en",
+ "file_path": "/qTEApvOJ4H7pGWcwDMqr9OcQ5sc.jpg",
+ "vote_average": 5.25,
+ "vote_count": 8,
+ "width": 1080
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 913,
+ "iso_639_1": "zh",
+ "file_path": "/rPKLWFUML5hf92AuTcpgOSbNFSr.jpg",
+ "vote_average": 4.918,
+ "vote_count": 43,
+ "width": 640
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fr",
+ "file_path": "/xqfTE9FjwD5vS1A6QnyoMdPQUvh.jpg",
+ "vote_average": 4.154,
+ "vote_count": 13,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "pl",
+ "file_path": "/sBnhJ4f5KAzg6C3FwnEb8QFj8SB.jpg",
+ "vote_average": 3.334,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "it",
+ "file_path": "/9OxcvTJwZDjQTFvY2NxiwnSrQS6.jpg",
+ "vote_average": 3.334,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": null,
+ "file_path": "/jkgkQtCoNVmmKDzKk3ccQRFkAER.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.676,
+ "height": 1000,
+ "iso_639_1": "bg",
+ "file_path": "/8ERqVgbD5JM1DxqeMH89LQf5Wb5.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 676
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "de",
+ "file_path": "/78Pb6FMLMfpm1jUOKTniwREYgAN.jpg",
+ "vote_average": 3.334,
+ "vote_count": 3,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": null,
+ "file_path": "/8ns9BU3KmssqML3CFmthddt2qOb.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1200,
+ "iso_639_1": "pl",
+ "file_path": "/7Iwiu8Sj0BLlyAglSnfyymkk4t1.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 841
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "hu",
+ "file_path": "/oBZ36R1z6Ner9TYmZeSWPhHwF7r.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "de",
+ "file_path": "/8o6SYam6HizgkQamJqIs511rAaN.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "de",
+ "file_path": "/g6T9oQLxkv1WLK9KSQlysO6FHF.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "de",
+ "file_path": "/mFBoXMocZNwMO8op85Y9TUq5Lbr.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "tr",
+ "file_path": "/7T2SDS5efuJiK45oyKoEzf9RKjw.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "tr",
+ "file_path": "/hOHhVYz9SFtwryNL0oxsSntoYXq.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "de",
+ "file_path": "/tfSoxlIokmu1vPcYSVujy95fIBq.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.674,
+ "height": 1484,
+ "iso_639_1": "he",
+ "file_path": "/nZPmmw6CFaYv2CwXGf7qX3imU3o.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1024,
+ "iso_639_1": "en",
+ "file_path": "/bAEV6D3M4tRVGBZca69BMYtxxFv.jpg",
+ "vote_average": 3.334,
+ "vote_count": 3,
+ "width": 683
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ro",
+ "file_path": "/eQesWpskcj6FFulKEKO6Sycawff.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/vbKG1RbdN7Y6eEVXgeMApb2me9L.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ro",
+ "file_path": "/tsY4m4IH8MZly4kvxZszbommLKj.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fr",
+ "file_path": "/xSVtT2gi6FfBtkdnLsmqqNP3KmP.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.7,
+ "height": 2858,
+ "iso_639_1": "ko",
+ "file_path": "/qV9BQZdiM8foEzDz0Ag5hGWE5qM.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ca",
+ "file_path": "/4DUFGVxyTJdcyvD9zG40vNVUXhR.jpg",
+ "vote_average": 3.334,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ja",
+ "file_path": "/xQY1yhixcSSfKRhdlhzwN8Mra6q.jpg",
+ "vote_average": 3.334,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ru",
+ "file_path": "/dGoSk9yyfjiWZXZPpTjwKBBriME.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2700,
+ "iso_639_1": "ru",
+ "file_path": "/l38alxTRHxvWBiUwFytpcUgdQmD.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1800
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ar",
+ "file_path": "/9rZu8rnOE1MwN1hrTquwAPR1l0G.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1411,
+ "iso_639_1": "hr",
+ "file_path": "/iaefBZx7B3AoNWdoEG38l4fGPDJ.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 941
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2097,
+ "iso_639_1": "en",
+ "file_path": "/hJdaYSO7II8EUfPEMKIfjmjmgxy.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1398
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/uVJlB59STDVu8M5Q5p2bzDJ66H0.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": null,
+ "file_path": "/pi0YD6U6KDLJxH6LYUQbSAXiO5E.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "es",
+ "file_path": "/l6V3TEoJlGh3ztAFxK2hemHfDJ2.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 750,
+ "iso_639_1": "fa",
+ "file_path": "/kVzRXQ8JRi8aAZo7q7UN6CgZCHZ.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 500
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 750,
+ "iso_639_1": "fa",
+ "file_path": "/iKc81aIlCahY7eyk93cXQpPZBSa.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 526
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 750,
+ "iso_639_1": "fa",
+ "file_path": "/7dhxu2oJxVhUmhafYfyOgXSzonV.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 500
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 750,
+ "iso_639_1": "fa",
+ "file_path": "/8QvIkGbDENeTDZDlvK332TLmEvI.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 526
+ },
+ {
+ "aspect_ratio": 0.665,
+ "height": 2720,
+ "iso_639_1": "fr",
+ "file_path": "/wSb7ofZ0VbQa6smOuQmiUcaGc4q.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1808
+ },
+ {
+ "aspect_ratio": 0.665,
+ "height": 2720,
+ "iso_639_1": "fr",
+ "file_path": "/h8fPpGyNNT1TklnOAymA7hGknxF.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1808
+ },
+ {
+ "aspect_ratio": 0.665,
+ "height": 2720,
+ "iso_639_1": "fr",
+ "file_path": "/k1oflmpuJP6baDGkrnPM1Lw4WuL.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1808
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2250,
+ "iso_639_1": "pt",
+ "file_path": "/4BSuFpQ2gd2WtO5ZK1fMjaMPMRc.jpg",
+ "vote_average": 2.736,
+ "vote_count": 17,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1800,
+ "iso_639_1": "zh",
+ "file_path": "/Aqo8yM5S5ZEdlcyeBBxj7s0vkTf.jpg",
+ "vote_average": 2.542,
+ "vote_count": 4,
+ "width": 1200
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "cs",
+ "file_path": "/hF4aMQF3x0SGFS3gd5SoQecurNV.jpg",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "de",
+ "file_path": "/ltLIbF304D8FQvTPhzZSTnumZdR.jpg",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/ruRhPgeh1xSN7kBMkvbvMjsYW1Z.jpg",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fr",
+ "file_path": "/iYfVYSMNLQDl03nVFTxvqHr19RQ.jpg",
+ "vote_average": 1.75,
+ "vote_count": 4,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.676,
+ "height": 1776,
+ "iso_639_1": "he",
+ "file_path": "/7Gvzbduz2iApKA3g7nbyGcfoBCL.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1200
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "he",
+ "file_path": "/hLLpzEK6q8QQJy477KCx9mAqBBy.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "fr",
+ "file_path": "/rL1YQLqUtHK3HdQyenHvuOCuWzO.jpg",
+ "vote_average": 1.75,
+ "vote_count": 6,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.698,
+ "height": 2149,
+ "iso_639_1": "ko",
+ "file_path": "/oAt6OtpwYCdJI76AVtVKW1eorYx.jpg",
+ "vote_average": 1.75,
+ "vote_count": 6,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2700,
+ "iso_639_1": "en",
+ "file_path": "/zFjb7BVXbKeGhSxC7Yg2TgTCSgr.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1800
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/orcTUEAuVyGYjUM47HRhb7DRLRa.jpg",
+ "vote_average": 1.75,
+ "vote_count": 4,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "tr",
+ "file_path": "/dXyIK3s8ZN7FH3AoaeyaBqX0eoJ.jpg",
+ "vote_average": 1.75,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fr",
+ "file_path": "/wJH9wMDQ2iEZkgYh76sp0wIhJOc.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/hoYr43FoLioV6M8s48KG5j1aVQS.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1350,
+ "iso_639_1": "en",
+ "file_path": "/4aR8q9eYyOFarByeHzJnGG25PZX.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 900
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/pVHyB857pFAl9pBgOGzWTChPwlK.jpg",
+ "vote_average": 1.75,
+ "vote_count": 4,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.75,
+ "height": 2560,
+ "iso_639_1": "ja",
+ "file_path": "/1FuwVDvsJqmKdLQjsN9lgNnwJm7.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "la",
+ "file_path": "/88MAvVVr6wJ6uNieCf2SdauEUVW.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 960,
+ "iso_639_1": "la",
+ "file_path": "/9tDQP1b1iffUP9gj1YCinNX3AcZ.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 640
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/vOTVk6ZAvhNef8l3devUFX28XiA.jpg",
+ "vote_average": 1.75,
+ "vote_count": 4,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2963,
+ "iso_639_1": "en",
+ "file_path": "/kd87OFsGRHWwYfbNZqiOFtu3qCJ.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1976
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/jXRpoV5VlwlasUxzI7MA5yOxNWO.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "fr",
+ "file_path": "/u56XDbQfdhqLQgGHtxa5OFZWnOI.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ca",
+ "file_path": "/1qCRLvKcGUpiqfDaq3whdoe1tXk.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1425,
+ "iso_639_1": "en",
+ "file_path": "/qYcGVwSDrOkEuM2DoJnKs8stlns.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 950
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/tRWnPRolQJF0SNHIQYQRCnKj7lG.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "es",
+ "file_path": "/zxXfCuskvMxL3Am563xQBKfPLSx.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1800,
+ "iso_639_1": "zh",
+ "file_path": "/sk4U9hbqLba2qL4ybCNCPdvEJ6m.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1200
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "pt",
+ "file_path": "/vSw24SogM3ciF6EzyvgZhtEBJku.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "es",
+ "file_path": "/7ZpJgdxMQ3rD746xRmfhFbfYRw3.jpg",
+ "vote_average": 1.444,
+ "vote_count": 6,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fr",
+ "file_path": "/jLAipQvoHwQL13db70Xq5igfQQu.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/3Y5pedOGJLnGevsQOWevrhQ7UiA.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/voKPwraRvfp4IIlCAIbTzrg7O4i.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.682,
+ "height": 755,
+ "iso_639_1": "en",
+ "file_path": "/2GgerXCbCMgvt2kLwWEmJWCSG65.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 515
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2400,
+ "iso_639_1": "de",
+ "file_path": "/ncnzihfDVOXuLb36pUnEVG5zvwe.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1600
+ },
+ {
+ "aspect_ratio": 0.744,
+ "height": 1600,
+ "iso_639_1": "fr",
+ "file_path": "/kkfCz0FZPMl5gOaiR6pKuUs4ddV.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1190
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "fr",
+ "file_path": "/jxOLe6sQoJ6mwSJ78LVAj2r2r1c.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "pt",
+ "file_path": "/6GZBRtAhzkSQcKfkZqmrG3cdfRQ.jpg",
+ "vote_average": 1.208,
+ "vote_count": 12,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.678,
+ "height": 2213,
+ "iso_639_1": "en",
+ "file_path": "/mPlopztbARoMahaSgl5oQvR0e4T.jpg",
+ "vote_average": 1.066,
+ "vote_count": 5,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "pt",
+ "file_path": "/zD5WqV8yswXYpDFScXgrBwGpcXa.jpg",
+ "vote_average": 1.066,
+ "vote_count": 10,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 750,
+ "iso_639_1": "es",
+ "file_path": "/vn2XvBmxgM906Olakmp8MpirVqa.jpg",
+ "vote_average": 0.958,
+ "vote_count": 5,
+ "width": 500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1863,
+ "iso_639_1": "zh",
+ "file_path": "/reHZHHsdfQDqWlzcnczAoRFyH2C.jpg",
+ "vote_average": 0.774,
+ "vote_count": 31,
+ "width": 1242
+ },
+ {
+ "aspect_ratio": 0.676,
+ "height": 1480,
+ "iso_639_1": "en",
+ "file_path": "/pkDjn2aAg96XTL373w88hYEBZ3N.jpg",
+ "vote_average": 0.5,
+ "vote_count": 5,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": "es",
+ "file_path": "/zZngO1m9BTOh5dGPHIHccHN2AZP.jpg",
+ "vote_average": 0.5,
+ "vote_count": 4,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.709,
+ "height": 776,
+ "iso_639_1": "ja",
+ "file_path": "/5NyJbE7JVfDJtP7c4CQzxgCLHFY.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 550
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 3000,
+ "iso_639_1": "uk",
+ "file_path": "/7e7c8xYDpF9MxleV6zHLgnrv2tP.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 1999
+ },
+ {
+ "aspect_ratio": 0.7,
+ "height": 1600,
+ "iso_639_1": "tr",
+ "file_path": "/eOZrLKszfq8VOqPUxOVlSLwpY5W.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 1120
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "sv",
+ "file_path": "/wSnStw76OolZTtVtbBeAsK7xgtJ.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/y3ULnBxPeEsUmgK2hSvFkzkIpYF.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.679,
+ "height": 1082,
+ "iso_639_1": "en",
+ "file_path": "/3v7VfHBDpNbEB3c0FRerKAMhEGO.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 735
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": "de",
+ "file_path": "/yPGxk3cr5mAKxYAMroKdOyEVwzO.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.704,
+ "height": 2272,
+ "iso_639_1": "de",
+ "file_path": "/rBtVI5oCbsev8NoCtsQckXGkPKx.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1600
+ },
+ {
+ "aspect_ratio": 0.705,
+ "height": 1418,
+ "iso_639_1": "de",
+ "file_path": "/yqlq7KRqYMuatp9y24IfgRz54aL.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2400,
+ "iso_639_1": "de",
+ "file_path": "/42YJMRPbuGOPv8CdRNXtJ4flFwJ.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 1600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "de",
+ "file_path": "/1tqLnG5ibkG27Gx8HSCX3VYaAK2.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": "es",
+ "file_path": "/j8IMbiv2LN0pSptfVgoVUkhWbPE.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 900,
+ "iso_639_1": "de",
+ "file_path": "/ivAuX9nENHF9UgVLQTHRxdkQR9M.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1125,
+ "iso_639_1": "tr",
+ "file_path": "/6KauxOU76foQywzbyyeZducc9An.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 750
+ },
+ {
+ "aspect_ratio": 0.75,
+ "height": 2666,
+ "iso_639_1": "fr",
+ "file_path": "/2XSBog97WLC7iX5kJ8OL630v6HZ.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": "hr",
+ "file_path": "/1Thadck9UBVw6ymxLLEDVnra1Ga.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1462,
+ "iso_639_1": "en",
+ "file_path": "/8xuf5l4l4hbYlSjmNpLxrBeFCue.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 975
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/akGgX7RIIg6HGVuqc5QkAgqX5XW.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/2vty1EcIvVawSvoFVxyCbZH7kDJ.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1875,
+ "iso_639_1": "en",
+ "file_path": "/sTqKtdiTkm9XYsOrAdSpp2J5y5G.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1250
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1875,
+ "iso_639_1": "en",
+ "file_path": "/aGIbKzbvqBLvFocfxS9CoL9WhND.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1250
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "fa",
+ "file_path": "/wr964aRv9tl6V0afR3crrQPi57i.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.714,
+ "height": 1644,
+ "iso_639_1": "en",
+ "file_path": "/zJZcQEjVLSmzTe7eGBAZMC2drNX.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1174
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1875,
+ "iso_639_1": "en",
+ "file_path": "/g8Om8s4hZwwGniqg8eMiiAs0NaB.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1250
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "sv",
+ "file_path": "/4j39r2UXXqrCZSJA0N2Tvl9EufS.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "it",
+ "file_path": "/hdBsFWCdcCYCl5F7ok2MvsNQ973.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "it",
+ "file_path": "/i4AxNN7MGjarGnN67V3eMgODY6k.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "hu",
+ "file_path": "/hhhYhZiubfKhl7RYd4BiDQabd55.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2148,
+ "iso_639_1": "ko",
+ "file_path": "/3hO6DIGRBaJQj2NLEYBMwpcz88D.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1432
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 1046,
+ "iso_639_1": "it",
+ "file_path": "/dhstPYlWLdjjvubWrB3HvfST60r.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 697
+ },
+ {
+ "aspect_ratio": 0.676,
+ "height": 1776,
+ "iso_639_1": "he",
+ "file_path": "/m0lkTW9r7NCFQXcAcGfOG8TfTO3.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1200
+ },
+ {
+ "aspect_ratio": 0.704,
+ "height": 781,
+ "iso_639_1": "pl",
+ "file_path": "/1ZHjnqcy0ommhnjXRIFQ58mAiRu.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 550
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 750,
+ "iso_639_1": "no",
+ "file_path": "/mvM2jWXjGGxjA3H4mYgErMrYMTD.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 900,
+ "iso_639_1": "mn",
+ "file_path": "/rDqAuJxd1u2PoQ6yT7z8uGd6oCW.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 600
+ },
+ {
+ "aspect_ratio": 0.704,
+ "height": 750,
+ "iso_639_1": "ja",
+ "file_path": "/nPuxODzbSWdDbxPCdt6fc32FSHh.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 528
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "fi",
+ "file_path": "/4O33Dfd3WV6A1rP30oelCGFIpa2.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.703,
+ "height": 2277,
+ "iso_639_1": "de",
+ "file_path": "/pRe80GfjBVhUFvQ1ACv4rdEcRAD.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1600
+ },
+ {
+ "aspect_ratio": 0.705,
+ "height": 1418,
+ "iso_639_1": "de",
+ "file_path": "/6yDAJdZzYyGysBZ0dkLh6oW3lkK.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.703,
+ "height": 1422,
+ "iso_639_1": "de",
+ "file_path": "/wDjWuPG69NgwImEY9ibAIY5podw.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.674,
+ "height": 1000,
+ "iso_639_1": "en",
+ "file_path": "/w6zm0soNQIFrLse5Lp5a1ZO9mhQ.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 674
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "de",
+ "file_path": "/nCMJaXS4DkbUbx2EctXO4YVb5Ly.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2650,
+ "iso_639_1": "en",
+ "file_path": "/p9F5HzPt7PJLTaTHA8h1Hg9mjC2.jpg",
+ "vote_average": 0,
+ "vote_count": 1,
+ "width": 1768
+ },
+ {
+ "aspect_ratio": 0.75,
+ "height": 835,
+ "iso_639_1": "uz",
+ "file_path": "/zgyRWri2luavFepRC2vHwYQcT0t.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 626
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 750,
+ "iso_639_1": "vi",
+ "file_path": "/zLyG4nquaaZKCA3CJdQCEzTwN1R.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/oKUqKztiF3or2XEnMy2D9ZuQpeA.jpg",
+ "vote_average": 0,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.675,
+ "height": 1080,
+ "iso_639_1": "ko",
+ "file_path": "/1sms5568Ta20go9N0GseZ0LGsNQ.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 729
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "de",
+ "file_path": "/aPwNvUuBpXcw2ehCCUQTuKJIlz3.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": null,
+ "file_path": "/jVGdzN7DTuP68WElqqJeXsjjQQq.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 959,
+ "iso_639_1": "en",
+ "file_path": "/b6qnj9ebvqU9STQHUgch2bOUxuf.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 640
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "es",
+ "file_path": "/hjvrLaLFzC4FOouEH13R4DaV8b7.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "ja",
+ "file_path": "/fzDcdO1VMPTxmCD3PZETATzwVlX.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1024,
+ "iso_639_1": "en",
+ "file_path": "/oA3MMsjuWC2MYEgFLMj6k6U14Ot.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 683
+ },
+ {
+ "aspect_ratio": 0.709,
+ "height": 1410,
+ "iso_639_1": "uk",
+ "file_path": "/iYqov9r2tMz8XATmYD6EpPLojjl.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.709,
+ "height": 2560,
+ "iso_639_1": "uk",
+ "file_path": "/sDaT7aGbAaUn2nxoHOHFk6gHR5J.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1814
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "it",
+ "file_path": "/tGFfw6S0qW5ukvwKRLQKm44leCl.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1499,
+ "iso_639_1": null,
+ "file_path": "/sk6SHy0bgTdRDaFj7vUyopqR47V.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/5OWFF1DhvYVQiX1yUrBE9CQqO5t.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fi",
+ "file_path": "/aClrpO0QRhgNXHQJdq4UXMuBGUX.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fi",
+ "file_path": "/15zQ0V9n0sBcf1YwCIs1M2xFDC7.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.7,
+ "height": 1000,
+ "iso_639_1": "el",
+ "file_path": "/A83tDJvKx41oMu4dqALmQjjp6rt.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 700
+ },
+ {
+ "aspect_ratio": 0.683,
+ "height": 1048,
+ "iso_639_1": "el",
+ "file_path": "/kWYHJdgfNZ7pYu9TieKlANct44G.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 716
+ },
+ {
+ "aspect_ratio": 0.75,
+ "height": 2667,
+ "iso_639_1": "it",
+ "file_path": "/qOburER4QhtP2Jj1I0NPAZvK6Ob.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2876,
+ "iso_639_1": "en",
+ "file_path": "/qsfaLB57yg0QhGKwjNjg7PP0Uuj.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1917
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "bg",
+ "file_path": "/eOXL6YCP92VorHUgbjb8S5zxLaj.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "bg",
+ "file_path": "/tITcu1W3sE8qaVv3kzNKhXhh8kk.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": null,
+ "file_path": "/6EtXxfHTbBANsOjpvsQo9B5LPU4.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": null,
+ "file_path": "/5ACk37KLpcQ1ecwEcb7Lm5RcVjL.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": null,
+ "file_path": "/9njC9T3BFRJGwXh4aE0nusS0tKa.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "fi",
+ "file_path": "/nG6ihaz7hj8fX6vfsJJUm63Dfyr.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": null,
+ "file_path": "/82rldpJVwOfauJDpKaVo3uUnPuZ.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "vi",
+ "file_path": "/ewi0rJKHG87TDJMrcQA1cQZT4CW.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "ar",
+ "file_path": "/rDeu1T2bbUz068zhBpIezFVnpbH.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1875,
+ "iso_639_1": "en",
+ "file_path": "/xCrYLx56jCGEIpv9g6BbDW5nAJN.jpg",
+ "vote_average": 0,
+ "vote_count": 1,
+ "width": 1250
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/6jkwCXHckbQTVrFJ81UfiVt5T9d.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.763,
+ "height": 2097,
+ "iso_639_1": "ar",
+ "file_path": "/6hIfprzHYeITeYEHwYR5K6FE9jA.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1601
+ }
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-278.json b/providers/.cache/tmdb_api/tmdb-movie-278.json
new file mode 100644
index 0000000..287c4d7
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-278.json
@@ -0,0 +1,57 @@
+{
+ "adult": false,
+ "backdrop_path": "/pNjh59JSxChQktamG3LMp9ZoQzp.jpg",
+ "belongs_to_collection": null,
+ "budget": 25000000,
+ "genres": [
+ {
+ "id": 18,
+ "name": "Drama"
+ },
+ {
+ "id": 80,
+ "name": "Crime"
+ }
+ ],
+ "homepage": "",
+ "id": 278,
+ "imdb_id": "tt0111161",
+ "origin_country": [
+ "US"
+ ],
+ "original_language": "en",
+ "original_title": "The Shawshank Redemption",
+ "overview": "Imprisoned in the 1940s for the double murder of his wife and her lover, upstanding banker Andy Dufresne begins a new life at the Shawshank prison, where he puts his accounting skills to work for an amoral warden. During his long stretch in prison, Dufresne comes to be admired by the other inmates -- including an older prisoner named Red -- for his integrity and unquenchable sense of hope.",
+ "popularity": 31.7568,
+ "poster_path": "/9cqNxx0GxF0bflZmeSMuL5tnGzr.jpg",
+ "production_companies": [
+ {
+ "id": 97,
+ "logo_path": "/qv3ih9pR9w2XNKZDsqDqAGuZjqc.png",
+ "name": "Castle Rock Entertainment",
+ "origin_country": "US"
+ }
+ ],
+ "production_countries": [
+ {
+ "iso_3166_1": "US",
+ "name": "United States of America"
+ }
+ ],
+ "release_date": "1994-09-23",
+ "revenue": 28341469,
+ "runtime": 142,
+ "spoken_languages": [
+ {
+ "english_name": "English",
+ "iso_639_1": "en",
+ "name": "English"
+ }
+ ],
+ "status": "Released",
+ "tagline": "Fear can hold you prisoner. Hope can set you free.",
+ "title": "The Shawshank Redemption",
+ "video": false,
+ "vote_average": 8.7,
+ "vote_count": 28866
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-293660-alternatives.json b/providers/.cache/tmdb_api/tmdb-movie-293660-alternatives.json
new file mode 100644
index 0000000..bc4d384
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-293660-alternatives.json
@@ -0,0 +1,25 @@
+{
+ "id": 293660,
+ "titles": [
+ {
+ "iso_3166_1": "VN",
+ "title": "Quái Nhân Deadpool",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "CN",
+ "title": "死侍1",
+ "type": ""
+ },
+ {
+ "iso_3166_1": "ES",
+ "title": "Deadpool: 1",
+ "type": "Castellano"
+ },
+ {
+ "iso_3166_1": "DE",
+ "title": "Deadpool 1",
+ "type": ""
+ }
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-293660-external_ids.json b/providers/.cache/tmdb_api/tmdb-movie-293660-external_ids.json
new file mode 100644
index 0000000..1b4befa
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-293660-external_ids.json
@@ -0,0 +1,8 @@
+{
+ "id": 293660,
+ "imdb_id": "tt1431045",
+ "wikidata_id": "Q19347291",
+ "facebook_id": "DeadpoolMovie",
+ "instagram_id": "deadpoolmovie",
+ "twitter_id": "deadpoolmovie"
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-293660-images.json b/providers/.cache/tmdb_api/tmdb-movie-293660-images.json
new file mode 100644
index 0000000..dbfa565
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-293660-images.json
@@ -0,0 +1,2160 @@
+{
+ "backdrops": [
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/en971MEXui9diirXlogOrPKmsEn.jpg",
+ "vote_average": 7.032,
+ "vote_count": 16,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/rFj9IKlL75B2pXhZA60jkNWvxeW.jpg",
+ "vote_average": 6.312,
+ "vote_count": 8,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/k2VX0gFu2BEJhvduQTq2ioYp8z7.jpg",
+ "vote_average": 6.312,
+ "vote_count": 8,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/n28I7FNYIT934OoHhKZn4IIDsrQ.jpg",
+ "vote_average": 4.3,
+ "vote_count": 10,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.776,
+ "height": 964,
+ "iso_639_1": "en",
+ "file_path": "/fY23D9UbnkYvy9HZtF7XliTysp6.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1712
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 802,
+ "iso_639_1": null,
+ "file_path": "/rw3z3ZuTCxhhHCztfR4eqEqRpGV.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1426
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "ko",
+ "file_path": "/plwgBvI54nmBREDn7vdMzU1OP0u.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1694,
+ "iso_639_1": "en",
+ "file_path": "/75375iF3MfdSIRsh00iI5JKPTbR.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 3012
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/MJvUuCAgurK1JgXUJvGrDa37Ke.jpg",
+ "vote_average": 1.75,
+ "vote_count": 6,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/9zWEKQwaefQ5QIC8QfbbZD2aYCl.jpg",
+ "vote_average": 1.75,
+ "vote_count": 4,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/jNUYL4RroNF1KRGilpVqCSujWSf.jpg",
+ "vote_average": 1.75,
+ "vote_count": 6,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "en",
+ "file_path": "/38B4MIYNyWpehNBQ9pc22OQjsZ7.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1686,
+ "iso_639_1": null,
+ "file_path": "/wsPO5Jny82b0pksjSvjUHEYHDkz.jpg",
+ "vote_average": 1.562,
+ "vote_count": 8,
+ "width": 2998
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/z09QxlvUXAyQfZbgggjcL2w04QU.jpg",
+ "vote_average": 1.444,
+ "vote_count": 6,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/zZvBe8xGX2gPlWURJfRNwF40rF3.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/n4GiahbsK9qZe8JC5v6kPFENXlH.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/uXsE8WOKB55GxLMfvMxmNVq6yMk.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": null,
+ "file_path": "/hxNxbBuuWD7kw06g9g6jge9N7JZ.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/1aWpHzY3Y4bODkhQkSARTYLbXW.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/9aIeqazwPiIQ1ClfxhwhCQ0IGzA.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/bUcmY4GuJRIwQbZ8mYy1lWWDfNI.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": "en",
+ "file_path": "/zBgz8ZQveXkRRysFnZaYi0fD6QM.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 720,
+ "iso_639_1": null,
+ "file_path": "/mooabI47OLF0sZi6wsw7KmnF0AM.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1280
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1125,
+ "iso_639_1": null,
+ "file_path": "/yzrGHCY0iRwdTXJpn1iUFiFYKxH.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/v8P8WLP6R7HDHUUykHJvfFkJrzz.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/lcCaABDOzD8v3ZSIudT5msnrkQ7.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/bcwEXWvGCUF3DCXSyLypZkqgXxu.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/2c3NYVUbRvYQeHgaR4HqKBD5csc.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/igmvRtYSm6viwEFFKfna6ckGHRt.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.777,
+ "height": 1688,
+ "iso_639_1": "ko",
+ "file_path": "/bJ63tGI6ou0f9s7aTj0Qu5SOQJn.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3000
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/iov1XbPUAKRgoTAlfVbhorSbIj2.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": "en",
+ "file_path": "/qEKTokfD3n6ueo24GTiU9sg1EiA.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "ka",
+ "file_path": "/bUpnpwCTNHCT7aZHZIKn6NGUFUW.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "pt",
+ "file_path": "/lL5Jn3cjWw7vTBVleU4o212AcqA.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1075,
+ "iso_639_1": null,
+ "file_path": "/8HzC4v2roWDJKg5YK58jFhUsUUk.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1911
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/bUILTt7RtX6YFtIjpqI1oaZm4Bh.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/wLpLv0PzcvsbJOrw5Ocifn6JuiQ.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/hvZlJkVdVhop1z5eedtzQpaVaaS.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.781,
+ "height": 2156,
+ "iso_639_1": "en",
+ "file_path": "/cMp6bAeTxnsihEhGWkuSgbYo8Qy.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 2160,
+ "iso_639_1": null,
+ "file_path": "/wajlGQsw35aBPnWLthQlYChxkTF.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": null,
+ "file_path": "/h0zqhGfbN6gad3DCosyIAMijUTQ.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ },
+ {
+ "aspect_ratio": 1.778,
+ "height": 1080,
+ "iso_639_1": "ja",
+ "file_path": "/36PThNOylBPqDxQ8C5MVIvqxaAT.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1920
+ }
+ ],
+ "id": 293660,
+ "logos": [
+ {
+ "aspect_ratio": 4.081,
+ "height": 941,
+ "iso_639_1": "he",
+ "file_path": "/v5jX2Q6DBmnbvdOqH82DK4kY1s6.png",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.934,
+ "height": 548,
+ "iso_639_1": "zh",
+ "file_path": "/CrzYEy5x4Uy4OibvlAEYzKaLwF.png",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1060
+ },
+ {
+ "aspect_ratio": 1.378,
+ "height": 2160,
+ "iso_639_1": "zh",
+ "file_path": "/eIJpn5Gf6FjsgMFHe5HVCbNAxLo.png",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2976
+ },
+ {
+ "aspect_ratio": 5.187,
+ "height": 539,
+ "iso_639_1": "fr",
+ "file_path": "/piuamNKC09lepRcjrWx9GfEa8hN.png",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2796
+ },
+ {
+ "aspect_ratio": 4.324,
+ "height": 185,
+ "iso_639_1": "uk",
+ "file_path": "/wdltMg9Y1PceKmqizoEpGRCe6cN.png",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 800
+ },
+ {
+ "aspect_ratio": 5.447,
+ "height": 389,
+ "iso_639_1": "en",
+ "file_path": "/zXyTWeQemn7yfvHLrEWWENkJzmT.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2119
+ },
+ {
+ "aspect_ratio": 4.384,
+ "height": 365,
+ "iso_639_1": "en",
+ "file_path": "/2RCCAVpLr3VtAVARpTjdONPmox2.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1600
+ },
+ {
+ "aspect_ratio": 7.31,
+ "height": 197,
+ "iso_639_1": "ja",
+ "file_path": "/tCw08ALwb7A0B3AxU0hd5hrXUaU.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1440
+ },
+ {
+ "aspect_ratio": 3.16,
+ "height": 243,
+ "iso_639_1": "he",
+ "file_path": "/jfx8C00ZsWBGh8AFKLEsmxqTV30.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 768
+ },
+ {
+ "aspect_ratio": 4.364,
+ "height": 330,
+ "iso_639_1": "ko",
+ "file_path": "/x8MA3ybDOJjP5AW4bFhi0YbN8oT.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1440
+ },
+ {
+ "aspect_ratio": 4.426,
+ "height": 244,
+ "iso_639_1": "ru",
+ "file_path": "/r9du1OkNiEt7NRClK5sISgBjycB.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1080
+ },
+ {
+ "aspect_ratio": 4.411,
+ "height": 394,
+ "iso_639_1": "uk",
+ "file_path": "/4gHcaEXFKBLVbAfbht0RdprajSn.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1738
+ },
+ {
+ "aspect_ratio": 2.082,
+ "height": 1844,
+ "iso_639_1": "zh",
+ "file_path": "/bhHtI0ve1cfyJgt07wtb92w94yI.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 3840
+ },
+ {
+ "aspect_ratio": 1.187,
+ "height": 1452,
+ "iso_639_1": "zh",
+ "file_path": "/9YIMKxR0tl65JPcGMkiVGehvzps.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1723
+ },
+ {
+ "aspect_ratio": 4.163,
+ "height": 509,
+ "iso_639_1": "en",
+ "file_path": "/kH1MbmJnLgIajwGfYzFwT0vLaPl.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2119
+ },
+ {
+ "aspect_ratio": 5.677,
+ "height": 811,
+ "iso_639_1": "en",
+ "file_path": "/cAN2qahGgyH3agmzLPlGAgAQmkA.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 4604
+ },
+ {
+ "aspect_ratio": 5.68,
+ "height": 122,
+ "iso_639_1": "en",
+ "file_path": "/aNYT6NNSOhJ71dcSAxZMMawrCrU.svg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 693
+ },
+ {
+ "aspect_ratio": 1.613,
+ "height": 287,
+ "iso_639_1": "zh",
+ "file_path": "/tfoKUkwu1ySY4Z3kyP15F71TfXq.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 463
+ },
+ {
+ "aspect_ratio": 3.931,
+ "height": 1099,
+ "iso_639_1": "ko",
+ "file_path": "/yePQm7R4Pj5SWse6JVAK34YVrIJ.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 4320
+ },
+ {
+ "aspect_ratio": 4.385,
+ "height": 985,
+ "iso_639_1": "ko",
+ "file_path": "/eqzLui5lsAOjRpP2n8sOiyMmRhD.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 4319
+ },
+ {
+ "aspect_ratio": 1.239,
+ "height": 1920,
+ "iso_639_1": "zh",
+ "file_path": "/m6kbAP34JF6DxjYIz2UNaW65onD.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2378
+ },
+ {
+ "aspect_ratio": 4.411,
+ "height": 394,
+ "iso_639_1": "uk",
+ "file_path": "/wmyfuT3507C16IX3UBbAQTUiaTD.png",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1738
+ }
+ ],
+ "posters": [
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fr",
+ "file_path": "/z5VjcCEioj2c2dvxmoqBW0Rj8Xj.jpg",
+ "vote_average": 6.722,
+ "vote_count": 6,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/3E53WEZJqP6aM84D8CckXx4pIHw.jpg",
+ "vote_average": 6.712,
+ "vote_count": 26,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/fSRb7vyIP8rQpL0I47P3qUsEKX3.jpg",
+ "vote_average": 5.808,
+ "vote_count": 34,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/zq8Cl3PNIDGU3iWNRoc5nEZ6pCe.jpg",
+ "vote_average": 5.726,
+ "vote_count": 20,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/pcZT1Ouq99dY6J2iGXjMxw16x6o.jpg",
+ "vote_average": 5.682,
+ "vote_count": 11,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/yGSxMiF0cYuAiyuve5DA6bnWEOI.jpg",
+ "vote_average": 5.53,
+ "vote_count": 17,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.673,
+ "height": 1127,
+ "iso_639_1": "en",
+ "file_path": "/8peYuPeLawgCFhuI4IcDjdrAAXw.jpg",
+ "vote_average": 5.25,
+ "vote_count": 9,
+ "width": 759
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2048,
+ "iso_639_1": "zh",
+ "file_path": "/wWzGAWmdX7IL1mOYyhiYKso0FrI.jpg",
+ "vote_average": 3.334,
+ "vote_count": 2,
+ "width": 1365
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "th",
+ "file_path": "/3Oft5fKQr1KHUhzqbfLrw9MDhwD.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2048,
+ "iso_639_1": "zh",
+ "file_path": "/qPJC6cNMkHLJhcD52jKHh56Fzxa.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1365
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2048,
+ "iso_639_1": "zh",
+ "file_path": "/uoEvIHCpli8qfMHnFRG6QxJA4tm.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1365
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2048,
+ "iso_639_1": "zh",
+ "file_path": "/ts2v8Lho9LJYqvKK7z0FGQ1cLLU.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1365
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2500,
+ "iso_639_1": "en",
+ "file_path": "/jTl9Xnhbvzmf5QRwzsUAfdcWrRT.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1667
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "de",
+ "file_path": "/VEfCqkbK062Egob26rYQWAJoE7.jpg",
+ "vote_average": 3.334,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.736,
+ "height": 2074,
+ "iso_639_1": "sk",
+ "file_path": "/kFOwg5obNkQN6KlsLHjKUeppEZZ.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1526
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "he",
+ "file_path": "/fJk1kspZ1Xo3R8sl7NhFziXudqt.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.676,
+ "height": 1837,
+ "iso_639_1": "en",
+ "file_path": "/pXBNcuhAZZ84yStZtD8b7T62q8W.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1242
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "ka",
+ "file_path": "/yJiFPlmEcvkawa3oArVy933i8rD.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/vb9etggDUhIfz8YU2hJD45MN7O4.jpg",
+ "vote_average": 3.334,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/mY37sVR85vtdwo2d0W98SCKHNx5.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/eOCjxsaxpoIZcucQ2ucP95JEJUO.jpg",
+ "vote_average": 3.334,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/uSDLpH0E1jOj3axjqhTucNrliLN.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2100,
+ "iso_639_1": "tr",
+ "file_path": "/99p0n6EhX6PebGIScQ0uRZ8aUv8.jpg",
+ "vote_average": 3.334,
+ "vote_count": 2,
+ "width": 1400
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/7BYksRLQ9HtZbUtanhAIdeQO9eD.jpg",
+ "vote_average": 3.334,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "ru",
+ "file_path": "/r5PYZGOiIQuGpaZas9TTplNZ5Ox.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ko",
+ "file_path": "/k1e0TlvDM4KsiSRyJENVrHxMqtK.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "it",
+ "file_path": "/zoSiiUUzg2ny6uzuil7PbP13z53.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2306,
+ "iso_639_1": "fr",
+ "file_path": "/AmTA3OrvsbjC4ejzFfKbzqm0Fs0.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 1537
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ja",
+ "file_path": "/zhqrRtBVHAbHqLl9O5dMYAHeyFH.jpg",
+ "vote_average": 3.334,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.705,
+ "height": 2179,
+ "iso_639_1": "fr",
+ "file_path": "/z4Fk3B8pWqZx8hF5hbf9WgBKREb.jpg",
+ "vote_average": 2.542,
+ "vote_count": 4,
+ "width": 1537
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/v7dXwm78BHkdlDzwT3u4fywgz1b.jpg",
+ "vote_average": 2.542,
+ "vote_count": 4,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.717,
+ "height": 2788,
+ "iso_639_1": null,
+ "file_path": "/gBYgQQe5mmh8fIQTWRht8gzJV8G.jpg",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": null,
+ "file_path": "/xu1lMNQr4rM0VQCWBkYXJmenj4U.jpg",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/wg3MLoL0wEtY2r2pbtdK5aF6e6F.jpg",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "uk",
+ "file_path": "/uNgSXu6iveo9WQABOhFb72QH0qr.jpg",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": null,
+ "file_path": "/kxNMigoaWF1keHTC3KtYBjZr5iX.jpg",
+ "vote_average": 2.278,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2104,
+ "iso_639_1": "uk",
+ "file_path": "/mErMIq92XNC3eWH4pYw7dKLezJ7.jpg",
+ "vote_average": 2.066,
+ "vote_count": 5,
+ "width": 1403
+ },
+ {
+ "aspect_ratio": 0.675,
+ "height": 2500,
+ "iso_639_1": "en",
+ "file_path": "/s2vj1zwydrQkwuz0711XBAEHdw4.jpg",
+ "vote_average": 2.066,
+ "vote_count": 5,
+ "width": 1688
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/2drDLdrmgq5zvxvWzAYhzv2pH0c.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "ru",
+ "file_path": "/7vEAHaoSXU5evsHMTETUFRVW3QW.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/geBTv3ktyaPnleK0r9jWN6GqiNT.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.675,
+ "height": 1600,
+ "iso_639_1": "en",
+ "file_path": "/jXQrgDkWcZogGAf2jWNRjf9Cmhv.jpg",
+ "vote_average": 1.75,
+ "vote_count": 4,
+ "width": 1080
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "he",
+ "file_path": "/rfekMukNPQsKuXjXc561OezRSD6.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "he",
+ "file_path": "/nnEfdPrwaxKuZNjTKvQFAjbs8HF.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "he",
+ "file_path": "/nvM5H4dAPcCU1PqqK2OBK6C3l8i.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/swS3PsQYD3wGEWZwtgpUlGRMv1G.jpg",
+ "vote_average": 1.75,
+ "vote_count": 4,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/7P21qxw0GhXCWGznJWb1RkCNTtc.jpg",
+ "vote_average": 1.75,
+ "vote_count": 4,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.7,
+ "height": 2858,
+ "iso_639_1": "ko",
+ "file_path": "/nzGvrSKrjOjdG1ojrVOf0v7ApkW.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "fr",
+ "file_path": "/4D6VH2i8AqdUK9mY2rgmcrYUaMO.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ko",
+ "file_path": "/bzpAD4rd40zZYoh6Lqzrz1O1xh4.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 900,
+ "iso_639_1": "ru",
+ "file_path": "/tMOhkuXYfVtJ4ZxNFsG9QbLS7yh.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 600
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": "ru",
+ "file_path": "/jhLx7UQ2LOYjzUF1oH1ne4HZWhL.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "zh",
+ "file_path": "/lGItu9eqKT91kRGbaSsHUSEi2jV.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/p5VMWZOEOzAKaV3xhebztRUgcuJ.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/wEGU0e47rmMdzdulkXirAIbCeXM.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.706,
+ "height": 2834,
+ "iso_639_1": "it",
+ "file_path": "/mdBGRd6OE9loKEQC8qAGm51qHya.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/3Wm440ayXLPVdRX56u9uuf7YAfd.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/xjZ8uAQ0QFKz8xrKFsQhB3RAchy.jpg",
+ "vote_average": 1.75,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/d2V5MyJxPM1GX7XcCNrTFHhYe3T.jpg",
+ "vote_average": 1.714,
+ "vote_count": 7,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.673,
+ "height": 1426,
+ "iso_639_1": "en",
+ "file_path": "/bm79nfBJb8ElpteFtnCMaKxdeV6.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 960
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/fOdFkicoeApMQMvxeVQsKZxexiV.jpg",
+ "vote_average": 1.434,
+ "vote_count": 5,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.702,
+ "height": 784,
+ "iso_639_1": "en",
+ "file_path": "/yVlGKF8J5Dd6xN7VigphGjlsyYG.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 550
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/gmYSK6mzEbeK4fEVvi8a7btzuNH.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/20bo8p996kwCQGVxMQxi0TTnfPe.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/bb5PrmnQrsMS35s4OUYPDLuiJbK.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.696,
+ "height": 1171,
+ "iso_639_1": "tr",
+ "file_path": "/nMKpconh6JTJ86eCQoGOH6ypDMN.jpg",
+ "vote_average": 1.222,
+ "vote_count": 3,
+ "width": 815
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/5vtbOGLhlYvr0G3ZjjZNxuSCZUe.jpg",
+ "vote_average": 0.958,
+ "vote_count": 4,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.708,
+ "height": 1696,
+ "iso_639_1": "ja",
+ "file_path": "/gHP7eDdmTPoipbNEbb9GqZXFbBW.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1200
+ },
+ {
+ "aspect_ratio": 0.676,
+ "height": 888,
+ "iso_639_1": "th",
+ "file_path": "/15RL0ZcKDdVzXRMDQD29lQWWyQ9.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 600
+ },
+ {
+ "aspect_ratio": 0.676,
+ "height": 1024,
+ "iso_639_1": "th",
+ "file_path": "/eelT9lXdxTbsEVJSKncqb6zwqUb.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 692
+ },
+ {
+ "aspect_ratio": 0.676,
+ "height": 814,
+ "iso_639_1": "th",
+ "file_path": "/qTRBbmHGbaShM8Vm2W95vXsae8b.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 550
+ },
+ {
+ "aspect_ratio": 0.652,
+ "height": 830,
+ "iso_639_1": "th",
+ "file_path": "/bmOfSrMAQcGbxO2FAPsOJEY9RCa.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 541
+ },
+ {
+ "aspect_ratio": 0.675,
+ "height": 2048,
+ "iso_639_1": "es",
+ "file_path": "/3TUYy0XvhPQBhrXJwRIaOoYFOBO.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1382
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 750,
+ "iso_639_1": "vi",
+ "file_path": "/cFi3j0Njdoe4Ty8xiqw3BKMnzRv.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 500
+ },
+ {
+ "aspect_ratio": 0.705,
+ "height": 2268,
+ "iso_639_1": "de",
+ "file_path": "/tdVPICyJLENwgmZHr8RsOgeWoyP.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fr",
+ "file_path": "/1YnUQABC6N7iu5c1G5jrUI7ZEbn.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "uk",
+ "file_path": "/78wOYwhjTj6edpen9YyBkBbIAmU.jpg",
+ "vote_average": 0.166,
+ "vote_count": 2,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.68,
+ "height": 1000,
+ "iso_639_1": null,
+ "file_path": "/hQWarU3816t1coKbULEIVFi2IH4.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 680
+ },
+ {
+ "aspect_ratio": 0.75,
+ "height": 1280,
+ "iso_639_1": "es",
+ "file_path": "/jTl6caQE4JOCJCl6ixaxQOTMKhZ.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 960
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": null,
+ "file_path": "/wCssZpoguaHACgkfVTT9vRwxukt.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/yVzqwBlzemXyR4u3jNpfCKImIRP.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.705,
+ "height": 2179,
+ "iso_639_1": "fr",
+ "file_path": "/wo7OlJV82uYSsht6Jt9eopQ7zmk.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1537
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "fr",
+ "file_path": "/195eLmtwDwe2t4RCPdAA8iEsltJ.jpg",
+ "vote_average": 0.166,
+ "vote_count": 1,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "he",
+ "file_path": "/8DB9m0ZUv4SUVqHD14pSgI802On.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "he",
+ "file_path": "/hhhBAcLfORujfe3gtz3lyF4QNEk.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.697,
+ "height": 2013,
+ "iso_639_1": "en",
+ "file_path": "/A9zSqJhTgJtzUgJJdupAIY4SsNs.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1403
+ },
+ {
+ "aspect_ratio": 0.619,
+ "height": 1256,
+ "iso_639_1": "bg",
+ "file_path": "/zVCFs9rtXRMvp88U7iFpttsPYph.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 777
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/lwWWsP4ffhKV9tM0otqkfqVPCAY.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 1501,
+ "iso_639_1": "bg",
+ "file_path": "/6dimiL4vAuGk4W3Z2yVUEf5tTA3.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.7,
+ "height": 2858,
+ "iso_639_1": "ko",
+ "file_path": "/lljWMCR3CZcMv75gII3Q2FsLLN3.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "nl",
+ "file_path": "/jnaahY4s4ThMpCzBE6u0ZXAN8Xy.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/wYmtZIZZRa56UV2Lurei6w8PjSB.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/5ztk65r3yHCBjuxDcmgHO3eIGR4.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": null,
+ "file_path": "/pjibhQczMPNbsLVsacWFaLAuDzv.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/kf3Xch3cLrltqhfFtBIbfPN4vRx.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.7,
+ "height": 2858,
+ "iso_639_1": "ko",
+ "file_path": "/pTcC9h62CLSPeT9JeZlJjXi2CrW.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1684,
+ "iso_639_1": "ko",
+ "file_path": "/aRqyldHBnkmaDiYDPleG7OSbXFu.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1181
+ },
+ {
+ "aspect_ratio": 0.696,
+ "height": 1696,
+ "iso_639_1": "ko",
+ "file_path": "/b2Gmv0e0wDiX4p2eQCNVCshfWIK.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1181
+ },
+ {
+ "aspect_ratio": 0.752,
+ "height": 1920,
+ "iso_639_1": "ko",
+ "file_path": "/40yIWj0tVVzAYi4l868yuMhY0QC.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1443
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1853,
+ "iso_639_1": "ko",
+ "file_path": "/kA7lGourGeXPTgjFh2UFq92bugT.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1299
+ },
+ {
+ "aspect_ratio": 0.75,
+ "height": 800,
+ "iso_639_1": null,
+ "file_path": "/5Q94jybSKWDL8CKM58a64xY7Dkn.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 600
+ },
+ {
+ "aspect_ratio": 0.71,
+ "height": 2818,
+ "iso_639_1": "en",
+ "file_path": "/a8BDmomxRtrD8MvmPz8ndMOWIgQ.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "it",
+ "file_path": "/2ChHrqM2MIDCS7adxRMvlqTvyxG.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/4dnjgufBAn6nKXGOqWKJtnHRY3E.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/cq7JSVCjyFX3TMRHYsYYPlTG24G.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2000,
+ "iso_639_1": "zh",
+ "file_path": "/aCZZLdK53CjbHkpwS8dthkZRIR9.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1335
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/aTlB4atQ8uPuMZfAGkcuZ8kPM6h.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "vi",
+ "file_path": "/kln2eqvULB8Y8a3tWYVVyX8Pjfr.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "vi",
+ "file_path": "/rNi0qDp2eOHH704GlzACYz2WH92.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "vi",
+ "file_path": "/ckKXQaEqjiC8CCWeiwSjUu4xzlw.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ka",
+ "file_path": "/3TzdBavRzxFYJCdQgAETQEHjbh9.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "de",
+ "file_path": "/5QudcynlZEgXKjaEAgImFIfjGHO.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.708,
+ "height": 1074,
+ "iso_639_1": "en",
+ "file_path": "/pRAJhu4Ez7BwuUhBK0TiHDrirm8.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 760
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/eU9rwsDCkyaU8SEtJ3ZhTQSwmUA.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.676,
+ "height": 1480,
+ "iso_639_1": "th",
+ "file_path": "/5Ih4CMvlL0TUQveXgyCKL5IBj3P.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.669,
+ "height": 1237,
+ "iso_639_1": "en",
+ "file_path": "/6FMa9V6WPFUMvKGafAFRqkhiZSd.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 828
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/trR9niPKWoY7h8KeMEV8nbtEHA6.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.672,
+ "height": 2197,
+ "iso_639_1": "ro",
+ "file_path": "/oceifJ5EG8nQ3Qt5yPwkfsgdW3y.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1476
+ },
+ {
+ "aspect_ratio": 0.697,
+ "height": 2013,
+ "iso_639_1": null,
+ "file_path": "/rVCOxsUvh9tsnn3TkQwGKIDrQFQ.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1403
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/yt2RYW5dCyviUu5LPcaptqCTWZa.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/bWKWGQzwGAsb1MMkOQEwfDNx2Kf.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2475,
+ "iso_639_1": "en",
+ "file_path": "/12WI1GPKG1flidifterg7CN1Mgr.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1650
+ },
+ {
+ "aspect_ratio": 0.675,
+ "height": 1080,
+ "iso_639_1": "sk",
+ "file_path": "/iFD7sEyj7ePmFEwcgFPw668ymLh.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 729
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1200,
+ "iso_639_1": "en",
+ "file_path": "/6hevaOt3X4dBXoPPj5QRLJETvxm.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 800
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/dmbytACR7x0DwMHI1Wz0MyVBNb3.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.7,
+ "height": 2048,
+ "iso_639_1": "lt",
+ "file_path": "/kIIqkdmBYS6Bjl79kIg5IgEzLc8.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1433
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/6sCHhfS58jYtWFSNDsZ0K7QKAZd.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1200,
+ "iso_639_1": "en",
+ "file_path": "/1A3EJHkBGSzMbYpFLOquC7NHpqZ.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 800
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/n5C3jAenNXTYZj8rx2jMb0g0e7j.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": null,
+ "file_path": "/lOQxPHzDlhVIU7stIzVjI0AuwPP.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.701,
+ "height": 1426,
+ "iso_639_1": null,
+ "file_path": "/nL3vovQSch7X2Oqa6mnWrlzpU7N.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "es",
+ "file_path": "/jAeZL0CH8kXSDmIryA7eYB761XN.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "ar",
+ "file_path": "/sxSvb0bb5MonuwiT21gxTcrrOL0.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 1223,
+ "iso_639_1": "en",
+ "file_path": "/qB0XdQzwRnIzky1Sf1qNfup0mhq.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 815
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2127,
+ "iso_639_1": "zh",
+ "file_path": "/hlGgOYQ4hsyeFY39wGtqKXbHSj2.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1418
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1517,
+ "iso_639_1": "en",
+ "file_path": "/o5wicO0TFjMforWRJ6KM9VykTvW.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1012
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 1530,
+ "iso_639_1": "en",
+ "file_path": "/irzVTGFkqyth4SY3ABsF2egJr84.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1019
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2100,
+ "iso_639_1": "en",
+ "file_path": "/4lR8GVy3Vtbsien85AQ55epf8PR.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1400
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/cKHrwILTLsAZATjam6OrKQetXMj.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/6wztazU7lnVGGYqD2U41jSgyPuA.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/t8OvWQpIuCwfdLU08fKJtbmvKRI.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/ufdjnYVRBUTvNQXtUt1acpRmutZ.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 2500,
+ "iso_639_1": "en",
+ "file_path": "/bsYM7uynOe3wPcQk4WF9xW0Kw1A.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1666
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 2818,
+ "iso_639_1": "en",
+ "file_path": "/ybTSFM2LMnsKQeqhgx4YgicIxjv.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1878
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2116,
+ "iso_639_1": "en",
+ "file_path": "/hJYoTgZislq4zB3us582Axh7pcR.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1411
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/kbNihG5y1do7vEcwU5NUsbAYSuL.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1000,
+ "iso_639_1": null,
+ "file_path": "/ux0ilYGw6sCLclwkKY6tezBtyQd.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 667
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1800,
+ "iso_639_1": "zh",
+ "file_path": "/uDvCPT8f3qwbK07ebrii65pXX3i.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1200
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 857,
+ "iso_639_1": "mk",
+ "file_path": "/vHhyYc2kwXfVxMWVTjvaox38z4D.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 571
+ },
+ {
+ "aspect_ratio": 0.7,
+ "height": 2100,
+ "iso_639_1": "es",
+ "file_path": "/w9AyORnXXqDY6aKRHEf4vw57WJx.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1470
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2250,
+ "iso_639_1": "ru",
+ "file_path": "/9VlabWiOurYYPjBG70W8jgfikd.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.666,
+ "height": 1000,
+ "iso_639_1": null,
+ "file_path": "/kthJ0NvBQZpPh9FIQGxP5KGfgTz.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 666
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1104,
+ "iso_639_1": "en",
+ "file_path": "/94OEkQH44vddh7K4aKXlDxeitUT.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 736
+ },
+ {
+ "aspect_ratio": 0.703,
+ "height": 1000,
+ "iso_639_1": "ru",
+ "file_path": "/sMmGMIllJVlk6JHNBIGaeH4d6LD.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 703
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "es",
+ "file_path": "/ruWXzVrEsfZ2oyWN9PDTN9nlczW.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.657,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/bbkyshoUIviywEkPvIdLX89MdPr.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1970
+ },
+ {
+ "aspect_ratio": 0.681,
+ "height": 1200,
+ "iso_639_1": "pt",
+ "file_path": "/9it1qyyxxSW7TFKnKF7orVF9BpT.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 817
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/eaTi0cLpMVSp8Ibg66IjdBTpnJh.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 2100,
+ "iso_639_1": "en",
+ "file_path": "/o8yeqbSBcXvRTMHDzwSz0jD41Bb.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1400
+ },
+ {
+ "aspect_ratio": 0.682,
+ "height": 1800,
+ "iso_639_1": "fa",
+ "file_path": "/3Xf0zrWSK5SbLD2nLiSqh1atlSz.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1228
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "zh",
+ "file_path": "/w1JqStudDoV9vU8azgfa9OIARtQ.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1620,
+ "iso_639_1": "ru",
+ "file_path": "/gjeZHVlbKaxE0H9Bjr0uTfTOt3D.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1080
+ },
+ {
+ "aspect_ratio": 0.704,
+ "height": 2130,
+ "iso_639_1": "ru",
+ "file_path": "/kAo21ZXNF5RWTJvBtujUDk6vD12.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.704,
+ "height": 2130,
+ "iso_639_1": "ru",
+ "file_path": "/ydaQcGupYNKB0Vuq0JMIcG1wtnC.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.704,
+ "height": 2130,
+ "iso_639_1": "ru",
+ "file_path": "/bLzW69ZmQZa5UrsiDGBH152apC2.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.704,
+ "height": 2130,
+ "iso_639_1": "ru",
+ "file_path": "/m09N1pa9aZ8TUVDro3GNnSYh7y.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.704,
+ "height": 2132,
+ "iso_639_1": "ru",
+ "file_path": "/hLe9dR5v1u60Ufb0GxtREuQfvtH.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1500
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1080,
+ "iso_639_1": "ru",
+ "file_path": "/2CPzyakbWjJB4i2gjcaS8P6Uy93.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 720
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/lNPDz5MA1217bJwViGO4K08fNaG.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 900,
+ "iso_639_1": "en",
+ "file_path": "/iZSsNFqxxh3Ix8OkF0iy3Tyjcx5.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 600
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "cs",
+ "file_path": "/2VFhMD3UOG7kPVVkdv5bCzLjQe5.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 994,
+ "iso_639_1": "cs",
+ "file_path": "/GJoITmzUMmvRQNGql3nz4AZDLG.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 663
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 1500,
+ "iso_639_1": "en",
+ "file_path": "/oNTRPmXSEsi1upDdVjCzZ76DmGq.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 1000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "en",
+ "file_path": "/fWZ21zxg8ItiMMWDqdTOe8UsTuY.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ },
+ {
+ "aspect_ratio": 0.667,
+ "height": 3000,
+ "iso_639_1": "uk",
+ "file_path": "/riod9l8JPmHq6J08BVS1USMAHZ6.jpg",
+ "vote_average": 0,
+ "vote_count": 0,
+ "width": 2000
+ }
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_api/tmdb-movie-293660.json b/providers/.cache/tmdb_api/tmdb-movie-293660.json
new file mode 100644
index 0000000..bcee82d
--- /dev/null
+++ b/providers/.cache/tmdb_api/tmdb-movie-293660.json
@@ -0,0 +1,84 @@
+{
+ "adult": false,
+ "backdrop_path": "/en971MEXui9diirXlogOrPKmsEn.jpg",
+ "belongs_to_collection": {
+ "id": 448150,
+ "name": "Deadpool Collection",
+ "poster_path": "/30c5jO7YEXuF8KiWXLg9m28GWDA.jpg",
+ "backdrop_path": "/dTq7mGyAR5eAydR532feWfjJjzm.jpg"
+ },
+ "budget": 58000000,
+ "genres": [
+ {
+ "id": 28,
+ "name": "Action"
+ },
+ {
+ "id": 12,
+ "name": "Adventure"
+ },
+ {
+ "id": 35,
+ "name": "Comedy"
+ }
+ ],
+ "homepage": "https://www.20thcenturystudios.com/movies/deadpool",
+ "id": 293660,
+ "imdb_id": "tt1431045",
+ "origin_country": [
+ "US"
+ ],
+ "original_language": "en",
+ "original_title": "Deadpool",
+ "overview": "The origin story of former Special Forces operative turned mercenary Wade Wilson, who, after being subjected to a rogue experiment that leaves him with accelerated healing powers, adopts the alter ego Deadpool. Armed with his new abilities and a dark, twisted sense of humor, Deadpool hunts down the man who nearly destroyed his life.",
+ "popularity": 15.1616,
+ "poster_path": "/3E53WEZJqP6aM84D8CckXx4pIHw.jpg",
+ "production_companies": [
+ {
+ "id": 25,
+ "logo_path": "/qZCc1lty5FzX30aOCVRBLzaVmcp.png",
+ "name": "20th Century Fox",
+ "origin_country": "US"
+ },
+ {
+ "id": 431,
+ "logo_path": "/6dcR1MbRqYgt3jUVYxkHe68GFnZ.png",
+ "name": "The Donners' Company",
+ "origin_country": "US"
+ },
+ {
+ "id": 28788,
+ "logo_path": "/Aqomtf9oh5dKtxBNEagkdlp3aGv.png",
+ "name": "Genre Films",
+ "origin_country": "US"
+ },
+ {
+ "id": 7505,
+ "logo_path": "/837VMM4wOkODc1idNxGT0KQJlej.png",
+ "name": "Marvel Entertainment",
+ "origin_country": "US"
+ }
+ ],
+ "production_countries": [
+ {
+ "iso_3166_1": "US",
+ "name": "United States of America"
+ }
+ ],
+ "release_date": "2016-02-09",
+ "revenue": 782837347,
+ "runtime": 108,
+ "spoken_languages": [
+ {
+ "english_name": "English",
+ "iso_639_1": "en",
+ "name": "English"
+ }
+ ],
+ "status": "Released",
+ "tagline": "Feel the love.",
+ "title": "Deadpool",
+ "video": false,
+ "vote_average": 7.623,
+ "vote_count": 31904
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_external_id/imdb-tt0111161-movie.json b/providers/.cache/tmdb_external_id/imdb-tt0111161-movie.json
new file mode 100644
index 0000000..cb76124
--- /dev/null
+++ b/providers/.cache/tmdb_external_id/imdb-tt0111161-movie.json
@@ -0,0 +1,5 @@
+{
+ "tmdbId": "278",
+ "tmdbType": "movie",
+ "title": "The Shawshank Redemption"
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_external_id/imdb-tt0120915-movie.json b/providers/.cache/tmdb_external_id/imdb-tt0120915-movie.json
new file mode 100644
index 0000000..ccf1cbc
--- /dev/null
+++ b/providers/.cache/tmdb_external_id/imdb-tt0120915-movie.json
@@ -0,0 +1,5 @@
+{
+ "tmdbId": "1893",
+ "tmdbType": "movie",
+ "title": "Star Wars: Episode I - The Phantom Menace"
+}
\ No newline at end of file
diff --git a/providers/.cache/tmdb_external_id/imdb-tt31868189-movie.json b/providers/.cache/tmdb_external_id/imdb-tt31868189-movie.json
new file mode 100644
index 0000000..eb28927
--- /dev/null
+++ b/providers/.cache/tmdb_external_id/imdb-tt31868189-movie.json
@@ -0,0 +1,5 @@
+{
+ "tmdbId": "1263256",
+ "tmdbType": "movie",
+ "title": "Happy Gilmore 2"
+}
\ No newline at end of file
diff --git a/providers/.cache/uhdmovies/uhd_final_v18_1263256_movie.json b/providers/.cache/uhdmovies/uhd_final_v18_1263256_movie.json
new file mode 100644
index 0000000..10b3e96
--- /dev/null
+++ b/providers/.cache/uhdmovies/uhd_final_v18_1263256_movie.json
@@ -0,0 +1,74 @@
+{
+ "data": [
+ {
+ "quality": "Unknown Quality",
+ "size": "Unknown",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzbjJiSzNaUWpVaG5QM1F2NGJZUjhRVT0=",
+ "rawQuality": "Unknown Quality",
+ "driveleechRedirectUrl": "https://uhdmovies.eu/1080p-uhd/"
+ },
+ {
+ "quality": "Unknown Quality",
+ "size": "Unknown",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzaE5qZ1JnMXNxa1hHT1JiL3ZEZ2lNcz0=",
+ "rawQuality": "Unknown Quality",
+ "driveleechRedirectUrl": "https://uhdmovies.eu/movies/"
+ },
+ {
+ "quality": "4K | HDR",
+ "size": "16.68 GB",
+ "link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2o4SUZUQjVyK3FDd1MyUXhZQlJ3TFJsdTNiUHhwd1Q4QTVGRlpUdGQxNVpPd0E2YmlWVUJ0c0lXZU9Sa0s1eXVuT2prMEd5dTVEc0xCdHl0Q0FZTTd2Nlhad1pLTnZzODg5L2tWRDR5aGp3ZEpZL014N1RRVVZRYUpWRXg5ZjRGQUtGZDZOTHJ0QVp0MitQUDY4WmVqbA==",
+ "rawQuality": "Happy Glimore 2 (2025).2160p NF WEB-DL HDR 10bit HEVC [Hindi DDP 5.1 + English DDP 5.1] x265 (HHWEB-UHDMovies) [16.68 GB]",
+ "driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=dWFxZDQrS3RwK2dZZFVoUHBydmRxQVlORUVHQVc0NkFsRm02UDk3ai80YjZHbE85N2dOWWVZcUhrMVh3U2JONA=="
+ },
+ {
+ "quality": "4K",
+ "size": "11.14 GB",
+ "link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2dBcGU3S01vY1JIWkxlYnRZUlpscVFDNFIxbEpDeGtTWVFxNCt3dlVsampCNlhrdVJlUXU3VkZCQVZPL0ttd0hPZ2Q3eU5KQ1VGZVI4cW5ZbWxmNUNXWEt0ejRiTUVBQ3FWQ1RZMjBmV2tPMWdZRVNnQURYZjZSWE56cjJUYjNHbnQ1OUZ2NG96VVZUclJlNlZKSGx6YQ==",
+ "rawQuality": "Happy Glimore 2 (2025).2160p NF WEB-DL SDR 10bit HEVC [Hindi DDP 5.1 + English DDP 5.1] x265 (HHWEB-UHDMovies) [11.14 GB]",
+ "driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=UHBTVjR3T3IybXRMS0RjY01tK3FHMVJqbGNzdWVEMFczNjkvdjdpWUh2SHl5ekwwVEFnNHFNdllKRFg2Z015TA=="
+ },
+ {
+ "quality": "1080p",
+ "size": "5.28 GB",
+ "link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2hiSUN6VHNPMnIyK1o2NHV4VkVpQmVnUmRqUmRoOFh1UkpKZkdhY3JmbWxOeXdMU1c2SVdnb0FwTnh1b2EySDVVZTVOK1hwTVk0RTIwNEgvN21BcEp4STc1OHlpbUV0Ylh6c1pyc0V5VjFQTEttS3luUXZPL0ZTQ3pycTlhYXgwcGpjWDcyZFdENmdKam5DUmxXUmFKcQ==",
+ "rawQuality": "Happy.Gilmore.2.2025.1080p.NF.WEB-DL.DUAL.DDP5.1.Atmos.H.264-ShiNobi [5.28 GB]",
+ "driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=cW5YYzgyZ2IwdW9pWmdXakRIMTRad2xkV3l2eGxkSEZtc0FwUE8vSEs4cjJTNEZLVWIvTjZvaUVPeHQrZ3p5bQ=="
+ },
+ {
+ "quality": "1080p",
+ "size": "5.28 GB",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzdldUTFJiZlVQZVg0V2JWNkRGRU9uM2RPcjB5UTRtWmxvUXF0OUVLWU8yYw==",
+ "rawQuality": "Happy.Gilmore.2.2025.1080p.NF.WEB-DL.DUAL.DDP5.1.Atmos.H.264-ShiNobi [5.28 GB]",
+ "driveleechRedirectUrl": "https://uhdmovies.eu/1080p-60fps/"
+ },
+ {
+ "quality": "1080p",
+ "size": "5.28 GB",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzcGJmM0lkMWZ4Zyt1Q2xiZ3VlQThqcXlHbHQ2ZUNaejFqbElUa1lXZm9PSg==",
+ "rawQuality": "Happy.Gilmore.2.2025.1080p.NF.WEB-DL.DUAL.DDP5.1.Atmos.H.264-ShiNobi [5.28 GB]",
+ "driveleechRedirectUrl": "https://uhdmovies.eu/1080p-10bit/"
+ },
+ {
+ "quality": "1080p",
+ "size": "5.28 GB",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzdlJ5d0FSNm5XZjFtTlkrM3FmOFpLbz0=",
+ "rawQuality": "Happy.Gilmore.2.2025.1080p.NF.WEB-DL.DUAL.DDP5.1.Atmos.H.264-ShiNobi [5.28 GB]",
+ "driveleechRedirectUrl": "https://uhdmovies.eu/4k-hdr/"
+ },
+ {
+ "quality": "Unknown Quality",
+ "size": "Unknown",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzamFGMjVxNDJ0ZTc0RFM2M0pUNFdYTW1tRlNzbVl2Uzk0N3pDSHdoTmZFUQ==",
+ "rawQuality": "Unknown Quality",
+ "driveleechRedirectUrl": "https://uhdmovies.eu/2160p-movies/"
+ },
+ {
+ "quality": "Unknown Quality",
+ "size": "Unknown",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzbDZUM21XeXB0Tzl6TTB6c1BDN0x0cz0=",
+ "rawQuality": "Unknown Quality",
+ "driveleechRedirectUrl": "https://uhdmovies.eu/3d-movies/"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/uhdmovies/uhd_final_v18_1399_tv_s1e1.json b/providers/.cache/uhdmovies/uhd_final_v18_1399_tv_s1e1.json
new file mode 100644
index 0000000..199ee1e
--- /dev/null
+++ b/providers/.cache/uhdmovies/uhd_final_v18_1399_tv_s1e1.json
@@ -0,0 +1,25 @@
+{
+ "data": [
+ {
+ "quality": "4K | DV | BluRay",
+ "size": "Unknown",
+ "link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2pvMHJ3OElxMDl5bFcwWjdSL2cvQWZBdGdnVTNZUE5uSUllcDBlZUc0N0FWb25JS2J4bDNLQVRXMTUwYytoRzFodExZa3pDNE00NWVrejVSS1R3bmlyaDZwR2diVkVMUFhLVkRWTlBWazNGNURYNWczYVFEZ080WWNydkNqNHRxajJuUitjdXJEZkZiNnNrRnBrZDlyMg==",
+ "rawQuality": "Game.of.Thrones.S01.UHD.BluRay.2160p.DV.HEVC.REMUX.[Hindi DD 2.0 – Eng TrueHD.Atmos.7.1]-MSubs~(Tom) FraMeSToR [25 GB/E]",
+ "driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=OEcxNEtwQ3ZrMFlaSEp2eFY1RGZYa1Mwa1V0NThXVGQ3T1FjZnpOM0NBY2poZjQyRFpRNmgwQ3hhZkxzeFpjRw=="
+ },
+ {
+ "quality": "1080p | BluRay",
+ "size": "Unknown",
+ "link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2oycFVobHI5cmZ3OVNWaG5RYWZEQTFyRmVkQWZ4amdycTVjU0J6Vnl1UUl5SmxPR1ZxdmJJWlRXL1doYUVKMitqN1FWdDdKdERiTUI2U3c4TVJ1M1lYdDZpMTd3WTc1bXM1WElFYVZLTGlrODFGbVNaN20wOFYzYzBIZkUyTlQvZWFRbXEvMXVndGh6dG1Ld2FwLy82OA==",
+ "rawQuality": "Game of Thrones (2011) S01 1080p BluRay [Hindi DD 2.0 + English DTS 5.1] x264-LiNG[AK47] [5 GB/E]",
+ "driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=eUc0QUdoUmt5VkxGdTNmWk1aOVlndTFwNHZlUHl5RHNIMFBMZjFZdEdXTkc1L2lqWXlQdU96Y3ZFRXl4UTNNbw=="
+ },
+ {
+ "quality": "1080p | BluRay",
+ "size": "Unknown",
+ "link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2pSNWFKd3dwNVR2MVpRd3lqN1cwYXFxQVJiaTdHOC9rWmhqcFNVTytydVVBUFFGVEd1aUJ5YjUxLzZFaFgxU1JjU1hFTEpVdDVpMXlGTWVNMmh0aFNWb2d4TzBaTlNaOU9EM3Y4SVM3bllGSmJQR0NvZzg1TWNObEdOOWZoNFVyazhBOGk3emhxZjhGVy9RY3NpYnB6MQ==",
+ "rawQuality": "Game of Thrones S01 1080p BluRay 10bit HEVC [Hindi DD 2.0 + English AAC 5.1] x265-Joy[AK47] [800 MB/E] [09 GB ZIP]",
+ "driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=U2lzTnlYK3lhbDg3a0JNb3NsUVZ5OCtLV1FvaysrMG5jRHJOSFpSUllrWW9qNm56UCtYdkRUcmREYlNxVkp4Ng=="
+ }
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/uhdmovies/uhd_final_v18_293660_movie.json b/providers/.cache/uhdmovies/uhd_final_v18_293660_movie.json
new file mode 100644
index 0000000..bdf363e
--- /dev/null
+++ b/providers/.cache/uhdmovies/uhd_final_v18_293660_movie.json
@@ -0,0 +1,123 @@
+{
+ "data": [
+ {
+ "quality": "Unknown Quality",
+ "size": "Unknown",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMza2Z2VFBEdEhydU93VlhXT3JOYXFGaUhtU3FyeGkwbjh6d1RoajJEaW5UbQ==",
+ "rawQuality": "Unknown Quality",
+ "driveleechRedirectUrl": "https://uhdmovies.mov/4k-movies/"
+ },
+ {
+ "quality": "Unknown Quality",
+ "size": "Unknown",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzbUoyR2JpV2JxSXVOcjZLK0dGKzFhNDdlR09GT3JsaHBmcXR6cFVXeEdCYw==",
+ "rawQuality": "Unknown Quality",
+ "driveleechRedirectUrl": "https://uhdmovies.mov/2160p-hevc/"
+ },
+ {
+ "quality": "Unknown Quality",
+ "size": "Unknown",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMza3ZQQ2I2VEZZM3p6ZWFPMDhBQWRoaEh6c21YSjRDQXV5dHNFdGhNZVF3UA==",
+ "rawQuality": "Unknown Quality",
+ "driveleechRedirectUrl": "https://uhdmovies.mov/1080p-uhd/"
+ },
+ {
+ "quality": "Unknown Quality",
+ "size": "Unknown",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzdlNJRWNQTHBvd0ZXZXQ2bXQzQ083ND0=",
+ "rawQuality": "Unknown Quality",
+ "driveleechRedirectUrl": "https://uhdmovies.mov/movies/"
+ },
+ {
+ "quality": "4K | HDR | DV | BluRay",
+ "size": "26GB",
+ "link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2hGRTRnNzZRQUIrNUIxcWpDMk9xMEVRNXV2bncyNG8reHE3YVJtOUxBbjhvVzRSYTFjd2VsN2drOUlxM2VVVHd1K3YzcmRtSDg5N3FXMVRQY2hPYjhkUUFmcGlNNnVmb1hZMnJEL2R1WHQxb1dhNEJjV0U2RERKYjVEc2ZHOUk5TzZVbXlxanZHVFhFYVRsOUp0LzdYag==",
+ "rawQuality": "Deadpool (2016) 2160p UHD BluRay DV HDR 10bit HEVC [Hindi DDP 5.1 + English DDP 5.1] x265 (d3g-UHDMovies [26GB]",
+ "driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=bFZyc1p1MTVRSU94bXo5ZmJzQlJHcDByaGYwcXZSdnZVbm84ZzVQRlFvSVlLQlFOcTAzWHFGUzB5UGh5cERDRw=="
+ },
+ {
+ "quality": "4K | HDR | DV | BluRay",
+ "size": "6GB",
+ "link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2llRS9MRS9Md3BGVWZLWDkrQzk3N05kZVd0aFJwNFNJZGJOYjJ2c3U0aXFiVkNpQkxseWhsNkNWemZwYkk2RFRyOWh5VHJiVHFMTGk3ODU0c2xrcG82Yzk3cnJlSEU5R1JwSjBkYk8wN1JkUnJ3dE0wWCtLWHJxUXc3OVBSZEMySTg0azhDMlc4cnVUc3pDUldaQlBGTg==",
+ "rawQuality": "Deadpool (2016) 2160p UHD BluRay DV HDR 10bit HEVC [Hindi DDP 5.1 + English DDP 5.1] x265 (RARBG-UHDMovies) [6GB]",
+ "driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=L0VucTlwOXNCdmRjNFJUL01XS2lTNDNuRTNQbGtnYWFpNk5QOUNQSEN1cm1kRUtmUy8rZDhReDUzVEk0N1k2Mw=="
+ },
+ {
+ "quality": "1080p | HDR | DV | BluRay",
+ "size": "12GB",
+ "link": "https://tech.unblockedgames.world/?sid=UldoSTVjL3N3QUU0K05LZzlkVXQxaDdNb0pJa0NJcXArK2RjL3RlQ1gvMD0=",
+ "rawQuality": "Deadpool (2016) 1080p UHD BluRay DV HDR 10bit HEVC [Hindi DDP 5.1 + English DDP 5.1] x265 (NMcT-UHDMovies [12GB]",
+ "driveleechRedirectUrl": "javascript:void(0);"
+ },
+ {
+ "quality": "1080p | BluRay",
+ "size": "11GB",
+ "link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2hBMkpOb2VJRHdGV1ROVTRVc2w5WGJERTNDVlhFUkE3TjdCUWdkcENqZXkwNXFlM1dRK0MwUjJucmpNTjJlUW5sRDZqWXlSamZRa3dHZThVbG9NelErbHA2VXp5eTBlbG1iY0g2NFNGZE1XL2lTSzlyR3VsTHd4YjVGQXF0NTBDSlpuTVhjVmpycGVKNEtGbmlJVVg2VQ==",
+ "rawQuality": "Deadpool (2016) 1080p UHD BluRay [Hindi DDP 5.1 + English DDP 5.1] x264 (LoRD-UHDMovies) [11GB]",
+ "driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=NUVMaXZ0dFJJWXd0WlJaWUZyMUpGaDFiRjhRUEt1SXRUT1JPd29JR3NMWEs1ZnNydWl1bjYxeVBCaFp0ZG52dA=="
+ },
+ {
+ "quality": "1080p | BluRay",
+ "size": "21GB",
+ "link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2pLSkd1UmpiYmdQRExHQnJZbS9UaEhmTUlYT09LQnI5QXIxR1ZGd3JzRy80SXdMbjB4OW9jR1R1S2llMkRTSk02SWdpdkJtSmVmZlVHZ3JBTHdyUkE2djg0VWdISXhiTXM3Q3NwVFg3R3E3UU5rVDJ0RDlUb290ckNuZDRWczdvVEgrSk40N3FpK3Q2UWE2TlVxa0M3ag==",
+ "rawQuality": "Deadpool (2016) 1080p BluRay REMUX AVC [Hindi DDP 5.1 + English DDP 5.1] x264 (CC-UHDMovies) [21GB]",
+ "driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=a3lXeUFGT29ZaVFZZFRua2lqOFZ3ZGF2bFRidFNaTWFqSGVYUWgrajZmMXl5TVVKclZWeHJFc1c1eDFFV2s3eQ=="
+ },
+ {
+ "quality": "1080p | BluRay",
+ "size": "11.6GB",
+ "link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2g5N3pSVmlGNnNibnMrdktudm9QWk9STklic3VrRFZBRE5PWXphOExvcUY0Z1BmRno1cFRKRXZIaHBhV3NIRjVYSWZPa0hwbnBJR1pxSEhGME52RllGcUxvdGx0ZVpqdkVyK3BUdmtlbUlJWE9LRVd2MUlQUFZhZnE5ZTErWUVtNTJnNnVKbE83UkpiTURrZ21UeHZzcQ==",
+ "rawQuality": "Deadpool (2016) 1080p BluRay AVC [Hindi DDP 5.1 + English DTS 5.1] x264 (HDMaNiAcS-UHDMovies) [11.6GB]",
+ "driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=bEtkV1ZOemMvVkFMdEVFRGtzK1ladkVndWFBYXhWMWVQSWN1aS96S0kvY2w4R0hUWm1MS25RbHIwVVk3N0RNVg=="
+ },
+ {
+ "quality": "1080p | BluRay",
+ "size": "6GB",
+ "link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2dYWHN4ODgzeXUrOURvQTVPbHhOVEZUWnJOZzRBdTd5UkhDTmV6bDIyNnFwUFd6VDBMaXdaVFh6U05ZeVl2U3lIMTE3ZjZOTWlEMVgxWFMvTVFHMzBoWHQvK0p1Y3p3UHRsREJjT0w4bVhtekduMnh1dWRKS0NMSTV4bXV6M3dtampiMXlLWDVpdVZLell1WC83b2tnLw==",
+ "rawQuality": "Deadpool (2016) 1080p BluRay 10bit HEVC [Hindi DDP 5.1 + English AAC 5.1] x265 (BeiTai-UHDMovies) [6GB]",
+ "driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=OGlEbjNEN1JGVVBueGE5elVCWjY3bTdVYUpPdm5tZGMrTnNna0lsTWIwMzVSQThUbmdQOEE5WkVVbDVRZTFLUg=="
+ },
+ {
+ "quality": "1080p | BluRay",
+ "size": "2GB",
+ "link": "https://tech.unblockedgames.world/?sid=bnpxOTF5Uk9VOVFZM2lEMkxXUmp0VTdoWDBEcGZMVWlrSmRYNlplRk9lQUdoYmJPbisvYi83VjZWNEdWbXVUai8vc3hQdGRwQ3lFRWtlZVVMR3YxSnR1MGV5dE1HTWs0bEtqM0x1bHhCT2dLSjBXTVNJWXVPK0FxeVZrUVZPUDhJMDJLcjRYOXZ4TVZXYlJ5dndpTDNsM0tmbkpQWVJ5em91NU41YndacERXSTNjemxCNE5GVnowM2F5QkYrVlE1SmhQVGcxelZIVjlNNXBONVJLYTcwK0dDNk42cWNMalE3Qk1WY0x1MVA1MFR0NkVGNGZkWkNRZnp6dS85Zml5Yw==",
+ "rawQuality": "Deadpool (2016) 1080p BluRay 10bit HEVC [Hindi DDP 5.1 + English AAC 5.1] x265 (RARBG-UHDMovies) [2GB]",
+ "driveleechRedirectUrl": "https://driveleech.net/r?key=UkVwSTIzU1gzQ3czMFBpQlBmeHB6NklzQjRRZFdMYStJaWI4UnZLdVd4QT0=&id=aVl6ZkFvQTZzUHdIUVE4SStONG02YmlONzkydzdVaUY0dDhIdHpxQVpjK2wrNmpUNkhCeHBwZWI3Q3Zwby9HLw=="
+ },
+ {
+ "quality": "1080p | BluRay",
+ "size": "2GB",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzbVhDeGlwbGZ5alNmd1dGSExtbllZNmlHQU1hd21Fd00xRGV5R081Ym1xSQ==",
+ "rawQuality": "Deadpool (2016) 1080p BluRay 10bit HEVC [Hindi DDP 5.1 + English AAC 5.1] x265 (RARBG-UHDMovies) [2GB]",
+ "driveleechRedirectUrl": "https://uhdmovies.mov/1080p-60fps/"
+ },
+ {
+ "quality": "1080p | BluRay",
+ "size": "2GB",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzbTlTYS9SYXVlWmVCNUpiM3VLMGY5VFpGMUMwRnBhRllXMXFWeUE3Q3dGcA==",
+ "rawQuality": "Deadpool (2016) 1080p BluRay 10bit HEVC [Hindi DDP 5.1 + English AAC 5.1] x265 (RARBG-UHDMovies) [2GB]",
+ "driveleechRedirectUrl": "https://uhdmovies.mov/1080p-10bit/"
+ },
+ {
+ "quality": "1080p | BluRay",
+ "size": "2GB",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzaEtZenp1aENhajVZeG5sTXNFcFVRTT0=",
+ "rawQuality": "Deadpool (2016) 1080p BluRay 10bit HEVC [Hindi DDP 5.1 + English AAC 5.1] x265 (RARBG-UHDMovies) [2GB]",
+ "driveleechRedirectUrl": "https://uhdmovies.mov/4k-hdr/"
+ },
+ {
+ "quality": "Unknown Quality",
+ "size": "Unknown",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzb3U1SmhRbk5yN0NDdGxPcmZNbUx4QkNPcEZ3bnQvM1R0Y1dsV2p1RFFGRQ==",
+ "rawQuality": "Unknown Quality",
+ "driveleechRedirectUrl": "https://uhdmovies.mov/2160p-movies/"
+ },
+ {
+ "quality": "Unknown Quality",
+ "size": "Unknown",
+ "link": "https://tech.unblockedgames.world/?sid=dmpORG1pUDNaSE4zMWt4RTFDVDMzdFBXM3RQUkFjRkF6T05icGNaL0FKejdzT0FXVGhwVVhCdVFkM294c2w4ag==",
+ "rawQuality": "Unknown Quality",
+ "driveleechRedirectUrl": "https://uhdmovies.mov/3d-movies/"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/1aad53a15787411b795b5524d51152d8.txt b/providers/.cache/xprime_stream_sizes/1aad53a15787411b795b5524d51152d8.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/1aad53a15787411b795b5524d51152d8.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/228c2e738c6cd080cac60a7d469be0a7.txt b/providers/.cache/xprime_stream_sizes/228c2e738c6cd080cac60a7d469be0a7.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/228c2e738c6cd080cac60a7d469be0a7.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/23f2e2575e9a53275b4e65e81f1513e3.txt b/providers/.cache/xprime_stream_sizes/23f2e2575e9a53275b4e65e81f1513e3.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/23f2e2575e9a53275b4e65e81f1513e3.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/30366ba90dc476972dc55b9c3288818c.txt b/providers/.cache/xprime_stream_sizes/30366ba90dc476972dc55b9c3288818c.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/30366ba90dc476972dc55b9c3288818c.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/4000906de5113a825f1e539ed233b1f0.txt b/providers/.cache/xprime_stream_sizes/4000906de5113a825f1e539ed233b1f0.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/4000906de5113a825f1e539ed233b1f0.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/417fb0a29f17b39113fe276a48113094.txt b/providers/.cache/xprime_stream_sizes/417fb0a29f17b39113fe276a48113094.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/417fb0a29f17b39113fe276a48113094.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/48741a5793088283d4d0ed2c6ebbe2da.txt b/providers/.cache/xprime_stream_sizes/48741a5793088283d4d0ed2c6ebbe2da.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/48741a5793088283d4d0ed2c6ebbe2da.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/51895d57ffb6928f37314b9857f9c02b.txt b/providers/.cache/xprime_stream_sizes/51895d57ffb6928f37314b9857f9c02b.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/51895d57ffb6928f37314b9857f9c02b.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/59df54de2c32254e3393fd8e7f3396eb.txt b/providers/.cache/xprime_stream_sizes/59df54de2c32254e3393fd8e7f3396eb.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/59df54de2c32254e3393fd8e7f3396eb.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/5ad6676fd79ba4e616d4bf30fbeac22e.txt b/providers/.cache/xprime_stream_sizes/5ad6676fd79ba4e616d4bf30fbeac22e.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/5ad6676fd79ba4e616d4bf30fbeac22e.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/659030e85029e6bd29f3776fdb947c5c.txt b/providers/.cache/xprime_stream_sizes/659030e85029e6bd29f3776fdb947c5c.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/659030e85029e6bd29f3776fdb947c5c.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/823fa5aa59cbe94cae6434846fe7429e.txt b/providers/.cache/xprime_stream_sizes/823fa5aa59cbe94cae6434846fe7429e.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/823fa5aa59cbe94cae6434846fe7429e.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/83202d7c20aac5625749f059374b0994.txt b/providers/.cache/xprime_stream_sizes/83202d7c20aac5625749f059374b0994.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/83202d7c20aac5625749f059374b0994.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/871cdc7cd959d5b93f2f1604de80c6f5.txt b/providers/.cache/xprime_stream_sizes/871cdc7cd959d5b93f2f1604de80c6f5.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/871cdc7cd959d5b93f2f1604de80c6f5.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/8f4ff27a0b288b211c0b54e9e063dd38.txt b/providers/.cache/xprime_stream_sizes/8f4ff27a0b288b211c0b54e9e063dd38.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/8f4ff27a0b288b211c0b54e9e063dd38.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/a9f2b84096292e5beddaf83202b669ea.txt b/providers/.cache/xprime_stream_sizes/a9f2b84096292e5beddaf83202b669ea.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/a9f2b84096292e5beddaf83202b669ea.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/b16713fa6fa939275df6fee6eccceecd.txt b/providers/.cache/xprime_stream_sizes/b16713fa6fa939275df6fee6eccceecd.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/b16713fa6fa939275df6fee6eccceecd.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/ba11809a580e18ecea164232540c91ab.txt b/providers/.cache/xprime_stream_sizes/ba11809a580e18ecea164232540c91ab.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/ba11809a580e18ecea164232540c91ab.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/bf2e8662e91c220a1dbfd3396a5e262e.txt b/providers/.cache/xprime_stream_sizes/bf2e8662e91c220a1dbfd3396a5e262e.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/bf2e8662e91c220a1dbfd3396a5e262e.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/c00fb6bcf578bf8bb8063a5504295aff.txt b/providers/.cache/xprime_stream_sizes/c00fb6bcf578bf8bb8063a5504295aff.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/c00fb6bcf578bf8bb8063a5504295aff.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/c80f68293909d1cdc490eedbd09d9162.txt b/providers/.cache/xprime_stream_sizes/c80f68293909d1cdc490eedbd09d9162.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/c80f68293909d1cdc490eedbd09d9162.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/.cache/xprime_stream_sizes/c9f286b6cbbd5807e4175a82c3a004f5.txt b/providers/.cache/xprime_stream_sizes/c9f286b6cbbd5807e4175a82c3a004f5.txt
new file mode 100644
index 0000000..efc4e60
--- /dev/null
+++ b/providers/.cache/xprime_stream_sizes/c9f286b6cbbd5807e4175a82c3a004f5.txt
@@ -0,0 +1 @@
+Unknown size
\ No newline at end of file
diff --git a/providers/4khdhub.js b/providers/4khdhub.js
new file mode 100644
index 0000000..4ccf07c
--- /dev/null
+++ b/providers/4khdhub.js
@@ -0,0 +1,1764 @@
+const https = require('https');
+const http = require('http');
+const { URL } = require('url');
+const cheerio = require('cheerio');
+const fs = require('fs').promises;
+const path = require('path');
+
+// Configuration
+const DOMAINS_URL = 'https://raw.githubusercontent.com/phisher98/TVVVV/refs/heads/main/domains.json';
+let cachedDomains = null;
+
+// --- Caching Configuration ---
+const CACHE_ENABLED = process.env.DISABLE_CACHE !== 'true';
+console.log(`[4KHDHub] Internal cache is ${CACHE_ENABLED ? 'enabled' : 'disabled'}.`);
+const CACHE_DIR = process.env.VERCEL ? path.join('/tmp', '.4khdhub_cache') : path.join(__dirname, '.cache', '4khdhub');
+
+// Caching layer simplified: currently inert placeholders (extend for FS persistence if desired)
+
+// --- Caching Helper Functions ---
+const ensureCacheDir = async () => {
+ if (!CACHE_ENABLED) return;
+ try {
+ await fs.mkdir(CACHE_DIR, { recursive: true });
+ } catch (error) {
+ if (error.code !== 'EEXIST') {
+ console.error(`[4KHDHub Cache] Error creating cache directory: ${error.message}`);
+ }
+ }
+};
+
+const getFromCache = async (key) => {
+ if (!CACHE_ENABLED) return null;
+ return null; // no-op
+};
+
+const saveToCache = async (key, data) => {
+ if (!CACHE_ENABLED) return;
+ // no-op (placeholder for future FS caching)
+};
+
+// Initialize cache directory on startup
+ensureCacheDir();
+
+// Utility functions
+function base64Decode(str) {
+ return Buffer.from(str, 'base64').toString('utf-8');
+}
+
+
+function rot13(str) {
+ return str.replace(/[A-Za-z]/g, function(char) {
+ const start = char <= 'Z' ? 65 : 97;
+ return String.fromCharCode(((char.charCodeAt(0) - start + 13) % 26) + start);
+ });
+}
+
+function validateUrl(url) {
+ return new Promise((resolve) => {
+ try {
+ const urlObj = new URL(url);
+
+ // Skip validation for known reliable hosting services
+ const trustedHosts = [
+ 'pixeldrain.dev',
+ 'r2.dev'
+ ];
+
+ const isTrustedHost = trustedHosts.some(host => urlObj.hostname.includes(host));
+ if (isTrustedHost) {
+ console.log(`[4KHDHub] Skipping validation for trusted host: ${urlObj.hostname}`);
+ resolve(true);
+ return;
+ }
+
+ const protocol = urlObj.protocol === 'https:' ? https : http;
+
+ const options = {
+ method: 'HEAD',
+ timeout: 15000,
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
+ }
+ };
+
+ const req = protocol.request(url, options, (res) => {
+ // Consider 2xx and 3xx status codes as valid, including 206 (Partial Content)
+ const isValid = res.statusCode >= 200 && res.statusCode < 400;
+ console.log(`[4KHDHub] URL validation for ${url}: ${res.statusCode} - ${isValid ? 'VALID' : 'INVALID'}`);
+ res.destroy(); // Close connection immediately
+ resolve(isValid);
+ });
+
+ req.on('error', (err) => {
+ console.log(`[4KHDHub] URL validation error for ${url}: ${err.message}`);
+ resolve(false);
+ });
+
+ req.on('timeout', () => {
+ console.log(`[4KHDHub] URL validation timeout for ${url}`);
+ req.destroy();
+ resolve(false);
+ });
+
+ req.setTimeout(15000);
+ req.end();
+ } catch (error) {
+ console.log(`[4KHDHub] URL validation parse error for ${url}: ${error.message}`);
+ resolve(false);
+ }
+ });
+}
+
+function makeRequest(url, options = {}) {
+ return new Promise((resolve, reject) => {
+ const urlObj = new URL(url);
+ const isHttps = urlObj.protocol === 'https:';
+ const httpModule = isHttps ? https : http;
+
+ const requestOptions = {
+ hostname: urlObj.hostname,
+ port: urlObj.port || (isHttps ? 443 : 80),
+ path: urlObj.pathname + urlObj.search,
+ method: options.method || 'GET',
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
+ ...options.headers
+ },
+ timeout: 30000
+ };
+
+ const req = httpModule.request(requestOptions, (res) => {
+ if (options.allowRedirects === false && (res.statusCode === 301 || res.statusCode === 302 || res.statusCode === 303 || res.statusCode === 307 || res.statusCode === 308)) {
+ resolve({ statusCode: res.statusCode, headers: res.headers });
+ return;
+ }
+
+ let data = '';
+ res.on('data', chunk => data += chunk);
+ res.on('end', () => {
+ if (options.parseHTML && data) {
+ const $ = cheerio.load(data);
+ resolve({ $: $, body: data, statusCode: res.statusCode, headers: res.headers });
+ } else {
+ resolve({ body: data, statusCode: res.statusCode, headers: res.headers });
+ }
+ });
+ });
+
+ req.on('error', reject);
+ req.on('timeout', () => reject(new Error('Request timeout')));
+ req.end();
+ });
+}
+
+// Helper function to decode URL-encoded filenames and make them human-readable
+function decodeFilename(filename) {
+ if (!filename) return filename;
+
+ try {
+ // Handle UTF-8 prefix and decode URL encoding
+ let decoded = filename;
+
+ // Remove UTF-8 prefix if present
+ if (decoded.startsWith('UTF-8')) {
+ decoded = decoded.substring(5);
+ }
+
+ // Decode URL encoding (%20 -> space, etc.)
+ decoded = decodeURIComponent(decoded);
+
+ return decoded;
+ } catch (error) {
+ console.log(`[4KHDHub] Error decoding filename: ${error.message}`);
+ return filename; // Return original if decoding fails
+ }
+}
+
+function getFilenameFromUrl(url) {
+ return new Promise((resolve) => {
+ try {
+ const urlObj = new URL(url);
+ const isHttps = urlObj.protocol === 'https:';
+ const httpModule = isHttps ? https : http;
+
+ const requestOptions = {
+ hostname: urlObj.hostname,
+ port: urlObj.port || (isHttps ? 443 : 80),
+ path: urlObj.pathname + urlObj.search,
+ method: 'HEAD',
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
+ },
+ timeout: 10000
+ };
+
+ const req = httpModule.request(requestOptions, (res) => {
+ const contentDisposition = res.headers['content-disposition'];
+ let filename = null;
+
+ if (contentDisposition) {
+ const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/i);
+ if (filenameMatch && filenameMatch[1]) {
+ filename = filenameMatch[1].replace(/["']/g, '');
+ }
+ }
+
+ if (!filename) {
+ // Extract from URL path
+ const pathParts = urlObj.pathname.split('/');
+ filename = pathParts[pathParts.length - 1];
+ if (filename && filename.includes('.')) {
+ filename = filename.replace(/\.[^.]+$/, ''); // Remove extension
+ }
+ }
+
+ // Decode the filename to make it human-readable
+ const decodedFilename = decodeFilename(filename);
+ resolve(decodedFilename || null);
+ });
+
+ req.on('error', () => resolve(null));
+ req.on('timeout', () => resolve(null));
+ req.end();
+ } catch (error) {
+ resolve(null);
+ }
+ });
+}
+
+function getDomains() {
+ if (cachedDomains) {
+ return Promise.resolve(cachedDomains);
+ }
+
+ return makeRequest(DOMAINS_URL)
+ .then(response => {
+ cachedDomains = JSON.parse(response.body);
+ return cachedDomains;
+ })
+ .catch(error => {
+ console.error('[4KHDHub] Failed to fetch domains:', error.message);
+ return null;
+ });
+}
+
+function getRedirectLinks(url) {
+ return makeRequest(url)
+ .then(response => {
+ const doc = response.body;
+ const regex = /s\('o','([A-Za-z0-9+/=]+)'|ck\('_wp_http_\d+','([^']+)'/g;
+ let combinedString = '';
+ let match;
+
+ while ((match = regex.exec(doc)) !== null) {
+ const extractedValue = match[1] || match[2];
+ if (extractedValue) {
+ combinedString += extractedValue;
+ }
+ }
+
+ try {
+ const decodedString = base64Decode(rot13(base64Decode(base64Decode(combinedString))));
+ const jsonObject = JSON.parse(decodedString);
+ const encodedurl = base64Decode(jsonObject.o || '').trim();
+ const data = base64Decode(jsonObject.data || '').trim();
+ const wphttp1 = (jsonObject.blog_url || '').trim();
+
+ if (encodedurl) {
+ return Promise.resolve(encodedurl);
+ }
+
+ if (wphttp1 && data) {
+ return makeRequest(`${wphttp1}?re=${data}`, { parseHTML: true })
+ .then(resp => resp.document.body.textContent.trim())
+ .catch(() => '');
+ }
+
+ return Promise.resolve('');
+ } catch (e) {
+ console.error('[4KHDHub] Error processing links:', e.message);
+ return Promise.resolve('');
+ }
+ })
+ .catch(error => {
+ console.error('[4KHDHub] Error fetching redirect links:', error.message);
+ return Promise.resolve('');
+ });
+}
+
+function getIndexQuality(str) {
+ const match = (str || '').match(/(\d{3,4})[pP]/);
+ return match ? parseInt(match[1]) : 2160;
+}
+
+function getBaseUrl(url) {
+ try {
+ const urlObj = new URL(url);
+ return `${urlObj.protocol}//${urlObj.host}`;
+ } catch (e) {
+ return '';
+ }
+}
+
+function cleanTitle(title) {
+ // Decode URL-encoded title first
+ const decodedTitle = decodeFilename(title);
+ const parts = decodedTitle.split(/[.\-_]/);
+
+ const qualityTags = ['WEBRip', 'WEB-DL', 'WEB', 'BluRay', 'HDRip', 'DVDRip', 'HDTV', 'CAM', 'TS', 'R5', 'DVDScr', 'BRRip', 'BDRip', 'DVD', 'PDTV', 'HD'];
+ const audioTags = ['AAC', 'AC3', 'DTS', 'MP3', 'FLAC', 'DD5', 'EAC3', 'Atmos'];
+ const subTags = ['ESub', 'ESubs', 'Subs', 'MultiSub', 'NoSub', 'EnglishSub', 'HindiSub'];
+ const codecTags = ['x264', 'x265', 'H264', 'HEVC', 'AVC'];
+
+ const startIndex = parts.findIndex(part =>
+ qualityTags.some(tag => part.toLowerCase().includes(tag.toLowerCase()))
+ );
+
+ const endIndex = parts.map((part, index) => {
+ const hasTag = [...subTags, ...audioTags, ...codecTags].some(tag =>
+ part.toLowerCase().includes(tag.toLowerCase())
+ );
+ return hasTag ? index : -1;
+ }).filter(index => index !== -1).pop() || -1;
+
+ if (startIndex !== -1 && endIndex !== -1 && endIndex >= startIndex) {
+ return parts.slice(startIndex, endIndex + 1).join('.');
+ } else if (startIndex !== -1) {
+ return parts.slice(startIndex).join('.');
+ } else {
+ return parts.slice(-3).join('.');
+ }
+}
+
+// Enhanced title normalization with better handling of special cases
+function normalizeTitle(title) {
+ return title
+ .toLowerCase()
+ // Handle common title variations
+ .replace(/&/g, 'and') // & -> and
+ .replace(/\b(the|a|an)\b/g, '') // Remove articles
+ // Handle common abbreviations and expansions
+ .replace(/\bvs\b/g, 'versus')
+ .replace(/\bversus\b/g, 'vs')
+ .replace(/\bdr\b/g, 'doctor')
+ .replace(/\bdoctor\b/g, 'dr')
+ .replace(/\bmr\b/g, 'mister')
+ .replace(/\bmister\b/g, 'mr')
+ .replace(/\bst\b/g, 'saint')
+ .replace(/\bsaint\b/g, 'st')
+ .replace(/\bmt\b/g, 'mount')
+ .replace(/\bmount\b/g, 'mt')
+ .replace(/[^a-z0-9\s]/g, ' ') // Remove special characters
+ .replace(/\s+/g, ' ') // Normalize whitespace
+ .trim();
+}
+
+// Extract year from title if present
+function extractYear(title) {
+ const yearMatch = title.match(/\((19|20)\d{2}\)/);
+ return yearMatch ? parseInt(yearMatch[0].replace(/[()]/g, '')) : null;
+}
+
+// Remove year from title for cleaner comparison
+function removeYear(title) {
+ return title.replace(/\s*\((19|20)\d{2}\)\s*/g, ' ').trim();
+}
+
+// Generate alternative search queries for better matching
+function generateAlternativeQueries(title, originalTitle = null) {
+ const queries = new Set();
+
+ // Add the original title
+ queries.add(title);
+
+ // Add original title if different
+ if (originalTitle && originalTitle !== title) {
+ queries.add(originalTitle);
+ }
+
+ // Remove year and try again
+ const titleWithoutYear = removeYear(title);
+ if (titleWithoutYear !== title) {
+ queries.add(titleWithoutYear);
+ }
+
+ // Remove colons and other punctuation
+ queries.add(title.replace(/:/g, ''));
+ queries.add(title.replace(/[^a-zA-Z0-9\s]/g, ' ').replace(/\s+/g, ' ').trim());
+
+ // Handle common title variations
+ const variations = [
+ title.replace(/\bPart\s+(\d+)\b/gi, 'Part $1'),
+ title.replace(/\bPart\s+(\d+)\b/gi, '$1'),
+ title.replace(/\b(\d+)\b/g, match => {
+ const num = parseInt(match);
+ const romans = ['', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X'];
+ return romans[num] || match;
+ }),
+ title.replace(/\b(I{1,3}|IV|V|VI{0,3}|IX|X)\b/g, match => {
+ const romans = { 'I': '1', 'II': '2', 'III': '3', 'IV': '4', 'V': '5',
+ 'VI': '6', 'VII': '7', 'VIII': '8', 'IX': '9', 'X': '10' };
+ return romans[match] || match;
+ })
+ ];
+
+ variations.forEach(v => {
+ if (v && v !== title) queries.add(v);
+ });
+
+ // Remove duplicates and filter out empty strings
+ return Array.from(queries).filter(q => q && q.trim().length > 0);
+}
+
+// Enhanced similarity calculation with multiple algorithms
+function calculateSimilarity(str1, str2) {
+ const s1 = normalizeTitle(str1);
+ const s2 = normalizeTitle(str2);
+
+ if (s1 === s2) return 1.0;
+
+ // Levenshtein distance
+ const levenshtein = calculateLevenshteinSimilarity(s1, s2);
+
+ // Jaccard similarity (word-based)
+ const jaccard = calculateJaccardSimilarity(s1, s2);
+
+ // Longest common subsequence
+ const lcs = calculateLCSSimilarity(s1, s2);
+
+ // Weighted combination of different similarity measures
+ return (levenshtein * 0.4) + (jaccard * 0.4) + (lcs * 0.2);
+}
+
+// Levenshtein distance similarity
+function calculateLevenshteinSimilarity(s1, s2) {
+ const len1 = s1.length;
+ const len2 = s2.length;
+
+ if (len1 === 0) return len2 === 0 ? 1.0 : 0.0;
+ if (len2 === 0) return 0.0;
+
+ const matrix = Array(len1 + 1).fill().map(() => Array(len2 + 1).fill(0));
+
+ for (let i = 0; i <= len1; i++) matrix[i][0] = i;
+ for (let j = 0; j <= len2; j++) matrix[0][j] = j;
+
+ for (let i = 1; i <= len1; i++) {
+ for (let j = 1; j <= len2; j++) {
+ const cost = s1[i - 1] === s2[j - 1] ? 0 : 1;
+ matrix[i][j] = Math.min(
+ matrix[i - 1][j] + 1, // deletion
+ matrix[i][j - 1] + 1, // insertion
+ matrix[i - 1][j - 1] + cost // substitution
+ );
+ }
+ }
+
+ const maxLen = Math.max(len1, len2);
+ return (maxLen - matrix[len1][len2]) / maxLen;
+}
+
+// Jaccard similarity for word-based comparison
+function calculateJaccardSimilarity(s1, s2) {
+ const words1 = new Set(s1.split(' ').filter(w => w.length > 0));
+ const words2 = new Set(s2.split(' ').filter(w => w.length > 0));
+
+ const intersection = new Set([...words1].filter(w => words2.has(w)));
+ const union = new Set([...words1, ...words2]);
+
+ return union.size === 0 ? 0 : intersection.size / union.size;
+}
+
+// Longest Common Subsequence similarity
+function calculateLCSSimilarity(s1, s2) {
+ const len1 = s1.length;
+ const len2 = s2.length;
+
+ if (len1 === 0 || len2 === 0) return 0;
+
+ const dp = Array(len1 + 1).fill().map(() => Array(len2 + 1).fill(0));
+
+ for (let i = 1; i <= len1; i++) {
+ for (let j = 1; j <= len2; j++) {
+ if (s1[i - 1] === s2[j - 1]) {
+ dp[i][j] = dp[i - 1][j - 1] + 1;
+ } else {
+ dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
+ }
+ }
+ }
+
+ const maxLen = Math.max(len1, len2);
+ return dp[len1][len2] / maxLen;
+}
+
+// Enhanced word containment check with fuzzy matching
+function containsWords(title, query) {
+ const titleWords = normalizeTitle(title).split(' ').filter(w => w.length > 1);
+ const queryWords = normalizeTitle(query).split(' ').filter(w => w.length > 1);
+
+ let matchedWords = 0;
+
+ for (const queryWord of queryWords) {
+ const found = titleWords.some(titleWord => {
+ // Exact match
+ if (titleWord === queryWord) return true;
+
+ // Substring match
+ if (titleWord.includes(queryWord) || queryWord.includes(titleWord)) return true;
+
+ // Fuzzy match for longer words (allow 1 character difference)
+ if (queryWord.length > 3 && titleWord.length > 3) {
+ const similarity = calculateLevenshteinSimilarity(titleWord, queryWord);
+ return similarity > 0.8;
+ }
+
+ return false;
+ });
+
+ if (found) matchedWords++;
+ }
+
+ // Require at least 70% of query words to be matched
+ return matchedWords / queryWords.length >= 0.7;
+}
+
+// Enhanced best match finder with improved scoring
+function findBestMatch(results, query, tmdbYear = null) {
+ if (results.length === 0) return null;
+ if (results.length === 1) return results[0];
+
+ console.log(`[4KHDHub] Finding best match for: "${query}" (Year: ${tmdbYear || 'N/A'})`);
+
+ // Strict year gating: if TMDB year is known, only consider exact matches first,
+ // then allow unknown-year entries as fallback. Reject clear mismatches.
+ let candidateResults = results;
+ if (tmdbYear) {
+ const tmdbYearInt = parseInt(tmdbYear);
+ const exactYearMatches = results.filter(r => {
+ const y = r.year || extractYear(r.title);
+ return y && parseInt(y) === tmdbYearInt;
+ });
+ if (exactYearMatches.length > 0) {
+ candidateResults = exactYearMatches;
+ console.log(`[4KHDHub] Year filter: using ${exactYearMatches.length} exact year matches for ${tmdbYearInt}`);
+ } else {
+ const unknownYear = results.filter(r => {
+ const y = r.year || extractYear(r.title);
+ return !y;
+ });
+ if (unknownYear.length > 0) {
+ candidateResults = unknownYear;
+ console.log(`[4KHDHub] Year filter: no exact matches; falling back to ${unknownYear.length} unknown-year results`);
+ } else {
+ console.log(`[4KHDHub] Year filter: no exact or unknown-year matches for ${tmdbYearInt}; rejecting results`);
+ return null;
+ }
+ }
+ }
+
+ // Score each result
+ const scoredResults = candidateResults.map(result => {
+ let score = 0;
+ // Use year from search result metadata if available, otherwise extract from title
+ const resultYear = result.year || extractYear(result.title);
+ const queryWithoutYear = removeYear(query);
+ const resultWithoutYear = removeYear(result.title);
+
+ // Exact match gets highest score (without year)
+ if (normalizeTitle(resultWithoutYear) === normalizeTitle(queryWithoutYear)) {
+ score += 100;
+ }
+
+ // Enhanced similarity score (0-60 points)
+ const similarity = calculateSimilarity(resultWithoutYear, queryWithoutYear);
+ score += similarity * 60;
+
+ // Word containment bonus (0-25 points)
+ if (containsWords(result.title, query)) {
+ score += 25;
+ }
+
+ // Year matching bonus (strict): only reward exact match when TMDB year is known
+ if (tmdbYear && resultYear) {
+ if (parseInt(tmdbYear) === parseInt(resultYear)) {
+ score += 30; // Strong reward for exact year
+ }
+ } else if (resultYear && !tmdbYear) {
+ score += 5; // Slight bonus for having year info when TMDB year unknown
+ }
+
+ // Length similarity bonus (0-10 points)
+ const lengthDiff = Math.abs(resultWithoutYear.length - queryWithoutYear.length);
+ score += Math.max(0, 10 - lengthDiff / 3);
+
+ // Prefer results with quality indicators
+ if (result.title.match(/\b(1080p|720p|4K|2160p|BluRay|WEB-DL)\b/i)) {
+ score += 3;
+ }
+
+ // Penalty for results with too many extra words
+ const queryWordCount = queryWithoutYear.split(' ').filter(w => w.length > 0).length;
+ const resultWordCount = resultWithoutYear.split(' ').filter(w => w.length > 0).length;
+ if (resultWordCount > queryWordCount * 2) {
+ score -= 10;
+ }
+
+ return { ...result, score, similarity, resultYear };
+ });
+
+ // Sort by score (highest first)
+ scoredResults.sort((a, b) => b.score - a.score);
+
+ console.log('[4KHDHub] Title matching scores:');
+ scoredResults.slice(0, 5).forEach((result, index) => {
+ console.log(`${index + 1}. ${result.title} (Score: ${result.score.toFixed(1)}, Similarity: ${(result.similarity * 100).toFixed(1)}%, Year: ${result.resultYear || 'N/A'})`);
+ });
+
+ // Additional validation: ensure the best match has a reasonable score
+ const bestResult = scoredResults[0];
+ // Final guard: if TMDB year is known and best has a conflicting year, reject
+ if (tmdbYear && bestResult.resultYear && parseInt(bestResult.resultYear) !== parseInt(tmdbYear)) {
+ console.log(`[4KHDHub] Best match year mismatch (best=${bestResult.resultYear}, tmdb=${tmdbYear}), rejecting`);
+ return null;
+ }
+ if (bestResult.score < 30) {
+ console.log(`[4KHDHub] Best match score too low (${bestResult.score.toFixed(1)}), rejecting`);
+ return null;
+ }
+
+ return bestResult;
+}
+
+function extractHubCloudLinks(url, referer) {
+ console.log(`[4KHDHub] Starting HubCloud extraction for: ${url}`);
+ const baseUrl = getBaseUrl(url);
+
+ return makeRequest(url, { parseHTML: true })
+ .then(response => {
+ const $ = response.$;
+ console.log(`[4KHDHub] Got HubCloud page, looking for download element...`);
+
+ // Check if this is already a hubcloud.php URL
+ let href;
+ if (url.includes('hubcloud.php')) {
+ href = url;
+ console.log(`[4KHDHub] Already a hubcloud.php URL: ${href}`);
+ } else {
+ const downloadElement = $('#download');
+ if (downloadElement.length === 0) {
+ console.log('[4KHDHub] Download element #download not found, trying alternatives...');
+ // Try alternative selectors
+ const alternatives = ['a[href*="hubcloud.php"]', '.download-btn', 'a[href*="download"]'];
+ let found = false;
+
+ for (const selector of alternatives) {
+ const altElement = $(selector).first();
+ if (altElement.length > 0) {
+ const rawHref = altElement.attr('href');
+ if (rawHref) {
+ href = rawHref.startsWith('http') ? rawHref : `${baseUrl.replace(/\/$/, '')}/${rawHref.replace(/^\//, '')}`;
+ console.log(`[4KHDHub] Found download link with selector ${selector}: ${href}`);
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ throw new Error('Download element not found with any selector');
+ }
+ } else {
+ const rawHref = downloadElement.attr('href');
+ if (!rawHref) {
+ throw new Error('Download href not found');
+ }
+
+ href = rawHref.startsWith('http') ? rawHref : `${baseUrl.replace(/\/$/, '')}/${rawHref.replace(/^\//, '')}`;
+ console.log(`[4KHDHub] Found download href: ${href}`);
+ }
+ }
+
+ console.log(`[4KHDHub] Making request to HubCloud download page: ${href}`);
+ return makeRequest(href, { parseHTML: true });
+ })
+ .then(response => {
+ const $ = response.$;
+
+ console.log(`[4KHDHub] Processing HubCloud download page...`);
+
+ // Extract quality and size information
+ const size = $('i#size').text() || '';
+ const header = $('div.card-header').text() || '';
+ const quality = getIndexQuality(header);
+ const headerDetails = cleanTitle(header);
+
+ console.log(`[4KHDHub] Extracted info - Size: ${size}, Header: ${header}, Quality: ${quality}, HeaderDetails: ${headerDetails}`);
+
+ // Extract just the quality for clean naming
+ const qualityLabel = quality ? ` - ${quality}p` : '';
+
+ // We'll build the title format later after getting actual filename from HEAD request
+
+ // Find download buttons
+ const downloadButtons = $('div.card-body h2 a.btn');
+ console.log(`[4KHDHub] Found ${downloadButtons.length} download buttons`);
+
+ if (downloadButtons.length === 0) {
+ // Try alternative selectors for download buttons
+ const altSelectors = ['a.btn', '.btn', 'a[href]'];
+ for (const selector of altSelectors) {
+ const altButtons = $(selector);
+ if (altButtons.length > 0) {
+ console.log(`[4KHDHub] Found ${altButtons.length} buttons with alternative selector: ${selector}`);
+ altButtons.each((index, btn) => {
+ const $btn = $(btn);
+ const link = $btn.attr('href');
+ const text = $btn.text();
+ console.log(`[4KHDHub] Button ${index + 1}: ${text} -> ${link}`);
+ });
+ break;
+ }
+ }
+ }
+
+ const promises = downloadButtons.get().map((button, index) => {
+ return new Promise((resolve) => {
+ const $button = $(button);
+ const link = $button.attr('href');
+ const text = $button.text();
+
+ console.log(`[4KHDHub] Processing button ${index + 1}: "${text}" -> ${link}`);
+
+ if (!link) {
+ console.log(`[4KHDHub] Button ${index + 1} has no link`);
+ resolve(null);
+ return;
+ }
+
+ const buttonBaseUrl = getBaseUrl(link);
+
+ if (text.includes('FSL Server')) {
+ console.log(`[4KHDHub] Button ${index + 1} is FSL Server`);
+ // Get actual filename from HEAD request
+ getFilenameFromUrl(link)
+ .then(actualFilename => {
+ const displayFilename = actualFilename || headerDetails || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ resolve({
+ name: `4KHDHub - FSL Server${qualityLabel}`,
+ title: finalTitle,
+ url: link,
+ quality: quality
+ });
+ })
+ .catch(() => {
+ const displayFilename = headerDetails || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ resolve({
+ name: `4KHDHub - FSL Server${qualityLabel}`,
+ title: finalTitle,
+ url: link,
+ quality: quality
+ });
+ });
+ } else if (text.includes('Download File')) {
+ console.log(`[4KHDHub] Button ${index + 1} is Download File`);
+ // Get actual filename from HEAD request
+ getFilenameFromUrl(link)
+ .then(actualFilename => {
+ const displayFilename = actualFilename || headerDetails || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ resolve({
+ name: `4KHDHub - HubCloud${qualityLabel}`,
+ title: finalTitle,
+ url: link,
+ quality: quality
+ });
+ })
+ .catch(() => {
+ const displayFilename = headerDetails || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ resolve({
+ name: `4KHDHub - HubCloud${qualityLabel}`,
+ title: finalTitle,
+ url: link,
+ quality: quality
+ });
+ });
+ } else if (text.includes('BuzzServer')) {
+ console.log(`[4KHDHub] Button ${index + 1} is BuzzServer, following redirect...`);
+ // Handle BuzzServer redirect
+ makeRequest(`${link}/download`, {
+ parseHTML: false,
+ allowRedirects: false,
+ headers: { 'Referer': link }
+ })
+ .then(response => {
+ const redirectUrl = response.headers['hx-redirect'] || response.headers['location'];
+ if (redirectUrl) {
+ console.log(`[4KHDHub] BuzzServer redirect found: ${redirectUrl}`);
+ const finalUrl = buttonBaseUrl + redirectUrl;
+ // Get actual filename from HEAD request
+ getFilenameFromUrl(finalUrl)
+ .then(actualFilename => {
+ const displayFilename = actualFilename || headerDetails || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ resolve({
+ name: `4KHDHub - BuzzServer${qualityLabel}`,
+ title: finalTitle,
+ url: finalUrl,
+ quality: quality
+ });
+ })
+ .catch(() => {
+ const displayFilename = headerDetails || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ resolve({
+ name: `4KHDHub - BuzzServer${qualityLabel}`,
+ title: finalTitle,
+ url: finalUrl,
+ quality: quality
+ });
+ });
+ } else {
+ console.log(`[4KHDHub] BuzzServer redirect not found`);
+ resolve(null);
+ }
+ })
+ .catch(err => {
+ console.log(`[4KHDHub] BuzzServer redirect failed: ${err.message}`);
+ resolve(null);
+ });
+ } else if (link.includes('pixeldra')) {
+ console.log(`[4KHDHub] Button ${index + 1} is Pixeldrain`);
+
+ // Convert pixeldrain.net/u/ID format to pixeldrain.net/api/file/ID format
+ let convertedLink = link;
+ const pixeldrainMatch = link.match(/pixeldrain\.net\/u\/([a-zA-Z0-9]+)/);
+ if (pixeldrainMatch) {
+ const fileId = pixeldrainMatch[1];
+ convertedLink = `https://pixeldrain.net/api/file/${fileId}`;
+ console.log(`[4KHDHub] Converted Pixeldrain URL from ${link} to ${convertedLink}`);
+ }
+
+ // Get actual filename from HEAD request
+ getFilenameFromUrl(convertedLink)
+ .then(actualFilename => {
+ const displayFilename = actualFilename || headerDetails || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ resolve({
+ name: `4KHDHub - Pixeldrain${qualityLabel}`,
+ title: finalTitle,
+ url: convertedLink,
+ quality: quality
+ });
+ })
+ .catch(() => {
+ const displayFilename = headerDetails || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ resolve({
+ name: `4KHDHub - Pixeldrain${qualityLabel}`,
+ title: finalTitle,
+ url: convertedLink,
+ quality: quality
+ });
+ });
+ } else if (text.includes('S3 Server')) {
+ console.log(`[4KHDHub] Button ${index + 1} is S3 Server`);
+ // Get actual filename from HEAD request
+ getFilenameFromUrl(link)
+ .then(actualFilename => {
+ const displayFilename = actualFilename || headerDetails || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ resolve({
+ name: `4KHDHub - S3 Server${qualityLabel}`,
+ title: finalTitle,
+ url: link,
+ quality: quality
+ });
+ })
+ .catch(() => {
+ const displayFilename = headerDetails || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ resolve({
+ name: `4KHDHub - S3 Server${qualityLabel}`,
+ title: finalTitle,
+ url: link,
+ quality: quality
+ });
+ });
+ } else if (text.includes('10Gbps')) {
+ console.log(`[4KHDHub] Button ${index + 1} is 10Gbps server, following redirects...`);
+ // Handle 10Gbps server with multiple redirects
+ let currentLink = link;
+
+ const followRedirects = () => {
+ return makeRequest(currentLink, {
+ parseHTML: false,
+ allowRedirects: false
+ })
+ .then(response => {
+ const redirectUrl = response.headers['location'];
+ if (!redirectUrl) {
+ throw new Error('No redirect found');
+ }
+
+ console.log(`[4KHDHub] 10Gbps redirect: ${redirectUrl}`);
+
+ if (redirectUrl.includes('id=')) {
+ // Final redirect, extract the link parameter
+ const finalLink = redirectUrl.split('link=')[1];
+ if (finalLink) {
+ console.log(`[4KHDHub] 10Gbps final link: ${finalLink}`);
+ const decodedUrl = decodeURIComponent(finalLink);
+ // Get actual filename from HEAD request
+ return getFilenameFromUrl(decodedUrl)
+ .then(actualFilename => {
+ const displayFilename = actualFilename || headerDetails || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ return {
+ name: `4KHDHub - 10Gbps Server${qualityLabel}`,
+ title: finalTitle,
+ url: decodedUrl,
+ quality: quality
+ };
+ })
+ .catch(() => {
+ const displayFilename = headerDetails || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ return {
+ name: `4KHDHub - 10Gbps Server${qualityLabel}`,
+ title: finalTitle,
+ url: decodedUrl,
+ quality: quality
+ };
+ });
+ }
+ throw new Error('Final link not found');
+ } else {
+ currentLink = redirectUrl;
+ return followRedirects();
+ }
+ });
+ };
+
+ followRedirects()
+ .then(result => {
+ console.log(`[4KHDHub] 10Gbps processing completed`);
+ resolve(result);
+ })
+ .catch(err => {
+ console.log(`[4KHDHub] 10Gbps processing failed: ${err.message}`);
+ resolve(null);
+ });
+ } else {
+ console.log(`[4KHDHub] Button ${index + 1} is generic link`);
+ // Generic link - Get actual filename from HEAD request
+ getFilenameFromUrl(link)
+ .then(actualFilename => {
+ const displayFilename = actualFilename || headerDetails || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ resolve({
+ name: `4KHDHub - HubCloud${qualityLabel}`,
+ title: finalTitle,
+ url: link,
+ quality: quality
+ });
+ })
+ .catch(() => {
+ const displayFilename = headerDetails || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ resolve({
+ name: `4KHDHub - HubCloud${qualityLabel}`,
+ title: finalTitle,
+ url: link,
+ quality: quality
+ });
+ });
+ }
+ });
+ });
+
+ return Promise.all(promises)
+ .then(results => {
+ const validResults = results.filter(result => result !== null);
+ console.log(`[4KHDHub] HubCloud extraction completed, found ${validResults.length} valid links`);
+ return validResults;
+ });
+ })
+ .catch(error => {
+ console.error(`[4KHDHub] HubCloud extraction error for ${url}:`, error.message);
+ return [];
+ });
+}
+
+function searchContent(query) {
+ return getDomains()
+ .then(domains => {
+ if (!domains || !domains['4khdhub']) {
+ throw new Error('Failed to get domain information');
+ }
+
+ const baseUrl = domains['4khdhub'];
+ const searchUrl = `${baseUrl}/?s=${encodeURIComponent(query)}`;
+ return makeRequest(searchUrl, { parseHTML: true })
+ .then(response => ({ response, baseUrl }));
+ })
+ .then(({ response, baseUrl }) => {
+ const $ = response.$;
+ const results = [];
+
+ $('div.card-grid a').each((index, card) => {
+ const $card = $(card);
+ const title = $card.find('h3').text();
+ const href = $card.attr('href');
+ const posterUrl = $card.find('img').attr('src');
+
+ // Extract year from movie-card-meta element
+ const metaElement = $card.find('.movie-card-meta');
+ let year = null;
+ if (metaElement.length > 0) {
+ const metaText = metaElement.text().trim();
+ const yearMatch = metaText.match(/(19|20)\d{2}/);
+ if (yearMatch) {
+ year = parseInt(yearMatch[0]);
+ }
+ }
+
+ if (title && href) {
+ // Convert relative URLs to absolute URLs
+ const absoluteUrl = href.startsWith('http') ? href : `${baseUrl}${href.startsWith('/') ? '' : '/'}${href}`;
+ results.push({
+ title: title.trim(),
+ url: absoluteUrl,
+ poster: posterUrl || '',
+ year: year
+ });
+ }
+ });
+
+ return results;
+ });
+}
+
+function loadContent(url) {
+ return makeRequest(url, { parseHTML: true })
+ .then(response => {
+ const $ = response.$;
+ const title = $('h1.page-title').text().split('(')[0].trim() || '';
+ const poster = $('meta[property="og:image"]').attr('content') || '';
+ const tags = $('div.mt-2 span.badge').map((i, el) => $(el).text()).get();
+ const year = parseInt($('div.mt-2 span').text()) || null;
+ const description = $('div.content-section p.mt-4').text().trim() || '';
+ const trailer = $('#trailer-btn').attr('data-trailer-url') || '';
+
+ const isMovie = tags.includes('Movies');
+
+ // Try multiple selectors to find download links
+ let hrefs = [];
+ const selectors = [
+ 'div.download-item a',
+ '.download-item a',
+ 'a[href*="hubdrive"]',
+ 'a[href*="hubcloud"]',
+ 'a[href*="drive"]',
+ '.btn[href]',
+ 'a.btn'
+ ];
+
+ for (const selector of selectors) {
+ const links = $(selector)
+ .map((i, a) => $(a).attr('href'))
+ .get()
+ .filter(href => href && href.trim());
+ if (links.length > 0) {
+ hrefs = links;
+ console.log(`[4KHDHub] Found ${links.length} links using selector: ${selector}`);
+ break;
+ }
+ }
+
+ if (hrefs.length === 0) {
+ console.log('[4KHDHub] No download links found. Available links on page:');
+ const allLinks = $('a[href]')
+ .map((i, a) => $(a).attr('href'))
+ .get()
+ .filter(href => href && href.includes('http'))
+ .slice(0, 10); // Show first 10 links
+ console.log(allLinks);
+ }
+
+ const content = {
+ title,
+ poster,
+ tags,
+ year,
+ description,
+ trailer,
+ type: isMovie ? 'movie' : 'series'
+ };
+
+ if (isMovie) {
+ content.downloadLinks = hrefs;
+ return Promise.resolve(content);
+ } else {
+ // Handle TV series episodes
+ const episodesMap = new Map(); // used to dedupe episodes below
+
+ console.log(`[4KHDHub] Looking for episode structure...`);
+ const seasonItems = $('div.episodes-list div.season-item');
+ console.log(`[4KHDHub] Found ${seasonItems.length} season items`);
+
+ if (seasonItems.length === 0) {
+ // Try alternative episode structure selectors
+ const altSelectors = [
+ 'div.season-item',
+ '.episode-item',
+ '.episode-download',
+ 'div[class*="episode"]',
+ 'div[class*="season"]'
+ ];
+
+ for (const selector of altSelectors) {
+ const items = $(selector);
+ if (items.length > 0) {
+ console.log(`[4KHDHub] Found ${items.length} items with selector: ${selector}`);
+ break;
+ }
+ }
+
+ // If no episode structure found, treat all found links as general series links
+ if (hrefs.length > 0) {
+ console.log(`[4KHDHub] No episode structure found, using general links for series`);
+ // Create a single episode entry with all links
+ content.episodes = [{
+ season: 1,
+ episode: 1,
+ downloadLinks: hrefs
+ }];
+ } else {
+ content.episodes = [];
+ }
+ } else {
+ seasonItems.each((i, seasonElement) => {
+ const $seasonElement = $(seasonElement);
+ const seasonText = $seasonElement.find('div.episode-number').text() || '';
+ const seasonMatch = seasonText.match(/S?([1-9][0-9]*)/);
+ const season = seasonMatch ? parseInt(seasonMatch[1]) : null;
+
+ const episodeItems = $seasonElement.find('div.episode-download-item');
+ episodeItems.each((j, episodeItem) => {
+ const $episodeItem = $(episodeItem);
+ const episodeText = $episodeItem.find('div.episode-file-info span.badge-psa').text() || '';
+ const episodeMatch = episodeText.match(/Episode-0*([1-9][0-9]*)/);
+ const episode = episodeMatch ? parseInt(episodeMatch[1]) : null;
+
+ const episodeHrefs = $episodeItem.find('a')
+ .map((k, a) => $(a).attr('href'))
+ .get()
+ .filter(href => href && href.trim());
+
+ if (season && episode && episodeHrefs.length > 0) {
+ const key = `${season}-${episode}`;
+ if (!episodesMap.has(key)) {
+ episodesMap.set(key, {
+ season,
+ episode,
+ downloadLinks: []
+ });
+ }
+ episodesMap.get(key).downloadLinks.push(...episodeHrefs);
+ }
+ });
+ });
+
+ content.episodes = Array.from(episodesMap.values()).map(ep => ({
+ ...ep,
+ downloadLinks: [...new Set(ep.downloadLinks)] // Remove duplicates
+ }));
+ }
+
+ console.log(`[4KHDHub] Found ${content.episodes.length} episodes with links`);
+ return Promise.resolve(content);
+ }
+ });
+}
+
+function extractStreamingLinks(downloadLinks) {
+ console.log(`[4KHDHub] Processing ${downloadLinks.length} download links...`);
+
+ const promises = downloadLinks.map((link, index) => {
+ return new Promise((resolve) => {
+ console.log(`[4KHDHub] Processing link ${index + 1}: ${link}`);
+
+ // Check if link needs redirect processing
+ if (link.toLowerCase().includes('id=')) {
+ console.log(`[4KHDHub] Link ${index + 1} needs redirect processing`);
+ getRedirectLinks(link)
+ .then(resolvedLink => {
+ if (resolvedLink) {
+ console.log(`[4KHDHub] Link ${index + 1} resolved to: ${resolvedLink}`);
+ processExtractorLink(resolvedLink, resolve, index + 1);
+ } else {
+ console.log(`[4KHDHub] Link ${index + 1} redirect resolution failed`);
+ resolve(null);
+ }
+ })
+ .catch(err => {
+ console.error(`[4KHDHub] Redirect failed for link ${index + 1} (${link}):`, err.message);
+ resolve(null);
+ });
+ } else {
+ processExtractorLink(link, resolve, index + 1);
+ }
+ });
+ });
+
+ return Promise.all(promises)
+ .then(results => {
+ const validResults = results.filter(result => result !== null);
+ const flatResults = validResults.flat();
+ // Filter out .zip files
+ const filteredResults = flatResults.filter(link => {
+ return link && link.url && !link.url.toLowerCase().endsWith('.zip');
+ });
+ // Note: Link count will be logged after validation completes
+ return filteredResults;
+ });
+}
+
+function extractHubDriveLinks(url, referer) {
+ console.log(`[4KHDHub] Starting HubDrive extraction for: ${url}`);
+
+ return makeRequest(url, { parseHTML: true })
+ .then(response => {
+ const $ = response.$;
+
+ console.log(`[4KHDHub] Got HubDrive page, looking for download button...`);
+
+ // Extract filename and size information
+ const size = $('i#size').text() || '';
+ const header = $('div.card-header').text() || '';
+ const quality = getIndexQuality(header);
+ const headerDetails = cleanTitle(header);
+
+ console.log(`[4KHDHub] HubDrive extracted info - Size: ${size}, Header: ${header}, Quality: ${quality}, HeaderDetails: ${headerDetails}`);
+
+ // Extract filename from header for title display
+ let filename = headerDetails || header || 'Unknown';
+ // Clean up the filename by removing common prefixes and file extensions
+ filename = filename.replace(/^4kHDHub\.com\s*[-_]?\s*/i, '')
+ .replace(/\.[a-z0-9]{2,4}$/i, '')
+ .replace(/[._]/g, ' ')
+ .trim();
+
+ // Use the exact selector from Kotlin code
+ const downloadBtn = $('.btn.btn-primary.btn-user.btn-success1.m-1').first();
+
+ if (downloadBtn.length === 0) {
+ console.log('[4KHDHub] Primary download button not found, trying alternative selectors...');
+ // Try alternative selectors
+ const alternatives = [
+ 'a.btn.btn-primary',
+ '.btn-primary',
+ 'a[href*="download"]',
+ 'a.btn'
+ ];
+
+ let foundBtn = null;
+ for (const selector of alternatives) {
+ foundBtn = $(selector).first();
+ if (foundBtn.length > 0) {
+ console.log(`[4KHDHub] Found download button with selector: ${selector}`);
+ break;
+ }
+ }
+
+ if (!foundBtn || foundBtn.length === 0) {
+ throw new Error('Download button not found with any selector');
+ }
+
+ const href = foundBtn.attr('href');
+ if (!href) {
+ throw new Error('Download link not found');
+ }
+
+ console.log(`[4KHDHub] Found HubDrive download link: ${href}`);
+ return processHubDriveLink(href, referer, filename, size, quality);
+ }
+
+ const href = downloadBtn.attr('href');
+ if (!href) {
+ throw new Error('Download link not found');
+ }
+
+ console.log(`[4KHDHub] Found HubDrive download link: ${href}`);
+ return processHubDriveLink(href, referer, filename, size, quality);
+ })
+ .catch(error => {
+ console.error(`[4KHDHub] Error extracting HubDrive links for ${url}:`, error.message);
+ return [];
+ });
+}
+
+function processHubDriveLink(href, referer, filename = 'Unknown', size = '', quality = 1080) {
+ // Check if it's a HubCloud link
+ if (href.toLowerCase().includes('hubcloud')) {
+ console.log('[4KHDHub] HubDrive link redirects to HubCloud, processing...');
+ return extractHubCloudLinks(href, '4KHDHub');
+ } else {
+ console.log('[4KHDHub] HubDrive direct link found');
+ // Direct link or other extractor
+ const qualityLabel = quality ? ` - ${quality}p` : '';
+
+ // Build labelExtras like the original extractor
+ const labelExtras = [];
+ if (filename && filename !== 'Unknown') labelExtras.push(`[${filename}]`);
+ if (size) labelExtras.push(`[${size}]`);
+ // labelExtra removed (not used)
+
+ // Get actual filename from HEAD request
+ return getFilenameFromUrl(href)
+ .then(actualFilename => {
+ const displayFilename = actualFilename || filename || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ return [{
+ name: `4KHDHub - HubDrive${qualityLabel}`,
+ title: finalTitle,
+ url: href,
+ quality: quality
+ }];
+ })
+ .catch(() => {
+ const displayFilename = filename || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ if (size) titleParts.push(size);
+ const finalTitle = titleParts.join('\n');
+
+ return [{
+ name: `4KHDHub - HubDrive${qualityLabel}`,
+ title: finalTitle,
+ url: href,
+ quality: quality
+ }];
+ });
+ }
+}
+
+function processExtractorLink(link, resolve, linkNumber) {
+ const linkLower = link.toLowerCase();
+
+ console.log(`[4KHDHub] Checking extractors for link ${linkNumber}: ${link}`);
+
+ if (linkLower.includes('hubdrive')) {
+ console.log(`[4KHDHub] Link ${linkNumber} matched HubDrive extractor`);
+ extractHubDriveLinks(link, '4KHDHub')
+ .then(links => {
+ console.log(`[4KHDHub] HubDrive extraction completed for link ${linkNumber}:`, links);
+ resolve(links);
+ })
+ .catch(err => {
+ console.error(`[4KHDHub] HubDrive extraction failed for link ${linkNumber} (${link}):`, err.message);
+ resolve(null);
+ });
+ } else if (linkLower.includes('hubcloud')) {
+ console.log(`[4KHDHub] Link ${linkNumber} matched HubCloud extractor`);
+ extractHubCloudLinks(link, '4KHDHub')
+ .then(links => {
+ console.log(`[4KHDHub] HubCloud extraction completed for link ${linkNumber}:`, links);
+ resolve(links);
+ })
+ .catch(err => {
+ console.error(`[4KHDHub] HubCloud extraction failed for link ${linkNumber} (${link}):`, err.message);
+ resolve(null);
+ });
+ } else {
+ console.log(`[4KHDHub] No extractor matched for link ${linkNumber}: ${link}`);
+ // Try to extract any direct streaming URLs from the link
+ if (link.includes('http') && (link.includes('.mp4') || link.includes('.mkv') || link.includes('.avi'))) {
+ console.log(`[4KHDHub] Link ${linkNumber} appears to be a direct video link`);
+ // Extract filename from URL
+ const urlParts = link.split('/');
+ const filename = urlParts[urlParts.length - 1].replace(/\.[^/.]+$/, '').replace(/[._]/g, ' ');
+
+ // Build labelExtras like the original extractor
+ const labelExtras = [];
+ if (filename) labelExtras.push(`[${filename}]`);
+ labelExtras.push('[Direct Link]');
+ // labelExtra removed (not used)
+
+ // Get actual filename from HEAD request
+ getFilenameFromUrl(link)
+ .then(actualFilename => {
+ const displayFilename = actualFilename || filename || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ titleParts.push('[Direct Link]');
+ const finalTitle = titleParts.join('\n');
+
+ resolve([{
+ name: '4KHDHub Direct Link',
+ title: finalTitle,
+ url: link,
+ quality: 1080
+ }]);
+ })
+ .catch(() => {
+ const displayFilename = filename || 'Unknown';
+ const titleParts = [];
+ if (displayFilename) titleParts.push(displayFilename);
+ titleParts.push('[Direct Link]');
+ const finalTitle = titleParts.join('\n');
+
+ resolve([{
+ name: '4KHDHub Direct Link',
+ title: finalTitle,
+ url: link,
+ quality: 1080
+ }]);
+ });
+ } else {
+ resolve(null);
+ }
+ }
+}
+
+// Helper function to get TMDB details
+async function getTMDBDetails(tmdbId, mediaType) {
+ const { getTmdbApiKey } = require('../utils/tmdbKey');
+ const TMDB_API_KEY = getTmdbApiKey();
+ if(!TMDB_API_KEY){
+ console.warn('[4KHDHub] TMDB API key missing; skipping TMDB metadata fetch');
+ return null;
+ }
+
+ try {
+ console.log(`[4KHDHub] Fetching ${mediaType} details for TMDB ID: ${tmdbId}`);
+ const response = await makeRequest(`https://api.themoviedb.org/3/${mediaType}/${tmdbId}?api_key=${TMDB_API_KEY}`);
+ const data = JSON.parse(response.body);
+
+ if (mediaType === 'movie') {
+ return {
+ title: data.title,
+ original_title: data.original_title,
+ year: data.release_date ? data.release_date.split('-')[0] : null
+ };
+ } else {
+ return {
+ title: data.name,
+ original_title: data.original_name,
+ year: data.first_air_date ? data.first_air_date.split('-')[0] : null
+ };
+ }
+ } catch (error) {
+ console.error(`[4KHDHub] Error fetching details from TMDB:`, error.message);
+ return null;
+ }
+}
+
+// Main function to get streams for the addon
+async function get4KHDHubStreams(tmdbId, type, season = null, episode = null) {
+ try {
+ console.log(`[4KHDHub] Starting search for TMDB ID: ${tmdbId}, Type: ${type}${season ? `, Season: ${season}` : ''}${episode ? `, Episode: ${episode}` : ''}`);
+
+ // Create cache key for resolved file hosting URLs
+ const cacheKey = `4khdhub_resolved_urls_v3_${tmdbId}_${type}${season ? `_s${season}e${episode}` : ''}`;
+
+ let streamingLinks = [];
+
+ // 1. Check cache for resolved file hosting URLs first
+ const cachedResolvedUrls = await getFromCache(cacheKey);
+ if (cachedResolvedUrls && cachedResolvedUrls.length > 0) {
+ console.log(`[4KHDHub] Cache HIT for ${cacheKey}. Using ${cachedResolvedUrls.length} cached resolved URLs.`);
+ // Process cached resolved URLs directly to final streaming links
+ console.log(`[4KHDHub] Processing ${cachedResolvedUrls.length} cached resolved URLs to get streaming links.`);
+ streamingLinks = await extractStreamingLinks(cachedResolvedUrls);
+ } else {
+ if (cachedResolvedUrls && cachedResolvedUrls.length === 0) {
+ console.log(`[4KHDHub] Cache contains empty data for ${cacheKey}. Refetching from source.`);
+ } else {
+ console.log(`[4KHDHub] Cache MISS for ${cacheKey}. Fetching from source.`);
+ }
+
+ // Map type to TMDB API format
+ const tmdbType = type === 'series' ? 'tv' : type;
+
+ // Get TMDB details to get the actual title
+ const tmdbDetails = await getTMDBDetails(tmdbId, tmdbType);
+ if (!tmdbDetails || !tmdbDetails.title) {
+ console.log(`[4KHDHub] Could not fetch TMDB details for ID: ${tmdbId}`);
+ return [];
+ }
+
+ console.log(`[4KHDHub] TMDB Details: ${tmdbDetails.title} (${tmdbDetails.year || 'N/A'})`);
+
+ // Enhanced search with fallback strategies
+ let searchResults = [];
+ let bestMatch = null;
+
+ // Primary search using the actual title
+ const searchQuery = tmdbDetails.title;
+ searchResults = await searchContent(searchQuery);
+ console.log(`[4KHDHub] Primary search found ${searchResults.length} results`);
+
+ if (searchResults.length > 0) {
+ bestMatch = findBestMatch(searchResults, tmdbDetails.title, tmdbDetails.year);
+ }
+
+ // Fallback search strategies if no good match found
+ if (!bestMatch && searchResults.length > 0) {
+ console.log(`[4KHDHub] No good match from primary search, trying fallback strategies...`);
+
+ // Try search without year
+ const titleWithoutYear = removeYear(tmdbDetails.title);
+ if (titleWithoutYear !== tmdbDetails.title) {
+ console.log(`[4KHDHub] Trying search without year: "${titleWithoutYear}"`);
+ const fallbackResults = await searchContent(titleWithoutYear);
+ if (fallbackResults.length > 0) {
+ const fallbackMatch = findBestMatch(fallbackResults, tmdbDetails.title, tmdbDetails.year);
+ if (fallbackMatch && (!bestMatch || fallbackMatch.score > bestMatch.score)) {
+ bestMatch = fallbackMatch;
+ searchResults = fallbackResults;
+ }
+ }
+ }
+
+ // Try search with comprehensive alternative title formats
+ if (!bestMatch) {
+ const alternativeQueries = generateAlternativeQueries(
+ tmdbDetails.title,
+ tmdbDetails.original_title
+ ).filter(query => query !== tmdbDetails.title); // Exclude the original title we already tried
+
+ for (const altQuery of alternativeQueries) {
+ console.log(`[4KHDHub] Trying alternative search: "${altQuery}"`);
+ const altResults = await searchContent(altQuery);
+ if (altResults.length > 0) {
+ const altMatch = findBestMatch(altResults, tmdbDetails.title, tmdbDetails.year);
+ if (altMatch && (!bestMatch || altMatch.score > bestMatch.score)) {
+ bestMatch = altMatch;
+ searchResults = altResults;
+ console.log(`[4KHDHub] Found better match with query: "${altQuery}" (score: ${altMatch.score})`);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (searchResults.length === 0) {
+ console.log(`[4KHDHub] No search results found for any query variation`);
+ return [];
+ }
+
+ if (!bestMatch) {
+ console.log(`[4KHDHub] No suitable match found for: ${tmdbDetails.title}`);
+ return [];
+ }
+
+ console.log(`[4KHDHub] Using best match: ${bestMatch.title}`);
+
+ const content = await loadContent(bestMatch.url);
+
+ let downloadLinks = [];
+
+ if (type === 'movie') {
+ downloadLinks = content.downloadLinks || [];
+ } else if ((type === 'series' || type === 'tv') && season && episode) {
+ console.log(`[4KHDHub] Looking for Season ${season}, Episode ${episode}`);
+ console.log(`[4KHDHub] Available episodes:`, content.episodes?.map(ep => `S${ep.season}E${ep.episode} (${ep.downloadLinks?.length || 0} links)`));
+
+ const targetEpisode = content.episodes?.find(ep =>
+ ep.season === parseInt(season) && ep.episode === parseInt(episode)
+ );
+
+ if (targetEpisode) {
+ console.log(`[4KHDHub] Found target episode S${targetEpisode.season}E${targetEpisode.episode} with ${targetEpisode.downloadLinks?.length || 0} links`);
+ downloadLinks = targetEpisode.downloadLinks || [];
+ } else {
+ console.log(`[4KHDHub] Target episode S${season}E${episode} not found`);
+ }
+ }
+
+ if (downloadLinks.length === 0) {
+ console.log(`[4KHDHub] No download links found`);
+ return [];
+ }
+
+ // Resolve redirect URLs to actual file hosting URLs
+ console.log(`[4KHDHub] Resolving ${downloadLinks.length} redirect URLs to file hosting URLs...`);
+ const resolvedUrls = [];
+
+ for (let i = 0; i < downloadLinks.length; i++) {
+ const link = downloadLinks[i];
+ console.log(`[4KHDHub] Resolving link ${i + 1}/${downloadLinks.length}: ${link}`);
+
+ try {
+ if (link.toLowerCase().includes('id=')) {
+ // This is a redirect URL, resolve it
+ const resolvedUrl = await getRedirectLinks(link);
+ if (resolvedUrl && resolvedUrl.trim()) {
+ console.log(`[4KHDHub] Link ${i + 1} resolved to: ${resolvedUrl}`);
+ resolvedUrls.push(resolvedUrl);
+ } else {
+ console.log(`[4KHDHub] Link ${i + 1} resolution failed or returned empty`);
+ }
+ } else {
+ // Direct URL, use as-is
+ console.log(`[4KHDHub] Link ${i + 1} is direct URL: ${link}`);
+ resolvedUrls.push(link);
+ }
+ } catch (error) {
+ console.error(`[4KHDHub] Error resolving link ${i + 1} (${link}):`, error.message);
+ }
+ }
+
+ if (resolvedUrls.length === 0) {
+ console.log(`[4KHDHub] No URLs resolved successfully`);
+ return [];
+ }
+
+ // Cache the resolved file hosting URLs
+ console.log(`[4KHDHub] Caching ${resolvedUrls.length} resolved URLs for key: ${cacheKey}`);
+ await saveToCache(cacheKey, resolvedUrls);
+
+ // Process resolved URLs to get final streaming links
+ console.log(`[4KHDHub] Processing ${resolvedUrls.length} resolved URLs to get streaming links.`);
+ streamingLinks = await extractStreamingLinks(resolvedUrls);
+ }
+
+ // Filter out suspicious AMP/redirect URLs
+ const filteredLinks = streamingLinks.filter(link => {
+ const url = link.url.toLowerCase();
+ const suspiciousPatterns = [
+ 'www-google-com.cdn.ampproject.org',
+ 'bloggingvector.shop',
+ 'cdn.ampproject.org'
+ ];
+
+ const isSuspicious = suspiciousPatterns.some(pattern => url.includes(pattern));
+ if (isSuspicious) {
+ console.log(`[4KHDHub] Filtered out suspicious URL: ${link.url}`);
+ return false;
+ }
+ return true;
+ });
+
+ // Remove duplicates based on URL
+ const uniqueLinks = [];
+ const seenUrls = new Set();
+
+ for (const link of filteredLinks) {
+ if (!seenUrls.has(link.url)) {
+ seenUrls.add(link.url);
+ uniqueLinks.push(link);
+ }
+ }
+
+ console.log(`[4KHDHub] Processing ${uniqueLinks.length} unique links (${streamingLinks.length - filteredLinks.length} suspicious URLs filtered, ${filteredLinks.length - uniqueLinks.length} duplicates removed)`);
+
+ // Validate URLs if DISABLE_4KHDHUB_URL_VALIDATION is false
+ let validatedLinks = uniqueLinks;
+ const disableValidation = process.env.DISABLE_4KHDHUB_URL_VALIDATION === 'true';
+
+ if (!disableValidation) {
+ console.log(`[4KHDHub] URL validation enabled, validating ${uniqueLinks.length} links...`);
+ const validationPromises = uniqueLinks.map(async (link) => {
+ const isValid = await validateUrl(link.url);
+ return isValid ? link : null;
+ });
+
+ const validationResults = await Promise.all(validationPromises);
+ validatedLinks = validationResults.filter(link => link !== null);
+
+ console.log(`[4KHDHub] URL validation complete: ${validatedLinks.length}/${uniqueLinks.length} links are valid`);
+ } else {
+ console.log(`[4KHDHub] URL validation disabled, skipping validation`);
+ }
+
+ // Normalize to generic stream object format
+ const streams = validatedLinks.map(link => ({
+ name: link.name, // Don't add prefix since it's already included
+ title: link.title || link.name,
+ url: link.url,
+ quality: `${link.quality}p`,
+ behaviorHints: {
+ bingeGroup: '4khdhub-streams'
+ }
+ }));
+
+ console.log(`[4KHDHub] Returning ${streams.length} streams`);
+ return streams;
+
+ } catch (error) {
+ console.error(`[4KHDHub] Error getting streams:`, error.message);
+ return [];
+ }
+}
+
+module.exports = {
+ get4KHDHubStreams
+};
\ No newline at end of file
diff --git a/providers/MP4Hydra.js b/providers/MP4Hydra.js
new file mode 100644
index 0000000..3081eb7
--- /dev/null
+++ b/providers/MP4Hydra.js
@@ -0,0 +1,506 @@
+const axios = require('axios');
+const FormData = require('form-data');
+
+// Helper function to generate slug from title
+function generateSlug(title) {
+ return title.toLowerCase()
+ .replace(/[^\w\s-]/g, '') // Remove special characters
+ .replace(/\s+/g, '-') // Replace spaces with hyphens
+ .replace(/-+/g, '-'); // Replace multiple hyphens with a single hyphen
+}
+
+// Process episode data from MP4Hydra response
+function processEpisode(episode, baseServer, serverName, serverNumber) {
+ const videoUrl = `${baseServer}${episode.src}`;
+ const subtitles = episode.subs ? episode.subs.map(sub => ({
+ label: sub.label,
+ url: `${baseServer}${sub.src}`
+ })) : [];
+
+ return {
+ title: episode.show_title || episode.title,
+ episode: episode.title,
+ type: episode.type,
+ quality: episode.quality || episode.label,
+ videoUrl: videoUrl,
+ server: serverName,
+ serverNumber: serverNumber,
+ subtitles: subtitles
+ };
+}
+
+// Main function to get streams from MP4Hydra
+async function getMP4HydraStreams(tmdbId, mediaType, seasonNum = null, episodeNum = null) {
+ try {
+ console.log(`[MP4Hydra] Fetching streams for TMDB ID: ${tmdbId}, Type: ${mediaType}, Season: ${seasonNum}, Episode: ${episodeNum}`);
+
+ // Get TMDB details
+ const details = await getTMDBDetails(tmdbId, mediaType);
+ if (!details) {
+ console.log(`[MP4Hydra] Could not fetch details for TMDB ID: ${tmdbId}`);
+ return [];
+ }
+
+ console.log(`[MP4Hydra] Found title: ${details.title} (${details.year})`);
+
+ // Generate slug in the format "movie-name-year"
+ let slug = details.slug;
+ if (mediaType === 'movie' && details.year) {
+ slug = `${details.slug}-${details.year}`;
+ }
+ console.log(`[MP4Hydra] Using slug: ${slug}`);
+
+ // Create form data for multipart/form-data request
+ const formData = new FormData();
+ formData.append('v', '8');
+ formData.append('z', JSON.stringify([{
+ s: slug,
+ t: mediaType,
+ se: seasonNum,
+ ep: episodeNum
+ }]));
+
+ // Make request to MP4Hydra API
+ const response = await axios({
+ method: 'post',
+ url: 'https://mp4hydra.org/info2?v=8',
+ data: formData,
+ headers: {
+ ...formData.getHeaders(),
+ 'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Mobile Safari/537.36',
+ 'Accept': '*/*',
+ 'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8',
+ 'Origin': 'https://mp4hydra.org',
+ 'Referer': `https://mp4hydra.org/${mediaType}/${slug}`,
+ 'Sec-Fetch-Dest': 'empty',
+ 'Sec-Fetch-Mode': 'cors',
+ 'Sec-Fetch-Site': 'same-origin'
+ },
+ timeout: 10000
+ });
+
+ // Process response
+ if (response.data && response.data.playlist && response.data.playlist.length > 0) {
+ const playlist = response.data.playlist;
+ const servers = response.data.servers;
+
+ console.log(`[MP4Hydra] Found ${playlist.length} videos`);
+ console.log(`[MP4Hydra] Available servers: ${Object.keys(servers).join(', ')}`);
+
+ // For TV shows, find the specific episode
+ if (mediaType === 'tv' && seasonNum && episodeNum) {
+ const paddedSeason = seasonNum.toString().padStart(2, '0');
+ const paddedEpisode = episodeNum.toString().padStart(2, '0');
+ const seasonEpisode = `S${paddedSeason}E${paddedEpisode}`;
+
+ const targetEpisode = playlist.find(item =>
+ item.title && item.title.toUpperCase() === seasonEpisode.toUpperCase()
+ );
+
+ if (!targetEpisode) {
+ console.log(`[MP4Hydra] Could not find ${seasonEpisode}`);
+ return [];
+ }
+
+ console.log(`[MP4Hydra] Found episode: ${targetEpisode.show_title || targetEpisode.title}`);
+
+ // Process streams from main servers
+ const streams = [];
+ const serverConfig = [
+ { name: 'Beta', number: '#1' },
+ { name: 'Beta#3', number: '#2' }
+ ];
+
+ serverConfig.forEach(server => {
+ const serverName = server.name;
+ const serverNumber = server.number;
+
+ if (servers[serverName]) {
+ const baseServer = servers[serverName];
+ console.log(`[MP4Hydra] Processing server: ${serverName} (${baseServer})`);
+
+ const processedEpisode = processEpisode(targetEpisode, baseServer, serverName, serverNumber);
+
+ // Convert to standard stream format
+ streams.push({
+ title: `${details.title} - ${seasonEpisode} - ${processedEpisode.quality} [MP4Hydra ${serverNumber}]`,
+ url: processedEpisode.videoUrl,
+ quality: processedEpisode.quality,
+ provider: "MP4Hydra",
+ size: "Unknown size",
+ behaviorHints: {
+ notWebReady: true,
+ headers: {
+ 'Referer': 'https://mp4hydra.org/'
+ }
+ }
+ });
+
+ // Add subtitle tracks if available
+ if (processedEpisode.subtitles && processedEpisode.subtitles.length > 0) {
+ streams[streams.length - 1].subtitles = processedEpisode.subtitles.map(sub => ({
+ url: sub.url,
+ lang: sub.label
+ }));
+ }
+ }
+ });
+
+ return streams;
+ }
+
+ // For movies, process all videos
+ const streams = [];
+ const serverConfig = [
+ { name: 'Beta', number: '#1' },
+ { name: 'Beta#3', number: '#2' }
+ ];
+
+ serverConfig.forEach(server => {
+ const serverName = server.name;
+ const serverNumber = server.number;
+
+ if (servers[serverName]) {
+ const baseServer = servers[serverName];
+ console.log(`[MP4Hydra] Processing server: ${serverName} (${baseServer})`);
+
+ playlist.forEach(item => {
+ const processedItem = processEpisode(item, baseServer, serverName, serverNumber);
+
+ // Convert to standard stream format
+ streams.push({
+ title: `${details.title} - ${processedItem.quality} [MP4Hydra ${serverNumber}]`,
+ url: processedItem.videoUrl,
+ quality: processedItem.quality,
+ provider: "MP4Hydra",
+ size: "Unknown size",
+ behaviorHints: {
+ notWebReady: true,
+ headers: {
+ 'Referer': 'https://mp4hydra.org/'
+ }
+ }
+ });
+
+ // Add subtitle tracks if available
+ if (processedItem.subtitles && processedItem.subtitles.length > 0) {
+ streams[streams.length - 1].subtitles = processedItem.subtitles.map(sub => ({
+ url: sub.url,
+ lang: sub.label
+ }));
+ }
+ });
+ }
+ });
+
+ return streams;
+ } else {
+ // Try with original title if the first attempt failed
+ if (details.title !== details.original_title) {
+ return await tryAlternativeTitle(details, mediaType, seasonNum, episodeNum);
+ }
+
+ // Try without year for movies
+ if (mediaType === 'movie' && details.year) {
+ return await tryWithoutYear(details, mediaType, seasonNum, episodeNum);
+ }
+
+ console.log('[MP4Hydra] No streaming links found');
+ return [];
+ }
+ } catch (error) {
+ console.error(`[MP4Hydra] Error fetching streams:`, error.message);
+ return [];
+ }
+}
+
+// Helper function to try with original title
+async function tryAlternativeTitle(details, mediaType, seasonNum, episodeNum) {
+ try {
+ console.log(`[MP4Hydra] Retrying with original title: ${details.original_title}`);
+ const originalSlug = generateSlug(details.original_title);
+ let originalFullSlug = originalSlug;
+
+ if (mediaType === 'movie' && details.year) {
+ originalFullSlug = `${originalSlug}-${details.year}`;
+ }
+
+ // Create new form data with original title
+ const formData = new FormData();
+ formData.append('v', '8');
+ formData.append('z', JSON.stringify([{
+ s: originalFullSlug,
+ t: mediaType,
+ se: seasonNum,
+ ep: episodeNum
+ }]));
+
+ const response = await axios({
+ method: 'post',
+ url: 'https://mp4hydra.org/info2?v=8',
+ data: formData,
+ headers: {
+ ...formData.getHeaders(),
+ 'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Mobile Safari/537.36',
+ 'Accept': '*/*',
+ 'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8',
+ 'Origin': 'https://mp4hydra.org',
+ 'Referer': `https://mp4hydra.org/${mediaType}/${originalFullSlug}`,
+ 'Sec-Fetch-Dest': 'empty',
+ 'Sec-Fetch-Mode': 'cors',
+ 'Sec-Fetch-Site': 'same-origin'
+ },
+ timeout: 10000
+ });
+
+ // Process response
+ if (response.data && response.data.playlist && response.data.playlist.length > 0) {
+ const playlist = response.data.playlist;
+ const servers = response.data.servers;
+
+ console.log(`[MP4Hydra] Found ${playlist.length} videos with original title`);
+
+ // For TV shows, find the specific episode
+ if (mediaType === 'tv' && seasonNum && episodeNum) {
+ const paddedSeason = seasonNum.toString().padStart(2, '0');
+ const paddedEpisode = episodeNum.toString().padStart(2, '0');
+ const seasonEpisode = `S${paddedSeason}E${paddedEpisode}`;
+
+ const targetEpisode = playlist.find(item =>
+ item.title && item.title.toUpperCase() === seasonEpisode.toUpperCase()
+ );
+
+ if (!targetEpisode) {
+ console.log(`[MP4Hydra] Could not find ${seasonEpisode} with original title`);
+ return [];
+ }
+
+ // Process streams from main servers
+ const streams = [];
+ const serverConfig = [
+ { name: 'Beta', number: '#1' },
+ { name: 'Beta#3', number: '#2' }
+ ];
+
+ serverConfig.forEach(server => {
+ const serverName = server.name;
+ const serverNumber = server.number;
+
+ if (servers[serverName]) {
+ const baseServer = servers[serverName];
+ console.log(`[MP4Hydra] Processing server: ${serverName} (${baseServer})`);
+
+ const processedEpisode = processEpisode(targetEpisode, baseServer, serverName, serverNumber);
+
+ // Convert to standard stream format
+ streams.push({
+ title: `${details.original_title} - ${seasonEpisode} - ${processedEpisode.quality} [MP4Hydra ${serverNumber}]`,
+ url: processedEpisode.videoUrl,
+ quality: processedEpisode.quality,
+ provider: "MP4Hydra",
+ size: "Unknown size",
+ behaviorHints: {
+ notWebReady: true,
+ headers: {
+ 'Referer': 'https://mp4hydra.org/'
+ }
+ }
+ });
+
+ // Add subtitle tracks if available
+ if (processedEpisode.subtitles && processedEpisode.subtitles.length > 0) {
+ streams[streams.length - 1].subtitles = processedEpisode.subtitles.map(sub => ({
+ url: sub.url,
+ lang: sub.label
+ }));
+ }
+ }
+ });
+
+ return streams;
+ }
+
+ // For movies, process all videos
+ const streams = [];
+ const serverConfig = [
+ { name: 'Beta', number: '#1' },
+ { name: 'Beta#3', number: '#2' }
+ ];
+
+ serverConfig.forEach(server => {
+ const serverName = server.name;
+ const serverNumber = server.number;
+
+ if (servers[serverName]) {
+ const baseServer = servers[serverName];
+ console.log(`[MP4Hydra] Processing server: ${serverName} (${baseServer})`);
+
+ playlist.forEach(item => {
+ const processedItem = processEpisode(item, baseServer, serverName, serverNumber);
+
+ // Convert to standard stream format
+ streams.push({
+ title: `${details.original_title} - ${processedItem.quality} [MP4Hydra ${serverNumber}]`,
+ url: processedItem.videoUrl,
+ quality: processedItem.quality,
+ provider: "MP4Hydra",
+ size: "Unknown size",
+ behaviorHints: {
+ notWebReady: true,
+ headers: {
+ 'Referer': 'https://mp4hydra.org/'
+ }
+ }
+ });
+
+ // Add subtitle tracks if available
+ if (processedItem.subtitles && processedItem.subtitles.length > 0) {
+ streams[streams.length - 1].subtitles = processedItem.subtitles.map(sub => ({
+ url: sub.url,
+ lang: sub.label
+ }));
+ }
+ });
+ }
+ });
+
+ return streams;
+ }
+
+ return [];
+ } catch (error) {
+ console.error(`[MP4Hydra] Error with alternative title:`, error.message);
+ return [];
+ }
+}
+
+// Helper function to try without year
+async function tryWithoutYear(details, mediaType, seasonNum, episodeNum) {
+ try {
+ console.log(`[MP4Hydra] Retrying with title only (without year): ${details.title}`);
+ const titleOnlySlug = details.slug;
+
+ // Create new form data with title only
+ const formData = new FormData();
+ formData.append('v', '8');
+ formData.append('z', JSON.stringify([{
+ s: titleOnlySlug,
+ t: mediaType,
+ se: seasonNum,
+ ep: episodeNum
+ }]));
+
+ const response = await axios({
+ method: 'post',
+ url: 'https://mp4hydra.org/info2?v=8',
+ data: formData,
+ headers: {
+ ...formData.getHeaders(),
+ 'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Mobile Safari/537.36',
+ 'Accept': '*/*',
+ 'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8',
+ 'Origin': 'https://mp4hydra.org',
+ 'Referer': `https://mp4hydra.org/${mediaType}/${titleOnlySlug}`,
+ 'Sec-Fetch-Dest': 'empty',
+ 'Sec-Fetch-Mode': 'cors',
+ 'Sec-Fetch-Site': 'same-origin'
+ },
+ timeout: 10000
+ });
+
+ // Process response
+ if (response.data && response.data.playlist && response.data.playlist.length > 0) {
+ const playlist = response.data.playlist;
+ const servers = response.data.servers;
+
+ console.log(`[MP4Hydra] Found ${playlist.length} videos with title only`);
+
+ // For movies, process all videos
+ const streams = [];
+ const serverConfig = [
+ { name: 'Beta', number: '#1' },
+ { name: 'Beta#3', number: '#2' }
+ ];
+
+ serverConfig.forEach(server => {
+ const serverName = server.name;
+ const serverNumber = server.number;
+
+ if (servers[serverName]) {
+ const baseServer = servers[serverName];
+ console.log(`[MP4Hydra] Processing server: ${serverName} (${baseServer})`);
+
+ playlist.forEach(item => {
+ const processedItem = processEpisode(item, baseServer, serverName, serverNumber);
+
+ // Convert to standard stream format
+ streams.push({
+ title: `${details.title} - ${processedItem.quality} [MP4Hydra ${serverNumber}]`,
+ url: processedItem.videoUrl,
+ quality: processedItem.quality,
+ provider: "MP4Hydra",
+ size: "Unknown size",
+ behaviorHints: {
+ notWebReady: true,
+ headers: {
+ 'Referer': 'https://mp4hydra.org/'
+ }
+ }
+ });
+
+ // Add subtitle tracks if available
+ if (processedItem.subtitles && processedItem.subtitles.length > 0) {
+ streams[streams.length - 1].subtitles = processedItem.subtitles.map(sub => ({
+ url: sub.url,
+ lang: sub.label
+ }));
+ }
+ });
+ }
+ });
+
+ return streams;
+ }
+
+ return [];
+ } catch (error) {
+ console.error(`[MP4Hydra] Error with title-only:`, error.message);
+ return [];
+ }
+}
+
+// Helper function to get TMDB details
+async function getTMDBDetails(tmdbId, mediaType) {
+ const { getTmdbApiKey } = require('../utils/tmdbKey');
+ const TMDB_API_KEY = getTmdbApiKey();
+ if(!TMDB_API_KEY){
+ console.warn('[MP4Hydra] TMDB API key missing; skipping TMDB metadata fetch');
+ return null;
+ }
+
+ try {
+ console.log(`[MP4Hydra] Fetching ${mediaType} details for TMDB ID: ${tmdbId}`);
+ const response = await axios.get(`https://api.themoviedb.org/3/${mediaType}/${tmdbId}?api_key=${TMDB_API_KEY}`);
+
+ if (mediaType === 'movie') {
+ return {
+ title: response.data.title,
+ original_title: response.data.original_title,
+ year: response.data.release_date ? response.data.release_date.split('-')[0] : null,
+ slug: generateSlug(response.data.title)
+ };
+ } else {
+ return {
+ title: response.data.name,
+ original_title: response.data.original_name,
+ year: response.data.first_air_date ? response.data.first_air_date.split('-')[0] : null,
+ slug: generateSlug(response.data.name)
+ };
+ }
+ } catch (error) {
+ console.error(`[MP4Hydra] Error fetching details from TMDB:`, error.message);
+ return null;
+ }
+}
+
+module.exports = { getMP4HydraStreams };
\ No newline at end of file
diff --git a/providers/Showbox.js b/providers/Showbox.js
new file mode 100644
index 0000000..dc38020
--- /dev/null
+++ b/providers/Showbox.js
@@ -0,0 +1,3139 @@
+require('dotenv').config();
+console.log(`Current DISABLE_CACHE value: '${process.env.DISABLE_CACHE}' (Type: ${typeof process.env.DISABLE_CACHE})`);
+const axios = require('axios');
+const cheerio = require('cheerio');
+const fs = require('fs').promises;
+const path = require('path');
+const crypto = require('crypto');
+// Redis removed: all caching now uses filesystem only.
+
+// --- Cookie Management --- (removed unused cookieIndex/detectedOssGroup)
+
+
+// Add configurable default region
+const DEFAULT_OSS_REGION = process.env.FEBBOX_REGION || 'USA7';
+console.log(`Using FebBox region setting: ${DEFAULT_OSS_REGION}`);
+
+// Global variable to store the user's region preference from the request
+global.currentRequestRegionPreference = null;
+
+// Add a global variable to track region availability
+global.regionAvailabilityStatus = {};
+const US_FALLBACK_REGIONS = ['USA7', 'USA6', 'USA5']; // Prioritized US regions for fallback
+
+// Modify the getCookieForRequest function to handle region fallbacks
+// Quota-aware cookie selection: if global.currentRequestConfig.cookies exists (array),
+// select the best cookie by querying flow from FebBox and choosing the highest remaining.
+// Fallback to existing single-cookie/rotation behavior.
+const getCookieForRequest = async (regionPreference = null, userCookie = null) => {
+ let detectedOssGroup = null;
+ const originalRegion = regionPreference;
+ let usingFallback = false;
+ let baseCookieToUse = null;
+
+ // Region detection
+ if (regionPreference) {
+ if (global.regionAvailabilityStatus && global.regionAvailabilityStatus[regionPreference] === false) {
+ usingFallback = true;
+ for (const fallback of US_FALLBACK_REGIONS) {
+ if (!global.regionAvailabilityStatus || global.regionAvailabilityStatus[fallback] !== false) {
+ detectedOssGroup = fallback;
+ console.log(`[CookieManager] Region ${regionPreference} unavailable, fallback to ${detectedOssGroup}`);
+ break;
+ }
+ }
+ if (!detectedOssGroup) {
+ detectedOssGroup = regionPreference;
+ console.log(`[CookieManager] All fallbacks unavailable, trying original ${detectedOssGroup}`);
+ }
+ } else {
+ detectedOssGroup = regionPreference;
+ console.log(`[CookieManager] Using explicit region: ${detectedOssGroup}`);
+ }
+ } else {
+ detectedOssGroup = DEFAULT_OSS_REGION;
+ console.log(`[CookieManager] No region preference; defaulting to ${detectedOssGroup}`);
+ }
+
+ global.lastRequestedRegion = { original: originalRegion, used: detectedOssGroup, usingFallback };
+
+ // Select cookie (simplified legacy logic retained)
+ if (!baseCookieToUse && global.currentRequestConfig) {
+ try {
+ const array = Array.isArray(global.currentRequestConfig.cookies) ? global.currentRequestConfig.cookies.filter(Boolean) : [];
+ if (array.length > 0) {
+ // Just pick first for now (quota logic removed here if previously elsewhere)
+ baseCookieToUse = array[0];
+ }
+ } catch (e) {
+ console.warn(`[CookieManager] Cookie array selection error: ${e.message}`);
+ }
+ }
+
+ // Check if a base cookie has already been chosen and cached for this specific request cycle
+ if (global.currentRequestConfig && global.currentRequestConfig.chosenFebboxBaseCookieForRequest) {
+ console.log(`[CookieManager] Re-using request-cached base cookie for this cycle.`);
+ baseCookieToUse = global.currentRequestConfig.chosenFebboxBaseCookieForRequest;
+ } else if (!baseCookieToUse) {
+ // No request-cached cookie, so we need to select one.
+ // 1. Prioritize user-supplied cookie passed directly to this function
+ if (userCookie) {
+ console.log('[CookieManager] Using user-supplied cookie passed to function for this cycle.');
+ baseCookieToUse = userCookie;
+ }
+ // 2. Prioritize user-supplied cookie from global (fallback for backward compatibility)
+ else if (global.currentRequestUserCookie) {
+ console.log('[CookieManager] Using user-supplied cookie from global state (legacy mode) for this cycle.');
+ baseCookieToUse = global.currentRequestUserCookie;
+ }
+ // No file-based fallback rotation (env-only)
+ else {
+ console.log('[CookieManager] No user-supplied cookies available for this cycle.');
+ baseCookieToUse = '';
+ }
+
+ // Cache the chosen base cookie for this request cycle
+ if (global.currentRequestConfig) {
+ global.currentRequestConfig.chosenFebboxBaseCookieForRequest = baseCookieToUse;
+ console.log(`[CookieManager] Cached base cookie for this request cycle.`);
+ }
+ }
+
+ // Now, apply the detected OSS group to the chosen base cookie
+ if (baseCookieToUse && baseCookieToUse.trim() !== '') {
+ if (detectedOssGroup) {
+ console.log(`[CookieManager] Applying region: ${detectedOssGroup} to chosen base cookie.`);
+ return `${baseCookieToUse}; oss_group=${detectedOssGroup}`;
+ }
+ return baseCookieToUse; // Return base cookie if no region detected/needed
+ } else {
+ if (detectedOssGroup) return `oss_group=${detectedOssGroup}`;
+ return '';
+ }
+};
+
+// Helper function to fetch stream size using a HEAD request
+const fetchStreamSize = async (url) => {
+ const cacheSubDir = 'stream_sizes';
+ // Create a cache key from the URL using hash to avoid long filenames
+ const urlHash = crypto.createHash('md5').update(url).digest('hex');
+ const urlCacheKey = `${urlHash}.txt`;
+
+ const cachedSize = await getFromCache(urlCacheKey, cacheSubDir);
+ if (cachedSize !== null) { // Check for null specifically, as 'Unknown size' is a valid cached string
+ // console.log(` CACHE HIT for stream size: ${url} -> ${cachedSize}`);
+ return cachedSize;
+ }
+ // console.log(` CACHE MISS for stream size: ${url}`);
+
+ try {
+ // For m3u8, Content-Length is for the playlist file, not the stream segments.
+ if (url.toLowerCase().includes('.m3u8')) {
+ return 'Playlist (size N/A)'; // Indicate HLS playlist
+ }
+ const response = await axios.head(url, { timeout: 5000 }); // 5-second timeout for HEAD request
+ if (response.headers['content-length']) {
+ const sizeInBytes = parseInt(response.headers['content-length'], 10);
+ if (!isNaN(sizeInBytes)) {
+ if (sizeInBytes < 1024) return `${sizeInBytes} B`;
+ if (sizeInBytes < 1024 * 1024) return `${(sizeInBytes / 1024).toFixed(2)} KB`;
+ if (sizeInBytes < 1024 * 1024 * 1024) return `${(sizeInBytes / (1024 * 1024)).toFixed(2)} MB`;
+ return `${(sizeInBytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
+ }
+ }
+ return 'Unknown size';
+ } catch (error) {
+ // console.warn(` Could not fetch size for ${url}: ${error.message}`);
+ // Cache the error/unknown result too, to prevent re-fetching a known problematic URL quickly
+ await saveToCache(urlCacheKey, 'Unknown size', cacheSubDir);
+ return 'Unknown size';
+ }
+};
+
+const FEBBOX_PLAYER_URL = "https://www.febbox.com/file/player";
+const FEBBOX_FILE_SHARE_LIST_URL = "https://www.febbox.com/file/file_share_list";
+// MODIFICATION: Remove SCRAPER_API_URL
+// const SCRAPER_API_URL = 'https://api.scraperapi.com/';
+// TMDB key now sourced from config/env; no hardcoded public key
+const { getTmdbApiKey } = require('../utils/tmdbKey');
+function obtainTmdbKey(){
+ const k = getTmdbApiKey();
+ if(!k) console.warn('[Showbox] No TMDB API key available (multi-key set empty).');
+ return k;
+}
+const TMDB_BASE_URL = 'https://api.themoviedb.org/3';
+// Determine cache directory based on environment
+// Use /tmp/.cache when running on Vercel, otherwise use local .cache directory
+// Allow external override to keep cache writes out of watched tree during dev
+const CACHE_DIR = process.env.SHOWBOX_CACHE_DIR
+ ? process.env.SHOWBOX_CACHE_DIR
+ : (process.env.VERCEL ? path.join('/tmp', '.cache') : path.join(require('os').tmpdir(), 'tmdb-embed-showbox-cache'));
+console.log(`Using cache directory: ${CACHE_DIR}`);
+// MODIFICATION: Remove hardcoded SHOWBOX_PROXY_URL, will use environment variable
+// const SHOWBOX_PROXY_URL = "https://starlit-valkyrie-39f5ab.netlify.app/?destination=";
+
+// Ensure cache directories exist
+const ensureCacheDir = async (dirPath) => {
+ try {
+ await fs.mkdir(dirPath, { recursive: true });
+ } catch (error) {
+ if (error.code !== 'EEXIST') {
+ console.warn(`Warning: Could not create cache directory ${dirPath}: ${error.message}`);
+ }
+ }
+};
+
+// Cache helpers
+const getFromCache = async (cacheKey, subDir = '') => {
+ if (process.env.DISABLE_CACHE === 'true') {
+ console.log(` CACHE DISABLED: Skipping read for ${path.join(subDir, cacheKey)}`);
+ return null;
+ }
+
+ // File system cache only (Redis removed)
+ const cachePath = path.join(CACHE_DIR, subDir, cacheKey);
+ try {
+ const fileData = await fs.readFile(cachePath, 'utf-8');
+ console.log(` FILE SYSTEM CACHE HIT for: ${path.join(subDir, cacheKey)}`);
+ // Redis removed: no cross-population
+ try {
+ return JSON.parse(fileData);
+ } catch (e) {
+ return fileData; // Return as string if not JSON
+ }
+ } catch (error) {
+ if (error.code !== 'ENOENT') {
+ console.warn(` FILE SYSTEM CACHE READ ERROR for ${cacheKey}: ${error.message}`);
+ } else {
+ console.log(` FILE SYSTEM CACHE MISS for: ${path.join(subDir, cacheKey)}`);
+ }
+ return null;
+ }
+};
+
+const saveToCache = async (cacheKey, content, subDir = '') => {
+ if (process.env.DISABLE_CACHE === 'true') {
+ console.log(` CACHE DISABLED: Skipping write for ${path.join(subDir, cacheKey)}`);
+ return;
+ }
+
+ const dataToSave = typeof content === 'string' ? content : JSON.stringify(content, null, 2);
+ // Save to file system cache
+ const fullSubDir = path.join(CACHE_DIR, subDir);
+ await ensureCacheDir(fullSubDir);
+ const cachePath = path.join(fullSubDir, cacheKey);
+ try {
+ await fs.writeFile(cachePath, dataToSave, 'utf-8');
+ console.log(` SAVED TO FILE SYSTEM CACHE: ${path.join(subDir, cacheKey)}`);
+ } catch (error) {
+ console.warn(` FILE SYSTEM CACHE WRITE ERROR for ${cacheKey}: ${error.message}`);
+ }
+};
+
+// NEW HELPER FUNCTIONS
+
+// Function to create URL-friendly slugs
+const slugify = (text) => {
+ if (!text) return '';
+ return text
+ .toString()
+ .toLowerCase()
+ .trim()
+ .replace(/&/g, 'and') // Replace & with 'and'
+ .replace(/[_\s]+/g, '-') // Replace spaces and underscores with -
+ .replace(/[^\w-]+/g, '') // Remove all non-word chars (except -)
+ .replace(/--+/g, '-') // Replace multiple - with single -
+ .replace(/^-+/, '') // Trim - from start of text
+ .replace(/-+$/, ''); // Trim - from end of text
+};
+
+// Function to normalize titles for comparison
+const normalizeTitleForComparison = (title) => {
+ if (!title) return '';
+ // Remove common season/episode patterns, year in parenthesis, and normalize
+ return title
+ .toLowerCase()
+ .replace(/\(?\d{4}\)?$/, '') // Remove year like (2023) at the end
+ .replace(/\s*-\s*(season|s)\s*\d+\s*(episode|e)\s*\d+/i, '') // Remove SXXEXX patterns
+ .replace(/\s*(season|s)\s*\d+/i, '') // Remove SXX patterns
+ .replace(/\s*(episode|e)\s*\d+/i, '') // Remove EXX patterns
+ .replace(/[^\w\s]|_/g, "") // Remove punctuation except spaces
+ .replace(/\s+/g, ' ') // Normalize multiple spaces to one
+ .trim();
+};
+
+// Function to validate if a ShowBox page title matches TMDB titles
+const validateShowboxTitle = (showboxPageTitle, tmdbMainTitle, tmdbOriginalTitle, tmdbAlternativeTitles = []) => {
+ if (!showboxPageTitle || !tmdbMainTitle) {
+ console.log(` [Validation] Missing titles. SB: "${showboxPageTitle}", TMDB Main: "${tmdbMainTitle}"`);
+ return false;
+ }
+
+ const normalizedPageTitle = normalizeTitleForComparison(showboxPageTitle);
+
+ // Collect all TMDB titles for comparison (main, original, alternatives)
+ const titlesToCompare = [tmdbMainTitle, tmdbOriginalTitle, ...tmdbAlternativeTitles.map(alt => alt.title)]
+ .filter(Boolean) // Remove any null/undefined titles
+ .map(normalizeTitleForComparison); // Normalize all titles
+
+ // Check for exact matches
+ if (titlesToCompare.some(normTmdbTitle => normalizedPageTitle === normTmdbTitle && normTmdbTitle.length > 0)) {
+ console.log(` [Validation] SUCCESS: Exact match. SB: "${normalizedPageTitle}" == TMDB: One of "${titlesToCompare.filter(t => t.length > 0).join('", "')}"`);
+ return true;
+ }
+
+ // Check for partial matches (e.g., "Title" in "Title: The Series" or vice versa)
+ if (titlesToCompare.some(normTmdbTitle =>
+ normTmdbTitle.length > 3 && normalizedPageTitle.length > 3 && // ensure titles aren't too short
+ (normalizedPageTitle.includes(normTmdbTitle) || normTmdbTitle.includes(normalizedPageTitle))
+ )) {
+ console.log(` [Validation] SUCCESS: Partial match. SB: "${normalizedPageTitle}" vs TMDB: One of "${titlesToCompare.filter(t => t.length > 0).join('", "')}"`);
+ return true;
+ }
+
+ console.log(` [Validation] FAILED: No strong match. SB: "${normalizedPageTitle}" vs TMDB Titles: "${titlesToCompare.filter(t => t.length > 0).join('", "')}"`);
+ return false;
+};
+
+// NEW HELPER FUNCTION: Extract TMDB image path from ShowBox detail page HTML
+const extractTmdbImagePathFromShowboxHtml = (htmlContent) => {
+ if (!htmlContent) return null;
+ // Log the beginning of the HTML content for debugging
+ console.log(` [ImageExtract DEBUG] HTML content (first 500 chars): ${String(htmlContent).substring(0, 500)}`);
+ try {
+ const $ = cheerio.load(htmlContent);
+ const coverDiv = $('div.cover_follow');
+ if (coverDiv.length) {
+ const styleAttr = coverDiv.attr('style');
+ console.log(` [ImageExtract DEBUG] Found div.cover_follow. Style attribute: ${styleAttr}`); // Log the style attribute
+ if (styleAttr) {
+ // MODIFIED REGEX: Made " optional
+ const urlMatch = styleAttr.match(/url\((?:")?(https?:\/\/image\.tmdb\.org\/t\/p\/original)?([^&]+?)(?:")?\)/);
+ if (urlMatch && urlMatch[2]) {
+ // Ensure it's a path, not a full URL if accidentally captured
+ const imagePath = urlMatch[2].startsWith('/') ? urlMatch[2] : '/' + urlMatch[2];
+ console.log(` [ImageExtract] Extracted TMDB image path from ShowBox HTML: ${imagePath}`);
+ return imagePath;
+ }
+ }
+ }
+ } catch (e) {
+ console.error(` [ImageExtract] Error parsing ShowBox HTML for TMDB image: ${e.message}`);
+ }
+ console.log(` [ImageExtract] Could not find TMDB image path in ShowBox HTML.`);
+ return null;
+};
+
+// NEW HELPER FUNCTION: Validate ShowBox TMDB image path against TMDB API backdrop paths
+const validateTmdbImage = (showboxImagePath, tmdbApiBackdropPaths = []) => {
+ if (!showboxImagePath || !tmdbApiBackdropPaths || tmdbApiBackdropPaths.length === 0) {
+ return false;
+ }
+ const match = tmdbApiBackdropPaths.some(apiPath => apiPath === showboxImagePath);
+ if (match) {
+ console.log(` [ImageValidation] SUCCESS: ShowBox image path "${showboxImagePath}" matches a TMDB API backdrop path.`);
+ } else {
+ console.log(` [ImageValidation] FAILED: ShowBox image path "${showboxImagePath}" does not match any of TMDB API backdrop paths (${tmdbApiBackdropPaths.slice(0, 3).join(', ')}...).`);
+ }
+ return match;
+};
+
+
+
+// Function to extract special title forms for anime (e.g., Romaji)
+const extractSpecialTitles = (tmdbData, alternativeTitles = []) => {
+ const specialTitles = [];
+ console.log(` [TITLE] Alternative titles available: ${alternativeTitles.length}`);
+ if (alternativeTitles.length > 0) {
+ console.log(` [TITLE] Available alternatives: ${alternativeTitles.map(t => `"${t.title}" (${t.iso_3166_1 || 'unknown'}-${t.iso_639_1 || 'unknown'})`).join(', ')}`);
+ }
+
+ // Get original title
+ const originalTitle = tmdbData.original_title || tmdbData.original_name || '';
+ const originalLanguage = tmdbData.original_language || '';
+
+ // Check if original title uses non-Latin script
+ // This regex covers most non-Latin scripts: CJK (Chinese, Japanese, Korean), Arabic, Cyrillic, etc.
+ const hasNonLatinChars = /[\u0400-\u04FF\u0500-\u052F\u1100-\u11FF\u3000-\u303F\u3040-\u309F\u30A0-\u30FF\u3130-\u318F\u31F0-\u31FF\u3400-\u4DBF\u4E00-\u9FFF\uAC00-\uD7AF\uF900-\uFAFF\uFF00-\uFFEF]/.test(originalTitle);
+
+ if (hasNonLatinChars) {
+ console.log(` [ROMAN] Detected non-Latin title: "${originalTitle}" (Language: ${originalLanguage}). Looking for Romanized version.`);
+
+ // Get language name for better logging
+ const languageNames = {
+ 'ko': 'Korean',
+ 'ja': 'Japanese',
+ 'zh': 'Chinese',
+ 'ru': 'Russian',
+ 'ar': 'Arabic',
+ 'th': 'Thai',
+ 'hi': 'Hindi'
+ // Add more as needed
+ };
+ const languageName = languageNames[originalLanguage] || originalLanguage;
+
+ // STEP 1: Try to find explicitly labeled romanized titles
+ const romanizedCandidates = alternativeTitles.filter(alt =>
+ // Any alt title labeled as "Romanized" or has "Romaji"/"Romanization" in type
+ (alt.type && (
+ alt.type.toLowerCase().includes('roman') ||
+ alt.type.toLowerCase().includes('romaji')
+ )) ||
+ // Special case: original language country code with Latin script
+ (alt.iso_3166_1 === originalLanguage.toUpperCase() &&
+ /^[a-zA-Z0-9\s\-:;,.!?()&'"]+$/.test(alt.title) &&
+ alt.iso_639_1 !== 'en')
+ );
+
+ if (romanizedCandidates.length > 0) {
+ romanizedCandidates.forEach(rc => {
+ console.log(` [ROMAN] Found labeled Romanized title: "${rc.title}" (${rc.iso_3166_1 || 'unknown'}-${rc.iso_639_1 || 'unknown'}${rc.type ? ', Type: ' + rc.type : ''})`);
+ specialTitles.push(rc.title);
+ });
+ } else {
+ console.log(` [ROMAN] No explicitly labeled Romanized titles found in alternatives.`);
+
+ // STEP 2: Identify Romanized by language and character set
+ // For non-Latin scripts, look for titles that:
+ // 1. Use Latin script
+ // 2. Are from the same country/language (if available)
+ // 3. Are not English
+ const nonEnglishLatinTitles = alternativeTitles.filter(alt =>
+ // Must use Latin script
+ /^[a-zA-Z0-9\s\-:;,.!?()&'"]+$/.test(alt.title) &&
+ // Should not be English if we can determine it
+ (alt.iso_639_1 !== 'en' || !alt.iso_639_1)
+ );
+
+ // Try to find titles from the same country/region first
+ const sameRegionTitles = nonEnglishLatinTitles.filter(alt =>
+ alt.iso_3166_1 &&
+ (alt.iso_3166_1 === originalLanguage.toUpperCase() ||
+ // Special case for languages that don't map directly to country codes
+ (originalLanguage === 'zh' && ['CN', 'TW', 'HK'].includes(alt.iso_3166_1)) ||
+ (originalLanguage === 'ja' && alt.iso_3166_1 === 'JP') ||
+ (originalLanguage === 'ko' && alt.iso_3166_1 === 'KR'))
+ );
+
+ if (sameRegionTitles.length > 0) {
+ sameRegionTitles.forEach(title => {
+ console.log(` [ROMAN] Found likely ${languageName} Romanized title: "${title.title}" (matched region)`);
+ specialTitles.push(title.title);
+ });
+ } else if (nonEnglishLatinTitles.length > 0) {
+ // If no same-region titles, try any non-English Latin title
+ // Prefer longer titles as they're often more descriptive/accurate
+ nonEnglishLatinTitles.sort((a, b) => b.title.length - a.title.length);
+ const bestCandidate = nonEnglishLatinTitles[0];
+ console.log(` [ROMAN] Using best non-English Latin title as Romanized version: "${bestCandidate.title}"`);
+ specialTitles.push(bestCandidate.title);
+ } else {
+ // STEP 3: Language-specific fallbacks based on patterns
+ // For Korean: Look for titles with particles like "-eui", "-ui", "-ga", "-reul", etc.
+ // For Japanese: Look for titles with particles like "no", "ga", "wo", "ni", etc.
+ // For Chinese: Look for titles with pinyin patterns
+
+ const languagePatterns = {
+ 'ko': /\b(ui|eui|ga|reul|neun|eun|leul|seo|e|ro)\b/i, // Korean particles
+ 'ja': /\b(no|ga|wo|ni|to|wa|ka|he|mo|de|kun|san|chan|sama|sensei)\b/i, // Japanese particles
+ 'zh': /\b(de|le|ba|ma|ne|ge|zai|shi)\b/i // Common Mandarin particles
+ };
+
+ if (languagePatterns[originalLanguage]) {
+ const patternMatches = alternativeTitles.filter(alt =>
+ // Must use Latin script
+ /^[a-zA-Z0-9\s\-:;,.!?()&'"]+$/.test(alt.title) &&
+ // Should match language pattern
+ languagePatterns[originalLanguage].test(alt.title.toLowerCase())
+ );
+
+ if (patternMatches.length > 0) {
+ patternMatches.forEach(match => {
+ console.log(` [ROMAN] Found likely ${languageName} Romanized title: "${match.title}" (matched language particles)`);
+ specialTitles.push(match.title);
+ });
+ } else {
+ console.log(` [ROMAN] No titles matching ${languageName} language patterns found.`);
+
+ // STEP 4: Last resort - use any longer alternative title in Latin script
+ const latinTitles = alternativeTitles.filter(alt =>
+ /^[a-zA-Z0-9\s\-:;,.!?()&'"]+$/.test(alt.title)
+ );
+
+ if (latinTitles.length > 0) {
+ // Prefer longer titles as they're often the romanized version
+ latinTitles.sort((a, b) => b.title.length - a.title.length);
+ const longestLatin = latinTitles[0];
+ console.log(` [ROMAN] Using longest Latin script title as fallback: "${longestLatin.title}"`);
+ specialTitles.push(longestLatin.title);
+ } else {
+ console.log(` [ROMAN] Could not find any suitable Romanized alternative for "${originalTitle}"`);
+ }
+ }
+ } else {
+ // For languages without specific patterns, just use the longest Latin title
+ const latinTitles = alternativeTitles.filter(alt =>
+ /^[a-zA-Z0-9\s\-:;,.!?()&'"]+$/.test(alt.title)
+ );
+
+ if (latinTitles.length > 0) {
+ // Prefer longer titles as they're often the romanized version
+ latinTitles.sort((a, b) => b.title.length - a.title.length);
+ const longestLatin = latinTitles[0];
+ console.log(` [ROMAN] Using longest Latin script title for ${languageName}: "${longestLatin.title}"`);
+ specialTitles.push(longestLatin.title);
+ } else {
+ console.log(` [ROMAN] Could not find any suitable Romanized alternative for "${originalTitle}"`);
+ }
+ }
+ }
+ }
+ } else if (originalLanguage && originalLanguage !== 'en') {
+ // For Latin-script non-English titles, still check for alternative titles
+ console.log(` [TITLE] Original title already uses Latin script: "${originalTitle}" (${originalLanguage})`);
+
+ // Some Latin-script languages might have alternative spellings/titles worth trying
+ const nonEnglishAlts = alternativeTitles.filter(alt =>
+ alt.iso_639_1 && alt.iso_639_1 !== 'en' && alt.title !== originalTitle
+ );
+
+ if (nonEnglishAlts.length > 0) {
+ nonEnglishAlts.forEach(alt => {
+ console.log(` [TITLE] Adding non-English alternative title: "${alt.title}"`);
+ specialTitles.push(alt.title);
+ });
+ }
+ }
+
+ return specialTitles;
+};
+
+// NEW FUNCTION: Search ShowBox and extract the most relevant URL
+const _searchAndExtractShowboxUrl = async (searchTerm, originalTmdbTitle, mediaYear, showboxScraperInstance, tmdbType, regionPreference = null, tmdbAllTitles = []) => {
+ const cacheSubDir = 'showbox_search_results';
+
+ // mediaTypeString removed (was unused after scoring refactor)
+
+ // Add a cache version to invalidate previous incorrect cached results
+ const CACHE_VERSION = "v15"; // Increment this whenever the search algorithm significantly changes
+
+ // Create a proper hash for the cache key to avoid filename issues with special characters
+ const cacheKeyData = `${CACHE_VERSION}_${tmdbType}_${originalTmdbTitle}_${mediaYear || 'noYear'}`;
+ const cacheKeyHash = crypto.createHash('md5').update(cacheKeyData).digest('hex');
+ const searchTermKey = `${cacheKeyHash}.txt`;
+
+ // Log what we're looking for to help with debugging
+ console.log(` Searching for ShowBox match for: "${originalTmdbTitle}" (${mediaYear || 'N/A'}) [Cache key: ${cacheKeyHash}]`);
+
+ // Check if DISABLE_CACHE is set to 'true'
+ if (process.env.DISABLE_CACHE !== 'true') {
+ const cachedResult = await getFromCache(searchTermKey, cacheSubDir);
+ if (cachedResult) {
+ // Handle both old string format and new object format
+ if (typeof cachedResult === 'string') {
+ console.log(` CACHE HIT for ShowBox search best match URL (${originalTmdbTitle} ${mediaYear || ''}): ${cachedResult}`);
+ if (cachedResult === 'NO_MATCH_FOUND') return { url: null, score: -1 };
+ return { url: cachedResult, score: 10 };
+ } else if (cachedResult.result === 'NO_MATCH_FOUND') {
+ // For stream searches, always retry immediately - content availability can change anytime
+ console.log(` CACHE HIT: Previously no match found for ${originalTmdbTitle} ${mediaYear || ''}, but retrying immediately for fresh content.`);
+ // Continue to search logic below to retry immediately
+ } else {
+ console.log(` CACHE HIT for ShowBox search best match URL (${originalTmdbTitle} ${mediaYear || ''}): ${cachedResult}`);
+ return { url: cachedResult, score: 10 };
+ }
+ }
+ } else {
+ console.log(` Cache disabled, skipping cache check for ShowBox search.`);
+ }
+
+ // Special characters often cause search issues, create a cleaned version of the search term
+ // Replace special characters with spaces, ensure words are properly separated
+ const cleanedSearchTerm = searchTerm.replace(/[&\-_:;,.]/g, ' ').replace(/\s+/g, ' ').trim();
+ console.log(` Using cleaned search term: "${cleanedSearchTerm}" (Original: "${searchTerm}")`);
+
+ // Try multiple search strategies if needed
+ const searchStrategies = [];
+
+ // Track strategy effectiveness (could be persisted to disk in a production system)
+ // Higher priority strategies should be tried first
+ const STRATEGY_PRIORITIES = {
+ "original_with_year": 10,
+ "cleaned_with_year": 9,
+ "special_title_with_year": 8,
+ "original_only": 7,
+ "and_replacement_with_year": 6,
+ "first_part_with_year": 5,
+ "alternative_with_year": 4,
+ "alternative_only": 3,
+ "first_word_with_year": 2,
+ "year_only": 1
+ };
+
+ // STRATEGY 1: Original TMDB title with year (highest priority)
+ if (mediaYear) {
+ searchStrategies.push({
+ term: `${originalTmdbTitle} ${mediaYear}`,
+ description: "original TMDB title with year",
+ priority: STRATEGY_PRIORITIES.original_with_year
+ });
+ }
+
+ // STRATEGY 2: Cleaned search term with year
+ if (mediaYear) {
+ searchStrategies.push({
+ term: `${cleanedSearchTerm} ${mediaYear}`,
+ description: "cleaned search term with year",
+ priority: STRATEGY_PRIORITIES.cleaned_with_year
+ });
+ } else {
+ searchStrategies.push({
+ term: cleanedSearchTerm,
+ description: "cleaned search term",
+ priority: STRATEGY_PRIORITIES.cleaned_with_year
+ });
+ }
+
+ // STRATEGY 3: Special titles (like anime romanizations) with year
+ const specialTitlesFromAll = tmdbAllTitles.filter(title =>
+ title !== originalTmdbTitle &&
+ (title.length > originalTmdbTitle.length ||
+ /[\u0080-\uFFFF]/.test(originalTmdbTitle))
+ ).slice(0, 2);
+
+ specialTitlesFromAll.forEach((specialTitle, idx) => {
+ if (mediaYear) {
+ searchStrategies.push({
+ term: `${specialTitle} ${mediaYear}`,
+ description: `special title ${idx + 1} with year`,
+ priority: STRATEGY_PRIORITIES.special_title_with_year
+ });
+ }
+ });
+
+ // STRATEGY 4: Original TMDB title only
+ searchStrategies.push({
+ term: originalTmdbTitle,
+ description: "original TMDB title only",
+ priority: STRATEGY_PRIORITIES.original_only
+ });
+
+ // STRATEGY 5: For titles with "&", try "and" replacement
+ if (originalTmdbTitle.includes('&')) {
+ const andTitle = originalTmdbTitle.replace(/&/g, 'and');
+ if (mediaYear) {
+ searchStrategies.push({
+ term: `${andTitle} ${mediaYear}`,
+ description: "& replaced with 'and', with year",
+ priority: STRATEGY_PRIORITIES.and_replacement_with_year
+ });
+ }
+ }
+
+ // STRATEGY 6: First part before "&" with year
+ if (originalTmdbTitle.includes('&')) {
+ const firstPart = originalTmdbTitle.split('&')[0].trim();
+ if (firstPart.length > 3 && mediaYear) {
+ searchStrategies.push({
+ term: `${firstPart} ${mediaYear}`,
+ description: "first part before &, with year",
+ priority: STRATEGY_PRIORITIES.first_part_with_year
+ });
+ }
+ }
+
+ // STRATEGY 7-8: Alternative titles (limit to 2 alternatives to reduce API calls)
+ const limitedAlternatives = tmdbAllTitles
+ .filter(altTitle => altTitle && altTitle !== originalTmdbTitle)
+ .slice(0, 2);
+
+ limitedAlternatives.forEach((altTitle, index) => {
+ if (mediaYear) {
+ searchStrategies.push({
+ term: `${altTitle} ${mediaYear}`,
+ description: `alternative title ${index + 1} with year`,
+ priority: STRATEGY_PRIORITIES.alternative_with_year
+ });
+ }
+ searchStrategies.push({
+ term: altTitle,
+ description: `alternative title ${index + 1}`,
+ priority: STRATEGY_PRIORITIES.alternative_only
+ });
+ });
+
+ // STRATEGY 9: First word with year (for potentially shortened titles)
+ const titleWords = originalTmdbTitle.split(/\s+/);
+ if (titleWords.length > 1) {
+ const firstWord = titleWords[0];
+ if (firstWord.length > 3 && !searchStrategies.some(s => s.term === firstWord) && mediaYear) {
+ searchStrategies.push({
+ term: `${firstWord} ${mediaYear}`,
+ description: "first word of title with year",
+ priority: STRATEGY_PRIORITIES.first_word_with_year
+ });
+ }
+ }
+
+ // STRATEGY 10: Year only (last resort for popular movies)
+ if (mediaYear) {
+ searchStrategies.push({
+ term: mediaYear,
+ description: "year only (for popular movies)",
+ priority: STRATEGY_PRIORITIES.year_only
+ });
+ }
+
+ // Sort strategies by priority
+ searchStrategies.sort((a, b) => b.priority - a.priority);
+
+ // For debugging
+ console.log(` Search strategies in order of priority:`);
+ searchStrategies.forEach((strategy, idx) => {
+ console.log(` ${idx + 1}. ${strategy.description} (Priority: ${strategy.priority}): "${strategy.term}"`);
+ });
+
+ let bestResult = { url: null, score: -1, strategy: null };
+
+ // Generate all possible slugs from TMDB titles
+ const allPossibleSlugs = tmdbAllTitles.map(title => slugify(title)).filter(Boolean);
+ console.log(` Generated ${allPossibleSlugs.length} possible slugs for matching: ${allPossibleSlugs.join(', ')}`);
+
+ // Track strategy effectiveness
+ const strategyResults = {};
+
+ // Limit the number of strategies to try (to reduce API calls)
+ const MAX_STRATEGIES_TO_TRY = 5;
+ let strategiesAttempted = 0;
+
+ for (const strategy of searchStrategies) {
+ // Limit the number of strategies we try
+ if (strategiesAttempted >= MAX_STRATEGIES_TO_TRY) {
+ console.log(` Reached maximum number of search strategies (${MAX_STRATEGIES_TO_TRY}). Stopping search.`);
+ break;
+ }
+
+ strategiesAttempted++;
+ const searchUrl = `https://www.showbox.media/search?keyword=${encodeURIComponent(strategy.term)}`;
+ console.log(` Searching ShowBox with URL: ${searchUrl} (Strategy: ${strategy.description})`);
+
+ const htmlContent = await showboxScraperInstance._makeRequest(searchUrl);
+ if (!htmlContent) {
+ console.log(` Failed to fetch ShowBox search results for strategy: ${strategy.description}`);
+ // Track failed strategy
+ strategyResults[strategy.description] = { success: false, score: 0 };
+ continue; // Try next strategy
+ }
+
+ const $ = cheerio.load(htmlContent);
+ const searchResults = [];
+
+ // Helper for simple string similarity (case-insensitive, removes non-alphanumeric)
+ const simplifyString = (str) => str.toLowerCase().replace(/[^a-z0-9]/g, '');
+ const simplifiedTmdbTitle = simplifyString(originalTmdbTitle);
+
+ // Create normalized versions of all TMDB titles for comparison
+ const normalizedTmdbTitles = tmdbAllTitles.map(title => normalizeTitleForComparison(title));
+
+ $('div.film-poster').each((i, elem) => {
+ const linkElement = $(elem).find('a.film-poster-ahref');
+ const itemTitle = linkElement.attr('title');
+ const itemHref = linkElement.attr('href');
+
+ if (itemTitle && itemHref) {
+ const simplifiedItemTitle = simplifyString(itemTitle);
+ const normalizedItemTitle = normalizeTitleForComparison(itemTitle);
+
+ // Extract slug from URL
+ const urlSlugMatch = itemHref.match(/\/(movie|tv)\/([mt]-[a-z0-9-]+-\d{4})/);
+ const itemSlug = urlSlugMatch ? urlSlugMatch[2] : '';
+
+ // Check if the slug matches any of our generated slugs
+ const slugMatchScore = allPossibleSlugs.some(slug =>
+ itemSlug.includes(slug) || // Direct inclusion of our slug in their slug
+ allPossibleSlugs.some(ourSlug => ourSlug.includes(itemSlug.replace(/^[mt]-/, ''))) // Their slug in our slug
+ ) ? 10 : 0;
+
+ // Attempt to extract year from title if present, e.g., "Title (YYYY)"
+ let itemYear = null;
+ const yearMatch = itemTitle.match(/\((\d{4})\)$/);
+ if (yearMatch && yearMatch[1]) {
+ itemYear = yearMatch[1];
+ }
+
+ // Extract year from URL if possible
+ if (!itemYear && itemHref) {
+ const urlYearMatch = itemHref.match(/-(20\d{2})$/);
+ if (urlYearMatch) {
+ itemYear = urlYearMatch[1];
+ }
+ }
+
+ // IMPROVED SCORING LOGIC
+ let score = 0;
+
+ // Extra points for URLs that match our expected pattern
+ const correctMediaType = (tmdbType === 'movie' && itemHref.includes('/movie/')) ||
+ (tmdbType === 'tv' && itemHref.includes('/tv/'));
+
+ // Strong bonus for matching the expected media type
+ if (correctMediaType) {
+ score += 12; // Significantly increase importance of correct media type
+ } else {
+ score -= 15; // Heavy penalty for wrong media type
+ }
+
+ // Strong bonus for slug match
+ score += slugMatchScore;
+
+ // Exact title match (any of our titles)
+ if (normalizedTmdbTitles.some(normTitle => normTitle === normalizedItemTitle)) {
+ score += 15; // Very strong bonus for exact normalized match
+ }
+ // Title contains our title or vice versa (any of our titles)
+ else if (normalizedTmdbTitles.some(normTitle =>
+ normTitle.length > 3 && normalizedItemTitle.length > 3 &&
+ (normalizedItemTitle.includes(normTitle) || normTitle.includes(normalizedItemTitle))
+ )) {
+ score += 10; // Good bonus for partial match
+ }
+ // Simplified title contains the entire simplified TMDB title
+ else if (simplifiedItemTitle.includes(simplifiedTmdbTitle)) {
+ score += 7; // Moderate bonus
+ }
+ // TMDB title contains the simplified item title (could be abbreviation/shortened)
+ else if (simplifiedTmdbTitle.includes(simplifiedItemTitle) && simplifiedItemTitle.length > 3) {
+ score += 3; // Small bonus for being contained in the TMDB title
+ }
+
+ // Word-by-word match calculation for multi-word titles
+ const tmdbWords = originalTmdbTitle.toLowerCase().split(/\s+/);
+ const itemWords = itemTitle.toLowerCase().split(/\s+/);
+
+ let wordMatchCount = 0;
+ for (const tmdbWord of tmdbWords) {
+ if (tmdbWord.length <= 2) continue; // Skip very short words
+ // More strict word matching - require exact word matches or very close matches
+ if (itemWords.some(itemWord => {
+ // Exact match
+ if (itemWord === tmdbWord) return true;
+ // Allow for very close matches (like plurals or slight variations)
+ if (tmdbWord.length > 3 && itemWord.length > 3) {
+ return (itemWord.includes(tmdbWord) && itemWord.length - tmdbWord.length <= 2) ||
+ (tmdbWord.includes(itemWord) && tmdbWord.length - itemWord.length <= 2);
+ }
+ return false;
+ })) {
+ wordMatchCount++;
+ }
+ }
+
+ // Add score based on percentage of words matched, but require at least some match
+ if (tmdbWords.length > 0 && wordMatchCount > 0) {
+ const wordMatchPercent = wordMatchCount / tmdbWords.length;
+ score += wordMatchPercent * 5; // Up to 5 points for word matches
+ } else if (tmdbWords.length > 1 && wordMatchCount === 0) {
+ // Heavy penalty for multi-word titles with no word matches
+ score -= 10;
+ }
+
+ // YEAR MATCHING - now much more important
+ if (mediaYear && itemYear) {
+ if (mediaYear === itemYear) {
+ score += 18; // MUCH stronger bonus for exact year match
+ } else {
+ // Penalty for year mismatch, larger for bigger differences
+ const yearDiff = Math.abs(parseInt(mediaYear) - parseInt(itemYear));
+ if (yearDiff <= 1) {
+ score -= 3; // Small penalty for 1 year difference
+ } else if (yearDiff <= 3) {
+ score -= 10; // Medium penalty for 2-3 year difference
+ } else {
+ score -= 20; // Large penalty for > 3 year difference
+ }
+ }
+ } else if (mediaYear && !itemYear) {
+ // If we have a year but the item doesn't, apply a small penalty
+ score -= 5;
+ }
+
+ searchResults.push({
+ title: itemTitle,
+ href: itemHref,
+ year: itemYear,
+ score: score,
+ slug: itemSlug,
+ isMovie: itemHref.includes('/movie/'),
+ isTv: itemHref.includes('/tv/')
+ });
+ }
+ });
+
+ // Sort by score and pick the best one
+ searchResults.sort((a, b) => b.score - a.score);
+
+ if (searchResults.length > 0) {
+ console.log(` Search results for strategy "${strategy.description}":`);
+ searchResults.slice(0, 3).forEach((result, i) => {
+ console.log(` ${i + 1}. Title: "${result.title}", Year: ${result.year || 'N/A'}, Score: ${result.score.toFixed(1)}, URL: ${result.href}, Media Type: ${result.isMovie ? 'Movie' : (result.isTv ? 'TV' : 'Unknown')}`);
+ });
+
+ const bestMatch = searchResults[0];
+ if (bestMatch.score > bestResult.score) {
+ bestResult = {
+ url: `https://www.showbox.media${bestMatch.href}`,
+ score: bestMatch.score,
+ strategy: strategy.description,
+ title: bestMatch.title,
+ year: bestMatch.year,
+ isCorrectType: (tmdbType === 'movie' && bestMatch.isMovie) || (tmdbType === 'tv' && bestMatch.isTv)
+ };
+
+ // Track successful strategy
+ strategyResults[strategy.description] = {
+ success: true,
+ score: bestMatch.score,
+ correctType: bestResult.isCorrectType
+ };
+ } else {
+ // Track strategy that didn't beat our current best
+ strategyResults[strategy.description] = {
+ success: true,
+ score: bestMatch.score,
+ correctType: (tmdbType === 'movie' && bestMatch.isMovie) || (tmdbType === 'tv' && bestMatch.isTv),
+ notBest: true
+ };
+ }
+ } else {
+ console.log(` No results found for strategy "${strategy.description}"`);
+ // Track failed strategy
+ strategyResults[strategy.description] = { success: false, score: 0 };
+ }
+
+ // INCREASED THRESHOLD: Require higher confidence for matches to avoid false positives
+ if (bestResult.score > 35 && bestResult.isCorrectType) {
+ console.log(` Found good match with score ${bestResult.score.toFixed(1)} using strategy "${bestResult.strategy}", stopping search`);
+ break;
+ }
+ }
+
+ // Log strategy effectiveness summary
+ console.log(` Strategy effectiveness summary:`);
+ Object.entries(strategyResults).forEach(([strategy, result]) => {
+ if (result.success) {
+ const status = result.notBest ? "Found results but not best" :
+ (result.correctType ? "Found correct type" : "Found wrong type");
+ console.log(` - ${strategy}: ${status} (Score: ${result.score.toFixed(1)})`);
+ } else {
+ console.log(` - ${strategy}: No results found`);
+ }
+ });
+
+ // Final decision based on all strategies
+ if (bestResult.url) {
+ let useResult = false;
+
+ // Use score-based confidence for validation - increased threshold to prevent false positives
+ if (bestResult.score >= 40 && bestResult.isCorrectType) {
+ useResult = true;
+ } else {
+ console.log(` Low confidence match (Score: ${bestResult.score.toFixed(1)}). Discarding - requires score >= 40.`);
+ useResult = false;
+ }
+
+ if (useResult && bestResult.url) {
+ console.log(` Best overall match: ${bestResult.url} (Score: ${bestResult.score.toFixed(1)}, Strategy: ${bestResult.strategy})`);
+
+ // Save high-score results to cache
+ if (process.env.DISABLE_CACHE !== 'true') {
+ await saveToCache(searchTermKey, bestResult.url, cacheSubDir);
+ }
+ return { url: bestResult.url, score: bestResult.score };
+ }
+ }
+
+ // This block will now be reached if the initial search found nothing, or if AI rejected the candidate.
+ console.log(` No suitable match found on ShowBox search for: ${originalTmdbTitle} (${mediaYear || 'N/A'})`);
+ if (process.env.DISABLE_CACHE !== 'true') {
+ await saveToCache(searchTermKey, { result: 'NO_MATCH_FOUND', timestamp: Date.now() }, cacheSubDir);
+ }
+ return { url: null, score: -1 };
+};
+
+// TMDB helper function to get ShowBox URL from TMDB ID
+// MODIFICATION: Enhanced for better anime and title matching
+const getShowboxUrlFromTmdbInfo = async (tmdbType, tmdbId, regionPreference = null) => {
+ const urlCacheSubDir = 'showbox_final_url';
+ const urlCacheKey = `v3_${tmdbType}_${tmdbId}.json`;
+ const disableCache = process.env.DISABLE_CACHE === 'true';
+
+ // 1. Check for the final, validated URL in the cache first.
+ if (!disableCache) {
+ const cachedResult = await getFromCache(urlCacheKey, urlCacheSubDir);
+ if (cachedResult) {
+ if (cachedResult.showboxUrl === 'NO_URL_FOUND') {
+ // For stream searches, always retry immediately - content availability can change anytime
+ console.log(` [Final URL Cache] HIT: Previously no URL found for ${tmdbType}/${tmdbId}, but retrying immediately for fresh content.`);
+ // Continue to search logic below to retry immediately
+ } else {
+ console.log(` [Final URL Cache] HIT: Found cached ShowBox result for ${tmdbType}/${tmdbId}.`);
+ return cachedResult;
+ }
+ }
+ }
+
+ // 2. If no cached final URL, proceed with the discovery logic.
+ console.time('getShowboxUrlFromTmdbInfo_total');
+ const mainCacheSubDir = 'tmdb_api';
+ const mainCacheKey = `tmdb-${tmdbType}-${tmdbId}.json`;
+ let tmdbData = await getFromCache(mainCacheKey, mainCacheSubDir);
+
+ if (!tmdbData || process.env.DISABLE_CACHE === 'true') {
+ const TMDB_API_KEY = obtainTmdbKey();
+ const tmdbApiUrl = `${TMDB_BASE_URL}/${tmdbType}/${tmdbId}?api_key=${TMDB_API_KEY}`;
+ console.log(` Fetching TMDB data from: ${tmdbApiUrl}`);
+ try {
+ const response = await axios.get(tmdbApiUrl, { timeout: 10000 });
+ tmdbData = response.data;
+ if (tmdbData) {
+ if (process.env.DISABLE_CACHE !== 'true') {
+ await saveToCache(mainCacheKey, tmdbData, mainCacheSubDir);
+ }
+ } else {
+ console.log(' No TMDB data received.');
+ console.timeEnd('getShowboxUrlFromTmdbInfo_total');
+ return null;
+ }
+ } catch (error) {
+ console.log(` Error fetching TMDB main data: ${error.message}`);
+ console.timeEnd('getShowboxUrlFromTmdbInfo_total');
+ return null;
+ }
+ }
+
+ if (!tmdbData) {
+ console.log(` Could not fetch TMDB data for ${tmdbType}/${tmdbId}. Cannot proceed.`);
+ console.timeEnd('getShowboxUrlFromTmdbInfo_total');
+ return null;
+ }
+
+ // Fetch alternative titles
+ const altTitlesCacheKey = `tmdb-${tmdbType}-${tmdbId}-alternatives.json`;
+ let tmdbAlternativeTitlesData = await getFromCache(altTitlesCacheKey, mainCacheSubDir);
+
+ if (!tmdbAlternativeTitlesData || process.env.DISABLE_CACHE === 'true') {
+ const TMDB_API_KEY = obtainTmdbKey();
+ const altTitlesApiUrl = `${TMDB_BASE_URL}/${tmdbType}/${tmdbId}/alternative_titles?api_key=${TMDB_API_KEY}`;
+ console.log(` Fetching TMDB alternative titles from: ${altTitlesApiUrl}`);
+ try {
+ const response = await axios.get(altTitlesApiUrl, { timeout: 10000 });
+ tmdbAlternativeTitlesData = response.data;
+ if (tmdbAlternativeTitlesData) {
+ if (process.env.DISABLE_CACHE !== 'true') {
+ await saveToCache(altTitlesCacheKey, tmdbAlternativeTitlesData, mainCacheSubDir);
+ }
+ }
+ } catch (error) {
+ console.log(` Error fetching TMDB alternative titles: ${error.message}`);
+ tmdbAlternativeTitlesData = { titles: [] };
+ }
+ }
+
+ // Get alternative titles array, or empty array if none
+ const alternativeTitles = tmdbAlternativeTitlesData?.titles || [];
+
+ // NEW: Fetch TMDB images
+ const imagesCacheKey = `tmdb-${tmdbType}-${tmdbId}-images.json`;
+ let tmdbImagesData = await getFromCache(imagesCacheKey, mainCacheSubDir);
+ let tmdbBackdropPaths = [];
+
+ if (!tmdbImagesData || process.env.DISABLE_CACHE === 'true') {
+ const TMDB_API_KEY = obtainTmdbKey();
+ const imagesApiUrl = `${TMDB_BASE_URL}/${tmdbType}/${tmdbId}/images?api_key=${TMDB_API_KEY}`;
+ console.log(` Fetching TMDB images from: ${imagesApiUrl}`);
+ try {
+ const response = await axios.get(imagesApiUrl, { timeout: 10000 });
+ tmdbImagesData = response.data;
+ if (tmdbImagesData) {
+ if (process.env.DISABLE_CACHE !== 'true') {
+ await saveToCache(imagesCacheKey, tmdbImagesData, mainCacheSubDir);
+ }
+ }
+ } catch (error) {
+ console.log(` Error fetching TMDB images: ${error.message}`);
+ tmdbImagesData = { backdrops: [], posters: [] }; // Default to empty if error
+ }
+ }
+ if (tmdbImagesData && tmdbImagesData.backdrops) {
+ tmdbBackdropPaths = tmdbImagesData.backdrops.map(img => img.file_path).filter(Boolean);
+ console.log(` Collected ${tmdbBackdropPaths.length} TMDB backdrop paths.`);
+ if (tmdbBackdropPaths.length > 0) {
+ console.log(` Sample TMDB backdrop paths: ${tmdbBackdropPaths.slice(0, 3).join(', ')}`);
+ }
+ }
+
+ // Log anime genres to help identify anime content
+ if (tmdbData.genres && Array.isArray(tmdbData.genres)) {
+ const animeGenre = tmdbData.genres.find(g => g.name === 'Animation');
+ if (animeGenre) {
+ console.log(` [ANIME] Content identified as Animation genre, will check for anime-specific titles`);
+ }
+ }
+
+ // Extract main titles and year
+ let mainTitle = null; // Primary/localized title
+ let originalTitle = null; // Original title (could be in non-Latin script)
+ let year = null;
+
+ if (tmdbType === 'movie') {
+ mainTitle = tmdbData.title; // Prioritize .title for movies (localized)
+ originalTitle = tmdbData.original_title;
+ if (tmdbData.release_date && String(tmdbData.release_date).length >= 4) {
+ year = String(tmdbData.release_date).substring(0, 4);
+ }
+ } else if (tmdbType === 'tv') {
+ mainTitle = tmdbData.name; // Prioritize .name for TV (localized)
+ originalTitle = tmdbData.original_name;
+ const rawFirstAirDate = tmdbData.first_air_date;
+ if (rawFirstAirDate && String(rawFirstAirDate).length >= 4) {
+ year = String(rawFirstAirDate).substring(0, 4);
+ }
+ }
+
+ if (!mainTitle && !originalTitle) {
+ console.log(` Could not determine any title from TMDB data for ${tmdbType}/${tmdbId}.`);
+ console.timeEnd('getShowboxUrlFromTmdbInfo_total');
+ return null;
+ }
+
+ // If mainTitle is missing, use originalTitle as fallback
+ if (!mainTitle) mainTitle = originalTitle;
+
+ // Extract special titles like Romaji for anime
+ const specialTitles = extractSpecialTitles(tmdbData, alternativeTitles);
+
+ // Collect all available titles in one array for processing
+ const allTitles = [mainTitle, originalTitle, ...specialTitles, ...alternativeTitles.map(alt => alt.title)]
+ .filter(Boolean) // Remove nulls/undefined
+ .filter((value, index, self) => self.indexOf(value) === index); // Remove duplicates
+
+ console.log(` Collected ${allTitles.length} unique titles for "${mainTitle || originalTitle}":`);
+ allTitles.forEach((title, idx) => {
+ console.log(` [${idx + 1}] "${title}"`);
+ });
+
+ const MAX_DIRECT_URL_ATTEMPTS = 3; // Configurable limit for direct URL construction
+ const titlesForDirectAttempt = allTitles.slice(0, MAX_DIRECT_URL_ATTEMPTS);
+ console.log(` Limiting direct URL construction attempts to first ${titlesForDirectAttempt.length} titles out of ${allTitles.length} total unique titles.`);
+
+ // Initialize ShowBox scraper instance
+ const showboxScraperInstance = new ShowBoxScraper(regionPreference);
+ const mediaTypeString = tmdbType === 'movie' ? 'movie' : 'tv';
+ const mediaTypePrefix = tmdbType === 'movie' ? 'm' : 't';
+
+ // This is a new inner function to contain all the discovery logic.
+ const findUrl = async () => {
+ // If we have a year, try direct URL construction with all titles
+ if (year) {
+ console.log(` Attempting direct ShowBox URL construction for ${tmdbType} "${mainTitle}" (${year}) with ${titlesForDirectAttempt.length} title variants.`);
+
+ for (const candidateTitle of titlesForDirectAttempt) {
+ const slug = slugify(candidateTitle);
+ if (!slug) {
+ console.log(` Skipping empty slug for title: "${candidateTitle}"`);
+ continue;
+ }
+
+ const directShowboxUrl = `https://www.showbox.media/${mediaTypeString}/${mediaTypePrefix}-${slug}-${year}`;
+ console.log(` Trying direct URL: ${directShowboxUrl} (from title: "${candidateTitle}")`);
+
+ const htmlContent = await showboxScraperInstance._makeRequest(directShowboxUrl);
+ if (htmlContent) {
+ console.log(` Successfully fetched content from direct URL: ${directShowboxUrl}`);
+ const pageInfo = showboxScraperInstance.extractContentIdAndType(directShowboxUrl, htmlContent);
+
+ if (pageInfo && pageInfo.title) {
+ const titleIsValid = validateShowboxTitle(pageInfo.title, mainTitle, originalTitle, alternativeTitles);
+ const showboxTmdbImagePath = extractTmdbImagePathFromShowboxHtml(htmlContent);
+ const imageIsValid = validateTmdbImage(showboxTmdbImagePath, tmdbBackdropPaths);
+
+ if (titleIsValid && imageIsValid) {
+ console.log(` SUCCESS (TITLE & IMAGE VALIDATED): Validated title and TMDB image for ${directShowboxUrl}. Using this URL.`);
+ return { showboxUrl: directShowboxUrl, year: year, title: mainTitle };
+ }
+ }
+ }
+ }
+ }
+
+ // ... (rest of the discovery logic: special slugs, AI search, _searchAndExtractShowboxUrl call)
+ // Note: all 'return { showboxUrl: ... }' statements will now return from this inner function.
+ // ... (this part of the code remains the same but is conceptually inside findUrl)
+
+ // The original search call at the end
+ console.log(` No validated ShowBox URL found through direct construction. Falling back to search...`);
+ const searchResult = await _searchAndExtractShowboxUrl(mainTitle, mainTitle, year, showboxScraperInstance, tmdbType, regionPreference, allTitles);
+ if (searchResult && searchResult.url) {
+ console.log(` Search found a result. Title: ${searchResult.title}, Year: ${searchResult.year}`);
+ return { showboxUrl: searchResult.url, year: year, title: mainTitle };
+ }
+
+ return null; // Return null if all methods fail
+ };
+
+ // Execute the discovery function
+ const finalResult = await findUrl();
+
+ // 3. Cache the result of the discovery, whether successful or not.
+ if (!disableCache) {
+ if (finalResult && finalResult.showboxUrl) {
+ console.log(` [Final URL Cache] SAVING result for ${tmdbType}/${tmdbId}: ${finalResult.showboxUrl}`);
+ await saveToCache(urlCacheKey, finalResult, urlCacheSubDir);
+ } else {
+ console.log(` [Final URL Cache] SAVING 'NO_URL_FOUND' for ${tmdbType}/${tmdbId}.`);
+ await saveToCache(urlCacheKey, { showboxUrl: 'NO_URL_FOUND', timestamp: Date.now() }, urlCacheSubDir);
+ }
+ }
+
+ console.timeEnd('getShowboxUrlFromTmdbInfo_total');
+ return finalResult;
+};
+
+// Function to fetch sources for a single FID
+// MODIFICATION: Remove scraperApiKey parameter
+const fetchSourcesForSingleFid = async (fidToProcess, shareKey, regionPreference = null, userCookie = null, retryAttempt = 0) => {
+ const MAX_RETRIES_SAME_REGION = 1; // Retry once on the same region before falling back
+
+ const targetPostData = new URLSearchParams();
+ targetPostData.append('fid', fidToProcess);
+ targetPostData.append('share_key', shareKey);
+
+ const cookieForRequest = await getCookieForRequest(regionPreference, userCookie);
+
+ const baseHeaders = {
+ 'Cookie': `ui=${cookieForRequest}`,
+ 'Content-Type': 'application/x-www-form-urlencoded'
+ };
+
+ const finalPostUrl = FEBBOX_PLAYER_URL;
+ const postDataForAxios = targetPostData.toString();
+ const axiosConfig = { headers: baseHeaders, timeout: 20000 };
+
+ console.log(` Fetching fresh player data for video FID: ${fidToProcess} (Share: ${shareKey}) directly to ${FEBBOX_PLAYER_URL}`);
+
+ try {
+ const response = await axios.post(finalPostUrl, postDataForAxios, axiosConfig);
+ const playerContent = response.data;
+
+ // Mark the region as available if the request succeeded
+ if (global.lastRequestedRegion && global.lastRequestedRegion.used) {
+ global.regionAvailabilityStatus[global.lastRequestedRegion.used] = true;
+ // If we successfully used a fallback, notify through a global flag
+ if (global.lastRequestedRegion.usingFallback) {
+ global.usedRegionFallback = {
+ original: global.lastRequestedRegion.original,
+ fallback: global.lastRequestedRegion.used
+ };
+ }
+ }
+
+ const sourcesMatch = playerContent.match(/var sources = (.*?);\s*/s);
+ if (!sourcesMatch) {
+ console.log(` Could not find sources array in player response for FID ${fidToProcess}`);
+ if (playerContent.startsWith('http') && (playerContent.includes('.mp4') || playerContent.includes('.m3u8'))) {
+ return [{ "label": "DirectLink", "url": playerContent.trim() }];
+ }
+ try {
+ const jsonResponse = JSON.parse(playerContent);
+ if (jsonResponse.msg) {
+ console.log(` FebBox API Error: ${jsonResponse.code} - ${jsonResponse.msg}`);
+ // Check for region-specific errors
+ if (jsonResponse.code === 1002 ||
+ jsonResponse.msg.includes("region") ||
+ jsonResponse.msg.includes("location") ||
+ jsonResponse.msg.includes("unavailable")) {
+
+ // --- BEGIN: Retry Logic ---
+ if (retryAttempt < MAX_RETRIES_SAME_REGION) {
+ console.log(` Region error on attempt ${retryAttempt + 1}. Retrying same region: ${global.lastRequestedRegion.used}`);
+ await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1 second
+ return fetchSourcesForSingleFid(fidToProcess, shareKey, regionPreference, userCookie, retryAttempt + 1);
+ }
+ // --- END: Retry Logic ---
+
+ // Mark the region as unavailable after retries have failed
+ if (global.lastRequestedRegion && global.lastRequestedRegion.used) {
+ console.log(` Marking region ${global.lastRequestedRegion.used} as unavailable after ${retryAttempt + 1} failed attempts.`);
+ global.regionAvailabilityStatus[global.lastRequestedRegion.used] = false;
+
+ // Try again with a US fallback region if we haven't already
+ if (!global.lastRequestedRegion.usingFallback) {
+ for (const fallbackRegion of US_FALLBACK_REGIONS) {
+ if (fallbackRegion !== global.lastRequestedRegion.used) {
+ console.log(` Retrying with fallback US region: ${fallbackRegion}`);
+ // Reset retryAttempt for the new region
+ return fetchSourcesForSingleFid(fidToProcess, shareKey, fallbackRegion, userCookie, 0);
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (e) { /* Not a JSON error message */ }
+ return [];
+ }
+
+ const sourcesJsArrayString = sourcesMatch[1];
+ const sourcesData = JSON.parse(sourcesJsArrayString);
+ const fidVideoLinks = [];
+ for (const sourceItem of sourcesData) {
+ if (sourceItem.file && sourceItem.label) {
+ let detailedFilename = null;
+ try {
+ const urlParams = new URLSearchParams(new URL(sourceItem.file).search);
+ if (urlParams.has('KEY5')) {
+ detailedFilename = urlParams.get('KEY5');
+ }
+ } catch (e) {
+ // console.warn('Could not parse URL to get KEY5:', sourceItem.file, e.message);
+ }
+ fidVideoLinks.push({
+ "label": String(sourceItem.label),
+ "url": String(sourceItem.file),
+ "detailedFilename": detailedFilename
+ });
+ }
+ }
+
+ if (fidVideoLinks.length > 0) {
+ console.log(` Extracted ${fidVideoLinks.length} fresh video link(s) for FID ${fidToProcess}`);
+ }
+ return fidVideoLinks;
+ } catch (error) {
+ console.log(` Request error for FID ${fidToProcess}: ${error.message}`);
+
+ // Check for region-specific errors and mark the region as unavailable
+ if ((error.message.includes('timeout') ||
+ error.message.includes('network') ||
+ (error.response && (error.response.status === 403 || error.response.status === 404)))) {
+
+ // --- BEGIN: Retry Logic ---
+ if (retryAttempt < MAX_RETRIES_SAME_REGION) {
+ console.log(` Network error on attempt ${retryAttempt + 1}. Retrying same region: ${global.lastRequestedRegion.used}`);
+ await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1 second
+ return fetchSourcesForSingleFid(fidToProcess, shareKey, regionPreference, userCookie, retryAttempt + 1);
+ }
+ // --- END: Retry Logic ---
+
+ if (global.lastRequestedRegion && global.lastRequestedRegion.used) {
+ console.log(` Marking region ${global.lastRequestedRegion.used} as potentially unavailable after ${retryAttempt + 1} failed attempts due to error.`);
+ global.regionAvailabilityStatus[global.lastRequestedRegion.used] = false;
+
+ // Try again with a US fallback region if we haven't already
+ if (!global.lastRequestedRegion.usingFallback) {
+ for (const fallbackRegion of US_FALLBACK_REGIONS) {
+ if (fallbackRegion !== global.lastRequestedRegion.used) {
+ console.log(` Retrying with fallback US region: ${fallbackRegion}`);
+ // Reset retryAttempt for the new region
+ return fetchSourcesForSingleFid(fidToProcess, shareKey, fallbackRegion, userCookie, 0);
+ }
+ }
+ }
+ }
+ }
+
+ console.log(` Fresh fetch failed for FID ${fidToProcess}.`);
+ return [];
+ }
+};
+
+// ShowBox scraper class
+class ShowBoxScraper {
+ constructor(regionPreference = null, userCookie = null) {
+ // Store the region preference and user cookie
+ this.regionPreference = regionPreference;
+ this.userCookie = userCookie;
+ // ScraperAPI key support removed
+
+ // Initialize proxy rotation counter for this instance
+ this.proxyCounter = Math.floor(Math.random() * 1000); // Random start to avoid patterns
+
+ this.baseHeaders = {
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
+ 'Accept-Language': 'en-US,en;q=0.9',
+ 'Accept-Encoding': 'gzip, deflate, br',
+ 'Connection': 'keep-alive',
+ 'Upgrade-Insecure-Requests': '1',
+ 'Sec-Fetch-Dest': 'document',
+ 'Sec-Fetch-Mode': 'navigate',
+ 'Sec-Fetch-Site': 'same-origin',
+ 'Sec-Fetch-User': '?1',
+ 'DNT': '1',
+ 'Sec-GPC': '1'
+ };
+ }
+
+ // Get the next proxy URL from the rotation
+ getNextProxy() {
+ // Read proxy configuration from environment
+ const useRotatingProxy = process.env.SHOWBOX_USE_ROTATING_PROXY === 'true';
+ const primaryProxy = process.env.SHOWBOX_PROXY_URL_VALUE;
+ const alternateProxy = process.env.SHOWBOX_PROXY_URL_ALTERNATE;
+
+ // Increment the counter for this instance
+ this.proxyCounter++;
+
+ // ScraperAPI support removed; simple proxy rotation only
+
+ // Return direct connection if both proxies are missing
+ if (!primaryProxy && !alternateProxy) return null;
+
+ // If rotation disabled or alternate proxy not set, just use primary proxy
+ if (!useRotatingProxy || !alternateProxy) return primaryProxy;
+
+ // Use modulo to alternate between available proxies
+ const proxyIndex = this.proxyCounter % 2;
+ const selectedProxy = proxyIndex === 0 ? primaryProxy : alternateProxy;
+
+ console.log(`[Rotating Proxy] Selected proxy ${proxyIndex + 1}/2 for request #${this.proxyCounter}`);
+ return selectedProxy;
+ }
+
+ async _makeRequest(url, isJsonExpected = false) {
+ // Removed unused timerLabel variable (profiling optional)
+
+ // For JSON requests, we still cache normally since they're small
+ if (isJsonExpected) {
+ const cacheSubDir = 'showbox_generic';
+ const urlHash = crypto.createHash('md5').update(url).digest('hex');
+ const cacheKey = `${urlHash}.json`;
+
+ const cachedData = await getFromCache(cacheKey, cacheSubDir);
+ if (cachedData && typeof cachedData === 'object') {
+ return cachedData;
+ }
+ }
+ // For HTML requests, we don't cache the raw HTML anymore - it's too large and wasteful
+
+ // Get the next proxy URL from the rotation
+ const selectedProxy = this.getNextProxy();
+ let requestUrl = url;
+ // removed unused isUsingScraperApi flag
+
+ if (selectedProxy) {
+ if (typeof selectedProxy === 'function') {
+ requestUrl = selectedProxy(url); // Direct transformation
+ } else if (selectedProxy.trim() !== '') {
+ // This is a regular proxy URL
+ requestUrl = `${selectedProxy}${encodeURIComponent(url)}`;
+ console.log(`ShowBoxScraper: Making request to: ${url} via Proxy: ${selectedProxy}`);
+ }
+ } else {
+ console.log(`ShowBoxScraper: Making direct request to: ${url} (no proxy available)`);
+ }
+
+ // Removed console.time call (timerLabel removed)
+
+ // Get the cookie with region preference if site requires it
+ let cookieValue = null;
+ if (url.includes('febbox.com')) {
+ if (this.regionPreference) {
+ console.log(`[ShowBoxScraper] Getting cookie with explicit region preference: ${this.regionPreference}`);
+ cookieValue = await getCookieForRequest(this.regionPreference, this.userCookie);
+ } else {
+ console.log(`[ShowBoxScraper] Getting cookie with default region (no preference specified)`);
+ cookieValue = await getCookieForRequest(null, this.userCookie);
+ }
+ }
+
+ const currentHeaders = { ...this.baseHeaders };
+ if (isJsonExpected) {
+ currentHeaders['Accept'] = 'application/json, text/javascript, */*; q=0.01';
+ currentHeaders['X-Requested-With'] = 'XMLHttpRequest';
+ currentHeaders['Sec-Fetch-Dest'] = 'empty';
+ currentHeaders['Sec-Fetch-Mode'] = 'cors';
+ delete currentHeaders['Upgrade-Insecure-Requests'];
+ }
+
+ if (cookieValue) {
+ currentHeaders['Cookie'] = `ui=${cookieValue}`;
+ }
+
+ try {
+ const response = await axios.get(requestUrl, {
+ headers: currentHeaders,
+ timeout: 30000 // Consider increasing if proxy adds significant latency
+ });
+ const responseData = response.data;
+
+ // Only cache JSON responses, not HTML (HTML is too large and wasteful)
+ if (responseData && isJsonExpected) {
+ const cacheSubDir = 'showbox_generic';
+ const urlHash = crypto.createHash('md5').update(url).digest('hex');
+ const cacheKey = `${urlHash}.json`;
+ await saveToCache(cacheKey, responseData, cacheSubDir);
+ }
+ // timerLabel removed; profiling disabled
+ return responseData;
+ } catch (error) {
+ const errorMessage = error.response ? `${error.message} (Status: ${error.response.status})` : error.message;
+ console.log(`ShowBoxScraper: Request failed for ${url}: ${errorMessage}`);
+ // timerLabel removed; profiling disabled
+ return null;
+ }
+ }
+
+ extractContentIdAndType(url, htmlContent) {
+ let contentId = null;
+ let contentTypeVal = null;
+ let title = "Unknown Title";
+ let sourceOfId = "unknown";
+
+ const urlMatchDetail = url.match(/\/(movie|tv)\/detail\/(\d+)(?:-([a-zA-Z0-9-]+))?/);
+ if (urlMatchDetail) {
+ const contentTypeStr = urlMatchDetail[1];
+ contentId = urlMatchDetail[2];
+ contentTypeVal = contentTypeStr === 'movie' ? '1' : '2';
+ const slugTitle = urlMatchDetail[3];
+ if (slugTitle) {
+ title = slugTitle.replace(/-/g, ' ').split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
+ }
+ sourceOfId = "url_direct";
+ }
+
+ if (htmlContent) {
+ const $ = cheerio.load(htmlContent);
+ let extractedHtmlTitle = null;
+ const titleElementH2 = $('h2.heading-name a');
+ if (titleElementH2.length) {
+ extractedHtmlTitle = titleElementH2.text().trim();
+ } else {
+ const titleElementH1 = $('h1.heading-name, h1.title');
+ if (titleElementH1.length) {
+ extractedHtmlTitle = titleElementH1.text().trim();
+ } else {
+ const titleElementMeta = $('meta[property="og:title"]');
+ if (titleElementMeta.length) {
+ extractedHtmlTitle = titleElementMeta.attr('content')?.trim();
+ } else {
+ const titleElementPlain = $('title, .movie-title, .tv-title');
+ if (titleElementPlain.length) {
+ extractedHtmlTitle = titleElementPlain.first().text().trim();
+ }
+ }
+ }
+ }
+
+ if (extractedHtmlTitle) {
+ title = extractedHtmlTitle;
+ if (title.includes(" - ShowBox")) title = title.split(" - ShowBox")[0].trim();
+ if (title.includes("| ShowBox")) title = title.split("| ShowBox")[0].trim();
+ }
+
+ if (!contentId || !contentTypeVal) {
+ const headingLinkSelector = 'h2.heading-name a[href*="/detail/"], h1.heading-name a[href*="/detail/"]';
+ const headingLink = $(headingLinkSelector).first();
+ if (headingLink.length) {
+ const href = headingLink.attr('href');
+ if (href) {
+ const idTypeMatchHtml = href.match(/\/(movie|tv)\/detail\/(\d+)/);
+ if (idTypeMatchHtml) {
+ contentId = idTypeMatchHtml[2];
+ contentTypeVal = idTypeMatchHtml[1] === 'movie' ? '1' : '2';
+ sourceOfId = "html_heading_link";
+ }
+ }
+ }
+
+ if (!contentId) {
+ const shareDiv = $('div.sharethis-inline-share-buttons');
+ if (shareDiv.length) {
+ let linkElements = shareDiv.find('a[href*="/movie/detail/"], a[href*="/tv/detail/"]');
+ const dataUrlOnDiv = shareDiv.attr('data-url');
+ if (linkElements.length === 0 && dataUrlOnDiv) {
+ const dummyLinkSoup = cheerio.load(``);
+ if (dummyLinkSoup('a').length) linkElements = dummyLinkSoup('a');
+ }
+
+ linkElements.each((i, el) => {
+ const href = $(el).attr('href');
+ if (href) {
+ const idTypeMatchShare = href.match(/\/(movie|tv)\/detail\/(\d+)/);
+ if (idTypeMatchShare) {
+ contentId = idTypeMatchShare[2];
+ contentTypeVal = idTypeMatchShare[1] === 'movie' ? '1' : '2';
+ sourceOfId = "html_share_div";
+ return false; // break loop
+ }
+ }
+ });
+ }
+ }
+ }
+ }
+
+ if (contentId && contentTypeVal) {
+ return { "id": contentId, "type": contentTypeVal, "title": title, "source": sourceOfId };
+ }
+
+ return null;
+ }
+
+ async extractFebboxShareLinks(showboxUrl) {
+ const timerLabel = `extractFebboxShareLinks_total_${showboxUrl.replace(/[^a-zA-Z0-9]/g, '')}`;
+ console.log(`ShowBoxScraper: Attempting to extract FebBox share link from: ${showboxUrl}`);
+ console.time(timerLabel);
+
+ try {
+ let htmlContent = null;
+ let contentInfo = this.extractContentIdAndType(showboxUrl, null);
+
+ if (!contentInfo || !contentInfo.id || !contentInfo.type) {
+ console.log("ShowBoxScraper: ID/Type not in URL, fetching HTML.");
+ htmlContent = await this._makeRequest(showboxUrl);
+ if (!htmlContent) {
+ console.log(`ShowBoxScraper: Failed to fetch HTML for ${showboxUrl}.`);
+ console.timeEnd(timerLabel);
+ return [];
+ }
+ contentInfo = this.extractContentIdAndType(showboxUrl, htmlContent);
+ }
+
+ if (!contentInfo || !contentInfo.id || !contentInfo.type) {
+ console.log(`ShowBoxScraper: Could not determine content ID/type for ${showboxUrl}.`);
+ // console.timeEnd removed (timerLabel eliminated)
+ return [];
+ }
+
+ const { id: contentId, type: contentType, title } = contentInfo;
+
+ if (htmlContent) {
+ const $ = cheerio.load(htmlContent);
+ let directFebboxLink = null;
+
+ $('a[href*="febbox.com/share/"]').each((i, elem) => {
+ const href = $(elem).attr('href');
+ if (href && href.includes("febbox.com/share/")) {
+ directFebboxLink = href;
+ return false;
+ }
+ });
+
+ if (!directFebboxLink) {
+ const scriptContents = $('script').map((i, el) => $(el).html()).get().join('\n');
+ const shareKeyMatch = scriptContents.match(/['"](https?:\/\/www\.febbox\.com\/share\/[a-zA-Z0-9-]+)['"]/);
+ if (shareKeyMatch && shareKeyMatch[1]) {
+ directFebboxLink = shareKeyMatch[1];
+ }
+ }
+
+ if (directFebboxLink) {
+ console.log(`ShowBoxScraper: Successfully fetched FebBox URL: ${directFebboxLink} from HTML`);
+ console.timeEnd(timerLabel);
+ return [{
+ "showbox_title": title,
+ "febbox_share_url": directFebboxLink,
+ "showbox_content_id": contentId,
+ "showbox_content_type": contentType
+ }];
+ }
+ }
+
+ // API call if direct parsing didn't work
+ console.log(`ShowBoxScraper: Making API call for ${title} (ID: ${contentId}, Type: ${contentType})`);
+ const shareApiUrl = `https://www.showbox.media/index/share_link?id=${contentId}&type=${contentType}`;
+ const apiTimerLabel = `extractFebboxShareLinks_apiCall_${contentId}`;
+ console.time(apiTimerLabel);
+ const apiResponseStr = await this._makeRequest(shareApiUrl, true);
+ console.timeEnd(apiTimerLabel);
+
+ if (!apiResponseStr) {
+ console.log(`ShowBoxScraper: Failed to get response from ShowBox share_link API`);
+ // console.timeEnd removed (timerLabel eliminated)
+ return [];
+ }
+
+ try {
+ const apiResponseJson = (typeof apiResponseStr === 'string') ? JSON.parse(apiResponseStr) : apiResponseStr;
+ if (apiResponseJson.code === 1 && apiResponseJson.data && apiResponseJson.data.link) {
+ const febboxShareUrl = apiResponseJson.data.link;
+ console.log(`ShowBoxScraper: Successfully fetched FebBox URL: ${febboxShareUrl} from API`);
+ // timerLabel removed; profiling disabled
+ return [{
+ "showbox_title": title,
+ "febbox_share_url": febboxShareUrl,
+ "showbox_content_id": contentId,
+ "showbox_content_type": contentType
+ }];
+ } else {
+ console.log(`ShowBoxScraper: ShowBox share_link API did not succeed for '${title}'.`);
+ // timerLabel removed; profiling disabled
+ return [];
+ }
+ } catch (e) {
+ console.log(`ShowBoxScraper: Error decoding JSON from ShowBox share_link API: ${e.message}`);
+ // timerLabel removed; profiling disabled
+ return [];
+ }
+ } catch (error) {
+ // Catch any unexpected errors from the outer logic
+ console.error(`ShowBoxScraper: Unexpected error in extractFebboxShareLinks for ${showboxUrl}: ${error.message}`);
+ // console.timeEnd removed (timerLabel eliminated)
+ return [];
+ }
+ }
+}
+
+// Function to extract FIDs from FebBox share page
+// MODIFICATION: Accept scraperApiKey -> MODIFICATION: Remove scraperApiKey
+const extractFidsFromFebboxPage = async (febboxUrl, regionPreference = null, userCookie = null) => {
+ // Removed timerLabel profiling label from extractFidsFromFebboxPage
+ let directSources = []; // Initialize directSources
+ const cacheSubDirParsed = 'febbox_parsed_page'; // Only cache parsed data
+ const urlHash = crypto.createHash('md5').update(febboxUrl).digest('hex');
+ const cacheKeyParsed = `${urlHash}.json`; // Parsed data will be JSON
+
+ // Check for cached parsed data first
+ const cachedParsedData = await getFromCache(cacheKeyParsed, cacheSubDirParsed);
+ if (cachedParsedData && typeof cachedParsedData === 'object') { // Ensure it's an object
+ // console.log(` CACHE HIT for parsed FebBox page data: ${febboxUrl}`);
+ // profiling disabled (timerLabel removed)
+ return cachedParsedData; // Return { fids, shareKey, directSources }
+ }
+ // console.log(` CACHE MISS for parsed FebBox page data: ${febboxUrl}`);
+
+ // Fetch HTML content directly without caching it
+ let contentHtml = null;
+ const cookieForRequest = await getCookieForRequest(regionPreference, userCookie); // Pass region preference and user cookie
+ const baseHeaders = { 'Cookie': `ui=${cookieForRequest}` };
+ const fetchTimerLabel = `extractFidsFromFebboxPage_fetch_${febboxUrl.replace(/[^a-zA-Z0-9]/g, '')}`;
+
+ // MODIFICATION: Removed ScraperAPI conditional logic
+ // const useScraperApi = process.env.USE_SCRAPER_API === 'true';
+ // const scraperApiKey = process.env.SCRAPER_API_KEY_VALUE;
+
+ const finalGetUrl = febboxUrl;
+ const axiosConfig = { headers: baseHeaders, timeout: 20000 };
+
+ // if (useScraperApi && scraperApiKey) {
+ // finalGetUrl = SCRAPER_API_BASE_URL; // Use defined base URL
+ // axiosConfig.params = { api_key: scraperApiKey, url: febboxUrl, keep_headers: 'true' };
+ // console.log(`Fetching FebBox page content from URL: ${febboxUrl} via ScraperAPI`);
+ // } else {
+ // console.log(`Fetching FebBox page content from URL: ${febboxUrl} directly`);
+ // }
+ console.log(`Fetching FebBox page content from URL: ${febboxUrl} directly`);
+
+ try {
+ // console.time(fetchTimerLabel);
+ const response = await axios.get(finalGetUrl, axiosConfig);
+ // console.timeEnd(fetchTimerLabel);
+ contentHtml = response.data;
+ // Note: No longer caching the raw HTML content
+ } catch (error) {
+ console.log(`Failed to fetch FebBox page: ${error.message}`);
+ if (fetchTimerLabel) console.timeEnd(fetchTimerLabel); // Ensure timer ends on error if started
+ // console.timeEnd(timerLabel);
+ return { fids: [], shareKey: null, directSources: [] };
+ }
+
+ let shareKey = null;
+ // Update regex to include hyphens in share key pattern
+ const matchShareKeyUrl = febboxUrl.match(/\/share\/([a-zA-Z0-9-]+)/);
+ if (matchShareKeyUrl) {
+ shareKey = matchShareKeyUrl[1];
+ } else if (contentHtml) {
+ // Update regex to include hyphens in share key pattern
+ const matchShareKeyHtml = contentHtml.match(/(?:var share_key\s*=|share_key:\s*|shareid=)"?([a-zA-Z0-9-]+)"?/);
+ if (matchShareKeyHtml) {
+ shareKey = matchShareKeyHtml[1];
+ }
+ }
+
+ if (!shareKey) {
+ console.log(`Warning: Could not extract share_key from ${febboxUrl}`);
+ // console.timeEnd(timerLabel);
+ return { fids: [], shareKey: null };
+ }
+
+ // Extract FIDs from the content HTML
+ const $ = cheerio.load(contentHtml);
+ const videoFidsFound = [];
+
+ // Direct player source check
+ const playerSetupMatch = contentHtml.match(/jwplayer\("[a-zA-Z0-9_-]+"\)\.setup/);
+ if (playerSetupMatch) {
+ const sourcesMatchDirect = contentHtml.match(/var sources = (.*?);\s*/s);
+ if (sourcesMatchDirect) {
+ try {
+ const sourcesJsArrayString = sourcesMatchDirect[1];
+ const sourcesData = JSON.parse(sourcesJsArrayString);
+ directSources = sourcesData.map(source => ({
+ label: String(source.label || 'Default'),
+ url: String(source.file)
+ })).filter(source => !!source.url);
+ return {
+ fids: [],
+ shareKey,
+ directSources
+ };
+ } catch (e) {
+ console.log(`Error decoding direct jwplayer sources: ${e.message}`);
+ }
+ }
+ }
+
+ // File list check
+ const fileElements = $('div.file');
+ if (fileElements.length === 0 && !(directSources && directSources.length > 0)) { // Check if directSources also not found
+ console.log(`No files or direct sources found on FebBox page: ${febboxUrl}`);
+ // console.timeEnd(timerLabel);
+ return { fids: [], shareKey, directSources: [] }; // Return empty directSources as well
+ }
+
+ fileElements.each((index, element) => {
+ const feEl = $(element);
+ const dataId = feEl.attr('data-id');
+ if (!dataId || !/^\d+$/.test(dataId) || feEl.hasClass('open_dir')) {
+ return; // Skip folders or invalid IDs
+ }
+ videoFidsFound.push(dataId);
+ });
+
+ // At the end of the function, before returning, save the parsed data
+ const parsedResult = { fids: [...new Set(videoFidsFound)], shareKey, directSources };
+ await saveToCache(cacheKeyParsed, parsedResult, cacheSubDirParsed);
+ // console.log(` SAVED PARSED FebBox page data to cache: ${febboxUrl}`);
+ // profiling disabled (timerLabel removed)
+ return parsedResult;
+};
+
+// Function to convert IMDb ID to TMDB ID using TMDB API
+// MODIFICATION: Accept expectedType parameter to prioritize correct content type
+const convertImdbToTmdb = async (imdbId, regionPreference = null, expectedType = null) => {
+ console.time(`convertImdbToTmdb_total_${imdbId}`);
+ if (!imdbId || !imdbId.startsWith('tt')) {
+ console.log(' Invalid IMDb ID format provided for conversion.', imdbId);
+ console.timeEnd(`convertImdbToTmdb_total_${imdbId}`);
+ return null;
+ }
+ console.log(` Attempting to convert IMDb ID: ${imdbId} to TMDB ID${expectedType ? ` (expected type: ${expectedType})` : ''}.`);
+
+ const cacheSubDir = 'tmdb_external_id';
+ // Include expected type in cache key to avoid conflicts between movie/tv requests
+ const cacheKey = `imdb-${imdbId}${expectedType ? `-${expectedType}` : ''}.json`;
+ const cachedData = await getFromCache(cacheKey, cacheSubDir);
+
+ if (cachedData) {
+ console.log(` IMDb to TMDB conversion found in CACHE for ${imdbId}:`, cachedData);
+ // Ensure cached data has the expected structure
+ if (cachedData.tmdbId && cachedData.tmdbType) {
+ console.timeEnd(`convertImdbToTmdb_total_${imdbId}`);
+ return cachedData;
+ }
+ console.log(' Cached data for IMDb conversion is malformed. Fetching fresh.');
+ }
+
+ const TMDB_API_KEY = obtainTmdbKey();
+ const findApiUrl = `${TMDB_BASE_URL}/find/${imdbId}?api_key=${TMDB_API_KEY}&external_source=imdb_id`;
+ console.log(` Fetching from TMDB find API: ${findApiUrl}`);
+ console.time(`convertImdbToTmdb_apiCall_${imdbId}`);
+
+ try {
+ const response = await axios.get(findApiUrl, { timeout: 10000 });
+ console.timeEnd(`convertImdbToTmdb_apiCall_${imdbId}`);
+ const findResults = response.data;
+
+ if (findResults) {
+ let result = null;
+
+ // Context-aware prioritization based on expected type
+ if (expectedType === 'tv' || expectedType === 'series') {
+ // For series requests, prioritize TV results
+ if (findResults.tv_results && findResults.tv_results.length > 0) {
+ result = { tmdbId: String(findResults.tv_results[0].id), tmdbType: 'tv', title: findResults.tv_results[0].name || findResults.tv_results[0].original_name };
+ console.log(` Prioritized TV result for series request: ${result.title}`);
+ } else if (findResults.movie_results && findResults.movie_results.length > 0) {
+ result = { tmdbId: String(findResults.movie_results[0].id), tmdbType: 'movie', title: findResults.movie_results[0].title || findResults.movie_results[0].original_title };
+ console.log(` Fallback to movie result for series request: ${result.title}`);
+ }
+ } else if (expectedType === 'movie') {
+ // For movie requests, prioritize movie results
+ if (findResults.movie_results && findResults.movie_results.length > 0) {
+ result = { tmdbId: String(findResults.movie_results[0].id), tmdbType: 'movie', title: findResults.movie_results[0].title || findResults.movie_results[0].original_title };
+ console.log(` Prioritized movie result for movie request: ${result.title}`);
+ } else if (findResults.tv_results && findResults.tv_results.length > 0) {
+ result = { tmdbId: String(findResults.tv_results[0].id), tmdbType: 'tv', title: findResults.tv_results[0].name || findResults.tv_results[0].original_name };
+ console.log(` Fallback to TV result for movie request: ${result.title}`);
+ }
+ } else {
+ // Default behavior: prioritize movie results, then tv results (backward compatibility)
+ if (findResults.movie_results && findResults.movie_results.length > 0) {
+ result = { tmdbId: String(findResults.movie_results[0].id), tmdbType: 'movie', title: findResults.movie_results[0].title || findResults.movie_results[0].original_title };
+ } else if (findResults.tv_results && findResults.tv_results.length > 0) {
+ result = { tmdbId: String(findResults.tv_results[0].id), tmdbType: 'tv', title: findResults.tv_results[0].name || findResults.tv_results[0].original_name };
+ }
+ }
+
+ if (findResults.person_results && findResults.person_results.length > 0 && !result) {
+ // Could handle other types if necessary, e.g. person, but for streams, movie/tv are key
+ console.log(` IMDb ID ${imdbId} resolved to a person, not a movie or TV show on TMDB.`);
+ } else if (!result) {
+ console.log(` No movie or TV results found on TMDB for IMDb ID ${imdbId}. Response:`, JSON.stringify(findResults).substring(0, 200));
+ }
+
+ if (result && result.tmdbId && result.tmdbType) {
+ console.log(` Successfully converted IMDb ID ${imdbId} to TMDB ${result.tmdbType} ID ${result.tmdbId} (${result.title})`);
+ await saveToCache(cacheKey, result, cacheSubDir);
+ console.timeEnd(`convertImdbToTmdb_total_${imdbId}`);
+ return result;
+ } else {
+ console.log(` Could not convert IMDb ID ${imdbId} to a usable TMDB movie/tv ID.`);
+ }
+ }
+ } catch (error) {
+ if (console.timeEnd && typeof console.timeEnd === 'function') console.timeEnd(`convertImdbToTmdb_apiCall_${imdbId}`); // Ensure timer ends on error
+ const errorMessage = error.response ? `${error.message} (Status: ${error.response.status})` : error.message;
+ console.log(` Error during TMDB find API call for IMDb ID ${imdbId}: ${errorMessage}`);
+ }
+ console.timeEnd(`convertImdbToTmdb_total_${imdbId}`);
+ return null;
+};
+
+// Public API: fetch streams by TMDB reference
+const getStreamsFromTmdbId = async (tmdbType, tmdbId, seasonNum = null, episodeNum = null, regionPreference = null, userCookie = null) => {
+ const mainTimerLabel = `getStreamsFromTmdbId_total_${tmdbType}_${tmdbId}` + (seasonNum ? `_s${seasonNum}` : '') + (episodeNum ? `_e${episodeNum}` : '');
+ console.time(mainTimerLabel);
+ console.log(`Getting streams for TMDB ${tmdbType}/${tmdbId}${seasonNum !== null ? `, Season ${seasonNum}` : ''}${episodeNum !== null ? `, Episode ${episodeNum}` : ''}`);
+
+ // PRIMARY METHOD: Try PStream API first (if enabled)
+
+ try {
+ // Get TMDB data to extract IMDB ID
+ const tmdbData = await getTmdbDataForPStream(tmdbType, tmdbId);
+ if (tmdbData && tmdbData.imdbId) {
+ console.log(`[PStream Primary] Attempting PStream API for IMDB ID: ${tmdbData.imdbId}`);
+
+ const pstreamStreams = await getStreamsFromPStreamAPI(
+ tmdbData.imdbId,
+ tmdbType,
+ seasonNum,
+ episodeNum,
+ regionPreference,
+ userCookie
+ );
+
+ if (pstreamStreams && pstreamStreams.length > 0) {
+ console.log(`[PStream Primary] SUCCESS: Found ${pstreamStreams.length} streams from PStream API`);
+
+ // Fetch sizes for PStream streams
+ if (pstreamStreams.length > 0) {
+ const sizePromises = pstreamStreams.map(async (stream) => {
+ stream.size = await fetchStreamSize(stream.url);
+ return stream;
+ });
+ await Promise.all(sizePromises); // removed unused streamsWithSizes var
+ }
+
+ const sortedStreams = sortStreamsByQuality(pstreamStreams);
+ console.timeEnd(mainTimerLabel);
+ return sortedStreams;
+ } else {
+ console.log(`[PStream Primary] No streams found from PStream API, falling back to FebBox`);
+ }
+ } else {
+ console.log(`[PStream Primary] Could not get IMDB ID from TMDB data, falling back to FebBox`);
+ }
+ } catch (error) {
+ console.error(`[PStream Primary] Error with PStream API: ${error.message}, falling back to FebBox`);
+ }
+
+ // FALLBACK METHOD: Use original FebBox/ShowBox logic
+ console.log(`[Fallback] Using FebBox/ShowBox method`);
+ const tmdbInfo = await getShowboxUrlFromTmdbInfo(tmdbType, tmdbId, regionPreference);
+
+ // Then, get the ShowBox URL from TMDB ID
+ if (!tmdbInfo || !tmdbInfo.showboxUrl) {
+ console.log(`Could not construct ShowBox URL for TMDB ${tmdbType}/${tmdbId}`);
+ console.timeEnd(mainTimerLabel);
+ return [];
+ }
+ const showboxUrl = tmdbInfo.showboxUrl;
+ const mediaYear = tmdbInfo.year; // Year from TMDB
+
+ // Check if we have cached FebBox share links to avoid redundant ShowBox requests
+ let febboxShareInfos = tmdbInfo.febboxShareInfos;
+
+ if (!febboxShareInfos) {
+ // Only make ShowBox request if FebBox links are not cached
+ console.log(`No cached FebBox links found, extracting from ShowBox: ${showboxUrl}`);
+ const showboxScraper = new ShowBoxScraper(regionPreference, userCookie);
+ febboxShareInfos = await showboxScraper.extractFebboxShareLinks(showboxUrl);
+
+ if (!febboxShareInfos || febboxShareInfos.length === 0) {
+ console.log(`No FebBox share links found for ${showboxUrl}`);
+ console.timeEnd(mainTimerLabel);
+ return [];
+ }
+
+ // Update cache with FebBox share links to avoid future ShowBox requests
+ if (process.env.DISABLE_CACHE !== 'true') {
+ const updatedTmdbInfo = { ...tmdbInfo, febboxShareInfos };
+ const urlCacheSubDir = 'showbox_final_url';
+ const urlCacheKey = `v3_${tmdbType}_${tmdbId}.json`;
+ await saveToCache(urlCacheKey, updatedTmdbInfo, urlCacheSubDir);
+ console.log(`[Final URL Cache] UPDATED with FebBox links for ${tmdbType}/${tmdbId}`);
+ }
+ } else {
+ console.log(`[Final URL Cache] Using cached FebBox links, skipping ShowBox request for ${showboxUrl}`);
+ }
+
+ // MODIFIED: Process FebBox share links in parallel
+ const streamPromises = febboxShareInfos.map(async (shareInfo) => {
+ const streamsFromThisShareInfo = [];
+ try {
+ const febboxUrl = shareInfo.febbox_share_url;
+ let baseStreamTitle = shareInfo.showbox_title || "Unknown Title";
+ if (tmdbType === 'movie' && mediaYear) {
+ baseStreamTitle = `${baseStreamTitle} (${mediaYear})`;
+ }
+
+ console.log(`Processing FebBox URL: ${febboxUrl} (${baseStreamTitle})`);
+
+ if (tmdbType === 'tv' && seasonNum !== null) {
+ // Call refactored processShowWithSeasonsEpisodes (which now returns streams)
+ const tvStreams = await processShowWithSeasonsEpisodes(febboxUrl, baseStreamTitle, seasonNum, episodeNum, true, regionPreference, userCookie);
+ streamsFromThisShareInfo.push(...tvStreams);
+ } else {
+ // Handle movies or TV shows without season/episode specified
+ const { fids, shareKey, directSources } = await extractFidsFromFebboxPage(febboxUrl, regionPreference, userCookie);
+
+ if (directSources && directSources.length > 0) {
+ for (const source of directSources) {
+ const streamTitle = `${baseStreamTitle} - ${source.label}`;
+ let key5FromDirectSource = null;
+ try {
+ const urlParams = new URLSearchParams(new URL(source.url).search);
+ if (urlParams.has('KEY5')) {
+ key5FromDirectSource = urlParams.get('KEY5');
+ }
+ } catch (e) { /* ignore if URL parsing fails */ }
+ streamsFromThisShareInfo.push({
+ title: streamTitle,
+ url: source.url,
+ quality: parseQualityFromLabel(source.label),
+ codecs: extractCodecDetails(key5FromDirectSource || streamTitle)
+ });
+ }
+ // If direct sources are found, original code used 'continue',
+ // effectively skipping FID processing for this shareInfo.
+ // This behavior is maintained as FID processing is in the 'else if' block.
+ } else if (fids.length > 0 && shareKey) { // Only process FIDs if no directSources were found
+ const fidPromises = fids.map(fid => fetchSourcesForSingleFid(fid, shareKey, regionPreference, userCookie));
+ const fidSourcesArray = await Promise.all(fidPromises);
+
+ for (const sources of fidSourcesArray) {
+ if (!sources || !Array.isArray(sources)) {
+ console.log(` Warning: Invalid sources data received: ${typeof sources}`);
+ continue;
+ }
+
+ for (const source of sources) {
+ if (!source || !source.url || !source.label) {
+ console.log(` Warning: Invalid source object: ${JSON.stringify(source)}`);
+ continue;
+ }
+
+ const streamTitle = `${baseStreamTitle} - ${source.label}`;
+ streamsFromThisShareInfo.push({
+ title: streamTitle,
+ url: source.url,
+ quality: parseQualityFromLabel(source.label),
+ codecs: extractCodecDetails(source.detailedFilename || streamTitle)
+ });
+ }
+ }
+ } else if (!directSources || directSources.length === 0) {
+ console.log(`No FIDs or share key found, and no direct sources for ${febboxUrl}`);
+ }
+ }
+ } catch (error) {
+ console.error(`Error processing share info for ${shareInfo.febbox_share_url}: ${error.message}`);
+ }
+ return streamsFromThisShareInfo;
+ });
+
+ const nestedStreams = await Promise.all(streamPromises);
+ const allStreams = nestedStreams.flat();
+
+ // Fetch sizes for all streams concurrently
+ if (allStreams.length > 0) {
+ console.time(`getStreamsFromTmdbId_fetchStreamSizes_${tmdbType}_${tmdbId}`);
+ const sizePromises = allStreams.map(async (stream) => {
+ stream.size = await fetchStreamSize(stream.url);
+ return stream;
+ });
+ await Promise.all(sizePromises); // removed unused streamsWithSizes var
+ console.timeEnd(`getStreamsFromTmdbId_fetchStreamSizes_${tmdbType}_${tmdbId}`);
+ }
+
+ // Sort streams by quality before returning
+ const sortedStreams = sortStreamsByQuality(allStreams);
+
+ // Filter out 360p and 480p streams
+ const streamsToShowBoxFiltered = sortedStreams.filter(stream => {
+ const quality = stream.quality ? String(stream.quality).toLowerCase() : '';
+ if (quality === '360p' || quality === '480p') {
+ console.log(` Filtering out potential ShowBox low-quality stream: ${stream.title} (${stream.quality})`);
+ return false;
+ }
+ return true;
+ });
+
+ // Apply size limit if not using a personal cookie
+ let finalFilteredStreams = streamsToShowBoxFiltered;
+ if (!userCookie && !global.currentRequestUserCookie) {
+ console.log('[SizeLimit] No personal cookie detected. Applying 9GB size limit to ShowBox streams.');
+ const NINE_GB_IN_BYTES = 9 * 1024 * 1024 * 1024;
+ finalFilteredStreams = streamsToShowBoxFiltered.filter(stream => {
+ const sizeInBytes = parseSizeToBytes(stream.size);
+ if (sizeInBytes >= NINE_GB_IN_BYTES) {
+ console.log(`[SizeLimit] Filtering out ShowBox stream due to size (${stream.size || 'Unknown size'}): ${stream.title}`);
+ return false;
+ }
+ return true;
+ });
+ }
+
+ if (finalFilteredStreams.length > 0) {
+ console.log(`Found ${finalFilteredStreams.length} streams (sorted, ShowBox-low-quality-filtered, and size-limited if applicable):`);
+ finalFilteredStreams.slice(0, 5).forEach((stream, i) => {
+ console.log(` ${i + 1}. ${stream.quality} (${stream.size || 'Unknown size'}) [${(stream.codecs || []).join(', ') || 'No codec info'}]: ${stream.title}`);
+ });
+ if (finalFilteredStreams.length > 5) {
+ console.log(` ... and ${finalFilteredStreams.length - 5} more streams`);
+ }
+ }
+ console.timeEnd(mainTimerLabel);
+ return finalFilteredStreams;
+};
+
+// Function to handle TV shows with seasons and episodes
+// MODIFICATION: Accept scraperApiKey -> MODIFICATION: Remove scraperApiKey
+// New parameter: resolveFids, defaults to true. If false, skips fetching sources for FIDs.
+const processShowWithSeasonsEpisodes = async (febboxUrl, showboxTitle, seasonNum, episodeNum, resolveFids = true, regionPreference = null, userCookie = null, retryAttempt = 0) => {
+ const processTimerLabel = `processShowWithSeasonsEpisodes_total_s${seasonNum}` + (episodeNum ? `_e${episodeNum}` : '_all') + (resolveFids ? '_resolve' : '_noresolve') + (retryAttempt > 0 ? `_retry${retryAttempt}` : '');
+ console.time(processTimerLabel);
+ console.log(`Processing TV Show: ${showboxTitle}, Season: ${seasonNum}, Episode: ${episodeNum !== null ? episodeNum : 'all'}${resolveFids ? '' : ' (FIDs not resolved)'}${retryAttempt > 0 ? ` (Retry attempt ${retryAttempt})` : ''}`);
+
+ const streamsForThisCall = []; // Initialize local array to store streams for this call
+ let selectedEpisode = null; // Ensure selectedEpisode is declared here
+
+ // Cache for the main FebBox page
+ const cacheSubDirMain = 'febbox_page_html';
+ const urlHash = crypto.createHash('md5').update(febboxUrl).digest('hex');
+ const cacheKeyMain = `${urlHash}.html`;
+
+ // Try to get the main page from cache first (skip cache on retry)
+ let contentHtml = retryAttempt > 0 ? null : await getFromCache(cacheKeyMain, cacheSubDirMain);
+
+ if (!contentHtml) {
+ // If not cached, fetch the HTML content
+ const fetchMainPageTimer = `processShowWithSeasonsEpisodes_fetchMainPage_s${seasonNum}`;
+ console.time(fetchMainPageTimer);
+
+ const cookieForRequest = await getCookieForRequest(regionPreference, userCookie);
+
+ const finalFebboxUrl = febboxUrl;
+ const axiosConfigMainPage = {
+ headers: { 'Cookie': `ui=${cookieForRequest}` },
+ timeout: 20000
+ };
+
+ console.log(`Fetching main FebBox page ${febboxUrl} directly${retryAttempt > 0 ? ' (forced refresh for missing season)' : ''}`);
+
+ try {
+ const response = await axios.get(finalFebboxUrl, axiosConfigMainPage);
+ contentHtml = response.data;
+ if (typeof contentHtml === 'string' && contentHtml.length > 0) {
+ await saveToCache(cacheKeyMain, contentHtml, cacheSubDirMain);
+ }
+ console.timeEnd(fetchMainPageTimer);
+ } catch (error) {
+ console.log(`Failed to fetch HTML content from ${febboxUrl}: ${error.message}`);
+ console.timeEnd(fetchMainPageTimer);
+ console.timeEnd(processTimerLabel);
+ return;
+ }
+ }
+
+ if (!contentHtml) {
+ console.log(`No HTML content available for ${febboxUrl}`);
+ console.timeEnd(processTimerLabel);
+ return;
+ }
+
+ // Parse the HTML to find folders (seasons)
+ const $ = cheerio.load(contentHtml);
+ const shareKey = contentHtml.match(/(?:var share_key\s*=|share_key:\s*|shareid=)"?([a-zA-Z0-9-]+)"?/)?.[1];
+
+ if (!shareKey) {
+ console.log(`Could not extract share_key from ${febboxUrl}`);
+ console.timeEnd(processTimerLabel);
+ return;
+ }
+
+ const folders = [];
+ const fileElements = $('div.file.open_dir');
+
+ fileElements.each((index, element) => {
+ const feEl = $(element);
+ const dataId = feEl.attr('data-id');
+ if (!dataId || !/^\d+$/.test(dataId)) {
+ return; // Skip if data-id is missing or not a number
+ }
+
+ const folderNameEl = feEl.find('p.file_name');
+ const folderName = folderNameEl.length ? folderNameEl.text().trim() : feEl.attr('data-path') || `Folder_${dataId}`;
+
+ // Extract season number from folder name for more accurate matching
+ let extractedSeasonNum = null;
+ const folderNameLower = folderName.toLowerCase();
+
+ // Try more specific season number extraction patterns
+ const seasonPatterns = [
+ /season\s+(\d+)/i, // Season 1
+ /s(\d+)/i, // S1
+ /season(\d+)/i // Season1
+ ];
+
+ for (const pattern of seasonPatterns) {
+ const match = folderNameLower.match(pattern);
+ if (match && match[1]) {
+ extractedSeasonNum = parseInt(match[1], 10);
+ break;
+ }
+ }
+
+ // If no specific pattern matched, look for any standalone numbers
+ if (extractedSeasonNum === null) {
+ const numMatches = folderNameLower.match(/\b(\d+)\b/g);
+ if (numMatches && numMatches.length === 1) { // Only if exactly one number is found
+ extractedSeasonNum = parseInt(numMatches[0], 10);
+ }
+ }
+
+ folders.push({
+ id: dataId,
+ name: folderName,
+ extractedSeasonNum: extractedSeasonNum
+ });
+ });
+
+ if (folders.length === 0) {
+ console.log(`No season folders found on ${febboxUrl}`);
+ // It might be directly files, so try the original logic as fallback
+ console.time(`processShowWithSeasonsEpisodes_fallbackDirect_s${seasonNum}`);
+ const { fids, directSources } = await extractFidsFromFebboxPage(febboxUrl, regionPreference, userCookie);
+ console.timeEnd(`processShowWithSeasonsEpisodes_fallbackDirect_s${seasonNum}`);
+
+ if (directSources && directSources.length > 0) {
+ for (const source of directSources) {
+ const streamTitle = `${showboxTitle} - ${source.label}`;
+ streamsForThisCall.push({ // MODIFIED: Push to streamsForThisCall
+ title: streamTitle,
+ url: source.url,
+ quality: parseQualityFromLabel(source.label),
+ codecs: extractCodecDetails(source.detailedFilename || streamTitle)
+ });
+ }
+ console.timeEnd(processTimerLabel);
+ return streamsForThisCall;
+ }
+
+ if (fids.length > 0) {
+ console.time(`processShowWithSeasonsEpisodes_fallbackFids_s${seasonNum}_concurrent`);
+ const fallbackFidPromises = fids.map(fid => fetchSourcesForSingleFid(fid, shareKey, regionPreference, userCookie));
+ const fallbackFidSourcesArray = await Promise.all(fallbackFidPromises);
+ console.timeEnd(`processShowWithSeasonsEpisodes_fallbackFids_s${seasonNum}_concurrent`);
+
+ for (const sources of fallbackFidSourcesArray) {
+ for (const source of sources) {
+ const streamTitle = `${showboxTitle} - ${source.label}`;
+ streamsForThisCall.push({ // MODIFIED: Push to streamsForThisCall
+ title: streamTitle,
+ url: source.url,
+ quality: parseQualityFromLabel(source.label),
+ codecs: extractCodecDetails(source.detailedFilename || streamTitle)
+ });
+ }
+ }
+ }
+ console.timeEnd(processTimerLabel);
+ return streamsForThisCall;
+ }
+
+ console.log(`Found ${folders.length} season folders:`, folders.map(f =>
+ `"${f.name}" (ID: ${f.id}, Extracted Season: ${f.extractedSeasonNum !== null ? f.extractedSeasonNum : 'None'})`
+ ).join(', '));
+
+ // Find matching season folder
+ let selectedFolder = null;
+
+ // First, look for exact season number match using extracted season numbers
+ for (const folder of folders) {
+ if (folder.extractedSeasonNum === seasonNum) {
+ selectedFolder = folder;
+ console.log(`Found exact season match: "${folder.name}" with extracted season number ${folder.extractedSeasonNum}`);
+ break;
+ }
+ }
+
+ // If no exact match by extracted number, try the text pattern matches (legacy approach)
+ if (!selectedFolder) {
+ for (const folder of folders) {
+ const folderNameLower = folder.name.toLowerCase();
+
+ // More precise matching patterns to avoid partial matches
+ if (
+ folderNameLower === `season ${seasonNum}` ||
+ folderNameLower === `s${seasonNum}` ||
+ folderNameLower === `season${seasonNum}` ||
+ // Match with word boundaries to avoid Season 1 matching Season 10
+ folderNameLower.match(new RegExp(`\\bseason\\s+${seasonNum}\\b`)) ||
+ folderNameLower.match(new RegExp(`\\bs${seasonNum}\\b`))
+ ) {
+ selectedFolder = folder;
+ console.log(`Found season match via text pattern: "${folder.name}"`);
+ break;
+ }
+ }
+ }
+
+ // If still no match, sort folders by extracted season number and try index-based approach
+ if (!selectedFolder && seasonNum > 0 && seasonNum <= folders.length) {
+ // First try to sort by extracted season number (if available)
+ const sortedFolders = [...folders].sort((a, b) => {
+ // If both have extracted season numbers, compare them
+ if (a.extractedSeasonNum !== null && b.extractedSeasonNum !== null) {
+ return a.extractedSeasonNum - b.extractedSeasonNum;
+ }
+ // If only one has extracted season number, put it first
+ if (a.extractedSeasonNum !== null) return -1;
+ if (b.extractedSeasonNum !== null) return 1;
+ // Otherwise, keep original order
+ return 0;
+ });
+
+ // Log the sorted folders for debugging
+ console.log(`Sorted folders by season number:`, sortedFolders.map(f =>
+ `"${f.name}" (ID: ${f.id}, Extracted Season: ${f.extractedSeasonNum !== null ? f.extractedSeasonNum : 'None'})`
+ ).join(', '));
+
+ // Check if any folder has an extracted season number matching the requested season
+ const exactExtractedMatch = sortedFolders.find(f => f.extractedSeasonNum === seasonNum);
+ if (exactExtractedMatch) {
+ selectedFolder = exactExtractedMatch;
+ console.log(`Found exact season match in sorted folders: "${selectedFolder.name}" with season ${selectedFolder.extractedSeasonNum}`);
+ }
+ // Otherwise, if we have folders with extracted season numbers, use them for mapping
+ else if (sortedFolders.some(f => f.extractedSeasonNum !== null)) {
+ // If we have some season numbers, try to find the appropriate folder
+ // This approach is better than using index because folders might be out of order
+ const validFolders = sortedFolders.filter(f => f.extractedSeasonNum !== null);
+ if (seasonNum <= validFolders.length) {
+ selectedFolder = validFolders[seasonNum - 1];
+ console.log(`Using sorted folder by extracted number index: "${selectedFolder.name}" at position ${seasonNum}`);
+ }
+ }
+ // Last resort: use index-based approach on original folder order
+ else {
+ selectedFolder = folders[seasonNum - 1];
+ console.log(`Using original folder order index: "${selectedFolder.name}" at position ${seasonNum}`);
+ }
+ }
+
+ if (!selectedFolder) {
+ // If season not found and this is the first attempt, try refreshing the cache
+ if (retryAttempt === 0) {
+ console.log(`Season ${seasonNum} not found in cached data. Attempting fresh fetch...`);
+ console.timeEnd(processTimerLabel);
+ // Recursive call with retry attempt to force fresh fetch
+ return await processShowWithSeasonsEpisodes(febboxUrl, showboxTitle, seasonNum, episodeNum, resolveFids, regionPreference, userCookie, 1);
+ } else {
+ console.log(`Could not find season ${seasonNum} folder in ${febboxUrl} even after fresh fetch. Aborting.`);
+ console.timeEnd(processTimerLabel);
+ return streamsForThisCall;
+ }
+ }
+
+ console.log(`Selected season folder: ${selectedFolder.name} (ID: ${selectedFolder.id})`);
+
+ // Cache for season folder content
+ const cacheSubDirFolderHtml = 'febbox_season_folders';
+ const cacheSubDirFolderParsed = 'febbox_parsed_season_folders';
+ const cacheKeyFolderHtml = `share-${shareKey}_folder-${selectedFolder.id}.html`;
+ const cacheKeyFolderParsed = `share-${shareKey}_folder-${selectedFolder.id}_parsed.json`;
+
+ let folderHtml = null;
+ const episodeDetails = []; // Declare episodeDetails here, initialized as an empty array
+ const episodeFids = []; // Declare episodeFids here, initialized as an empty array
+
+ const cachedParsedEpisodeList = await getFromCache(cacheKeyFolderParsed, cacheSubDirFolderParsed);
+ if (cachedParsedEpisodeList && Array.isArray(cachedParsedEpisodeList)) {
+ console.log(` CACHE HIT for parsed episode list: Season ${seasonNum}, Folder ${selectedFolder.id}`);
+ episodeDetails.push(...cachedParsedEpisodeList); // Populate if cache hit
+ } else {
+ // Parsed list not in cache, so we need to process HTML
+ // console.log(` CACHE MISS for parsed episode list: Season ${seasonNum}, Folder ${selectedFolder.id}`);
+ folderHtml = await getFromCache(cacheKeyFolderHtml, cacheSubDirFolderHtml); // Assign to the higher-scoped folderHtml
+
+ if (!folderHtml) {
+ const fetchFolderTimer = `processShowWithSeasonsEpisodes_fetchFolder_s${seasonNum}_id${selectedFolder.id}`;
+ console.time(fetchFolderTimer);
+ try {
+ const targetFolderListUrl = `${FEBBOX_FILE_SHARE_LIST_URL}?share_key=${shareKey}&parent_id=${selectedFolder.id}&is_html=1&pwd=`;
+
+ const cookieForRequestFolder = await getCookieForRequest(regionPreference, userCookie); // Simplified cookie call
+ const finalFolderUrl = targetFolderListUrl;
+ const axiosConfigFolder = {
+ headers: {
+ 'Cookie': `ui=${cookieForRequestFolder}`,
+ 'Referer': febboxUrl,
+ 'X-Requested-With': 'XMLHttpRequest'
+ },
+ timeout: 20000
+ };
+
+ console.log(`Fetching FebBox folder ${targetFolderListUrl} directly`);
+
+ const folderResponse = await axios.get(finalFolderUrl, axiosConfigFolder);
+ console.log(` FebBox folder list response status: ${folderResponse.status}`);
+ console.log(` FebBox folder list response content-type: ${folderResponse.headers['content-type']}`);
+ // Log the beginning of the data to inspect its structure
+ const responseDataPreview = (typeof folderResponse.data === 'string')
+ ? folderResponse.data.substring(0, 500)
+ : JSON.stringify(folderResponse.data).substring(0, 500);
+ console.log(` FebBox folder list response data (preview): ${responseDataPreview}`);
+
+ if (folderResponse.data && typeof folderResponse.data === 'object' && folderResponse.data.html) {
+ folderHtml = folderResponse.data.html;
+ console.log(` Successfully extracted HTML from FebBox folder list JSON response.`);
+ } else if (typeof folderResponse.data === 'string') {
+ folderHtml = folderResponse.data;
+ console.log(` Received direct HTML string from FebBox folder list response.`);
+ } else {
+ console.log(` Invalid or unexpected response format from FebBox folder API for ${selectedFolder.id}. Data: ${JSON.stringify(folderResponse.data)}`);
+ // folderHtml remains null
+ }
+
+ if (folderHtml && folderHtml.trim().length > 0) { // Also check if html is not just whitespace
+ await saveToCache(cacheKeyFolderHtml, folderHtml, cacheSubDirFolderHtml);
+ console.log(` Cached FebBox folder HTML for ${selectedFolder.id}`);
+ } else {
+ console.log(` Folder HTML from FebBox was empty or null for ${selectedFolder.id}. Not caching.`);
+ folderHtml = null; // Ensure it's explicitly null if empty
+ }
+ console.timeEnd(fetchFolderTimer);
+ } catch (error) {
+ console.error(` ERROR fetching FebBox folder content for ${selectedFolder.id}: ${error.message}`);
+ if (error.response) {
+ console.error(` FebBox Error Status: ${error.response.status}`);
+ console.error(` FebBox Error Data: ${JSON.stringify(error.response.data)}`);
+ }
+ // console.timeEnd(fetchFolderTimer); // fetchFolderTimer might not be defined if cache hit for HTML but miss for parsed
+ console.timeEnd(processTimerLabel); // End outer timer
+ return streamsForThisCall; // Return empty streams array if fetching folder content fails
+ }
+ }
+ }
+
+ // If episodeDetails is populated from cache, folderHtml might be null. That's okay.
+ // If episodeDetails is still empty, we must have folderHtml to parse.
+ if (episodeDetails.length === 0) { // Only proceed if we didn't get data from parsed cache
+ if (!folderHtml) { // If still no folderHtml (e.g. HTML cache miss and fetch fail), then error out
+ console.log(`No folder HTML content available (and no cached parsed list) for folder ${selectedFolder.id}`);
+ console.timeEnd(processTimerLabel);
+ return streamsForThisCall;
+ }
+
+ // Parse the folderHtml since we didn't have a cached parsed list
+ const $folder = cheerio.load(folderHtml);
+ $folder('div.file').each((index, element) => {
+ const feEl = $folder(element);
+ const dataId = feEl.attr('data-id');
+ if (!dataId || !/^\d+$/.test(dataId) || feEl.hasClass('open_dir')) {
+ return;
+ }
+
+ const fileNameEl = feEl.find('p.file_name');
+ const fileName = fileNameEl.length ? fileNameEl.text().trim() : `File_${dataId}`;
+
+ episodeDetails.push({
+ fid: dataId,
+ name: fileName,
+ episodeNum: getEpisodeNumberFromName(fileName)
+ });
+ });
+
+ // After parsing, save the extracted episodeDetails to its cache
+ // This will also save an empty array if parsing yields no episodes, preventing re-parsing of empty folders
+ await saveToCache(cacheKeyFolderParsed, episodeDetails, cacheSubDirFolderParsed);
+ if (episodeDetails.length > 0) {
+ // console.log(` SAVED PARSED episode list to cache: Season ${seasonNum}, Folder ${selectedFolder.id}`);
+ }
+ }
+
+ // Sort episodes by their number (whether from cache or freshly parsed)
+ // Ensure episodeDetails is sorted if populated
+ if (episodeDetails.length > 0) {
+ episodeDetails.sort((a, b) => a.episodeNum - b.episodeNum);
+ }
+
+ // If episode number specified, find matching episode
+ if (episodeNum !== null) {
+ // First try exact episode number match
+ for (const episode of episodeDetails) {
+ if (episode.episodeNum === episodeNum) {
+ selectedEpisode = episode;
+ break;
+ }
+ }
+
+ // If no match by number, try index-based (episode 1 = first file)
+ if (!selectedEpisode && episodeNum > 0 && episodeNum <= episodeDetails.length) {
+ selectedEpisode = episodeDetails[episodeNum - 1];
+ }
+
+ if (!selectedEpisode) {
+ console.log(`Could not find episode ${episodeNum} in season folder ${selectedFolder.name}`);
+ console.timeEnd(processTimerLabel);
+ return streamsForThisCall;
+ }
+
+ console.log(`Found episode: ${selectedEpisode.name} (FID: ${selectedEpisode.fid})`);
+ episodeFids.push(selectedEpisode.fid); // Now episodeFids is already declared
+ } else {
+ // If no episode specified, process all episodes
+ // Ensure episodeDetails is populated before mapping
+ if (episodeDetails.length > 0) {
+ episodeFids.push(...episodeDetails.map(ep => ep.fid)); // episodeFids is already declared
+ } else {
+ console.log(` No episode details found for folder ${selectedFolder.name} to extract FIDs for all episodes.`);
+ }
+ }
+
+ // Get video sources for each episode FID
+ if (resolveFids && episodeFids.length > 0) { // Check resolveFids flag here
+ const episodeTimerLabel = `processShowWithSeasonsEpisodes_fetchEpisodeSources_s${seasonNum}` + (episodeNum ? `_e${episodeNum}` : '_allEp_concurrent');
+ console.time(episodeTimerLabel);
+ const episodeSourcePromises = episodeFids.map(fid =>
+ fetchSourcesForSingleFid(fid, shareKey, regionPreference, userCookie)
+ .then(sources => ({ fid, sources }))
+ );
+ const episodeSourcesResults = await Promise.all(episodeSourcePromises);
+ console.timeEnd(episodeTimerLabel);
+
+ for (const result of episodeSourcesResults) {
+ // Check if result is defined and has sources
+ if (result && result.fid && result.sources && Array.isArray(result.sources)) {
+ const { fid, sources } = result;
+
+ for (const source of sources) {
+ const episodeDetail = episodeDetails.find(ep => ep.fid === fid);
+ const episodeName = episodeDetail ? episodeDetail.name : '';
+
+ const streamTitle = `${showboxTitle} - S${seasonNum}${episodeNum && selectedEpisode && fid === selectedEpisode.fid ? `E${episodeNum}` : (episodeDetail ? `E${episodeDetail.episodeNum}` : '')} - ${episodeName} - ${source.label}`;
+ streamsForThisCall.push({ // MODIFIED: Push to streamsForThisCall
+ title: streamTitle,
+ url: source.url,
+ quality: parseQualityFromLabel(source.label),
+ codecs: extractCodecDetails(source.detailedFilename || streamTitle)
+ });
+ }
+ } else {
+ console.log(` Warning: Invalid result structure for an episode source: ${JSON.stringify(result)}`);
+ }
+ }
+ } else if (!resolveFids && episodeFids.length > 0) {
+ console.log(` Skipping FID resolution for ${episodeFids.length} episodes in S${seasonNum} as per request.`);
+ }
+ console.timeEnd(processTimerLabel);
+ return streamsForThisCall; // MODIFIED: Return the collected streams
+};
+
+// Helper function to get episode number from filename
+const getEpisodeNumberFromName = (name) => {
+ const nameLower = name.toLowerCase();
+
+ // Common TV episode naming patterns
+ const patterns = [
+ /[._\s-]s\d{1,2}[._\s-]?e(\d{1,3})[._\s-]?/, // S01E01, s1e1
+ /[._\s-]e[cp]?[._\s-]?(\d{1,3})[._\s-]?/, // E01, EP01
+ /episode[._\s-]?(\d{1,3})/, // Episode 1
+ /part[._\s-]?(\d{1,3})/, // Part 1
+ /ep[._\s-]?(\d{1,3})/, // Ep 1
+ /pt[._\s-]?(\d{1,3})/ // Pt 1
+ ];
+
+ for (const pattern of patterns) {
+ const match = nameLower.match(pattern);
+ if (match && match[1]) {
+ return parseInt(match[1], 10);
+ }
+ }
+
+ // Try to find standalone numbers that might be episode numbers
+ const simpleNumMatches = nameLower.match(/(? 0 && num < 200 &&
+ !((simpleNumMatches[0] + "p") === nameLower) &&
+ !nameLower.includes("x" + simpleNumMatches[0]) &&
+ !nameLower.includes("h" + simpleNumMatches[0]) &&
+ (nameLower.split(simpleNumMatches[0]).length - 1 <= 1 || !["1", "2"].includes(simpleNumMatches[0]))
+ ) {
+ return num;
+ }
+ }
+
+ // Default to infinity (for sorting purposes)
+ return Infinity;
+};
+
+// Helper function to parse quality from label
+const parseQualityFromLabel = (label) => {
+ if (!label) return "ORG";
+
+ const labelLower = String(label).toLowerCase();
+
+ if (labelLower.includes('1080p') || labelLower.includes('1080')) {
+ return "1080p";
+ } else if (labelLower.includes('720p') || labelLower.includes('720')) {
+ return "720p";
+ } else if (labelLower.includes('480p') || labelLower.includes('480')) {
+ return "480p";
+ } else if (labelLower.includes('360p') || labelLower.includes('360')) {
+ return "360p";
+ } else if (labelLower.includes('2160p') || labelLower.includes('2160') ||
+ labelLower.includes('4k') || labelLower.includes('uhd')) {
+ return "2160p";
+ } else if (labelLower.includes('hd')) {
+ return "720p"; // Assuming HD is 720p
+ } else if (labelLower.includes('sd')) {
+ return "480p"; // Assuming SD is 480p
+ }
+
+ // Use ORG (original) label for unknown quality
+ return "ORG";
+};
+
+// Helper function to parse size string to bytes
+const parseSizeToBytes = (sizeString) => {
+ if (!sizeString || typeof sizeString !== 'string') return Number.MAX_SAFE_INTEGER;
+
+ const sizeLower = sizeString.toLowerCase();
+
+ if (sizeLower.includes('unknown') || sizeLower.includes('n/a')) {
+ return Number.MAX_SAFE_INTEGER; // Sort unknown/NA sizes last
+ }
+
+ const units = {
+ gb: 1024 * 1024 * 1024,
+ mb: 1024 * 1024,
+ kb: 1024,
+ b: 1
+ };
+
+ const match = sizeString.match(/([\d.]+)\s*(gb|mb|kb|b)/i);
+ if (match && match[1] && match[2]) {
+ const value = parseFloat(match[1]);
+ const unit = match[2].toLowerCase();
+ if (!isNaN(value) && units[unit]) {
+ return Math.floor(value * units[unit]);
+ }
+ }
+ return Number.MAX_SAFE_INTEGER; // Fallback for unparsed strings
+};
+
+// Helper function to extract codec details from a string (filename/label)
+const extractCodecDetails = (text) => {
+ if (!text || typeof text !== 'string') return [];
+ const details = new Set();
+ const lowerText = text.toLowerCase();
+
+ // Video Codecs & Technologies
+ if (lowerText.includes('dolby vision') || lowerText.includes('dovi') || lowerText.includes('.dv.')) details.add('DV');
+ if (lowerText.includes('hdr10+') || lowerText.includes('hdr10plus')) details.add('HDR10+');
+ else if (lowerText.includes('hdr')) details.add('HDR'); // General HDR if not HDR10+
+ if (lowerText.includes('sdr')) details.add('SDR');
+
+ if (lowerText.includes('av1')) details.add('AV1');
+ else if (lowerText.includes('h265') || lowerText.includes('x265') || lowerText.includes('hevc')) details.add('H.265');
+ else if (lowerText.includes('h264') || lowerText.includes('x264') || lowerText.includes('avc')) details.add('H.264');
+
+ // Audio Codecs
+ if (lowerText.includes('atmos')) details.add('Atmos');
+ if (lowerText.includes('truehd') || lowerText.includes('true-hd')) details.add('TrueHD');
+ if (lowerText.includes('dts-hd ma') || lowerText.includes('dtshdma') || lowerText.includes('dts-hdhr')) details.add('DTS-HD MA');
+ else if (lowerText.includes('dts-hd')) details.add('DTS-HD'); // General DTS-HD if not MA/HR
+ else if (lowerText.includes('dts') && !lowerText.includes('dts-hd')) details.add('DTS'); // Plain DTS
+
+ if (lowerText.includes('eac3') || lowerText.includes('e-ac-3') || lowerText.includes('dd+') || lowerText.includes('ddplus')) details.add('EAC3');
+ else if (lowerText.includes('ac3') || (lowerText.includes('dd') && !lowerText.includes('dd+') && !lowerText.includes('ddp'))) details.add('AC3'); // Plain AC3/DD
+
+ if (lowerText.includes('aac')) details.add('AAC');
+ if (lowerText.includes('opus')) details.add('Opus');
+ if (lowerText.includes('mp3')) details.add('MP3');
+
+ // Bit depth (less common but useful)
+ if (lowerText.includes('10bit') || lowerText.includes('10-bit')) details.add('10-bit');
+ else if (lowerText.includes('8bit') || lowerText.includes('8-bit')) details.add('8-bit');
+
+ return Array.from(details);
+};
+
+// Utility function to sort streams by quality in order of resolution
+const sortStreamsByQuality = (streams) => {
+ // Quality ranking for output ordering
+ const qualityOrder = {
+ "ORG": 1, // ORG will show at the top (since it's at the bottom of the list)
+ "2160p": 2,
+ "1080p": 3,
+ "720p": 4,
+ "480p": 5,
+ "360p": 6 // 360p will show at the bottom
+ };
+
+ // Provider priority ordering (lower number = higher priority)
+ const providerSortKeys = {
+ 'ShowBox': 1,
+ 'Xprime.tv': 2,
+ 'HollyMovieHD': 3,
+ 'Soaper TV': 4,
+ // Default for unknown providers
+ default: 99
+ };
+
+ return [...streams].sort((a, b) => {
+ const qualityA = a.quality || "ORG";
+ const qualityB = b.quality || "ORG";
+
+ const orderA = qualityOrder[qualityA] || 10;
+ const orderB = qualityOrder[qualityB] || 10;
+
+ // First, compare by quality order
+ if (orderA !== orderB) {
+ return orderA - orderB;
+ }
+
+ // If qualities are the same, compare by size (descending - larger sizes first means earlier in array)
+ const sizeAInBytes = parseSizeToBytes(a.size);
+ const sizeBInBytes = parseSizeToBytes(b.size);
+
+ if (sizeAInBytes !== sizeBInBytes) {
+ return sizeBInBytes - sizeAInBytes;
+ }
+
+ // If quality AND size are the same, compare by provider
+ const providerA = a.provider || 'default';
+ const providerB = b.provider || 'default';
+
+ const providerOrderA = providerSortKeys[providerA] || providerSortKeys.default;
+ const providerOrderB = providerSortKeys[providerB] || providerSortKeys.default;
+
+ return providerOrderA - providerOrderB;
+ });
+}
+
+// Initialize the cache directory
+ensureCacheDir(CACHE_DIR).catch(console.error);
+
+// Fallback cookie loader removed (legacy loadFallbackCookies was deprecated).
+// No-op now: runtime only uses user-supplied cookies from config/override.
+
+// PStream API Configuration
+const PSTREAM_API_BASE_URL = 'https://fed-api.pstream.mov';
+const PSTREAM_ACCEPT_HEADER = 'pstream.org';
+
+// Region mapping for PStream API (FebBox regions -> PStream regions)
+const PSTREAM_REGION_MAPPING = {
+ // US Regions
+ 'USA7': 'East',
+ 'USA6': 'West',
+ 'USA5': 'East',
+ 'USA4': 'West',
+ 'USA3': 'West',
+ 'USA2': 'West',
+ 'USA1': 'West',
+
+ // European Regions
+ 'UK3': 'Europe',
+ 'FR1': 'Europe',
+ 'DE2': 'Europe',
+ 'EU1': 'Europe',
+ 'EU2': 'Europe',
+
+ // Asian Regions
+ 'HK1': 'Asia',
+ 'IN1': 'Asia',
+ 'SZ': 'Asia',
+ 'ASIA1': 'Asia',
+ 'ASIA2': 'Asia',
+
+ // Other Regions
+ 'CA1': 'East', // Canada maps to East (US East)
+ 'AU1': 'Asia' // Australia maps to Asia
+};
+
+// Function to map FebBox region to PStream region
+const mapRegionForPStream = (febboxRegion) => {
+ if (!febboxRegion) {
+ return PSTREAM_REGION_MAPPING[DEFAULT_OSS_REGION] || 'East';
+ }
+
+ const mappedRegion = PSTREAM_REGION_MAPPING[febboxRegion];
+ if (mappedRegion) {
+ return mappedRegion;
+ }
+
+ // Fallback to East if region not found
+ console.log(`[PStream] Region ${febboxRegion} not found in mapping, using East as fallback`);
+ return 'East';
+};
+
+// Function to fetch streams from PStream API (new primary method)
+const getStreamsFromPStreamAPI = async (imdbId, tmdbType, seasonNum = null, episodeNum = null, regionPreference = null, userCookie = null) => {
+ const timerLabel = `getStreamsFromPStreamAPI_${imdbId}_${tmdbType}` + (seasonNum ? `_s${seasonNum}` : '') + (episodeNum ? `_e${episodeNum}` : '');
+ console.time(timerLabel);
+
+ try {
+ // Build the PStream API URL
+ let apiUrl;
+ if (tmdbType === 'movie') {
+ apiUrl = `${PSTREAM_API_BASE_URL}/movie/${imdbId}`;
+ } else if (tmdbType === 'tv' && seasonNum !== null && episodeNum !== null) {
+ apiUrl = `${PSTREAM_API_BASE_URL}/tv/${imdbId}/${seasonNum}/${episodeNum}`;
+ } else {
+ console.log(`[PStream] Invalid parameters for ${tmdbType}: season=${seasonNum}, episode=${episodeNum}`);
+ return [];
+ }
+
+ console.log(`[PStream] Making request to: ${apiUrl}`);
+
+ // Get the region for PStream API
+ const pstreamRegion = mapRegionForPStream(regionPreference || global.lastRequestedRegion?.used);
+
+ // Prepare headers for PStream API
+ const headers = {
+ 'accept': PSTREAM_ACCEPT_HEADER,
+ 'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8',
+ 'origin': 'https://pstream.mov',
+ 'referer': `https://pstream.mov/media/tmdb-${tmdbType}-${imdbId}`,
+ 'region': pstreamRegion,
+ 'sec-ch-ua': '"Not;A=Brand";v="99", "Google Chrome";v="139", "Chromium";v="139"',
+ 'sec-ch-ua-mobile': '?0',
+ 'sec-ch-ua-platform': '"macOS"',
+ 'sec-fetch-dest': 'empty',
+ 'sec-fetch-mode': 'cors',
+ 'sec-fetch-site': 'same-site',
+ 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'
+ };
+
+ // Add ui-token if available
+ const uiToken = await getUiTokenForPStream(userCookie);
+ if (uiToken) {
+ headers['ui-token'] = uiToken;
+ console.log(`[PStream] Using ui-token for authentication`);
+ } else {
+ console.log(`[PStream] No ui-token available, making unauthenticated request`);
+ }
+
+ // Check if proxy should be used
+ const useProxy = process.env.SHOWBOX_PROXY_URL_VALUE && process.env.SHOWBOX_PROXY_URL_VALUE.trim() !== '';
+ let finalApiUrl = apiUrl;
+
+ if (useProxy) {
+ finalApiUrl = `${process.env.SHOWBOX_PROXY_URL_VALUE}${encodeURIComponent(apiUrl)}`;
+ console.log(`[PStream] Using proxy for request: ${finalApiUrl}`);
+ } else {
+ console.log(`[PStream] Making direct request (no proxy configured)`);
+ }
+
+ // Make the request
+ const response = await axios.get(finalApiUrl, {
+ headers: headers,
+ timeout: 30000
+ });
+
+ if (!response.data) {
+ console.log(`[PStream] No data received from API`);
+ return [];
+ }
+
+ console.log(`[PStream] Response received, processing streams...`);
+
+ // Process the PStream API response
+ const streams = processPStreamResponse(response.data, tmdbType, seasonNum, episodeNum);
+
+ console.timeEnd(timerLabel);
+ console.log(`[PStream] Found ${streams.length} streams`);
+ return streams;
+
+ } catch (error) {
+ console.error(`[PStream] Error fetching streams: ${error.message}`);
+ if (error.response) {
+ console.error(`[PStream] Status: ${error.response.status}, Data: ${JSON.stringify(error.response.data).substring(0, 200)}`);
+ }
+ console.timeEnd(timerLabel);
+ return [];
+ }
+};
+
+// Function to process PStream API response and convert to standard stream format
+const processPStreamResponse = (apiResponse, tmdbType, seasonNum, episodeNum) => {
+ const streams = [];
+
+ try {
+ // Log the actual response structure for debugging
+ console.log(`[PStream] API Response structure:`, JSON.stringify(apiResponse, null, 2).substring(0, 1000));
+ console.log(`[PStream] API Response type:`, typeof apiResponse);
+ console.log(`[PStream] API Response keys:`, apiResponse ? Object.keys(apiResponse) : 'null/undefined');
+
+ // Check if response has streams object (PStream API format)
+ if (apiResponse && apiResponse.streams && typeof apiResponse.streams === 'object') {
+ console.log(`[PStream] Found streams object with ${Object.keys(apiResponse.streams).length} quality levels`);
+
+ // Process streams object format
+ for (const [quality, url] of Object.entries(apiResponse.streams)) {
+ if (url && typeof url === 'string') {
+ // Use "Auto" for name and actual filename for title
+ const streamName = "Auto";
+ const streamTitle = apiResponse.name || `${tmdbType === 'movie' ? 'PStream' : `PStream - S${seasonNum}E${episodeNum}`} - ${quality}`;
+
+ streams.push({
+ name: streamName,
+ title: streamTitle,
+ url: url,
+ quality: parseQualityFromLabel(quality),
+ codecs: extractCodecDetails(apiResponse.name || quality), // Use filename for codec detection
+ size: apiResponse.size || 'Unknown size',
+ provider: 'PStream'
+ });
+ }
+ }
+
+ console.log(`[PStream] Successfully parsed ${streams.length} streams from streams object`);
+ return streams;
+ }
+
+ // Check if response has sources array (alternative format)
+ if (apiResponse && Array.isArray(apiResponse.sources)) {
+ console.log(`[PStream] Found sources array with ${apiResponse.sources.length} sources`);
+
+ for (const source of apiResponse.sources) {
+ if (!source.url || !source.quality) {
+ continue;
+ }
+
+ const streamName = "Auto";
+ const streamTitle = apiResponse.name || `${tmdbType === 'movie' ? 'PStream' : `PStream - S${seasonNum}E${episodeNum}`} - ${source.quality}`;
+
+ streams.push({
+ name: streamName,
+ title: streamTitle,
+ url: source.url,
+ quality: parseQualityFromLabel(source.quality),
+ codecs: source.codec ? [source.codec] : [],
+ size: source.size || 'Unknown size',
+ provider: 'PStream'
+ });
+ }
+
+ return streams;
+ }
+
+ // Check if response has data array (another alternative format)
+ if (apiResponse && Array.isArray(apiResponse.data)) {
+ console.log(`[PStream] Found 'data' array instead of 'sources'`);
+
+ for (const item of apiResponse.data) {
+ if (item.url || item.file) {
+ const streamName = "Auto";
+ const streamTitle = apiResponse.name || `${tmdbType === 'movie' ? 'PStream' : `PStream - S${seasonNum}E${episodeNum}`} - ${item.quality || item.label || 'Unknown'}`;
+
+ streams.push({
+ name: streamName,
+ title: streamTitle,
+ url: item.url || item.file,
+ quality: parseQualityFromLabel(item.quality || item.label),
+ codecs: item.codec ? [item.codec] : [],
+ size: item.size || 'Unknown size',
+ provider: 'PStream'
+ });
+ }
+ }
+
+ return streams;
+ }
+
+ // No recognized format found
+ console.log(`[PStream] No recognized stream format found in response`);
+ if (apiResponse && apiResponse.message) {
+ console.log(`[PStream] API returned message:`, apiResponse.message);
+ } else if (apiResponse && apiResponse.error) {
+ console.log(`[PStream] API returned error:`, apiResponse.error);
+ }
+
+ return streams;
+
+ } catch (error) {
+ console.error(`[PStream] Error processing API response: ${error.message}`);
+ }
+
+ return streams;
+};
+
+// Function to get TMDB data specifically for PStream API (extracts IMDB ID)
+const getTmdbDataForPStream = async (tmdbType, tmdbId) => {
+ const cacheSubDir = 'tmdb_api';
+ const cacheKey = `tmdb-${tmdbType}-${tmdbId}.json`;
+
+ // Try cache first
+ let tmdbData = await getFromCache(cacheKey, cacheSubDir);
+
+ if (!tmdbData || process.env.DISABLE_CACHE === 'true') {
+ const TMDB_API_KEY = obtainTmdbKey();
+ const tmdbApiUrl = `${TMDB_BASE_URL}/${tmdbType}/${tmdbId}?api_key=${TMDB_API_KEY}`;
+ console.log(` [PStream] Fetching TMDB data from: ${tmdbApiUrl}`);
+
+ try {
+ const response = await axios.get(tmdbApiUrl, { timeout: 10000 });
+ tmdbData = response.data;
+ if (tmdbData) {
+ if (process.env.DISABLE_CACHE !== 'true') {
+ await saveToCache(cacheKey, tmdbData, cacheSubDir);
+ }
+ }
+ } catch (error) {
+ console.log(` [PStream] Error fetching TMDB data: ${error.message}`);
+ return null;
+ }
+ }
+
+ if (!tmdbData) {
+ console.log(` [PStream] No TMDB data found for ${tmdbType}/${tmdbId}`);
+ return null;
+ }
+
+ // Extract IMDB ID
+ let imdbId = null;
+ const externalIdsCacheKey = `tmdb-${tmdbType}-${tmdbId}-external_ids.json`;
+ let externalIdsData = await getFromCache(externalIdsCacheKey, cacheSubDir);
+
+ if (!externalIdsData || process.env.DISABLE_CACHE === 'true') {
+ const TMDB_API_KEY = obtainTmdbKey();
+ const externalIdsApiUrl = `${TMDB_BASE_URL}/${tmdbType}/${tmdbId}/external_ids?api_key=${TMDB_API_KEY}`;
+ console.log(` [PStream] Fetching TMDB external IDs from: ${externalIdsApiUrl}`);
+
+ try {
+ const response = await axios.get(externalIdsApiUrl, { timeout: 10000 });
+ externalIdsData = response.data;
+ if (externalIdsData) {
+ if (process.env.DISABLE_CACHE !== 'true') {
+ await saveToCache(externalIdsCacheKey, externalIdsData, cacheSubDir);
+ }
+ }
+ } catch (error) {
+ console.log(` [PStream] Error fetching TMDB external IDs: ${error.message}`);
+ }
+ }
+
+ if (externalIdsData && externalIdsData.imdb_id) {
+ imdbId = externalIdsData.imdb_id;
+ }
+
+ if (!imdbId) {
+ console.log(` [PStream] No IMDB ID found for ${tmdbType}/${tmdbId}`);
+ return null;
+ }
+
+ return {
+ imdbId: imdbId,
+ title: tmdbType === 'movie' ? tmdbData.title : tmdbData.name,
+ year: tmdbData.release_date ? new Date(tmdbData.release_date).getFullYear() :
+ tmdbData.first_air_date ? new Date(tmdbData.first_air_date).getFullYear() : null
+ };
+};
+
+// Function to get ui-token for PStream API (handles JWT tokens)
+const getUiTokenForPStream = async (userCookie = null) => {
+ // If user provided a JWT token directly, use it
+ if (userCookie && userCookie.startsWith('eyJ')) {
+ console.log('[PStream CookieManager] Using user-provided JWT token as ui-token');
+ return userCookie;
+ }
+
+ // If user provided a regular cookie, try to convert it to JWT format
+ if (userCookie && !userCookie.startsWith('eyJ')) {
+ console.log('[PStream CookieManager] Regular cookie provided, attempting to use as ui-token');
+ // For now, pass it through as-is - the API might handle conversion
+ return userCookie;
+ }
+
+ // Check global cookie
+ if (global.currentRequestUserCookie && global.currentRequestUserCookie.startsWith('eyJ')) {
+ console.log('[PStream CookieManager] Using JWT token from global state');
+ return global.currentRequestUserCookie;
+ }
+
+ // Try intelligent selection from cookies array if available
+ if (global.currentRequestConfig && Array.isArray(global.currentRequestConfig.cookies) && global.currentRequestConfig.cookies.length > 0) {
+ try {
+ const candidates = global.currentRequestConfig.cookies.filter(Boolean);
+ const flowResults = await Promise.all(candidates.map(async (c) => {
+ try {
+ const headers = { 'Cookie': c.startsWith('ui=') ? c : `ui=${c}`, 'Accept': 'application/json, text/javascript, */*; q=0.01' };
+ const resp = await axios.get('https://www.febbox.com/console/user_cards', { headers, timeout: 10000, validateStatus: () => true });
+ if (resp.status === 200 && resp.data && resp.data.data && resp.data.data.flow) {
+ const flow = resp.data.data.flow;
+ const remaining = (Number(flow.traffic_limit_mb) || 0) - (Number(flow.traffic_usage_mb) || 0);
+ return { cookie: c, remainingMB: remaining, ok: true };
+ }
+ } catch (e) { /* ignore per-candidate error */ }
+ return { cookie: c, remainingMB: -1, ok: false };
+ }));
+ flowResults.sort((a, b) => (b.remainingMB - a.remainingMB));
+ const best = flowResults[0];
+ if (best && best.ok) {
+ global.currentRequestUserCookie = best.cookie;
+ global.currentRequestUserCookieRemainingMB = best.remainingMB;
+ console.log(`[PStream CookieManager] Selected best ui-token by remaining quota: ${best.remainingMB} MB`);
+ // Return JWT directly if it is JWT, otherwise return as-is
+ return best.cookie;
+ }
+ } catch (e) {
+ console.warn(`[PStream CookieManager] Multi-cookie selection failed: ${e.message}`);
+ }
+ }
+
+ console.log('[PStream CookieManager] No valid ui-token available');
+ return null;
+};
+
+module.exports = {
+ getStreamsFromTmdbId,
+ parseQualityFromLabel,
+ convertImdbToTmdb,
+ getShowboxUrlFromTmdbInfo,
+ ShowBoxScraper,
+ extractFidsFromFebboxPage,
+ processShowWithSeasonsEpisodes,
+ sortStreamsByQuality,
+ getStreamsFromPStreamAPI,
+ processPStreamResponse,
+ getTmdbDataForPStream,
+ getUiTokenForPStream
+};
\ No newline at end of file
diff --git a/providers/VidZee.js b/providers/VidZee.js
new file mode 100644
index 0000000..42f260f
--- /dev/null
+++ b/providers/VidZee.js
@@ -0,0 +1,129 @@
+const axios = require('axios');
+
+// Removed unused parseArgs helper
+
+const getVidZeeStreams = async (tmdbId, mediaType, seasonNum, episodeNum) => {
+ if (!tmdbId) {
+ console.error('[VidZee] Error: TMDB ID (tmdbId) is required.');
+ return [];
+ }
+
+ if (!mediaType || (mediaType !== 'movie' && mediaType !== 'tv')) {
+ console.error('[VidZee] Error: mediaType is required and must be either "movie" or "tv".');
+ return [];
+ }
+
+ if (mediaType === 'tv') {
+ if (!seasonNum) {
+ console.error('[VidZee] Error: Season (seasonNum) is required for TV shows.');
+ return [];
+ }
+ if (!episodeNum) {
+ console.error('[VidZee] Error: Episode (episodeNum) is required for TV shows.');
+ return [];
+ }
+ }
+
+ const servers = [1,2,3,4,5,6,7,8,9,10]; // VidZee server identifiers
+
+ const streamPromises = servers.map(async (sr) => {
+ let targetApiUrl = `https://player.vidzee.wtf/api/server?id=${tmdbId}&sr=${sr}`;
+
+ if (mediaType === 'tv') {
+ targetApiUrl += `&ss=${seasonNum}&ep=${episodeNum}`;
+ }
+
+ let finalApiUrl;
+ const headers = {
+ 'Referer': `https://player.vidzee.wtf/embed/movie/${tmdbId}` // Default for proxy method
+ };
+ const timeout = 7000; // Reduced timeout
+
+ const proxyBaseUrl = process.env.VIDZEE_PROXY_URL || process.env.SHOWBOX_PROXY_URL_VALUE;
+ if (proxyBaseUrl) {
+ finalApiUrl = proxyBaseUrl + encodeURIComponent(targetApiUrl);
+ } else {
+ finalApiUrl = targetApiUrl;
+ }
+
+ console.log(`[VidZee] Fetching from server ${sr}: ${targetApiUrl}`);
+
+ try {
+ const response = await axios.get(finalApiUrl, {
+ headers: headers,
+ timeout: timeout
+ });
+
+ const responseData = response.data;
+
+ if (!responseData || typeof responseData !== 'object') {
+ console.error(`[VidZee S${sr}] Error: Invalid response data from API.`);
+ return [];
+ }
+
+ if (responseData.tracks) {
+ delete responseData.tracks;
+ }
+
+ let apiSources = [];
+ if (responseData.url && Array.isArray(responseData.url)) {
+ apiSources = responseData.url;
+ } else if (responseData.link && typeof responseData.link === 'string') {
+ apiSources = [responseData];
+ }
+
+ if (!apiSources || apiSources.length === 0) {
+ console.log(`[VidZee S${sr}] No stream sources found in API response.`);
+ return [];
+ }
+
+ const streams = apiSources.map(sourceItem => {
+ // Prefer sourceItem.name as label, fallback to sourceItem.type, then 'VidZee Stream'
+ const label = sourceItem.name || sourceItem.type || 'VidZee';
+ // Ensure quality has 'p' if it's a resolution, or keep it as is
+ let quality = String(label).match(/^\d+$/) ? `${label}p` : label;
+ // Normalize non-numeric or ambiguous quality labels to a baseline so they survive minQuality filter
+ if (!/(\d{3,4})p/.test(quality.toLowerCase())) {
+ quality = '720p';
+ }
+ const language = sourceItem.language || sourceItem.lang;
+
+ return {
+ title: `VidZee S${sr} - ${quality}`,
+ url: sourceItem.link, // Use sourceItem.link for the URL
+ quality: quality,
+ language: language,
+ provider: "VidZee",
+ size: "Unknown size",
+ behaviorHints: {
+ notWebReady: true,
+ headers: {
+ 'Referer': 'https://core.vidzee.wtf/'
+ }
+ }
+ };
+ }).filter(stream => stream.url);
+
+ console.log(`[VidZee S${sr}] Successfully extracted ${streams.length} streams. Qualities: ${streams.map(s=>s.quality).join(', ')}`);
+ return streams;
+
+ } catch (error) {
+ if (error.response) {
+ console.error(`[VidZee S${sr}] Error fetching: ${error.response.status} ${error.response.statusText}`);
+ } else if (error.request) {
+ console.error(`[VidZee S${sr}] Error fetching: No response received.`);
+ } else {
+ console.error(`[VidZee S${sr}] Error fetching:`, error.message);
+ }
+ return [];
+ }
+ });
+
+ const allStreamsNested = await Promise.all(streamPromises);
+ const allStreams = allStreamsNested.flat();
+
+ console.log(`[VidZee] Found a total of ${allStreams.length} streams from servers ${servers.join(', ')}.`);
+ return allStreams;
+};
+
+module.exports = { getVidZeeStreams };
\ No newline at end of file
diff --git a/providers/moviesmod.js b/providers/moviesmod.js
new file mode 100644
index 0000000..d9d3201
--- /dev/null
+++ b/providers/moviesmod.js
@@ -0,0 +1,1225 @@
+/**
+ * MoviesMod provider (standalone API)
+ * Supports both movies and TV series
+ */
+
+const axios = require('axios');
+const cheerio = require('cheerio');
+const FormData = require('form-data');
+const { CookieJar } = require('tough-cookie');
+const { URLSearchParams, URL } = require('url');
+const fs = require('fs').promises;
+const path = require('path');
+const { findBestMatch } = require('string-similarity');
+
+// Dynamic import for axios-cookiejar-support
+let axiosCookieJarSupport = null;
+const getAxiosCookieJarSupport = async () => {
+ if (!axiosCookieJarSupport) {
+ axiosCookieJarSupport = await import('axios-cookiejar-support');
+ }
+ return axiosCookieJarSupport;
+};
+
+function escapeRegExp(string) {
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
+}
+
+// --- Proxy Configuration ---
+const MOVIESMOD_PROXY_URL = process.env.MOVIESMOD_PROXY_URL;
+if (MOVIESMOD_PROXY_URL) {
+ console.log(`[MoviesMod] Proxy support enabled: ${MOVIESMOD_PROXY_URL}`);
+} else {
+ console.log('[MoviesMod] No proxy configured, using direct connections');
+}
+
+// --- Domain Fetching ---
+let moviesModDomain = 'https://moviesmod.chat'; // Fallback domain
+let domainCacheTimestamp = 0;
+const DOMAIN_CACHE_TTL = 4 * 60 * 60 * 1000; // 4 hours
+
+async function getMoviesModDomain() {
+ const now = Date.now();
+ if (now - domainCacheTimestamp < DOMAIN_CACHE_TTL) {
+ return moviesModDomain;
+ }
+
+ try {
+ console.log('[MoviesMod] Fetching latest domain...');
+ const response = await makeRequest('https://raw.githubusercontent.com/phisher98/TVVVV/refs/heads/main/domains.json', { timeout: 10000 });
+ if (response.data && response.data.moviesmod) {
+ moviesModDomain = response.data.moviesmod;
+ domainCacheTimestamp = now;
+ console.log(`[MoviesMod] Updated domain to: ${moviesModDomain}`);
+ } else {
+ console.warn('[MoviesMod] Domain JSON fetched, but "moviesmod" key was not found. Using fallback.');
+ }
+ } catch (error) {
+ console.error(`[MoviesMod] Failed to fetch latest domain, using fallback. Error: ${error.message}`);
+ }
+ return moviesModDomain;
+}
+
+// --- Caching Configuration ---
+const CACHE_ENABLED = process.env.DISABLE_CACHE !== 'true';
+console.log(`[MoviesMod Cache] Internal cache is ${CACHE_ENABLED ? 'enabled' : 'disabled'}.`);
+const CACHE_DIR = process.env.VERCEL ? path.join('/tmp', '.moviesmod_cache') : path.join(__dirname, '.cache', 'moviesmod');
+
+// Caching layer simplified: placeholders only (extend for FS persistence if needed)
+
+// --- Caching Helper Functions ---
+const ensureCacheDir = async () => {
+ if (!CACHE_ENABLED) return;
+ try {
+ await fs.mkdir(CACHE_DIR, { recursive: true });
+ } catch (error) {
+ if (error.code !== 'EEXIST') {
+ console.error(`[MoviesMod Cache] Error creating cache directory: ${error.message}`);
+ }
+ }
+};
+
+const getFromCache = async (key) => {
+ if (!CACHE_ENABLED) return null;
+ return null; // no-op
+};
+
+const saveToCache = async (key, data) => {
+ if (!CACHE_ENABLED) return;
+ // no-op (placeholder for future FS caching)
+};
+
+// Initialize cache directory on startup
+ensureCacheDir();
+
+// Proxy wrapper function
+const makeRequest = async (url, options = {}) => {
+ if (MOVIESMOD_PROXY_URL) {
+ // Route through proxy
+ const proxiedUrl = `${MOVIESMOD_PROXY_URL}${encodeURIComponent(url)}`;
+ console.log(`[MoviesMod] Making proxied request to: ${url}`);
+ return axios.get(proxiedUrl, options);
+ } else {
+ // Direct request
+ console.log(`[MoviesMod] Making direct request to: ${url}`);
+ return axios.get(url, options);
+ }
+};
+
+// Helper function to create a proxied session for SID resolution
+const createProxiedSession = async (jar) => {
+ const { wrapper } = await getAxiosCookieJarSupport();
+
+ const sessionConfig = {
+ jar,
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36',
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
+ 'Accept-Language': 'en-US,en;q=0.5',
+ 'Connection': 'keep-alive',
+ 'Upgrade-Insecure-Requests': '1'
+ }
+ };
+
+ const session = wrapper(axios.create(sessionConfig));
+
+ // Helper function to extract cookies from jar for a given URL
+ const getCookiesForUrl = async (url) => {
+ try {
+ const cookies = await jar.getCookies(url);
+ return cookies.map(cookie => `${cookie.key}=${cookie.value}`).join('; ');
+ } catch (error) {
+ console.error(`[MoviesMod] Error getting cookies for ${url}: ${error.message}`);
+ return '';
+ }
+ };
+
+ // If proxy is enabled, wrap the session methods to use proxy
+ if (MOVIESMOD_PROXY_URL) {
+ console.log(`[MoviesMod] Creating SID session with proxy: ${MOVIESMOD_PROXY_URL}`);
+ const originalGet = session.get.bind(session);
+ const originalPost = session.post.bind(session);
+
+ session.get = async (url, options = {}) => {
+ const proxiedUrl = `${MOVIESMOD_PROXY_URL}${encodeURIComponent(url)}`;
+ console.log(`[MoviesMod] Making proxied SID GET request to: ${url}`);
+
+ // Extract cookies from jar and add to headers
+ const cookieString = await getCookiesForUrl(url);
+ if (cookieString) {
+ console.log(`[MoviesMod] Adding cookies to proxied request: ${cookieString}`);
+ options.headers = {
+ ...options.headers,
+ 'Cookie': cookieString
+ };
+ }
+
+ return originalGet(proxiedUrl, options);
+ };
+
+ session.post = async (url, data, options = {}) => {
+ const proxiedUrl = `${MOVIESMOD_PROXY_URL}${encodeURIComponent(url)}`;
+ console.log(`[MoviesMod] Making proxied SID POST request to: ${url}`);
+
+ // Extract cookies from jar and add to headers
+ const cookieString = await getCookiesForUrl(url);
+ if (cookieString) {
+ console.log(`[MoviesMod] Adding cookies to proxied request: ${cookieString}`);
+ options.headers = {
+ ...options.headers,
+ 'Cookie': cookieString
+ };
+ }
+
+ return originalPost(proxiedUrl, data, options);
+ };
+ }
+
+ return session;
+};
+
+// Helper function to extract quality from text
+function extractQuality(text) {
+ if (!text) return 'Unknown';
+
+ const qualityMatch = text.match(/(480p|720p|1080p|2160p|4k)/i);
+ if (qualityMatch) {
+ return qualityMatch[1];
+ }
+
+ // Try to extract from full text
+ const cleanMatch = text.match(/(480p|720p|1080p|2160p|4k)[^)]*\)/i);
+ if (cleanMatch) {
+ return cleanMatch[0];
+ }
+
+ return 'Unknown';
+}
+
+function parseQualityForSort(qualityString) {
+ if (!qualityString) return 0;
+ const match = qualityString.match(/(\d{3,4})p/i);
+ return match ? parseInt(match[1], 10) : 0;
+}
+
+function getTechDetails(qualityString) {
+ if (!qualityString) return [];
+ const details = [];
+ const lowerText = qualityString.toLowerCase();
+ if (lowerText.includes('10bit')) details.push('10-bit');
+ if (lowerText.includes('hevc') || lowerText.includes('x265')) details.push('HEVC');
+ if (lowerText.includes('hdr')) details.push('HDR');
+ return details;
+}
+
+// Search for content on MoviesMod
+async function searchMoviesMod(query) {
+ try {
+ const baseUrl = await getMoviesModDomain();
+ const searchUrl = `${baseUrl}/?s=${encodeURIComponent(query)}`;
+ const { data } = await makeRequest(searchUrl);
+ const $ = cheerio.load(data);
+
+ const results = [];
+ $('.latestPost').each((i, element) => {
+ const linkElement = $(element).find('a');
+ const title = linkElement.attr('title');
+ const url = linkElement.attr('href');
+ if (title && url) {
+ results.push({ title, url });
+ }
+ });
+
+ return results;
+ } catch (error) {
+ console.error(`[MoviesMod] Error searching: ${error.message}`);
+ return [];
+ }
+}
+
+// Extract download links from a movie/series page
+async function extractDownloadLinks(moviePageUrl) {
+ try {
+ const { data } = await makeRequest(moviePageUrl);
+ const $ = cheerio.load(data);
+ const links = [];
+ const contentBox = $('.thecontent');
+
+ // Get all relevant headers (for movies and TV shows) in document order
+ const headers = contentBox.find('h3:contains("Season"), h4');
+
+ headers.each((i, el) => {
+ const header = $(el);
+ const headerText = header.text().trim();
+
+ // Define the content block for this header
+ const blockContent = header.nextUntil('h3, h4');
+
+ if (header.is('h3') && headerText.toLowerCase().includes('season')) {
+ // TV Show Logic
+ const linkElements = blockContent.find('a.maxbutton-episode-links, a.maxbutton-batch-zip');
+ linkElements.each((j, linkEl) => {
+ const buttonText = $(linkEl).text().trim();
+ const linkUrl = $(linkEl).attr('href');
+ if (linkUrl && !buttonText.toLowerCase().includes('batch')) {
+ links.push({
+ quality: `${headerText} - ${buttonText}`,
+ url: linkUrl
+ });
+ }
+ });
+ } else if (header.is('h4')) {
+ // Movie Logic
+ const linkElement = blockContent.find('a[href*="modrefer.in"]').first();
+ if (linkElement.length > 0) {
+ const link = linkElement.attr('href');
+ const cleanQuality = extractQuality(headerText);
+ links.push({
+ quality: cleanQuality,
+ url: link
+ });
+ }
+ }
+ });
+
+ return links;
+ } catch (error) {
+ console.error(`[MoviesMod] Error extracting download links: ${error.message}`);
+ return [];
+ }
+}
+
+// Resolve intermediate links (dramadrip, episodes.modpro.blog, modrefer.in)
+async function resolveIntermediateLink(initialUrl, refererUrl, quality) {
+ try {
+ const urlObject = new URL(initialUrl);
+
+ if (urlObject.hostname.includes('dramadrip.com')) {
+ const { data: dramaData } = await makeRequest(initialUrl, { headers: { 'Referer': refererUrl } });
+ const $$ = cheerio.load(dramaData);
+
+ let episodePageLink = null;
+ const seasonMatch = quality.match(/Season \d+/i);
+ // Extract the specific quality details, e.g., "1080p x264"
+ const specificQualityMatch = quality.match(/(480p|720p|1080p|2160p|4k)[ \w\d-]*/i);
+
+ if (seasonMatch && specificQualityMatch) {
+ const seasonIdentifier = seasonMatch[0].toLowerCase();
+ // Clean up the identifier to get only the essential parts
+ const specificQualityIdentifier = specificQualityMatch[0].toLowerCase().replace(/msubs.*/i, '').replace(/esubs.*/i, '').replace(/\{.*/, '').trim();
+ const qualityParts = specificQualityIdentifier.split(/\s+/); // -> ['1080p', 'x264']
+
+ $$('a[href*="episodes.modpro.blog"], a[href*="cinematickit.org"]').each((i, el) => {
+ const link = $$(el);
+ const linkText = link.text().trim().toLowerCase();
+ const seasonHeader = link.closest('.wp-block-buttons').prevAll('h2.wp-block-heading').first().text().trim().toLowerCase();
+
+ const seasonIsMatch = seasonHeader.includes(seasonIdentifier);
+ // Ensure that the link text contains all parts of our specific quality
+ const allPartsMatch = qualityParts.every(part => linkText.includes(part));
+
+ if (seasonIsMatch && allPartsMatch) {
+ episodePageLink = link.attr('href');
+ console.log(`[MoviesMod] Found specific match for "${quality}" -> "${link.text().trim()}": ${episodePageLink}`);
+ return false; // Break loop, we found our specific link
+ }
+ });
+ }
+
+ if (!episodePageLink) {
+ console.error(`[MoviesMod] Could not find a specific quality match on dramadrip page for: ${quality}`);
+ return [];
+ }
+
+ // Pass quality to recursive call
+ return await resolveIntermediateLink(episodePageLink, initialUrl, quality);
+
+ } else if (urlObject.hostname.includes('cinematickit.org')) {
+ // Handle cinematickit.org pages
+ const { data } = await makeRequest(initialUrl, { headers: { 'Referer': refererUrl } });
+ const $ = cheerio.load(data);
+ const finalLinks = [];
+
+ // Look for episode links on cinematickit.org
+ $('a[href*="driveseed.org"]').each((i, el) => {
+ const link = $(el).attr('href');
+ const text = $(el).text().trim();
+ if (link && text && !text.toLowerCase().includes('batch')) {
+ finalLinks.push({
+ server: text.replace(/\s+/g, ' '),
+ url: link,
+ });
+ }
+ });
+
+ // If no driveseed links found, try other patterns
+ if (finalLinks.length === 0) {
+ $('a[href*="modrefer.in"], a[href*="dramadrip.com"]').each((i, el) => {
+ const link = $(el).attr('href');
+ const text = $(el).text().trim();
+ if (link && text) {
+ finalLinks.push({
+ server: text.replace(/\s+/g, ' '),
+ url: link,
+ });
+ }
+ });
+ }
+
+ return finalLinks;
+
+ } else if (urlObject.hostname.includes('episodes.modpro.blog')) {
+ const { data } = await makeRequest(initialUrl, { headers: { 'Referer': refererUrl } });
+ const $ = cheerio.load(data);
+ const finalLinks = [];
+
+ $('.entry-content a[href*="driveseed.org"], .entry-content a[href*="tech.unblockedgames.world"], .entry-content a[href*="tech.creativeexpressionsblog.com"], .entry-content a[href*="tech.examzculture.in"]').each((i, el) => {
+ const link = $(el).attr('href');
+ const text = $(el).text().trim();
+ if (link && text && !text.toLowerCase().includes('batch')) {
+ finalLinks.push({
+ server: text.replace(/\s+/g, ' '),
+ url: link,
+ });
+ }
+ });
+ return finalLinks;
+
+ } else if (urlObject.hostname.includes('modrefer.in')) {
+ const encodedUrl = urlObject.searchParams.get('url');
+ if (!encodedUrl) {
+ console.error('[MoviesMod] Could not find encoded URL in modrefer.in link.');
+ return [];
+ }
+
+ const decodedUrl = Buffer.from(encodedUrl, 'base64').toString('utf8');
+ const { data } = await makeRequest(decodedUrl, {
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
+ 'Referer': refererUrl,
+ }
+ });
+
+ const $ = cheerio.load(data);
+ const finalLinks = [];
+
+ $('.timed-content-client_show_0_5_0 a').each((i, el) => {
+ const link = $(el).attr('href');
+ const text = $(el).text().trim();
+ if (link) {
+ finalLinks.push({
+ server: text,
+ url: link,
+ });
+ }
+ });
+ return finalLinks;
+ } else {
+ console.warn(`[MoviesMod] Unknown hostname: ${urlObject.hostname}`);
+ return [];
+ }
+ } catch (error) {
+ console.error(`[MoviesMod] Error resolving intermediate link: ${error.message}`);
+ return [];
+ }
+}
+
+// Function to resolve tech.unblockedgames.world links to driveleech URLs (adapted from UHDMovies)
+async function resolveTechUnblockedLink(sidUrl) {
+ console.log(`[MoviesMod] Resolving SID link: ${sidUrl}`);
+ const { origin } = new URL(sidUrl);
+ const jar = new CookieJar();
+
+ // Create session with proxy support
+ const session = await createProxiedSession(jar);
+
+ try {
+ // Step 0: Get the _wp_http value
+ console.log(" [SID] Step 0: Fetching initial page...");
+ const responseStep0 = await session.get(sidUrl);
+ let $ = cheerio.load(responseStep0.data);
+ const initialForm = $('#landing');
+ const wp_http_step1 = initialForm.find('input[name="_wp_http"]').val();
+ const action_url_step1 = initialForm.attr('action');
+
+ if (!wp_http_step1 || !action_url_step1) {
+ console.error(" [SID] Error: Could not find _wp_http in initial form.");
+ return null;
+ }
+
+ // Step 1: POST to the first form's action URL
+ console.log(" [SID] Step 1: Submitting initial form...");
+ const step1Data = new URLSearchParams({ '_wp_http': wp_http_step1 });
+ const responseStep1 = await session.post(action_url_step1, step1Data, {
+ headers: { 'Referer': sidUrl, 'Content-Type': 'application/x-www-form-urlencoded' }
+ });
+
+ // Step 2: Parse verification page for second form
+ console.log(" [SID] Step 2: Parsing verification page...");
+ $ = cheerio.load(responseStep1.data);
+ const verificationForm = $('#landing');
+ const action_url_step2 = verificationForm.attr('action');
+ const wp_http2 = verificationForm.find('input[name="_wp_http2"]').val();
+ const token = verificationForm.find('input[name="token"]').val();
+
+ if (!action_url_step2) {
+ console.error(" [SID] Error: Could not find verification form.");
+ return null;
+ }
+
+ // Step 3: POST to the verification URL
+ console.log(" [SID] Step 3: Submitting verification...");
+ const step2Data = new URLSearchParams({ '_wp_http2': wp_http2, 'token': token });
+ const responseStep2 = await session.post(action_url_step2, step2Data, {
+ headers: { 'Referer': responseStep1.request.res.responseUrl, 'Content-Type': 'application/x-www-form-urlencoded' }
+ });
+
+ // Step 4: Find dynamic cookie and link from JavaScript
+ console.log(" [SID] Step 4: Parsing final page for JS data...");
+ let finalLinkPath = null;
+ let cookieName = null;
+ let cookieValue = null;
+
+ const scriptContent = responseStep2.data;
+ const cookieMatch = scriptContent.match(/s_343\('([^']+)',\s*'([^']+)'/);
+ const linkMatch = scriptContent.match(/c\.setAttribute\("href",\s*"([^"]+)"\)/);
+
+ if (cookieMatch) {
+ cookieName = cookieMatch[1].trim();
+ cookieValue = cookieMatch[2].trim();
+ }
+ if (linkMatch) {
+ finalLinkPath = linkMatch[1].trim();
+ }
+
+ if (!finalLinkPath || !cookieName || !cookieValue) {
+ console.error(" [SID] Error: Could not extract dynamic cookie/link from JS.");
+ return null;
+ }
+
+ const finalUrl = new URL(finalLinkPath, origin).href;
+ console.log(` [SID] Dynamic link found: ${finalUrl}`);
+ console.log(` [SID] Dynamic cookie found: ${cookieName}`);
+
+ // Step 5: Set cookie and make final request
+ console.log(" [SID] Step 5: Setting cookie and making final request...");
+ await jar.setCookie(`${cookieName}=${cookieValue}`, origin);
+
+ const finalResponse = await session.get(finalUrl, {
+ headers: { 'Referer': responseStep2.request.res.responseUrl }
+ });
+
+ // Step 6: Extract driveleech URL from meta refresh tag
+ $ = cheerio.load(finalResponse.data);
+ const metaRefresh = $('meta[http-equiv="refresh"]');
+ if (metaRefresh.length > 0) {
+ const content = metaRefresh.attr('content');
+ const urlMatch = content.match(/url=(.*)/i);
+ if (urlMatch && urlMatch[1]) {
+ const driveleechUrl = urlMatch[1].replace(/"/g, "").replace(/'/g, "");
+ console.log(` [SID] SUCCESS! Resolved Driveleech URL: ${driveleechUrl}`);
+ return driveleechUrl;
+ }
+ }
+
+ console.error(" [SID] Error: Could not find meta refresh tag with Driveleech URL.");
+ return null;
+
+ } catch (error) {
+ console.error(` [SID] Error during SID resolution: ${error.message}`);
+ if (error.response) {
+ console.error(` [SID] Status: ${error.response.status}`);
+ }
+ return null;
+ }
+}
+
+
+// Resolve Resume Cloud link to final download URL
+async function resolveResumeCloudLink(resumeUrl) {
+ try {
+ const { data } = await makeRequest(resumeUrl, {
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
+ 'Referer': 'https://driveseed.org/',
+ }
+ });
+ const $ = cheerio.load(data);
+ const downloadLink = $('a:contains("Cloud Resume Download")').attr('href');
+ return downloadLink || null;
+ } catch (error) {
+ console.error(`[MoviesMod] Error resolving Resume Cloud link: ${error.message}`);
+ return null;
+ }
+}
+
+// Resolve Worker Seed link to final download URL
+async function resolveWorkerSeedLink(workerSeedUrl) {
+ try {
+ console.log(`[MoviesMod] Resolving Worker-seed link: ${workerSeedUrl}`);
+
+ const jar = new CookieJar();
+
+ // Get the wrapper function from dynamic import
+ const { wrapper } = await getAxiosCookieJarSupport();
+ const session = wrapper(axios.create({
+ jar,
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
+ }
+ }));
+
+ // Step 1: GET the page to get the script content and cookies
+ console.log(`[MoviesMod] Step 1: Fetching page to get script content and cookies...`);
+ const { data: pageHtml } = await session.get(workerSeedUrl);
+
+ // Step 2: Use regex to extract the token and the correct ID from the script
+ const scriptTags = pageHtml.match(/
+
+
+
+
+
+
+ No FEBBOX_COOKIES configured. Showbox / PStream streams may be unavailable.
+ Cache is DISABLED; expect slower responses & higher source load.
+ No TMDB API Keys configured. Metadata-dependent providers (Showbox, 4khdhub, MoviesMod, MP4Hydra) may degrade.
+
+
+
+
+
+
+
+
+
+