diff --git a/.gitignore b/.gitignore index cd4d1ba..6a4f0ab 100644 --- a/.gitignore +++ b/.gitignore @@ -403,4 +403,4 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml -dist/ +dist/ \ No newline at end of file diff --git a/deployment/docker/.env.example b/deployment/docker/.env.example index 32953d2..1d84fe9 100644 --- a/deployment/docker/.env.example +++ b/deployment/docker/.env.example @@ -23,7 +23,9 @@ RABBIT_URI=amqp://guest:guest@rabbitmq:5672/?heartbeat=30 QUEUE_NAME=ingested JOB_CONCURRENCY=5 JOBS_ENABLED=true -MAX_SINGLE_TORRENT_CONNECTIONS=10 +LOG_LEVEL=info # can be debug for extra verbosity (a lot more verbosity - useful for development) +MAX_CONNECTIONS_PER_TORRENT=10 +MAX_CONNECTIONS_OVERALL=100 TORRENT_TIMEOUT=30000 UDP_TRACKERS_ENABLED=true CONSUMER_REPLICAS=3 diff --git a/src/node/consumer/.eslintignore b/src/node/consumer/.eslintignore index b0a155e..0f6ba20 100644 --- a/src/node/consumer/.eslintignore +++ b/src/node/consumer/.eslintignore @@ -1 +1,3 @@ -*.ts \ No newline at end of file +dist/ +esbuild.ts +jest.config.ts \ No newline at end of file diff --git a/src/node/consumer/.eslintrc b/src/node/consumer/.eslintrc new file mode 100644 index 0000000..f3b4e84 --- /dev/null +++ b/src/node/consumer/.eslintrc @@ -0,0 +1,84 @@ +{ + "root": true, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": [ + "./tsconfig.json" + ] + }, + "plugins": [ + "@typescript-eslint", + "import", + "import-helpers" + ], + "rules": { + "default-case": "off", + "import/no-duplicates": "error", + "import/no-extraneous-dependencies": "error", + "import/order": "off", + "import-helpers/order-imports": [ + "warn", + { + "alphabetize": { + "order": "asc" + } + } + ], + "lines-between-class-members": [ + "error", + "always", + { + "exceptAfterSingleLine": true + } + ], + "no-continue": "off", + "no-param-reassign": "off", + "no-plusplus": [ + "error", + { + "allowForLoopAfterthoughts": true + } + ], + "no-restricted-syntax": "off", + "no-unused-expressions": [ + "off", + { + "allowShortCircuit": true + } + ], + "no-unused-vars": "off", + "no-use-before-define": "off", + "one-var": [ + "error", + { + "uninitialized": "consecutive" + } + ], + "prefer-destructuring": "error", + "@typescript-eslint/explicit-function-return-type": "error", + "@typescript-eslint/consistent-type-assertions": [ + "error", + { + "assertionStyle": "as", + "objectLiteralTypeAssertions": "never" + } + ] + }, + "overrides": [ + { + "files": [ + "*.test.ts" + ], + "rules": { + "@typescript-eslint/consistent-type-assertions": "off", + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-unused-vars": "off" + } + } + ] +} \ No newline at end of file diff --git a/src/node/consumer/.eslintrc.cjs b/src/node/consumer/.eslintrc.cjs deleted file mode 100644 index 1f703e1..0000000 --- a/src/node/consumer/.eslintrc.cjs +++ /dev/null @@ -1,39 +0,0 @@ -/** @type {import("eslint").ESLint.Options} */ -module.exports = { - env: { - es2024: true, - node: true, - }, - globals: { - Atomics: "readonly", - SharedArrayBuffer: "readonly", - }, - parserOptions: { - sourceType: "module", - }, - plugins: ["import", "import-helpers"], - rules: { - "default-case": "off", - "import/no-duplicates": "off", - "import/no-extraneous-dependencies": ["off", { devDependencies: ["backend", "frontend", "mobile"] }], - "import/order": "off", - "import-helpers/order-imports": [ - "warn", - { - alphabetize: { - order: "asc", - }, - }, - ], - "lines-between-class-members": ["error", "always", { exceptAfterSingleLine: true }], - "no-continue": "off", - "no-param-reassign": "off", - "no-plusplus": ["error", { allowForLoopAfterthoughts: true }], - "no-restricted-syntax": "off", - "no-unused-expressions": ["off", { allowShortCircuit: true }], - "no-unused-vars": "off", - "no-use-before-define": "off", - "one-var": ["error", { uninitialized: "consecutive" }], - "prefer-destructuring": "off", - }, -}; \ No newline at end of file diff --git a/src/node/consumer/.nvmrc b/src/node/consumer/.nvmrc new file mode 100644 index 0000000..016efd8 --- /dev/null +++ b/src/node/consumer/.nvmrc @@ -0,0 +1 @@ +v20.10.0 \ No newline at end of file diff --git a/src/node/consumer/Dockerfile b/src/node/consumer/Dockerfile index c26b653..b869f14 100644 --- a/src/node/consumer/Dockerfile +++ b/src/node/consumer/Dockerfile @@ -1,8 +1,6 @@ FROM node:lts-buster-slim as builder -RUN apt-get update && \ - apt-get install -y git && \ - rm -rf /var/lib/apt/lists/* +RUN apt update && apt install -y git && rm -rf /var/lib/apt/lists/* WORKDIR /app @@ -10,16 +8,16 @@ COPY package*.json ./ RUN npm install COPY . . RUN npm run build +RUN npm prune --omit=dev -# --- Runtime Stage --- FROM node:lts-buster-slim WORKDIR /app -ENV NODE_ENV production - COPY --from=builder /app ./ -RUN npm prune --omit=dev + +ENV NODE_ENV production +ENV NODE_OPTIONS "--no-deprecation" # CIS-DI-0001 RUN useradd -d /home/consumer -m -s /bin/bash consumer diff --git a/src/node/consumer/esbuild.js b/src/node/consumer/esbuild.ts similarity index 84% rename from src/node/consumer/esbuild.js rename to src/node/consumer/esbuild.ts index 63b1d16..c483f01 100644 --- a/src/node/consumer/esbuild.js +++ b/src/node/consumer/esbuild.ts @@ -1,8 +1,6 @@ import { build } from "esbuild"; import { readFileSync, rmSync } from "fs"; -const { devDependencies } = JSON.parse(readFileSync("./package.json", "utf8")); - const start = Date.now(); try { @@ -13,9 +11,8 @@ try { build({ bundle: true, entryPoints: [ - "./src/index.js", + "./src/main.ts", ], - external: [...(devDependencies && Object.keys(devDependencies))], keepNames: true, minify: true, outbase: "./src", @@ -42,7 +39,6 @@ try { } ], }).then(() => { - // biome-ignore lint/style/useTemplate: console.log("⚡ " + "\x1b[32m" + `Done in ${Date.now() - start}ms`); }); } catch (e) { diff --git a/src/node/consumer/jest.config.ts b/src/node/consumer/jest.config.ts new file mode 100644 index 0000000..426cc27 --- /dev/null +++ b/src/node/consumer/jest.config.ts @@ -0,0 +1,14 @@ +import { pathsToModuleNameMapper } from 'ts-jest'; +import { compilerOptions } from './tsconfig.json'; + +export default { + preset: 'ts-jest', + testEnvironment: 'node', + moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '/src/' }), + modulePaths: [ + '' + ], + transform: { + '^.+\\.tsx?$': 'ts-jest', + }, +}; \ No newline at end of file diff --git a/src/node/consumer/jsconfig.json b/src/node/consumer/jsconfig.json deleted file mode 100644 index 6b1c407..0000000 --- a/src/node/consumer/jsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compilerOptions": { - "baseUrl": "./src", - "checkJs": true, - "isolatedModules": true, - "lib": ["es6"], - "module": "ESNext", - "moduleResolution": "node", - "outDir": "./dist", - "pretty": true, - "removeComments": true, - "resolveJsonModule": true, - "rootDir": "./src", - "skipLibCheck": true, - "sourceMap": true, - "target": "ES6", - "types": ["node"], - "typeRoots": ["node_modules/@types", "src/@types"] - }, - "exclude": ["node_modules"] -} \ No newline at end of file diff --git a/src/node/consumer/package-lock.json b/src/node/consumer/package-lock.json index f6408a3..41b4c50 100644 --- a/src/node/consumer/package-lock.json +++ b/src/node/consumer/package-lock.json @@ -14,43 +14,57 @@ "axios": "^1.6.1", "bottleneck": "^2.19.5", "cache-manager": "^5.4.0", - "dotenv": "^16.4.1", "google-sr": "^3.2.1", - "jaro-winkler": "^0.2.8", + "inversify": "^6.0.2", "magnet-uri": "^6.2.0", "moment": "^2.30.1", - "mongodb": "^6.3.0", "name-to-imdb": "^3.0.4", "parse-torrent-title": "https://github.com/TheBeastLT/parse-torrent-title.git#022408972c2a040f846331a912a6a8487746a654", "pg": "^8.11.3", "pg-hstore": "^2.3.4", "pino": "^8.18.0", - "sequelize": "^6.31.1", - "torrent-stream": "^1.2.1", - "user-agents": "^1.0.1444" + "reflect-metadata": "^0.2.1", + "sequelize": "^6.36.0", + "sequelize-typescript": "^2.1.6", + "torrent-stream": "^1.2.1" }, "devDependencies": { - "@types/node": "^20.11.6", - "@types/stremio-addon-sdk": "^1.6.10", + "@types/amqplib": "^0.10.4", + "@types/jest": "^29.5.12", + "@types/magnet-uri": "^5.1.5", + "@types/node": "^20.11.16", + "@types/pg": "^8.11.0", + "@types/torrent-stream": "^0.0.9", + "@types/validator": "^13.11.8", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", "esbuild": "^0.20.0", "eslint": "^8.56.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-import-helpers": "^1.3.1", + "jest": "^29.7.0", + "msw": "^2.1.7", "pino-pretty": "^10.3.1", - "tsx": "^4.7.0" + "ts-jest": "^29.1.2", + "ts-node": "^10.9.2", + "tsconfig-paths": "^4.2.0", + "tsx": "^4.7.0", + "typescript": "^5.3.3" } }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/@acuminous/bitsyntax": { "version": "0.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@acuminous/bitsyntax/-/bitsyntax-0.1.2.tgz", + "integrity": "sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==", "dependencies": { "buffer-more-ints": "~1.0.0", "debug": "^4.3.4", @@ -60,6 +74,723 @@ "node": ">=0.8" } }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "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, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", + "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.9", + "@babel/parser": "^7.23.9", + "@babel/template": "^7.23.9", + "@babel/traverse": "^7.23.9", + "@babel/types": "^7.23.9", + "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/core/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, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/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, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/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, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", + "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.23.9", + "@babel/traverse": "^7.23.9", + "@babel/types": "^7.23.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "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, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", + "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.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, + "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, + "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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "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, + "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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "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, + "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, + "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, + "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, + "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, + "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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.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, + "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.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", + "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.23.9", + "@babel/types": "^7.23.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", + "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.9", + "@babel/types": "^7.23.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", + "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "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/@bundled-es-modules/cookie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz", + "integrity": "sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==", + "dev": true, + "dependencies": { + "cookie": "^0.5.0" + } + }, + "node_modules/@bundled-es-modules/statuses": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz", + "integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==", + "dev": true, + "dependencies": { + "statuses": "^2.0.1" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.20.0", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.0.tgz", @@ -430,8 +1161,9 @@ }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, - "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -444,16 +1176,18 @@ }, "node_modules/@eslint-community/regexpp": { "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "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": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -472,18 +1206,42 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/js": { "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", "dev": true, - "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", @@ -493,10 +1251,33 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/config-array/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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "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" }, @@ -507,20 +1288,483 @@ }, "node_modules/@humanwhocodes/object-schema": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "dev": true + }, + "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, - "license": "BSD-3-Clause" + "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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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, + "engines": { + "node": ">=8" + } + }, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", + "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } }, "node_modules/@mongodb-js/saslprep": { "version": "1.1.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.4.tgz", + "integrity": "sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw==", "dependencies": { "sparse-bitfield": "^3.0.3" } }, + "node_modules/@mswjs/cookies": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mswjs/cookies/-/cookies-1.1.0.tgz", + "integrity": "sha512-0ZcCVQxifZmhwNBoQIrystCb+2sWBY2Zw8lpfJBPCHGCA/HWqehITeCRVIv4VMy8MPlaHo2w2pTHFV2pFfqKPw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@mswjs/interceptors": { + "version": "0.25.16", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.25.16.tgz", + "integrity": "sha512-8QC8JyKztvoGAdPgyZy49c9vSHHAZjHagwl4RY9E8carULk8ym3iTaiawrT1YoLF/qb449h48f71XDPgkUSOUg==", + "dev": true, + "dependencies": { + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.2.1", + "strict-event-emitter": "^0.5.1" + }, + "engines": { + "node": ">=18" + } + }, "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" @@ -531,16 +1775,18 @@ }, "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" @@ -549,6 +1795,52 @@ "node": ">= 8" } }, + "node_modules/@open-draft/deferred-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", + "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", + "dev": true + }, + "node_modules/@open-draft/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", + "dev": true, + "dependencies": { + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" + } + }, + "node_modules/@open-draft/until": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", + "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", + "dev": true + }, + "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 + }, + "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, + "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, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, "node_modules/@tirke/node-cache-manager-mongodb": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@tirke/node-cache-manager-mongodb/-/node-cache-manager-mongodb-1.6.0.tgz", @@ -563,57 +1855,437 @@ "url": "https://github.com/sponsors/tirke" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@types/amqplib": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@types/amqplib/-/amqplib-0.10.4.tgz", + "integrity": "sha512-Y5Sqquh/LqDxSgxYaAAFNM0M7GyONtSDCcFMJk+DQwYEjibPyW6y+Yu9H9omdkKc3epyXULmFN3GTaeBHhn2Hg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "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, + "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.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "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, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", + "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true + }, "node_modules/@types/debug": { "version": "4.1.12", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", "dependencies": { "@types/ms": "*" } }, + "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, + "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==", + "dev": true + }, + "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, + "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, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, "node_modules/@types/json5": { "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/magnet-uri": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/magnet-uri/-/magnet-uri-5.1.5.tgz", + "integrity": "sha512-SbBjlb1KGe38VfjRR+mwqztJd/4skhdKkRbIzPDhTy7IAeEAPZWIVSEkZw00Qr4ZZOGR3/ATJ20WWPBfrKHGdA==", "dev": true, - "license": "MIT" + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/ms": { "version": "0.7.34", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { "version": "20.11.16", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz", + "integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==", "dependencies": { "undici-types": "~5.26.4" } }, - "node_modules/@types/node/node_modules/undici-types": { - "version": "5.26.5", - "license": "MIT" - }, - "node_modules/@types/stremio-addon-sdk": { - "version": "1.6.11", + "node_modules/@types/pg": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.0.tgz", + "integrity": "sha512-sDAlRiBNthGjNFfvt0k6mtotoVYVQ63pA8R4EMWka7crawSR60waVYR0HAgmPRs/e2YaeJTD/43OoZ3PFw80pw==", "dev": true, - "license": "MIT" + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^4.0.1" + } + }, + "node_modules/@types/semver": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "dev": true + }, + "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 + }, + "node_modules/@types/statuses": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.4.tgz", + "integrity": "sha512-eqNDvZsCNY49OAXB0Firg/Sc2BgoWsntsLUdybGFOhAfCD6QJ2n9HXUIHGqt5qjrxmMv4wS8WLAw43ZkKcJ8Pw==", + "dev": true + }, + "node_modules/@types/torrent-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@types/torrent-stream/-/torrent-stream-0.0.9.tgz", + "integrity": "sha512-SY0K6HNlDdnU7yk4TWpLjlv65/liZnxmftMuOdjRriC2IGExqnAYfl8dprjU1j1KQMPVM/X174cusUPNPloghQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/validator": { - "version": "13.11.8", - "license": "MIT" + "version": "13.11.9", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.9.tgz", + "integrity": "sha512-FCTsikRozryfayPuiI46QzH3fnrOoctTjvOYZkho9BTFLCOZ2rgZJHMOVgCOfttjPJcgOx52EpkY0CMfy87MIw==" }, "node_modules/@types/webidl-conversions": { "version": "7.0.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" }, "node_modules/@types/whatwg-url": { "version": "11.0.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.4.tgz", + "integrity": "sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==", "dependencies": { "@types/webidl-conversions": "*" } }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "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 + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true }, "node_modules/abort-controller": { "version": "3.0.0", @@ -628,8 +2300,9 @@ }, "node_modules/acorn": { "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, - "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -639,20 +2312,32 @@ }, "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.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/addr-to-ip-port": { "version": "1.5.4", - "license": "MIT" + "resolved": "https://registry.npmjs.org/addr-to-ip-port/-/addr-to-ip-port-1.5.4.tgz", + "integrity": "sha512-ByxmJgv8vjmDcl3IDToxL2yrWFrRtFpZAToY0f46XFXl8zS081t7El5MXIodwm7RC6DhHBRoOSMLFSPKCtHukg==" }, "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": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -666,7 +2351,8 @@ }, "node_modules/amqplib": { "version": "0.10.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.3.tgz", + "integrity": "sha512-UHmuSa7n8vVW/a5HGh2nFPqAEr8+cD4dEZ6u9GjP91nHfr1a54RyAKyra7Sb5NH7NBKOUlyQSMXIp0qAixKexw==", "dependencies": { "@acuminous/bitsyntax": "^0.1.2", "buffer-more-ints": "~1.0.0", @@ -677,18 +2363,47 @@ "node": ">=10" } }, + "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==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "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" } }, "node_modules/ansi-styles": { "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" }, @@ -699,18 +2414,42 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "node_modules/argparse": { "version": "2.0.1", - "dev": true, - "license": "Python-2.0" + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/array-buffer-byte-length": { - "version": "1.0.0", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -718,8 +2457,9 @@ }, "node_modules/array-includes": { "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -734,16 +2474,45 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.3", + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.filter": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz", + "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz", + "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -754,8 +2523,9 @@ }, "node_modules/array.prototype.flat": { "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -771,8 +2541,9 @@ }, "node_modules/array.prototype.flatmap": { "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -787,16 +2558,18 @@ } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.2", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, - "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", "is-shared-array-buffer": "^1.0.2" }, "engines": { @@ -808,7 +2581,8 @@ }, "node_modules/asynckit": { "version": "0.4.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/atomic-sleep": { "version": "1.0.0", @@ -820,8 +2594,9 @@ }, "node_modules/available-typed-arrays": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", + "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -831,16 +2606,134 @@ }, "node_modules/axios": { "version": "1.6.7", - "license": "MIT", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dependencies": { "follow-redirects": "^1.15.4", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, + "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, + "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" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.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, + "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" + }, + "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, + "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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/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, + "bin": { + "semver": "bin/semver.js" + } + }, + "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, + "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-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@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-top-level-await": "^7.8.3" + }, + "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, + "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/balanced-match": { "version": "1.0.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base64-js": { "version": "1.5.1", @@ -863,19 +2756,32 @@ }, "node_modules/bencode": { "version": "0.7.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/bencode/-/bencode-0.7.0.tgz", + "integrity": "sha512-MG5AM/hkQIZoz/layZ1JK3xBTfqkLcJ3dJ7u2lx+6vZT1JWyK3OgEFGx1WFzWt6grGH6OSGQvRcCnhWKLp4f1Q==" }, "node_modules/bep53-range": { "version": "1.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/bep53-range/-/bep53-range-1.1.1.tgz", + "integrity": "sha512-ct6s33iiwRCUPp9KXnJ4QMWDgHIgaw36caK/5XEQ9L8dCzSQlJt1Vk6VmHh1VD4AlGCAI4C2zmtfItifBBPrhQ==" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } }, "node_modules/bitfield": { "version": "0.1.0", - "license": "-" + "resolved": "https://registry.npmjs.org/bitfield/-/bitfield-0.1.0.tgz", + "integrity": "sha512-M15ypXCxXd81FSOWL2ejHpB1TDKmz7Y55/VuqfExJi72sHW0JzE5dfV+hrSZafZtWRg/tdMsdte5dgwrlOM7nA==" }, "node_modules/bittorrent-dht": { "version": "6.4.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/bittorrent-dht/-/bittorrent-dht-6.4.2.tgz", + "integrity": "sha512-DeBunF1nL/ckThYyU3AVtHFR195zNV06Ob6bKNXA1y6X56GSKMfkNCABB45YcbZevGMW1dytFlm59D/fws5lTg==", "dependencies": { "bencode": "^0.7.0", "buffer-equals": "^1.0.3", @@ -888,18 +2794,21 @@ }, "node_modules/bittorrent-dht/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, - "node_modules/bittorrent-dht/node_modules/debug/node_modules/ms": { + "node_modules/bittorrent-dht/node_modules/ms": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/bittorrent-tracker": { "version": "7.7.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/bittorrent-tracker/-/bittorrent-tracker-7.7.0.tgz", + "integrity": "sha512-YFgPTVRhUMncZr8tM3ige7gnViMGhKoGF23qaiISRG8xtYebTGHrMSMXsTXo6O1KbtdEI+4jzvGY1K/wdT9GUA==", "dependencies": { "bencode": "^0.8.0", "bn.js": "^4.4.0", @@ -927,60 +2836,188 @@ }, "node_modules/bittorrent-tracker/node_modules/bencode": { "version": "0.8.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/bencode/-/bencode-0.8.0.tgz", + "integrity": "sha512-MWs3FqaWOGg5l+quIT9JTx7+SlcMbfPqqpWy+GOYi5rjZkX8i03tkNhAQn3pD2GAKENPpP3ScUR97ZUMffhHZA==" }, "node_modules/bittorrent-tracker/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, - "node_modules/bittorrent-tracker/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "license": "MIT" + "node_modules/bittorrent-tracker/node_modules/ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" }, - "node_modules/bittorrent-tracker/node_modules/once": { - "version": "1.4.0", - "license": "ISC", + "node_modules/bittorrent-tracker/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, "dependencies": { - "wrappy": "1" + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bl/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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" + } + ] + }, + "node_modules/bl/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" } }, "node_modules/bn.js": { "version": "4.12.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, "node_modules/bncode": { - "version": "0.5.3" + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/bncode/-/bncode-0.5.3.tgz", + "integrity": "sha512-0P5VuWobU5Gwbeio8n9Jsdv0tE1IikrV9n4f7RsnXHNtxmdd/oeIO6QyoSEUAEyo5P6i3XMfBppi82WqNsT4JA==" }, "node_modules/boolbase": { "version": "1.0.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, "node_modules/bottleneck": { "version": "2.19.5", - "license": "MIT" + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "license": "MIT", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.3.tgz", + "integrity": "sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==", + "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" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001580", + "electron-to-chromium": "^1.4.648", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "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, + "dependencies": { + "node-int64": "^0.4.0" } }, "node_modules/bson": { "version": "6.3.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.3.0.tgz", + "integrity": "sha512-balJfqwwTBddxfnidJZagCBPP/f48zj9Sdp3OJswREOgsJzHiQSaOIAtApSgDQFYgHqAvFkp53AFSqjMDZoTFw==", "engines": { "node": ">=16.20.1" } }, "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, "funding": [ { "type": "github", @@ -997,12 +3034,13 @@ ], "dependencies": { "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "ieee754": "^1.1.13" } }, "node_modules/buffer-alloc": { "version": "1.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", "dependencies": { "buffer-alloc-unsafe": "^1.1.0", "buffer-fill": "^1.0.0" @@ -1010,44 +3048,52 @@ }, "node_modules/buffer-alloc-unsafe": { "version": "1.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" }, "node_modules/buffer-equal": { "version": "0.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", + "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==", "engines": { "node": ">=0.4.0" } }, "node_modules/buffer-equals": { "version": "1.0.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/buffer-equals/-/buffer-equals-1.0.4.tgz", + "integrity": "sha512-99MsCq0j5+RhubVEtKQgKaD6EM+UP3xJgIvQqwJ3SOLDUekzxMX1ylXBng+Wa2sh7mGT0W6RUly8ojjr1Tt6nA==", "engines": { "node": ">=0.10.0" } }, "node_modules/buffer-fill": { "version": "1.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" }, "node_modules/buffer-from": { "version": "1.1.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "node_modules/buffer-more-ints": { "version": "1.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" }, "node_modules/buffer-writer": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", "engines": { "node": ">=4" } }, "node_modules/cache-manager": { "version": "5.4.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-5.4.0.tgz", + "integrity": "sha512-FS7o8vqJosnLpu9rh2gQTo8EOzCRJLF1BJ4XDEUDMqcfvs7SJZs5iuoFTXLauzQ3S5v8sBAST1pCwMaurpyi1A==", "dependencies": { "lodash.clonedeep": "^4.5.0", "lru-cache": "^10.1.0", @@ -1055,13 +3101,18 @@ } }, "node_modules/call-bind": { - "version": "1.0.5", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz", + "integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==", "dev": true, - "license": "MIT", "dependencies": { + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.3", + "set-function-length": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1069,16 +3120,47 @@ }, "node_modules/callsites": { "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, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001585", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001585.tgz", + "integrity": "sha512-yr2BWR1yLXQ8fMpdS/4ZZXpseBgE7o4g41x3a6AJOqZuOi+iE/WdJYAuZ6Y95i4Ohd2Y+9MzIWRR+uGABH4s3Q==", + "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" + } + ] + }, "node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -1090,9 +3172,25 @@ "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==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "node_modules/cheerio": { "version": "1.0.0-rc.12", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", @@ -1111,7 +3209,8 @@ }, "node_modules/cheerio-select": { "version": "2.1.0", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", @@ -1124,8 +3223,46 @@ "url": "https://github.com/sponsors/fb55" } }, + "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, + "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.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/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, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/chrome-dgram": { "version": "3.0.6", + "resolved": "https://registry.npmjs.org/chrome-dgram/-/chrome-dgram-3.0.6.tgz", + "integrity": "sha512-bqBsUuaOiXiqxXt/zA/jukNJJ4oaOtc7ciwqJpZVEaaXwwxqgI2/ZdG02vXYWUhHGziDlvGMQWk0qObgJwVYKA==", "funding": [ { "type": "github", @@ -1140,7 +3277,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "inherits": "^2.0.4", "run-series": "^1.1.9" @@ -1148,13 +3284,16 @@ }, "node_modules/chrome-dns": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/chrome-dns/-/chrome-dns-1.0.1.tgz", + "integrity": "sha512-HqsYJgIc8ljJJOqOzLphjAs79EUuWSX3nzZi2LNkzlw3GIzAeZbaSektC8iT/tKvLqZq8yl1GJu5o6doA4TRbg==", "dependencies": { "chrome-net": "^3.3.2" } }, "node_modules/chrome-net": { "version": "3.3.4", + "resolved": "https://registry.npmjs.org/chrome-net/-/chrome-net-3.3.4.tgz", + "integrity": "sha512-Jzy2EnzmE+ligqIZUsmWnck9RBXLuUy6CaKyuNMtowFG3ZvLt8d+WBJCTPEludV0DHpIKjAOlwjFmTaEdfdWCw==", "funding": [ { "type": "github", @@ -1169,15 +3308,125 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "inherits": "^2.0.1" } }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "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, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/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, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "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, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "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 + }, "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" }, @@ -1187,8 +3436,9 @@ }, "node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/colorette": { "version": "2.0.20", @@ -1198,7 +3448,8 @@ }, "node_modules/combined-stream": { "version": "1.0.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -1208,23 +3459,69 @@ }, "node_modules/compact2string": { "version": "1.4.1", - "license": "BSD", + "resolved": "https://registry.npmjs.org/compact2string/-/compact2string-1.4.1.tgz", + "integrity": "sha512-3D+EY5nsRhqnOwDxveBv5T8wGo4DEvYxjDtPGmdOX+gfr5gE92c2RC0w2wa+xEefm07QuVqqcF3nZJUZ92l/og==", "dependencies": { "ipaddr.js": ">= 0.1.5" } }, "node_modules/concat-map": { "version": "0.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "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 + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } }, "node_modules/core-util-is": { "version": "1.0.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "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, + "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" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true }, "node_modules/cross-spawn": { "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1236,7 +3533,8 @@ }, "node_modules/css-select": { "version": "5.1.0", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", @@ -1250,7 +3548,8 @@ }, "node_modules/css-what": { "version": "6.1.0", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "engines": { "node": ">= 6" }, @@ -1259,7 +3558,9 @@ } }, "node_modules/cyclist": { - "version": "0.1.1" + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.1.1.tgz", + "integrity": "sha512-w8a8nQk9YSCkMmH2wDbFqpH1XMz7l409mSvWnnG6Iu6D0Ydhvq61XASE7QIaA46FxfG2Ag524ZuGgAy2cXPfsw==" }, "node_modules/dateformat": { "version": "4.6.3", @@ -1272,7 +3573,8 @@ }, "node_modules/debug": { "version": "4.3.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, @@ -1285,13 +3587,10 @@ } } }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "license": "MIT" - }, "node_modules/decompress-response": { "version": "3.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", "dependencies": { "mimic-response": "^1.0.0" }, @@ -1299,26 +3598,65 @@ "node": ">=4" } }, + "node_modules/dedent": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, "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 + }, + "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==", "dev": true, - "license": "MIT" + "engines": { + "node": ">=0.10.0" + } }, "node_modules/deepmerge-ts": { "version": "5.1.0", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-5.1.0.tgz", + "integrity": "sha512-eS8dRJOckyo9maw9Tu5O5RUi/4inFLrnoLkBe3cPfDMx3WZioXtmOew4TXQaxq7Rhl4xjDtR7c6x8nNTxOvbFw==", "engines": { "node": ">=16.0.0" } }, - "node_modules/define-data-property": { - "version": "1.1.1", + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, - "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.1", + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz", + "integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.2", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -1326,8 +3664,9 @@ }, "node_modules/define-properties": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, - "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -1342,19 +3681,61 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { "node": ">=0.4.0" } }, + "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, + "engines": { + "node": ">=8" + } + }, "node_modules/diacritics": { "version": "1.3.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/diacritics/-/diacritics-1.3.0.tgz", + "integrity": "sha512-wlwEkqcsaxvPJML+rDh/2iS824jbREk6DUMUKkEaSlxdYHeS43cClJtsWglvw2RfeXGm6ohKDqsXteJ5sP5enA==" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.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, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } }, "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": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -1364,7 +3745,8 @@ }, "node_modules/dom-serializer": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -1376,17 +3758,19 @@ }, "node_modules/domelementtype": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/fb55" } - ], - "license": "BSD-2-Clause" + ] }, "node_modules/domhandler": { "version": "5.0.3", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dependencies": { "domelementtype": "^2.3.0" }, @@ -1399,7 +3783,8 @@ }, "node_modules/domutils": { "version": "3.1.0", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -1409,31 +3794,71 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/dotenv": { - "version": "16.4.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", - "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==", + "node_modules/dottie": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.6.tgz", + "integrity": "sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA==" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.661", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.661.tgz", + "integrity": "sha512-AFg4wDHSOk5F+zA8aR+SVIOabu7m0e7BiJnigCvPXzIGy731XENw/lmNxTySpVFtkFEy+eyt4oHhh5FF3NjQNw==", + "dev": true + }, + "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, "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/dottie": { - "version": "2.0.6", - "license": "MIT" + "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 + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "optional": true, + "peer": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "optional": true, + "peer": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, "node_modules/end-of-stream": { - "version": "0.1.5", - "license": "MIT", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, "dependencies": { - "once": "~1.3.0" + "once": "^1.4.0" } }, "node_modules/entities": { "version": "4.5.0", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "engines": { "node": ">=0.12" }, @@ -1441,10 +3866,20 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "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, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/es-abstract": { "version": "1.22.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", + "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", "dev": true, - "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.0", "arraybuffer.prototype.slice": "^1.0.2", @@ -1493,10 +3928,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-set-tostringtag": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", + "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", "dev": true, - "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.2", "has-tostringtag": "^1.0.0", @@ -1508,16 +3959,18 @@ }, "node_modules/es-shim-unscopables": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, - "license": "MIT", "dependencies": { "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, - "license": "MIT", "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -1568,10 +4021,20 @@ "@esbuild/win32-x64": "0.20.0" } }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/escape-string-regexp": { "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": ">=10" }, @@ -1581,8 +4044,9 @@ }, "node_modules/eslint": { "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -1635,8 +4099,9 @@ }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -1645,21 +4110,18 @@ }, "node_modules/eslint-import-resolver-node/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, - "node_modules/eslint-import-resolver-node/node_modules/debug/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "license": "MIT" - }, "node_modules/eslint-module-utils": { "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^3.2.7" }, @@ -1674,21 +4136,18 @@ }, "node_modules/eslint-module-utils/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, - "node_modules/eslint-module-utils/node_modules/debug/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "license": "MIT" - }, "node_modules/eslint-plugin-import": { "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, - "license": "MIT", "dependencies": { "array-includes": "^3.1.7", "array.prototype.findlastindex": "^1.2.3", @@ -1717,29 +4176,37 @@ }, "node_modules/eslint-plugin-import-helpers": { "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-helpers/-/eslint-plugin-import-helpers-1.3.1.tgz", + "integrity": "sha512-MrACDozK6TmTJoCFHD71Ew3r5210Za3zlTrhX+fQGsyvxceaFvAI9AcvZ/8oSU0pZ61G3nDEn6mXY0T4S8cJEg==", "dev": true, - "license": "MIT", "peerDependencies": { "eslint": "5.x - 8.x" } }, + "node_modules/eslint-plugin-import/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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/eslint-plugin-import/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, - "node_modules/eslint-plugin-import/node_modules/debug/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "license": "MIT" - }, "node_modules/eslint-plugin-import/node_modules/doctrine": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, - "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -1747,10 +4214,65 @@ "node": ">=0.10.0" } }, + "node_modules/eslint-plugin-import/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-import/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, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-import/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, "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" @@ -1764,8 +4286,9 @@ }, "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" }, @@ -1773,10 +4296,33 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "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", @@ -1789,10 +4335,24 @@ "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, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -1802,8 +4362,9 @@ }, "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" }, @@ -1813,16 +4374,18 @@ }, "node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "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" } @@ -1837,11 +4400,74 @@ }, "node_modules/events": { "version": "3.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "engines": { "node": ">=0.8.x" } }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "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, + "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/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/fast-copy": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.1.tgz", @@ -1850,18 +4476,49 @@ }, "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 + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, - "license": "MIT" + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/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, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true }, "node_modules/fast-redact": { "version": "3.3.0", @@ -1878,21 +4535,57 @@ "dev": true }, "node_modules/fastq": { - "version": "1.17.0", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, - "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, + "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==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, "node_modules/fifo": { "version": "0.1.4", - "license": "MIT" + "resolved": "https://registry.npmjs.org/fifo/-/fifo-0.1.4.tgz", + "integrity": "sha512-CpKgwraLo4YWY9cUEICNJ1WcOVR2WE1Jvot3Nvr7FGBiGOKgkn1CmF4zuCl9VxvEh1nQsdYXtQg+V0etPiED6g==" + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.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" }, @@ -1900,10 +4593,23 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/find-up": { "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": "^6.0.0", "path-exists": "^4.0.0" @@ -1917,8 +4623,9 @@ }, "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", @@ -1928,40 +4635,31 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/flatted": { "version": "3.2.9", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true }, "node_modules/flatten": { "version": "0.0.1", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-0.0.1.tgz", + "integrity": "sha512-pzNZh42/A2HmcRIpddSP0T+zBofd119o5rNB2u1YHv36CM2C/ietI2ZsjWZ2LSL7J0BNVkFn1a9Ad+cmO2lDQg==", + "deprecated": "flatten is deprecated in favor of utility frameworks such as lodash.", "engines": { "node": "*" } }, "node_modules/follow-redirects": { "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], - "license": "MIT", "engines": { "node": ">=4.0" }, @@ -1973,15 +4671,17 @@ }, "node_modules/for-each": { "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, - "license": "MIT", "dependencies": { "is-callable": "^1.1.3" } }, "node_modules/form-data": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -1993,7 +4693,8 @@ }, "node_modules/fs-chunk-store": { "version": "1.7.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/fs-chunk-store/-/fs-chunk-store-1.7.0.tgz", + "integrity": "sha512-KhjJmZAs2eqfhCb6PdPx4RcZtheGTz86tpTC5JTvqBn/xda+Nb+0C7dCyjOSN7T76H6a56LvH0SVXQMchLXDRw==", "dependencies": { "mkdirp": "^0.5.1", "random-access-file": "^2.0.1", @@ -2005,7 +4706,8 @@ }, "node_modules/fs-chunk-store/node_modules/mkdirp": { "version": "0.5.6", - "license": "MIT", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dependencies": { "minimist": "^1.2.6" }, @@ -2013,9 +4715,21 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/fs-chunk-store/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.3", @@ -2033,16 +4747,18 @@ }, "node_modules/function-bind": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/function.prototype.name": { "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -2058,37 +4774,85 @@ }, "node_modules/functions-have-names": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, - "license": "MIT", "funding": { "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, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-browser-rtc": { "version": "1.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/get-browser-rtc/-/get-browser-rtc-1.1.0.tgz", + "integrity": "sha512-MghbMJ61EJrRsDe7w1Bvqt3ZsBuqhce5nrn/XAwgwOXhcsz53/ltdxOse1h/8eKXj5slzxdsz56g5rzOFSGwfQ==" + }, + "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, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } }, "node_modules/get-intrinsic": { - "version": "1.2.2", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, - "license": "MIT", "dependencies": { + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-symbol-description": { - "version": "1.0.0", + "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, + "engines": { + "node": ">=8.0.0" + } + }, + "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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" @@ -2111,7 +4875,8 @@ }, "node_modules/glob": { "version": "7.2.3", - "license": "ISC", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2129,8 +4894,9 @@ }, "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" }, @@ -2138,17 +4904,31 @@ "node": ">=10.13.0" } }, - "node_modules/glob/node_modules/once": { - "version": "1.4.0", - "license": "ISC", + "node_modules/glob/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==", "dependencies": { - "wrappy": "1" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, "node_modules/globals": { "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" }, @@ -2161,8 +4941,9 @@ }, "node_modules/globalthis": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, - "license": "MIT", "dependencies": { "define-properties": "^1.1.3" }, @@ -2173,9 +4954,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/google-sr": { "version": "3.2.1", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/google-sr/-/google-sr-3.2.1.tgz", + "integrity": "sha512-1WGy6mxMTKo+jbIrmq1mwm+2Egvmx9ttsXzCiR0Y2LMcpeG4shqc8C4g12msi4arRn9qEwG1qrFQ1W9jo3dDzw==", "dependencies": { "axios": "^1.4.0", "cheerio": "1.0.0-rc.12", @@ -2186,12 +4988,14 @@ }, "node_modules/google-sr-selectors": { "version": "0.0.2", - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/google-sr-selectors/-/google-sr-selectors-0.0.2.tgz", + "integrity": "sha512-7h+vo7NSDf+pZB/InDon4mwhXeTvy/9yvAChGnjppcdHgTwlUWDpYPWGUn781J3PrjBj6rZAginsSTGqG5uUZw==" }, "node_modules/gopd": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, - "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -2199,31 +5003,50 @@ "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==", + "dev": true + }, "node_modules/graphemer": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/graphql": { + "version": "16.8.1", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz", + "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==", "dev": true, - "license": "MIT" + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } }, "node_modules/has-bigints": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "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": ">=8" } }, "node_modules/has-property-descriptors": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "dev": true, - "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.2" }, @@ -2233,8 +5056,9 @@ }, "node_modules/has-proto": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -2244,8 +5068,9 @@ }, "node_modules/has-symbols": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -2255,8 +5080,9 @@ }, "node_modules/has-tostringtag": { "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" }, @@ -2269,8 +5095,9 @@ }, "node_modules/hasown": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", "dev": true, - "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -2280,7 +5107,17 @@ }, "node_modules/hat": { "version": "0.0.3", - "license": "MIT/X11" + "resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz", + "integrity": "sha512-zpImx2GoKXy42fVDSEad2BPKuSQdLcqsCYa48K3zHSzM/ugWuYjLDr8IXxpVuL7uCLHw56eaiLxCRthhOzf5ug==", + "engines": { + "node": "*" + } + }, + "node_modules/headers-polyfill": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.2.tgz", + "integrity": "sha512-EWGTfnTqAO2L/j5HZgoM/3z82L7necsJ0pO9Tp0X1wil3PDLrkypTBRgVO2ExehEEvUycejZD3FuRaXpZZc3kw==", + "dev": true }, "node_modules/help-me": { "version": "5.0.0", @@ -2288,8 +5125,16 @@ "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", "dev": true }, + "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/htmlparser2": { "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -2297,7 +5142,6 @@ "url": "https://github.com/sponsors/fb55" } ], - "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", @@ -2305,9 +5149,19 @@ "entities": "^4.4.0" } }, + "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, + "engines": { + "node": ">=10.17.0" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", - "license": "MIT", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -2336,20 +5190,23 @@ }, "node_modules/ignore": { "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/immediate-chunk-store": { "version": "1.0.8", - "license": "MIT" + "resolved": "https://registry.npmjs.org/immediate-chunk-store/-/immediate-chunk-store-1.0.8.tgz", + "integrity": "sha512-0tQyTytUaIUskpv5j5L5ZeQuEjYDl9QIekwDUisdqpAM81OZjBaEIriW7hoiRLaLNxj1fXE8e1yx5JaCGrrE7A==" }, "node_modules/import-fresh": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -2361,46 +5218,89 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.19" } }, "node_modules/inflection": { "version": "1.13.4", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz", + "integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==", "engines": [ "node >= 0.4.0" - ], - "license": "MIT" + ] }, "node_modules/inflight": { "version": "1.0.6", - "license": "ISC", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "node_modules/inflight/node_modules/once": { - "version": "1.4.0", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/inherits": { "version": "2.0.4", - "license": "ISC" + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/inquirer": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } }, "node_modules/internal-slot": { - "version": "1.0.6", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, - "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.2", + "es-errors": "^1.3.0", "hasown": "^2.0.0", "side-channel": "^1.0.4" }, @@ -2408,28 +5308,44 @@ "node": ">= 0.4" } }, + "node_modules/inversify": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/inversify/-/inversify-6.0.2.tgz", + "integrity": "sha512-i9m8j/7YIv4mDuYXUAcrpKPSaju/CIly9AHK5jvCBeoiM/2KEsuCQTTP+rzSWWpLYWRukdXFSl6ZTk2/uumbiA==" + }, "node_modules/ip": { - "version": "1.1.8", - "license": "MIT" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "optional": true, + "peer": true }, "node_modules/ip-set": { "version": "1.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ip-set/-/ip-set-1.0.2.tgz", + "integrity": "sha512-Mb6kv78bTi4RNAIIWL8Bbre7hXOR2pNUi3j8FaQkLaitf/ZWxkq3/iIwXNYk2ACO3IMfdVdQrOkUtwZblO7uBA==", "dependencies": { "ip": "^1.1.3" } }, + "node_modules/ip-set/node_modules/ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" + }, "node_modules/ipaddr.js": { "version": "2.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", "engines": { "node": ">= 10" } }, "node_modules/is-array-buffer": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1" @@ -2441,10 +5357,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, "node_modules/is-bigint": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, - "license": "MIT", "dependencies": { "has-bigints": "^1.0.1" }, @@ -2452,10 +5375,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -2469,8 +5405,9 @@ }, "node_modules/is-callable": { "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -2480,8 +5417,9 @@ }, "node_modules/is-core-module": { "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, - "license": "MIT", "dependencies": { "hasown": "^2.0.0" }, @@ -2491,8 +5429,9 @@ }, "node_modules/is-date-object": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, - "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -2505,16 +5444,36 @@ }, "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": ">=0.10.0" } }, + "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, + "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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "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" }, @@ -2522,10 +5481,20 @@ "node": ">=0.10.0" } }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-negative-zero": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -2533,10 +5502,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-node-process": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", + "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", + "dev": true + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/is-number-object": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, - "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -2549,16 +5534,18 @@ }, "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" } }, "node_modules/is-regex": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -2572,8 +5559,9 @@ }, "node_modules/is-shared-array-buffer": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -2581,10 +5569,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, - "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -2597,8 +5598,9 @@ }, "node_modules/is-symbol": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, - "license": "MIT", "dependencies": { "has-symbols": "^1.0.2" }, @@ -2611,8 +5613,9 @@ }, "node_modules/is-typed-array": { "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, - "license": "MIT", "dependencies": { "which-typed-array": "^1.1.14" }, @@ -2623,10 +5626,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-weakref": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -2636,16 +5652,635 @@ }, "node_modules/isarray": { "version": "0.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" }, "node_modules/isexe": { "version": "2.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, - "node_modules/jaro-winkler": { - "version": "0.2.8", - "license": "MIT" + "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, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", + "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "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, + "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, + "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.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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-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, + "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, + "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-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, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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, + "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-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, + "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, + "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, + "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, + "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, + "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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } }, "node_modules/joycon": { "version": "3.1.1", @@ -2656,10 +6291,17 @@ "node": ">=10" } }, + "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 + }, "node_modules/js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -2667,35 +6309,58 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/json-buffer": { "version": "3.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "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==", + "dev": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "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 }, "node_modules/json5": { - "version": "1.0.2", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, "bin": { "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, "node_modules/k-bucket": { "version": "0.6.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/k-bucket/-/k-bucket-0.6.0.tgz", + "integrity": "sha512-1zJpqkrLYgolqdO1TE1/FWf+mHfhJKLC2Wpi4JaMFZKi4b6tFEn9/d+JqscBIJw5auWFewp16CSAEetFGEC4NQ==", "dependencies": { "buffer-equal": "0.0.1", "inherits": "^2.0.1" @@ -2703,7 +6368,8 @@ }, "node_modules/k-rpc": { "version": "3.7.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/k-rpc/-/k-rpc-3.7.0.tgz", + "integrity": "sha512-XFL8PatIToQ/qhSSAq9FSK73wk4fX4DcHqjnkvSCrWC59PV02Oj1KeYa3KnREAXgA1DlCSzcKjk7M8usnT/dUw==", "dependencies": { "buffer-equals": "^1.0.3", "k-bucket": "^2.0.0", @@ -2712,7 +6378,8 @@ }, "node_modules/k-rpc-socket": { "version": "1.11.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/k-rpc-socket/-/k-rpc-socket-1.11.1.tgz", + "integrity": "sha512-8xtA8oqbZ6v1Niryp2/g4GxW16EQh5MvrUylQoOG+zcrDff5CKttON2XUXvMwlIHq4/2zfPVFiinAccJ+WhxoA==", "dependencies": { "bencode": "^2.0.0", "chrome-dgram": "^3.0.2", @@ -2722,11 +6389,13 @@ }, "node_modules/k-rpc-socket/node_modules/bencode": { "version": "2.0.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.3.tgz", + "integrity": "sha512-D/vrAD4dLVX23NalHwb8dSvsUsxeRPO8Y7ToKA015JQYq69MLDOMkC0uGZYA/MPpltLO8rt8eqFC2j8DxjTZ/w==" }, "node_modules/k-rpc/node_modules/k-bucket": { "version": "2.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/k-bucket/-/k-bucket-2.0.1.tgz", + "integrity": "sha512-Xuye90xBBDJJbvNSuy3z/Yl8ceVX02/sopqGUEwJkMgRw+//TQXx0/Hbgp60GsoVfZcCBllQXXp6AWe2INu8pw==", "dependencies": { "buffer-equal": "0.0.1", "randombytes": "^2.0.3" @@ -2734,16 +6403,36 @@ }, "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", "dependencies": { "json-buffer": "3.0.1" } }, + "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, + "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, + "engines": { + "node": ">=6" + } + }, "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" @@ -2752,10 +6441,17 @@ "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 + }, "node_modules/locate-path": { "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": "^5.0.0" }, @@ -2768,20 +6464,46 @@ }, "node_modules/lodash": { "version": "4.17.21", - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash.clonedeep": { "version": "4.5.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true }, "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 + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, - "license": "MIT" + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/lru": { "version": "2.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/lru/-/lru-2.0.1.tgz", + "integrity": "sha512-JGRd3IHM64MPsGVw1Mqbz2Y2HDIePqi/MLfPtdrkHQwvvJnSrS9b6gM3KS9PFR5xJnufXJczHHZSmGqfuII1ew==", "dependencies": { "inherits": "^2.0.1" }, @@ -2791,13 +6513,16 @@ }, "node_modules/lru-cache": { "version": "10.2.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", "engines": { "node": "14 || >=16.14" } }, "node_modules/magnet-uri": { "version": "6.2.0", + "resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-6.2.0.tgz", + "integrity": "sha512-O9AgdDwT771fnUj0giPYu/rACpz8173y8UXCSOdLITjOVfBenZ9H9q3FqQmveK+ORUMuD+BkKNSZP8C3+IMAKQ==", "funding": [ { "type": "github", @@ -2812,26 +6537,86 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "bep53-range": "^1.1.0", "thirty-two": "^1.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, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, "node_modules/memory-pager": { "version": "1.5.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + }, + "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 + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } }, "node_modules/mime-db": { "version": "1.52.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.35", - "license": "MIT", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { "mime-db": "1.52.0" }, @@ -2839,48 +6624,63 @@ "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, + "engines": { + "node": ">=6" + } + }, "node_modules/mimic-response": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "engines": { "node": ">=4" } }, "node_modules/minimatch": { - "version": "3.1.2", - "license": "ISC", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { "version": "1.2.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mkdirp": { - "version": "0.3.5", - "license": "MIT" - }, "node_modules/mkdirp-classic": { "version": "0.5.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "node_modules/moment": { "version": "2.30.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", "engines": { "node": "*" } }, "node_modules/moment-timezone": { - "version": "0.5.44", - "license": "MIT", + "version": "0.5.45", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz", + "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==", "dependencies": { "moment": "^2.29.4" }, @@ -2890,7 +6690,8 @@ }, "node_modules/mongodb": { "version": "6.3.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz", + "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==", "dependencies": { "@mongodb-js/saslprep": "^1.1.0", "bson": "^6.2.0", @@ -2934,43 +6735,85 @@ }, "node_modules/mongodb-connection-string-url": { "version": "3.0.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", + "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", "dependencies": { "@types/whatwg-url": "^11.0.2", "whatwg-url": "^13.0.0" } }, - "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { - "version": "13.0.0", - "license": "MIT", + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/msw": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.1.7.tgz", + "integrity": "sha512-yTIYqEMqDSrdbVMrfmqP6rTKQsnIbglTvVmAHDWwNegyXPXRcV+RjsaFEqubRS266gwWCDLm9YdOkWSKLdDvJQ==", + "dev": true, + "hasInstallScript": true, "dependencies": { - "tr46": "^4.1.1", - "webidl-conversions": "^7.0.0" + "@bundled-es-modules/cookie": "^2.0.0", + "@bundled-es-modules/statuses": "^1.0.1", + "@mswjs/cookies": "^1.1.0", + "@mswjs/interceptors": "^0.25.16", + "@open-draft/until": "^2.1.0", + "@types/cookie": "^0.6.0", + "@types/statuses": "^2.0.4", + "chalk": "^4.1.2", + "chokidar": "^3.4.2", + "graphql": "^16.8.1", + "headers-polyfill": "^4.0.2", + "inquirer": "^8.2.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.2", + "path-to-regexp": "^6.2.0", + "strict-event-emitter": "^0.5.1", + "type-fest": "^4.9.0", + "yargs": "^17.7.2" }, + "bin": { + "msw": "cli/index.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mswjs" + }, + "peerDependencies": { + "typescript": ">= 4.7.x <= 5.3.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/msw/node_modules/type-fest": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.2.tgz", + "integrity": "sha512-anpAG63wSpdEbLwOqH8L84urkL6PiVIov3EMmgIhhThevh9aiMQov+6Btx0wldNcvm4wV+e2/Rt1QdDwKHFbHw==", + "dev": true, "engines": { "node": ">=16" - } - }, - "node_modules/mongodb-connection-string-url/node_modules/whatwg-url/node_modules/tr46": { - "version": "4.1.1", - "license": "MIT", - "dependencies": { - "punycode": "^2.3.0" }, - "engines": { - "node": ">=14" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mongodb-connection-string-url/node_modules/whatwg-url/node_modules/webidl-conversions": { - "version": "7.0.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true }, "node_modules/name-to-imdb": { "version": "3.0.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/name-to-imdb/-/name-to-imdb-3.0.4.tgz", + "integrity": "sha512-OVmDvWoAZso2eHxK51UK7TMIpUpM4LnI3KhvvZe+JkDatEda9WS3/YXZVQnand5skI38shoniOFcyrw08QsNeA==", "dependencies": { "diacritics": "~1.3.0", "named-queue": "^2.1.0", @@ -2980,16 +6823,19 @@ }, "node_modules/named-queue": { "version": "2.2.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/named-queue/-/named-queue-2.2.1.tgz", + "integrity": "sha512-ssW6R5DZza+ixfGgu+piZAqszqRViHNZjjazXknCWyRYZfRJkBmbSPd1nIcH29aejsyBNPNrn3AdMfB+qvb2Hw==" }, "node_modules/natural-compare": { "version": "1.4.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true }, "node_modules/needle": { "version": "1.6.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/needle/-/needle-1.6.0.tgz", + "integrity": "sha512-ogVK1D/Cgemw2vM1KJN6B83DwcKbDepdkMNtVJcXIe+xoaCOdC+aJHzhEov7xjsY9S7rBIuHP59W1fLsbGqDhA==", "dependencies": { "debug": "^2.1.2", "iconv-lite": "^0.4.4" @@ -3003,18 +6849,21 @@ }, "node_modules/needle/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, - "node_modules/needle/node_modules/debug/node_modules/ms": { + "node_modules/needle/node_modules/ms": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/node-fetch": { "version": "2.7.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -3030,25 +6879,62 @@ } } }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/node-fetch/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==" + }, "node_modules/node-fetch/node_modules/whatwg-url": { "version": "5.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, - "node_modules/node-fetch/node_modules/whatwg-url/node_modules/tr46": { - "version": "0.0.3", - "license": "MIT" + "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==", + "dev": true }, - "node_modules/node-fetch/node_modules/whatwg-url/node_modules/webidl-conversions": { - "version": "3.0.1", - "license": "BSD-2-Clause" + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "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, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } }, "node_modules/nth-check": { "version": "2.1.1", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dependencies": { "boolbase": "^1.0.0" }, @@ -3058,24 +6944,27 @@ }, "node_modules/object-inspect": { "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-keys": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -3091,8 +6980,9 @@ }, "node_modules/object.fromentries": { "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -3106,20 +6996,23 @@ } }, "node_modules/object.groupby": { - "version": "1.0.1", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.2.tgz", + "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1" + "array.prototype.filter": "^1.0.3", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0" } }, "node_modules/object.values": { "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -3132,6 +7025,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, "node_modules/on-exit-leak-free": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", @@ -3141,16 +7040,33 @@ } }, "node_modules/once": { - "version": "1.3.3", - "license": "ISC", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "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==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, - "license": "MIT", "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", @@ -3165,14 +7081,55 @@ }, "node_modules/options": { "version": "0.0.6", + "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", + "integrity": "sha512-bOj3L1ypm++N+n7CEbbe473A414AB7z+amKYshRb//iuL3MpdDCLhPnw6aVTdKB9g5ZRVHIEp8eUln6L2NUStg==", "engines": { "node": ">=0.4.0" } }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/outvariant": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.2.tgz", + "integrity": "sha512-Ou3dJ6bA/UJ5GVHxah4LnqDwZRwAmWxrG3wtrHrbGnP4RnLCtA64A4F+ae7Y8ww660JaddSoArUR5HjipWSHAQ==", + "dev": true + }, "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==", "dev": true, - "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -3185,8 +7142,9 @@ }, "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" }, @@ -3197,14 +7155,25 @@ "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, + "engines": { + "node": ">=6" + } + }, "node_modules/packet-reader": { "version": "1.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" }, "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==", "dev": true, - "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -3212,9 +7181,28 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "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, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse-torrent": { "version": "4.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/parse-torrent/-/parse-torrent-4.1.0.tgz", + "integrity": "sha512-FeoGe8bOYmSzxO31kYy44A03FjuULCMOIMom8KyuGvO8/lLVPJyo2nr9CwH/iYmNHm74hk7h70o59DOfk9Rq+A==", "dependencies": { "magnet-uri": "^4.0.0", "parse-torrent-file": "^2.0.0" @@ -3225,7 +7213,9 @@ }, "node_modules/parse-torrent-file": { "version": "2.1.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/parse-torrent-file/-/parse-torrent-file-2.1.4.tgz", + "integrity": "sha512-u2MgLOjZPDDer1oRg1c+H/+54iIQYY5TKgQ5G8KrGLT1Dcwdo7Lj+QfQR123+u8J0AMSFGbQUvsBlSB7uIJcCA==", + "deprecated": "Use the parse-torrent package instead", "dependencies": { "bencode": "^0.7.0", "simple-sha1": "^2.0.0" @@ -3237,7 +7227,7 @@ "node_modules/parse-torrent-title": { "version": "1.3.0", "resolved": "git+ssh://git@github.com/TheBeastLT/parse-torrent-title.git#022408972c2a040f846331a912a6a8487746a654", - "integrity": "sha512-Ja7OfUtTb5UKvcjHLh/va3LGZdE/CiJP6it8lxPWf/N9+4aq1hQGwXw1dnJss5dIINQo4ufyDnT2mOIP+ii/pA==", + "integrity": "sha512-2Y0gkYUyrT5sRo5cnpOt90HpciJk7oqa1iOt/AQxr186oOvth7Llj2+aqDB9MzNHX7IZ3QpfRs5fr9TZ2zAIfg==", "license": "MIT", "dependencies": { "moment": "^2.24.0" @@ -3248,22 +7238,26 @@ }, "node_modules/parse-torrent/node_modules/magnet-uri": { "version": "4.2.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-4.2.3.tgz", + "integrity": "sha512-aHhR49CRBOq3BX6jQOBdGMXhNT2+9LIH3CCIwHlR+aFE8nWMfBD1aNYxfm2u2LsCOwvfPeyCsdIg9KXSwdsOLQ==", "dependencies": { "flatten": "0.0.1", "thirty-two": "^0.0.2", "xtend": "^4.0.0" } }, - "node_modules/parse-torrent/node_modules/magnet-uri/node_modules/thirty-two": { + "node_modules/parse-torrent/node_modules/thirty-two": { "version": "0.0.2", + "resolved": "https://registry.npmjs.org/thirty-two/-/thirty-two-0.0.2.tgz", + "integrity": "sha512-0j1A9eqbP8dSEtkqqEJGpYFN2lPgQR1d0qKS2KNAmIxkK6gV37D5hRa5b/mYzVL1fyAVWBkeUDIXybZdCLVBzA==", "engines": { "node": ">=0.2.6" } }, "node_modules/parse5": { "version": "7.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "dependencies": { "entities": "^4.4.0" }, @@ -3273,7 +7267,8 @@ }, "node_modules/parse5-htmlparser2-tree-adapter": { "version": "7.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", "dependencies": { "domhandler": "^5.0.2", "parse5": "^7.0.0" @@ -3284,34 +7279,55 @@ }, "node_modules/path-exists": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "license": "MIT", "engines": { "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 + }, + "node_modules/path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "license": "MIT" + "engines": { + "node": ">=8" + } }, "node_modules/peer-wire-protocol": { "version": "0.7.1", + "resolved": "https://registry.npmjs.org/peer-wire-protocol/-/peer-wire-protocol-0.7.1.tgz", + "integrity": "sha512-V9oTa/ZcfNNz9fAST28Gg0fXbPeFPk3SBImsYO8GDDG5D0E195vxXmjZ+SPrzr4BJyMQmdDmwUfTf9MZ62z4mw==", "dependencies": { "bitfield": "^0.1.0", "bncode": "^0.2.3", @@ -3322,10 +7338,14 @@ } }, "node_modules/peer-wire-protocol/node_modules/bncode": { - "version": "0.2.3" + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/bncode/-/bncode-0.2.3.tgz", + "integrity": "sha512-IXGfySD68R/J2X/it8GZqAM+Vb3ByZvAlUi0Gysq4ZACq6hXGQ3YshKo0QS/f3S9wOWKjJnEjP6x3ELxqBnAOA==" }, "node_modules/peer-wire-swarm": { "version": "0.12.2", + "resolved": "https://registry.npmjs.org/peer-wire-swarm/-/peer-wire-swarm-0.12.2.tgz", + "integrity": "sha512-sIWZ1nTL9l6mI9J18kW1AeByBwagvNzGJlMmQA9pM+otKQtTIwnigK8SR0nEFrNZYqZelI6RQ6g4udvtQ2TI1g==", "dependencies": { "buffer-from": "^1.0.0", "fifo": "^0.1.4", @@ -3335,16 +7355,10 @@ "utp": "0.0.7" } }, - "node_modules/peer-wire-swarm/node_modules/once": { - "version": "1.4.0", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/pg": { "version": "8.11.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", + "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", "dependencies": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", @@ -3371,16 +7385,19 @@ }, "node_modules/pg-cloudflare": { "version": "1.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", "optional": true }, "node_modules/pg-connection-string": { "version": "2.6.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", + "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" }, "node_modules/pg-hstore": { "version": "2.3.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pg-hstore/-/pg-hstore-2.3.4.tgz", + "integrity": "sha512-N3SGs/Rf+xA1M2/n0JBiXFDVMzdekwLZLAO0g7mpDY9ouX+fDI7jS6kTq3JujmYbtNSJ53TJ0q4G98KVZSM4EA==", "dependencies": { "underscore": "^1.13.1" }, @@ -3390,25 +7407,56 @@ }, "node_modules/pg-int8": { "version": "1.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", "engines": { "node": ">=4.0.0" } }, + "node_modules/pg-numeric": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", + "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/pg-pool": { "version": "3.6.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", + "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { "version": "1.6.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" }, "node_modules/pg-types": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.2.tgz", + "integrity": "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==", + "dev": true, + "dependencies": { + "pg-int8": "1.0.1", + "pg-numeric": "1.0.2", + "postgres-array": "~3.0.1", + "postgres-bytea": "~3.0.0", + "postgres-date": "~2.1.0", + "postgres-interval": "^3.0.0", + "postgres-range": "^1.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pg/node_modules/pg-types": { "version": "2.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", @@ -3420,13 +7468,67 @@ "node": ">=4" } }, + "node_modules/pg/node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/pg/node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pg/node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pg/node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/pgpass": { "version": "1.0.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", "dependencies": { "split2": "^4.1.0" } }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/pino": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/pino/-/pino-8.18.0.tgz", @@ -3457,6 +7559,29 @@ "split2": "^4.0.0" } }, + "node_modules/pino-abstract-transport/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/pino-abstract-transport/node_modules/readable-stream": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", @@ -3524,6 +7649,30 @@ "pino-pretty": "bin.js" } }, + "node_modules/pino-pretty/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/pino-pretty/node_modules/readable-stream": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", @@ -3574,45 +7723,159 @@ "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==" }, - "node_modules/postgres-array": { - "version": "2.0.0", - "license": "MIT", + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, "engines": { - "node": ">=4" + "node": ">= 6" + } + }, + "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, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/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==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/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==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/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, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/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==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postgres-array": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", + "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", + "dev": true, + "engines": { + "node": ">=12" } }, "node_modules/postgres-bytea": { - "version": "1.0.0", - "license": "MIT", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", + "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", + "dev": true, + "dependencies": { + "obuf": "~1.1.2" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, "node_modules/postgres-date": { - "version": "1.0.7", - "license": "MIT", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.1.0.tgz", + "integrity": "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, "node_modules/postgres-interval": { - "version": "1.2.0", - "license": "MIT", - "dependencies": { - "xtend": "^4.0.0" - }, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", + "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, + "node_modules/postgres-range": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.4.tgz", + "integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==", + "dev": true + }, "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": ">= 0.8.0" } }, + "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, + "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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -3623,7 +7886,8 @@ }, "node_modules/process-nextick-args": { "version": "2.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/process-warning": { "version": "3.0.0", @@ -3632,14 +7896,29 @@ }, "node_modules/promise-coalesce": { "version": "1.1.2", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/promise-coalesce/-/promise-coalesce-1.1.2.tgz", + "integrity": "sha512-zLaJ9b8hnC564fnJH6NFSOGZYYdzrAJn2JUUIwzoQb32fG2QAakpDNM+CZo1km6keXkRXRM+hml1BFAPVnPkxg==", "engines": { "node": ">=16" } }, + "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, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "node_modules/pump": { "version": "3.0.0", @@ -3651,31 +7930,30 @@ "once": "^1.3.1" } }, - "node_modules/pump/node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/pump/node_modules/once": { - "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, - "dependencies": { - "wrappy": "1" - } - }, "node_modules/punycode": { "version": "2.3.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "engines": { "node": ">=6" } }, + "node_modules/pure-rand": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", + "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -3683,6 +7961,8 @@ }, "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==", "funding": [ { "type": "github", @@ -3696,12 +7976,12 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/queue-tick": { "version": "1.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" }, "node_modules/quick-format-unescaped": { "version": "4.0.4", @@ -3710,7 +7990,8 @@ }, "node_modules/random-access-file": { "version": "2.2.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/random-access-file/-/random-access-file-2.2.1.tgz", + "integrity": "sha512-RGU0xmDqdOyEiynob1KYSeh8+9c9Td1MJ74GT1viMEYAn8SJ9oBtWCXLsYZukCF46yududHOdM449uRYbzBrZQ==", "dependencies": { "mkdirp-classic": "^0.5.2", "random-access-storage": "^1.1.1" @@ -3718,7 +7999,8 @@ }, "node_modules/random-access-storage": { "version": "1.4.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/random-access-storage/-/random-access-storage-1.4.3.tgz", + "integrity": "sha512-D5e2iIC5dNENWyBxsjhEnNOMCwZZ64TARK6dyMN+3g4OTC4MJxyjh9hKLjTGoNhDOPrgjI+YlFEHFnrp/cSnzQ==", "dependencies": { "events": "^3.3.0", "inherits": "^2.0.3", @@ -3727,40 +8009,32 @@ }, "node_modules/random-iterate": { "version": "1.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/random-iterate/-/random-iterate-1.0.1.tgz", + "integrity": "sha512-Jdsdnezu913Ot8qgKgSgs63XkAjEsnMcS1z+cC6D6TNXsUXsMxy0RpclF2pzGZTEiTXL9BiArdGTEexcv4nqcA==" }, "node_modules/randombytes": { "version": "2.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dependencies": { "safe-buffer": "^5.1.0" } }, - "node_modules/randombytes/node_modules/safe-buffer": { - "version": "5.2.1", - "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/re-emitter": { "version": "1.1.4", - "license": "MIT" + "resolved": "https://registry.npmjs.org/re-emitter/-/re-emitter-1.1.4.tgz", + "integrity": "sha512-C0SIXdXDSus2yqqvV7qifnb4NoWP7mEBXJq3axci301mXHCZb8Djwm4hrEZo4UeXRaEnfjH98uQ8EBppk2oNWA==" + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true }, "node_modules/readable-stream": { "version": "1.1.14", - "license": "MIT", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -3768,6 +8042,18 @@ "string_decoder": "~0.10.x" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/real-require": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", @@ -3776,10 +8062,16 @@ "node": ">= 12.13.0" } }, + "node_modules/reflect-metadata": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", + "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==" + }, "node_modules/regexp.prototype.flags": { "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -3792,14 +8084,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/requires-port": { "version": "1.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "node_modules/resolve": { "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, - "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -3812,10 +8115,32 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/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, + "engines": { + "node": ">=8" + } + }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } @@ -3829,31 +8154,71 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/retry-as-promised": { "version": "7.0.4", - "license": "MIT" + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-7.0.4.tgz", + "integrity": "sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA==" }, "node_modules/reusify": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rimraf": { - "version": "2.7.1", - "license": "ISC", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" } }, "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==", "funding": [ { "type": "github", @@ -3868,13 +8233,14 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/run-series": { "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.9.tgz", + "integrity": "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==", "funding": [ { "type": "github", @@ -3888,17 +8254,27 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/rusha": { "version": "0.8.14", - "license": "MIT" + "resolved": "https://registry.npmjs.org/rusha/-/rusha-0.8.14.tgz", + "integrity": "sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA==" + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } }, "node_modules/safe-array-concat": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", + "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "get-intrinsic": "^1.2.2", @@ -3914,20 +8290,23 @@ }, "node_modules/safe-array-concat/node_modules/isarray": { "version": "2.0.5", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true }, "node_modules/safe-buffer": { "version": "5.1.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/safe-regex-test": { - "version": "1.0.2", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "get-intrinsic": "^1.2.2", + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", "is-regex": "^1.1.4" }, "engines": { @@ -3947,7 +8326,8 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/secure-json-parse": { "version": "2.7.0", @@ -3956,22 +8336,40 @@ "dev": true }, "node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, "node_modules/sequelize": { "version": "6.36.0", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.36.0.tgz", + "integrity": "sha512-PqOa11EHwA/zLmGDU4aynbsavbHJUlgRvFuC/2cA4LhOuV6NHKcQ0IXB+hNdFrGT3rULmvc4kdIwnfCNsrECMQ==", "funding": [ { "type": "opencollective", "url": "https://opencollective.com/sequelize" } ], - "license": "MIT", "dependencies": { "@types/debug": "^4.1.8", "@types/validator": "^13.7.17", @@ -4025,42 +8423,78 @@ }, "node_modules/sequelize-pool": { "version": "7.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", + "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==", "engines": { "node": ">= 10.0.0" } }, - "node_modules/sequelize/node_modules/semver": { - "version": "7.5.4", - "license": "ISC", + "node_modules/sequelize-typescript": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/sequelize-typescript/-/sequelize-typescript-2.1.6.tgz", + "integrity": "sha512-Vc2N++3en346RsbGjL3h7tgAl2Y7V+2liYTAOZ8XL0KTw3ahFHsyAUzOwct51n+g70I1TOUDgs06Oh6+XGcFkQ==", "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "glob": "7.2.0" }, "engines": { - "node": ">=10" + "node": ">=10.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "@types/validator": "*", + "reflect-metadata": "*", + "sequelize": ">=6.20.1" } }, - "node_modules/sequelize/node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "license": "ISC", + "node_modules/sequelize-typescript/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==", "dependencies": { - "yallist": "^4.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/sequelize-typescript/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">=10" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sequelize-typescript/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, "node_modules/set-function-length": { - "version": "1.2.0", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", "dev": true, - "license": "MIT", "dependencies": { - "define-data-property": "^1.1.1", + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", + "get-intrinsic": "^1.2.3", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.1" }, @@ -4070,8 +8504,9 @@ }, "node_modules/set-function-name": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", "dev": true, - "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "functions-have-names": "^1.2.3", @@ -4083,8 +8518,9 @@ }, "node_modules/shebang-command": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -4094,27 +8530,41 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/side-channel": { - "version": "1.0.4", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", + "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "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 + }, "node_modules/simple-concat": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", "funding": [ { "type": "github", @@ -4128,28 +8578,22 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/simple-get": { "version": "2.8.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", + "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", "dependencies": { "decompress-response": "^3.3.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, - "node_modules/simple-get/node_modules/once": { - "version": "1.4.0", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/simple-peer": { "version": "6.4.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/simple-peer/-/simple-peer-6.4.4.tgz", + "integrity": "sha512-sY35UHankz0ba02Dd8YzdyXhEeTAnW6ZUyDfKOSwUht1GLp9VuMT4jQUXF/wG7C9vpwvitV7Ig7a6IkY/qizwg==", "dependencies": { "debug": "^2.1.0", "get-browser-rtc": "^1.0.0", @@ -4160,18 +8604,26 @@ }, "node_modules/simple-peer/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, - "node_modules/simple-peer/node_modules/debug/node_modules/ms": { + "node_modules/simple-peer/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/simple-peer/node_modules/ms": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/simple-peer/node_modules/readable-stream": { "version": "2.3.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -4182,27 +8634,26 @@ "util-deprecate": "~1.0.1" } }, - "node_modules/simple-peer/node_modules/readable-stream/node_modules/isarray": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/simple-peer/node_modules/readable-stream/node_modules/string_decoder": { + "node_modules/simple-peer/node_modules/string_decoder": { "version": "1.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/simple-sha1": { "version": "2.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/simple-sha1/-/simple-sha1-2.1.2.tgz", + "integrity": "sha512-TQl9rm4rdKAVmhO++sXAb8TNN0D6JAD5iyI1mqEPNpxUzTRrtm4aOG1pDf/5W/qCFihiaoK6uuL9rvQz1x1VKw==", "dependencies": { "rusha": "^0.8.1" } }, "node_modules/simple-websocket": { "version": "4.3.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/simple-websocket/-/simple-websocket-4.3.1.tgz", + "integrity": "sha512-knEO6ub2Pw00c7ueOV6snKE1hr7jIdY068+239v0I8DVKofyd7IQmYHXrM9pZL1zuI0H7sd+Y5kedndBi5GXIA==", "dependencies": { "debug": "^2.1.3", "inherits": "^2.0.1", @@ -4214,18 +8665,26 @@ }, "node_modules/simple-websocket/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, - "node_modules/simple-websocket/node_modules/debug/node_modules/ms": { + "node_modules/simple-websocket/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/simple-websocket/node_modules/ms": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/simple-websocket/node_modules/readable-stream": { "version": "2.3.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -4236,20 +8695,23 @@ "util-deprecate": "~1.0.1" } }, - "node_modules/simple-websocket/node_modules/readable-stream/node_modules/isarray": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/simple-websocket/node_modules/readable-stream/node_modules/string_decoder": { + "node_modules/simple-websocket/node_modules/string_decoder": { "version": "1.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dependencies": { "safe-buffer": "~5.1.0" } }, + "node_modules/simple-websocket/node_modules/ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" + }, "node_modules/simple-websocket/node_modules/ws": { "version": "2.3.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ws/-/ws-2.3.1.tgz", + "integrity": "sha512-61a+9LgtYZxTq1hAonhX8Xwpo2riK4IOR/BIVxioFbCfc3QFKmpE4x9dLExfLHKtUfVZigYa36tThVhO57erEw==", "dependencies": { "safe-buffer": "~5.0.1", "ultron": "~1.1.0" @@ -4257,11 +8719,49 @@ }, "node_modules/simple-websocket/node_modules/ws/node_modules/safe-buffer": { "version": "5.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", + "integrity": "sha512-cr7dZWLwOeaFBLTIuZeYdkfO7UzGIKhjYENJFAxUOMKWGaWDm2nJM2rzxNRm5Owu0DH3ApwNo6kx5idXZfb/Iw==" }, - "node_modules/simple-websocket/node_modules/ws/node_modules/ultron": { - "version": "1.1.1", - "license": "MIT" + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "optional": true, + "peer": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "optional": true, + "peer": true, + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } }, "node_modules/sonic-boom": { "version": "3.8.0", @@ -4271,31 +8771,125 @@ "atomic-sleep": "^1.0.0" } }, + "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, + "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, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/sparse-bitfield": { "version": "3.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", "dependencies": { "memory-pager": "^1.0.2" } }, "node_modules/speedometer": { - "version": "0.1.4" + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-0.1.4.tgz", + "integrity": "sha512-phdEoDlA6EUIVtzwq1UiNMXDUogczp204aYF/yfOhjNePWFfIpBJ1k5wLMuXQhEOOMjuTJEcc4vdZa+vuP+n/Q==" }, "node_modules/split2": { "version": "4.2.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "engines": { "node": ">= 10.x" } }, + "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 + }, + "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, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/strict-event-emitter": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", + "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", + "dev": true + }, "node_modules/string_decoder": { "version": "0.10.31", - "license": "MIT" + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "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, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } }, "node_modules/string.prototype.trim": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -4310,8 +8904,9 @@ }, "node_modules/string.prototype.trimend": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -4323,8 +8918,9 @@ }, "node_modules/string.prototype.trimstart": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -4336,7 +8932,8 @@ }, "node_modules/string2compact": { "version": "1.3.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/string2compact/-/string2compact-1.3.2.tgz", + "integrity": "sha512-3XUxUgwhj7Eqh2djae35QHZZT4mN3fsO7kagZhSGmhhlrQagVvWSFuuFIWnpxFS0CdTB2PlQcaL16RDi14I8uw==", "dependencies": { "addr-to-ip-port": "^1.0.1", "ipaddr.js": "^2.0.0" @@ -4344,8 +8941,9 @@ }, "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" }, @@ -4354,17 +8952,28 @@ } }, "node_modules/strip-bom": { - "version": "3.0.0", + "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": ">=4" + "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, + "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", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -4374,8 +8983,9 @@ }, "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" }, @@ -4385,8 +8995,9 @@ }, "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, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4394,13 +9005,52 @@ "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, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/text-table": { "version": "0.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true }, "node_modules/thirty-two": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/thirty-two/-/thirty-two-1.0.2.tgz", + "integrity": "sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA==", "engines": { "node": ">=0.2.6" } @@ -4413,17 +9063,65 @@ "real-require": "^0.2.0" } }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, "node_modules/thunky": { "version": "1.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.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==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } }, "node_modules/toposort-class": { "version": "1.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", + "integrity": "sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==" }, "node_modules/torrent-discovery": { "version": "5.4.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/torrent-discovery/-/torrent-discovery-5.4.0.tgz", + "integrity": "sha512-bPTDIA7XEjRlw6vQyt7kM/h1mg1INBsibjbujISITonx4POENZgxfyCSEXZpDhbAkluSPH4HKRKs4/YTmNLC6w==", "dependencies": { "bittorrent-dht": "^6.0.0", "bittorrent-tracker": "^7.0.0", @@ -4436,21 +9134,26 @@ }, "node_modules/torrent-discovery/node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, - "node_modules/torrent-discovery/node_modules/debug/node_modules/ms": { + "node_modules/torrent-discovery/node_modules/ms": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/torrent-piece": { "version": "1.1.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/torrent-piece/-/torrent-piece-1.1.2.tgz", + "integrity": "sha512-ElXPyXKKG73o+uziHJ8qlYE9EuyDVxnK2zWL+pW/2bma7RsLpSwFFIJAb8Qui7/tel2hsHQW1z3zBnfQNREpWA==" }, "node_modules/torrent-stream": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/torrent-stream/-/torrent-stream-1.2.1.tgz", + "integrity": "sha512-F+3tYmXnpO2gyhZQ7o8yakELJH3FtKISI/FU0iWvchOWFUXiFnjbEBoumSzfcK1P71Qxzx2az4lVK4Dkq4KSew==", "dependencies": { "bitfield": "^0.1.0", "bncode": "^0.5.2", @@ -4468,20 +9171,175 @@ "torrent-piece": "^1.0.0" } }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "dev": true, - "license": "MIT", + "node_modules/torrent-stream/node_modules/end-of-stream": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", + "integrity": "sha512-go5TQkd0YRXYhX+Lc3UrXkoKU5j+m72jEP5lHWr2Nh82L8wfZtH8toKgcg4T10o23ELIMGXQdwCbl+qAXIPDrw==", "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", + "once": "~1.3.0" + } + }, + "node_modules/torrent-stream/node_modules/mkdirp": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha512-8OCq0De/h9ZxseqzCH8Kw/Filf5pF/vMI6+BH7Lu0jXz2pqYCjTAQRolSxRIi+Ax+oCCjlxoJMP0YQ4XlrQNHg==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)" + }, + "node_modules/torrent-stream/node_modules/once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha512-6vaNInhu+CHxtONf3zw3vq4SP2DOQhjBvIa3rNcG0+P7eKWlYH6Peu7rHizSloRU2EwMz6GraLieis9Ac9+p1w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/torrent-stream/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/ts-api-utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", + "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-jest": { + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz", + "integrity": "sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "dependencies": { + "json5": "^2.2.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" } }, "node_modules/tslib": { "version": "2.6.2", - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/tsx": { "version": "4.7.0", @@ -4910,8 +9768,9 @@ }, "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" }, @@ -4919,10 +9778,20 @@ "node": ">= 0.8.0" } }, + "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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/type-fest": { "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": { "node": ">=10" }, @@ -4931,13 +9800,14 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.0", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.1.tgz", + "integrity": "sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -4945,8 +9815,9 @@ }, "node_modules/typed-array-byte-length": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -4962,8 +9833,9 @@ }, "node_modules/typed-array-byte-offset": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", "dev": true, - "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -4980,8 +9852,9 @@ }, "node_modules/typed-array-length": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -4991,14 +9864,29 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/ultron": { "version": "1.0.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", + "integrity": "sha512-QMpnpVtYaWEeY+MwKDN/UdKlE/LsFZXM5lO1u7GaZzNgmIbGixHEmVMIKT+vqYOALu3m5GYQy9kz4Xu4IVn7Ow==" }, "node_modules/unbox-primitive": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -5011,16 +9899,54 @@ }, "node_modules/underscore": { "version": "1.13.6", - "license": "MIT" + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/uniq": { "version": "1.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==" + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "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" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } }, "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, - "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -5034,41 +9960,98 @@ "requires-port": "^1.0.0" } }, - "node_modules/user-agents": { - "version": "1.1.104", - "license": "BSD-2-Clause", - "dependencies": { - "lodash.clonedeep": "^4.5.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/utp": { "version": "0.0.7", + "resolved": "https://registry.npmjs.org/utp/-/utp-0.0.7.tgz", + "integrity": "sha512-2ZLjisH0HQkpqZTg2m7TK0Yn7TETTg7DxM0EpCKIIIV2ky9w9nSxW5a7gzdk4nH2h+pomrrGw0uywrUJfsm2eA==", "dependencies": { "cyclist": "~0.1.0" } }, "node_modules/uuid": { "version": "8.3.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "bin": { "uuid": "dist/bin/uuid" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "dev": true, + "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/validator": { "version": "13.11.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", "engines": { "node": ">= 0.10" } }, + "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, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "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==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -5081,8 +10064,9 @@ }, "node_modules/which-boxed-primitive": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, - "license": "MIT", "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -5096,8 +10080,9 @@ }, "node_modules/which-typed-array": { "version": "1.1.14", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", + "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", "dev": true, - "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.6", "call-bind": "^1.0.5", @@ -5114,18 +10099,48 @@ }, "node_modules/wkx": { "version": "0.5.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", + "integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==", "dependencies": { "@types/node": "*" } }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrappy": { "version": "1.0.2", - "license": "ISC" + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "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, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } }, "node_modules/ws": { "version": "1.1.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", + "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", "dependencies": { "options": ">=0.0.5", "ultron": "1.0.x" @@ -5133,19 +10148,67 @@ }, "node_modules/xtend": { "version": "4.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "engines": { "node": ">=0.4" } }, + "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, + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "4.0.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "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, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "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, + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } }, "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", "engines": { "node": ">=10" }, diff --git a/src/node/consumer/package.json b/src/node/consumer/package.json index 9678cfc..d144b5e 100644 --- a/src/node/consumer/package.json +++ b/src/node/consumer/package.json @@ -3,10 +3,14 @@ "version": "0.0.1", "type": "module", "scripts": { - "build": "node esbuild.js", - "dev": "tsx watch --ignore node_modules src/index.js | pino-pretty", - "start": "node dist/index.cjs", - "lint": "eslint . --ext .ts,.js" + "clean": "rm -rf dist", + "build": "tsx esbuild.ts", + "dev": "tsx watch --ignore node_modules src/main.ts | pino-pretty", + "start": "node dist/main.cjs", + "lint": "eslint ./src --ext .ts,.js", + "lint-fix": "npm run lint -- --fix", + "test": "jest", + "test:watch": "jest --watch" }, "license": "MIT", "dependencies": { @@ -16,7 +20,7 @@ "bottleneck": "^2.19.5", "cache-manager": "^5.4.0", "google-sr": "^3.2.1", - "jaro-winkler": "^0.2.8", + "inversify": "^6.0.2", "magnet-uri": "^6.2.0", "moment": "^2.30.1", "name-to-imdb": "^3.0.4", @@ -24,18 +28,32 @@ "pg": "^8.11.3", "pg-hstore": "^2.3.4", "pino": "^8.18.0", - "sequelize": "^6.31.1", - "torrent-stream": "^1.2.1", - "user-agents": "^1.0.1444" + "reflect-metadata": "^0.2.1", + "sequelize": "^6.36.0", + "sequelize-typescript": "^2.1.6", + "torrent-stream": "^1.2.1" }, "devDependencies": { - "@types/node": "^20.11.6", - "@types/stremio-addon-sdk": "^1.6.10", + "@types/amqplib": "^0.10.4", + "@types/jest": "^29.5.12", + "@types/magnet-uri": "^5.1.5", + "@types/node": "^20.11.16", + "@types/pg": "^8.11.0", + "@types/torrent-stream": "^0.0.9", + "@types/validator": "^13.11.8", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", "esbuild": "^0.20.0", "eslint": "^8.56.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-import-helpers": "^1.3.1", + "jest": "^29.7.0", + "msw": "^2.1.7", + "pino-pretty": "^10.3.1", + "ts-jest": "^29.1.2", + "ts-node": "^10.9.2", + "tsconfig-paths": "^4.2.0", "tsx": "^4.7.0", - "pino-pretty": "^10.3.1" + "typescript": "^5.3.3" } } diff --git a/src/node/consumer/src/index.js b/src/node/consumer/src/index.js deleted file mode 100644 index ac1dd83..0000000 --- a/src/node/consumer/src/index.js +++ /dev/null @@ -1,9 +0,0 @@ -import { listenToQueue } from './jobs/processTorrents.js'; -import { connect } from './lib/repository.js'; -import { getTrackers } from "./lib/trackerService.js"; - -(async () => { - await getTrackers(); - await connect(); - await listenToQueue(); -})(); \ No newline at end of file diff --git a/src/node/consumer/src/jobs/processTorrents.js b/src/node/consumer/src/jobs/processTorrents.js deleted file mode 100644 index 23d9701..0000000 --- a/src/node/consumer/src/jobs/processTorrents.js +++ /dev/null @@ -1,37 +0,0 @@ -import amqp from 'amqplib' -import { rabbitConfig, jobConfig } from '../lib/config.js' -import { processTorrentRecord } from "../lib/ingestedTorrent.js"; -import {logger} from "../lib/logger.js"; - -const assertQueueOptions = { durable: true } -const consumeQueueOptions = { noAck: false } - -const processMessage = msg => processTorrentRecord(getMessageAsJson(msg)); - -const getMessageAsJson = msg => - JSON.parse(msg.content.toString()).message; - -const assertAndConsumeQueue = async channel => { - logger.info('Worker is running! Waiting for new torrents...') - - const ackMsg = msg => - processMessage(msg) - .then(() => channel.ack(msg)) - .catch(error => logger.error('Failed processing torrent', error)); - - channel.assertQueue(rabbitConfig.QUEUE_NAME, assertQueueOptions) - .then(() => channel.prefetch(jobConfig.JOB_CONCURRENCY)) - .then(() => channel.consume(rabbitConfig.QUEUE_NAME, ackMsg, consumeQueueOptions)) - .catch(error => logger.error('Failed to setup channel', error)); -} - -export const listenToQueue = async () => { - if (!jobConfig.JOBS_ENABLED) { - return; - } - - return amqp.connect(rabbitConfig.URI) - .then(connection => connection.createChannel()) - .then(channel => assertAndConsumeQueue(channel)) - .catch(error => logger.error('Failed to connect and setup channel', error)); - }; \ No newline at end of file diff --git a/src/node/consumer/src/lib/cache.js b/src/node/consumer/src/lib/cache.js deleted file mode 100644 index 7b9be26..0000000 --- a/src/node/consumer/src/lib/cache.js +++ /dev/null @@ -1,84 +0,0 @@ -import { createCache, memoryStore} from 'cache-manager'; -import { mongoDbStore } from '@tirke/node-cache-manager-mongodb' -import { cacheConfig } from './config.js'; -import { logger } from './logger.js'; -import { CacheType } from "./types.js"; - -const GLOBAL_KEY_PREFIX = 'knightcrawler-consumer'; -const IMDB_ID_PREFIX = `${GLOBAL_KEY_PREFIX}|imdb_id`; -const KITSU_ID_PREFIX = `${GLOBAL_KEY_PREFIX}|kitsu_id`; -const METADATA_PREFIX = `${GLOBAL_KEY_PREFIX}|metadata`; -const TRACKERS_KEY_PREFIX = `${GLOBAL_KEY_PREFIX}|trackers`; - -const GLOBAL_TTL = process.env.METADATA_TTL || 7 * 24 * 60 * 60; // 7 days -const MEMORY_TTL = process.env.METADATA_TTL || 2 * 60 * 60; // 2 hours -const TRACKERS_TTL = 2 * 24 * 60 * 60; // 2 days - -const initiateMemoryCache = () => - createCache(memoryStore(), { - ttl: parseInt(MEMORY_TTL) - }); - -const initiateMongoCache = () => { - const store = mongoDbStore({ - collectionName: cacheConfig.COLLECTION_NAME, - ttl: parseInt(GLOBAL_TTL), - url: cacheConfig.MONGO_URI, - mongoConfig:{ - socketTimeoutMS: 120000, - appName: 'knightcrawler-consumer', - } - }); - - return createCache(store, { - ttl: parseInt(GLOBAL_TTL), - }); -} - -const initiateRemoteCache = ()=> { - if (cacheConfig.NO_CACHE) { - logger.debug('Cache is disabled'); - return null; - } - return cacheConfig.MONGO_URI ? initiateMongoCache() : initiateMemoryCache(); -} - -const getCacheType = (cacheType) => { - switch (cacheType) { - case CacheType.MEMORY: - return memoryCache; - case CacheType.MONGODB: - return remoteCache; - default: - return null; - } -} - -const memoryCache = initiateMemoryCache() -const remoteCache = initiateRemoteCache() - -const cacheWrap = async (cacheType, key, method, options) => { - const cache = getCacheType(cacheType); - - if (cacheConfig.NO_CACHE || !cache) { - return method(); - } - - logger.debug(`Cache type: ${cacheType}`); - logger.debug(`Cache key: ${key}`); - logger.debug(`Cache options: ${JSON.stringify(options)}`); - - return cache.wrap(key, method, options.ttl); -} - -export const cacheWrapImdbId = (key, method) => - cacheWrap(CacheType.MONGODB, `${IMDB_ID_PREFIX}:${key}`, method, { ttl: parseInt(GLOBAL_TTL) }); - -export const cacheWrapKitsuId = (key, method) => - cacheWrap(CacheType.MONGODB, `${KITSU_ID_PREFIX}:${key}`, method, { ttl: parseInt(GLOBAL_TTL) }); - -export const cacheWrapMetadata = (id, method) => - cacheWrap(CacheType.MEMORY, `${METADATA_PREFIX}:${id}`, method, { ttl: parseInt(MEMORY_TTL) }); - -export const cacheTrackers = (method) => - cacheWrap(CacheType.MEMORY, `${TRACKERS_KEY_PREFIX}`, method, { ttl: parseInt(TRACKERS_TTL) }); \ No newline at end of file diff --git a/src/node/consumer/src/lib/config.js b/src/node/consumer/src/lib/config.js deleted file mode 100644 index a63f093..0000000 --- a/src/node/consumer/src/lib/config.js +++ /dev/null @@ -1,63 +0,0 @@ -export const rabbitConfig = { - URI: process.env.RABBIT_URI || 'amqp://localhost', - QUEUE_NAME: process.env.QUEUE_NAME || 'test-queue' -} - -export const cacheConfig = { - MONGODB_HOST: process.env.MONGODB_HOST || 'mongodb', - MONGODB_PORT: process.env.MONGODB_PORT || '27017', - MONGODB_DB: process.env.MONGODB_DB || 'knightcrawler', - MONGO_INITDB_ROOT_USERNAME: process.env.MONGO_INITDB_ROOT_USERNAME || 'mongo', - MONGO_INITDB_ROOT_PASSWORD: process.env.MONGO_INITDB_ROOT_PASSWORD || 'mongo', - NO_CACHE: parseBool(process.env.NO_CACHE, false), - COLLECTION_NAME: process.env.MONGODB_COLLECTION || 'knightcrawler_consumer_collection' -} - -// Combine the environment variables into a connection string -// The combined string will look something like: -// 'mongodb://mongo:mongo@localhost:27017/knightcrawler?authSource=admin' -cacheConfig.MONGO_URI = 'mongodb://' + cacheConfig.MONGO_INITDB_ROOT_USERNAME + ':' + cacheConfig.MONGO_INITDB_ROOT_PASSWORD + '@' + cacheConfig.MONGODB_HOST + ':' + cacheConfig.MONGODB_PORT + '/' + cacheConfig.MONGODB_DB + '?authSource=admin'; - -export const databaseConfig = { - POSTGRES_HOST: process.env.POSTGRES_HOST || 'postgres', - POSTGRES_PORT: process.env.POSTGRES_PORT || '5432', - POSTGRES_DB: process.env.POSTGRES_DB || 'knightcrawler', - POSTGRES_USER: process.env.POSTGRES_USER || 'postgres', - POSTGRES_PASSWORD: process.env.POSTGRES_PASSWORD || 'postgres', - AUTO_CREATE_AND_APPLY_MIGRATIONS: parseBool(process.env.AUTO_CREATE_AND_APPLY_MIGRATIONS, false) -} - -// Combine the environment variables into a connection string -// The combined string will look something like: -// 'postgres://postgres:postgres@localhost:5432/knightcrawler' -databaseConfig.POSTGRES_URI = 'postgres://' + databaseConfig.POSTGRES_USER + ':' + databaseConfig.POSTGRES_PASSWORD + '@' + databaseConfig.POSTGRES_HOST + ':' + databaseConfig.POSTGRES_PORT + '/' + databaseConfig.POSTGRES_DB; - -export const jobConfig = { - JOB_CONCURRENCY: parseInt(process.env.JOB_CONCURRENCY || 1), - JOBS_ENABLED: parseBool(process.env.JOBS_ENABLED || true) -} - -export const metadataConfig = { - IMDB_CONCURRENT: parseInt(process.env.IMDB_CONCURRENT || 1), - IMDB_INTERVAL_MS: parseInt(process.env.IMDB_INTERVAL_MS || 1000), -} - -export const trackerConfig = { - TRACKERS_URL: process.env.TRACKERS_URL || 'https://ngosang.github.io/trackerslist/trackers_all.txt', - UDP_ENABLED: parseBool(process.env.UDP_TRACKERS_ENABLED || false), -} - -export const torrentConfig = { - MAX_CONNECTIONS_PER_TORRENT: parseInt(process.env.MAX_SINGLE_TORRENT_CONNECTIONS || 20), - TIMEOUT: parseInt(process.env.TORRENT_TIMEOUT || 30000), -} - -function parseBool(boolString, defaultValue) { - const isString = typeof boolString === 'string' || boolString instanceof String; - - if (!isString) { - return defaultValue; - } - - return boolString.toLowerCase() === 'true' ? true : defaultValue; -} \ No newline at end of file diff --git a/src/node/consumer/src/lib/enums/cache_types.ts b/src/node/consumer/src/lib/enums/cache_types.ts new file mode 100644 index 0000000..d1cf197 --- /dev/null +++ b/src/node/consumer/src/lib/enums/cache_types.ts @@ -0,0 +1,4 @@ +export enum CacheType { + Memory = 'memory', + MongoDb = 'mongodb' +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/enums/torrent_types.ts b/src/node/consumer/src/lib/enums/torrent_types.ts new file mode 100644 index 0000000..47743c6 --- /dev/null +++ b/src/node/consumer/src/lib/enums/torrent_types.ts @@ -0,0 +1,5 @@ +export enum TorrentType { + Series = 'Series', + Movie = 'Movie', + Anime = 'anime', +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/extension.js b/src/node/consumer/src/lib/extension.js deleted file mode 100644 index 6c11617..0000000 --- a/src/node/consumer/src/lib/extension.js +++ /dev/null @@ -1,62 +0,0 @@ -const VIDEO_EXTENSIONS = [ - "3g2", - "3gp", - "avi", - "flv", - "mkv", - "mk3d", - "mov", - "mp2", - "mp4", - "m4v", - "mpe", - "mpeg", - "mpg", - "mpv", - "webm", - "wmv", - "ogm", - "divx" -]; -const SUBTITLE_EXTENSIONS = [ - "aqt", - "gsub", - "jss", - "sub", - "ttxt", - "pjs", - "psb", - "rt", - "smi", - "slt", - "ssf", - "srt", - "ssa", - "ass", - "usf", - "idx", - "vtt" -]; -const DISK_EXTENSIONS = [ - "iso", - "m2ts", - "ts", - "vob" -] - -export function isVideo(filename) { - return isExtension(filename, VIDEO_EXTENSIONS); -} - -export function isSubtitle(filename) { - return isExtension(filename, SUBTITLE_EXTENSIONS); -} - -export function isDisk(filename) { - return isExtension(filename, DISK_EXTENSIONS); -} - -export function isExtension(filename, extensions) { - const extensionMatch = filename.match(/\.(\w{2,4})$/); - return extensionMatch && extensions.includes(extensionMatch[1].toLowerCase()); -} \ No newline at end of file diff --git a/src/node/consumer/src/lib/helpers/boolean_helpers.ts b/src/node/consumer/src/lib/helpers/boolean_helpers.ts new file mode 100644 index 0000000..93819f6 --- /dev/null +++ b/src/node/consumer/src/lib/helpers/boolean_helpers.ts @@ -0,0 +1,18 @@ +export const BooleanHelpers = { + parseBool: (value: string | undefined, defaultValue: boolean): boolean => { + switch (value?.trim().toLowerCase()) { + case undefined: + return defaultValue; + case 'true': + case 'yes': + case '1': + return true; + case 'false': + case 'no': + case '0': + return false; + default: + throw new Error(`Invalid boolean value: '${value}'. Allowed values are 'true', 'false', 'yes', 'no', '1', or '0'.`); + } + } +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/helpers/extension_helpers.ts b/src/node/consumer/src/lib/helpers/extension_helpers.ts new file mode 100644 index 0000000..f24b237 --- /dev/null +++ b/src/node/consumer/src/lib/helpers/extension_helpers.ts @@ -0,0 +1,66 @@ +const VIDEO_EXTENSIONS = [ + "3g2", + "3gp", + "avi", + "flv", + "mkv", + "mk3d", + "mov", + "mp2", + "mp4", + "m4v", + "mpe", + "mpeg", + "mpg", + "mpv", + "webm", + "wmv", + "ogm", + "divx" +]; + +const SUBTITLE_EXTENSIONS = [ + "aqt", + "gsub", + "jss", + "sub", + "ttxt", + "pjs", + "psb", + "rt", + "smi", + "slt", + "ssf", + "srt", + "ssa", + "ass", + "usf", + "idx", + "vtt" +]; + +const DISK_EXTENSIONS = [ + "iso", + "m2ts", + "ts", + "vob" +]; + +export const ExtensionHelpers = { + isVideo(filename: string): boolean { + return this.isExtension(filename, VIDEO_EXTENSIONS); + }, + + isSubtitle(filename: string): boolean { + return this.isExtension(filename, SUBTITLE_EXTENSIONS); + }, + + isDisk(filename: string): boolean { + return this.isExtension(filename, DISK_EXTENSIONS); + }, + + isExtension(filename: string, extensions: string[]): boolean { + const extensionMatch = filename.match(/\.(\w{2,4})$/); + return extensionMatch !== null && extensions.includes(extensionMatch[1].toLowerCase()); + } +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/helpers/promises_helpers.ts b/src/node/consumer/src/lib/helpers/promises_helpers.ts new file mode 100644 index 0000000..af38d2d --- /dev/null +++ b/src/node/consumer/src/lib/helpers/promises_helpers.ts @@ -0,0 +1,37 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +export const PromiseHelpers = { + + sequence: async function (promises: (() => Promise)[]): Promise { + return promises.reduce((promise, func) => + promise.then(result => func().then(res => result.concat(res))), Promise.resolve([])); + }, + + first: async function (promises: any): Promise { + return Promise.all(promises.map((p: any) => { + return p.then((val: any) => Promise.reject(val), (err: any) => Promise.resolve(err)); + })).then( + (errors) => Promise.reject(errors), + (val) => Promise.resolve(val) + ); + }, + + delay: async function (duration: number): Promise { + return new Promise(resolve => setTimeout(() => resolve(), duration)); + }, + + timeout: async function (timeoutMs: number, promise: any, message = 'Timed out'): Promise { + return Promise.race([ + promise, + new Promise(function (resolve, reject) { + setTimeout(function () { + reject(message); + }, timeoutMs); + }) + ]); + }, + + mostCommonValue: function (array: any[]): any { + return array.sort((a, b) => array.filter(v => v === a).length - array.filter(v => v === b).length).pop(); + } +}; +/* eslint-enable @typescript-eslint/no-explicit-any */ \ No newline at end of file diff --git a/src/node/consumer/src/lib/ingestedTorrent.js b/src/node/consumer/src/lib/ingestedTorrent.js deleted file mode 100644 index 4948173..0000000 --- a/src/node/consumer/src/lib/ingestedTorrent.js +++ /dev/null @@ -1,46 +0,0 @@ -import { createTorrentEntry, checkAndUpdateTorrent } from './torrentEntries.js'; -import {getTrackers} from "./trackerService.js"; -import { TorrentType } from './types.js'; -import {logger} from "./logger.js"; - -export async function processTorrentRecord(torrent) { - const {category} = torrent; - const type = category === 'tv' ? TorrentType.SERIES : TorrentType.MOVIE; - const torrentInfo = await parseTorrent(torrent, type); - logger.info(`Processing torrent ${torrentInfo.title} with infoHash ${torrentInfo.infoHash}`) - - if (await checkAndUpdateTorrent(torrentInfo)) { - return torrentInfo; - } - - return createTorrentEntry(torrentInfo); -} - -async function assignTorrentTrackers() { - const trackers = await getTrackers(); - return trackers.join(','); -} - -async function parseTorrent(torrent, category) { - const infoHash = torrent.infoHash?.trim().toLowerCase() - return { - title: torrent.name, - torrentId: `${torrent.name}_${infoHash}`, - infoHash: infoHash, - seeders: 100, - size: torrent.size, - uploadDate: torrent.createdAt, - imdbId: parseImdbId(torrent), - type: category, - provider: torrent.source, - trackers: await assignTorrentTrackers(), - } -} - -function parseImdbId(torrent) { - if (torrent.imdb === undefined || torrent.imdb === null) { - return undefined; - } - - return torrent.imdb; -} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/cache_options.ts b/src/node/consumer/src/lib/interfaces/cache_options.ts new file mode 100644 index 0000000..8613c41 --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/cache_options.ts @@ -0,0 +1,3 @@ +export interface ICacheOptions { + ttl: number; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/cache_service.ts b/src/node/consumer/src/lib/interfaces/cache_service.ts new file mode 100644 index 0000000..962de97 --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/cache_service.ts @@ -0,0 +1,11 @@ +import {CacheMethod} from "@services/cache_service"; + +/* eslint-disable @typescript-eslint/no-explicit-any */ +export interface ICacheService { + cacheWrapImdbId: (key: string, method: CacheMethod) => Promise; + cacheWrapKitsuId: (key: string, method: CacheMethod) => Promise; + cacheWrapMetadata: (id: string, method: CacheMethod) => Promise; + cacheTrackers: (method: CacheMethod) => Promise; +} + +/* eslint-enable @typescript-eslint/no-explicit-any */ \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/cinemeta_metadata.ts b/src/node/consumer/src/lib/interfaces/cinemeta_metadata.ts new file mode 100644 index 0000000..cb3a427 --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/cinemeta_metadata.ts @@ -0,0 +1,84 @@ +import {ICommonVideoMetadata} from "@interfaces/common_video_metadata"; + +export interface ICinemetaJsonResponse { + meta?: ICinemetaMetaData; + trailerStreams?: ICinemetaTrailerStream[]; + links?: ICinemetaLink[]; + behaviorHints?: ICinemetaBehaviorHints; +} + +export interface ICinemetaMetaData { + awards?: string; + cast?: string[]; + country?: string; + description?: string; + director?: null; + dvdRelease?: null; + genre?: string[]; + imdbRating?: string; + name?: string; + popularity?: number; + poster?: string; + released?: string; + runtime?: string; + status?: string; + tvdb_id?: number; + type?: string; + writer?: string[]; + year?: string; + background?: string; + logo?: string; + popularities?: ICinemetaPopularities; + moviedb_id?: number; + slug?: string; + trailers?: ICinemetaTrailer[]; + id?: string; + genres?: string[]; + releaseInfo?: string; + videos?: ICinemetaVideo[]; +} + +export interface ICinemetaPopularities { + PXS_TEST?: number; + PXS?: number; + SCM?: number; + EXMD?: number; + ALLIANCE?: number; + EJD?: number; + moviedb?: number; + trakt?: number; + stremio?: number; + stremio_lib?: number; +} + +export interface ICinemetaTrailer { + source?: string; + type?: string; +} + +export interface ICinemetaVideo extends ICommonVideoMetadata { + name?: string; + number?: number; + firstAired?: string; + tvdb_id?: number; + rating?: string; + overview?: string; + thumbnail?: string; + description?: string; +} + +export interface ICinemetaTrailerStream { + title?: string; + ytId?: string; +} + +export interface ICinemetaLink { + name?: string; + category?: string; + url?: string; +} + +export interface ICinemetaBehaviorHints { + defaultVideoId?: null; + hasScheduledVideos?: boolean; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/common_video_metadata.ts b/src/node/consumer/src/lib/interfaces/common_video_metadata.ts new file mode 100644 index 0000000..6b7546c --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/common_video_metadata.ts @@ -0,0 +1,9 @@ +export interface ICommonVideoMetadata { + season?: number; + episode?: number; + released?: string; + title?: string; + name?: string; + id?: string; + imdb_id?: string; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/ingested_rabbit_message.ts b/src/node/consumer/src/lib/interfaces/ingested_rabbit_message.ts new file mode 100644 index 0000000..db25a2f --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/ingested_rabbit_message.ts @@ -0,0 +1,15 @@ +export interface IIngestedRabbitTorrent { + name: string; + source: string; + category: string; + infoHash: string; + size: string; + seeders: number; + leechers: number; + imdb: string; + processed: boolean; +} + +export interface IIngestedRabbitMessage { + message: IIngestedRabbitTorrent; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/kitsu_catalog_metadata.ts b/src/node/consumer/src/lib/interfaces/kitsu_catalog_metadata.ts new file mode 100644 index 0000000..277b44c --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/kitsu_catalog_metadata.ts @@ -0,0 +1,23 @@ +import {IKitsuLink, IKitsuTrailer} from "@interfaces/kitsu_metadata"; + +export interface IKitsuCatalogJsonResponse { + metas: IKitsuCatalogMetaData[]; +} + +export interface IKitsuCatalogMetaData { + id: string; + type: string; + animeType: string; + name: string; + aliases: string[]; + description: string; + releaseInfo: string; + runtime: string; + imdbRating: string; + genres: string[]; + logo?: string; + poster: string; + background: string; + trailers: IKitsuTrailer[]; + links: IKitsuLink[]; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/kitsu_metadata.ts b/src/node/consumer/src/lib/interfaces/kitsu_metadata.ts new file mode 100644 index 0000000..2c29416 --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/kitsu_metadata.ts @@ -0,0 +1,49 @@ +import {ICommonVideoMetadata} from "@interfaces/common_video_metadata"; + +export interface IKitsuJsonResponse { + cacheMaxAge?: number; + meta?: IKitsuMeta; +} + +export interface IKitsuMeta { + aliases?: string[]; + animeType?: string; + background?: string; + description?: string; + country?: string; + genres?: string[]; + id?: string; + imdbRating?: string; + imdb_id?: string; + kitsu_id?: string; + links?: IKitsuLink[]; + logo?: string; + name?: string; + poster?: string; + releaseInfo?: string; + runtime?: string; + slug?: string; + status?: string; + trailers?: IKitsuTrailer[]; + type?: string; + userCount?: number; + videos?: IKitsuVideo[]; + year?: string; +} + +export interface IKitsuVideo extends ICommonVideoMetadata { + imdbEpisode?: number; + imdbSeason?: number; + thumbnail?: string; +} + +export interface IKitsuTrailer { + source?: string; + type?: string; +} + +export interface IKitsuLink { + name?: string; + category?: string; + url?: string; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/logging_service.ts b/src/node/consumer/src/lib/interfaces/logging_service.ts new file mode 100644 index 0000000..19a365e --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/logging_service.ts @@ -0,0 +1,12 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +export interface ILoggingService { + info(message: string, ...args: any[]): void; + + error(message: string, ...args: any[]): void; + + debug(message: string, ...args: any[]): void; + + warn(message: string, ...args: any[]): void; +} + +/* eslint-enable @typescript-eslint/no-explicit-any */ \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/metadata_query.ts b/src/node/consumer/src/lib/interfaces/metadata_query.ts new file mode 100644 index 0000000..8acca9c --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/metadata_query.ts @@ -0,0 +1,9 @@ +export interface IMetaDataQuery { + title?: string + type?: string + year?: number | string + date?: string + season?: number + episode?: number + id?: string | number +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/metadata_response.ts b/src/node/consumer/src/lib/interfaces/metadata_response.ts new file mode 100644 index 0000000..8bccc5e --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/metadata_response.ts @@ -0,0 +1,15 @@ +import {ICommonVideoMetadata} from "@interfaces/common_video_metadata"; + +export interface IMetadataResponse { + kitsuId?: number; + imdbId?: number; + type?: string; + title?: string; + year?: number; + country?: string; + genres?: string[]; + status?: string; + videos?: ICommonVideoMetadata[]; + episodeCount?: number[]; + totalCount?: number; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/metadata_service.ts b/src/node/consumer/src/lib/interfaces/metadata_service.ts new file mode 100644 index 0000000..d9c583d --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/metadata_service.ts @@ -0,0 +1,14 @@ +import {IMetaDataQuery} from "@interfaces/metadata_query"; +import {IMetadataResponse} from "@interfaces/metadata_response"; + +export interface IMetadataService { + getKitsuId(info: IMetaDataQuery): Promise; + + getImdbId(info: IMetaDataQuery): Promise; + + getMetadata(query: IMetaDataQuery): Promise; + + isEpisodeImdbId(imdbId: string | undefined): Promise; + + escapeTitle(title: string): string; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/parse_torrent_title_result.ts b/src/node/consumer/src/lib/interfaces/parse_torrent_title_result.ts new file mode 100644 index 0000000..24429fc --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/parse_torrent_title_result.ts @@ -0,0 +1,36 @@ +import {IFileAttributes} from "@repository/interfaces/file_attributes"; + +export interface IParseTorrentTitleResult { + title?: string; + date?: string; + year?: number | string; + resolution?: string; + extended?: boolean; + unrated?: boolean; + proper?: boolean; + repack?: boolean; + convert?: boolean; + hardcoded?: boolean; + retail?: boolean; + remastered?: boolean; + complete?: boolean; + region?: string; + container?: string; + extension?: string; + source?: string; + codec?: string; + bitDepth?: string; + hdr?: Array; + audio?: string; + group?: string; + volumes?: Array; + seasons?: Array; + season?: number; + episodes?: Array; + episode?: number; + languages?: string; + dubbed?: boolean; + videoFile?: IFileAttributes; + folderName?: string; + fileName?: string; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/parsed_torrent.ts b/src/node/consumer/src/lib/interfaces/parsed_torrent.ts new file mode 100644 index 0000000..cf30030 --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/parsed_torrent.ts @@ -0,0 +1,18 @@ +import {TorrentType} from "@enums/torrent_types"; +import {IParseTorrentTitleResult} from "@interfaces/parse_torrent_title_result"; +import {ITorrentFileCollection} from "@interfaces/torrent_file_collection"; + +export interface IParsedTorrent extends IParseTorrentTitleResult { + size?: number; + isPack?: boolean; + imdbId?: string | number; + kitsuId?: number; + trackers?: string; + provider?: string | null; + infoHash: string; + type: string | TorrentType; + uploadDate?: Date; + seeders?: number; + torrentId?: string; + fileCollection?: ITorrentFileCollection; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/process_torrents_job.ts b/src/node/consumer/src/lib/interfaces/process_torrents_job.ts new file mode 100644 index 0000000..1603f5d --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/process_torrents_job.ts @@ -0,0 +1,3 @@ +export interface IProcessTorrentsJob { + listenToQueue: () => Promise; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/torrent_download_service.ts b/src/node/consumer/src/lib/interfaces/torrent_download_service.ts new file mode 100644 index 0000000..5d7789c --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/torrent_download_service.ts @@ -0,0 +1,6 @@ +import {IParsedTorrent} from "@interfaces/parsed_torrent"; +import {ITorrentFileCollection} from "@interfaces/torrent_file_collection"; + +export interface ITorrentDownloadService { + getTorrentFiles(torrent: IParsedTorrent, timeout: number): Promise; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/torrent_entries_service.ts b/src/node/consumer/src/lib/interfaces/torrent_entries_service.ts new file mode 100644 index 0000000..032be9b --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/torrent_entries_service.ts @@ -0,0 +1,18 @@ +import {IParsedTorrent} from "@interfaces/parsed_torrent"; +import {ITorrentAttributes, ITorrentCreationAttributes} from "@repository/interfaces/torrent_attributes"; +import {SkipTorrent} from "@repository/models/skipTorrent"; +import {Torrent} from "@repository/models/torrent"; + +export interface ITorrentEntriesService { + createTorrentEntry(torrent: IParsedTorrent, overwrite: boolean): Promise; + + createSkipTorrentEntry(torrent: ITorrentCreationAttributes): Promise<[SkipTorrent, boolean | null]>; + + getStoredTorrentEntry(torrent: Torrent): Promise; + + checkAndUpdateTorrent(torrent: IParsedTorrent): Promise; + + createTorrentContents(torrent: Torrent): Promise; + + updateTorrentSeeders(torrent: ITorrentAttributes): Promise<[number] | undefined>; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/torrent_file_collection.ts b/src/node/consumer/src/lib/interfaces/torrent_file_collection.ts new file mode 100644 index 0000000..043c01a --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/torrent_file_collection.ts @@ -0,0 +1,9 @@ +import {IContentAttributes} from "@repository/interfaces/content_attributes"; +import {IFileAttributes} from "@repository/interfaces/file_attributes"; +import {ISubtitleAttributes} from "@repository/interfaces/subtitle_attributes"; + +export interface ITorrentFileCollection { + contents?: IContentAttributes[]; + videos?: IFileAttributes[]; + subtitles?: ISubtitleAttributes[]; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/torrent_file_service.ts b/src/node/consumer/src/lib/interfaces/torrent_file_service.ts new file mode 100644 index 0000000..bedea14 --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/torrent_file_service.ts @@ -0,0 +1,8 @@ +import {IParsedTorrent} from "@interfaces/parsed_torrent"; +import {ITorrentFileCollection} from "@interfaces/torrent_file_collection"; + +export interface ITorrentFileService { + parseTorrentFiles(torrent: IParsedTorrent): Promise; + + isPackTorrent(torrent: IParsedTorrent): boolean; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/torrent_processing_service.ts b/src/node/consumer/src/lib/interfaces/torrent_processing_service.ts new file mode 100644 index 0000000..abdbd5f --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/torrent_processing_service.ts @@ -0,0 +1,5 @@ +import {IIngestedTorrentAttributes} from "@repository/interfaces/ingested_torrent_attributes"; + +export interface ITorrentProcessingService { + processTorrentRecord(torrent: IIngestedTorrentAttributes): Promise; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/torrent_subtitle_service.ts b/src/node/consumer/src/lib/interfaces/torrent_subtitle_service.ts new file mode 100644 index 0000000..1869c0b --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/torrent_subtitle_service.ts @@ -0,0 +1,5 @@ +import {ITorrentFileCollection} from "@interfaces/torrent_file_collection"; + +export interface ITorrentSubtitleService { + assignSubtitles(fileCollection: ITorrentFileCollection): ITorrentFileCollection; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/interfaces/tracker_service.ts b/src/node/consumer/src/lib/interfaces/tracker_service.ts new file mode 100644 index 0000000..cc15453 --- /dev/null +++ b/src/node/consumer/src/lib/interfaces/tracker_service.ts @@ -0,0 +1,3 @@ +export interface ITrackerService { + getTrackers(): Promise; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/jobs/process_torrents_job.ts b/src/node/consumer/src/lib/jobs/process_torrents_job.ts new file mode 100644 index 0000000..b010407 --- /dev/null +++ b/src/node/consumer/src/lib/jobs/process_torrents_job.ts @@ -0,0 +1,63 @@ +import {IIngestedRabbitMessage, IIngestedRabbitTorrent} from "@interfaces/ingested_rabbit_message"; +import {ILoggingService} from "@interfaces/logging_service"; +import {IProcessTorrentsJob} from "@interfaces/process_torrents_job"; +import {ITorrentProcessingService} from "@interfaces/torrent_processing_service"; +import {IIngestedTorrentAttributes} from "@repository/interfaces/ingested_torrent_attributes"; +import {configurationService} from '@services/configuration_service'; +import {IocTypes} from "@setup/ioc_types"; +import client, {Channel, Connection, ConsumeMessage, Options} from 'amqplib' +import {inject, injectable} from "inversify"; + +@injectable() +export class ProcessTorrentsJob implements IProcessTorrentsJob { + @inject(IocTypes.ITorrentProcessingService) torrentProcessingService: ITorrentProcessingService; + @inject(IocTypes.ILoggingService) logger: ILoggingService; + + private readonly assertQueueOptions: Options.AssertQueue = {durable: true}; + private readonly consumeQueueOptions: Options.Consume = {noAck: false}; + + async listenToQueue(): Promise { + if (!configurationService.jobConfig.JOBS_ENABLED) { + return; + } + + try { + const connection: Connection = await client.connect(configurationService.rabbitConfig.RABBIT_URI); + const channel: Channel = await connection.createChannel(); + await this.assertAndConsumeQueue(channel); + } catch (error) { + this.logger.error('Failed to connect and setup channel', error); + } + } + + private processMessage = (msg: ConsumeMessage | null): Promise => { + const ingestedTorrent: IIngestedTorrentAttributes = this.getMessageAsJson(msg); + return this.torrentProcessingService.processTorrentRecord(ingestedTorrent); + }; + + private getMessageAsJson = (msg: ConsumeMessage | null): IIngestedTorrentAttributes => { + const content = msg?.content.toString('utf8') ?? "{}"; + const receivedObject: IIngestedRabbitMessage = JSON.parse(content); + const receivedTorrent: IIngestedRabbitTorrent = receivedObject.message; + return {...receivedTorrent, info_hash: receivedTorrent.infoHash}; + }; + + private assertAndConsumeQueue = async (channel: Channel): Promise => { + this.logger.info('Worker is running! Waiting for new torrents...'); + + const ackMsg = async (msg: ConsumeMessage | null): Promise => { + await this.processMessage(msg) + .then(() => this.logger.info('Processed torrent')) + .then(() => msg && channel.ack(msg)) + .catch((error) => this.logger.error('Failed to process torrent', error)); + } + + try { + await channel.assertQueue(configurationService.rabbitConfig.QUEUE_NAME, this.assertQueueOptions); + await channel.prefetch(configurationService.jobConfig.JOB_CONCURRENCY); + await channel.consume(configurationService.rabbitConfig.QUEUE_NAME, ackMsg, this.consumeQueueOptions); + } catch (error) { + this.logger.error('Failed to setup channel', error); + } + }; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/logger.js b/src/node/consumer/src/lib/logger.js deleted file mode 100644 index 2ea0d7a..0000000 --- a/src/node/consumer/src/lib/logger.js +++ /dev/null @@ -1,5 +0,0 @@ -import pino from 'pino'; - -export const logger = pino({ - level: process.env.LOG_LEVEL || 'info' -}); \ No newline at end of file diff --git a/src/node/consumer/src/lib/metadata.js b/src/node/consumer/src/lib/metadata.js deleted file mode 100644 index 874decb..0000000 --- a/src/node/consumer/src/lib/metadata.js +++ /dev/null @@ -1,165 +0,0 @@ -import axios from 'axios'; -import { search } from 'google-sr'; -import nameToImdb from 'name-to-imdb'; -import { cacheWrapImdbId, cacheWrapKitsuId, cacheWrapMetadata } from './cache.js'; -import { TorrentType } from './types.js'; - -const CINEMETA_URL = 'https://v3-cinemeta.strem.io'; -const KITSU_URL = 'https://anime-kitsu.strem.fun'; -const TIMEOUT = 20000; - -export function getMetadata(id, type = TorrentType.SERIES) { - if (!id) { - return Promise.reject("no valid id provided"); - } - - const key = Number.isInteger(id) || id.match(/^\d+$/) ? `kitsu:${id}` : id; - const metaType = type === TorrentType.MOVIE ? TorrentType.MOVIE : TorrentType.SERIES; - return cacheWrapMetadata(key, () => _requestMetadata(`${KITSU_URL}/meta/${metaType}/${key}.json`) - .catch(() => _requestMetadata(`${CINEMETA_URL}/meta/${metaType}/${key}.json`)) - .catch(() => { - // try different type in case there was a mismatch - const otherType = metaType === TorrentType.MOVIE ? TorrentType.SERIES : TorrentType.MOVIE; - return _requestMetadata(`${CINEMETA_URL}/meta/${otherType}/${key}.json`) - }) - .catch((error) => { - throw new Error(`failed metadata query ${key} due: ${error.message}`); - })); -} - -function _requestMetadata(url) { - return axios.get(url, { timeout: TIMEOUT }) - .then((response) => { - const body = response.data; - if (body && body.meta && (body.meta.imdb_id || body.meta.kitsu_id)) { - return { - kitsuId: body.meta.kitsu_id, - imdbId: body.meta.imdb_id, - type: body.meta.type, - title: body.meta.name, - year: body.meta.year, - country: body.meta.country, - genres: body.meta.genres, - status: body.meta.status, - videos: (body.meta.videos || []) - .map((video) => Number.isInteger(video.imdbSeason) - ? { - name: video.name || video.title, - season: video.season, - episode: video.episode, - imdbSeason: video.imdbSeason, - imdbEpisode: video.imdbEpisode - } - : { - name: video.name || video.title, - season: video.season, - episode: video.episode, - kitsuId: video.kitsu_id, - kitsuEpisode: video.kitsuEpisode, - released: video.released - } - ), - episodeCount: Object.values((body.meta.videos || []) - .filter((entry) => entry.season !== 0 && entry.episode !== 0) - .sort((a, b) => a.season - b.season) - .reduce((map, next) => { - map[next.season] = map[next.season] + 1 || 1; - return map; - }, {})), - totalCount: body.meta.videos && body.meta.videos - .filter((entry) => entry.season !== 0 && entry.episode !== 0).length - }; - } else { - throw new Error('No search results'); - } - }); -} - -export function escapeTitle(title) { - return title.toLowerCase() - .normalize('NFKD') // normalize non-ASCII characters - .replace(/[\u0300-\u036F]/g, '') - .replace(/&/g, 'and') - .replace(/[;, ~./]+/g, ' ') // replace dots, commas or underscores with spaces - .replace(/[^\w \-()×+#@!'\u0400-\u04ff]+/g, '') // remove all non-alphanumeric chars - .replace(/^\d{1,2}[.#\s]+(?=(?:\d+[.\s]*)?[\u0400-\u04ff])/i, '') // remove russian movie numbering - .replace(/\s{2,}/, ' ') // replace multiple spaces - .trim(); -} - -export async function getImdbId(info, type) { - const name = escapeTitle(info.title); - const year = info.year || (info.date && info.date.slice(0, 4)); - const key = `${name}_${year || 'NA'}_${type}`; - const query = `${name} ${year || ''} ${type} imdb`; - const fallbackQuery = `${name} ${type} imdb`; - const googleQuery = year ? query : fallbackQuery; - - try { - const imdbId = await cacheWrapImdbId(key, - () => getIMDbIdFromNameToImdb(name, info.year, type) - ); - return imdbId && 'tt' + imdbId.replace(/tt0*([1-9][0-9]*)$/, '$1').padStart(7, '0'); - } catch (error) { - const imdbIdFallback = await getIMDbIdFromGoogle(googleQuery); - return imdbIdFallback && 'tt' + imdbIdFallback.replace(/tt0*([1-9][0-9]*)$/, '$1').padStart(7, '0'); - } -} - -function getIMDbIdFromNameToImdb(name, year, type) { - return new Promise((resolve, reject) => { - nameToImdb({ name, year, type }, function(err, res) { - if (res) { - resolve(res); - } else { - reject(err || new Error('Failed IMDbId search')); - } - }); - }); -} - -async function getIMDbIdFromGoogle(query) { - try { - const searchResults = await search({ query: query }); - for (const result of searchResults) { - if (result.link.includes('imdb.com/title/')) { - const match = result.link.match(/imdb\.com\/title\/(tt\d+)/); - if (match) { - return match[1]; - } - } - } - return undefined; - } - catch (error) { - throw new Error('Failed to find IMDb ID from Google search'); - } -} - -export async function getKitsuId(info) { - const title = escapeTitle(info.title.replace(/\s\|\s.*/, '')); - const year = info.year ? ` ${info.year}` : ''; - const season = info.season > 1 ? ` S${info.season}` : ''; - const key = `${title}${year}${season}`; - const query = encodeURIComponent(key); - - return cacheWrapKitsuId(key, - () => axios.get(`${KITSU_URL}/catalog/series/kitsu-anime-list/search=${query}.json`, { timeout: 60000 }) - .then((response) => { - const body = response.data; - if (body && body.metas && body.metas.length) { - return body.metas[0].id.replace('kitsu:', ''); - } else { - throw new Error('No search results'); - } - })); -} - -export async function isEpisodeImdbId(imdbId) { - if (!imdbId) { - return false; - } - return axios.get(`https://www.imdb.com/title/${imdbId}/`, { timeout: 10000 }) - .then(response => !!(response.data && response.data.includes('video.episode'))) - .catch(() => false); -} \ No newline at end of file diff --git a/src/node/consumer/src/lib/models/configuration/cache_config.ts b/src/node/consumer/src/lib/models/configuration/cache_config.ts new file mode 100644 index 0000000..21f283f --- /dev/null +++ b/src/node/consumer/src/lib/models/configuration/cache_config.ts @@ -0,0 +1,15 @@ +import {BooleanHelpers} from "@helpers/boolean_helpers"; + +export const cacheConfig = { + MONGODB_HOST: process.env.MONGODB_HOST || 'mongodb', + MONGODB_PORT: process.env.MONGODB_PORT || '27017', + MONGODB_DB: process.env.MONGODB_DB || 'knightcrawler', + MONGO_INITDB_ROOT_USERNAME: process.env.MONGO_INITDB_ROOT_USERNAME || 'mongo', + MONGO_INITDB_ROOT_PASSWORD: process.env.MONGO_INITDB_ROOT_PASSWORD || 'mongo', + NO_CACHE: BooleanHelpers.parseBool(process.env.NO_CACHE, false), + COLLECTION_NAME: process.env.MONGODB_COLLECTION || 'knightcrawler_consumer_collection', + + get MONGO_URI(): string { + return `mongodb://${this.MONGO_INITDB_ROOT_USERNAME}:${this.MONGO_INITDB_ROOT_PASSWORD}@${this.MONGODB_HOST}:${this.MONGODB_PORT}/${this.MONGODB_DB}?authSource=admin`; + } +}; \ No newline at end of file diff --git a/src/node/consumer/src/lib/models/configuration/database_config.ts b/src/node/consumer/src/lib/models/configuration/database_config.ts new file mode 100644 index 0000000..4c07d73 --- /dev/null +++ b/src/node/consumer/src/lib/models/configuration/database_config.ts @@ -0,0 +1,14 @@ +import {BooleanHelpers} from "@helpers/boolean_helpers"; + +export const databaseConfig = { + POSTGRES_HOST: process.env.POSTGRES_HOST || 'postgres', + POSTGRES_PORT: parseInt(process.env.POSTGRES_PORT || '5432'), + POSTGRES_DB: process.env.POSTGRES_DB || 'knightcrawler', + POSTGRES_USER: process.env.POSTGRES_USER || 'postgres', + POSTGRES_PASSWORD: process.env.POSTGRES_PASSWORD || 'postgres', + AUTO_CREATE_AND_APPLY_MIGRATIONS: BooleanHelpers.parseBool(process.env.AUTO_CREATE_AND_APPLY_MIGRATIONS, false), + + get POSTGRES_URI(): string { + return `postgres://${this.POSTGRES_USER}:${this.POSTGRES_PASSWORD}@${this.POSTGRES_HOST}:${this.POSTGRES_PORT}/${this.POSTGRES_DB}`; + } +}; \ No newline at end of file diff --git a/src/node/consumer/src/lib/models/configuration/job_config.ts b/src/node/consumer/src/lib/models/configuration/job_config.ts new file mode 100644 index 0000000..70f8476 --- /dev/null +++ b/src/node/consumer/src/lib/models/configuration/job_config.ts @@ -0,0 +1,6 @@ +import {BooleanHelpers} from "@helpers/boolean_helpers"; + +export const jobConfig = { + JOB_CONCURRENCY: parseInt(process.env.JOB_CONCURRENCY || "1", 10), + JOBS_ENABLED: BooleanHelpers.parseBool(process.env.JOBS_ENABLED, true) +}; \ No newline at end of file diff --git a/src/node/consumer/src/lib/models/configuration/metadata_config.ts b/src/node/consumer/src/lib/models/configuration/metadata_config.ts new file mode 100644 index 0000000..32b4e33 --- /dev/null +++ b/src/node/consumer/src/lib/models/configuration/metadata_config.ts @@ -0,0 +1,4 @@ +export const metadataConfig = { + IMDB_CONCURRENT: parseInt(process.env.IMDB_CONCURRENT || "1", 10), + IMDB_INTERVAL_MS: parseInt(process.env.IMDB_INTERVAL_MS || "1000", 10) +}; \ No newline at end of file diff --git a/src/node/consumer/src/lib/models/configuration/rabbit_config.ts b/src/node/consumer/src/lib/models/configuration/rabbit_config.ts new file mode 100644 index 0000000..b06ff9f --- /dev/null +++ b/src/node/consumer/src/lib/models/configuration/rabbit_config.ts @@ -0,0 +1,4 @@ +export const rabbitConfig = { + RABBIT_URI: process.env.RABBIT_URI || 'amqp://localhost', + QUEUE_NAME: process.env.QUEUE_NAME || 'test-queue' +}; \ No newline at end of file diff --git a/src/node/consumer/src/lib/models/configuration/torrent_config.ts b/src/node/consumer/src/lib/models/configuration/torrent_config.ts new file mode 100644 index 0000000..d40d0ed --- /dev/null +++ b/src/node/consumer/src/lib/models/configuration/torrent_config.ts @@ -0,0 +1,4 @@ +export const torrentConfig = { + MAX_CONNECTIONS_PER_TORRENT: parseInt(process.env.MAX_CONNECTIONS_PER_TORRENT || "20", 10), + TIMEOUT: parseInt(process.env.TORRENT_TIMEOUT || "30000", 10) +}; \ No newline at end of file diff --git a/src/node/consumer/src/lib/models/configuration/tracker_config.ts b/src/node/consumer/src/lib/models/configuration/tracker_config.ts new file mode 100644 index 0000000..f748b93 --- /dev/null +++ b/src/node/consumer/src/lib/models/configuration/tracker_config.ts @@ -0,0 +1,6 @@ +import {BooleanHelpers} from "@helpers/boolean_helpers"; + +export const trackerConfig = { + TRACKERS_URL: process.env.TRACKERS_URL || 'https://ngosang.github.io/trackerslist/trackers_all.txt', + UDP_ENABLED: BooleanHelpers.parseBool(process.env.UDP_TRACKERS_ENABLED, false) +}; \ No newline at end of file diff --git a/src/node/consumer/src/lib/parseHelper.js b/src/node/consumer/src/lib/parseHelper.js deleted file mode 100644 index b088687..0000000 --- a/src/node/consumer/src/lib/parseHelper.js +++ /dev/null @@ -1,98 +0,0 @@ -import { parse } from 'parse-torrent-title'; -import { TorrentType } from './types.js'; - -const MULTIPLE_FILES_SIZE = 4 * 1024 * 1024 * 1024; // 4 GB - -export function parseSeriesVideos(torrent, videos) { - const parsedTorrentName = parse(torrent.title); - const hasMovies = parsedTorrentName.complete || !!torrent.title.match(/movies?(?:\W|$)/i); - const parsedVideos = videos.map(video => parseSeriesVideo(video, parsedTorrentName)); - return parsedVideos.map(video => ({ ...video, isMovie: isMovieVideo(video, parsedVideos, torrent.type, hasMovies) })); -} - -function parseSeriesVideo(video, parsedTorrentName) { - const videoInfo = parse(video.name); - // the episode may be in a folder containing season number - if (!Number.isInteger(videoInfo.season) && video.path.includes('/')) { - const folders = video.path.split('/'); - const pathInfo = parse(folders[folders.length - 2]); - videoInfo.season = pathInfo.season; - } - if (!Number.isInteger(videoInfo.season) && parsedTorrentName.season) { - videoInfo.season = parsedTorrentName.season; - } - if (!Number.isInteger(videoInfo.season) && videoInfo.seasons && videoInfo.seasons.length > 1) { - // in case single file was interpreted as having multiple seasons - videoInfo.season = videoInfo.seasons[0]; - } - if (!Number.isInteger(videoInfo.season) && video.path.includes('/') && parsedTorrentName.seasons - && parsedTorrentName.seasons.length > 1) { - // russian season are usually named with 'series name-2` i.e. Улицы разбитых фонарей-6/22. Одиночный выстрел.mkv - const folderPathSeasonMatch = video.path.match(/[\u0400-\u04ff]-(\d{1,2})(?=.*\/)/); - videoInfo.season = folderPathSeasonMatch && parseInt(folderPathSeasonMatch[1], 10) || undefined; - } - // sometimes video file does not have correct date format as in torrent title - if (!videoInfo.episodes && !videoInfo.date && parsedTorrentName.date) { - videoInfo.date = parsedTorrentName.date; - } - // limit number of episodes in case of incorrect parsing - if (videoInfo.episodes && videoInfo.episodes.length > 20) { - videoInfo.episodes = [videoInfo.episodes[0]]; - videoInfo.episode = videoInfo.episodes[0]; - } - // force episode to any found number if it was not parsed - if (!videoInfo.episodes && !videoInfo.date) { - const epMatcher = videoInfo.title.match( - /(? 3 - && otherVideos.filter(other => other.title === video.title && other.year === video.year) < 3; -} - -export function isPackTorrent(torrent) { - if (torrent.pack) { - return true; - } - const parsedInfo = parse(torrent.title); - if (torrent.type === TorrentType.MOVIE) { - return parsedInfo.complete || typeof parsedInfo.year === 'string' || /movies/i.test(torrent.title); - } - const hasMultipleEpisodes = parsedInfo.complete || - torrent.size > MULTIPLE_FILES_SIZE || - (parsedInfo.seasons && parsedInfo.seasons.length > 1) || - (parsedInfo.episodes && parsedInfo.episodes.length > 1) || - (parsedInfo.seasons && !parsedInfo.episodes); - const hasSingleEpisode = Number.isInteger(parsedInfo.episode) || (!parsedInfo.episodes && parsedInfo.date); - return hasMultipleEpisodes && !hasSingleEpisode; -} \ No newline at end of file diff --git a/src/node/consumer/src/lib/promises.js b/src/node/consumer/src/lib/promises.js deleted file mode 100644 index 33e3dae..0000000 --- a/src/node/consumer/src/lib/promises.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Execute promises in sequence one after another. - */ -export async function sequence(promises) { - return promises.reduce((promise, func) => - promise.then(result => func().then(Array.prototype.concat.bind(result))), Promise.resolve([])); -} - -/** - * Return first resolved promise as the result. - */ -export async function first(promises) { - return Promise.all(promises.map((p) => { - // If a request fails, count that as a resolution so it will keep - // waiting for other possible successes. If a request succeeds, - // treat it as a rejection so Promise.all immediately bails out. - return p.then( - (val) => Promise.reject(val), - (err) => Promise.resolve(err) - ); - })).then( - // If '.all' resolved, we've just got an array of errors. - (errors) => Promise.reject(errors), - // If '.all' rejected, we've got the result we wanted. - (val) => Promise.resolve(val) - ); -} - -/** - * Delay promise - */ -export async function delay(duration) { - return new Promise((resolve) => setTimeout(resolve, duration)); -} - -/** - * Timeout promise after a set time in ms - */ -export async function timeout(timeoutMs, promise, message = 'Timed out') { - return Promise.race([ - promise, - new Promise(function (resolve, reject) { - setTimeout(function () { - reject(message); - }, timeoutMs); - }) - ]); -} - -/** - * Return most common value from given array. - */ -export function mostCommonValue(array) { - return array.sort((a, b) => array.filter(v => v === a).length - array.filter(v => v === b).length).pop(); -} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository.js b/src/node/consumer/src/lib/repository.js deleted file mode 100644 index 34c2b8c..0000000 --- a/src/node/consumer/src/lib/repository.js +++ /dev/null @@ -1,382 +0,0 @@ -import moment from 'moment'; -import { Sequelize, Op, DataTypes, fn, col, literal } from 'sequelize'; -import { databaseConfig } from './config.js'; -import { logger } from "./logger.js"; -import * as Promises from './promises.js'; - -const database = new Sequelize( - databaseConfig.POSTGRES_URI, - { - logging: false - } -); - -const Provider = database.define('provider', { - name: { type: DataTypes.STRING(32), primaryKey: true }, - lastScraped: { type: DataTypes.DATE }, - lastScrapedId: { type: DataTypes.STRING(128) } -}); - -const IngestedTorrent = database.define('ingested_torrent', { - id: { type: DataTypes.BIGINT, autoIncrement: true, primaryKey: true }, - name: DataTypes.STRING, - source: DataTypes.STRING, - category: DataTypes.STRING, - info_hash: DataTypes.STRING, - size: DataTypes.STRING, - seeders: DataTypes.INTEGER, - leechers: DataTypes.INTEGER, - imdb: DataTypes.STRING, - processed: { - type: DataTypes.BOOLEAN, - defaultValue: false - } -}, - { - indexes: [ - { - unique: true, - fields: ['source', 'info_hash'] - } - ] - }) - -/* eslint-disable no-unused-vars */ -const IngestedPage = database.define('ingested_page', { - id: { type: DataTypes.BIGINT, autoIncrement: true, primaryKey: true }, - url: { type: DataTypes.STRING, allowNull: false }, -}, - { - indexes: [ - { - unique: true, - fields: ['url'] - } - ] - }) -/* eslint-enable no-unused-vars */ - -const Torrent = database.define('torrent', - { - infoHash: { type: DataTypes.STRING(64), primaryKey: true }, - provider: { type: DataTypes.STRING(32), allowNull: false }, - torrentId: { type: DataTypes.STRING(512) }, - title: { type: DataTypes.STRING(512), allowNull: false }, - size: { type: DataTypes.BIGINT }, - type: { type: DataTypes.STRING(16), allowNull: false }, - uploadDate: { type: DataTypes.DATE, allowNull: false }, - seeders: { type: DataTypes.SMALLINT }, - trackers: { type: DataTypes.STRING(8000) }, - languages: { type: DataTypes.STRING(4096) }, - resolution: { type: DataTypes.STRING(16) }, - reviewed: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false }, - opened: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false } - } -); - -const File = database.define('file', - { - id: { type: DataTypes.BIGINT, autoIncrement: true, primaryKey: true }, - infoHash: { - type: DataTypes.STRING(64), - allowNull: false, - references: { model: Torrent, key: 'infoHash' }, - onDelete: 'CASCADE' - }, - fileIndex: { type: DataTypes.INTEGER }, - title: { type: DataTypes.STRING(512), allowNull: false }, - size: { type: DataTypes.BIGINT }, - imdbId: { type: DataTypes.STRING(32) }, - imdbSeason: { type: DataTypes.INTEGER }, - imdbEpisode: { type: DataTypes.INTEGER }, - kitsuId: { type: DataTypes.INTEGER }, - kitsuEpisode: { type: DataTypes.INTEGER } - }, - { - indexes: [ - { - unique: true, - name: 'files_unique_file_constraint', - fields: [ - col('infoHash'), - fn('COALESCE', (col('fileIndex')), -1), - fn('COALESCE', (col('imdbId')), 'null'), - fn('COALESCE', (col('imdbSeason')), -1), - fn('COALESCE', (col('imdbEpisode')), -1), - fn('COALESCE', (col('kitsuId')), -1), - fn('COALESCE', (col('kitsuEpisode')), -1) - ] - }, - { unique: false, fields: ['imdbId', 'imdbSeason', 'imdbEpisode'] }, - { unique: false, fields: ['kitsuId', 'kitsuEpisode'] } - ] - } -); - -const Subtitle = database.define('subtitle', - { - infoHash: { - type: DataTypes.STRING(64), - allowNull: false, - references: { model: Torrent, key: 'infoHash' }, - onDelete: 'CASCADE' - }, - fileIndex: { - type: DataTypes.INTEGER, - allowNull: false - }, - fileId: { - type: DataTypes.BIGINT, - allowNull: true, - references: { model: File, key: 'id' }, - onDelete: 'SET NULL' - }, - title: { type: DataTypes.STRING(512), allowNull: false }, - }, - { - timestamps: false, - indexes: [ - { - unique: true, - name: 'subtitles_unique_subtitle_constraint', - fields: [ - col('infoHash'), - col('fileIndex'), - fn('COALESCE', (col('fileId')), -1) - ] - }, - { unique: false, fields: ['fileId'] } - ] - } -); - -const Content = database.define('content', - { - infoHash: { - type: DataTypes.STRING(64), - primaryKey: true, - allowNull: false, - references: { model: Torrent, key: 'infoHash' }, - onDelete: 'CASCADE' - }, - fileIndex: { - type: DataTypes.INTEGER, - primaryKey: true, - allowNull: false - }, - path: { type: DataTypes.STRING(512), allowNull: false }, - size: { type: DataTypes.BIGINT }, - }, - { - timestamps: false, - } -); - -const SkipTorrent = database.define('skip_torrent', { - infoHash: { type: DataTypes.STRING(64), primaryKey: true }, -}); - -Torrent.hasMany(File, { foreignKey: 'infoHash', constraints: false }); -File.belongsTo(Torrent, { foreignKey: 'infoHash', constraints: false }); -Torrent.hasMany(Content, { foreignKey: 'infoHash', constraints: false }); -Content.belongsTo(Torrent, { foreignKey: 'infoHash', constraints: false }); -File.hasMany(Subtitle, { foreignKey: 'fileId', constraints: false }); -Subtitle.belongsTo(File, { foreignKey: 'fileId', constraints: false }); - -export function connect() { - return database.sync({ alter: databaseConfig.AUTO_CREATE_AND_APPLY_MIGRATIONS }) - .catch(error => { - console.error('Failed syncing database: ', error.message); - throw error; - }); - // I'm not convinced this code is needed. If anyone can see where it leads, or what it does, please inform me. - // For now, I'm commenting it out. I don't think we ever reach this at the moment anyway as the previous ENABLE_SYNC - // was always on. - // return Promise.resolve(); -} - -export function getProvider(provider) { - return Provider.findOrCreate({ where: { name: { [Op.eq]: provider.name } }, defaults: provider }) - .then((result) => result[0]) - .catch(() => provider); -} - -export function getTorrent(torrent) { - const where = torrent.infoHash - ? { infoHash: torrent.infoHash } - : { provider: torrent.provider, torrentId: torrent.torrentId } - return Torrent.findOne({ where: where }); -} - -export function getTorrentsBasedOnTitle(titleQuery, type) { - return getTorrentsBasedOnQuery({ title: { [Op.regexp]: `${titleQuery}` }, type: type }); -} - -export function getTorrentsBasedOnQuery(where) { - return Torrent.findAll({ where: where }); -} - -export function getFilesBasedOnQuery(where) { - return File.findAll({ where: where }); -} - -export function getUnprocessedIngestedTorrents() { - return IngestedTorrent.findAll({ - where: { - processed: false, - category: { - [Op.or]: ['tv', 'movies'] - } - }, - - }); -} - -export function setIngestedTorrentsProcessed(ingestedTorrents) { - return Promises.sequence(ingestedTorrents - .map(ingestedTorrent => () => { - ingestedTorrent.processed = true; - return ingestedTorrent.save(); - })); -} - -export function getTorrentsWithoutSize() { - return Torrent.findAll({ - where: literal( - 'exists (select 1 from files where files."infoHash" = torrent."infoHash" and files.size = 300000000)'), - order: [ - ['seeders', 'DESC'] - ] - }); -} - -export function getUpdateSeedersTorrents(limit = 50) { - const until = moment().subtract(7, 'days').format('YYYY-MM-DD'); - return Torrent.findAll({ - where: literal(`torrent."updatedAt" < '${until}'`), - limit: limit, - order: [ - ['seeders', 'DESC'], - ['updatedAt', 'ASC'] - ] - }); -} - -export function getUpdateSeedersNewTorrents(limit = 50) { - const lastUpdate = moment().subtract(12, 'hours').format('YYYY-MM-DD'); - const createdAfter = moment().subtract(4, 'days').format('YYYY-MM-DD'); - return Torrent.findAll({ - where: literal(`torrent."updatedAt" < '${lastUpdate}' AND torrent."createdAt" > '${createdAfter}'`), - limit: limit, - order: [ - ['seeders', 'ASC'], - ['updatedAt', 'ASC'] - ] - }); -} - -export function getNoContentsTorrents() { - return Torrent.findAll({ - where: { opened: false, seeders: { [Op.gte]: 1 } }, - limit: 500, - order: [[fn('RANDOM')]] - }); -} - -export function createTorrent(torrent) { - return Torrent.upsert(torrent) - .then(() => createContents(torrent.infoHash, torrent.contents)) - .then(() => createSubtitles(torrent.infoHash, torrent.subtitles)); -} - -export function setTorrentSeeders(torrent, seeders) { - const where = torrent.infoHash - ? { infoHash: torrent.infoHash } - : { provider: torrent.provider, torrentId: torrent.torrentId } - return Torrent.update( - { seeders: seeders }, - { where: where } - ); -} - -export function deleteTorrent(torrent) { - return Torrent.destroy({ where: { infoHash: torrent.infoHash } }) -} - -export function createFile(file) { - if (file.id) { - return (file.dataValues ? file.save() : File.upsert(file)) - .then(() => upsertSubtitles(file, file.subtitles)); - } - if (file.subtitles && file.subtitles.length) { - file.subtitles = file.subtitles.map(subtitle => ({ infoHash: file.infoHash, title: subtitle.path, ...subtitle })); - } - return File.create(file, { include: [Subtitle], ignoreDuplicates: true }); -} - -export function getFiles(torrent) { - return File.findAll({ where: { infoHash: torrent.infoHash } }); -} - -export function getFilesBasedOnTitle(titleQuery) { - return File.findAll({ where: { title: { [Op.regexp]: `${titleQuery}` } } }); -} - -export function deleteFile(file) { - return File.destroy({ where: { id: file.id } }) -} - -export function createSubtitles(infoHash, subtitles) { - if (subtitles && subtitles.length) { - return Subtitle.bulkCreate(subtitles.map(subtitle => ({ infoHash, title: subtitle.path, ...subtitle }))); - } - return Promise.resolve(); -} - -export function upsertSubtitles(file, subtitles) { - if (file.id && subtitles && subtitles.length) { - return Promises.sequence(subtitles - .map(subtitle => { - subtitle.fileId = file.id; - subtitle.infoHash = subtitle.infoHash || file.infoHash; - subtitle.title = subtitle.title || subtitle.path; - return subtitle; - }) - .map(subtitle => () => subtitle.dataValues ? subtitle.save() : Subtitle.create(subtitle))); - } - return Promise.resolve(); -} - -export function getSubtitles(torrent) { - return Subtitle.findAll({ where: { infoHash: torrent.infoHash } }); -} - -export function getUnassignedSubtitles() { - return Subtitle.findAll({ where: { fileId: null } }); -} - -export function createContents(infoHash, contents) { - if (contents && contents.length) { - return Content.bulkCreate(contents.map(content => ({ infoHash, ...content })), { ignoreDuplicates: true }) - .then(() => Torrent.update({ opened: true }, { where: { infoHash: infoHash }, silent: true })); - } - return Promise.resolve(); -} - -export function getContents(torrent) { - return Content.findAll({ where: { infoHash: torrent.infoHash } }); -} - -export function getSkipTorrent(torrent) { - return SkipTorrent.findByPk(torrent.infoHash) - .then((result) => { - if (!result) { - throw new Error(`torrent not found: ${torrent.infoHash}`); - } - return result.dataValues; - }) -} - -export function createSkipTorrent(torrent) { - return SkipTorrent.upsert({ infoHash: torrent.infoHash }); -} diff --git a/src/node/consumer/src/lib/repository/database_repository.ts b/src/node/consumer/src/lib/repository/database_repository.ts new file mode 100644 index 0000000..3152ece --- /dev/null +++ b/src/node/consumer/src/lib/repository/database_repository.ts @@ -0,0 +1,260 @@ +import {PromiseHelpers} from '@helpers/promises_helpers'; +import {ILoggingService} from "@interfaces/logging_service"; +import {IContentCreationAttributes} from "@repository/interfaces/content_attributes"; +import {IDatabaseRepository} from "@repository/interfaces/database_repository"; +import {IFileAttributes, IFileCreationAttributes} from "@repository/interfaces/file_attributes"; +import {ISubtitleAttributes, ISubtitleCreationAttributes} from "@repository/interfaces/subtitle_attributes"; +import {ITorrentAttributes, ITorrentCreationAttributes} from "@repository/interfaces/torrent_attributes"; +import {Content} from "@repository/models/content"; +import {File} from "@repository/models/file"; +import {IngestedPage} from "@repository/models/ingestedPage"; +import {IngestedTorrent} from "@repository/models/ingestedTorrent"; +import {Provider} from "@repository/models/provider"; +import {SkipTorrent} from "@repository/models/skipTorrent"; +import {Subtitle} from "@repository/models/subtitle"; +import {Torrent} from "@repository/models/torrent"; +import {configurationService} from '@services/configuration_service'; +import {IocTypes} from "@setup/ioc_types"; +import {inject, injectable} from "inversify"; +import moment from 'moment'; +import {literal, Op, WhereOptions} from "sequelize"; +import {Model, Sequelize} from 'sequelize-typescript'; + +@injectable() +export class DatabaseRepository implements IDatabaseRepository { + @inject(IocTypes.ILoggingService) logger: ILoggingService; + + private readonly database: Sequelize; + + private models = [ + Torrent, + Provider, + File, + Subtitle, + Content, + SkipTorrent, + IngestedTorrent, + IngestedPage]; + + constructor() { + this.database = this.createDatabase(); + } + + async connect(): Promise { + try { + await this.database.sync({alter: configurationService.databaseConfig.AUTO_CREATE_AND_APPLY_MIGRATIONS}); + } catch (error) { + this.logger.debug('Failed to sync database', error); + this.logger.error('Failed syncing database'); + process.exit(1); + } + } + + async getProvider(provider: Provider): Promise { + try { + const [result] = await Provider.findOrCreate({where: {name: {[Op.eq]: provider.name}}, defaults: provider}); + return result; + } catch { + return provider as Provider; + } + } + + async getTorrent(torrent: ITorrentAttributes): Promise { + const where = torrent.infoHash + ? {infoHash: torrent.infoHash} + : {provider: torrent.provider, torrentId: torrent.torrentId}; + return await Torrent.findOne({where}); + } + + async getTorrentsBasedOnTitle(titleQuery: string, type: string): Promise { + return this.getTorrentsBasedOnQuery({ + title: {[Op.regexp]: `${titleQuery}`}, + type + }); + } + + async getTorrentsBasedOnQuery(where: WhereOptions): Promise { + return await Torrent.findAll({where}); + } + + async getFilesBasedOnQuery(where: WhereOptions): Promise { + return await File.findAll({where}); + } + + async getTorrentsWithoutSize(): Promise { + return await Torrent.findAll({ + where: literal( + 'exists (select 1 from files where files."infoHash" = torrent."infoHash" and files.size = 300000000)'), + order: [ + ['seeders', 'DESC'] + ] + }); + } + + async getUpdateSeedersTorrents(limit = 50): Promise { + const until = moment().subtract(7, 'days').format('YYYY-MM-DD'); + return await Torrent.findAll({ + where: literal(`torrent."updatedAt" < '${until}'`), + limit: limit, + order: [ + ['seeders', 'DESC'], + ['updatedAt', 'ASC'] + ] + }); + } + + async getUpdateSeedersNewTorrents(limit = 50): Promise { + const lastUpdate = moment().subtract(12, 'hours').format('YYYY-MM-DD'); + const createdAfter = moment().subtract(4, 'days').format('YYYY-MM-DD'); + return await Torrent.findAll({ + where: literal(`torrent."updatedAt" < '${lastUpdate}' AND torrent."createdAt" > '${createdAfter}'`), + limit: limit, + order: [ + ['seeders', 'ASC'], + ['updatedAt', 'ASC'] + ] + }); + } + + async getNoContentsTorrents(): Promise { + return await Torrent.findAll({ + where: {opened: false, seeders: {[Op.gte]: 1}}, + limit: 500, + order: literal('random()') + }); + } + + async createTorrent(torrent: ITorrentCreationAttributes): Promise { + try { + await Torrent.upsert(torrent); + await this.createContents(torrent.infoHash, torrent.contents); + await this.createSubtitles(torrent.infoHash, torrent.subtitles); + } catch (error) { + this.logger.error(`Failed to create torrent: ${torrent.infoHash}`); + this.logger.debug("Error: ", error); + } + } + + async setTorrentSeeders(torrent: ITorrentAttributes, seeders: number): Promise<[number]> { + const where = torrent.infoHash + ? {infoHash: torrent.infoHash} + : {provider: torrent.provider, torrentId: torrent.torrentId}; + + return await Torrent.update( + {seeders: seeders}, + {where: where} + ); + } + + async deleteTorrent(infoHash: string): Promise { + return await Torrent.destroy({where: {infoHash: infoHash}}); + } + + async createFile(file: IFileCreationAttributes): Promise { + try { + const operatingFile = File.build(file); + if (operatingFile.id) { + if (operatingFile.dataValues) { + await operatingFile.save(); + } else { + await File.upsert(file); + } + await this.upsertSubtitles(operatingFile, file.subtitles); + } else { + if (operatingFile.subtitles && operatingFile.subtitles.length) { + operatingFile.subtitles = operatingFile.subtitles.map(subtitle => { + subtitle.title = subtitle.path || ''; + return subtitle; + }); + } + await File.create(file, {include: [Subtitle], ignoreDuplicates: true}); + } + } catch (error) { + this.logger.error(`Failed to create file: ${file.infoHash}`); + this.logger.debug("Error: ", error); + } + } + + async getFiles(infoHash: string): Promise { + return File.findAll({where: {infoHash: infoHash}}); + } + + async getFilesBasedOnTitle(titleQuery: string): Promise { + return File.findAll({where: {title: {[Op.regexp]: `${titleQuery}`}}}); + } + + async deleteFile(id: number): Promise { + return File.destroy({where: {id: id}}); + } + + async createSubtitles(infoHash: string, subtitles: ISubtitleCreationAttributes[] | undefined): Promise[]> { + if (subtitles && subtitles.length) { + return Subtitle.bulkCreate(subtitles.map(subtitle => ({...subtitle, infoHash: infoHash, title: subtitle.path}))); + } + return Promise.resolve(); + } + + async upsertSubtitles(file: File, subtitles: ISubtitleCreationAttributes[] | undefined): Promise { + if (file.id && subtitles && subtitles.length) { + await PromiseHelpers.sequence(subtitles + .map(subtitle => { + subtitle.fileId = file.id; + subtitle.infoHash = subtitle.infoHash || file.infoHash; + subtitle.title = subtitle.title || subtitle.path || ''; + return subtitle; + }) + .map(subtitle => async () => { + const operatingInstance = Subtitle.build(subtitle); + if (operatingInstance.dataValues) { + await operatingInstance.save(); + } else { + await Subtitle.create(subtitle); + } + })); + } + } + + async getSubtitles(infoHash: string): Promise { + return Subtitle.findAll({where: {infoHash: infoHash}}); + } + + async getUnassignedSubtitles(): Promise { + return Subtitle.findAll({where: {fileId: null}}); + } + + async createContents(infoHash: string, contents: IContentCreationAttributes[] | undefined): Promise { + if (contents && contents.length) { + await Content.bulkCreate(contents.map(content => ({...content, infoHash})), {ignoreDuplicates: true}); + await Torrent.update({opened: true}, {where: {infoHash: infoHash}, silent: true}); + } + } + + async getContents(infoHash: string): Promise { + return Content.findAll({where: {infoHash: infoHash}}); + } + + async getSkipTorrent(infoHash: string): Promise { + const result = await SkipTorrent.findByPk(infoHash); + if (!result) { + throw new Error(`torrent not found: ${infoHash}`); + } + return result.dataValues as SkipTorrent; + } + + async createSkipTorrent(torrent: ITorrentCreationAttributes): Promise<[SkipTorrent, boolean | null]> { + return SkipTorrent.upsert({infoHash: torrent.infoHash}); + } + + private createDatabase = (): Sequelize => { + const newDatabase = new Sequelize( + configurationService.databaseConfig.POSTGRES_URI, + { + logging: false + } + ); + + newDatabase.addModels(this.models); + + return newDatabase; + }; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/interfaces/content_attributes.ts b/src/node/consumer/src/lib/repository/interfaces/content_attributes.ts new file mode 100644 index 0000000..03d7944 --- /dev/null +++ b/src/node/consumer/src/lib/repository/interfaces/content_attributes.ts @@ -0,0 +1,11 @@ +import {Optional} from "sequelize"; + +export interface IContentAttributes { + infoHash: string; + fileIndex: number; + path: string; + size: number; +} + +export interface IContentCreationAttributes extends Optional { +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/interfaces/database_repository.ts b/src/node/consumer/src/lib/repository/interfaces/database_repository.ts new file mode 100644 index 0000000..9b54278 --- /dev/null +++ b/src/node/consumer/src/lib/repository/interfaces/database_repository.ts @@ -0,0 +1,64 @@ +import {IContentCreationAttributes} from "@repository/interfaces/content_attributes"; +import {IFileAttributes, IFileCreationAttributes} from "@repository/interfaces/file_attributes"; +import {ISubtitleAttributes, ISubtitleCreationAttributes} from "@repository/interfaces/subtitle_attributes"; +import {ITorrentAttributes, ITorrentCreationAttributes} from "@repository/interfaces/torrent_attributes"; +import {Content} from "@repository/models/content"; +import {File} from "@repository/models/file"; +import {Provider} from "@repository/models/provider"; +import {SkipTorrent} from "@repository/models/skipTorrent"; +import {Subtitle} from "@repository/models/subtitle"; +import {Torrent} from "@repository/models/torrent"; +import {WhereOptions} from "sequelize"; +import {Model} from "sequelize-typescript"; + +export interface IDatabaseRepository { + connect(): Promise; + + getProvider(provider: Provider): Promise; + + getTorrent(torrent: ITorrentAttributes): Promise; + + getTorrentsBasedOnTitle(titleQuery: string, type: string): Promise; + + getTorrentsBasedOnQuery(where: WhereOptions): Promise; + + getFilesBasedOnQuery(where: WhereOptions): Promise; + + getTorrentsWithoutSize(): Promise; + + getUpdateSeedersTorrents(limit: number): Promise; + + getUpdateSeedersNewTorrents(limit: number): Promise; + + getNoContentsTorrents(): Promise; + + createTorrent(torrent: ITorrentCreationAttributes): Promise; + + setTorrentSeeders(torrent: ITorrentAttributes, seeders: number): Promise<[number]>; + + deleteTorrent(infoHash: string): Promise; + + createFile(file: IFileCreationAttributes): Promise; + + getFiles(infoHash: string): Promise; + + getFilesBasedOnTitle(titleQuery: string): Promise; + + deleteFile(id: number): Promise; + + createSubtitles(infoHash: string, subtitles: ISubtitleCreationAttributes[]): Promise[]>; + + upsertSubtitles(file: File, subtitles: ISubtitleCreationAttributes[] | undefined): Promise; + + getSubtitles(infoHash: string): Promise; + + getUnassignedSubtitles(): Promise; + + createContents(infoHash: string, contents: IContentCreationAttributes[]): Promise; + + getContents(infoHash: string): Promise; + + getSkipTorrent(infoHash: string): Promise; + + createSkipTorrent(torrent: ITorrentCreationAttributes): Promise<[SkipTorrent, boolean | null]>; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/interfaces/file_attributes.ts b/src/node/consumer/src/lib/repository/interfaces/file_attributes.ts new file mode 100644 index 0000000..b899f56 --- /dev/null +++ b/src/node/consumer/src/lib/repository/interfaces/file_attributes.ts @@ -0,0 +1,22 @@ +import {IParseTorrentTitleResult} from "@interfaces/parse_torrent_title_result"; +import {ISubtitleAttributes} from "@repository/interfaces/subtitle_attributes"; +import {Optional} from "sequelize"; + +export interface IFileAttributes extends IParseTorrentTitleResult { + id?: number; + infoHash?: string; + fileIndex?: number; + title: string; + size?: number; + imdbId?: string; + imdbSeason?: number; + imdbEpisode?: number; + kitsuId?: number; + kitsuEpisode?: number; + subtitles?: ISubtitleAttributes[]; + path?: string; + isMovie?: boolean; +} + +export interface IFileCreationAttributes extends Optional { +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/interfaces/ingested_page_attributes.ts b/src/node/consumer/src/lib/repository/interfaces/ingested_page_attributes.ts new file mode 100644 index 0000000..b8814f5 --- /dev/null +++ b/src/node/consumer/src/lib/repository/interfaces/ingested_page_attributes.ts @@ -0,0 +1,6 @@ +export interface IIngestedPageAttributes { + url: string; +} + +export interface IIngestedPageCreationAttributes extends IIngestedPageAttributes { +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/interfaces/ingested_torrent_attributes.ts b/src/node/consumer/src/lib/repository/interfaces/ingested_torrent_attributes.ts new file mode 100644 index 0000000..53ab7ab --- /dev/null +++ b/src/node/consumer/src/lib/repository/interfaces/ingested_torrent_attributes.ts @@ -0,0 +1,17 @@ +import {Optional} from "sequelize"; + +export interface IIngestedTorrentAttributes { + name: string; + source: string; + category: string; + info_hash: string; + size: string; + seeders: number; + leechers: number; + imdb: string; + processed: boolean; + createdAt?: Date; +} + +export interface IIngestedTorrentCreationAttributes extends Optional { +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/interfaces/provider_attributes.ts b/src/node/consumer/src/lib/repository/interfaces/provider_attributes.ts new file mode 100644 index 0000000..984ae2e --- /dev/null +++ b/src/node/consumer/src/lib/repository/interfaces/provider_attributes.ts @@ -0,0 +1,10 @@ +import {Optional} from "sequelize"; + +export interface IProviderAttributes { + name: string; + lastScraped: Date; + lastScrapedId: string; +} + +export interface IProviderCreationAttributes extends Optional { +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/interfaces/skip_torrent_attributes.ts b/src/node/consumer/src/lib/repository/interfaces/skip_torrent_attributes.ts new file mode 100644 index 0000000..4d8c1da --- /dev/null +++ b/src/node/consumer/src/lib/repository/interfaces/skip_torrent_attributes.ts @@ -0,0 +1,8 @@ +import {Optional} from "sequelize"; + +export interface ISkipTorrentAttributes { + infoHash: string; +} + +export interface ISkipTorrentCreationAttributes extends Optional { +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/interfaces/subtitle_attributes.ts b/src/node/consumer/src/lib/repository/interfaces/subtitle_attributes.ts new file mode 100644 index 0000000..bef6538 --- /dev/null +++ b/src/node/consumer/src/lib/repository/interfaces/subtitle_attributes.ts @@ -0,0 +1,12 @@ +import {Optional} from "sequelize"; + +export interface ISubtitleAttributes { + infoHash: string; + fileIndex: number; + fileId?: number | null; + title: string; + path: string; +} + +export interface ISubtitleCreationAttributes extends Optional { +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/interfaces/torrent_attributes.ts b/src/node/consumer/src/lib/repository/interfaces/torrent_attributes.ts new file mode 100644 index 0000000..c34fa4c --- /dev/null +++ b/src/node/consumer/src/lib/repository/interfaces/torrent_attributes.ts @@ -0,0 +1,26 @@ +import {IContentAttributes} from "@repository/interfaces/content_attributes"; +import {IFileAttributes} from "@repository/interfaces/file_attributes"; +import {ISubtitleAttributes} from "@repository/interfaces/subtitle_attributes"; +import {Optional} from "sequelize"; + +export interface ITorrentAttributes { + infoHash: string; + provider?: string | null; + torrentId?: string; + title?: string; + size?: number; + type?: string; + uploadDate?: Date; + seeders?: number; + trackers?: string; + languages?: string; + resolution?: string; + reviewed?: boolean; + opened?: boolean; + contents?: IContentAttributes[]; + files?: IFileAttributes[]; + subtitles?: ISubtitleAttributes[]; +} + +export interface ITorrentCreationAttributes extends Optional { +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/models/content.ts b/src/node/consumer/src/lib/repository/models/content.ts new file mode 100644 index 0000000..db7c7cc --- /dev/null +++ b/src/node/consumer/src/lib/repository/models/content.ts @@ -0,0 +1,22 @@ +import {IContentAttributes, IContentCreationAttributes} from "@repository/interfaces/content_attributes"; +import {Torrent} from "@repository/models/torrent"; +import {BelongsTo, Column, DataType, ForeignKey, Model, Table} from 'sequelize-typescript'; + +@Table({modelName: 'content', timestamps: false}) +export class Content extends Model { + @Column({type: DataType.STRING(64), primaryKey: true, allowNull: false, onDelete: 'CASCADE'}) + @ForeignKey(() => Torrent) + declare infoHash: string; + + @Column({type: DataType.INTEGER, primaryKey: true, allowNull: false}) + declare fileIndex: number; + + @Column({type: DataType.STRING(512), allowNull: false}) + declare path: string; + + @Column({type: DataType.BIGINT}) + declare size: number; + + @BelongsTo(() => Torrent, {constraints: false, foreignKey: 'infoHash'}) + torrent?: Torrent; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/models/file.ts b/src/node/consumer/src/lib/repository/models/file.ts new file mode 100644 index 0000000..378311b --- /dev/null +++ b/src/node/consumer/src/lib/repository/models/file.ts @@ -0,0 +1,59 @@ +import {IFileAttributes, IFileCreationAttributes} from "@repository/interfaces/file_attributes"; +import {Subtitle} from "@repository/models/subtitle"; +import {Torrent} from "@repository/models/torrent"; +import {BelongsTo, Column, DataType, ForeignKey, HasMany, Model, Table} from 'sequelize-typescript'; + +const indexes = [ + { + unique: true, + name: 'files_unique_file_constraint', + fields: [ + 'infoHash', + 'fileIndex', + 'imdbId', + 'imdbSeason', + 'imdbEpisode', + 'kitsuId', + 'kitsuEpisode' + ] + }, + {unique: false, fields: ['imdbId', 'imdbSeason', 'imdbEpisode']}, + {unique: false, fields: ['kitsuId', 'kitsuEpisode']} +]; + +@Table({modelName: 'file', timestamps: true, indexes: indexes}) +export class File extends Model { + @Column({type: DataType.STRING(64), allowNull: false, onDelete: 'CASCADE'}) + @ForeignKey(() => Torrent) + declare infoHash: string; + + @Column({type: DataType.INTEGER}) + declare fileIndex: number; + + @Column({type: DataType.STRING(512), allowNull: false}) + declare title: string; + + @Column({type: DataType.BIGINT}) + declare size: number; + + @Column({type: DataType.STRING(32)}) + declare imdbId: string; + + @Column({type: DataType.INTEGER}) + declare imdbSeason: number; + + @Column({type: DataType.INTEGER}) + declare imdbEpisode: number; + + @Column({type: DataType.INTEGER}) + declare kitsuId: number; + + @Column({type: DataType.INTEGER}) + declare kitsuEpisode: number; + + @HasMany(() => Subtitle, {constraints: false, foreignKey: 'fileId'}) + declare subtitles?: Subtitle[]; + + @BelongsTo(() => Torrent, {constraints: false, foreignKey: 'infoHash'}) + torrent?: Torrent; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/models/ingestedPage.ts b/src/node/consumer/src/lib/repository/models/ingestedPage.ts new file mode 100644 index 0000000..0e91bb5 --- /dev/null +++ b/src/node/consumer/src/lib/repository/models/ingestedPage.ts @@ -0,0 +1,16 @@ +import {IIngestedPageAttributes, IIngestedPageCreationAttributes} from "@repository/interfaces/ingested_page_attributes"; +import {Column, DataType, Model, Table} from 'sequelize-typescript'; + +const indexes = [ + { + unique: true, + name: 'ingested_page_unique_url_constraint', + fields: ['url'] + } +]; + +@Table({modelName: 'ingested_page', timestamps: true, indexes: indexes}) +export class IngestedPage extends Model { + @Column({type: DataType.STRING(512), allowNull: false}) + declare url: string; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/models/ingestedTorrent.ts b/src/node/consumer/src/lib/repository/models/ingestedTorrent.ts new file mode 100644 index 0000000..437eeca --- /dev/null +++ b/src/node/consumer/src/lib/repository/models/ingestedTorrent.ts @@ -0,0 +1,40 @@ +import {IIngestedTorrentAttributes, IIngestedTorrentCreationAttributes} from "@repository/interfaces/ingested_torrent_attributes"; +import {Column, DataType, Model, Table} from 'sequelize-typescript'; + +const indexes = [ + { + unique: true, + name: 'ingested_torrent_unique_source_info_hash_constraint', + fields: ['source', 'info_hash'] + } +]; + +@Table({modelName: 'ingested_torrent', timestamps: true, indexes: indexes}) +export class IngestedTorrent extends Model { + @Column({type: DataType.STRING(512)}) + declare name: string; + + @Column({type: DataType.STRING(512)}) + declare source: string; + + @Column({type: DataType.STRING(32)}) + declare category: string; + + @Column({type: DataType.STRING(64)}) + declare info_hash: string; + + @Column({type: DataType.STRING(32)}) + declare size: string; + + @Column({type: DataType.INTEGER}) + declare seeders: number; + + @Column({type: DataType.INTEGER}) + declare leechers: number; + + @Column({type: DataType.STRING(32)}) + declare imdb: string; + + @Column({type: DataType.BOOLEAN, defaultValue: false}) + declare processed: boolean; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/models/provider.ts b/src/node/consumer/src/lib/repository/models/provider.ts new file mode 100644 index 0000000..fef9c18 --- /dev/null +++ b/src/node/consumer/src/lib/repository/models/provider.ts @@ -0,0 +1,15 @@ +import {IProviderAttributes, IProviderCreationAttributes} from "@repository/interfaces/provider_attributes"; +import {Column, DataType, Model, Table} from 'sequelize-typescript'; + +@Table({modelName: 'provider', timestamps: false}) +export class Provider extends Model { + + @Column({type: DataType.STRING(32), primaryKey: true}) + declare name: string; + + @Column({type: DataType.DATE}) + declare lastScraped: Date; + + @Column({type: DataType.STRING(128)}) + declare lastScrapedId: string; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/models/skipTorrent.ts b/src/node/consumer/src/lib/repository/models/skipTorrent.ts new file mode 100644 index 0000000..9022126 --- /dev/null +++ b/src/node/consumer/src/lib/repository/models/skipTorrent.ts @@ -0,0 +1,9 @@ +import {ISkipTorrentAttributes, ISkipTorrentCreationAttributes} from "@repository/interfaces/skip_torrent_attributes"; +import {Column, DataType, Model, Table} from 'sequelize-typescript'; + +@Table({modelName: 'skip_torrent', timestamps: false}) +export class SkipTorrent extends Model { + + @Column({type: DataType.STRING(64), primaryKey: true}) + declare infoHash: string; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/models/subtitle.ts b/src/node/consumer/src/lib/repository/models/subtitle.ts new file mode 100644 index 0000000..3742caf --- /dev/null +++ b/src/node/consumer/src/lib/repository/models/subtitle.ts @@ -0,0 +1,38 @@ +import {ISubtitleAttributes, ISubtitleCreationAttributes} from "@repository/interfaces/subtitle_attributes"; +import {File} from "@repository/models/file"; +import {BelongsTo, Column, DataType, ForeignKey, Model, Table} from 'sequelize-typescript'; + +const indexes = [ + { + unique: true, + name: 'subtitles_unique_subtitle_constraint', + fields: [ + 'infoHash', + 'fileIndex', + 'fileId' + ] + }, + {unique: false, fields: ['fileId']} +]; + +@Table({modelName: 'subtitle', timestamps: false, indexes: indexes}) +export class Subtitle extends Model { + + @Column({type: DataType.STRING(64), allowNull: false, onDelete: 'CASCADE'}) + declare infoHash: string; + + @Column({type: DataType.INTEGER, allowNull: false}) + declare fileIndex: number; + + @Column({type: DataType.BIGINT, allowNull: true, onDelete: 'SET NULL'}) + @ForeignKey(() => File) + declare fileId?: number | null; + + @Column({type: DataType.STRING(512), allowNull: false}) + declare title: string; + + @BelongsTo(() => File, {constraints: false, foreignKey: 'fileId'}) + file?: File; + + path?: string; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/repository/models/torrent.ts b/src/node/consumer/src/lib/repository/models/torrent.ts new file mode 100644 index 0000000..4539e69 --- /dev/null +++ b/src/node/consumer/src/lib/repository/models/torrent.ts @@ -0,0 +1,56 @@ +import {ITorrentAttributes, ITorrentCreationAttributes} from "@repository/interfaces/torrent_attributes"; +import {Content} from "@repository/models/content"; +import {File} from "@repository/models/file"; +import {Subtitle} from "@repository/models/subtitle"; +import {Column, DataType, HasMany, Model, Table} from 'sequelize-typescript'; + +@Table({modelName: 'torrent', timestamps: true}) + +export class Torrent extends Model { + @Column({type: DataType.STRING(64), primaryKey: true}) + declare infoHash: string; + + @Column({type: DataType.STRING(32), allowNull: false}) + declare provider: string; + + @Column({type: DataType.STRING(512)}) + declare torrentId: string; + + @Column({type: DataType.STRING(512), allowNull: false}) + declare title: string; + + @Column({type: DataType.BIGINT}) + declare size: number; + + @Column({type: DataType.STRING(16), allowNull: false}) + declare type: string; + + @Column({type: DataType.DATE, allowNull: false}) + declare uploadDate: Date; + + @Column({type: DataType.SMALLINT}) + declare seeders: number; + + @Column({type: DataType.STRING(8000)}) + declare trackers: string; + + @Column({type: DataType.STRING(4096)}) + declare languages: string; + + @Column({type: DataType.STRING(16)}) + declare resolution: string; + + @Column({type: DataType.BOOLEAN, allowNull: false, defaultValue: false}) + declare reviewed: boolean; + + @Column({type: DataType.BOOLEAN, allowNull: false, defaultValue: false}) + declare opened: boolean; + + @HasMany(() => Content, {foreignKey: 'infoHash', constraints: false}) + contents?: Content[]; + + @HasMany(() => File, {foreignKey: 'infoHash', constraints: false}) + files?: File[]; + + subtitles?: Subtitle[]; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/services/cache_service.ts b/src/node/consumer/src/lib/services/cache_service.ts new file mode 100644 index 0000000..015a995 --- /dev/null +++ b/src/node/consumer/src/lib/services/cache_service.ts @@ -0,0 +1,111 @@ +import {CacheType} from "@enums/cache_types"; +import {ICacheOptions} from "@interfaces/cache_options"; +import {ICacheService} from "@interfaces/cache_service"; +import {ILoggingService} from "@interfaces/logging_service"; +import {configurationService} from '@services/configuration_service'; +import {IocTypes} from "@setup/ioc_types"; +import {mongoDbStore} from '@tirke/node-cache-manager-mongodb' +import {Cache, createCache, MemoryCache, memoryStore} from 'cache-manager'; +import {inject, injectable} from "inversify"; + +const GLOBAL_KEY_PREFIX = 'knightcrawler-consumer'; +const IMDB_ID_PREFIX = `${GLOBAL_KEY_PREFIX}|imdb_id`; +const KITSU_ID_PREFIX = `${GLOBAL_KEY_PREFIX}|kitsu_id`; +const METADATA_PREFIX = `${GLOBAL_KEY_PREFIX}|metadata`; +const TRACKERS_KEY_PREFIX = `${GLOBAL_KEY_PREFIX}|trackers`; + +const GLOBAL_TTL: number = Number(process.env.METADATA_TTL) || 7 * 24 * 60 * 60; // 7 days +const MEMORY_TTL: number = Number(process.env.METADATA_TTL) || 2 * 60 * 60; // 2 hours +const TRACKERS_TTL: number = 2 * 24 * 60 * 60; // 2 days + +/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ +export type CacheMethod = () => any; + +@injectable() +export class CacheService implements ICacheService { + @inject(IocTypes.ILoggingService) private logger: ILoggingService; + + private readonly memoryCache: MemoryCache | undefined; + private readonly remoteCache: Cache | MemoryCache | undefined; + + constructor() { + if (configurationService.cacheConfig.NO_CACHE) { + this.logger.info('Cache is disabled'); + return; + } + + this.memoryCache = this.initiateMemoryCache(); + this.remoteCache = this.initiateRemoteCache(); + } + + cacheWrapImdbId(key: string, method: CacheMethod): Promise { + return this.cacheWrap(CacheType.MongoDb, `${IMDB_ID_PREFIX}:${key}`, method, {ttl: GLOBAL_TTL}); + } + + cacheWrapKitsuId(key: string, method: CacheMethod): Promise { + return this.cacheWrap(CacheType.MongoDb, `${KITSU_ID_PREFIX}:${key}`, method, {ttl: GLOBAL_TTL}); + } + + cacheWrapMetadata(id: string, method: CacheMethod): Promise { + return this.cacheWrap(CacheType.Memory, `${METADATA_PREFIX}:${id}`, method, {ttl: MEMORY_TTL}); + } + + cacheTrackers(method: CacheMethod): Promise { + return this.cacheWrap(CacheType.Memory, `${TRACKERS_KEY_PREFIX}`, method, {ttl: TRACKERS_TTL}); + } + + private initiateMemoryCache = (): MemoryCache => + createCache(memoryStore(), { + ttl: MEMORY_TTL + }); + + private initiateMongoCache = (): Cache => { + const store = mongoDbStore({ + collectionName: configurationService.cacheConfig.COLLECTION_NAME, + ttl: GLOBAL_TTL, + url: configurationService.cacheConfig.MONGO_URI, + mongoConfig: { + socketTimeoutMS: 120000, + appName: 'knightcrawler-consumer', + } + }); + + return createCache(store, { + ttl: GLOBAL_TTL, + }); + } + + private initiateRemoteCache = (): Cache | undefined => { + if (configurationService.cacheConfig.NO_CACHE) { + this.logger.debug('Cache is disabled'); + return undefined; + } + + return configurationService.cacheConfig.MONGO_URI ? this.initiateMongoCache() : this.initiateMemoryCache(); + } + + private getCacheType = (cacheType: CacheType): MemoryCache | Cache | undefined => { + switch (cacheType) { + case CacheType.Memory: + return this.memoryCache; + case CacheType.MongoDb: + return this.remoteCache; + default: + return undefined; + } + } + + private cacheWrap = async (cacheType: CacheType, key: string, method: CacheMethod, options: ICacheOptions): Promise => { + const cache = this.getCacheType(cacheType); + + if (configurationService.cacheConfig.NO_CACHE || !cache) { + return method(); + } + + this.logger.debug(`Cache type: ${cacheType}`); + this.logger.debug(`Cache key: ${key}`); + this.logger.debug(`Cache options: ${JSON.stringify(options)}`); + + return cache.wrap(key, method, options.ttl); + }; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/services/configuration_service.ts b/src/node/consumer/src/lib/services/configuration_service.ts new file mode 100644 index 0000000..39cf00d --- /dev/null +++ b/src/node/consumer/src/lib/services/configuration_service.ts @@ -0,0 +1,17 @@ +import {cacheConfig} from "@models/configuration/cache_config"; +import {databaseConfig} from "@models/configuration/database_config"; +import {jobConfig} from "@models/configuration/job_config"; +import {metadataConfig} from "@models/configuration/metadata_config"; +import {rabbitConfig} from "@models/configuration/rabbit_config"; +import {torrentConfig} from "@models/configuration/torrent_config"; +import {trackerConfig} from "@models/configuration/tracker_config"; + +export const configurationService = { + rabbitConfig: rabbitConfig, + cacheConfig: cacheConfig, + databaseConfig: databaseConfig, + jobConfig: jobConfig, + metadataConfig: metadataConfig, + trackerConfig: trackerConfig, + torrentConfig: torrentConfig +}; \ No newline at end of file diff --git a/src/node/consumer/src/lib/services/logging_service.ts b/src/node/consumer/src/lib/services/logging_service.ts new file mode 100644 index 0000000..5b2837d --- /dev/null +++ b/src/node/consumer/src/lib/services/logging_service.ts @@ -0,0 +1,32 @@ +import {ILoggingService} from "@interfaces/logging_service"; +import {injectable} from "inversify"; +import {Logger, pino} from "pino"; + +/* eslint-disable @typescript-eslint/no-explicit-any */ +@injectable() +export class LoggingService implements ILoggingService { + private readonly logger: Logger; + + constructor() { + this.logger = pino({ + level: process.env.LOG_LEVEL || 'info' + }); + } + + public info = (message: string, ...args: any[]): void => { + this.logger.info(message, args); + }; + + public error = (message: string, ...args: any[]): void => { + this.logger.error(message, args); + }; + + public debug = (message: string, ...args: any[]): void => { + this.logger.debug(message, args); + }; + + public warn = (message: string, ...args: any[]): void => { + this.logger.warn(message, args); + }; +} +/* eslint-enable @typescript-eslint/no-explicit-any */ \ No newline at end of file diff --git a/src/node/consumer/src/lib/services/metadata_service.ts b/src/node/consumer/src/lib/services/metadata_service.ts new file mode 100644 index 0000000..3dfeb1d --- /dev/null +++ b/src/node/consumer/src/lib/services/metadata_service.ts @@ -0,0 +1,234 @@ +import {TorrentType} from '@enums/torrent_types'; +import {ICacheService} from "@interfaces/cache_service"; +import {ICinemetaJsonResponse} from "@interfaces/cinemeta_metadata"; +import {ICommonVideoMetadata} from "@interfaces/common_video_metadata"; +import {IKitsuCatalogJsonResponse} from "@interfaces/kitsu_catalog_metadata"; +import {IKitsuJsonResponse} from "@interfaces/kitsu_metadata"; +import {IMetaDataQuery} from "@interfaces/metadata_query"; +import {IMetadataResponse} from "@interfaces/metadata_response"; +import {IMetadataService} from "@interfaces/metadata_service"; +import {IocTypes} from "@setup/ioc_types"; +import axios from 'axios'; +import {ResultTypes, search} from 'google-sr'; +import {inject, injectable} from "inversify"; +import nameToImdb from 'name-to-imdb'; + +const CINEMETA_URL = 'https://v3-cinemeta.strem.io'; +const KITSU_URL = 'https://anime-kitsu.strem.fun'; +const TIMEOUT = 60000; + +@injectable() +export class MetadataService implements IMetadataService { + @inject(IocTypes.ICacheService) private cacheService: ICacheService; + + async getKitsuId(info: IMetaDataQuery): Promise { + const title = this.escapeTitle(info.title!.replace(/\s\|\s.*/, '')); + const year = info.year ? ` ${info.year}` : ''; + const season = info.season || 0 > 1 ? ` S${info.season}` : ''; + const key = `${title}${year}${season}`; + const query = encodeURIComponent(key); + + return this.cacheService.cacheWrapKitsuId(key, + () => axios.get(`${KITSU_URL}/catalog/series/kitsu-anime-list/search=${query}.json`, {timeout: TIMEOUT}) + .then((response) => { + const body = response.data as IKitsuCatalogJsonResponse; + if (body && body.metas && body.metas.length) { + return body.metas[0].id.replace('kitsu:', ''); + } else { + throw new Error('No search results'); + } + })); + } + + async getImdbId(info: IMetaDataQuery): Promise { + const name = this.escapeTitle(info.title!); + const year = info.year || (info.date && info.date.slice(0, 4)); + const key = `${name}_${year || 'NA'}_${info.type}`; + const query = `${name} ${year || ''} ${info.type} imdb`; + const fallbackQuery = `${name} ${info.type} imdb`; + const googleQuery = year ? query : fallbackQuery; + + try { + const imdbId = await this.cacheService.cacheWrapImdbId(key, + () => this.getIMDbIdFromNameToImdb(name, info) + ); + return imdbId && 'tt' + imdbId.replace(/tt0*([1-9][0-9]*)$/, '$1').padStart(7, '0'); + } catch (error) { + const imdbIdFallback = await this.getIMDbIdFromGoogle(googleQuery); + return imdbIdFallback && 'tt' + imdbIdFallback.toString().replace(/tt0*([1-9][0-9]*)$/, '$1').padStart(7, '0'); + } + } + + async getMetadata(query: IMetaDataQuery): Promise { + if (!query.id) { + return Promise.reject("no valid id provided"); + } + + const key = Number.isInteger(query.id) || query.id.toString().match(/^\d+$/) ? `kitsu:${query.id}` : query.id; + const metaType = query.type === TorrentType.Movie ? TorrentType.Movie : TorrentType.Series; + const isImdbId = Boolean(key.toString().match(/^tt\d+$/)); + + try { + try { + return await this.cacheService.cacheWrapMetadata(key.toString(), () => { + switch (isImdbId) { + case true: + return this.requestMetadata(`${CINEMETA_URL}/meta/imdb/${key}.json`, this.handleCinemetaResponse); + default: + return this.requestMetadata(`${KITSU_URL}/meta/${metaType}/${key}.json`, this.handleKitsuResponse) + } + }); + } catch (e) { + // try different type in case there was a mismatch + const otherType = metaType === TorrentType.Movie ? TorrentType.Series : TorrentType.Movie; + return this.requestMetadata(`${CINEMETA_URL}/meta/${otherType}/${key}.json`, this.handleCinemetaResponse) + } + } catch (error) { + throw new Error(`failed metadata query ${key} due: ${error.message}`); + } + } + + async isEpisodeImdbId(imdbId: string | undefined): Promise { + if (!imdbId || !imdbId.toString().match(/^tt\d+$/)) { + return false; + } + + try { + const response = await axios.get(`https://www.imdb.com/title/${imdbId}/`, {timeout: TIMEOUT}); + return response.data.includes('video.episode'); + } catch (error) { + return false; + } + } + + escapeTitle(title: string): string { + return title.toLowerCase() + .normalize('NFKD') // normalize non-ASCII characters + .replace(/[\u0300-\u036F]/g, '') + .replace(/&/g, 'and') + .replace(/[;, ~./]+/g, ' ') // replace dots, commas or underscores with spaces + .replace(/[^\w \-()×+#@!'\u0400-\u04ff]+/g, '') // remove all non-alphanumeric chars + .replace(/^\d{1,2}[.#\s]+(?=(?:\d+[.\s]*)?[\u0400-\u04ff])/i, '') // remove russian movie numbering + .replace(/\s{2,}/, ' ') // replace multiple spaces + .trim(); + } + + private requestMetadata = async (url: string, handler: (body: unknown) => IMetadataResponse): Promise => { + try { + const response = await axios.get(url, {timeout: TIMEOUT}); + const body = response.data; + return handler(body); + } catch (error) { + throw new Error(`HTTP error! status: ${error.response?.status}`); + } + }; + + private handleCinemetaResponse = (response: unknown): IMetadataResponse => { + const body = response as ICinemetaJsonResponse + + return ({ + imdbId: parseInt(body.meta?.id || '0'), + type: body.meta?.type, + title: body.meta?.name, + year: parseInt(body.meta?.year || '0'), + country: body.meta?.country, + genres: body.meta?.genres, + status: body.meta?.status, + videos: body.meta?.videos + ? body.meta.videos.map(video => ({ + name: video.name, + season: video.season, + episode: video.episode, + imdbSeason: video.season, + imdbEpisode: video.episode, + })) + : [], + episodeCount: body.meta?.videos + ? this.getEpisodeCount(body.meta.videos) + : [], + totalCount: body.meta?.videos + ? body.meta.videos.filter( + entry => entry.season !== 0 && entry.episode !== 0 + ).length + : 0, + }); + }; + + private handleKitsuResponse = (response: unknown): IMetadataResponse => { + const body = response as IKitsuJsonResponse; + + return ({ + kitsuId: parseInt(body.meta?.kitsu_id || '0'), + type: body.meta?.type, + title: body.meta?.name, + year: parseInt(body.meta?.year || '0'), + country: body.meta?.country, + genres: body.meta?.genres, + status: body.meta?.status, + videos: body.meta?.videos + ? body.meta?.videos.map(video => ({ + name: video.title, + season: video.season, + episode: video.episode, + kitsuId: video.id, + kitsuEpisode: video.episode, + released: video.released, + })) + : [], + episodeCount: body.meta?.videos + ? this.getEpisodeCount(body.meta.videos) + : [], + totalCount: body.meta?.videos + ? body.meta.videos.filter( + entry => entry.season !== 0 && entry.episode !== 0 + ).length + : 0, + }); + }; + + private getEpisodeCount = (videos: ICommonVideoMetadata[]): number[] => + Object.values( + videos + .filter(entry => entry.season !== null && entry.season !== 0 && entry.episode !== 0) + .sort((a, b) => (a.season || 0) - (b.season || 0)) + .reduce((map: Record, next) => { + if (next.season || next.season === 0) { + map[next.season] = (map[next.season] || 0) + 1; + } + return map; + }, {}) + ); + + private getIMDbIdFromNameToImdb = (name: string, info: IMetaDataQuery): Promise => { + const {year} = info; + const {type} = info; + return new Promise((resolve, reject) => { + nameToImdb({name, year, type}, function (err: Error, res: string) { + if (res) { + resolve(res); + } else { + reject(err || new Error('Failed IMDbId search')); + } + }); + }); + }; + + private getIMDbIdFromGoogle = async (query: string): Promise => { + try { + const searchResults = await search({query: query}); + for (const result of searchResults) { + if (result.type === ResultTypes.SearchResult) { + if (result.link.includes('imdb.com/title/')) { + const match = result.link.match(/imdb\.com\/title\/(tt\d+)/); + if (match) { + return match[1]; + } + } + } + } + return undefined; + } catch (error) { + throw new Error('Failed to find IMDb ID from Google search'); + } + }; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/services/torrent_download_service.ts b/src/node/consumer/src/lib/services/torrent_download_service.ts new file mode 100644 index 0000000..46aa9f5 --- /dev/null +++ b/src/node/consumer/src/lib/services/torrent_download_service.ts @@ -0,0 +1,164 @@ +import {ExtensionHelpers} from '@helpers/extension_helpers'; +import {ILoggingService} from "@interfaces/logging_service"; +import {IParsedTorrent} from "@interfaces/parsed_torrent"; +import {ITorrentDownloadService} from "@interfaces/torrent_download_service"; +import {ITorrentFileCollection} from "@interfaces/torrent_file_collection"; +import {IContentAttributes} from "@repository/interfaces/content_attributes"; +import {IFileAttributes} from "@repository/interfaces/file_attributes"; +import {ISubtitleAttributes} from "@repository/interfaces/subtitle_attributes"; +import {configurationService} from '@services/configuration_service'; +import {IocTypes} from "@setup/ioc_types"; +import {inject, injectable} from "inversify"; +import {encode} from 'magnet-uri'; +import {parse} from "parse-torrent-title"; +// eslint-disable-next-line import/no-extraneous-dependencies +import * as torrentStream from "torrent-stream"; +import TorrentEngine = TorrentStream.TorrentEngine; +import TorrentEngineOptions = TorrentStream.TorrentEngineOptions; + +interface ITorrentFile { + name: string; + path: string; + length: number; + fileIndex: number; +} + +@injectable() +export class TorrentDownloadService implements ITorrentDownloadService { + @inject(IocTypes.ILoggingService) private logger: ILoggingService; + + private engineOptions: TorrentEngineOptions = { + connections: configurationService.torrentConfig.MAX_CONNECTIONS_PER_TORRENT, + uploads: 0, + verify: false, + dht: false, + tracker: true, + }; + + async getTorrentFiles(torrent: IParsedTorrent, timeout: number = 30000): Promise { + const torrentFiles: ITorrentFile[] = await this.filesFromTorrentStream(torrent, timeout); + + const videos = this.filterVideos(torrent, torrentFiles); + const subtitles = this.filterSubtitles(torrent, torrentFiles); + const contents = this.createContent(torrent, torrentFiles); + + return { + contents: contents, + videos: videos, + subtitles: subtitles, + }; + } + + private filesFromTorrentStream = async (torrent: IParsedTorrent, timeout: number): Promise => { + if (!torrent.infoHash) { + return Promise.reject(new Error("No infoHash...")); + } + const magnet = encode({infoHash: torrent.infoHash, announce: torrent.trackers!.split(',')}); + + return new Promise((resolve, reject) => { + this.logger.debug(`Adding torrent with infoHash ${torrent.infoHash} to torrent engine...`); + + const timeoutId = setTimeout(() => { + engine.destroy(() => { + }); + reject(new Error('No available connections for torrent!')); + }, timeout); + + const engine: TorrentEngine = torrentStream.default(magnet, this.engineOptions); + + engine.on("ready", () => { + const files: ITorrentFile[] = engine.files.map((file, fileId) => ({ + fileIndex: fileId, + length: file.length, + name: file.name, + path: file.path, + })); + + resolve(files); + clearTimeout(timeoutId); + engine.destroy(() => { + }); + }); + }); + }; + + private filterVideos = (torrent: IParsedTorrent, torrentFiles: ITorrentFile[]): IFileAttributes[] => { + if (torrentFiles.length === 1 && !Number.isInteger(torrentFiles[0].fileIndex)) { + return [this.mapTorrentFileToFileAttributes(torrent, torrentFiles[0])]; + } + const videos = torrentFiles.filter(file => ExtensionHelpers.isVideo(file.path || '')); + const maxSize = Math.max(...videos.map((video: ITorrentFile) => video.length)); + const minSampleRatio = videos.length <= 3 ? 3 : 10; + const minAnimeExtraRatio = 5; + const minRedundantRatio = videos.length <= 3 ? 30 : Number.MAX_VALUE; + + const isSample = (video: ITorrentFile): boolean => video.path?.toString()?.match(/sample|bonus|promo/i) && maxSize / video.length > minSampleRatio || false; + const isRedundant = (video: ITorrentFile): boolean => maxSize / video.length > minRedundantRatio; + const isExtra = (video: ITorrentFile): boolean => /extras?\//i.test(video.path?.toString() || ""); + const isAnimeExtra = (video: ITorrentFile): boolean => { + if (!video.path || !video.length) { + return false; + } + + return video.path.toString()?.match(/(?:\b|_)(?:NC)?(?:ED|OP|PV)(?:v?\d\d?)?(?:\b|_)/i) + && maxSize / parseInt(video.length.toString()) > minAnimeExtraRatio || false; + }; + const isWatermark = (video: ITorrentFile): boolean => { + if (!video.path || !video.length) { + return false; + } + + return video.path.toString()?.match(/^[A-Z-]+(?:\.[A-Z]+)?\.\w{3,4}$/) + && maxSize / parseInt(video.length.toString()) > minAnimeExtraRatio || false; + } + + return videos + .filter(video => !isSample(video)) + .filter(video => !isExtra(video)) + .filter(video => !isAnimeExtra(video)) + .filter(video => !isRedundant(video)) + .filter(video => !isWatermark(video)) + .map(video => this.mapTorrentFileToFileAttributes(torrent, video)); + }; + + private filterSubtitles = (torrent: IParsedTorrent, torrentFiles: ITorrentFile[]): ISubtitleAttributes[] => torrentFiles.filter(file => ExtensionHelpers.isSubtitle(file.name || '')) + .map(file => this.mapTorrentFileToSubtitleAttributes(torrent, file)); + + private createContent = (torrent: IParsedTorrent, torrentFiles: ITorrentFile[]): IContentAttributes[] => torrentFiles.map(file => this.mapTorrentFileToContentAttributes(torrent, file)); + + private mapTorrentFileToFileAttributes = (torrent: IParsedTorrent, file: ITorrentFile): IFileAttributes => { + try { + const videoFile: IFileAttributes = { + title: file.name, + size: file.length, + fileIndex: file.fileIndex || 0, + path: file.path, + infoHash: torrent.infoHash?.toString(), + imdbId: torrent.imdbId?.toString() || '', + imdbSeason: torrent.season || 0, + imdbEpisode: torrent.episode || 0, + kitsuId: parseInt(torrent.kitsuId?.toString() || '0') || 0, + kitsuEpisode: torrent.episode || 0, + }; + + return {...videoFile, ...parse(file.name)}; + } catch (error) { + throw new Error(`Error parsing file ${file.name} from torrent ${torrent.infoHash}: ${error}`); + } + }; + + private mapTorrentFileToSubtitleAttributes = (torrent: IParsedTorrent, file: ITorrentFile): ISubtitleAttributes => ({ + title: file.name, + infoHash: torrent.infoHash, + fileIndex: file.fileIndex, + fileId: file.fileIndex, + path: file.path, + }); + + private mapTorrentFileToContentAttributes = (torrent: IParsedTorrent, file: ITorrentFile): IContentAttributes => ({ + infoHash: torrent.infoHash, + fileIndex: file.fileIndex, + path: file.path, + size: file.length, + }); +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/services/torrent_entries_service.ts b/src/node/consumer/src/lib/services/torrent_entries_service.ts new file mode 100644 index 0000000..681b55b --- /dev/null +++ b/src/node/consumer/src/lib/services/torrent_entries_service.ts @@ -0,0 +1,288 @@ +import {TorrentType} from '@enums/torrent_types'; +import {PromiseHelpers} from '@helpers/promises_helpers'; +import {ILoggingService} from "@interfaces/logging_service"; +import {IMetaDataQuery} from "@interfaces/metadata_query"; +import {IMetadataService} from "@interfaces/metadata_service"; +import {IParsedTorrent} from "@interfaces/parsed_torrent"; +import {ITorrentEntriesService} from "@interfaces/torrent_entries_service"; +import {ITorrentFileCollection} from "@interfaces/torrent_file_collection"; +import {ITorrentFileService} from "@interfaces/torrent_file_service"; +import {ITorrentSubtitleService} from "@interfaces/torrent_subtitle_service"; +import {IDatabaseRepository} from "@repository/interfaces/database_repository"; +import {IFileCreationAttributes} from "@repository/interfaces/file_attributes"; +import {ISubtitleAttributes} from "@repository/interfaces/subtitle_attributes"; +import {ITorrentAttributes, ITorrentCreationAttributes} from "@repository/interfaces/torrent_attributes"; +import {File} from "@repository/models/file"; +import {SkipTorrent} from "@repository/models/skipTorrent"; +import {Subtitle} from "@repository/models/subtitle"; +import {Torrent} from "@repository/models/torrent"; +import {IocTypes} from "@setup/ioc_types"; +import {inject, injectable} from "inversify"; +import {parse} from 'parse-torrent-title'; + +@injectable() +export class TorrentEntriesService implements ITorrentEntriesService { + @inject(IocTypes.IMetadataService) private metadataService: IMetadataService; + @inject(IocTypes.ILoggingService) private logger: ILoggingService; + @inject(IocTypes.ITorrentFileService) private fileService: ITorrentFileService; + @inject(IocTypes.ITorrentSubtitleService) private subtitleService: ITorrentSubtitleService; + @inject(IocTypes.IDatabaseRepository) private repository: IDatabaseRepository; + + async createTorrentEntry(torrent: IParsedTorrent, overwrite = false): Promise { + if (!torrent.title) { + this.logger.warn(`No title found for ${torrent.provider} [${torrent.infoHash}]`); + return; + } + + const titleInfo = parse(torrent.title); + + if (!torrent.imdbId && torrent.type !== TorrentType.Anime) { + const imdbQuery = { + title: titleInfo.title, + year: titleInfo.year, + type: torrent.type + }; + torrent.imdbId = await this.metadataService.getImdbId(imdbQuery) + .catch(() => undefined); + } + if (torrent.imdbId && torrent.imdbId.toString().length < 9) { + // pad zeros to imdbId if missing + torrent.imdbId = 'tt' + torrent.imdbId.toString().replace('tt', '').padStart(7, '0'); + } + if (torrent.imdbId && torrent.imdbId.toString().length > 9 && torrent.imdbId.toString().startsWith('tt0')) { + // sanitize imdbId from redundant zeros + torrent.imdbId = torrent.imdbId.toString().replace(/tt0+([0-9]{7,})$/, 'tt$1'); + } + if (!torrent.kitsuId && torrent.type === TorrentType.Anime) { + const kitsuQuery = { + title: titleInfo.title, + year: titleInfo.year, + season: titleInfo.season, + }; + + await this.assignKitsuId(kitsuQuery, torrent); + } + + if (!torrent.imdbId && !torrent.kitsuId && !this.fileService.isPackTorrent(torrent)) { + this.logger.warn(`imdbId or kitsuId not found: ${torrent.provider} ${torrent.title}`); + return; + } + + const fileCollection: ITorrentFileCollection = await this.fileService.parseTorrentFiles(torrent) + .then((torrentContents: ITorrentFileCollection) => overwrite ? this.overwriteExistingFiles(torrent, torrentContents) : torrentContents) + .then((torrentContents: ITorrentFileCollection) => this.subtitleService.assignSubtitles(torrentContents)) + .catch(error => { + this.logger.warn(`Failed getting files for ${torrent.title}`, error.message); + return {}; + }); + + if (!fileCollection.videos || !fileCollection.videos.length) { + this.logger.warn(`no video files found for ${torrent.provider} [${torrent.infoHash}] ${torrent.title}`); + return; + } + + const newTorrent: ITorrentCreationAttributes = ({ + ...torrent, + contents: fileCollection.contents, + subtitles: fileCollection.subtitles + }); + + return this.repository.createTorrent(newTorrent) + .then(() => PromiseHelpers.sequence(fileCollection.videos!.map(video => () => { + const newVideo: IFileCreationAttributes = {...video, infoHash: video.infoHash, title: video.title}; + if (!newVideo.kitsuId) { + newVideo.kitsuId = 0; + } + return this.repository.createFile(newVideo) + }))) + .then(() => this.logger.info(`Created ${torrent.provider} entry for [${torrent.infoHash}] ${torrent.title}`)); + } + + async createSkipTorrentEntry(torrent: ITorrentCreationAttributes): Promise<[SkipTorrent, boolean | null]> { + return this.repository.createSkipTorrent(torrent); + } + + async getStoredTorrentEntry(torrent: Torrent): Promise { + return this.repository.getSkipTorrent(torrent.infoHash) + .catch(() => this.repository.getTorrent(torrent.dataValues)) + .catch(() => undefined); + } + + async checkAndUpdateTorrent(torrent: IParsedTorrent): Promise { + const query: ITorrentAttributes = { + infoHash: torrent.infoHash, + provider: torrent.provider, + } + + const existingTorrent = await this.repository.getTorrent(query).catch(() => undefined); + + if (!existingTorrent) { + return false; + } + + if (existingTorrent.provider === 'RARBG') { + return true; + } + if (existingTorrent.provider === 'KickassTorrents' && torrent.provider) { + existingTorrent.provider = torrent.provider; + existingTorrent.torrentId = torrent.torrentId!; + } + + if (!existingTorrent.languages && torrent.languages && existingTorrent.provider !== 'RARBG') { + existingTorrent.languages = torrent.languages; + await existingTorrent.save(); + this.logger.debug(`Updated [${existingTorrent.infoHash}] ${existingTorrent.title} language to ${torrent.languages}`); + } + + return this.createTorrentContents(existingTorrent) + .then(() => this.updateTorrentSeeders(existingTorrent.dataValues)) + .then(() => Promise.resolve(true)) + .catch(() => Promise.reject(false)); + } + + async createTorrentContents(torrent: Torrent): Promise { + if (torrent.opened) { + return; + } + + const storedVideos: File[] = await this.repository.getFiles(torrent.infoHash).catch(() => []); + if (!storedVideos || !storedVideos.length) { + return; + } + const notOpenedVideo = storedVideos.length === 1 && !Number.isInteger(storedVideos[0].fileIndex); + const imdbId: string | undefined = PromiseHelpers.mostCommonValue(storedVideos.map(stored => stored.imdbId)); + const kitsuId: number = PromiseHelpers.mostCommonValue(storedVideos.map(stored => stored.kitsuId || 0)); + + const fileCollection: ITorrentFileCollection = await this.fileService.parseTorrentFiles(torrent) + .then(torrentContents => notOpenedVideo ? torrentContents : { + ...torrentContents, + videos: storedVideos.map(video => video.dataValues) + }) + .then(torrentContents => this.subtitleService.assignSubtitles(torrentContents)) + .then(torrentContents => this.assignMetaIds(torrentContents, imdbId, kitsuId)) + .catch(error => { + this.logger.warn(`Failed getting contents for [${torrent.infoHash}] ${torrent.title}`, error.message); + return {}; + }); + + if (!fileCollection.contents || !fileCollection.contents.length) { + return; + } + + if (notOpenedVideo && fileCollection.videos?.length === 1) { + // if both have a single video and stored one was not opened, update stored one to true metadata and use that + storedVideos[0].fileIndex = fileCollection?.videos[0]?.fileIndex || 0; + storedVideos[0].title = fileCollection.videos[0].title; + storedVideos[0].size = fileCollection.videos[0].size || 0; + const subtitles: ISubtitleAttributes[] = fileCollection.videos[0]?.subtitles || []; + storedVideos[0].subtitles = subtitles.map(subtitle => Subtitle.build(subtitle)); + fileCollection.videos[0] = {...storedVideos[0], subtitles: subtitles}; + } + // no videos available or more than one new videos were in the torrent + const shouldDeleteOld = notOpenedVideo && fileCollection.videos?.every(video => !video.id) || false; + + const newTorrent: ITorrentCreationAttributes = { + ...torrent, + files: fileCollection.videos, + contents: fileCollection.contents, + subtitles: fileCollection.subtitles + }; + + return this.repository.createTorrent(newTorrent) + .then(() => { + if (shouldDeleteOld) { + this.logger.debug(`Deleting old video for [${torrent.infoHash}] ${torrent.title}`) + return storedVideos[0].destroy(); + } + return Promise.resolve(); + }) + .then(() => { + const promises = fileCollection.videos!.map(video => { + const newVideo: IFileCreationAttributes = {...video, infoHash: video.infoHash, title: video.title}; + return this.repository.createFile(newVideo); + }); + return Promise.all(promises); + }) + .then(() => this.logger.info(`Created contents for ${torrent.provider} [${torrent.infoHash}] ${torrent.title}`)) + .catch(error => this.logger.error(`Failed saving contents for [${torrent.infoHash}] ${torrent.title}`, error)); + } + + async updateTorrentSeeders(torrent: ITorrentAttributes): Promise<[number]> { + if (!(torrent.infoHash || (torrent.provider && torrent.torrentId)) || !Number.isInteger(torrent.seeders)) { + return [0]; + } + + if (torrent.seeders === undefined) { + this.logger.warn(`Seeders not found for ${torrent.provider} [${torrent.infoHash}] ${torrent.title}`); + return [0]; + } + + + return this.repository.setTorrentSeeders(torrent, torrent.seeders) + .catch(error => { + this.logger.warn('Failed updating seeders:', error); + return [0]; + }); + } + + private assignKitsuId = async (kitsuQuery: IMetaDataQuery, torrent: IParsedTorrent): Promise => { + await this.metadataService.getKitsuId(kitsuQuery) + .then((result: number | Error) => { + if (typeof result === 'number') { + torrent.kitsuId = result; + } else { + torrent.kitsuId = 0; + } + }) + .catch((error: Error) => { + this.logger.debug(`Failed getting kitsuId for ${torrent.title}`, error.message); + torrent.kitsuId = 0; + }); + }; + + private assignMetaIds = (fileCollection: ITorrentFileCollection, imdbId: string | undefined, kitsuId: number): ITorrentFileCollection => { + if (fileCollection && fileCollection.videos && fileCollection.videos.length) { + fileCollection.videos.forEach(video => { + video.imdbId = imdbId || ''; + video.kitsuId = kitsuId || 0; + }); + } + + return fileCollection; + }; + + private overwriteExistingFiles = async (torrent: IParsedTorrent, torrentContents: ITorrentFileCollection): Promise => { + const videos = torrentContents && torrentContents.videos; + if (videos && videos.length) { + const existingFiles = await this.repository.getFiles(torrent.infoHash) + .then((existing) => existing.reduce<{ [key: number]: File[] }>((map, next) => { + const fileIndex = next.fileIndex !== undefined ? next.fileIndex : null; + if (fileIndex !== null) { + map[fileIndex] = (map[fileIndex] || []).concat(next); + } + return map; + }, {})) + .catch(() => undefined); + if (existingFiles && Object.keys(existingFiles).length) { + const overwrittenVideos = videos + .map(file => { + const index = file.fileIndex !== undefined ? file.fileIndex : null; + let mapping; + if (index !== null) { + mapping = videos.length === 1 && Object.keys(existingFiles).length === 1 + ? Object.values(existingFiles)[0] + : existingFiles[index]; + } + if (mapping) { + const originalFile = mapping.shift(); + return {id: originalFile!.id, ...file}; + } + return file; + }); + return {...torrentContents, videos: overwrittenVideos}; + } + return torrentContents; + } + return Promise.reject(`No video files found for: ${torrent.title}`); + }; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/services/torrent_file_service.ts b/src/node/consumer/src/lib/services/torrent_file_service.ts new file mode 100644 index 0000000..60efe4d --- /dev/null +++ b/src/node/consumer/src/lib/services/torrent_file_service.ts @@ -0,0 +1,733 @@ +import {TorrentType} from '@enums/torrent_types'; +import {ExtensionHelpers} from '@helpers/extension_helpers'; +import {PromiseHelpers} from '@helpers/promises_helpers'; +import {ICommonVideoMetadata} from "@interfaces/common_video_metadata"; +import {ILoggingService} from "@interfaces/logging_service"; +import {IMetaDataQuery} from "@interfaces/metadata_query"; +import {IMetadataResponse} from "@interfaces/metadata_response"; +import {IMetadataService} from "@interfaces/metadata_service"; +import {IParsedTorrent} from "@interfaces/parsed_torrent"; +import {ITorrentDownloadService} from "@interfaces/torrent_download_service"; +import {ITorrentFileCollection} from "@interfaces/torrent_file_collection"; +import {ITorrentFileService} from "@interfaces/torrent_file_service"; +import {IContentAttributes} from "@repository/interfaces/content_attributes"; +import {IFileAttributes} from "@repository/interfaces/file_attributes"; +import {configurationService} from '@services/configuration_service'; +import {IocTypes} from "@setup/ioc_types"; +import Bottleneck from 'bottleneck'; +import {inject, injectable} from "inversify"; +import moment from 'moment'; +import {parse} from 'parse-torrent-title'; + +const MIN_SIZE: number = 5 * 1024 * 1024; // 5 MB +const MULTIPLE_FILES_SIZE = 4 * 1024 * 1024 * 1024; // 4 GB + +type SeasonEpisodeMap = Record>; + +@injectable() +export class TorrentFileService implements ITorrentFileService { + @inject(IocTypes.IMetadataService) metadataService: IMetadataService; + @inject(IocTypes.ITorrentDownloadService) torrentDownloadService: ITorrentDownloadService; + @inject(IocTypes.ILoggingService) logger: ILoggingService; + + private readonly imdb_limiter: Bottleneck = new Bottleneck({ + maxConcurrent: configurationService.metadataConfig.IMDB_CONCURRENT, + minTime: configurationService.metadataConfig.IMDB_INTERVAL_MS + }); + + async parseTorrentFiles(torrent: IParsedTorrent): Promise { + if (!torrent.title) { + return Promise.reject(new Error('Torrent title is missing')); + } + + if (!torrent.infoHash) { + return Promise.reject(new Error('Torrent infoHash is missing')); + } + + const parsedTorrentName = parse(torrent.title); + const query: IMetaDataQuery = { + id: torrent.kitsuId || torrent.imdbId, + type: torrent.type || TorrentType.Movie, + }; + const metadata = await this.metadataService.getMetadata(query) + .then(meta => Object.assign({}, meta)) + .catch(() => undefined); + + if (metadata === undefined || metadata instanceof Error) { + return Promise.reject(new Error('Failed to retrieve metadata')); + } + + if (torrent.type !== TorrentType.Anime && metadata && metadata.type && metadata.type !== torrent.type) { + // it's actually a movie/series + torrent.type = metadata.type; + } + + if (torrent.type === TorrentType.Movie && (!parsedTorrentName.seasons || + parsedTorrentName.season === 5 && [1, 5].includes(parsedTorrentName.episode || 0))) { + return this.parseMovieFiles(torrent, metadata); + } + + return this.parseSeriesFiles(torrent, metadata) + } + + isPackTorrent(torrent: IParsedTorrent): boolean { + if (torrent.isPack) { + return true; + } + if (!torrent.title) { + return false; + } + const parsedInfo = parse(torrent.title); + if (torrent.type === TorrentType.Movie) { + return parsedInfo.complete || typeof parsedInfo.year === 'string' || /movies/i.test(torrent.title); + } + + const hasMultipleEpisodes = Boolean(parsedInfo.complete || torrent.size || 0 > MULTIPLE_FILES_SIZE || + (parsedInfo.seasons && parsedInfo.seasons.length > 1) || + (parsedInfo.episodes && parsedInfo.episodes.length > 1) || + (parsedInfo.seasons && !parsedInfo.episodes)); + + const hasSingleEpisode: boolean = Boolean(Number.isInteger(parsedInfo.episode) || (!parsedInfo.episodes && parsedInfo.date)); + + return hasMultipleEpisodes && !hasSingleEpisode; + } + + private parseSeriesVideos = (torrent: IParsedTorrent, videos: IFileAttributes[]): IFileAttributes[] => { + const parsedTorrentName = parse(torrent.title!); + const hasMovies = parsedTorrentName.complete || !!torrent.title!.match(/movies?(?:\W|$)/i); + const parsedVideos = videos.map(video => this.parseSeriesVideo(video)); + + return parsedVideos.map(video => ({...video, isMovie: this.isMovieVideo(torrent, video, parsedVideos, hasMovies)})); + }; + + private parseMovieFiles = async (torrent: IParsedTorrent, metadata: IMetadataResponse): Promise => { + const fileCollection: ITorrentFileCollection = await this.getMoviesTorrentContent(torrent); + if (fileCollection.videos === undefined || fileCollection.videos.length === 0) { + return {...fileCollection, videos: this.getDefaultFileEntries(torrent)}; + } + + const filteredVideos = fileCollection.videos + .filter(video => video.size! > MIN_SIZE) + .filter(video => !this.isFeaturette(video)); + if (this.isSingleMovie(filteredVideos)) { + const parsedVideos = filteredVideos.map(video => ({ + infoHash: torrent.infoHash, + fileIndex: video.fileIndex, + title: video.title || video.path || video.fileName || '', + size: video.size || torrent.size, + imdbId: torrent.imdbId?.toString() || metadata && metadata.imdbId?.toString(), + kitsuId: parseInt(torrent.kitsuId?.toString() || metadata && metadata.kitsuId?.toString() || '0') + })); + return {...fileCollection, videos: parsedVideos}; + } + + const parsedVideos = await PromiseHelpers.sequence(filteredVideos.map(video => () => this.isFeaturette(video) + ? Promise.resolve(video) + : this.findMovieImdbId(video.title).then(imdbId => ({...video, imdbId: imdbId?.toString() || ''})))) + .then(videos => videos.map((video: IFileAttributes) => ({ + infoHash: torrent.infoHash, + fileIndex: video.fileIndex, + title: video.title || video.path, + size: video.size, + imdbId: video.imdbId, + }))); + return {...fileCollection, videos: parsedVideos}; + }; + + private parseSeriesFiles = async (torrent: IParsedTorrent, metadata: IMetadataResponse): Promise => { + const fileCollection: ITorrentFileCollection = await this.getSeriesTorrentContent(torrent); + if (fileCollection.videos === undefined || fileCollection.videos.length === 0) { + return {...fileCollection, videos: this.getDefaultFileEntries(torrent)}; + } + + const parsedVideos: IFileAttributes[] = await Promise.resolve(fileCollection.videos) + .then(videos => videos.filter(video => videos?.length === 1 || video.size! > MIN_SIZE)) + .then(videos => this.parseSeriesVideos(torrent, videos)) + .then(videos => this.decomposeEpisodes(torrent, videos, metadata)) + .then(videos => this.assignKitsuOrImdbEpisodes(torrent, videos, metadata)) + .then(videos => Promise.all(videos.map(video => video.isMovie + ? this.mapSeriesMovie(torrent, video) + : this.mapSeriesEpisode(torrent, video, videos)))) + .then(videos => videos + .reduce((a, b) => a.concat(b), []) + .map(video => this.isFeaturette(video) ? this.clearInfoFields(video) : video)); + return {...torrent.fileCollection, videos: parsedVideos}; + }; + + private getMoviesTorrentContent = async (torrent: IParsedTorrent): Promise => { + const files = await this.torrentDownloadService.getTorrentFiles(torrent, configurationService.torrentConfig.TIMEOUT) + .catch(error => { + if (!this.isPackTorrent(torrent)) { + const entries = this.getDefaultFileEntries(torrent); + return {videos: entries, contents: [], subtitles: [], files: entries} + } + return Promise.reject(error); + }); + + if (files.contents && files.contents.length && !files.videos?.length && this.isDiskTorrent(files.contents)) { + files.videos = this.getDefaultFileEntries(torrent); + } + + return files; + }; + + private getDefaultFileEntries = (torrent: IParsedTorrent): IFileAttributes[] => [{ + title: torrent.title!, + path: torrent.title, + size: torrent.size, + fileIndex: 0, + }]; + + private getSeriesTorrentContent = async (torrent: IParsedTorrent): Promise => this.torrentDownloadService.getTorrentFiles(torrent, configurationService.torrentConfig.TIMEOUT) + .catch(error => { + if (!this.isPackTorrent(torrent)) { + return {videos: this.getDefaultFileEntries(torrent), subtitles: [], contents: []} + } + return Promise.reject(error); + }); + + private mapSeriesEpisode = async (torrent: IParsedTorrent, file: IFileAttributes, files: IFileAttributes[]): Promise => { + if (!file.episodes && !file.episodes) { + if (files.length === 1 || files.some(f => f.episodes || f.episodes) || parse(torrent.title!).seasons) { + return Promise.resolve([{ + infoHash: torrent.infoHash, + fileIndex: file.fileIndex, + title: file.path || file.title, + size: file.size, + imdbId: torrent?.imdbId?.toString() || file?.imdbId?.toString() || '', + }]); + } + return Promise.resolve([]); + } + const episodeIndexes = [...(file.episodes || file.episodes).keys()]; + return Promise.resolve(episodeIndexes.map((index) => ({ + infoHash: torrent.infoHash, + fileIndex: file.fileIndex, + title: file.path || file.title, + size: file.size, + imdbId: file?.imdbId?.toString() || torrent?.imdbId?.toString() || '', + imdbSeason: file.season, + season: file.season, + imdbEpisode: file.episodes && file.episodes[index], + episode: file.episodes && file.episodes[index], + kitsuEpisode: file.episodes && file.episodes[index], + episodes: file.episodes, + kitsuId: parseInt(file.kitsuId?.toString() || torrent.kitsuId?.toString() || '0') || 0, + }))) + }; + + private mapSeriesMovie = async (torrent: IParsedTorrent, file: IFileAttributes): Promise => { + const kitsuId = torrent.type === TorrentType.Anime ? await this.findMovieKitsuId(file) + .then(result => { + if (result instanceof Error) { + this.logger.warn(`Failed to retrieve kitsuId due to error: ${result.message}`); + return undefined; + } + return result; + }) : undefined; + + const imdbId = !kitsuId ? await this.findMovieImdbId(file) : undefined; + + const query: IMetaDataQuery = { + id: kitsuId || imdbId, + type: TorrentType.Movie + }; + + const metadataOrError = await this.metadataService.getMetadata(query); + if (metadataOrError instanceof Error) { + this.logger.warn(`Failed to retrieve metadata due to error: ${metadataOrError.message}`); + // return default result or throw error, depending on your use case + return [{ + infoHash: torrent.infoHash, + fileIndex: file.fileIndex, + title: file.path || file.title, + size: file.size, + imdbId: imdbId, + kitsuId: parseInt(kitsuId?.toString() || '0') || 0, + episodes: undefined, + imdbSeason: undefined, + imdbEpisode: undefined, + kitsuEpisode: undefined + }]; + } + // at this point, TypeScript infers that metadataOrError is actually MetadataResponse + const metadata = metadataOrError; + const hasEpisode = metadata.videos && metadata.videos.length && (file.episode || metadata.videos.length === 1); + const episodeVideo = hasEpisode && metadata.videos && metadata.videos[(file.episode || 1) - 1]; + return [{ + infoHash: torrent.infoHash, + fileIndex: file.fileIndex, + title: file.path || file.title, + size: file.size, + imdbId: metadata.imdbId?.toString() || imdbId || '', + kitsuId: parseInt(metadata.kitsuId?.toString() || kitsuId?.toString() || '0') || 0, + imdbSeason: episodeVideo && metadata.imdbId ? episodeVideo.season : undefined, + imdbEpisode: episodeVideo && metadata.imdbId || episodeVideo && metadata.kitsuId ? episodeVideo.episode || episodeVideo.episode : undefined, + kitsuEpisode: episodeVideo && metadata.imdbId || episodeVideo && metadata.kitsuId ? episodeVideo.episode || episodeVideo.episode : undefined, + }]; + }; + + private decomposeEpisodes = async (torrent: IParsedTorrent, files: IFileAttributes[], metadata: IMetadataResponse = {episodeCount: []}): Promise => { + if (files.every(file => !file.episodes && !file.date)) { + return files; + } + + this.preprocessEpisodes(files); + + if (torrent.type === TorrentType.Anime && torrent.kitsuId) { + if (this.needsCinemetaMetadataForAnime(files, metadata)) { + // In some cases anime could be resolved to wrong kitsuId + // because of imdb season naming/absolute per series naming/multiple seasons + // So in these cases we need to fetch cinemeta based metadata and decompose episodes using that + await this.updateToCinemetaMetadata(metadata); + if (files.some(file => Number.isInteger(file.season))) { + // sometimes multi season anime torrents don't include season 1 naming + files + .filter(file => !Number.isInteger(file.season) && file.episodes) + .forEach(file => file.season = 1); + } + } else { + // otherwise for anime type episodes are always absolute and for a single season + files + .filter(file => file.episodes && file.season !== 0) + .forEach(file => file.season = 1); + return files; + } + } + + const sortedEpisodes = files + .map(file => !file.isMovie && file.episodes || []) + .reduce((a, b) => a.concat(b), []) + .sort((a, b) => a - b); + + if (this.isConcatSeasonAndEpisodeFiles(files, sortedEpisodes, metadata)) { + this.decomposeConcatSeasonAndEpisodeFiles(files, metadata); + } else if (this.isDateEpisodeFiles(files, metadata)) { + this.decomposeDateEpisodeFiles(files, metadata); + } else if (this.isAbsoluteEpisodeFiles(torrent, files, metadata)) { + this.decomposeAbsoluteEpisodeFiles(torrent, files, metadata); + } + // decomposeEpisodeTitleFiles(torrent, files, metadata); + + return files; + }; + + private preprocessEpisodes = (files: IFileAttributes[]): void => { + // reverse special episode naming when they named with 0 episode, ie. S02E00 + files + .filter(file => Number.isInteger(file.season) && file.episode === 0) + .forEach(file => { + file.episode = file.season + file.episodes = [file.season || 0]; + file.season = 0; + }) + }; + + private isConcatSeasonAndEpisodeFiles = (files: IFileAttributes[], sortedEpisodes: number[], metadata: IMetadataResponse): boolean => { + if (metadata.kitsuId !== undefined) { + // anime does not use this naming scheme in 99% of cases; + return false; + } + // decompose concat season and episode files (ex. 101=S01E01) in case: + // 1. file has a season, but individual files are concatenated with that season (ex. path Season 5/511 - Prize + // Fighters.avi) + // 2. file does not have a season and the episode does not go out of range for the concat season + // episode count + const thresholdAbove = Math.max(Math.ceil(files.length * 0.05), 5); + const thresholdSorted = Math.max(Math.ceil(files.length * 0.8), 8); + const threshold = Math.max(Math.ceil(files.length * 0.8), 5); + const sortedConcatEpisodes = sortedEpisodes + .filter(ep => ep > 100) + .filter(ep => metadata.episodeCount && metadata.episodeCount[this.div100(ep) - 1] < ep) + .filter(ep => metadata.episodeCount && metadata.episodeCount[this.div100(ep) - 1] >= this.mod100(ep)); + const concatFileEpisodes = files + .filter(file => !file.isMovie && file.episodes) + .filter(file => !file.season || file.episodes?.every(ep => this.div100(ep) === file.season)); + const concatAboveTotalEpisodeCount = files + .filter(file => !file.isMovie && file.episodes && file.episodes.every(ep => ep > 100)) + .filter(file => file.episodes?.every(ep => ep > metadata.totalCount!)); + return sortedConcatEpisodes.length >= thresholdSorted && concatFileEpisodes.length >= threshold + || concatAboveTotalEpisodeCount.length >= thresholdAbove; + }; + + private isDateEpisodeFiles = (files: IFileAttributes[], metadata: IMetadataResponse): boolean => files.every(file => (!file.season || metadata.episodeCount && !metadata.episodeCount[file.season - 1]) && file.date); + + private isAbsoluteEpisodeFiles = (torrent: IParsedTorrent, files: IFileAttributes[], metadata: IMetadataResponse): boolean => { + const threshold = Math.ceil(files.length / 5); + const isAnime = torrent.type === TorrentType.Anime && torrent.kitsuId; + const nonMovieEpisodes = files.filter(file => !file.isMovie && file.episodes); + const absoluteEpisodes = files + .filter(file => file.season && file.episodes) + .filter(file => file.episodes?.every(ep => + metadata.episodeCount && file.season && metadata.episodeCount[file.season - 1] < ep)); + return nonMovieEpisodes.every(file => !file.season) + || (isAnime && nonMovieEpisodes.every(file => + metadata.episodeCount && file.season && file.season > metadata.episodeCount.length)) + || absoluteEpisodes.length >= threshold; + }; + + private isNewEpisodeNotInMetadata = (torrent: IParsedTorrent, video: IFileAttributes, metadata: IMetadataResponse): boolean => { + const isAnime = torrent.type === TorrentType.Anime && torrent.kitsuId; + return !!(!isAnime && !video.isMovie && video.episodes && video.season !== 1 + && metadata.status && /continuing|current/i.test(metadata.status) + && metadata.episodeCount && video.season && video.season >= metadata.episodeCount.length + && video.episodes.every(ep => metadata.episodeCount && video.season && ep > (metadata.episodeCount[video.season - 1] || 0))); + }; + + private decomposeConcatSeasonAndEpisodeFiles = (files: IFileAttributes[], metadata: IMetadataResponse): void => { + files + .filter(file => file.episodes && file.season !== 0 && file.episodes.every(ep => ep > 100)) + .filter(file => file.episodes && metadata?.episodeCount && + ((file.season || this.div100(file.episodes[0])) - 1) >= 0 && + metadata.episodeCount[(file.season || this.div100(file.episodes[0])) - 1] < 100) + .filter(file => (file.season && file.episodes && file.episodes.every(ep => this.div100(ep) === file.season)) || !file.season) + .forEach(file => { + if (file.episodes) { + file.season = this.div100(file.episodes[0]); + file.episodes = file.episodes.map(ep => this.mod100(ep)); + } + }); + }; + + private decomposeAbsoluteEpisodeFiles = (torrent: IParsedTorrent, videos: IFileAttributes[], metadata: IMetadataResponse): void => { + if (metadata.episodeCount?.length === 0) { + videos + .filter(file => !Number.isInteger(file.season) && file.episodes && !file.isMovie) + .forEach(file => { + file.season = 1; + }); + return; + } + if (!metadata.episodeCount) return; + + videos + .filter(file => file.episodes && !file.isMovie && file.season !== 0) + .filter(file => !this.isNewEpisodeNotInMetadata(torrent, file, metadata)) + .filter(file => { + if (!file.episodes || !metadata.episodeCount) return false; + return !file.season || (metadata.episodeCount[file.season - 1] || 0) < file.episodes[0]; + }) + .forEach(file => { + if (!file.episodes || !metadata.episodeCount) return; + + let seasonIdx = metadata.episodeCount + .map((_, i) => i) + .find(i => metadata.episodeCount && file.episodes && metadata.episodeCount.slice(0, i + 1).reduce((a, b) => a + b) >= file.episodes[0]); + + seasonIdx = (seasonIdx || 1 || metadata.episodeCount.length) - 1; + + file.season = seasonIdx + 1; + file.episodes = file.episodes + .map(ep => ep - (metadata.episodeCount?.slice(0, seasonIdx).reduce((a, b) => a + b, 0) || 0)); + }); + }; + + private decomposeDateEpisodeFiles = (files: IFileAttributes[], metadata: IMetadataResponse): void => { + if (!metadata || !metadata.videos || !metadata.videos.length) { + return; + } + + const timeZoneOffset = this.getTimeZoneOffset(metadata.country); + const offsetVideos: { [key: string]: ICommonVideoMetadata } = metadata.videos + .reduce((map: { [key: string]: ICommonVideoMetadata }, video: ICommonVideoMetadata) => { + const releaseDate = moment(video.released).utcOffset(timeZoneOffset).format('YYYY-MM-DD'); + map[releaseDate] = video; + return map; + }, {}); + + files + .filter(file => file.date) + .forEach(file => { + const video = offsetVideos[file.date!]; + if (video) { + file.season = video.season; + file.episodes = [video.episode || 0]; + } + }); + }; + + private getTimeZoneOffset = (country: string | undefined): string => { + switch (country) { + case 'United States': + case 'USA': + return '-08:00'; + default: + return '00:00'; + } + }; + + private assignKitsuOrImdbEpisodes = (torrent: IParsedTorrent, files: IFileAttributes[], metadata: IMetadataResponse): IFileAttributes[] => { + if (!metadata || !metadata.videos || !metadata.videos.length) { + if (torrent.type === TorrentType.Anime) { + // assign episodes as kitsu episodes for anime when no metadata available for imdb mapping + files + .filter(file => file.season && file.episodes) + .forEach(file => { + file.season = undefined; + file.episodes = undefined; + }) + if (metadata.type === TorrentType.Movie && files.every(file => !file.imdbId)) { + // sometimes a movie has episode naming, thus not recognized as a movie and imdbId not assigned + files.forEach(file => file.imdbId = metadata.imdbId?.toString()); + } + } + return files; + } + + const seriesMapping = metadata.videos + .filter(video => video.season !== undefined && Number.isInteger(video.season) && video.episode !== undefined && Number.isInteger(video.episode)) + .reduce((map, video) => { + if (video.season !== undefined && video.episode !== undefined) { + const episodeMap = map[video.season] || {}; + episodeMap[video.episode] = video; + map[video.season] = episodeMap; + } + return map; + }, {}); + + + if (metadata.videos.some(video => Number.isInteger(video.season)) || !metadata.imdbId) { + files.filter(file => file && Number.isInteger(file.season) && file.episodes) + .map(file => { + const seasonMapping = file && file.season && seriesMapping[file.season] || null; + const episodeMapping = seasonMapping && file && file.episodes && file.episodes[0] && seasonMapping[file.episodes[0]] || null; + + if (episodeMapping && Number.isInteger(episodeMapping.season)) { + file.imdbId = metadata.imdbId?.toString(); + file.season = episodeMapping.season; + file.episodes = file.episodes && file.episodes.map(ep => (seasonMapping && seasonMapping[ep]) ? Number(seasonMapping[ep].episode) : 0); + } else { + file.season = undefined; + file.episodes = undefined; + } + }); + } else if (metadata.videos.some(video => video.episode)) { + // imdb episode info is base + files + .filter(file => Number.isInteger(file.season) && file.episodes) + .forEach(file => { + if (!file.season || !file.episodes) { + return; + } + if (seriesMapping[file.season]) { + + const seasonMapping = seriesMapping[file.season]; + file.imdbId = metadata.imdbId?.toString(); + file.kitsuId = seasonMapping[file.episodes[0]] && parseInt(seasonMapping[file.episodes[0]].id || '0') || 0; + file.episodes = file.episodes.map(ep => seasonMapping[ep]?.episode) + .filter((ep): ep is number => ep !== undefined); + } else if (seriesMapping[file.season - 1]) { + // sometimes a second season might be a continuation of the previous season + const seasonMapping = seriesMapping[file.season - 1] as ICommonVideoMetadata; + const episodes = Object.values(seasonMapping); + const firstKitsuId = episodes.length && episodes[0]; + const differentTitlesCount = new Set(episodes.map(ep => ep.id)).size + const skippedCount = episodes.filter(ep => ep.id === firstKitsuId).length; + const emptyArray: number[] = []; + const seasonEpisodes = files + .filter((otherFile: IFileAttributes) => otherFile.season === file.season && otherFile.episodes) + .reduce((a, b) => a.concat(b.episodes || []), emptyArray); + const isAbsoluteOrder = seasonEpisodes.every(ep => ep > skippedCount && ep <= episodes.length) + const isNormalOrder = seasonEpisodes.every(ep => ep + skippedCount <= episodes.length) + if (differentTitlesCount >= 1 && (isAbsoluteOrder || isNormalOrder)) { + const {season} = file; + const [episode] = file.episodes; + file.imdbId = metadata.imdbId?.toString(); + file.season = file.season - 1; + file.episodes = file.episodes.map(ep => isAbsoluteOrder ? ep : ep + skippedCount); + const currentEpisode = seriesMapping[season][episode]; + file.kitsuId = currentEpisode ? parseInt(currentEpisode.id || '0') : 0; + if (typeof season === 'number' && Array.isArray(file.episodes)) { + file.episodes = file.episodes.map(ep => + seriesMapping[season] + && seriesMapping[season][ep] + && seriesMapping[season][ep].episode + || ep); + } + } + } else if (Object.values(seriesMapping).length === 1 && seriesMapping[1]) { + // sometimes series might be named with sequel season but it's not a season on imdb and a new title + // eslint-disable-next-line prefer-destructuring + const seasonMapping = seriesMapping[1]; + file.imdbId = metadata.imdbId?.toString(); + file.season = 1; + file.kitsuId = parseInt(seasonMapping[file.episodes[0]].id || '0') || 0; + file.episodes = file.episodes.map(ep => seasonMapping[ep] && seasonMapping[ep].episode) + .filter((ep): ep is number => ep !== undefined); + } + }); + } + return files; + }; + + private needsCinemetaMetadataForAnime = (files: IFileAttributes[], metadata: IMetadataResponse): boolean => { + if (!metadata || !metadata.imdbId || !metadata.videos || !metadata.videos.length) { + return false; + } + + const seasons = metadata.videos + .map(video => video.season) + .filter((season): season is number => season !== null && season !== undefined); + + // Using || 0 instead of || Number.MAX_VALUE to match previous logic + const minSeason = Math.min(...seasons) || 0; + const maxSeason = Math.max(...seasons) || 0; + const differentSeasons = new Set(seasons.filter(season => Number.isInteger(season))).size; + + const total = metadata.totalCount || Number.MAX_VALUE; + + return differentSeasons > 1 || files + .filter(file => !file.isMovie && file.episodes) + .some(file => file.season || 0 < minSeason || file.season || 0 > maxSeason || file.episodes?.every(ep => ep > total)); + }; + + private updateToCinemetaMetadata = async (metadata: IMetadataResponse): Promise => { + const query: IMetaDataQuery = { + id: metadata.imdbId, + type: metadata.type + }; + + return await this.metadataService.getMetadata(query) + .then((newMetadataOrError) => { + if (newMetadataOrError instanceof Error) { + // handle error + this.logger.warn(`Failed ${metadata.imdbId} metadata cinemeta update due: ${newMetadataOrError.message}`); + return metadata; // or throw newMetadataOrError to propagate error up the call stack + } + // At this point TypeScript infers newMetadataOrError to be of type MetadataResponse + const newMetadata = newMetadataOrError; + if (!newMetadata.videos || !newMetadata.videos.length) { + return metadata; + } else { + metadata.videos = newMetadata.videos; + metadata.episodeCount = newMetadata.episodeCount; + metadata.totalCount = newMetadata.totalCount; + return metadata; + } + }) + }; + + private findMovieImdbId = (title: IFileAttributes | string): Promise => { + const parsedTitle = typeof title === 'string' ? parse(title) : title; + this.logger.debug(`Finding movie imdbId for ${title}`); + return this.imdb_limiter.schedule(async () => { + const imdbQuery = { + title: parsedTitle.title, + year: parsedTitle.year, + type: TorrentType.Movie + }; + try { + return await this.metadataService.getImdbId(imdbQuery); + } catch (e) { + return undefined; + } + }); + }; + + private findMovieKitsuId = async (title: IFileAttributes | string): Promise => { + const parsedTitle = typeof title === 'string' ? parse(title) : title; + const kitsuQuery = { + title: parsedTitle.title, + year: parsedTitle.year, + season: parsedTitle.season, + type: TorrentType.Movie + }; + try { + return await this.metadataService.getKitsuId(kitsuQuery); + } catch (e) { + return undefined; + } + }; + + private isDiskTorrent = (contents: IContentAttributes[]): boolean => contents.some(content => ExtensionHelpers.isDisk(content.path)); + + private isSingleMovie = (videos: IFileAttributes[]): boolean => videos.length === 1 || + (videos.length === 2 && + videos.find(v => /\b(?:part|disc|cd)[ ._-]?0?1\b|^0?1\.\w{2,4}$/i.test(v.path!)) && + videos.find(v => /\b(?:part|disc|cd)[ ._-]?0?2\b|^0?2\.\w{2,4}$/i.test(v.path!))) !== undefined; + + private isFeaturette = (video: IFileAttributes): boolean => /featurettes?\/|extras-grym/i.test(video.path!); + + private parseSeriesVideo = (video: IFileAttributes): IFileAttributes => { + const videoInfo = parse(video.title); + // the episode may be in a folder containing season number + if (!Number.isInteger(videoInfo.season) && video.path?.includes('/')) { + const folders = video.path?.split('/'); + const pathInfo = parse(folders[folders.length - 2]); + videoInfo.season = pathInfo.season; + } + if (!Number.isInteger(videoInfo.season) && video.season) { + videoInfo.season = video.season; + } + if (!Number.isInteger(videoInfo.season) && videoInfo.seasons && videoInfo.seasons.length > 1) { + // in case single file was interpreted as having multiple seasons + [videoInfo.season] = videoInfo.seasons; + } + if (!Number.isInteger(videoInfo.season) && video.path?.includes('/') && video.seasons + && video.seasons.length > 1) { + // russian season are usually named with 'series name-2` i.e. Улицы разбитых фонарей-6/22. Одиночный выстрел.mkv + const folderPathSeasonMatch = video.path?.match(/[\u0400-\u04ff]-(\d{1,2})(?=.*\/)/); + videoInfo.season = folderPathSeasonMatch && parseInt(folderPathSeasonMatch[1], 10) || undefined; + } + // sometimes video file does not have correct date format as in torrent title + if (!videoInfo.episodes && !videoInfo.date && video.date) { + videoInfo.date = video.date; + } + // limit number of episodes in case of incorrect parsing + if (videoInfo.episodes && videoInfo.episodes.length > 20) { + videoInfo.episodes = [videoInfo.episodes[0]]; + [videoInfo.episode] = videoInfo.episodes; + } + // force episode to any found number if it was not parsed + if (!videoInfo.episodes && !videoInfo.date) { + const epMatcher = videoInfo.title.match( + /(? { + if (Number.isInteger(torrent.season) && Array.isArray(torrent.episodes)) { + // not movie if video has season + return false; + } + if (torrent.title?.match(/\b(?:\d+[ .]movie|movie[ .]\d+)\b/i)) { + // movie if video explicitly has numbered movie keyword in the name, ie. 1 Movie or Movie 1 + return true; + } + if (!hasMovies && torrent.type !== TorrentType.Anime) { + // not movie if torrent name does not contain movies keyword or is not a pack torrent and is not anime + return false; + } + if (!torrent.episodes) { + // movie if there's no episode info it could be a movie + return true; + } + // movie if contains year info and there aren't more than 3 video with same title and year + // as some series titles might contain year in it. + return !!torrent.year + && otherVideos.length > 3 + && otherVideos.filter(other => other.title === video.title && other.year === video.year).length < 3; + }; + + private clearInfoFields = (video: IFileAttributes): IFileAttributes => { + video.imdbId = undefined; + video.imdbSeason = undefined; + video.imdbEpisode = undefined; + video.kitsuId = undefined; + video.kitsuEpisode = undefined; + return video; + }; + + private div100 = (episode: number): number => (episode / 100 >> 0); + + private mod100 = (episode: number): number => episode % 100; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/services/torrent_processing_service.ts b/src/node/consumer/src/lib/services/torrent_processing_service.ts new file mode 100644 index 0000000..a68ac03 --- /dev/null +++ b/src/node/consumer/src/lib/services/torrent_processing_service.ts @@ -0,0 +1,59 @@ +import {TorrentType} from "@enums/torrent_types"; +import {ILoggingService} from "@interfaces/logging_service"; +import {IParsedTorrent} from "@interfaces/parsed_torrent"; +import {ITorrentEntriesService} from "@interfaces/torrent_entries_service"; +import {ITorrentProcessingService} from "@interfaces/torrent_processing_service"; +import {ITrackerService} from "@interfaces/tracker_service"; +import {IIngestedTorrentAttributes} from "@repository/interfaces/ingested_torrent_attributes"; +import {IocTypes} from "@setup/ioc_types"; +import {inject, injectable} from "inversify"; + +@injectable() +export class TorrentProcessingService implements ITorrentProcessingService { + @inject(IocTypes.ITorrentEntriesService) torrentEntriesService: ITorrentEntriesService; + @inject(IocTypes.ILoggingService) logger: ILoggingService; + @inject(IocTypes.ITrackerService) trackerService: ITrackerService; + + async processTorrentRecord(torrent: IIngestedTorrentAttributes): Promise { + const {category} = torrent; + const type = category === 'tv' ? TorrentType.Series : TorrentType.Movie; + const torrentInfo: IParsedTorrent = await this.parseTorrent(torrent, type); + + this.logger.info(`Processing torrent ${torrentInfo.title} with infoHash ${torrentInfo.infoHash}`); + + if (await this.torrentEntriesService.checkAndUpdateTorrent(torrentInfo)) { + return; + } + + return this.torrentEntriesService.createTorrentEntry(torrentInfo, false); + } + + private assignTorrentTrackers = async (): Promise => { + const trackers = await this.trackerService.getTrackers(); + return trackers.join(','); + } + + private parseTorrent = async (torrent: IIngestedTorrentAttributes, category: string): Promise => { + const infoHash = torrent.info_hash?.trim().toLowerCase() + return { + title: torrent.name, + torrentId: `${torrent.name}_${infoHash}`, + infoHash: infoHash, + seeders: 100, + size: parseInt(torrent.size), + uploadDate: torrent.createdAt, + imdbId: this.parseImdbId(torrent), + type: category, + provider: torrent.source, + trackers: await this.assignTorrentTrackers(), + } + }; + + private parseImdbId = (torrent: IIngestedTorrentAttributes): string | undefined => { + if (torrent.imdb === undefined || torrent.imdb === null) { + return undefined; + } + + return torrent.imdb; + }; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/services/torrent_subtitle_service.ts b/src/node/consumer/src/lib/services/torrent_subtitle_service.ts new file mode 100644 index 0000000..5a678a9 --- /dev/null +++ b/src/node/consumer/src/lib/services/torrent_subtitle_service.ts @@ -0,0 +1,107 @@ +import {ITorrentFileCollection} from "@interfaces/torrent_file_collection"; +import {ITorrentSubtitleService} from "@interfaces/torrent_subtitle_service"; +import {IFileAttributes} from "@repository/interfaces/file_attributes"; +import {ISubtitleAttributes} from "@repository/interfaces/subtitle_attributes"; +import {injectable} from "inversify"; +import {parse} from 'parse-torrent-title'; + +@injectable() +export class TorrentSubtitleService implements ITorrentSubtitleService { + assignSubtitles(fileCollection: ITorrentFileCollection): ITorrentFileCollection { + if (fileCollection.videos && fileCollection.videos.length && fileCollection.subtitles && fileCollection.subtitles.length) { + if (fileCollection.videos.length === 1) { + const matchingSubtitles = fileCollection.subtitles.filter(subtitle => + this.mostProbableSubtitleVideos(subtitle, [fileCollection.videos[0]]).length > 0 + ); + fileCollection.videos[0].subtitles = matchingSubtitles; + const nonMatchingSubtitles = fileCollection.subtitles.filter(subtitle => + !matchingSubtitles.includes(subtitle) + ); + return {...fileCollection, subtitles: nonMatchingSubtitles}; + } + + const parsedVideos = fileCollection.videos.map(video => this.parseVideo(video)); + const assignedSubs = fileCollection.subtitles.map(subtitle => ({ + subtitle, + videos: this.mostProbableSubtitleVideos(subtitle, parsedVideos) + })); + const unassignedSubs = assignedSubs.filter(assignedSub => !assignedSub.videos).map(assignedSub => assignedSub.subtitle); + + assignedSubs + .filter(assignedSub => assignedSub.videos) + .forEach(assignedSub => assignedSub.videos.forEach(video => video.subtitles = (video.subtitles || []).concat(assignedSub.subtitle))); + return {...fileCollection, subtitles: unassignedSubs}; + } + return fileCollection; + } + + private parseVideo = (video: IFileAttributes): IFileAttributes => { + const fileName = video.title?.split('/')?.pop()?.replace(/\.(\w{2,4})$/, '') || ''; + const folderName = video.title?.replace(/\/?[^/]+$/, '') || ''; + return Object.assign(video, { + fileName: fileName, + folderName: folderName, + ...this.parseFilename(video.title.toString() || '') + }); + } + + private mostProbableSubtitleVideos = (subtitle: ISubtitleAttributes, parsedVideos: IFileAttributes[]): IFileAttributes[] => { + const subTitle = (subtitle.title || subtitle.path)?.split('/')?.pop()?.replace(/\.(\w{2,4})$/, '') || ''; + const parsedSub = this.parsePath(subtitle.title || subtitle.path); + const byFileName = parsedVideos.filter(video => subTitle.includes(video.title!)); + if (byFileName.length === 1) { + return byFileName.map(v => v); + } + const byTitleSeasonEpisode = parsedVideos.filter(video => video.title === parsedSub.title + && parsedSub.seasons && parsedSub.episodes + && this.arrayEquals(video.seasons || [], parsedSub.seasons) + && this.arrayEquals(video.episodes || [], parsedSub.episodes)); + if (this.singleVideoFile(byTitleSeasonEpisode)) { + return byTitleSeasonEpisode.map(v => v); + } + const bySeasonEpisode = parsedVideos.filter(video => parsedSub.seasons && parsedSub.episodes + && this.arrayEquals(video.seasons || [], parsedSub.seasons) + && this.arrayEquals(video.episodes || [], parsedSub.episodes)); + if (this.singleVideoFile(bySeasonEpisode)) { + return bySeasonEpisode.map(v => v); + } + const byTitle = parsedVideos.filter(video => video.title && video.title === parsedSub.title); + if (this.singleVideoFile(byTitle)) { + return byTitle.map(v => v); + } + const byEpisode = parsedVideos.filter(video => parsedSub.episodes + && this.arrayEquals(video.episodes || [], parsedSub.episodes || [])); + if (this.singleVideoFile(byEpisode)) { + return byEpisode.map(v => v); + } + const byInfoHash = parsedVideos.filter(video => video.infoHash === subtitle.infoHash); + if (this.singleVideoFile(byInfoHash)) { + return byInfoHash.map(v => v); + } + return []; + } + + private singleVideoFile = (videos: IFileAttributes[]): boolean => { + return new Set(videos.map(v => v.fileIndex)).size === 1; + } + + private parsePath = (path: string): IFileAttributes => { + const pathParts = path.split('/').map(part => this.parseFilename(part)); + const parsedWithEpisode = pathParts.find(parsed => parsed.season && parsed.episodes); + return parsedWithEpisode || pathParts[pathParts.length - 1]; + } + + private parseFilename = (filename: string): IFileAttributes => { + const parsedInfo = parse(filename) + const titleEpisode = parsedInfo.title.match(/(\d+)$/); + if (!parsedInfo.episodes && titleEpisode) { + parsedInfo.episodes = [parseInt(titleEpisode[1], 10)]; + } + return parsedInfo; + } + + private arrayEquals = (array1: T[], array2: T[]): boolean => { + if (!array1 || !array2) return array1 === array2; + return array1.length === array2.length && array1.every((value, index) => value === array2[index]) + } +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/services/tracker_service.ts b/src/node/consumer/src/lib/services/tracker_service.ts new file mode 100644 index 0000000..f1c9ed4 --- /dev/null +++ b/src/node/consumer/src/lib/services/tracker_service.ts @@ -0,0 +1,36 @@ +import {ICacheService} from "@interfaces/cache_service"; +import {ILoggingService} from "@interfaces/logging_service"; +import {ITrackerService} from "@interfaces/tracker_service"; +import {configurationService} from '@services/configuration_service'; +import {IocTypes} from "@setup/ioc_types"; +import axios, {AxiosResponse} from 'axios'; +import {inject, injectable} from "inversify"; + +@injectable() +export class TrackerService implements ITrackerService { + @inject(IocTypes.ICacheService) cacheService: ICacheService; + @inject(IocTypes.ILoggingService) logger: ILoggingService; + + async getTrackers(): Promise { + return this.cacheService.cacheTrackers(this.downloadTrackers); + } + + private downloadTrackers = async (): Promise => { + const response: AxiosResponse = await axios.get(configurationService.trackerConfig.TRACKERS_URL); + const trackersListText: string = response.data; + // Trackers are separated by a newline character + let urlTrackers = trackersListText.split("\n"); + // remove blank lines + urlTrackers = urlTrackers.filter(line => line.trim() !== ''); + + if (!configurationService.trackerConfig.UDP_ENABLED) { + // remove any udp trackers + urlTrackers = urlTrackers.filter(line => !line.startsWith('udp://')); + + } + + this.logger.info(`Trackers updated at ${Date.now()}: ${urlTrackers.length} trackers`); + + return urlTrackers; + }; +} \ No newline at end of file diff --git a/src/node/consumer/src/lib/torrent.js b/src/node/consumer/src/lib/torrent.js deleted file mode 100644 index 4253052..0000000 --- a/src/node/consumer/src/lib/torrent.js +++ /dev/null @@ -1,82 +0,0 @@ -import { decode } from 'magnet-uri'; -import torrentStream from 'torrent-stream'; -import { torrentConfig } from './config.js'; -import {isSubtitle, isVideo} from './extension.js'; - -export async function torrentFiles(torrent, timeout) { - return filesFromTorrentStream(torrent, timeout) - .then(files => ({ - contents: files, - videos: filterVideos(files), - subtitles: filterSubtitles(files) - })); -} - -async function filesFromTorrentStream(torrent, timeout) { - return filesAndSizeFromTorrentStream(torrent, timeout).then(result => result.files); -} - -const engineOptions = { - connections: torrentConfig.MAX_CONNECTIONS_PER_TORRENT, - uploads: 0, - verify: false, - dht: false, - tracker: true -} - -function filesAndSizeFromTorrentStream(torrent, timeout = 30000) { - if (!torrent.infoHash) { - return Promise.reject(new Error("no infoHash...")); - } - const magnet = decode.encode({ infoHash: torrent.infoHash, announce: torrent.trackers }); - return new Promise((resolve, rejected) => { - const timeoutId = setTimeout(() => { - engine.destroy(); - rejected(new Error('No available connections for torrent!')); - }, timeout); - - const engine = new torrentStream(magnet, engineOptions); - - engine.ready(() => { - const files = engine.files - .map((file, fileId) => ({ - fileIndex: fileId, - name: file.name, - path: file.path.replace(/^[^/]+\//, ''), - size: file.length - })); - const size = engine.torrent.length; - resolve({ files, size }); - engine.destroy(); - clearTimeout(timeoutId); - }); - }); -} - -function filterVideos(files) { - if (files.length === 1 && !Number.isInteger(files[0].fileIndex)) { - return files; - } - const videos = files.filter(file => isVideo(file.path)); - const maxSize = Math.max(...videos.map(video => video.size)); - const minSampleRatio = videos.length <= 3 ? 3 : 10; - const minAnimeExtraRatio = 5; - const minRedundantRatio = videos.length <= 3 ? 30 : Number.MAX_VALUE; - const isSample = video => video.path.match(/sample|bonus|promo/i) && maxSize / parseInt(video.size) > minSampleRatio; - const isRedundant = video => maxSize / parseInt(video.size) > minRedundantRatio; - const isExtra = video => video.path.match(/extras?\//i); - const isAnimeExtra = video => video.path.match(/(?:\b|_)(?:NC)?(?:ED|OP|PV)(?:v?\d\d?)?(?:\b|_)/i) - && maxSize / parseInt(video.size) > minAnimeExtraRatio; - const isWatermark = video => video.path.match(/^[A-Z-]+(?:\.[A-Z]+)?\.\w{3,4}$/) - && maxSize / parseInt(video.size) > minAnimeExtraRatio - return videos - .filter(video => !isSample(video)) - .filter(video => !isExtra(video)) - .filter(video => !isAnimeExtra(video)) - .filter(video => !isRedundant(video)) - .filter(video => !isWatermark(video)); -} - -function filterSubtitles(files) { - return files.filter(file => isSubtitle(file.path)); -} diff --git a/src/node/consumer/src/lib/torrentEntries.js b/src/node/consumer/src/lib/torrentEntries.js deleted file mode 100644 index 998b92e..0000000 --- a/src/node/consumer/src/lib/torrentEntries.js +++ /dev/null @@ -1,173 +0,0 @@ -import { parse } from 'parse-torrent-title'; -import { getImdbId, getKitsuId } from './metadata.js'; -import { isPackTorrent } from './parseHelper.js'; -import * as Promises from './promises.js'; -import * as repository from './repository.js'; -import { parseTorrentFiles } from './torrentFiles.js'; -import { assignSubtitles } from './torrentSubtitles.js'; -import { TorrentType } from './types.js'; -import {logger} from "./logger.js"; - -export async function createTorrentEntry(torrent, overwrite = false) { - const titleInfo = parse(torrent.title); - - if (!torrent.imdbId && torrent.type !== TorrentType.ANIME) { - torrent.imdbId = await getImdbId(titleInfo, torrent.type) - .catch(() => undefined); - } - if (torrent.imdbId && torrent.imdbId.length < 9) { - // pad zeros to imdbId if missing - torrent.imdbId = 'tt' + torrent.imdbId.replace('tt', '').padStart(7, '0'); - } - if (torrent.imdbId && torrent.imdbId.length > 9 && torrent.imdbId.startsWith('tt0')) { - // sanitize imdbId from redundant zeros - torrent.imdbId = torrent.imdbId.replace(/tt0+([0-9]{7,})$/, 'tt$1'); - } - if (!torrent.kitsuId && torrent.type === TorrentType.ANIME) { - torrent.kitsuId = await getKitsuId(titleInfo) - .catch(() => undefined); - } - - if (!torrent.imdbId && !torrent.kitsuId && !isPackTorrent(torrent)) { - logger.warn(`imdbId or kitsuId not found: ${torrent.provider} ${torrent.title}`); - return; - } - - const { contents, videos, subtitles } = await parseTorrentFiles(torrent) - .then(torrentContents => overwrite ? overwriteExistingFiles(torrent, torrentContents) : torrentContents) - .then(torrentContents => assignSubtitles(torrentContents)) - .catch(error => { - logger.warn(`Failed getting files for ${torrent.title}`, error.message); - return {}; - }); - if (!videos || !videos.length) { - logger.warn(`no video files found for ${torrent.provider} [${torrent.infoHash}] ${torrent.title}`); - return; - } - - return repository.createTorrent({ ...torrent, contents, subtitles }) - .then(() => Promises.sequence(videos.map(video => () => repository.createFile(video)))) - .then(() => logger.info(`Created ${torrent.provider} entry for [${torrent.infoHash}] ${torrent.title}`)); -} - -async function overwriteExistingFiles(torrent, torrentContents) { - const videos = torrentContents && torrentContents.videos; - if (videos && videos.length) { - const existingFiles = await repository.getFiles({ infoHash: videos[0].infoHash }) - .then((existing) => existing - .reduce((map, next) => { - const fileIndex = next.fileIndex !== undefined ? next.fileIndex : null; - map[fileIndex] = (map[fileIndex] || []).concat(next); - return map; - }, {})) - .catch(() => undefined); - if (existingFiles && Object.keys(existingFiles).length) { - const overwrittenVideos = videos - .map(file => { - const mapping = videos.length === 1 && Object.keys(existingFiles).length === 1 - ? Object.values(existingFiles)[0] - : existingFiles[file.fileIndex !== undefined ? file.fileIndex : null]; - if (mapping) { - const originalFile = mapping.shift(); - return { id: originalFile.id, ...file }; - } - return file; - }); - return { ...torrentContents, videos: overwrittenVideos }; - } - return torrentContents; - } - return Promise.reject(`No video files found for: ${torrent.title}`); -} - -export async function createSkipTorrentEntry(torrent) { - return repository.createSkipTorrent(torrent); -} - -export async function getStoredTorrentEntry(torrent) { - return repository.getSkipTorrent(torrent) - .catch(() => repository.getTorrent(torrent)) - .catch(() => undefined); -} - -export async function checkAndUpdateTorrent(torrent) { - const storedTorrent = torrent.dataValues - ? torrent - : await repository.getTorrent(torrent).catch(() => undefined); - if (!storedTorrent) { - return false; - } - if (storedTorrent.provider === 'RARBG') { - return true; - } - if (storedTorrent.provider === 'KickassTorrents' && torrent.provider) { - storedTorrent.provider = torrent.provider; - storedTorrent.torrentId = torrent.torrentId; - } - if (!storedTorrent.languages && torrent.languages && storedTorrent.provider !== 'RARBG') { - storedTorrent.languages = torrent.languages; - await storedTorrent.save(); - logger.debug(`Updated [${storedTorrent.infoHash}] ${storedTorrent.title} language to ${torrent.languages}`); - } - return createTorrentContents({ ...storedTorrent.get(), torrentLink: torrent.torrentLink }) - .then(() => updateTorrentSeeders(torrent)); -} - -export async function createTorrentContents(torrent) { - if (torrent.opened) { - return; - } - const storedVideos = await repository.getFiles(torrent).catch(() => []); - if (!storedVideos || !storedVideos.length) { - return; - } - const notOpenedVideo = storedVideos.length === 1 && !Number.isInteger(storedVideos[0].fileIndex); - const imdbId = Promises.mostCommonValue(storedVideos.map(stored => stored.imdbId)); - const kitsuId = Promises.mostCommonValue(storedVideos.map(stored => stored.kitsuId)); - - const { contents, videos, subtitles } = await parseTorrentFiles({ ...torrent, imdbId, kitsuId }) - .then(torrentContents => notOpenedVideo ? torrentContents : { ...torrentContents, videos: storedVideos }) - .then(torrentContents => assignSubtitles(torrentContents)) - .catch(error => { - logger.warn(`Failed getting contents for [${torrent.infoHash}] ${torrent.title}`, error.message); - return {}; - }); - - if (!contents || !contents.length) { - return; - } - if (notOpenedVideo && videos.length === 1) { - // if both have a single video and stored one was not opened, update stored one to true metadata and use that - storedVideos[0].fileIndex = videos[0].fileIndex; - storedVideos[0].title = videos[0].title; - storedVideos[0].size = videos[0].size; - storedVideos[0].subtitles = videos[0].subtitles; - videos[0] = storedVideos[0]; - } - // no videos available or more than one new videos were in the torrent - const shouldDeleteOld = notOpenedVideo && videos.every(video => !video.id); - - return repository.createTorrent({ ...torrent, contents, subtitles }) - .then(() => { - if (shouldDeleteOld) { - logger.debug(`Deleting old video for [${torrent.infoHash}] ${torrent.title}`) - return storedVideos[0].destroy(); - } - return Promise.resolve(); - }) - .then(() => Promises.sequence(videos.map(video => () => repository.createFile(video)))) - .then(() => logger.info(`Created contents for ${torrent.provider} [${torrent.infoHash}] ${torrent.title}`)) - .catch(error => logger.error(`Failed saving contents for [${torrent.infoHash}] ${torrent.title}`, error)); -} - -export async function updateTorrentSeeders(torrent) { - if (!(torrent.infoHash || (torrent.provider && torrent.torrentId)) || !Number.isInteger(torrent.seeders)) { - return torrent; - } - - return repository.setTorrentSeeders(torrent, torrent.seeders) - .catch(error => { - logger.warn('Failed updating seeders:', error); - return undefined; - }); -} diff --git a/src/node/consumer/src/lib/torrentFiles.js b/src/node/consumer/src/lib/torrentFiles.js deleted file mode 100644 index 0ac9ea9..0000000 --- a/src/node/consumer/src/lib/torrentFiles.js +++ /dev/null @@ -1,513 +0,0 @@ -import Bottleneck from 'bottleneck'; -import distance from 'jaro-winkler'; -import moment from 'moment'; -import { parse } from 'parse-torrent-title'; -import { metadataConfig } from './config.js'; -import { isDisk } from './extension.js'; -import { getMetadata, getImdbId, getKitsuId } from './metadata.js'; -import { parseSeriesVideos, isPackTorrent } from './parseHelper.js'; -import * as Promises from './promises.js'; -import {torrentFiles} from "./torrent.js"; -import { TorrentType } from './types.js'; -import {logger} from "./logger.js"; - -const MIN_SIZE = 5 * 1024 * 1024; // 5 MB -const imdb_limiter = new Bottleneck({ maxConcurrent: metadataConfig.IMDB_CONCURRENT, minTime: metadataConfig.IMDB_INTERVAL_MS }); - -export async function parseTorrentFiles(torrent) { - const parsedTorrentName = parse(torrent.title); - const metadata = await getMetadata(torrent.kitsuId || torrent.imdbId, torrent.type || TorrentType.MOVIE) - .then(meta => Object.assign({}, meta)) - .catch(() => undefined); - - // if (metadata && metadata.type !== torrent.type && torrent.type !== Type.ANIME) { - // throw new Error(`Mismatching entry type for ${torrent.name}: ${torrent.type}!=${metadata.type}`); - // } - if (torrent.type !== TorrentType.ANIME && metadata && metadata.type && metadata.type !== torrent.type) { - // it's actually a movie/series - torrent.type = metadata.type; - } - - if (torrent.type === TorrentType.MOVIE && (!parsedTorrentName.seasons || - parsedTorrentName.season === 5 && [1, 5].includes(parsedTorrentName.episode))) { - return parseMovieFiles(torrent, parsedTorrentName, metadata); - } - - return parseSeriesFiles(torrent, parsedTorrentName, metadata) -} - -async function parseMovieFiles(torrent, parsedName, metadata) { - const { contents, videos, subtitles } = await getMoviesTorrentContent(torrent); - const filteredVideos = videos - .filter(video => video.size > MIN_SIZE) - .filter(video => !isFeaturette(video)); - if (isSingleMovie(filteredVideos)) { - const parsedVideos = filteredVideos.map(video => ({ - infoHash: torrent.infoHash, - fileIndex: video.fileIndex, - title: video.path || torrent.title, - size: video.size || torrent.size, - imdbId: torrent.imdbId || metadata && metadata.imdbId, - kitsuId: torrent.kitsuId || metadata && metadata.kitsuId - })); - return { contents, videos: parsedVideos, subtitles }; - } - - const parsedVideos = await Promises.sequence(filteredVideos.map(video => () => isFeaturette(video) - ? Promise.resolve(video) - : findMovieImdbId(video.name).then(imdbId => ({ ...video, imdbId })))) - .then(videos => videos.map(video => ({ - infoHash: torrent.infoHash, - fileIndex: video.fileIndex, - title: video.path || video.name, - size: video.size, - imdbId: video.imdbId, - }))); - return { contents, videos: parsedVideos, subtitles }; -} - -async function parseSeriesFiles(torrent, parsedName, metadata) { - const { contents, videos, subtitles } = await getSeriesTorrentContent(torrent); - const parsedVideos = await Promise.resolve(videos) - .then(videos => videos.filter(video => videos.length === 1 || video.size > MIN_SIZE)) - .then(videos => parseSeriesVideos(torrent, videos)) - .then(videos => decomposeEpisodes(torrent, videos, metadata)) - .then(videos => assignKitsuOrImdbEpisodes(torrent, videos, metadata)) - .then(videos => Promise.all(videos.map(video => video.isMovie - ? mapSeriesMovie(video, torrent) - : mapSeriesEpisode(video, torrent, videos)))) - .then(videos => videos - .reduce((a, b) => a.concat(b), []) - .map(video => isFeaturette(video) ? clearInfoFields(video) : video)) - return { contents, videos: parsedVideos, subtitles }; -} - -async function getMoviesTorrentContent(torrent) { - const files = await torrentFiles(torrent) - .catch(error => { - if (!isPackTorrent(torrent)) { - return { videos: [{ name: torrent.title, path: torrent.title, size: torrent.size }] } - } - return Promise.reject(error); - }); - if (files.contents && files.contents.length && !files.videos.length && isDiskTorrent(files.contents)) { - files.videos = [{ name: torrent.title, path: torrent.title, size: torrent.size }]; - } - return files; -} - -async function getSeriesTorrentContent(torrent) { - return torrentFiles(torrent) - .catch(error => { - if (!isPackTorrent(torrent)) { - return { videos: [{ name: torrent.title, path: torrent.title, size: torrent.size }] } - } - return Promise.reject(error); - }); -} - -async function mapSeriesEpisode(file, torrent, files) { - if (!file.episodes && !file.kitsuEpisodes) { - if (files.length === 1 || files.some(f => f.episodes || f.kitsuEpisodes) || parse(torrent.title).seasons) { - return Promise.resolve({ - infoHash: torrent.infoHash, - fileIndex: file.fileIndex, - title: file.path || file.name, - size: file.size, - imdbId: torrent.imdbId || file.imdbId, - }); - } - return Promise.resolve([]); - } - const episodeIndexes = [...(file.episodes || file.kitsuEpisodes).keys()]; - return Promise.resolve(episodeIndexes.map((index) => ({ - infoHash: torrent.infoHash, - fileIndex: file.fileIndex, - title: file.path || file.name, - size: file.size, - imdbId: file.imdbId || torrent.imdbId, - imdbSeason: file.season, - imdbEpisode: file.episodes && file.episodes[index], - kitsuId: file.kitsuId || torrent.kitsuId, - kitsuEpisode: file.kitsuEpisodes && file.kitsuEpisodes[index] - }))) -} - -async function mapSeriesMovie(file, torrent) { - const kitsuId = torrent.type === TorrentType.ANIME ? await findMovieKitsuId(file) : undefined; - const imdbId = !kitsuId ? await findMovieImdbId(file) : undefined; - const metadata = await getMetadata(kitsuId || imdbId, TorrentType.MOVIE).catch(() => ({})); - const hasEpisode = metadata.videos && metadata.videos.length && (file.episode || metadata.videos.length === 1); - const episodeVideo = hasEpisode && metadata.videos[(file.episode || 1) - 1]; - return [{ - infoHash: torrent.infoHash, - fileIndex: file.fileIndex, - title: file.path || file.name, - size: file.size, - imdbId: metadata.imdbId || imdbId, - kitsuId: metadata.kitsuId || kitsuId, - imdbSeason: episodeVideo && metadata.imdbId ? episodeVideo.imdbSeason : undefined, - imdbEpisode: episodeVideo && metadata.imdbId ? episodeVideo.imdbEpisode || episodeVideo.episode : undefined, - kitsuEpisode: episodeVideo && metadata.kitsuId ? episodeVideo.kitsuEpisode || episodeVideo.episode : undefined - }]; -} - -async function decomposeEpisodes(torrent, files, metadata = { episodeCount: [] }) { - if (files.every(file => !file.episodes && !file.date)) { - return files; - } - - preprocessEpisodes(files); - - if (torrent.type === TorrentType.ANIME && torrent.kitsuId) { - if (needsCinemetaMetadataForAnime(files, metadata)) { - // In some cases anime could be resolved to wrong kitsuId - // because of imdb season naming/absolute per series naming/multiple seasons - // So in these cases we need to fetch cinemeta based metadata and decompose episodes using that - await updateToCinemetaMetadata(metadata); - if (files.some(file => Number.isInteger(file.season))) { - // sometimes multi season anime torrents don't include season 1 naming - files - .filter(file => !Number.isInteger(file.season) && file.episodes) - .forEach(file => file.season = 1); - } - } else { - // otherwise for anime type episodes are always absolute and for a single season - files - .filter(file => file.episodes && file.season !== 0) - .forEach(file => file.season = 1); - return files; - } - } - - const sortedEpisodes = files - .map(file => !file.isMovie && file.episodes || []) - .reduce((a, b) => a.concat(b), []) - .sort((a, b) => a - b); - - if (isConcatSeasonAndEpisodeFiles(files, sortedEpisodes, metadata)) { - decomposeConcatSeasonAndEpisodeFiles(torrent, files, metadata); - } else if (isDateEpisodeFiles(files, metadata)) { - decomposeDateEpisodeFiles(torrent, files, metadata); - } else if (isAbsoluteEpisodeFiles(torrent, files, metadata)) { - decomposeAbsoluteEpisodeFiles(torrent, files, metadata); - } - // decomposeEpisodeTitleFiles(torrent, files, metadata); - - return files; -} - -function preprocessEpisodes(files) { - // reverse special episode naming when they named with 0 episode, ie. S02E00 - files - .filter(file => Number.isInteger(file.season) && file.episode === 0) - .forEach(file => { - file.episode = file.season - file.episodes = [file.season] - file.season = 0; - }) -} - -function isConcatSeasonAndEpisodeFiles(files, sortedEpisodes, metadata) { - if (metadata.kitsuId !== undefined) { - // anime does not use this naming scheme in 99% of cases; - return false; - } - // decompose concat season and episode files (ex. 101=S01E01) in case: - // 1. file has a season, but individual files are concatenated with that season (ex. path Season 5/511 - Prize - // Fighters.avi) - // 2. file does not have a season and the episode does not go out of range for the concat season - // episode count - const thresholdAbove = Math.max(Math.ceil(files.length * 0.05), 5); - const thresholdSorted = Math.max(Math.ceil(files.length * 0.8), 8); - const threshold = Math.max(Math.ceil(files.length * 0.8), 5); - const sortedConcatEpisodes = sortedEpisodes - .filter(ep => ep > 100) - .filter(ep => metadata.episodeCount[div100(ep) - 1] < ep) - .filter(ep => metadata.episodeCount[div100(ep) - 1] >= mod100(ep)); - const concatFileEpisodes = files - .filter(file => !file.isMovie && file.episodes) - .filter(file => !file.season || file.episodes.every(ep => div100(ep) === file.season)); - const concatAboveTotalEpisodeCount = files - .filter(file => !file.isMovie && file.episodes && file.episodes.every(ep => ep > 100)) - .filter(file => file.episodes.every(ep => ep > metadata.totalCount)); - return sortedConcatEpisodes.length >= thresholdSorted && concatFileEpisodes.length >= threshold - || concatAboveTotalEpisodeCount.length >= thresholdAbove; -} - -function isDateEpisodeFiles(files, metadata) { - return files.every(file => (!file.season || !metadata.episodeCount[file.season - 1]) && file.date); -} - -function isAbsoluteEpisodeFiles(torrent, files, metadata) { - const threshold = Math.ceil(files.length / 5); - const isAnime = torrent.type === TorrentType.ANIME && torrent.kitsuId; - const nonMovieEpisodes = files - .filter(file => !file.isMovie && file.episodes); - const absoluteEpisodes = files - .filter(file => file.season && file.episodes) - .filter(file => file.episodes.every(ep => metadata.episodeCount[file.season - 1] < ep)) - return nonMovieEpisodes.every(file => !file.season) - || (isAnime && nonMovieEpisodes.every(file => file.season > metadata.episodeCount.length)) - || absoluteEpisodes.length >= threshold; -} - -function isNewEpisodeNotInMetadata(torrent, file, metadata) { - // new episode might not yet been indexed by cinemeta. - // detect this if episode number is larger than the last episode or season is larger than the last one - // only for non anime metas - const isAnime = torrent.type === TorrentType.ANIME && torrent.kitsuId; - return !isAnime && !file.isMovie && file.episodes && file.season !== 1 - && /continuing|current/i.test(metadata.status) - && file.season >= metadata.episodeCount.length - && file.episodes.every(ep => ep > (metadata.episodeCount[file.season - 1] || 0)); -} - -function decomposeConcatSeasonAndEpisodeFiles(torrent, files, metadata) { - files - .filter(file => file.episodes && file.season !== 0 && file.episodes.every(ep => ep > 100)) - .filter(file => metadata.episodeCount[(file.season || div100(file.episodes[0])) - 1] < 100) - .filter(file => file.season && file.episodes.every(ep => div100(ep) === file.season) || !file.season) - .forEach(file => { - file.season = div100(file.episodes[0]); - file.episodes = file.episodes.map(ep => mod100(ep)) - }); - -} - -function decomposeAbsoluteEpisodeFiles(torrent, files, metadata) { - if (metadata.episodeCount.length === 0) { - files - .filter(file => !Number.isInteger(file.season) && file.episodes && !file.isMovie) - .forEach(file => { - file.season = 1; - }); - return; - } - files - .filter(file => file.episodes && !file.isMovie && file.season !== 0) - .filter(file => !isNewEpisodeNotInMetadata(torrent, file, metadata)) - .filter(file => !file.season || (metadata.episodeCount[file.season - 1] || 0) < file.episodes[0]) - .forEach(file => { - const seasonIdx = ([...metadata.episodeCount.keys()] - .find((i) => metadata.episodeCount.slice(0, i + 1).reduce((a, b) => a + b) >= file.episodes[0]) - + 1 || metadata.episodeCount.length) - 1; - - file.season = seasonIdx + 1; - file.episodes = file.episodes - .map(ep => ep - metadata.episodeCount.slice(0, seasonIdx).reduce((a, b) => a + b, 0)) - }); -} - -function decomposeDateEpisodeFiles(torrent, files, metadata) { - if (!metadata || !metadata.videos || !metadata.videos.length) { - return; - } - - const timeZoneOffset = getTimeZoneOffset(metadata.country); - const offsetVideos = metadata.videos - .reduce((map, video) => { - const releaseDate = moment(video.released).utcOffset(timeZoneOffset).format('YYYY-MM-DD'); - map[releaseDate] = video; - return map; - }, {}); - - files - .filter(file => file.date) - .forEach(file => { - const video = offsetVideos[file.date]; - if (video) { - file.season = video.season; - file.episodes = [video.episode]; - } - }); -} - - -/* eslint-disable no-unused-vars */ -function decomposeEpisodeTitleFiles(torrent, files, metadata) { - files - // .filter(file => !file.season) - .map(file => { - const episodeTitle = file.name.replace('_', ' ') - .replace(/^.*(?:E\d+[abc]?|- )\s?(.+)\.\w{1,4}$/, '$1') - .trim(); - const foundEpisode = metadata.videos - .map(video => ({ ...video, distance: distance(episodeTitle, video.name) })) - .sort((a, b) => b.distance - a.distance)[0]; - if (foundEpisode) { - file.isMovie = false; - file.season = foundEpisode.season; - file.episodes = [foundEpisode.episode]; - } - }) -} -/* eslint-enable no-unused-vars */ - -function getTimeZoneOffset(country) { - switch (country) { - case 'United States': - case 'USA': - return '-08:00'; - default: - return '00:00'; - } -} - -function assignKitsuOrImdbEpisodes(torrent, files, metadata) { - if (!metadata || !metadata.videos || !metadata.videos.length) { - if (torrent.type === TorrentType.ANIME) { - // assign episodes as kitsu episodes for anime when no metadata available for imdb mapping - files - .filter(file => file.season && file.episodes) - .forEach(file => { - file.kitsuEpisodes = file.episodes; - file.season = undefined; - file.episodes = undefined; - }) - if (metadata.type === TorrentType.MOVIE && files.every(file => !file.imdbId)) { - // sometimes a movie has episode naming, thus not recognized as a movie and imdbId not assigned - files.forEach(file => file.imdbId = metadata.imdbId); - } - } - return files; - } - - const seriesMapping = metadata.videos - .reduce((map, video) => { - const episodeMap = map[video.season] || {}; - episodeMap[video.episode] = video; - map[video.season] = episodeMap; - return map; - }, {}); - - if (metadata.videos.some(video => Number.isInteger(video.imdbSeason)) || !metadata.imdbId) { - // kitsu episode info is the base - files - .filter(file => Number.isInteger(file.season) && file.episodes) - .map(file => { - const seasonMapping = seriesMapping[file.season]; - const episodeMapping = seasonMapping && seasonMapping[file.episodes[0]]; - file.kitsuEpisodes = file.episodes; - if (episodeMapping && Number.isInteger(episodeMapping.imdbSeason)) { - file.imdbId = metadata.imdbId; - file.season = episodeMapping.imdbSeason; - file.episodes = file.episodes.map(ep => seasonMapping[ep] && seasonMapping[ep].imdbEpisode); - } else { - // no imdb mapping available for episode - file.season = undefined; - file.episodes = undefined; - } - }); - } else if (metadata.videos.some(video => video.kitsuEpisode)) { - // imdb episode info is base - files - .filter(file => Number.isInteger(file.season) && file.episodes) - .forEach(file => { - if (seriesMapping[file.season]) { - const seasonMapping = seriesMapping[file.season]; - file.imdbId = metadata.imdbId; - file.kitsuId = seasonMapping[file.episodes[0]] && seasonMapping[file.episodes[0]].kitsuId; - file.kitsuEpisodes = file.episodes.map(ep => seasonMapping[ep] && seasonMapping[ep].kitsuEpisode); - } else if (seriesMapping[file.season - 1]) { - // sometimes a second season might be a continuation of the previous season - const seasonMapping = seriesMapping[file.season - 1]; - const episodes = Object.values(seasonMapping); - const firstKitsuId = episodes.length && episodes[0].kitsuId; - const differentTitlesCount = new Set(episodes.map(ep => ep.kitsuId)).size - const skippedCount = episodes.filter(ep => ep.kitsuId === firstKitsuId).length; - const seasonEpisodes = files - .filter(otherFile => otherFile.season === file.season) - .reduce((a, b) => a.concat(b.episodes), []); - const isAbsoluteOrder = seasonEpisodes.every(ep => ep > skippedCount && ep <= episodes.length) - const isNormalOrder = seasonEpisodes.every(ep => ep + skippedCount <= episodes.length) - if (differentTitlesCount >= 1 && (isAbsoluteOrder || isNormalOrder)) { - file.imdbId = metadata.imdbId; - file.season = file.season - 1; - file.episodes = file.episodes.map(ep => isAbsoluteOrder ? ep : ep + skippedCount); - file.kitsuId = seasonMapping[file.episodes[0]].kitsuId; - file.kitsuEpisodes = file.episodes.map(ep => seasonMapping[ep] && seasonMapping[ep].kitsuEpisode); - } - } else if (Object.values(seriesMapping).length === 1 && seriesMapping[1]) { - // sometimes series might be named with sequel season but it's not a season on imdb and a new title - const seasonMapping = seriesMapping[1]; - file.imdbId = metadata.imdbId; - file.season = 1; - file.kitsuId = seasonMapping[file.episodes[0]].kitsuId; - file.kitsuEpisodes = file.episodes.map(ep => seasonMapping[ep] && seasonMapping[ep].kitsuEpisode); - } - }); - } - return files; -} - -function needsCinemetaMetadataForAnime(files, metadata) { - if (!metadata || !metadata.imdbId || !metadata.videos || !metadata.videos.length) { - return false; - } - - const minSeason = Math.min(...metadata.videos.map(video => video.imdbSeason)) || Number.MAX_VALUE; - const maxSeason = Math.max(...metadata.videos.map(video => video.imdbSeason)) || Number.MAX_VALUE; - const differentSeasons = new Set(metadata.videos - .map(video => video.imdbSeason) - .filter(season => Number.isInteger(season))).size; - const total = metadata.totalCount || Number.MAX_VALUE; - return differentSeasons > 1 || files - .filter(file => !file.isMovie && file.episodes) - .some(file => file.season < minSeason || file.season > maxSeason || file.episodes.every(ep => ep > total)); -} - -async function updateToCinemetaMetadata(metadata) { - return getMetadata(metadata.imdbId, metadata.type) - .then(newMetadata => !newMetadata.videos || !newMetadata.videos.length ? metadata : newMetadata) - .then(newMetadata => { - metadata.videos = newMetadata.videos; - metadata.episodeCount = newMetadata.episodeCount; - metadata.totalCount = newMetadata.totalCount; - return metadata; - }) - .catch(error => logger.warn(`Failed ${metadata.imdbId} metadata cinemeta update due: ${error.message}`)); -} - -function findMovieImdbId(title) { - const parsedTitle = typeof title === 'string' ? parse(title) : title; - logger.debug(`Finding movie imdbId for ${title}`); - return imdb_limiter.schedule(() => getImdbId(parsedTitle, TorrentType.MOVIE).catch(() => undefined)); -} - -function findMovieKitsuId(title) { - const parsedTitle = typeof title === 'string' ? parse(title) : title; - return getKitsuId(parsedTitle, TorrentType.MOVIE).catch(() => undefined); -} - -function isDiskTorrent(contents) { - return contents.some(content => isDisk(content.path)); -} - -function isSingleMovie(videos) { - return videos.length === 1 || - (videos.length === 2 && - videos.find(v => /\b(?:part|disc|cd)[ ._-]?0?1\b|^0?1\.\w{2,4}$/i.test(v.path)) && - videos.find(v => /\b(?:part|disc|cd)[ ._-]?0?2\b|^0?2\.\w{2,4}$/i.test(v.path))); -} - -function isFeaturette(video) { - return /featurettes?\/|extras-grym/i.test(video.path); -} - -function clearInfoFields(video) { - video.imdbId = undefined; - video.imdbSeason = undefined; - video.imdbEpisode = undefined; - video.kitsuId = undefined; - video.kitsuEpisode = undefined; - return video; -} - -function div100(episode) { - return (episode / 100 >> 0); // floor to nearest int -} - -function mod100(episode) { - return episode % 100; -} \ No newline at end of file diff --git a/src/node/consumer/src/lib/torrentSubtitles.js b/src/node/consumer/src/lib/torrentSubtitles.js deleted file mode 100644 index 7bd9ab4..0000000 --- a/src/node/consumer/src/lib/torrentSubtitles.js +++ /dev/null @@ -1,89 +0,0 @@ -import { parse } from 'parse-torrent-title'; - -export function assignSubtitles({ contents, videos, subtitles }) { - if (videos && videos.length && subtitles && subtitles.length) { - if (videos.length === 1) { - videos[0].subtitles = subtitles; - return { contents, videos, subtitles: [] }; - } - - const parsedVideos = videos - .map(video => _parseVideo(video)); - const assignedSubs = subtitles - .map(subtitle => ({ subtitle, videos: _mostProbableSubtitleVideos(subtitle, parsedVideos) })); - const unassignedSubs = assignedSubs - .filter(assignedSub => !assignedSub.videos) - .map(assignedSub => assignedSub.subtitle); - - assignedSubs - .filter(assignedSub => assignedSub.videos) - .forEach(assignedSub => assignedSub.videos - .forEach(video => video.subtitles = (video.subtitles || []).concat(assignedSub.subtitle))); - return { contents, videos, subtitles: unassignedSubs }; - } - return { contents, videos, subtitles }; -} - -function _parseVideo(video) { - const fileName = video.title.split('/').pop().replace(/\.(\w{2,4})$/, ''); - const folderName = video.title.replace(/\/?[^/]+$/, ''); - return { - videoFile: video, - fileName: fileName, - folderName: folderName, - ...parseFilename(video.title) - }; -} - -function _mostProbableSubtitleVideos(subtitle, parsedVideos) { - const subTitle = (subtitle.title || subtitle.path).split('/').pop().replace(/\.(\w{2,4})$/, ''); - const parsedSub = parsePath(subtitle.title || subtitle.path); - const byFileName = parsedVideos.filter(video => subTitle.includes(video.fileName)); - if (byFileName.length === 1) { - return byFileName.map(v => v.videoFile); - } - const byTitleSeasonEpisode = parsedVideos.filter(video => video.title === parsedSub.title - && arrayEquals(video.seasons, parsedSub.seasons) - && arrayEquals(video.episodes, parsedSub.episodes)); - if (singleVideoFile(byTitleSeasonEpisode)) { - return byTitleSeasonEpisode.map(v => v.videoFile); - } - const bySeasonEpisode = parsedVideos.filter(video => arrayEquals(video.seasons, parsedSub.seasons) - && arrayEquals(video.episodes, parsedSub.episodes)); - if (singleVideoFile(bySeasonEpisode)) { - return bySeasonEpisode.map(v => v.videoFile); - } - const byTitle = parsedVideos.filter(video => video.title && video.title === parsedSub.title); - if (singleVideoFile(byTitle)) { - return byTitle.map(v => v.videoFile); - } - const byEpisode = parsedVideos.filter(video => arrayEquals(video.episodes, parsedSub.episodes)); - if (singleVideoFile(byEpisode)) { - return byEpisode.map(v => v.videoFile); - } - return undefined; -} - -function singleVideoFile(videos) { - return new Set(videos.map(v => v.videoFile.fileIndex)).size === 1; -} - -function parsePath(path) { - const pathParts = path.split('/').map(part => parseFilename(part)); - const parsedWithEpisode = pathParts.find(parsed => parsed.season && parsed.episodes); - return parsedWithEpisode || pathParts[pathParts.length - 1]; -} - -function parseFilename(filename) { - const parsedInfo = parse(filename) - const titleEpisode = parsedInfo.title.match(/(\d+)$/); - if (!parsedInfo.episodes && titleEpisode) { - parsedInfo.episodes = [parseInt(titleEpisode[1], 10)]; - } - return parsedInfo; -} - -function arrayEquals(array1, array2) { - if (!array1 || !array2) return array1 === array2; - return array1.length === array2.length && array1.every((value, index) => value === array2[index]) -} \ No newline at end of file diff --git a/src/node/consumer/src/lib/trackerService.js b/src/node/consumer/src/lib/trackerService.js deleted file mode 100644 index 1af9b13..0000000 --- a/src/node/consumer/src/lib/trackerService.js +++ /dev/null @@ -1,26 +0,0 @@ -import axios from 'axios'; -import {cacheTrackers} from "./cache.js"; -import { trackerConfig } from './config.js'; -import {logger} from "./logger.js"; - -const downloadTrackers = async () => { - const response = await axios.get(trackerConfig.TRACKERS_URL); - const trackersListText = response.data; - // Trackers are separated by a newline character - let urlTrackers = trackersListText.split("\n"); - // remove blank lines - urlTrackers = urlTrackers.filter(line => line.trim() !== ''); - - if (!trackerConfig.UDP_ENABLED) { - // remove any udp trackers - urlTrackers = urlTrackers.filter(line => !line.startsWith('udp://')); - } - - logger.info(`Trackers updated at ${Date.now()}: ${urlTrackers.length} trackers`); - - return urlTrackers; -}; - -export const getTrackers = async () => { - return cacheTrackers(downloadTrackers); -}; \ No newline at end of file diff --git a/src/node/consumer/src/lib/types.js b/src/node/consumer/src/lib/types.js deleted file mode 100644 index 17d37dc..0000000 --- a/src/node/consumer/src/lib/types.js +++ /dev/null @@ -1,11 +0,0 @@ -export const TorrentType = { - MOVIE: 'movie', - SERIES: 'series', - ANIME: 'anime', - PORN: 'xxx', -}; - -export const CacheType = { - MEMORY: 'memory', - MONGODB: 'mongodb', -}; \ No newline at end of file diff --git a/src/node/consumer/src/main.ts b/src/node/consumer/src/main.ts new file mode 100644 index 0000000..7a5afeb --- /dev/null +++ b/src/node/consumer/src/main.ts @@ -0,0 +1,9 @@ +import "reflect-metadata"; // required +import {ICompositionalRoot} from "@setup/composition_root"; +import {serviceContainer} from "@setup/inversify_config"; +import {IocTypes} from "@setup/ioc_types"; + +(async (): Promise => { + const compositionalRoot = serviceContainer.get(IocTypes.ICompositionalRoot); + await compositionalRoot.start(); +})(); \ No newline at end of file diff --git a/src/node/consumer/src/setup/composition_root.ts b/src/node/consumer/src/setup/composition_root.ts new file mode 100644 index 0000000..ce28aa0 --- /dev/null +++ b/src/node/consumer/src/setup/composition_root.ts @@ -0,0 +1,22 @@ +import {IProcessTorrentsJob} from "@interfaces/process_torrents_job"; +import {ITrackerService} from "@interfaces/tracker_service"; +import {IDatabaseRepository} from "@repository/interfaces/database_repository"; +import {IocTypes} from "@setup/ioc_types"; +import {inject, injectable} from "inversify"; + +export interface ICompositionalRoot { + start(): Promise; +} + +@injectable() +export class CompositionalRoot implements ICompositionalRoot { + @inject(IocTypes.ITrackerService) trackerService: ITrackerService; + @inject(IocTypes.IDatabaseRepository) databaseRepository: IDatabaseRepository; + @inject(IocTypes.IProcessTorrentsJob) processTorrentsJob: IProcessTorrentsJob; + + async start(): Promise { + await this.trackerService.getTrackers(); + await this.databaseRepository.connect(); + await this.processTorrentsJob.listenToQueue(); + } +} \ No newline at end of file diff --git a/src/node/consumer/src/setup/inversify_config.ts b/src/node/consumer/src/setup/inversify_config.ts new file mode 100644 index 0000000..796bacd --- /dev/null +++ b/src/node/consumer/src/setup/inversify_config.ts @@ -0,0 +1,42 @@ +import {ICacheService} from "@interfaces/cache_service"; +import {ILoggingService} from "@interfaces/logging_service"; +import {IMetadataService} from "@interfaces/metadata_service"; +import {IProcessTorrentsJob} from "@interfaces/process_torrents_job"; +import {ITorrentDownloadService} from "@interfaces/torrent_download_service"; +import {ITorrentEntriesService} from "@interfaces/torrent_entries_service"; +import {ITorrentFileService} from "@interfaces/torrent_file_service"; +import {ITorrentProcessingService} from "@interfaces/torrent_processing_service"; +import {ITorrentSubtitleService} from "@interfaces/torrent_subtitle_service"; +import {ITrackerService} from "@interfaces/tracker_service"; +import {ProcessTorrentsJob} from "@jobs/process_torrents_job"; +import {DatabaseRepository} from "@repository/database_repository"; +import {IDatabaseRepository} from "@repository/interfaces/database_repository"; +import {CacheService} from "@services/cache_service"; +import {LoggingService} from "@services/logging_service"; +import {MetadataService} from "@services/metadata_service"; +import {TorrentDownloadService} from "@services/torrent_download_service"; +import {TorrentEntriesService} from "@services/torrent_entries_service"; +import {TorrentFileService} from "@services/torrent_file_service"; +import {TorrentProcessingService} from "@services/torrent_processing_service"; +import {TorrentSubtitleService} from "@services/torrent_subtitle_service"; +import {TrackerService} from "@services/tracker_service"; +import {ICompositionalRoot, CompositionalRoot} from "@setup/composition_root"; +import {IocTypes} from "@setup/ioc_types"; +import {Container} from "inversify"; + +const serviceContainer = new Container(); + +serviceContainer.bind(IocTypes.ICompositionalRoot).to(CompositionalRoot).inSingletonScope(); +serviceContainer.bind(IocTypes.ICacheService).to(CacheService).inSingletonScope(); +serviceContainer.bind(IocTypes.ILoggingService).to(LoggingService).inSingletonScope(); +serviceContainer.bind(IocTypes.ITrackerService).to(TrackerService).inSingletonScope(); +serviceContainer.bind(IocTypes.ITorrentDownloadService).to(TorrentDownloadService).inSingletonScope(); +serviceContainer.bind(IocTypes.ITorrentFileService).to(TorrentFileService); +serviceContainer.bind(IocTypes.ITorrentProcessingService).to(TorrentProcessingService); +serviceContainer.bind(IocTypes.ITorrentSubtitleService).to(TorrentSubtitleService); +serviceContainer.bind(IocTypes.ITorrentEntriesService).to(TorrentEntriesService); +serviceContainer.bind(IocTypes.IMetadataService).to(MetadataService); +serviceContainer.bind(IocTypes.IDatabaseRepository).to(DatabaseRepository); +serviceContainer.bind(IocTypes.IProcessTorrentsJob).to(ProcessTorrentsJob); + +export {serviceContainer}; diff --git a/src/node/consumer/src/setup/ioc_types.ts b/src/node/consumer/src/setup/ioc_types.ts new file mode 100644 index 0000000..ebe437b --- /dev/null +++ b/src/node/consumer/src/setup/ioc_types.ts @@ -0,0 +1,18 @@ +export const IocTypes = { + // Composition root + ICompositionalRoot: Symbol.for("ICompositionalRoot"), + // Services + ICacheService: Symbol.for("ICacheService"), + ILoggingService: Symbol.for("ILoggingService"), + IMetadataService: Symbol.for("IMetadataService"), + ITorrentDownloadService: Symbol.for("ITorrentDownloadService"), + ITorrentEntriesService: Symbol.for("ITorrentEntriesService"), + ITorrentFileService: Symbol.for("ITorrentFileService"), + ITorrentProcessingService: Symbol.for("ITorrentProcessingService"), + ITorrentSubtitleService: Symbol.for("ITorrentSubtitleService"), + ITrackerService: Symbol.for("ITrackerService"), + // DAL + IDatabaseRepository: Symbol.for("IDatabaseRepository"), + // Jobs + IProcessTorrentsJob: Symbol.for("IProcessTorrentsJob"), +}; \ No newline at end of file diff --git a/src/node/consumer/test/helpers/boolean_helpers.test.ts b/src/node/consumer/test/helpers/boolean_helpers.test.ts new file mode 100644 index 0000000..32e285c --- /dev/null +++ b/src/node/consumer/test/helpers/boolean_helpers.test.ts @@ -0,0 +1,35 @@ +import { BooleanHelpers } from '@helpers/boolean_helpers'; + +describe('BooleanHelpers.parseBool', () => { + it('should return true when value is "true"', () => { + expect(BooleanHelpers.parseBool('true', false)).toBe(true); + }); + + it('should return true when value is "1"', () => { + expect(BooleanHelpers.parseBool('1', false)).toBe(true); + }); + + it('should return true when value is "yes"', () => { + expect(BooleanHelpers.parseBool('yes', false)).toBe(true); + }); + + it('should return false when value is "false"', () => { + expect(BooleanHelpers.parseBool('false', true)).toBe(false); + }); + + it('should return false when value is "0"', () => { + expect(BooleanHelpers.parseBool('0', true)).toBe(false); + }); + + it('should return false when value is "no"', () => { + expect(BooleanHelpers.parseBool('no', true)).toBe(false); + }); + + it('should return default value when value is undefined', () => { + expect(BooleanHelpers.parseBool(undefined, true)).toBe(true); + }); + + it('should return default value when value is not "true", "1", "yes", "false", "0", or "no"', () => { + expect(BooleanHelpers.parseBool('random', true)).toBe(true); + }); +}); \ No newline at end of file diff --git a/src/node/consumer/test/helpers/extension_helpers.test.ts b/src/node/consumer/test/helpers/extension_helpers.test.ts new file mode 100644 index 0000000..ad92d8d --- /dev/null +++ b/src/node/consumer/test/helpers/extension_helpers.test.ts @@ -0,0 +1,33 @@ +import { ExtensionHelpers } from '@helpers/extension_helpers'; + +describe('ExtensionHelpers', () => { + describe('isVideo', () => { + it('should return true when file extension is a video extension', () => { + expect(ExtensionHelpers.isVideo('file.mp4')).toBe(true); + }); + + it('should return false when file extension is not a video extension', () => { + expect(ExtensionHelpers.isVideo('file.txt')).toBe(false); + }); + }); + + describe('isSubtitle', () => { + it('should return true when file extension is a subtitle extension', () => { + expect(ExtensionHelpers.isSubtitle('file.srt')).toBe(true); + }); + + it('should return false when file extension is not a subtitle extension', () => { + expect(ExtensionHelpers.isSubtitle('file.txt')).toBe(false); + }); + }); + + describe('isDisk', () => { + it('should return true when file extension is a disk extension', () => { + expect(ExtensionHelpers.isDisk('file.iso')).toBe(true); + }); + + it('should return false when file extension is not a disk extension', () => { + expect(ExtensionHelpers.isDisk('file.txt')).toBe(false); + }); + }); +}); \ No newline at end of file diff --git a/src/node/consumer/test/helpers/promise_helpers.test.ts b/src/node/consumer/test/helpers/promise_helpers.test.ts new file mode 100644 index 0000000..d265177 --- /dev/null +++ b/src/node/consumer/test/helpers/promise_helpers.test.ts @@ -0,0 +1,55 @@ +import { PromiseHelpers } from '@helpers/promises_helpers'; + +describe('PromiseHelpers', () => { + beforeAll(() => { + jest.useFakeTimers({timerLimit: 5000}); + }); + + afterAll(() => { + jest.useRealTimers(); + }); + + describe('sequence', () => { + it('should resolve promises in sequence', async () => { + const promises = [() => Promise.resolve(1), () => Promise.resolve(2), () => Promise.resolve(3)]; + const result = await PromiseHelpers.sequence(promises); + expect(result).toEqual([1, 2, 3]); + }); + }); + + describe('first', () => { + it('should resolve the first fulfilled promise', async () => { + const promises = [Promise.reject('error'), Promise.resolve('success'), Promise.resolve('success2')]; + const result = await PromiseHelpers.first(promises); + expect(result).toBe('success'); + }); + }); + + describe('delay', () => { + it('should delay execution', async () => { + const startTime = Date.now(); + const delayPromise = PromiseHelpers.delay(1000); + jest.runAllTimers(); + await delayPromise; + const endTime = Date.now(); + expect(endTime - startTime).toBeGreaterThanOrEqual(1000); + }, 30000); + }); + + describe('timeout', () => { + it('should reject promise after timeout', async () => { + const promise = new Promise((resolve) => setTimeout(resolve, 2000)); + const timeoutPromise = PromiseHelpers.timeout(1000, promise); + jest.advanceTimersByTime(1000); + await expect(timeoutPromise).rejects.toBe('Timed out'); + }, 20000); + }); + + describe('mostCommonValue', () => { + it('should return the most common value in an array', () => { + const array = [1, 2, 2, 3, 3, 3]; + const result = PromiseHelpers.mostCommonValue(array); + expect(result).toBe(3); + }); + }); +}); \ No newline at end of file diff --git a/src/node/consumer/test/mock-responses/assets/cinemeta-query-response.json b/src/node/consumer/test/mock-responses/assets/cinemeta-query-response.json new file mode 100644 index 0000000..8b573d4 --- /dev/null +++ b/src/node/consumer/test/mock-responses/assets/cinemeta-query-response.json @@ -0,0 +1,21006 @@ +{ + "jsonrpc": "2.0", + "id": 1, + "result": [ + { + "_id": "53677f0c847ccc8123a19216", + "imdb_id": "tt3444938", + "name": "The Tonight Show Starring Jimmy Fallon", + "type": "series", + "year": "2014–" + }, + { + "_id": "5507880b711bd19c92ade25c", + "imdb_id": "tt0075474", + "name": "The Old Fox", + "year": "1977–", + "type": "series" + }, + { + "_id": "53677f74847ccc8123a23737", + "imdb_id": "tt3513388", + "name": "Late Night with Seth Meyers", + "type": "series", + "year": "2014–" + }, + { + "_id": "54b28a0b8527d2e0cb50620a", + "imdb_id": "tt3697842", + "name": "The Late Show with Stephen Colbert", + "type": "series", + "year": "2015–" + }, + { + "_id": "53677f00847ccc8123a16293", + "imdb_id": "tt2057880", + "name": "Watch What Happens Live with Andy Cohen", + "type": "series", + "year": "2009–" + }, + { + "_id": "53677f05847ccc8123a17631", + "imdb_id": "tt0056751", + "name": "Doctor Who", + "type": "series", + "year": "1963–1989" + }, + { + "_id": "53677efa847ccc8123a1483c", + "imdb_id": "tt0098904", + "name": "Seinfeld", + "type": "series", + "year": "1989–1998" + }, + { + "_id": "5d78fd7dc4ccb5dd92e4d7e2", + "imdb_id": "tt9022950", + "name": "The Kelly Clarkson Show", + "type": "series", + "year": "2019–" + }, + { + "_id": "53677ef5847ccc8123a1374f", + "imdb_id": "tt0247082", + "name": "CSI: Crime Scene Investigation", + "type": "series", + "year": "2000–2015" + }, + { + "_id": "53677f35847ccc8123a1eabe", + "imdb_id": "tt0121220", + "name": "Dragon Ball Z", + "type": "series", + "year": "1989–1996" + }, + { + "_id": "53677efc847ccc8123a15331", + "imdb_id": "tt0118480", + "name": "Stargate SG-1", + "type": "series", + "year": "1997–2007" + }, + { + "_id": "53677f29847ccc8123a1df0e", + "imdb_id": "tt2467372", + "name": "Brooklyn Nine-Nine", + "type": "series", + "year": "2013–2021" + }, + { + "_id": "576c5a7df0b6c53b3c76ac3a", + "imdb_id": "tt5555260", + "name": "This Is Us", + "year": "2016–2022", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a1388b", + "imdb_id": "tt1600194", + "name": "Hawaii Five-0", + "type": "series", + "year": "2010–2020" + }, + { + "_id": "5559c147bf6c900d1833cb94", + "imdb_id": "tt4016454", + "name": "Supergirl", + "year": "2015–2021", + "type": "series" + }, + { + "_id": "53677f1d847ccc8123a1bf77", + "imdb_id": "tt0988818", + "name": "Gintama", + "type": "series", + "year": "2005–2021" + }, + { + "_id": "5c0ad5b9173739c9f4d613a1", + "imdb_id": "tt8146760", + "name": "Summer Camp Island", + "type": "series", + "year": "2018–2023" + }, + { + "_id": "5378cbf6847ccc8123ad33c7", + "imdb_id": "tt3205802", + "name": "How to Get Away with Murder", + "type": "series", + "year": "2014–2020" + }, + { + "_id": "53677f02847ccc8123a16d8c", + "imdb_id": "tt0094514", + "name": "Murphy Brown", + "type": "series", + "year": "1988–2018" + }, + { + "_id": "5378cc37847ccc8123ad565c", + "imdb_id": "tt3487356", + "name": "Black-ish", + "type": "series", + "year": "2014–2022" + }, + { + "_id": "53677f4a847ccc8123a20373", + "imdb_id": "tt0055686", + "name": "The Lucy Show", + "type": "series", + "year": "1962–1968" + }, + { + "_id": "53677ef9847ccc8123a13e10", + "imdb_id": "tt1442464", + "name": "The Middle", + "type": "series", + "year": "2009–2018" + }, + { + "_id": "5c194df8173739c9f45aba7f", + "imdb_id": "tt0306368", + "name": "Operación triunfo", + "type": "series", + "year": "2001–" + }, + { + "_id": "53677f20847ccc8123a1c6d5", + "imdb_id": "tt2098220", + "name": "Hunter x Hunter", + "type": "series", + "year": "2011–2014" + }, + { + "_id": "53677f17847ccc8123a1acad", + "imdb_id": "tt0235918", + "name": "The Fairly OddParents", + "type": "series", + "year": "2001–2017" + }, + { + "_id": "53677f40847ccc8123a1f5e9", + "imdb_id": "tt0090477", + "name": "Lovejoy", + "type": "series", + "year": "1986–1994" + }, + { + "_id": "53677f05847ccc8123a17b19", + "imdb_id": "tt0262151", + "name": "Bob the Builder", + "type": "series", + "year": "1997–2018" + }, + { + "_id": "53677ef9847ccc8123a14032", + "imdb_id": "tt0409591", + "name": "Naruto", + "type": "series", + "year": "2002–2007" + }, + { + "_id": "54fb5f89711bd19c92ad476a", + "imdb_id": "tt0405831", + "name": "Chest imeyu!..", + "year": "2004–", + "type": "series" + }, + { + "_id": "5378cc11847ccc8123ad4b05", + "imdb_id": "tt3514324", + "name": "Scorpion", + "type": "series", + "year": "2014–2018" + }, + { + "_id": "53677ef9847ccc8123a13ee9", + "imdb_id": "tt0367279", + "name": "Arrested Development", + "type": "series", + "year": "2003–2019" + }, + { + "_id": "5c0cd816173739c9f44fb2f9", + "imdb_id": "tt7670568", + "type": "series", + "name": "The Masked Singer", + "year": "2019–2024" + }, + { + "_id": "53677f09847ccc8123a185f2", + "imdb_id": "tt0106028", + "name": "Homicide: Life on the Street", + "type": "series", + "year": "1993–1999" + }, + { + "_id": "53677ef9847ccc8123a137ea", + "imdb_id": "tt1830617", + "name": "Grimm", + "type": "series", + "year": "2011–2017" + }, + { + "_id": "5c0d9f2e173739c9f4e40fcb", + "imdb_id": "tt9111220", + "name": "Hudson & Rex", + "type": "series", + "year": "2019–" + }, + { + "_id": "53677f25847ccc8123a1d576", + "imdb_id": "tt0081856", + "name": "Dynasty", + "type": "series", + "year": "1981–1989" + }, + { + "_id": "53677ef9847ccc8123a13873", + "imdb_id": "tt1327801", + "name": "Glee", + "type": "series", + "year": "2009–2015" + }, + { + "_id": "53677efa847ccc8123a14936", + "imdb_id": "tt0050037", + "name": "Maverick", + "type": "series", + "year": "1957–1962" + }, + { + "_id": "53677f04847ccc8123a17491", + "imdb_id": "tt0046617", + "name": "Lassie", + "type": "series", + "year": "1954–1974" + }, + { + "_id": "53677f00847ccc8123a164c7", + "imdb_id": "tt0118375", + "name": "King of the Hill", + "type": "series", + "year": "1997–2010" + }, + { + "_id": "53677ef9847ccc8123a139e3", + "imdb_id": "tt1378167", + "name": "NCIS: Los Angeles", + "type": "series", + "year": "2009–2023" + }, + { + "_id": "53677f0c847ccc8123a19444", + "imdb_id": "tt0068149", + "name": "The Waltons", + "type": "series", + "year": "1972–1981" + }, + { + "_id": "5c2280bc173739c9f4e935e5", + "imdb_id": "tt7124904", + "name": "Tomorrow Is Ours", + "type": "series", + "year": "2017–" + }, + { + "_id": "5c2e3909173739c9f4a109ae", + "imdb_id": "tt3105422", + "name": "Ace of Diamond", + "type": "series", + "year": "2013–2016" + }, + { + "_id": "53677ef9847ccc8123a13ae5", + "imdb_id": "tt0434665", + "name": "Bleach", + "type": "series", + "year": "2004–2023" + }, + { + "_id": "53677f0f847ccc8123a19a50", + "imdb_id": "tt1865718", + "name": "Gravity Falls", + "type": "series", + "year": "2012–2016" + }, + { + "_id": "53677f05847ccc8123a176f0", + "imdb_id": "tt0088512", + "name": "EastEnders", + "type": "series", + "year": "1985–" + }, + { + "_id": "53677f0f847ccc8123a1996c", + "imdb_id": "tt2261391", + "name": "Chicago Fire", + "type": "series", + "year": "2012–" + }, + { + "_id": "53677ef9847ccc8123a141c4", + "imdb_id": "tt0115270", + "name": "Millennium", + "type": "series", + "year": "1996–1999" + }, + { + "_id": "53677efc847ccc8123a14d23", + "imdb_id": "tt0098844", + "name": "Law & Order", + "type": "series", + "year": "1990–" + }, + { + "_id": "53677f02847ccc8123a16db7", + "imdb_id": "tt0105986", + "name": "Diagnosis Murder", + "type": "series", + "year": "1993–2001" + }, + { + "_id": "53677f00847ccc8123a16678", + "imdb_id": "tt2191671", + "name": "Elementary", + "type": "series", + "year": "2012–2019" + }, + { + "_id": "53677f02847ccc8123a16bb4", + "imdb_id": "tt0106080", + "name": "The Nanny", + "type": "series", + "year": "1993–1999" + }, + { + "_id": "53677f19847ccc8123a1b235", + "imdb_id": "tt0278866", + "name": "Kim Possible", + "type": "series", + "year": "2002–2007" + }, + { + "_id": "53677efc847ccc8123a1523e", + "imdb_id": "tt0053494", + "name": "Coronation Street", + "type": "series", + "year": "1960–" + }, + { + "_id": "53677ef9847ccc8123a1381f", + "imdb_id": "tt0182576", + "name": "Family Guy", + "type": "series", + "year": "1999–" + }, + { + "_id": "57e04e3bd7e54929823e5674", + "imdb_id": "tt5897304", + "name": "Mob Psycho 100", + "year": "2016–2022", + "type": "series" + }, + { + "_id": "53677eff847ccc8123a160ea", + "imdb_id": "tt0364817", + "name": "Tru Calling", + "type": "series", + "year": "2003–2005" + }, + { + "_id": "554d2d8916e3a4523a768e58", + "imdb_id": "tt3609352", + "name": "Grace and Frankie", + "year": "2015–2022", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a1391a", + "imdb_id": "tt0313043", + "name": "CSI: Miami", + "type": "series", + "year": "2002–2012" + }, + { + "_id": "5a5ea363543165dcd86c3ef8", + "imdb_id": "tt4869896", + "type": "series", + "name": "Overlord", + "year": "2015–2022" + }, + { + "_id": "53677f47847ccc8123a201c0", + "imdb_id": "tt0053525", + "name": "My Three Sons", + "type": "series", + "year": "1960–1972" + }, + { + "_id": "53677ef9847ccc8123a13abb", + "imdb_id": "tt0086759", + "name": "Miami Vice", + "type": "series", + "year": "1984–1989" + }, + { + "_id": "5c0d2135173739c9f4da546a", + "imdb_id": "tt8883922", + "name": "Chronicles of the Sun", + "type": "series", + "year": "2018–" + }, + { + "_id": "53677f38847ccc8123a1ee21", + "imdb_id": "tt0101188", + "name": "Rugrats", + "type": "series", + "year": "1991–2006" + }, + { + "_id": "53677ef9847ccc8123a14149", + "imdb_id": "tt0165581", + "name": "The King of Queens", + "type": "series", + "year": "1998–2007" + }, + { + "_id": "5d968228c4ccb5dd92e33091", + "imdb_id": "tt10691888", + "name": "AEW Dynamite", + "type": "series", + "year": "2019–" + }, + { + "_id": "5c4dddfad582b2575688de43", + "imdb_id": "tt0040051", + "name": "Studio One", + "type": "series", + "year": "1948–1958" + }, + { + "_id": "53677f21847ccc8123a1cb4d", + "imdb_id": "tt3107288", + "name": "The Flash", + "type": "series", + "year": "2014–2023" + }, + { + "_id": "53677f4a847ccc8123a203e0", + "imdb_id": "tt0051297", + "name": "Naked City", + "type": "series", + "year": "1958–1963" + }, + { + "_id": "54ce5d26e573cadcfa1f8c17", + "imdb_id": "tt0454349", + "name": "Johnny Test", + "type": "series", + "year": "2005–2014" + }, + { + "_id": "53677f1b847ccc8123a1b80c", + "imdb_id": "tt2230051", + "name": "High School DxD", + "type": "series", + "year": "2012–2018" + }, + { + "_id": "53677efc847ccc8123a14dad", + "imdb_id": "tt2364582", + "name": "Agents of S.H.I.E.L.D.", + "type": "series", + "year": "2013–2020" + }, + { + "_id": "53677ef9847ccc8123a13a48", + "imdb_id": "tt0458290", + "name": "Star Wars: The Clone Wars", + "type": "series", + "year": "2008–2020" + }, + { + "_id": "54ce5d15e573cadcfa1f8bf8", + "imdb_id": "tt3061050", + "name": "Clarence", + "type": "series", + "year": "2013–2018" + }, + { + "_id": "53677ef9847ccc8123a13cb4", + "imdb_id": "tt0072562", + "name": "Saturday Night Live", + "type": "series", + "year": "1975–" + }, + { + "_id": "53677ef9847ccc8123a137a8", + "imdb_id": "tt0413573", + "name": "Grey's Anatomy", + "type": "series", + "year": "2005–" + }, + { + "_id": "5378cc0a847ccc8123ad473e", + "imdb_id": "tt3566726", + "name": "Jane the Virgin", + "type": "series", + "year": "2014–2019" + }, + { + "_id": "539173bca8f27b1bb90ade63", + "imdb_id": "tt0996695", + "name": "Eyeshield 21", + "type": "series", + "year": "2005–2008" + }, + { + "_id": "53677f07847ccc8123a18177", + "imdb_id": "tt1734537", + "name": "Marple", + "type": "series", + "year": "2004–2013" + }, + { + "_id": "55075d87711bd19c92addeb3", + "imdb_id": "tt2789238", + "name": "Strike the Blood", + "year": "2013–2022", + "type": "series" + }, + { + "_id": "56b8b50ff6b914c6c680f89e", + "imdb_id": "tt2788432", + "name": "American Crime Story", + "year": "2016–", + "type": "series" + }, + { + "_id": "5c4cb888d582b2575615f902", + "imdb_id": "tt0872309", + "name": "Genesis of Aquarion", + "type": "series", + "year": "2005–2015" + }, + { + "_id": "53677ef9847ccc8123a13edf", + "imdb_id": "tt0094455", + "name": "Empty Nest", + "type": "series", + "year": "1988–1995" + }, + { + "_id": "59be2e281712e0f4dd892e90", + "imdb_id": "tt6135682", + "type": "series", + "name": "Spider-Man", + "year": "2017–2020" + }, + { + "_id": "53677f29847ccc8123a1dd90", + "imdb_id": "tt2861424", + "name": "Rick and Morty", + "type": "series", + "year": "2013–" + }, + { + "_id": "53677efc847ccc8123a150eb", + "imdb_id": "tt0892700", + "name": "The Penguins of Madagascar", + "type": "series", + "year": "2008–2015" + }, + { + "_id": "53677f05847ccc8123a17700", + "imdb_id": "tt0118360", + "name": "Johnny Bravo", + "type": "series", + "year": "1997–2004" + }, + { + "_id": "53677f05847ccc8123a179db", + "imdb_id": "tt0493334", + "name": "Yu-Gi-Oh! GX", + "type": "series", + "year": "2004–2008" + }, + { + "_id": "53677f00847ccc8123a1672a", + "imdb_id": "tt1480925", + "name": "Bakemonogatari", + "type": "series", + "year": "2009–2010" + }, + { + "_id": "53677f2c847ccc8123a1e02d", + "imdb_id": "tt2771780", + "name": "Teen Titans Go!", + "type": "series", + "year": "2013–" + }, + { + "_id": "53677f59847ccc8123a2192e", + "imdb_id": "tt0118933", + "name": "David", + "type": "series", + "year": "1997" + }, + { + "_id": "53677ef9847ccc8123a13b83", + "imdb_id": "tt0203259", + "name": "Law & Order: Special Victims Unit", + "type": "series", + "year": "1999–" + }, + { + "_id": "53677f19847ccc8123a1b1e3", + "imdb_id": "tt0108894", + "name": "Party of Five", + "type": "series", + "year": "1994–2000" + }, + { + "_id": "5378b8cb847ccc8123ad1826", + "imdb_id": "tt0318913", + "name": "Teenage Mutant Ninja Turtles", + "type": "series", + "year": "2003–2010" + }, + { + "_id": "5c2bcb30173739c9f45daeaf", + "imdb_id": "tt7997010", + "name": "I Live Alone", + "type": "series", + "year": "2013–" + }, + { + "_id": "55089941711bd19c92ade50e", + "imdb_id": "tt0043224", + "name": "The Red Skelton Hour", + "year": "1951–1971", + "type": "series" + }, + { + "_id": "53677f00847ccc8123a165c4", + "imdb_id": "tt0068120", + "name": "The Price is Right", + "type": "series", + "year": "1972–" + }, + { + "_id": "53677efa847ccc8123a149ad", + "imdb_id": "tt1305826", + "name": "Adventure Time", + "type": "series", + "year": "2010–2018" + }, + { + "_id": "53677ef9847ccc8123a13b4f", + "imdb_id": "tt0096697", + "name": "The Simpsons", + "type": "series", + "year": "1989–2025" + }, + { + "_id": "5b2dad2216f4806c2aff7b84", + "imdb_id": "tt4236770", + "type": "series", + "name": "Yellowstone", + "year": "2018–" + }, + { + "_id": "53677ef9847ccc8123a13edd", + "imdb_id": "tt1416765", + "name": "Parenthood", + "type": "series", + "year": "2010–2015" + }, + { + "_id": "5c26ee7e173739c9f4e0a14b", + "imdb_id": "tt7216636", + "name": "Hazbin Hotel", + "type": "series", + "year": "2024–" + }, + { + "_id": "55b96fb2bf6c900d183bed2f", + "imdb_id": "tt4839610", + "name": "We Bare Bears", + "year": "2014–2019", + "type": "series" + }, + { + "_id": "53677f0a847ccc8123a18ac0", + "imdb_id": "tt0070992", + "name": "Happy Days", + "type": "series", + "year": "1974–1984" + }, + { + "_id": "55cb60b8bf6c900d183def29", + "imdb_id": "tt4052886", + "name": "Lucifer", + "year": "2016–2021", + "type": "series" + }, + { + "_id": "5c43e04fd582b257568449df", + "imdb_id": "tt0052445", + "name": "Bat Masterson", + "type": "series", + "year": "1958–1961" + }, + { + "_id": "53677efc847ccc8123a15274", + "imdb_id": "tt0112022", + "name": "JAG", + "type": "series", + "year": "1995–2005" + }, + { + "_id": "57f8c980d7e54929823fa198", + "imdb_id": "tt3398540", + "name": "Haikyu!!", + "year": "2014–2020", + "type": "series" + }, + { + "_id": "53677f23847ccc8123a1cee4", + "imdb_id": "tt0134269", + "name": "V.I.P.", + "type": "series", + "year": "1998–2002" + }, + { + "_id": "53677f05847ccc8123a17bcd", + "imdb_id": "tt2177489", + "name": "Baby Daddy", + "type": "series", + "year": "2012–2017" + }, + { + "_id": "53de7d2ea8f27b1bb90bd552", + "imdb_id": "tt3596174", + "name": "Henry Danger", + "type": "series", + "year": "2014–2020" + }, + { + "_id": "53677f29847ccc8123a1de72", + "imdb_id": "tt2712740", + "name": "The Goldbergs", + "type": "series", + "year": "2013–2023" + }, + { + "_id": "53677ef9847ccc8123a139fe", + "imdb_id": "tt0364782", + "name": "The Apprentice", + "type": "series", + "year": "2004–2017" + }, + { + "_id": "550efc59cc9eee85bb52d997", + "imdb_id": "tt2061527", + "name": "Tiger & Bunny", + "year": "2011–2022", + "type": "series" + }, + { + "_id": "53677f7a847ccc8123a23d0b", + "imdb_id": "tt3502248", + "name": "Bosch", + "type": "series", + "year": "2014–2021" + }, + { + "_id": "53677efa847ccc8123a14639", + "imdb_id": "tt0176385", + "name": "#DUPE#", + "type": "series", + "year": "1997–" + }, + { + "_id": "53677efd847ccc8123a15621", + "imdb_id": "tt0050025", + "name": "Have Gun - Will Travel", + "type": "series", + "year": "1957–1963" + }, + { + "_id": "53677f2c847ccc8123a1df68", + "imdb_id": "tt2185037", + "name": "Running Man", + "type": "series", + "year": "2010–" + }, + { + "_id": "55075d78711bd19c92addd6f", + "imdb_id": "tt0978215", + "name": "Utawarerumono", + "year": "2006", + "type": "series" + }, + { + "_id": "53677efa847ccc8123a14ccb", + "imdb_id": "tt2071645", + "name": "The Following", + "type": "series", + "year": "2013–2015" + }, + { + "_id": "5c219b11173739c9f45b31aa", + "imdb_id": "tt0070981", + "name": "Derrick", + "type": "series", + "year": "1974–1998" + }, + { + "_id": "53677ef9847ccc8123a13c01", + "imdb_id": "tt0460091", + "name": "My Name Is Earl", + "type": "series", + "year": "2005–2009" + }, + { + "_id": "53677f19847ccc8123a1b5e2", + "imdb_id": "tt0075592", + "name": "Tales of the Unexpected", + "type": "series", + "year": "1979–1988" + }, + { + "_id": "53677efa847ccc8123a14618", + "imdb_id": "tt0402711", + "name": "Boston Legal", + "type": "series", + "year": "2004–2008" + }, + { + "_id": "53677f23847ccc8123a1cf33", + "imdb_id": "tt2741602", + "name": "The Blacklist", + "type": "series", + "year": "2013–2023" + }, + { + "_id": "53677ef9847ccc8123a13d0d", + "imdb_id": "tt1567432", + "name": "Teen Wolf", + "type": "series", + "year": "2011–2017" + }, + { + "_id": "59b043451712e0f4dd1ff969", + "imdb_id": "tt5515212", + "name": "Big Hero 6: The Series", + "year": "2017–2021", + "type": "series" + }, + { + "_id": "53677f0c847ccc8123a18ecc", + "imdb_id": "tt1308089", + "name": "A Certain Magical Index", + "type": "series", + "year": "2008–2019" + }, + { + "_id": "5f784bf35424253341ead722", + "imdb_id": "tt11858104", + "name": "Dragon Quest: The Adventure of Dai", + "type": "series", + "year": "2020–2022" + }, + { + "_id": "53677f0a847ccc8123a18ae6", + "imdb_id": "tt0366025", + "name": "Hope & Faith", + "type": "series", + "year": "2003–2006" + }, + { + "_id": "53677f02847ccc8123a168bd", + "imdb_id": "tt0108724", + "name": "Chicago Hope", + "type": "series", + "year": "1994–2000" + }, + { + "_id": "53677ef9847ccc8123a144bd", + "imdb_id": "tt1466074", + "name": "Columbo", + "type": "series", + "year": "1971–1978" + }, + { + "_id": "53677ef5847ccc8123a13773", + "imdb_id": "tt0364845", + "name": "NCIS", + "type": "series", + "year": "2003–" + }, + { + "_id": "5a3f61c9543165dcd8e89248", + "imdb_id": "tt6148376", + "type": "series", + "name": "Ben 10", + "year": "2016–2021" + }, + { + "_id": "5c597cb4d582b25756ac7bfd", + "imdb_id": "tt2398674", + "name": "Aikatsu!", + "type": "series", + "year": "2012–2016" + }, + { + "_id": "53677f29847ccc8123a1de6a", + "imdb_id": "tt1710295", + "name": "Doc McStuffins", + "type": "series", + "year": "2012–2022" + }, + { + "_id": "53677f66847ccc8123a229e6", + "imdb_id": "tt2712516", + "name": "The Thundermans", + "type": "series", + "year": "2013–2018" + }, + { + "_id": "5378cc10847ccc8123ad4a01", + "imdb_id": "tt3501584", + "name": "iZombie", + "type": "series", + "year": "2015–2019" + }, + { + "_id": "53677f45847ccc8123a1fdfe", + "imdb_id": "tt0317028", + "name": "V Graham Norton", + "type": "series", + "year": "2002–2003" + }, + { + "_id": "53677f00847ccc8123a16287", + "imdb_id": "tt0806910", + "name": "Tatort", + "type": "series", + "year": "1970–" + }, + { + "_id": "53677f0f847ccc8123a197d1", + "imdb_id": "tt2250192", + "name": "Sword Art Online", + "type": "series", + "year": "2012–" + }, + { + "_id": "53677ef9847ccc8123a13a06", + "imdb_id": "tt1196946", + "name": "The Mentalist", + "type": "series", + "year": "2008–2015" + }, + { + "_id": "55075d32711bd19c92addb86", + "imdb_id": "tt0054519", + "name": "Ben Casey", + "year": "1961–1966", + "type": "series" + }, + { + "_id": "53677efa847ccc8123a14a28", + "imdb_id": "tt0092400", + "name": "Married... with Children", + "type": "series", + "year": "1987–1997" + }, + { + "_id": "53677ef9847ccc8123a1440e", + "imdb_id": "tt2137109", + "name": "Masters of Sex", + "type": "series", + "year": "2013–2016" + }, + { + "_id": "53677efa847ccc8123a1494a", + "imdb_id": "tt1632701", + "name": "Suits", + "type": "series", + "year": "2011–2019" + }, + { + "_id": "53677ef9847ccc8123a13858", + "imdb_id": "tt1439629", + "name": "Community", + "type": "series", + "year": "2009–2015" + }, + { + "_id": "614ae5b264ec43ef98728413", + "imdb_id": "tt13622982", + "name": "Star Wars: Visions", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677ef9847ccc8123a13ad4", + "imdb_id": "tt1353056", + "name": "RuPaul's Drag Race", + "type": "series", + "year": "2009–" + }, + { + "_id": "53677f07847ccc8123a1817e", + "imdb_id": "tt0481256", + "name": "Fighting Spirit", + "type": "series", + "year": "2000–2002" + }, + { + "_id": "53677f51847ccc8123a20e77", + "imdb_id": "tt0044248", + "name": "Cavalcade of America", + "type": "series", + "year": "1952–1957" + }, + { + "_id": "5c118f3f173739c9f4c485ff", + "imdb_id": "tt8722888", + "name": "Stargirl", + "type": "series", + "year": "2020–2022" + }, + { + "_id": "536907f2847ccc8123acddc5", + "imdb_id": "tt0044259", + "name": "Death Valley Days", + "type": "series", + "year": "1952–1970" + }, + { + "_id": "589329951635517fbf56c91a", + "imdb_id": "tt4859164", + "name": "The Loud House", + "type": "series", + "year": "2014–" + }, + { + "_id": "587fc2541635517fbf569601", + "imdb_id": "tt5011816", + "name": "Sneaky Pete", + "type": "series", + "year": "2015–2019" + }, + { + "_id": "53677ef9847ccc8123a137b9", + "imdb_id": "tt0410975", + "name": "Desperate Housewives", + "type": "series", + "year": "2004–2012" + }, + { + "_id": "53677f0a847ccc8123a18917", + "imdb_id": "tt0101120", + "name": "Home Improvement", + "type": "series", + "year": "1991–1999" + }, + { + "_id": "5c26b328173739c9f48399ba", + "imdb_id": "tt2267446", + "name": "Space Brothers", + "type": "series", + "year": "2012–2014" + }, + { + "_id": "53677ef5847ccc8123a13765", + "imdb_id": "tt0452046", + "name": "Criminal Minds", + "type": "series", + "year": "2005–" + }, + { + "_id": "53677ef9847ccc8123a142f8", + "imdb_id": "tt0112178", + "name": "Star Trek: Voyager", + "type": "series", + "year": "1995–2001" + }, + { + "_id": "53677f52847ccc8123a21014", + "imdb_id": "tt0318252", + "name": "The Twilight Zone", + "type": "series", + "year": "2002–2003" + }, + { + "_id": "53677ef9847ccc8123a13896", + "imdb_id": "tt0463398", + "name": "Dancing with the Stars", + "type": "series", + "year": "2005–" + }, + { + "_id": "53677f79847ccc8123a23aed", + "imdb_id": "tt2802850", + "name": "Fargo", + "type": "series", + "year": "2014–2024" + }, + { + "_id": "5429bef3a8f27b1bb90ce418", + "imdb_id": "tt3339966", + "name": "Unbreakable Kimmy Schmidt", + "type": "series", + "year": "2015–2020" + }, + { + "_id": "58c984c91635517fbf56e602", + "imdb_id": "tt5853176", + "name": "The Good Fight", + "type": "series", + "year": "2017–2022" + }, + { + "_id": "5c0fb75e173739c9f4471367", + "imdb_id": "tt5129382", + "name": "The Return of Superman", + "type": "series", + "year": "2013–" + }, + { + "_id": "53677ef9847ccc8123a13c2d", + "imdb_id": "tt0935095", + "name": "In Plain Sight", + "type": "series", + "year": "2008–2012" + }, + { + "_id": "53677f02847ccc8123a16854", + "imdb_id": "tt0115163", + "name": "Early Edition", + "type": "series", + "year": "1996–2000" + }, + { + "_id": "53677efa847ccc8123a145a6", + "imdb_id": "tt0421482", + "name": "Winx Club", + "type": "series", + "year": "2004–2023" + }, + { + "_id": "5c269276173739c9f4403ae7", + "imdb_id": "tt0106097", + "name": "Peak Practice", + "type": "series", + "year": "1993–2002" + }, + { + "_id": "53677ef9847ccc8123a13e2a", + "imdb_id": "tt0988824", + "name": "Naruto: Shippuden", + "type": "series", + "year": "2007–2017" + }, + { + "_id": "5c1bd504173739c9f4fe0a78", + "imdb_id": "tt8322592", + "name": "Fast & Furious Spy Racers", + "type": "series", + "year": "2019–2021" + }, + { + "_id": "53677f03847ccc8123a17310", + "imdb_id": "tt2049323", + "name": "The Jonathan Ross Show", + "type": "series", + "year": "2011–" + }, + { + "_id": "53677f23847ccc8123a1cff3", + "imdb_id": "tt2211129", + "name": "The Mindy Project", + "type": "series", + "year": "2012–2017" + }, + { + "_id": "5973f3511635517fbf56e96f", + "imdb_id": "tt6116060", + "name": "The Bold Type", + "type": "series", + "year": "2017–2021" + }, + { + "_id": "62793d6d64ec43ef98dc810a", + "imdb_id": "tt14168162", + "name": "Bosch: Legacy", + "type": "series", + "year": "2022–" + }, + { + "_id": "57f0f4d9d7e54929823f33de", + "imdb_id": "tt0475784", + "name": "Westworld", + "year": "2016–2022", + "type": "series" + }, + { + "_id": "53677f68847ccc8123a22b07", + "imdb_id": "tt2805096", + "name": "Chicago P.D.", + "type": "series", + "year": "2014–" + }, + { + "_id": "5c12d1e4173739c9f40a8e93", + "imdb_id": "tt4648640", + "name": "Talking Tom and Friends", + "type": "series", + "year": "2014–2021" + }, + { + "_id": "53677f3a847ccc8123a1f0f1", + "imdb_id": "tt0081860", + "name": "A Case for Two", + "type": "series", + "year": "1981–2023" + }, + { + "_id": "53677f0c847ccc8123a19396", + "imdb_id": "tt0212671", + "name": "Malcolm in the Middle", + "type": "series", + "year": "2000–2006" + }, + { + "_id": "53677f0a847ccc8123a18a5c", + "imdb_id": "tt2288064", + "name": "Witches of East End", + "type": "series", + "year": "2013–2014" + }, + { + "_id": "53677f5b847ccc8123a21cf5", + "imdb_id": "tt0041061", + "name": "Suspense", + "type": "series", + "year": "1949–1954" + }, + { + "_id": "54250886a8f27b1bb90cd78d", + "imdb_id": "tt3749900", + "name": "Gotham", + "type": "series", + "year": "2014–2019" + }, + { + "_id": "54fc0959711bd19c92ad4a28", + "imdb_id": "tt0962826", + "name": "Black Lagoon", + "year": "2006", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a1395d", + "imdb_id": "tt0395843", + "name": "CSI: NY", + "type": "series", + "year": "2004–2013" + }, + { + "_id": "54e19896e573cadcfa1fd641", + "imdb_id": "tt0056742", + "name": "Bob Hope Presents the Chrysler Theatre", + "type": "series", + "year": "1963–1967" + }, + { + "_id": "53677efa847ccc8123a1466c", + "imdb_id": "tt0050051", + "name": "Perry Mason", + "type": "series", + "year": "1957–1966" + }, + { + "_id": "551ad095cc9eee85bb52e022", + "imdb_id": "tt4465472", + "name": "Rosewood", + "type": "series", + "year": "2015–2017" + }, + { + "_id": "53677f09847ccc8123a185da", + "imdb_id": "tt0129717", + "name": "Softly Softly", + "type": "series", + "year": "1966–1969" + }, + { + "_id": "53677f5a847ccc8123a21b11", + "imdb_id": "tt0267212", + "name": "Question Time", + "type": "series", + "year": "1979–" + }, + { + "_id": "53677f08847ccc8123a18506", + "imdb_id": "tt2647544", + "name": "Sleepy Hollow", + "type": "series", + "year": "2013–2017" + }, + { + "_id": "53677ef9847ccc8123a13810", + "imdb_id": "tt1845307", + "name": "2 Broke Girls", + "type": "series", + "year": "2011–2017" + }, + { + "_id": "53677f21847ccc8123a1ca42", + "imdb_id": "tt0071034", + "name": "Police Woman", + "type": "series", + "year": "1974–1978" + }, + { + "_id": "53677ef9847ccc8123a13e37", + "imdb_id": "tt0765425", + "name": "Top Chef", + "type": "series", + "year": "2006–" + }, + { + "_id": "604bb2005424253341252d86", + "imdb_id": "tt14094206", + "name": "Marvel Studios: Assembled", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677f08847ccc8123a184e2", + "imdb_id": "tt1751105", + "name": "My Little Pony: Friendship Is Magic", + "type": "series", + "year": "2010–2020" + }, + { + "_id": "53677efc847ccc8123a15081", + "imdb_id": "tt0321021", + "name": "Without a Trace", + "type": "series", + "year": "2002–2009" + }, + { + "_id": "53677f76847ccc8123a23969", + "imdb_id": "tt0159208", + "name": "City Hunter", + "type": "series", + "year": "1987–1991" + }, + { + "_id": "53677f19847ccc8123a1b53b", + "imdb_id": "tt1178180", + "name": "The Marvelous Misadventures of Flapjack", + "type": "series", + "year": "2008–2010" + }, + { + "_id": "5a5dd073543165dcd8707d2f", + "imdb_id": "tt6483832", + "type": "series", + "name": "The Resident", + "year": "2018–2023" + }, + { + "_id": "53677ef9847ccc8123a13d43", + "imdb_id": "tt0397306", + "name": "American Dad!", + "type": "series", + "year": "2005–" + }, + { + "_id": "659fcf59bd36726cbba28e84", + "imdb_id": "tt14824792", + "name": "Ted", + "type": "series", + "year": "2024" + }, + { + "_id": "53677ef9847ccc8123a13845", + "imdb_id": "tt0436992", + "name": "Doctor Who", + "type": "series", + "year": "2005–" + }, + { + "_id": "53677f0c847ccc8123a18f16", + "imdb_id": "tt0078569", + "name": "Benson", + "type": "series", + "year": "1979–1986" + }, + { + "_id": "53677f29847ccc8123a1dcb5", + "imdb_id": "tt0055708", + "name": "The Tonight Show Starring Johnny Carson", + "type": "series", + "year": "1962–1992" + }, + { + "_id": "53677efc847ccc8123a150ec", + "imdb_id": "tt0112206", + "name": "Unhappily Ever After", + "type": "series", + "year": "1995–1999" + }, + { + "_id": "55e70875bf6c900d1840c69a", + "imdb_id": "tt4532368", + "name": "DC's Legends of Tomorrow", + "year": "2016–2022", + "type": "series" + }, + { + "_id": "53677efc847ccc8123a14ddc", + "imdb_id": "tt1325113", + "name": "Childrens Hospital", + "type": "series", + "year": "2008–2016" + }, + { + "_id": "53677ef9847ccc8123a13ab7", + "imdb_id": "tt1842530", + "name": "Unforgettable", + "type": "series", + "year": "2011–2016" + }, + { + "_id": "551e1e99cc9eee85bb52e13c", + "imdb_id": "tt4335742", + "name": "Lip Sync Battle", + "year": "2015–2019", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a14252", + "imdb_id": "tt0449545", + "name": "Curious George", + "type": "series", + "year": "2006–2022" + }, + { + "_id": "53677ef9847ccc8123a13a8e", + "imdb_id": "tt0350448", + "name": "Real Time with Bill Maher", + "type": "series", + "year": "2003–" + }, + { + "_id": "5ccc3c905111f1a8a3866e86", + "imdb_id": "tt8064302", + "name": "Dead to Me", + "type": "series", + "year": "2019–2022" + }, + { + "_id": "5565dba4bf6c900d18341e74", + "imdb_id": "tt4158110", + "name": "Mr. Robot", + "year": "2015–2019", + "type": "series" + }, + { + "_id": "53677f1c847ccc8123a1bba1", + "imdb_id": "tt0278238", + "name": "Samurai Jack", + "type": "series", + "year": "2001–2017" + }, + { + "_id": "53677efe847ccc8123a15be6", + "imdb_id": "tt0062539", + "name": "Adam-12", + "type": "series", + "year": "1968–1975" + }, + { + "_id": "53677ef9847ccc8123a13925", + "imdb_id": "tt1722512", + "name": "Ultimate Spider-Man", + "type": "series", + "year": "2012–2017" + }, + { + "_id": "5c1d4816173739c9f496c34d", + "imdb_id": "tt4087032", + "name": "Good Mythical Morning", + "type": "series", + "year": "2012–" + }, + { + "_id": "53677f23847ccc8123a1cfd5", + "imdb_id": "tt2632424", + "name": "The Originals", + "type": "series", + "year": "2013–2018" + }, + { + "_id": "53677f1b847ccc8123a1ba38", + "imdb_id": "tt2234222", + "name": "Orphan Black", + "type": "series", + "year": "2013–2017" + }, + { + "_id": "53677ef9847ccc8123a137c4", + "imdb_id": "tt1429449", + "name": "Lost Girl", + "type": "series", + "year": "2010–2016" + }, + { + "_id": "53677f00847ccc8123a16283", + "imdb_id": "tt0065327", + "name": "Night Gallery", + "type": "series", + "year": "1969–1973" + }, + { + "_id": "5b8e9359173739c9f47db502", + "imdb_id": "tt5715524", + "name": "Mayans M.C.", + "type": "series", + "year": "2018–2023" + }, + { + "_id": "53677f42847ccc8123a1fa06", + "imdb_id": "tt0292414", + "name": "McLeod's Daughters", + "type": "series", + "year": "2001–2009" + }, + { + "_id": "6153c63c64ec43ef9841952d", + "imdb_id": "tt11640018", + "name": "La Brea", + "type": "series", + "year": "2021–2024" + }, + { + "_id": "54ff69e9711bd19c92add0a7", + "imdb_id": "tt0063927", + "name": "Marcus Welby, M.D.", + "year": "1969–1976", + "type": "series" + }, + { + "_id": "53677f2c847ccc8123a1e16c", + "imdb_id": "tt2729716", + "name": "The Haves and the Have Nots", + "type": "series", + "year": "2013–2021" + }, + { + "_id": "53677ef9847ccc8123a14310", + "imdb_id": "tt0972534", + "name": "iCarly", + "type": "series", + "year": "2007–2012" + }, + { + "_id": "53677efd847ccc8123a15716", + "imdb_id": "tt1131746", + "name": "Big Time Rush", + "type": "series", + "year": "2009–2023" + }, + { + "_id": "53ac6496a8f27b1bb90b2fae", + "imdb_id": "tt2699128", + "name": "The Leftovers", + "type": "series", + "year": "2014–2017" + }, + { + "_id": "5c0ddf86173739c9f4421a08", + "imdb_id": "tt0088476", + "name": "Alfred Hitchcock Presents", + "type": "series", + "year": "1985–1989" + }, + { + "_id": "53677ef9847ccc8123a13c8b", + "imdb_id": "tt1586680", + "name": "Shameless", + "type": "series", + "year": "2011–2021" + }, + { + "_id": "53677efa847ccc8123a1465c", + "imdb_id": "tt0092345", + "name": "DuckTales", + "type": "series", + "year": "1987–1990" + }, + { + "_id": "53677f2c847ccc8123a1e318", + "imdb_id": "tt2309295", + "name": "Hemlock Grove", + "type": "series", + "year": "2013–2015" + }, + { + "_id": "54c0f5778527d2e0cb509758", + "imdb_id": "tt3230454", + "name": "The Last Man on Earth", + "type": "series", + "year": "2015–2018" + }, + { + "_id": "5c53554fd582b25756bc86bd", + "imdb_id": "tt0101069", + "name": "The Commish", + "type": "series", + "year": "1991–1996" + }, + { + "_id": "6523e206bd36726cbb910fab", + "imdb_id": "tt2640044", + "name": "Masters of the Air", + "type": "series", + "year": "2024–" + }, + { + "_id": "53677f5a847ccc8123a21afc", + "imdb_id": "tt0434706", + "name": "Monster", + "type": "series", + "year": "2004–2005" + }, + { + "_id": "53677f0c847ccc8123a1912a", + "imdb_id": "tt0106057", + "name": "Lois & Clark: The New Adventures of Superman", + "type": "series", + "year": "1993–1997" + }, + { + "_id": "543d5217a8f27b1bb90d39af", + "imdb_id": "tt2150751", + "name": "Chihayafuru", + "type": "series", + "year": "2011–2020" + }, + { + "_id": "53677f45847ccc8123a1fce0", + "imdb_id": "tt2356777", + "name": "True Detective", + "type": "series", + "year": "2014–" + }, + { + "_id": "53677f0c847ccc8123a191af", + "imdb_id": "tt2193021", + "name": "Arrow", + "type": "series", + "year": "2012–2020" + }, + { + "_id": "53677efd847ccc8123a15806", + "imdb_id": "tt0059978", + "name": "Dark Shadows", + "type": "series", + "year": "1966–1971" + }, + { + "_id": "53677efa847ccc8123a149f1", + "imdb_id": "tt0074074", + "name": "Wonder Woman", + "type": "series", + "year": "1975–1979" + }, + { + "_id": "53677ef9847ccc8123a13812", + "imdb_id": "tt1578873", + "name": "Pretty Little Liars", + "type": "series", + "year": "2010–2017" + }, + { + "_id": "5a13e030543165dcd8f723cd", + "imdb_id": "tt1236246", + "type": "series", + "name": "Runaways", + "year": "2017–2019" + }, + { + "_id": "53677f29847ccc8123a1dbee", + "imdb_id": "tt0111987", + "name": "Goosebumps", + "type": "series", + "year": "1995–1998" + }, + { + "_id": "53677efd847ccc8123a15b66", + "imdb_id": "tt0105946", + "name": "Babylon 5", + "type": "series", + "year": "1993–1998" + }, + { + "_id": "53677ef9847ccc8123a1400b", + "imdb_id": "tt0362359", + "name": "The O.C.", + "type": "series", + "year": "2003–2007" + }, + { + "_id": "53677f0f847ccc8123a199d6", + "imdb_id": "tt2402137", + "name": "Legends", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "586d4c941635517fbf5677ae", + "imdb_id": "tt1734135", + "name": "Trollhunters: Tales of Arcadia", + "type": "series", + "year": "2016–2018" + }, + { + "_id": "558a8c99bf6c900d1837984d", + "imdb_id": "tt0048899", + "name": "The Steve Allen Plymouth Show", + "year": "1956–1960", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13c9d", + "imdb_id": "tt1086761", + "name": "Keeping Up with the Kardashians", + "type": "series", + "year": "2007–2021" + }, + { + "_id": "53677f00847ccc8123a163ae", + "imdb_id": "tt1714204", + "name": "Perception", + "type": "series", + "year": "2012–2015" + }, + { + "_id": "53677ef9847ccc8123a13990", + "imdb_id": "tt1119176", + "name": "Underbelly", + "type": "series", + "year": "2008–2013" + }, + { + "_id": "53677f07847ccc8123a180c9", + "imdb_id": "tt0373474", + "name": "1-800-Missing", + "type": "series", + "year": "2003–2006" + }, + { + "_id": "53677f1a847ccc8123a1b685", + "imdb_id": "tt2654620", + "name": "The Strain", + "type": "series", + "year": "2014–2017" + }, + { + "_id": "53677f6d847ccc8123a230d1", + "imdb_id": "tt3121722", + "name": "PAW Patrol", + "type": "series", + "year": "2013–" + }, + { + "_id": "5bab132d173739c9f47613ec", + "imdb_id": "tt7817340", + "name": "New Amsterdam", + "type": "series", + "year": "2018–2023" + }, + { + "_id": "5c0ec329173739c9f4b0fc58", + "imdb_id": "tt7658402", + "name": "Harley Quinn", + "type": "series", + "year": "2019–" + }, + { + "_id": "53677ef9847ccc8123a137f5", + "imdb_id": "tt1441109", + "name": "Cougar Town", + "type": "series", + "year": "2009–2015" + }, + { + "_id": "53677ef9847ccc8123a1401e", + "imdb_id": "tt0852863", + "name": "Phineas and Ferb", + "type": "series", + "year": "2007–2024" + }, + { + "_id": "53a5820aa8f27b1bb90b1c89", + "imdb_id": "tt0050066", + "name": "Tales of Wells Fargo", + "type": "series", + "year": "1957–1962" + }, + { + "_id": "53677f02847ccc8123a1700d", + "imdb_id": "tt0081873", + "name": "Hill Street Blues", + "type": "series", + "year": "1981–1987" + }, + { + "_id": "53677ef9847ccc8123a13b23", + "imdb_id": "tt1280822", + "name": "Drop Dead Diva", + "type": "series", + "year": "2009–2014" + }, + { + "_id": "53677f00847ccc8123a16325", + "imdb_id": "tt0411027", + "name": "Strictly Come Dancing", + "type": "series", + "year": "2004–" + }, + { + "_id": "53677ef9847ccc8123a13792", + "imdb_id": "tt0924651", + "name": "The Graham Norton Show", + "type": "series", + "year": "2007–" + }, + { + "_id": "5385c00a847ccc8123ad85be", + "imdb_id": "tt2477230", + "name": "The Night Shift", + "type": "series", + "year": "2014–2017" + }, + { + "_id": "53677f24847ccc8123a1d166", + "imdb_id": "tt0078657", + "name": "Minder", + "type": "series", + "year": "1979–1994" + }, + { + "_id": "53677ef5847ccc8123a13762", + "imdb_id": "tt1839578", + "name": "Person of Interest", + "type": "series", + "year": "2011–2016" + }, + { + "_id": "541c1363a8f27b1bb90cb4f3", + "imdb_id": "tt3187578", + "name": "The Mysteries of Laura", + "type": "series", + "year": "2014–2016" + }, + { + "_id": "53677f0c847ccc8123a19067", + "imdb_id": "tt3032476", + "name": "Better Call Saul", + "type": "series", + "year": "2015–2022" + }, + { + "_id": "53677f26847ccc8123a1d75d", + "imdb_id": "tt0081930", + "name": "Simon & Simon", + "type": "series", + "year": "1981–1989" + }, + { + "_id": "54fb5f5a711bd19c92ad44ce", + "imdb_id": "tt1316554", + "name": "Black Butler", + "year": "2008–2011", + "type": "series" + }, + { + "_id": "5fccc65854242533410f04c2", + "imdb_id": "tt7440726", + "name": "Your Honor", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "64cfc2e6bd36726cbb47fe06", + "imdb_id": "tt1536749", + "name": "Let's Make a Deal", + "type": "series", + "year": "2009–" + }, + { + "_id": "53677efd847ccc8123a159fd", + "imdb_id": "tt0094484", + "name": "In the Heat of the Night", + "type": "series", + "year": "1988–1995" + }, + { + "_id": "564dedcdbb83c664989515f4", + "imdb_id": "tt4655480", + "name": "Chicago Med", + "year": "2015–", + "type": "series" + }, + { + "_id": "53677f08847ccc8123a18587", + "imdb_id": "tt0050073", + "name": "Wagon Train", + "type": "series", + "year": "1957–1965" + }, + { + "_id": "53677ef9847ccc8123a138f6", + "imdb_id": "tt1442462", + "name": "The Good Wife", + "type": "series", + "year": "2009–2016" + }, + { + "_id": "53677ef9847ccc8123a1443d", + "imdb_id": "tt0185103", + "name": "WWE Raw", + "type": "series", + "year": "1993–" + }, + { + "_id": "5f64e3bb54242533411e7c2d", + "imdb_id": "tt10436228", + "name": "Jurassic World: Camp Cretaceous", + "type": "series", + "year": "2020–2022" + }, + { + "_id": "53677ef9847ccc8123a13dbf", + "imdb_id": "tt0052520", + "name": "The Twilight Zone", + "type": "series", + "year": "1959–1964" + }, + { + "_id": "5c0aaed0173739c9f487e905", + "imdb_id": "tt7772602", + "name": "In the Dark", + "type": "series", + "year": "2019–2022" + }, + { + "_id": "53677f72847ccc8123a2359d", + "imdb_id": "tt2349440", + "name": "Robot and Monster", + "type": "series", + "year": "2012–2015" + }, + { + "_id": "53677f12847ccc8123a19eff", + "imdb_id": "tt0072574", + "name": "Switch", + "type": "series", + "year": "1975–1978" + }, + { + "_id": "53677f2e847ccc8123a1e472", + "imdb_id": "tt0364774", + "name": "Lilo & Stitch: The Series", + "type": "series", + "year": "2003–2006" + }, + { + "_id": "53677f00847ccc8123a166d0", + "imdb_id": "tt0092359", + "name": "Full House", + "type": "series", + "year": "1987–1995" + }, + { + "_id": "5f7811ea54242533419be55f", + "imdb_id": "tt12343534", + "name": "Jujutsu Kaisen", + "type": "series", + "year": "2020–" + }, + { + "_id": "53677ef9847ccc8123a13d3a", + "imdb_id": "tt0121955", + "name": "South Park", + "type": "series", + "year": "1997–" + }, + { + "_id": "53677f0a847ccc8123a18c00", + "imdb_id": "tt0429455", + "name": "Commander in Chief", + "type": "series", + "year": "2005–2006" + }, + { + "_id": "53677ef9847ccc8123a137d7", + "imdb_id": "tt0096555", + "name": "Casualty", + "type": "series", + "year": "1986–" + }, + { + "_id": "53677efc847ccc8123a15386", + "imdb_id": "tt0426769", + "name": "Peppa Pig", + "type": "series", + "year": "2004–" + }, + { + "_id": "53677efa847ccc8123a14613", + "imdb_id": "tt0364784", + "name": "Austin City Limits", + "type": "series", + "year": "1975–" + }, + { + "_id": "61b1d02d64ec43ef98c4a82b", + "imdb_id": "tt13819960", + "name": "And Just Like That...", + "type": "series", + "year": "2021–" + }, + { + "_id": "54fb5f1a711bd19c92ad42b7", + "imdb_id": "tt0046587", + "name": "Climax!", + "year": "1954–1958", + "type": "series" + }, + { + "_id": "53677efc847ccc8123a14ee5", + "imdb_id": "tt1780441", + "name": "Portlandia", + "type": "series", + "year": "2011–2018" + }, + { + "_id": "53677f2c847ccc8123a1e004", + "imdb_id": "tt2188671", + "name": "Bates Motel", + "type": "series", + "year": "2013–2017" + }, + { + "_id": "59c9a93b1712e0f4dd856e03", + "imdb_id": "tt6226232", + "type": "series", + "name": "Young Sheldon", + "year": "2017–2024" + }, + { + "_id": "54c0f5778527d2e0cb50975a", + "imdb_id": "tt2758770", + "name": "Star vs. the Forces of Evil", + "type": "series", + "year": "2015–2019" + }, + { + "_id": "61f3c70a64ec43ef9835ed7b", + "imdb_id": "tt14169960", + "name": "All of Us Are Dead", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677ef5847ccc8123a1374c", + "imdb_id": "tt1844624", + "name": "American Horror Story", + "type": "series", + "year": "2011–" + }, + { + "_id": "53677f72847ccc8123a23530", + "imdb_id": "tt3232262", + "name": "Sonic Boom", + "type": "series", + "year": "2014–2017" + }, + { + "_id": "53677f2c847ccc8123a1e21b", + "imdb_id": "tt2262532", + "name": "The Fosters", + "type": "series", + "year": "2013–2018" + }, + { + "_id": "53677f02847ccc8123a16d5c", + "imdb_id": "tt0058824", + "name": "Lost in Space", + "type": "series", + "year": "1965–1968" + }, + { + "_id": "615e6a1764ec43ef981b7bb2", + "imdb_id": "tt12887536", + "name": "CSI: Vegas", + "type": "series", + "year": "2021–" + }, + { + "_id": "53f6326fa8f27b1bb90c33c2", + "imdb_id": "tt2930604", + "name": "Star Wars: Rebels", + "type": "series", + "year": "2014–2018" + }, + { + "_id": "53677f07847ccc8123a18227", + "imdb_id": "tt1224144", + "name": "Reborn!", + "type": "series", + "year": "2006–2010" + }, + { + "_id": "53677ef9847ccc8123a14072", + "imdb_id": "tt0460644", + "name": "Ghost Whisperer", + "type": "series", + "year": "2005–2010" + }, + { + "_id": "5c0bb8cc173739c9f4584c70", + "imdb_id": "tt9288030", + "type": "series", + "name": "Reacher", + "year": "2022–" + }, + { + "_id": "5c3d0203d582b2575697d498", + "imdb_id": "tt0101165", + "name": "The Paradise Club", + "type": "series", + "year": "1989–1990" + }, + { + "_id": "548061978527d2e0cb4fc346", + "imdb_id": "tt0163507", + "name": "Whose Line Is It Anyway?", + "type": "series", + "year": "1998–2007" + }, + { + "_id": "54b28a0c8527d2e0cb50621e", + "imdb_id": "tt3921180", + "name": "Scream: The TV Series", + "type": "series", + "year": "2015–2019" + }, + { + "_id": "53677f14847ccc8123a1a4ca", + "imdb_id": "tt1114855", + "name": "Bakugan Battle Brawlers", + "type": "series", + "year": "2007–2011" + }, + { + "_id": "55052246711bd19c92add653", + "imdb_id": "tt3604232", + "name": "Transformers: Robots in Disguise", + "year": "2014–2020", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13d88", + "imdb_id": "tt1828327", + "name": "Last Man Standing", + "type": "series", + "year": "2011–2021" + }, + { + "_id": "53677ef9847ccc8123a13806", + "imdb_id": "tt0944947", + "name": "Game of Thrones", + "type": "series", + "year": "2011–2019" + }, + { + "_id": "53677ef9847ccc8123a13d68", + "imdb_id": "tt1551632", + "name": "Rizzoli & Isles", + "type": "series", + "year": "2010–2016" + }, + { + "_id": "53677efa847ccc8123a149c9", + "imdb_id": "tt1836037", + "name": "Longmire", + "type": "series", + "year": "2012–2017" + }, + { + "_id": "53677f0c847ccc8123a18dd3", + "imdb_id": "tt0135733", + "name": "Match of the Day", + "type": "series", + "year": "1964–" + }, + { + "_id": "5c107cc6173739c9f4d23988", + "imdb_id": "tt2131864", + "name": "Junior Bake Off", + "type": "series", + "year": "2011–" + }, + { + "_id": "53677f19847ccc8123a1b435", + "imdb_id": "tt0052461", + "name": "Dennis the Menace", + "type": "series", + "year": "1959–1963" + }, + { + "_id": "542a5ae8a8f27b1bb90ce56d", + "imdb_id": "tt2267661", + "name": "Pointless Celebrities", + "type": "series", + "year": "2010–" + }, + { + "_id": "5c150371173739c9f4da905e", + "imdb_id": "tt0199253", + "name": "Noddy", + "type": "series", + "year": "1998–2000" + }, + { + "_id": "58c984c81635517fbf56e5ff", + "imdb_id": "tt3920596", + "name": "Big Little Lies", + "type": "series", + "year": "2017–2019" + }, + { + "_id": "53677f22847ccc8123a1cd4d", + "imdb_id": "tt0078610", + "name": "The Facts of Life", + "type": "series", + "year": "1979–1988" + }, + { + "_id": "53677efa847ccc8123a14c2f", + "imdb_id": "tt0052522", + "name": "The Untouchables", + "type": "series", + "year": "1959–1963" + }, + { + "_id": "5378cbd6847ccc8123ad24ec", + "imdb_id": "tt2937900", + "name": "The Knick", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "53677f1b847ccc8123a1b70b", + "imdb_id": "tt0063951", + "name": "Sesame Street", + "type": "series", + "year": "1969–" + }, + { + "_id": "53677ef9847ccc8123a13f18", + "imdb_id": "tt0118401", + "name": "Midsomer Murders", + "type": "series", + "year": "1997–" + }, + { + "_id": "53677ef9847ccc8123a137e7", + "imdb_id": "tt1825133", + "name": "Smash", + "type": "series", + "year": "2012–2013" + }, + { + "_id": "53677f6f847ccc8123a232cd", + "imdb_id": "tt1725902", + "name": "Fish Hooks", + "type": "series", + "year": "2010–2014" + }, + { + "_id": "5bc6a9a3173739c9f4d0c93a", + "imdb_id": "tt7587890", + "name": "The Rookie", + "type": "series", + "year": "2018–" + }, + { + "_id": "53677f63847ccc8123a22685", + "imdb_id": "tt0075500", + "name": "Eight Is Enough", + "type": "series", + "year": "1977–1981" + }, + { + "_id": "53677f1d847ccc8123a1beb3", + "imdb_id": "tt0962740", + "name": "Hell Girl", + "type": "series", + "year": "2005–2006" + }, + { + "_id": "5c102970173739c9f426ca72", + "imdb_id": "tt1738419", + "name": "Bakuman.", + "type": "series", + "year": "2010–2013" + }, + { + "_id": "5c25921d173739c9f47f9f44", + "imdb_id": "tt0486171", + "name": "Ikki tousen", + "type": "series", + "year": "2003–" + }, + { + "_id": "5c0a1621173739c9f47a8100", + "imdb_id": "tt8712204", + "name": "Batwoman", + "type": "series", + "year": "2019–2022" + }, + { + "_id": "5bc40456173739c9f46fcfcf", + "imdb_id": "tt6394324", + "name": "Charmed", + "type": "series", + "year": "2018–2022" + }, + { + "_id": "53677f37847ccc8123a1ecc7", + "imdb_id": "tt1460205", + "name": "Dinosaur Train", + "type": "series", + "year": "2009–2023" + }, + { + "_id": "53677ef9847ccc8123a13dde", + "imdb_id": "tt1132290", + "name": "Warehouse 13", + "type": "series", + "year": "2009–2014" + }, + { + "_id": "5c3fd77bd582b25756027e8b", + "imdb_id": "tt3985228", + "name": "Shirobako", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "619f4c7564ec43ef98589687", + "imdb_id": "tt10160804", + "type": "series", + "name": "Hawkeye", + "year": "2021" + }, + { + "_id": "53677f07847ccc8123a181e1", + "imdb_id": "tt0069602", + "name": "Last of the Summer Wine", + "type": "series", + "year": "1973–2010" + }, + { + "_id": "64e355a6bd36726cbbcbc6e5", + "imdb_id": "tt12324366", + "name": "Percy Jackson and the Olympians", + "type": "series", + "year": "2023–" + }, + { + "_id": "64f1690bbd36726cbb004423", + "imdb_id": "tt15248880", + "name": "Adventure Time: Fionna & Cake", + "type": "series", + "year": "2023" + }, + { + "_id": "53677ef9847ccc8123a14167", + "imdb_id": "tt1355642", + "name": "Fullmetal Alchemist: Brotherhood", + "type": "series", + "year": "2009–2010" + }, + { + "_id": "556060ebbf6c900d1833f534", + "imdb_id": "tt4546568", + "name": "Infinite Challenge", + "year": "2005–2018", + "type": "series" + }, + { + "_id": "53677efa847ccc8123a1486d", + "imdb_id": "tt0312172", + "name": "Monk", + "type": "series", + "year": "2002–2009" + }, + { + "_id": "53677ef9847ccc8123a14448", + "imdb_id": "tt0264235", + "name": "Curb Your Enthusiasm", + "type": "series", + "year": "2000–2024" + }, + { + "_id": "570f045f890e549c9a5833d0", + "imdb_id": "tt3846642", + "name": "The Girlfriend Experience", + "year": "2016–2021", + "type": "series" + }, + { + "_id": "53677efc847ccc8123a1501d", + "imdb_id": "tt1388589", + "name": "The Super Hero Squad Show", + "type": "series", + "year": "2009–2011" + }, + { + "_id": "53677efd847ccc8123a159fa", + "imdb_id": "tt0167743", + "name": "The Wild Thornberrys", + "type": "series", + "year": "1998–2004" + }, + { + "_id": "58e7adcc1635517fbf56e713", + "imdb_id": "tt4902964", + "name": "Rapunzel's Tangled Adventure", + "type": "series", + "year": "2017–2020" + }, + { + "_id": "53677f45847ccc8123a1fdc7", + "imdb_id": "tt0068122", + "name": "The Protectors", + "type": "series", + "year": "1972–1974" + }, + { + "_id": "53677f02847ccc8123a16ccc", + "imdb_id": "tt0083505", + "name": "The Young Ones", + "type": "series", + "year": "1982–1984" + }, + { + "_id": "53677efc847ccc8123a14e3e", + "imdb_id": "tt0084967", + "name": "The A-Team", + "type": "series", + "year": "1983–1987" + }, + { + "_id": "53677f1d847ccc8123a1bd95", + "imdb_id": "tt2306299", + "name": "Vikings", + "type": "series", + "year": "2013–2020" + }, + { + "_id": "53677f57847ccc8123a21683", + "imdb_id": "tt0115200", + "name": "Hey Arnold!", + "type": "series", + "year": "1996–2004" + }, + { + "_id": "53677f19847ccc8123a1b2b4", + "imdb_id": "tt2661044", + "name": "The 100", + "type": "series", + "year": "2014–2020" + }, + { + "_id": "53677ef9847ccc8123a13bbb", + "imdb_id": "tt1663676", + "name": "Awkward.", + "type": "series", + "year": "2011–2016" + }, + { + "_id": "61d3d75a64ec43ef9832f794", + "imdb_id": "tt10023294", + "name": "That's My Jam", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677f79847ccc8123a23cbc", + "imdb_id": "tt3559124", + "name": "The Tom and Jerry Show", + "type": "series", + "year": "2011–2022" + }, + { + "_id": "5542e9cfb0c92842850377ce", + "imdb_id": "tt4189022", + "name": "Ash vs Evil Dead", + "year": "2015–2018", + "type": "series" + }, + { + "_id": "549447ca8527d2e0cb5009cc", + "imdb_id": "tt0156214", + "name": "Kamen Rider", + "type": "series", + "year": "1971–1973" + }, + { + "_id": "60efc10764ec43ef981888b3", + "imdb_id": "tt12306692", + "name": "American Horror Stories", + "type": "series", + "year": "2021–" + }, + { + "_id": "61e6578464ec43ef98bd4a09", + "imdb_id": "tt14500082", + "name": "How I Met Your Father", + "type": "series", + "year": "2022–2023" + }, + { + "_id": "5fb4a6e15424253341a3194b", + "imdb_id": "tt11794642", + "name": "Big Sky", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "53677ef9847ccc8123a13e11", + "imdb_id": "tt0115355", + "name": "Silent Witness", + "type": "series", + "year": "1996–" + }, + { + "_id": "5c0a0623173739c9f4697374", + "imdb_id": "tt5721172", + "name": "The Worst Witch", + "type": "series", + "year": "2017–" + }, + { + "_id": "53677f15847ccc8123a1a94e", + "imdb_id": "tt0077008", + "name": "Fantasy Island", + "type": "series", + "year": "1977–1984" + }, + { + "_id": "53677ef9847ccc8123a13c4a", + "imdb_id": "tt0328733", + "name": "Beyblade", + "type": "series", + "year": "2001–2005" + }, + { + "_id": "5ba5acd4173739c9f4ade561", + "imdb_id": "tt4944090", + "name": "Jay Leno's Garage", + "type": "series", + "year": "2015–2022" + }, + { + "_id": "53677f02847ccc8123a16d68", + "imdb_id": "tt1710177", + "name": "The Octonauts", + "type": "series", + "year": "2010–2021" + }, + { + "_id": "53677f17847ccc8123a1aa8b", + "imdb_id": "tt0115088", + "name": "Alarm für Cobra 11 - Die Autobahnpolizei", + "type": "series", + "year": "1996–" + }, + { + "_id": "5c16bc03173739c9f409ac4c", + "imdb_id": "tt0306398", + "name": "Star Academy", + "type": "series", + "year": "2001–" + }, + { + "_id": "53677ef9847ccc8123a13ce1", + "imdb_id": "tt0318912", + "name": "Natural World", + "type": "series", + "year": "1983–" + }, + { + "_id": "57e33ebad7e54929823e7a5b", + "imdb_id": "tt5296406", + "type": "series", + "name": "Designated Survivor", + "year": "2016–2019" + }, + { + "_id": "5c0c1eb2173739c9f42779dd", + "imdb_id": "tt5607976", + "name": "His Dark Materials", + "type": "series", + "year": "2019–2022" + }, + { + "_id": "5fb631a95424253341ec0892", + "imdb_id": "tt7569576", + "name": "The Flight Attendant", + "type": "series", + "year": "2020–2022" + }, + { + "_id": "53677f09847ccc8123a185e7", + "imdb_id": "tt0094582", + "name": "The Wonder Years", + "type": "series", + "year": "1988–1993" + }, + { + "_id": "5f8b993c5424253341a0ed97", + "imdb_id": "tt12287748", + "name": "Yashahime: Princess Half-Demon", + "type": "series", + "year": "2020–" + }, + { + "_id": "53677efa847ccc8123a14a23", + "imdb_id": "tt1837576", + "name": "Scandal", + "type": "series", + "year": "2012–2018" + }, + { + "_id": "53677efd847ccc8123a15afb", + "imdb_id": "tt0106079", + "name": "NYPD Blue", + "type": "series", + "year": "1993–2005" + }, + { + "_id": "53677f0a847ccc8123a1884c", + "imdb_id": "tt0184122", + "name": "Holby City", + "type": "series", + "year": "1999–2022" + }, + { + "_id": "53677ef9847ccc8123a13b12", + "imdb_id": "tt0086815", + "name": "Thomas & Friends", + "type": "series", + "year": "1984–2021" + }, + { + "_id": "53677ef9847ccc8123a13ea2", + "imdb_id": "tt2022170", + "name": "The Client List", + "type": "series", + "year": "2011–2013" + }, + { + "_id": "53677efa847ccc8123a14a3e", + "imdb_id": "tt1545214", + "name": "Kung Fu Panda: Legends of Awesomeness", + "type": "series", + "year": "2011–2016" + }, + { + "_id": "53677f0f847ccc8123a19af9", + "imdb_id": "tt0062568", + "name": "Hawaii Five-O", + "type": "series", + "year": "1968–1980" + }, + { + "_id": "53677f2c847ccc8123a1dfbf", + "imdb_id": "tt2193041", + "name": "Beauty and the Beast", + "type": "series", + "year": "2012–2016" + }, + { + "_id": "53677f1d847ccc8123a1bdcb", + "imdb_id": "tt0105941", + "name": "Animaniacs", + "type": "series", + "year": "1993–1998" + }, + { + "_id": "53677ef9847ccc8123a13c46", + "imdb_id": "tt1839337", + "name": "The Voice", + "type": "series", + "year": "2011–" + }, + { + "_id": "53677f68847ccc8123a22c16", + "imdb_id": "tt2573338", + "name": "Mighty Med", + "type": "series", + "year": "2013–2015" + }, + { + "_id": "53677f08847ccc8123a18429", + "imdb_id": "tt0057733", + "name": "Bewitched", + "type": "series", + "year": "1964–1972" + }, + { + "_id": "5a73f3a8543165dcd83504c8", + "imdb_id": "tt6461726", + "type": "series", + "name": "A.P. Bio", + "year": "2018–2021" + }, + { + "_id": "588d421c1635517fbf56ae47", + "imdb_id": "tt6236572", + "name": "Mary Kills People", + "type": "series", + "year": "2017–2019" + }, + { + "_id": "53677f0c847ccc8123a18eac", + "imdb_id": "tt0981456", + "name": "Baki the Grappler", + "type": "series", + "year": "2001–2007" + }, + { + "_id": "5c0a8c31173739c9f44448b8", + "imdb_id": "tt6156584", + "name": "Snowpiercer", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "53677ef9847ccc8123a13ac4", + "imdb_id": "tt0131613", + "name": "Teenage Mutant Ninja Turtles", + "type": "series", + "year": "1987–1996" + }, + { + "_id": "53677ef9847ccc8123a13f33", + "imdb_id": "tt0106145", + "name": "Star Trek: Deep Space Nine", + "type": "series", + "year": "1993–1999" + }, + { + "_id": "53677f1c847ccc8123a1bafa", + "imdb_id": "tt0088471", + "name": "A.D.", + "type": "series", + "year": "1985" + }, + { + "_id": "53677f14847ccc8123a1a422", + "imdb_id": "tt0390733", + "name": "Last Exile", + "type": "series", + "year": "2003" + }, + { + "_id": "5c1814b7173739c9f43b44eb", + "imdb_id": "tt9174578", + "name": "Around the World in 80 Days", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677ef9847ccc8123a1379c", + "imdb_id": "tt0903747", + "name": "Breaking Bad", + "type": "series", + "year": "2008–2013" + }, + { + "_id": "53677f79847ccc8123a23c94", + "imdb_id": "tt2904418", + "name": "Free!", + "type": "series", + "year": "2013–2018" + }, + { + "_id": "5c168c11173739c9f4a4b91b", + "imdb_id": "tt0337762", + "name": "G.I. Joe", + "type": "series", + "year": "1990–1992" + }, + { + "_id": "588b16791635517fbf56a99f", + "imdb_id": "tt6264782", + "name": "Mickey and the Roadster Racers", + "type": "series", + "year": "2017–2021" + }, + { + "_id": "53677f32847ccc8123a1e6b0", + "imdb_id": "tt2244495", + "name": "The Eric Andre Show", + "type": "series", + "year": "2012–" + }, + { + "_id": "53677f14847ccc8123a1a572", + "imdb_id": "tt0068069", + "name": "Emmerdale Farm", + "type": "series", + "year": "1972–" + }, + { + "_id": "53677f03847ccc8123a171d5", + "imdb_id": "tt0058805", + "name": "Get Smart", + "type": "series", + "year": "1965–1970" + }, + { + "_id": "5c13051d173739c9f4718322", + "imdb_id": "tt0052507", + "name": "The Bullwinkle Show", + "type": "series", + "year": "1959–1963" + }, + { + "_id": "5c1bf2b1173739c9f438ae48", + "imdb_id": "tt4838372", + "name": "Osomatsu-san", + "type": "series", + "year": "2015–2021" + }, + { + "_id": "53677f7c847ccc8123a23e8b", + "imdb_id": "tt3127020", + "name": "Faking It", + "type": "series", + "year": "2014–2016" + }, + { + "_id": "55198016cc9eee85bb52dd78", + "imdb_id": "tt3219170", + "name": "Harvey Beaks", + "year": "2015–2017", + "type": "series" + }, + { + "_id": "53677f13847ccc8123a1a281", + "imdb_id": "tt0312081", + "name": "8 Simple Rules", + "type": "series", + "year": "2002–2005" + }, + { + "_id": "53677f68847ccc8123a22c3e", + "imdb_id": "tt2252938", + "name": "Wander Over Yonder", + "type": "series", + "year": "2013–2016" + }, + { + "_id": "53677ef9847ccc8123a140b4", + "imdb_id": "tt0437745", + "name": "Robot Chicken", + "type": "series", + "year": "2001–" + }, + { + "_id": "5c5dd64ad582b257568dd9d7", + "imdb_id": "tt7821582", + "name": "Truth Be Told", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "53677f00847ccc8123a1631e", + "imdb_id": "tt0162065", + "name": "Angel", + "type": "series", + "year": "1999–2004" + }, + { + "_id": "565dff8dbb83c66498973339", + "imdb_id": "tt4477976", + "name": "Superstore", + "year": "2015–2021", + "type": "series" + }, + { + "_id": "53677f43847ccc8123a1fc19", + "imdb_id": "tt0454656", + "name": "The Wiggles", + "type": "series", + "year": "1993–2022" + }, + { + "_id": "53677f05847ccc8123a1772e", + "imdb_id": "tt0052451", + "name": "Bonanza", + "type": "series", + "year": "1959–1973" + }, + { + "_id": "53677efc847ccc8123a150fe", + "imdb_id": "tt0052504", + "name": "Rawhide", + "type": "series", + "year": "1959–1965" + }, + { + "_id": "53677efa847ccc8123a1477d", + "imdb_id": "tt1055238", + "name": "Would I Lie to You?", + "type": "series", + "year": "2007–" + }, + { + "_id": "5e5e9af0c4ccb5dd92c40be4", + "imdb_id": "tt9193770", + "name": "Isekai Quartet", + "type": "series", + "year": "2019–" + }, + { + "_id": "53677ef9847ccc8123a13d06", + "imdb_id": "tt0285331", + "name": "24", + "type": "series", + "year": "2001–2010" + }, + { + "_id": "6576e81ebd36726cbbcf3e52", + "imdb_id": "tt14044212", + "name": "Mr. & Mrs. Smith", + "type": "series", + "year": "2024–" + }, + { + "_id": "53677ef9847ccc8123a140e9", + "imdb_id": "tt0160904", + "name": "MI-5", + "type": "series", + "year": "2002–2011" + }, + { + "_id": "6013950654242533412b1da9", + "imdb_id": "tt13274038", + "name": "True Beauty", + "type": "series", + "year": "2020–2021" + }, + { + "_id": "53677f13847ccc8123a1a35b", + "imdb_id": "tt0106168", + "name": "Walker, Texas Ranger", + "type": "series", + "year": "1993–2001" + }, + { + "_id": "53677eff847ccc8123a15ff1", + "imdb_id": "tt1214085", + "name": "Soul Eater", + "type": "series", + "year": "2008–2009" + }, + { + "_id": "54fb5f21711bd19c92ad42c6", + "imdb_id": "tt0058842", + "name": "Public Eye", + "year": "1965–1975", + "type": "series" + }, + { + "_id": "59b03ef21712e0f4dd1e6822", + "imdb_id": "tt6128300", + "name": "Dynasty", + "year": "2017–2022", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a137ee", + "imdb_id": "tt1988386", + "name": "Miss Fisher's Murder Mysteries", + "type": "series", + "year": "2012–2015" + }, + { + "_id": "5593df94bf6c900d18388e73", + "imdb_id": "tt3250026", + "name": "Zoo", + "year": "2015–2017", + "type": "series" + }, + { + "_id": "58cfe2d01635517fbf56e655", + "imdb_id": "tt5421602", + "name": "Anne with an E", + "type": "series", + "year": "2017–2019" + }, + { + "_id": "53677ef9847ccc8123a138ad", + "imdb_id": "tt0279600", + "name": "Smallville", + "type": "series", + "year": "2001–2011" + }, + { + "_id": "5c449114d582b2575632d6db", + "imdb_id": "tt0052481", + "name": "Laramie", + "type": "series", + "year": "1959–1963" + }, + { + "_id": "541d9757a8f27b1bb90cbaf2", + "imdb_id": "tt1746428", + "name": "Sidekick", + "type": "series", + "year": "2010–2019" + }, + { + "_id": "5bd2c992173739c9f42e01f3", + "imdb_id": "tt7569592", + "name": "Chilling Adventures of Sabrina", + "type": "series", + "year": "2018–2020" + }, + { + "_id": "53677ef9847ccc8123a13c27", + "imdb_id": "tt0085032", + "name": "Hotel", + "type": "series", + "year": "1983–1988" + }, + { + "_id": "53677ef9847ccc8123a14136", + "imdb_id": "tt0056757", + "name": "The Fugitive", + "type": "series", + "year": "1963–1967" + }, + { + "_id": "5af5eba645a99666bd0c768c", + "imdb_id": "tt0069557", + "type": "series", + "name": "Barnaby Jones", + "year": "1973–1980" + }, + { + "_id": "59b03ef21712e0f4dd1e686c", + "imdb_id": "tt6470478", + "name": "The Good Doctor", + "type": "series", + "year": "2017–2024" + }, + { + "_id": "53677f68847ccc8123a22d11", + "imdb_id": "tt2942218", + "name": "Log Horizon", + "type": "series", + "year": "2013–2021" + }, + { + "_id": "53677ef9847ccc8123a139ad", + "imdb_id": "tt1583607", + "name": "Hot in Cleveland", + "type": "series", + "year": "2010–2015" + }, + { + "_id": "53677ef9847ccc8123a13a23", + "imdb_id": "tt0458254", + "name": "The Colbert Report", + "type": "series", + "year": "2005–2014" + }, + { + "_id": "57efb835d7e54929823f1ddc", + "imdb_id": "tt4508902", + "name": "One Punch Man", + "type": "series", + "year": "2015–2019" + }, + { + "_id": "53677f29847ccc8123a1dd3e", + "imdb_id": "tt2455546", + "name": "Avengers Assemble", + "type": "series", + "year": "2012–2019" + }, + { + "_id": "557ee9fcbf6c900d1835842f", + "imdb_id": "tt4494948", + "name": "Shimmer and Shine", + "year": "2015–2020", + "type": "series" + }, + { + "_id": "53677f2e847ccc8123a1e3bb", + "imdb_id": "tt0217960", + "name": "Something in the Air", + "type": "series", + "year": "2000–2002" + }, + { + "_id": "5c184bde173739c9f4a59a23", + "imdb_id": "tt9016022", + "name": "Basketball: A Love Story", + "type": "series", + "year": "2018–" + }, + { + "_id": "57e5c5ccd7e54929823e9891", + "imdb_id": "tt1399045", + "name": "MacGyver", + "year": "2016–2021", + "type": "series" + }, + { + "_id": "5d8d796fc4ccb5dd9270691c", + "imdb_id": "tt9055008", + "name": "Evil", + "type": "series", + "year": "2019–" + }, + { + "_id": "53677ef9847ccc8123a13bed", + "imdb_id": "tt0106179", + "name": "The X-Files", + "type": "series", + "year": "1993–2018" + }, + { + "_id": "53677ef9847ccc8123a13790", + "imdb_id": "tt0460681", + "name": "Supernatural", + "type": "series", + "year": "2005–2020" + }, + { + "_id": "55075dd3711bd19c92ade16d", + "imdb_id": "tt2074035", + "name": "Horizon in the Middle of Nowhere", + "year": "2011–2012", + "type": "series" + }, + { + "_id": "659540d3bd36726cbb050188", + "imdb_id": "tt26628595", + "name": "Marry My Husband", + "type": "series", + "year": "2024–" + }, + { + "_id": "61495a1b64ec43ef98158a74", + "imdb_id": "tt14218674", + "name": "NCIS: Hawai'i", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677efa847ccc8123a14904", + "imdb_id": "tt0364828", + "name": "Las Vegas", + "type": "series", + "year": "2003–2008" + }, + { + "_id": "5c11c3bb173739c9f4315778", + "imdb_id": "tt1413677", + "name": "My Big Big Friend", + "type": "series", + "year": "2011–2014" + }, + { + "_id": "5beb40b9173739c9f438ed10", + "imdb_id": "tt7745956", + "name": "She-Ra and the Princesses of Power", + "type": "series", + "year": "2018–2020" + }, + { + "_id": "53677f21847ccc8123a1ca87", + "imdb_id": "tt0292800", + "name": "The Grim Adventures of Billy & Mandy", + "type": "series", + "year": "2001–2007" + }, + { + "_id": "5ac9f99ba5989fb3214c1873", + "imdb_id": "tt7016936", + "type": "series", + "name": "Killing Eve", + "year": "2018–2022" + }, + { + "_id": "53677f00847ccc8123a16643", + "imdb_id": "tt0279077", + "name": "FLCL", + "type": "series", + "year": "2000–2001" + }, + { + "_id": "53677f32847ccc8123a1e6be", + "imdb_id": "tt2375720", + "name": "The Doctor Blake Mysteries", + "type": "series", + "year": "2013–2018" + }, + { + "_id": "53677efd847ccc8123a15622", + "imdb_id": "tt0060009", + "name": "Mission: Impossible", + "type": "series", + "year": "1966–1973" + }, + { + "_id": "5eba5d2f5424253341e2819d", + "imdb_id": "tt11886236", + "name": "Princess Connect! Re: Dive", + "type": "series", + "year": "2020–" + }, + { + "_id": "5529420ecc9eee85bb52e2c8", + "imdb_id": "tt4176370", + "name": "Guardians of the Galaxy", + "year": "2015–2019", + "type": "series" + }, + { + "_id": "53677efa847ccc8123a146a0", + "imdb_id": "tt0362357", + "name": "New Tricks", + "type": "series", + "year": "2003–2015" + }, + { + "_id": "627e4fc664ec43ef987d9245", + "imdb_id": "tt13833978", + "name": "The Lincoln Lawyer", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677f6a847ccc8123a22de5", + "imdb_id": "tt3115338", + "name": "Nisekoi", + "type": "series", + "year": "2014–2016" + }, + { + "_id": "60c6205664ec43ef98734b2e", + "imdb_id": "tt13167196", + "name": "Edens Zero", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "55c8a051bf6c900d183dc177", + "imdb_id": "tt4474344", + "name": "Blindspot", + "year": "2015–2020", + "type": "series" + }, + { + "_id": "53677efa847ccc8123a14ce9", + "imdb_id": "tt0056777", + "name": "The Outer Limits", + "type": "series", + "year": "1963–1965" + }, + { + "_id": "55198011cc9eee85bb52dd58", + "imdb_id": "tt3837246", + "name": "Assassination Classroom", + "year": "2013–2016", + "type": "series" + }, + { + "_id": "5ea932805424253341bb230e", + "imdb_id": "tt7826376", + "name": "Upload", + "type": "series", + "year": "2020–" + }, + { + "_id": "588aacf91635517fbf56a921", + "imdb_id": "tt5420376", + "name": "Riverdale", + "type": "series", + "year": "2017–2023" + }, + { + "_id": "6599a6fabd36726cbb2bbc78", + "imdb_id": "tt21209876", + "name": "Solo Leveling", + "type": "series", + "year": "2024–" + }, + { + "_id": "53677efc847ccc8123a153c5", + "imdb_id": "tt0863046", + "name": "Flight of the Conchords", + "type": "series", + "year": "2007–2009" + }, + { + "_id": "57dd5a13d7e54929823e26d9", + "imdb_id": "tt4644488", + "name": "Dragon Ball Super", + "type": "series", + "year": "2015–2018" + }, + { + "_id": "53677f0f847ccc8123a19c5f", + "imdb_id": "tt0061265", + "name": "The Invaders", + "type": "series", + "year": "1967–1968" + }, + { + "_id": "53677ef9847ccc8123a140fa", + "imdb_id": "tt0108778", + "name": "Friends", + "type": "series", + "year": "1994–2004" + }, + { + "_id": "5c0ad577173739c9f4d594b4", + "imdb_id": "tt6874502", + "name": "Unikitty!", + "type": "series", + "year": "2017–2020" + }, + { + "_id": "53677ef5847ccc8123a13753", + "imdb_id": "tt0185133", + "name": "Yu Yu Hakusho: Ghost Files", + "type": "series", + "year": "1992–1995" + }, + { + "_id": "55197feccc9eee85bb52dd0b", + "imdb_id": "tt1693435", + "name": "MAJOR", + "year": "2004–2012", + "type": "series" + }, + { + "_id": "5c0d5adc173739c9f450c6d8", + "imdb_id": "tt0293737", + "name": "The Proud Family", + "type": "series", + "year": "2001–2005" + }, + { + "_id": "53677efd847ccc8123a15b37", + "imdb_id": "tt0094469", + "name": "Garfield and Friends", + "type": "series", + "year": "1988–1995" + }, + { + "_id": "5378cbf6847ccc8123ad3456", + "imdb_id": "tt3216608", + "name": "Dr. Ken", + "type": "series", + "year": "2015–2017" + }, + { + "_id": "53677f5a847ccc8123a21bd2", + "imdb_id": "tt0432648", + "name": "Celebrity Fit Club", + "type": "series", + "year": "2005–2010" + }, + { + "_id": "53677ef9847ccc8123a137d3", + "imdb_id": "tt1758772", + "name": "Switched at Birth", + "type": "series", + "year": "2011–2017" + }, + { + "_id": "53677efa847ccc8123a14951", + "imdb_id": "tt1135300", + "name": "Dollhouse", + "type": "series", + "year": "2009–2010" + }, + { + "_id": "58e5f46f1635517fbf56e6c6", + "imdb_id": "tt5722190", + "name": "Brockmire", + "type": "series", + "year": "2017–2020" + }, + { + "_id": "54e19892e573cadcfa1fd63e", + "imdb_id": "tt2357547", + "name": "Jessica Jones", + "type": "series", + "year": "2015–2019" + }, + { + "_id": "53677f3a847ccc8123a1ee2c", + "imdb_id": "tt0367439", + "name": "Wolf's Rain", + "type": "series", + "year": "2003–2004" + }, + { + "_id": "53677f19847ccc8123a1b114", + "imdb_id": "tt0108756", + "name": "Due South", + "type": "series", + "year": "1994–1999" + }, + { + "_id": "6091046264ec43ef98e0d63e", + "imdb_id": "tt12708542", + "name": "Star Wars: The Bad Batch", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677f00847ccc8123a162c9", + "imdb_id": "tt0094466", + "name": "Freddy's Nightmares", + "type": "series", + "year": "1988–1990" + }, + { + "_id": "53677f08847ccc8123a1843f", + "imdb_id": "tt0062578", + "name": "Land of the Giants", + "type": "series", + "year": "1968–1970" + }, + { + "_id": "54e70d48417d39942847ac9a", + "imdb_id": "tt3595776", + "name": "The Odd Couple", + "type": "series", + "year": "2015–2017" + }, + { + "_id": "53677f05847ccc8123a17c55", + "imdb_id": "tt0088559", + "name": "MacGyver", + "type": "series", + "year": "1985–1992" + }, + { + "_id": "53677f05847ccc8123a17b43", + "imdb_id": "tt0091211", + "name": "Fist of the North Star", + "type": "series", + "year": "1984–1988" + }, + { + "_id": "53677f2e847ccc8123a1e458", + "imdb_id": "tt2215842", + "name": "Father Brown", + "type": "series", + "year": "2013–" + }, + { + "_id": "53677f00847ccc8123a163e8", + "imdb_id": "tt0088621", + "name": "Taggart", + "type": "series", + "year": "1983–2010" + }, + { + "_id": "53677f40847ccc8123a1f774", + "imdb_id": "tt2395695", + "name": "Cosmos: A Spacetime Odyssey", + "type": "series", + "year": "2014" + }, + { + "_id": "53677f35847ccc8123a1e9c6", + "imdb_id": "tt1833403", + "name": "Captain Jake and the Never Land Pirates", + "type": "series", + "year": "2011–2016" + }, + { + "_id": "53677f05847ccc8123a17b6e", + "imdb_id": "tt0098830", + "name": "In Living Color", + "type": "series", + "year": "1990–1994" + }, + { + "_id": "53677ef9847ccc8123a14165", + "imdb_id": "tt1415889", + "name": "Good Luck Charlie", + "type": "series", + "year": "2010–2014" + }, + { + "_id": "53677f0f847ccc8123a19712", + "imdb_id": "tt0201391", + "name": "Roswell", + "type": "series", + "year": "1999–2002" + }, + { + "_id": "5beeab70173739c9f48b6cd2", + "imdb_id": "tt8714904", + "name": "Narcos: Mexico", + "type": "series", + "year": "2018–2021" + }, + { + "_id": "5f1bd08d5424253341724598", + "imdb_id": "tt11448214", + "name": "Rent-a-Girlfriend", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "53677f00847ccc8123a165ea", + "imdb_id": "tt0103442", + "name": "Highlander", + "type": "series", + "year": "1992–1998" + }, + { + "_id": "53677ef9847ccc8123a13814", + "imdb_id": "tt1073507", + "name": "Party Down", + "type": "series", + "year": "2009–" + }, + { + "_id": "5a94f73f53336c1ba890feba", + "imdb_id": "tt6474378", + "type": "series", + "name": "Good Girls", + "year": "2018–2021" + }, + { + "_id": "5378cc09847ccc8123ad4552", + "imdb_id": "tt3551096", + "name": "Fresh Off the Boat", + "type": "series", + "year": "2015–2020" + }, + { + "_id": "5bdbd2e8173739c9f44d3d0f", + "imdb_id": "tt7008682", + "name": "Homecoming", + "type": "series", + "year": "2018–2020" + }, + { + "_id": "53677f21847ccc8123a1cb8a", + "imdb_id": "tt2189221", + "name": "Defiance", + "type": "series", + "year": "2013–2015" + }, + { + "_id": "539c4866a8f27b1bb90afe5d", + "imdb_id": "tt0075529", + "name": "The Love Boat", + "type": "series", + "year": "1977–1987" + }, + { + "_id": "59b03ef21712e0f4dd1e6622", + "imdb_id": "tt6111130", + "name": "S.W.A.T.", + "type": "series", + "year": "2017–2024" + }, + { + "_id": "53677efc847ccc8123a150f5", + "imdb_id": "tt0306274", + "name": "What's New, Scooby-Doo?", + "type": "series", + "year": "2002–2006" + }, + { + "_id": "53677f05847ccc8123a17684", + "imdb_id": "tt0096579", + "name": "Family Matters", + "type": "series", + "year": "1989–1998" + }, + { + "_id": "53677f1b847ccc8123a1b871", + "imdb_id": "tt0085029", + "name": "Hardcastle and McCormick", + "type": "series", + "year": "1983–1986" + }, + { + "_id": "539c4866a8f27b1bb90afe93", + "imdb_id": "tt3398228", + "name": "BoJack Horseman", + "type": "series", + "year": "2014–2020" + }, + { + "_id": "59c7a0eb1712e0f4dd3ca41b", + "imdb_id": "tt5531466", + "type": "series", + "name": "DuckTales", + "year": "2017–2021" + }, + { + "_id": "53677efc847ccc8123a153e2", + "imdb_id": "tt0285351", + "name": "According to Jim", + "type": "series", + "year": "2001–2009" + }, + { + "_id": "5c0a53c9173739c9f4dc138c", + "imdb_id": "tt8755712", + "type": "series", + "name": "The Shop", + "year": "2018–" + }, + { + "_id": "57fec6d1d7e54929824008c2", + "imdb_id": "tt5912064", + "name": "Kim's Convenience", + "type": "series", + "year": "2016–2021" + }, + { + "_id": "5a742be8543165dcd875c27e", + "imdb_id": "tt2261227", + "type": "series", + "name": "Altered Carbon", + "year": "2018–2020" + }, + { + "_id": "53677f22847ccc8123a1cbe9", + "imdb_id": "tt0096560", + "name": "Coach", + "type": "series", + "year": "1989–1997" + }, + { + "_id": "53677ef9847ccc8123a1443c", + "imdb_id": "tt0765491", + "name": "Eureka Seven", + "type": "series", + "year": "2005–2006" + }, + { + "_id": "5c119552173739c9f4d13d29", + "imdb_id": "tt8111088", + "name": "The Mandalorian", + "type": "series", + "year": "2019–" + }, + { + "_id": "53eb359ea8f27b1bb90c0863", + "imdb_id": "tt3330720", + "name": "The Last Leg", + "type": "series", + "year": "2012–" + }, + { + "_id": "57e1e61ed7e54929823e6ac8", + "imdb_id": "tt5827228", + "name": "Bull", + "type": "series", + "year": "2016–2022" + }, + { + "_id": "53677f09847ccc8123a18633", + "imdb_id": "tt2139371", + "name": "Transformers: Rescue Bots", + "type": "series", + "year": "2011–2016" + }, + { + "_id": "53677ef9847ccc8123a138c7", + "imdb_id": "tt0319931", + "name": "American Idol", + "type": "series", + "year": "2002–" + }, + { + "_id": "53677f07847ccc8123a18135", + "imdb_id": "tt0088503", + "name": "Dempsey and Makepeace", + "type": "series", + "year": "1985–1986" + }, + { + "_id": "55072fe2711bd19c92adda0a", + "imdb_id": "tt3743822", + "name": "Fear the Walking Dead", + "year": "2015–2023", + "type": "series" + }, + { + "_id": "53677f05847ccc8123a176ab", + "imdb_id": "tt2149175", + "name": "The Americans", + "type": "series", + "year": "2013–2018" + }, + { + "_id": "53677ef9847ccc8123a13a66", + "imdb_id": "tt1699748", + "name": "Hell on Wheels", + "type": "series", + "year": "2011–2016" + }, + { + "_id": "5c18d97f173739c9f4770552", + "imdb_id": "tt6738600", + "name": "All Out", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "53677f02847ccc8123a16f81", + "imdb_id": "tt0059991", + "name": "The Green Hornet", + "type": "series", + "year": "1966–1967" + }, + { + "_id": "5c0ba934173739c9f43b054e", + "imdb_id": "tt7456722", + "name": "Hunters", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "5ab0d0f553336c1ba8a36cd3", + "imdb_id": "tt7808344", + "type": "series", + "name": "Karakai Jouzu no Takagi-san", + "year": "2018–2022" + }, + { + "_id": "53c58b44a8f27b1bb90b7c7d", + "imdb_id": "tt3155320", + "name": "Extant", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "5c0a7fef173739c9f42d21da", + "imdb_id": "tt6357658", + "type": "series", + "name": "Baki", + "year": "2018–2020" + }, + { + "_id": "53677ef9847ccc8123a13b22", + "imdb_id": "tt0123338", + "name": "60 Minutes", + "type": "series", + "year": "1968–" + }, + { + "_id": "53677efa847ccc8123a1487b", + "imdb_id": "tt0052478", + "name": "Johnny Ringo", + "type": "series", + "year": "1959–1960" + }, + { + "_id": "53677f04847ccc8123a1740e", + "imdb_id": "tt0106004", + "name": "Frasier", + "type": "series", + "year": "1993–2004" + }, + { + "_id": "53677ef9847ccc8123a13b32", + "imdb_id": "tt1520211", + "name": "The Walking Dead", + "type": "series", + "year": "2010–2022" + }, + { + "_id": "55984192bf6c900d1838f5f8", + "imdb_id": "tt0437729", + "name": "The Late Late Show with Craig Ferguson", + "year": "2005–2015", + "type": "series" + }, + { + "_id": "5a0c053d543165dcd8f212fc", + "imdb_id": "tt6881870", + "type": "series", + "name": "Frankie Drake Mysteries", + "year": "2017–2021" + }, + { + "_id": "53677efa847ccc8123a14a97", + "imdb_id": "tt0158552", + "name": "Charmed", + "type": "series", + "year": "1998–2006" + }, + { + "_id": "53677ef9847ccc8123a13a6f", + "imdb_id": "tt1595859", + "name": "Blue Bloods", + "type": "series", + "year": "2010–2024" + }, + { + "_id": "6342ccbd64ec43ef98a27ed8", + "imdb_id": "tt15433166", + "name": "Mobile Suit Gundam: The Witch from Mercury", + "type": "series", + "year": "2022–2023" + }, + { + "_id": "53677f21847ccc8123a1c93f", + "imdb_id": "tt0425720", + "name": "Tom Goes to the Mayor", + "type": "series", + "year": "2004–2006" + }, + { + "_id": "57e0866bd7e54929823e5a7c", + "imdb_id": "tt4955642", + "type": "series", + "name": "The Good Place", + "year": "2016–2020" + }, + { + "_id": "5c0c3c30173739c9f467aea5", + "imdb_id": "tt8772296", + "name": "Euphoria", + "type": "series", + "year": "2019–" + }, + { + "_id": "53677f05847ccc8123a17aca", + "imdb_id": "tt0063925", + "name": "Love, American Style", + "type": "series", + "year": "1969–1974" + }, + { + "_id": "567c8a22bb83c664989a183a", + "imdb_id": "tt5193172", + "name": "Dawn of the Croods", + "year": "2015–2017", + "type": "series" + }, + { + "_id": "5c2034b4173739c9f4e5e0f7", + "imdb_id": "tt0338621", + "name": "Kirby: Right Back at Ya!", + "type": "series", + "year": "2001–2003" + }, + { + "_id": "5c163fa4173739c9f40b725d", + "imdb_id": "tt0131160", + "name": "Cat's Eye", + "type": "series", + "year": "1983–1985" + }, + { + "_id": "55075d47711bd19c92addbeb", + "imdb_id": "tt0115082", + "name": "3rd Rock from the Sun", + "year": "1996–2001", + "type": "series" + }, + { + "_id": "53f87474a8f27b1bb90c3b56", + "imdb_id": "tt0140733", + "name": "Crown Court", + "type": "series", + "year": "1972–2007" + }, + { + "_id": "5527c3c7cc9eee85bb52e28d", + "imdb_id": "tt3952746", + "name": "Just Add Magic", + "year": "2015–2019", + "type": "series" + }, + { + "_id": "53677f02847ccc8123a17092", + "imdb_id": "tt0101114", + "name": "Heartbeat", + "type": "series", + "year": "1992–2010" + }, + { + "_id": "5e581949c4ccb5dd92ae6d11", + "imdb_id": "tt10936342", + "name": "Transplant", + "type": "series", + "year": "2020–2024" + }, + { + "_id": "588b1d821635517fbf56a9a5", + "imdb_id": "tt5419200", + "name": "Justice League Action", + "type": "series", + "year": "2016–2018" + }, + { + "_id": "53677efd847ccc8123a15509", + "imdb_id": "tt0050063", + "name": "Sugarfoot", + "type": "series", + "year": "1957–1961" + }, + { + "_id": "53d3d592a8f27b1bb90bae88", + "imdb_id": "tt0175058", + "name": "The Powerpuff Girls", + "type": "series", + "year": "1998–2004" + }, + { + "_id": "53677f0a847ccc8123a18976", + "imdb_id": "tt0068074", + "name": "Circle of Fear", + "type": "series", + "year": "1972–1973" + }, + { + "_id": "5f79bbac5424253341f27818", + "imdb_id": "tt12311976", + "name": "TONIKAWA: Over the Moon for You", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "53677efa847ccc8123a1488a", + "imdb_id": "tt0460690", + "name": "The Unit", + "type": "series", + "year": "2006–2009" + }, + { + "_id": "53677ef5847ccc8123a1375b", + "imdb_id": "tt0369179", + "name": "Two and a Half Men", + "type": "series", + "year": "2003–2015" + }, + { + "_id": "600cbfbd54242533411611b6", + "imdb_id": "tt13103134", + "name": "Horimiya", + "type": "series", + "year": "2021" + }, + { + "_id": "53677f00847ccc8123a167c2", + "imdb_id": "tt0084988", + "name": "Blackadder", + "type": "series", + "year": "1982–1983" + }, + { + "_id": "5bc7a7a0173739c9f46eb556", + "imdb_id": "tt8103070", + "name": "Legacies", + "type": "series", + "year": "2018–2022" + }, + { + "_id": "5c17d8a7173739c9f4cde03e", + "imdb_id": "tt3432210", + "name": "Yo-Kai Watch", + "type": "series", + "year": "2014–" + }, + { + "_id": "5c0f98cf173739c9f40d5450", + "imdb_id": "tt0066689", + "name": "The New Dick Van Dyke Show", + "type": "series", + "year": "1971–1974" + }, + { + "_id": "53677f15847ccc8123a1a885", + "imdb_id": "tt2768802", + "name": "Mickey Mouse", + "type": "series", + "year": "2013–2019" + }, + { + "_id": "5c1c83ce173739c9f433bd71", + "imdb_id": "tt7203552", + "name": "The Morning Show", + "type": "series", + "year": "2019–" + }, + { + "_id": "53677f2c847ccc8123a1e320", + "imdb_id": "tt1877889", + "name": "Teenage Mutant Ninja Turtles", + "type": "series", + "year": "2012–2017" + }, + { + "_id": "53677ef9847ccc8123a13a39", + "imdb_id": "tt1837642", + "name": "Revenge", + "type": "series", + "year": "2011–2015" + }, + { + "_id": "5600c0da6c6a1c0b815c4f28", + "imdb_id": "tt4384086", + "name": "Life in Pieces", + "year": "2015–2019", + "type": "series" + }, + { + "_id": "53677f07847ccc8123a18102", + "imdb_id": "tt0077089", + "name": "Taxi", + "type": "series", + "year": "1978–1983" + }, + { + "_id": "53677ef9847ccc8123a13ace", + "imdb_id": "tt1442437", + "name": "Modern Family", + "type": "series", + "year": "2009–2020" + }, + { + "_id": "53677efa847ccc8123a14c22", + "imdb_id": "tt1034201", + "name": "Britain's Got Talent", + "type": "series", + "year": "2007–" + }, + { + "_id": "54fb5f87711bd19c92ad4758", + "imdb_id": "tt3981938", + "name": "Rage of Bahamut: Genesis", + "year": "2014", + "type": "series" + }, + { + "_id": "53677efc847ccc8123a14f8d", + "imdb_id": "tt0206501", + "name": "Nova", + "type": "series", + "year": "1974–" + }, + { + "_id": "53ac6496a8f27b1bb90b2fc0", + "imdb_id": "tt0090418", + "name": "Designing Women", + "type": "series", + "year": "1986–1993" + }, + { + "_id": "5de808acc4ccb5dd92569c67", + "imdb_id": "tt10885406", + "name": "Ascendance of a Bookworm", + "type": "series", + "year": "2019–2022" + }, + { + "_id": "5c1fecd5173739c9f4547637", + "imdb_id": "tt2549176", + "name": "Cardfight!! Vanguard", + "type": "series", + "year": "2011–" + }, + { + "_id": "5c2746ac173739c9f4575b3d", + "imdb_id": "tt9359796", + "name": "Blade Runner: Black Lotus", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "53677f47847ccc8123a20033", + "imdb_id": "tt0856348", + "name": "Basilisk: The Kouga Ninja Scrolls", + "type": "series", + "year": "2005" + }, + { + "_id": "53677efa847ccc8123a14cda", + "imdb_id": "tt0251497", + "name": "Big Brother", + "type": "series", + "year": "2000–" + }, + { + "_id": "5e5a6a0cc4ccb5dd9248ee4c", + "imdb_id": "tt8050756", + "name": "The Owl House", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "54d7b476e573cadcfa1fb263", + "imdb_id": "tt0245637", + "name": "Little Bear", + "type": "series", + "year": "1995–2003" + }, + { + "_id": "53677f07847ccc8123a17e7b", + "imdb_id": "tt0057751", + "name": "Gilligan's Island", + "type": "series", + "year": "1963–1967" + }, + { + "_id": "5bbdf461173739c9f4fac689", + "imdb_id": "tt0159175", + "name": "Lupin the Third", + "type": "series", + "year": "1971–1972" + }, + { + "_id": "53677ef9847ccc8123a1447f", + "imdb_id": "tt0077000", + "name": "Dallas", + "type": "series", + "year": "1978–1991" + }, + { + "_id": "53677f02847ccc8123a16dd7", + "imdb_id": "tt0086691", + "name": "Crazy Like a Fox", + "type": "series", + "year": "1984–1986" + }, + { + "_id": "53677ef9847ccc8123a1419c", + "imdb_id": "tt1519931", + "name": "Haven", + "type": "series", + "year": "2010–2015" + }, + { + "_id": "53677f66847ccc8123a229f3", + "imdb_id": "tt2244077", + "name": "Littlest Pet Shop", + "type": "series", + "year": "2012–2022" + }, + { + "_id": "5c2c77cd173739c9f4704c2d", + "imdb_id": "tt0112044", + "name": "Die Harald Schmidt Show", + "type": "series", + "year": "1995–2004" + }, + { + "_id": "53677f03847ccc8123a1727b", + "imdb_id": "tt0047736", + "name": "Gunsmoke", + "type": "series", + "year": "1955–1975" + }, + { + "_id": "541463a2a8f27b1bb90c99c3", + "imdb_id": "tt3843168", + "name": "Z Nation", + "type": "series", + "year": "2014–2018" + }, + { + "_id": "6020b2c954242533419483cc", + "imdb_id": "tt11242246", + "name": "The Equalizer", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677ef9847ccc8123a13834", + "imdb_id": "tt1820166", + "name": "Ridiculousness", + "type": "series", + "year": "2011–" + }, + { + "_id": "53677f25847ccc8123a1d4cf", + "imdb_id": "tt0452718", + "name": "Surface", + "type": "series", + "year": "2005–2006" + }, + { + "_id": "59ce2a5b067c4652103b9d17", + "imdb_id": "tt6524350", + "type": "series", + "name": "Big Mouth", + "year": "2017–2024" + }, + { + "_id": "65170350bd36726cbb8c457b", + "imdb_id": "tt22248376", + "name": "Frieren: Beyond Journey's End", + "type": "series", + "year": "2023–" + }, + { + "_id": "5c16843d173739c9f494a1f5", + "imdb_id": "tt5023666", + "name": "The Heroic Legend of Arslan", + "type": "series", + "year": "2015–2016" + }, + { + "_id": "5c1e2260173739c9f40a6df6", + "imdb_id": "tt0111056", + "name": "Gensomaden Saiyuki", + "type": "series", + "year": "2000–2001" + }, + { + "_id": "5c09d277173739c9f41e4009", + "imdb_id": "tt7049682", + "name": "Watchmen", + "type": "series", + "year": "2019" + }, + { + "_id": "53677f29847ccc8123a1da4c", + "imdb_id": "tt0912343", + "name": "Tim and Eric Awesome Show, Great Job!", + "type": "series", + "year": "2007–2017" + }, + { + "_id": "5c0b05c7173739c9f4389f39", + "imdb_id": "tt4563516", + "name": "DD Fist of the North Star", + "type": "series", + "year": "2013–" + }, + { + "_id": "6349699e64ec43ef982dcd7a", + "imdb_id": "tt16764368", + "name": "Urusei Yatsura", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677efa847ccc8123a1475e", + "imdb_id": "tt0115341", + "name": "Sabrina the Teenage Witch", + "type": "series", + "year": "1996–2003" + }, + { + "_id": "53677f4f847ccc8123a20db8", + "imdb_id": "tt3294962", + "name": "Saturday Night Live Korea", + "type": "series", + "year": "2011–2017" + }, + { + "_id": "5c1462fd173739c9f4e758e0", + "imdb_id": "tt1751634", + "name": "The Sandman", + "type": "series", + "year": "2022–" + }, + { + "_id": "61dff46264ec43ef98a24620", + "imdb_id": "tt13146488", + "name": "Peacemaker", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677f23847ccc8123a1d063", + "imdb_id": "tt2442560", + "name": "Peaky Blinders", + "type": "series", + "year": "2013–2022" + }, + { + "_id": "53677f45847ccc8123a1fdcb", + "imdb_id": "tt0051290", + "name": "Lawman", + "type": "series", + "year": "1958–1962" + }, + { + "_id": "5c10258f173739c9f41f114f", + "imdb_id": "tt8806524", + "name": "Star Trek: Picard", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "5c0901d5173739c9f4886159", + "imdb_id": "tt7892026", + "name": "La resistencia", + "type": "series", + "year": "2018–" + }, + { + "_id": "53677f1f847ccc8123a1c47f", + "imdb_id": "tt2325846", + "name": "DreamWorks Dragons", + "type": "series", + "year": "2012–2014" + }, + { + "_id": "5c14d8c6173739c9f48b7640", + "imdb_id": "tt0042116", + "name": "The Jack Benny Program", + "type": "series", + "year": "1950–1965" + }, + { + "_id": "54ff1e6c711bd19c92adcf4b", + "imdb_id": "tt2891574", + "name": "Ballers", + "year": "2015–2019", + "type": "series" + }, + { + "_id": "53677f26847ccc8123a1d7ba", + "imdb_id": "tt0206511", + "name": "Even Stevens", + "type": "series", + "year": "2000–2003" + }, + { + "_id": "53677f05847ccc8123a1769e", + "imdb_id": "tt0050035", + "name": "M Squad", + "type": "series", + "year": "1957–1960" + }, + { + "_id": "53677f0a847ccc8123a18c84", + "imdb_id": "tt1132205", + "name": "Minami-ke", + "type": "series", + "year": "2007–" + }, + { + "_id": "53677ef9847ccc8123a1394d", + "imdb_id": "tt0790772", + "name": "Rules of Engagement", + "type": "series", + "year": "2007–2013" + }, + { + "_id": "53677efd847ccc8123a15922", + "imdb_id": "tt0059968", + "name": "Batman", + "type": "series", + "year": "1966–1968" + }, + { + "_id": "632ae2b764ec43ef987db136", + "imdb_id": "tt13207736", + "name": "Monster", + "type": "series", + "year": "2022–2024" + }, + { + "_id": "61f38ea364ec43ef98f1970d", + "imdb_id": "tt11247158", + "name": "The Legend of Vox Machina", + "type": "series", + "year": "2022–" + }, + { + "_id": "62e6bcca64ec43ef981ad1cd", + "imdb_id": "tt14400866", + "name": "A Couple of Cuckoos", + "type": "series", + "year": "2022" + }, + { + "_id": "53677ef9847ccc8123a137e9", + "imdb_id": "tt1724587", + "name": "Green Lantern: The Animated Series", + "type": "series", + "year": "2011–2013" + }, + { + "_id": "5c4f221cd582b2575607dd1d", + "imdb_id": "tt9561862", + "name": "Love, Death & Robots", + "type": "series", + "year": "2019–" + }, + { + "_id": "5d9ee182c4ccb5dd921f763f", + "imdb_id": "tt10313176", + "name": "Nancy Drew", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "53677efa847ccc8123a147ea", + "imdb_id": "tt0057752", + "name": "Gomer Pyle: USMC", + "type": "series", + "year": "1964–1969" + }, + { + "_id": "5c3380ce173739c9f406e213", + "imdb_id": "tt7050978", + "name": "Dorothy and the Wizard of Oz", + "type": "series", + "year": "2017–2020" + }, + { + "_id": "53677f38847ccc8123a1ee05", + "imdb_id": "tt0072554", + "name": "One Day at a Time", + "type": "series", + "year": "1975–1984" + }, + { + "_id": "53677ef9847ccc8123a13895", + "imdb_id": "tt0810788", + "name": "Burn Notice", + "type": "series", + "year": "2007–2013" + }, + { + "_id": "53677ef9847ccc8123a13dfb", + "imdb_id": "tt1871731", + "name": "Ninjago: Masters of Spinjitzu", + "type": "series", + "year": "2011–2019" + }, + { + "_id": "53677ef9847ccc8123a13931", + "imdb_id": "tt0496424", + "name": "30 Rock", + "type": "series", + "year": "2006–2013" + }, + { + "_id": "53677f00847ccc8123a163d7", + "imdb_id": "tt0157246", + "name": "Will & Grace", + "type": "series", + "year": "1998–2020" + }, + { + "_id": "53677ef9847ccc8123a13ba3", + "imdb_id": "tt1179817", + "name": "The Secret Life of the American Teenager", + "type": "series", + "year": "2008–2013" + }, + { + "_id": "53677ef9847ccc8123a1385a", + "imdb_id": "tt0460627", + "name": "Bones", + "type": "series", + "year": "2005–2017" + }, + { + "_id": "53677f08847ccc8123a18396", + "imdb_id": "tt0098936", + "name": "Twin Peaks", + "type": "series", + "year": "1990–1991" + }, + { + "_id": "5c14a50f173739c9f4393288", + "imdb_id": "tt5334292", + "name": "Dimension W", + "type": "series", + "year": "2016–" + }, + { + "_id": "53677f12847ccc8123a1a018", + "imdb_id": "tt0072567", + "name": "Starsky and Hutch", + "type": "series", + "year": "1975–1979" + }, + { + "_id": "5c12728b173739c9f44ac5f4", + "imdb_id": "tt0088610", + "name": "Small Wonder", + "type": "series", + "year": "1985–1989" + }, + { + "_id": "5a7f367c543165dcd8827011", + "imdb_id": "tt7865090", + "type": "series", + "name": "Darling in the Franxx", + "year": "2018" + }, + { + "_id": "54fb5f67711bd19c92ad45a9", + "imdb_id": "tt3398976", + "name": "Knights of Sidonia", + "year": "2014–2015", + "type": "series" + }, + { + "_id": "5c39fbf3d582b25756eea9c9", + "imdb_id": "tt2904426", + "name": "Fate/kaleid liner Prisma Illya", + "type": "series", + "year": "2013–" + }, + { + "_id": "5c0b7953173739c9f4e0ff1c", + "imdb_id": "tt4816058", + "name": "Dragons: Race to the Edge", + "type": "series", + "year": "2015–2018" + }, + { + "_id": "53677efc847ccc8123a14ff9", + "imdb_id": "tt0076987", + "name": "Blake's 7", + "type": "series", + "year": "1978–1981" + }, + { + "_id": "53677f05847ccc8123a1776e", + "imdb_id": "tt0096708", + "name": "Tales from the Crypt", + "type": "series", + "year": "1989–1996" + }, + { + "_id": "53677ef9847ccc8123a14418", + "imdb_id": "tt1641384", + "name": "Young Justice", + "type": "series", + "year": "2010–2022" + }, + { + "_id": "5c2b094a173739c9f4eed5d5", + "imdb_id": "tt0090530", + "name": "Street Legal", + "type": "series", + "year": "1987–1994" + }, + { + "_id": "53677ef9847ccc8123a141bc", + "imdb_id": "tt0187636", + "name": "Farscape", + "type": "series", + "year": "1999–2003" + }, + { + "_id": "5ac8d24ba5989fb3210999dc", + "imdb_id": "tt7741824", + "type": "series", + "name": "The Boss Baby: Back in Business", + "year": "2018–2021" + }, + { + "_id": "53677ef9847ccc8123a13fa0", + "imdb_id": "tt0285403", + "name": "Scrubs", + "type": "series", + "year": "2001–2010" + }, + { + "_id": "53677ef9847ccc8123a13851", + "imdb_id": "tt1723816", + "name": "Girls", + "type": "series", + "year": "2012–2017" + }, + { + "_id": "5c0b0a0e173739c9f440bb70", + "imdb_id": "tt7588054", + "type": "series", + "name": "Roswell, New Mexico", + "year": "2019–2022" + }, + { + "_id": "53677eff847ccc8123a15cb0", + "imdb_id": "tt2100976", + "name": "Impractical Jokers", + "type": "series", + "year": "2011–" + }, + { + "_id": "57667d902e22ea26fe51d397", + "imdb_id": "tt0190924", + "name": "Space Stars", + "year": "1981", + "type": "series" + }, + { + "_id": "569686d7bb83c664989c90cc", + "imdb_id": "tt4145054", + "name": "Shadowhunters", + "year": "2016–2019", + "type": "series" + }, + { + "_id": "5c43cea1d582b257567299e0", + "imdb_id": "tt6741278", + "name": "Invincible", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677ef9847ccc8123a13dc7", + "imdb_id": "tt0407362", + "name": "Battlestar Galactica", + "type": "series", + "year": "2004–2009" + }, + { + "_id": "53677f07847ccc8123a1804c", + "imdb_id": "tt0044230", + "name": "The Adventures of Ozzie and Harriet", + "type": "series", + "year": "1952–1966" + }, + { + "_id": "53677ef9847ccc8123a13f0e", + "imdb_id": "tt0374455", + "name": "Stargate: Atlantis", + "type": "series", + "year": "2004–2009" + }, + { + "_id": "53677ef9847ccc8123a13e1c", + "imdb_id": "tt0086659", + "name": "'Allo 'Allo!", + "type": "series", + "year": "1982–1992" + }, + { + "_id": "53677ef9847ccc8123a13f73", + "imdb_id": "tt0083452", + "name": "Nature", + "type": "series", + "year": "1982–" + }, + { + "_id": "56536418bb83c6649895f893", + "imdb_id": "tt3230854", + "name": "The Expanse", + "year": "2015–2022", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13a25", + "imdb_id": "tt1608180", + "name": "Mike & Molly", + "type": "series", + "year": "2010–2016" + }, + { + "_id": "53677ef9847ccc8123a137f1", + "imdb_id": "tt1587678", + "name": "Happy Endings", + "type": "series", + "year": "2011–2020" + }, + { + "_id": "53677ef9847ccc8123a13944", + "imdb_id": "tt1103987", + "name": "Leverage", + "type": "series", + "year": "2008–2012" + }, + { + "_id": "53677ef9847ccc8123a13c6c", + "imdb_id": "tt1986770", + "name": "Anger Management", + "type": "series", + "year": "2012–2014" + }, + { + "_id": "53677ef9847ccc8123a137b5", + "imdb_id": "tt1830888", + "name": "The Exes", + "type": "series", + "year": "2011–2015" + }, + { + "_id": "54e60074fc2ab98b66971c2a", + "imdb_id": "tt0047757", + "name": "The Mickey Mouse Club", + "type": "series", + "year": "1955–1958" + }, + { + "_id": "53677f4f847ccc8123a20abb", + "imdb_id": "tt0047706", + "name": "The Adventures of Robin Hood", + "type": "series", + "year": "1955–1960" + }, + { + "_id": "5601ff0f6c6a1c0b815c67a7", + "imdb_id": "tt4558858", + "name": "New Looney Tunes", + "year": "2015–2020", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a14124", + "imdb_id": "tt1622696", + "name": "Ben 10: Ultimate Alien", + "type": "series", + "year": "2010–2012" + }, + { + "_id": "53677ef9847ccc8123a143f1", + "imdb_id": "tt0103491", + "name": "Melrose Place", + "type": "series", + "year": "1992–1999" + }, + { + "_id": "53677f19847ccc8123a1b2a1", + "imdb_id": "tt2183404", + "name": "Rectify", + "type": "series", + "year": "2013–2016" + }, + { + "_id": "53677f0c847ccc8123a18d80", + "imdb_id": "tt1936532", + "name": "Major Crimes", + "type": "series", + "year": "2012–2018" + }, + { + "_id": "53677f05847ccc8123a176df", + "imdb_id": "tt2710394", + "name": "Reign", + "type": "series", + "year": "2013–2017" + }, + { + "_id": "5c146e78173739c9f4f97163", + "imdb_id": "tt1976753", + "name": "Flor Salvaje", + "type": "series", + "year": "2011–" + }, + { + "_id": "53677ef9847ccc8123a139f9", + "imdb_id": "tt1405406", + "name": "The Vampire Diaries", + "type": "series", + "year": "2009–2017" + }, + { + "_id": "54bacf638527d2e0cb508158", + "imdb_id": "tt1740299", + "name": "The Man in the High Castle", + "type": "series", + "year": "2015–2019" + }, + { + "_id": "53c58b44a8f27b1bb90b7c0f", + "imdb_id": "tt0113483", + "name": "Joseph", + "type": "series", + "year": "1995" + }, + { + "_id": "53677f04847ccc8123a17479", + "imdb_id": "tt0105935", + "name": "Aladdin", + "type": "series", + "year": "1994–1995" + }, + { + "_id": "53677f0a847ccc8123a18bde", + "imdb_id": "tt0096694", + "name": "Saved by the Bell", + "type": "series", + "year": "1989–1992" + }, + { + "_id": "577abba8f0b6c53b3c778716", + "imdb_id": "tt1064899", + "name": "Queen of the South", + "year": "2016–2021", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13a7c", + "imdb_id": "tt1441135", + "name": "Flashforward", + "type": "series", + "year": "2009–2010" + }, + { + "_id": "53677ef9847ccc8123a13ffa", + "imdb_id": "tt0083437", + "name": "Knight Rider", + "type": "series", + "year": "1982–1986" + }, + { + "_id": "53677f2f847ccc8123a1e4cf", + "imdb_id": "tt0055683", + "name": "The Jetsons", + "type": "series", + "year": "1962–1963" + }, + { + "_id": "5c116a6d173739c9f475df7d", + "imdb_id": "tt0144724", + "name": "Malhação", + "type": "series", + "year": "1995–2020" + }, + { + "_id": "536907fc847ccc8123acde80", + "imdb_id": "tt0058816", + "name": "I Spy", + "type": "series", + "year": "1965–1968" + }, + { + "_id": "53677f0c847ccc8123a193bf", + "imdb_id": "tt0101081", + "name": "Dinosaurs", + "type": "series", + "year": "1991–1994" + }, + { + "_id": "5c2e895d173739c9f4443583", + "imdb_id": "tt0816387", + "name": "Kyô kara maô!", + "type": "series", + "year": "2004–" + }, + { + "_id": "587fc2531635517fbf5695ff", + "imdb_id": "tt4834206", + "name": "A Series of Unfortunate Events", + "type": "series", + "year": "2017–2019" + }, + { + "_id": "570f0577890e549c9a5833f3", + "imdb_id": "tt4718304", + "name": "The Powerpuff Girls", + "year": "2016–2023", + "type": "series" + }, + { + "_id": "64305e9764ec43ef98cfb0d6", + "imdb_id": "tt21209804", + "name": "Mashle: Magic and Muscles", + "type": "series", + "year": "2023–" + }, + { + "_id": "59f2f845067c465210ed1fe5", + "imdb_id": "tt7441658", + "type": "series", + "name": "Black Clover", + "year": "2017–2021" + }, + { + "_id": "557f064fbf6c900d1835848b", + "imdb_id": "tt0042123", + "name": "Lux Video Theatre", + "year": "1950–1959", + "type": "series" + }, + { + "_id": "53677f17847ccc8123a1ab6d", + "imdb_id": "tt0123366", + "name": "The View", + "type": "series", + "year": "1997–" + }, + { + "_id": "57ff6f9ad7e5492982400f39", + "imdb_id": "tt0068044", + "name": "Banacek", + "year": "1972–1974", + "type": "series" + }, + { + "_id": "53677efa847ccc8123a145e5", + "imdb_id": "tt0348913", + "name": "Dead Like Me", + "type": "series", + "year": "2003–2004" + }, + { + "_id": "5c0bdc9d173739c9f49f435e", + "imdb_id": "tt9225320", + "name": "Radiant", + "type": "series", + "year": "2018–" + }, + { + "_id": "53677ef9847ccc8123a137b7", + "imdb_id": "tt1219024", + "name": "Castle", + "type": "series", + "year": "2009–2016" + }, + { + "_id": "631f17cb64ec43ef9821baa8", + "imdb_id": "tt8291284", + "name": "The Peripheral", + "type": "series", + "year": "2022" + }, + { + "_id": "53677f08847ccc8123a183fa", + "imdb_id": "tt0083399", + "name": "Cheers", + "type": "series", + "year": "1982–1993" + }, + { + "_id": "53677ef9847ccc8123a13b8c", + "imdb_id": "tt1587669", + "name": "Body of Proof", + "type": "series", + "year": "2011–2013" + }, + { + "_id": "53677f4f847ccc8123a20abe", + "imdb_id": "tt0122356", + "name": "The Mysterious Cities of Gold", + "type": "series", + "year": "1982–1983" + }, + { + "_id": "53677f15847ccc8123a1a7c9", + "imdb_id": "tt0062572", + "name": "It Takes a Thief", + "type": "series", + "year": "1968–1970" + }, + { + "_id": "53677f79847ccc8123a23b8b", + "imdb_id": "tt2575988", + "name": "Silicon Valley", + "type": "series", + "year": "2014–2019" + }, + { + "_id": "5e9017f105bdfe7d18e27a32", + "imdb_id": "tt8400662", + "name": "Jashin-chan Dropkick", + "type": "series", + "year": "2018–" + }, + { + "_id": "53677f05847ccc8123a179eb", + "imdb_id": "tt0069620", + "name": "Police Story", + "type": "series", + "year": "1973–1980" + }, + { + "_id": "57ec8000d7e54929823ef766", + "imdb_id": "tt5024912", + "name": "Insecure", + "type": "series", + "year": "2016–2021" + }, + { + "_id": "53677f20847ccc8123a1c705", + "imdb_id": "tt0167565", + "name": "The Count of Monte Cristo", + "type": "series", + "year": "1998" + }, + { + "_id": "5c390b60d582b25756742d1d", + "imdb_id": "tt8741368", + "name": "Rugrats", + "type": "series", + "year": "2021–" + }, + { + "_id": "575e46152e22ea26fe51773f", + "imdb_id": "tt4878326", + "name": "Wynonna Earp", + "year": "2016–2021", + "type": "series" + }, + { + "_id": "5991bd833e5e4b900ae85c31", + "imdb_id": "tt5761496", + "name": "Get Shorty", + "type": "series", + "year": "2017–2019" + }, + { + "_id": "53677f54847ccc8123a21295", + "imdb_id": "tt1637574", + "name": "Conan", + "type": "series", + "year": "2010–2021" + }, + { + "_id": "5aa3158153336c1ba83f90ef", + "imdb_id": "tt6461812", + "name": "Deception", + "year": "2018", + "type": "series" + }, + { + "_id": "53677f17847ccc8123a1af45", + "imdb_id": "tt1307224", + "name": "Kid vs. Kat", + "type": "series", + "year": "2008–2011" + }, + { + "_id": "53677efa847ccc8123a14959", + "imdb_id": "tt0088526", + "name": "The Golden Girls", + "type": "series", + "year": "1985–1992" + }, + { + "_id": "5a65d78b543165dcd87cd09a", + "imdb_id": "tt4604612", + "name": "The Alienist", + "year": "2018–2020", + "type": "series" + }, + { + "_id": "57fd9864d7e54929823ff505", + "imdb_id": "tt5396394", + "type": "series", + "name": "American Housewife", + "year": "2016–2021" + }, + { + "_id": "5c0ad5ab173739c9f4d5f86a", + "imdb_id": "tt7713450", + "name": "Craig of the Creek", + "type": "series", + "year": "2018–2024" + }, + { + "_id": "558ece8fbf6c900d18381c2d", + "imdb_id": "tt4507442", + "name": "Best Friends Whenever", + "year": "2015–2016", + "type": "series" + }, + { + "_id": "581ae9d855f8aab460cfc0ca", + "imdb_id": "tt5351176", + "name": "The Circus: Inside the Greatest Political Show on Earth", + "type": "series", + "year": "2016–2023" + }, + { + "_id": "5c118f57173739c9f4c4b9f9", + "imdb_id": "tt8425532", + "name": "Pennyworth", + "type": "series", + "year": "2019–2022" + }, + { + "_id": "53677ef9847ccc8123a13d20", + "imdb_id": "tt0073972", + "name": "Charlie's Angels", + "type": "series", + "year": "1976–1981" + }, + { + "_id": "5834f3b3b0a40c25066d27c5", + "imdb_id": "tt5460226", + "name": "Search Party", + "type": "series", + "year": "2016–2022" + }, + { + "_id": "62b41ee564ec43ef98526532", + "imdb_id": "tt14452776", + "name": "The Bear", + "type": "series", + "year": "2022–" + }, + { + "_id": "550e2710cc9eee85bb52d935", + "imdb_id": "tt0272388", + "name": "House of Mouse", + "year": "2001–2003", + "type": "series" + }, + { + "_id": "6012427354242533410287da", + "imdb_id": "tt8690918", + "name": "Resident Alien", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677efa847ccc8123a14982", + "imdb_id": "tt0415463", + "name": "Zoey 101", + "type": "series", + "year": "2005–2008" + }, + { + "_id": "53677f19847ccc8123a1b19b", + "imdb_id": "tt2874692", + "name": "When Calls the Heart", + "type": "series", + "year": "2014–" + }, + { + "_id": "5f766dda542425334162173f", + "imdb_id": "tt10148174", + "name": "The Walking Dead: World Beyond", + "type": "series", + "year": "2020–2021" + }, + { + "_id": "5c3a8710d582b25756419cd6", + "imdb_id": "tt9522300", + "name": "Kaguya-sama: Love is War", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "55078876711bd19c92ade321", + "imdb_id": "tt3621796", + "name": "Fate/stay night [Unlimited Blade Works]", + "year": "2014–2015", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a138d6", + "imdb_id": "tt0412142", + "name": "House", + "type": "series", + "year": "2004–2012" + }, + { + "_id": "53677f1d847ccc8123a1bf7e", + "imdb_id": "tt0068067", + "name": "Emergency!", + "type": "series", + "year": "1972–1979" + }, + { + "_id": "53677f32847ccc8123a1e74c", + "imdb_id": "tt0056739", + "name": "Astro Boy", + "type": "series", + "year": "1963–1965" + }, + { + "_id": "53677f43847ccc8123a1fb74", + "imdb_id": "tt0306370", + "name": "The Osbournes", + "type": "series", + "year": "2002–2005" + }, + { + "_id": "53677f0a847ccc8123a18c53", + "imdb_id": "tt0042094", + "name": "The Colgate Comedy Hour", + "type": "series", + "year": "1950–1955" + }, + { + "_id": "551256cbcc9eee85bb52db63", + "imdb_id": "tt3741634", + "name": "Tokyo Ghoul", + "year": "2014", + "type": "series" + }, + { + "_id": "53677ef5847ccc8123a13775", + "imdb_id": "tt1495708", + "name": "Covert Affairs", + "type": "series", + "year": "2010–2014" + }, + { + "_id": "53677f03847ccc8123a1730c", + "imdb_id": "tt0073992", + "name": "Family", + "type": "series", + "year": "1976–1980" + }, + { + "_id": "5c0c53f4173739c9f49a0478", + "imdb_id": "tt6965802", + "name": "OK K.O.! Let's Be Heroes", + "type": "series", + "year": "2017–2019" + }, + { + "_id": "62b58d9664ec43ef98720928", + "imdb_id": "tt14271498", + "name": "Loot", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677f13847ccc8123a1a216", + "imdb_id": "tt2243973", + "name": "Hannibal", + "type": "series", + "year": "2013–2015" + }, + { + "_id": "5c0ac062173739c9f4a9e988", + "imdb_id": "tt1190634", + "name": "The Boys", + "type": "series", + "year": "2019–" + }, + { + "_id": "643c056f64ec43ef982924c1", + "imdb_id": "tt15789088", + "name": "Birdie Wing: Golf Girls' Story", + "type": "series", + "year": "2022–" + }, + { + "_id": "555c6d1ebf6c900d1833deea", + "imdb_id": "tt3868848", + "name": "Stitchers", + "year": "2015–2017", + "type": "series" + }, + { + "_id": "53677efa847ccc8123a14617", + "imdb_id": "tt1663641", + "name": "Face Off", + "type": "series", + "year": "2011–2018" + }, + { + "_id": "53677f07847ccc8123a1824c", + "imdb_id": "tt0053534", + "name": "Route 66", + "type": "series", + "year": "1960–1964" + }, + { + "_id": "53677f1e847ccc8123a1c0e2", + "imdb_id": "tt0106126", + "name": "SeaQuest 2032", + "type": "series", + "year": "1993–1996" + }, + { + "_id": "53677f15847ccc8123a1a729", + "imdb_id": "tt0112230", + "name": "Xena: Warrior Princess", + "type": "series", + "year": "1995–2001" + }, + { + "_id": "63b4f18164ec43ef985208b5", + "imdb_id": "tt17543592", + "name": "Will Trent", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677f4a847ccc8123a20551", + "imdb_id": "tt0054533", + "name": "The Dick Van Dyke Show", + "type": "series", + "year": "1961–1966" + }, + { + "_id": "629e4d9964ec43ef98dc0412", + "imdb_id": "tt14016500", + "name": "The Summer I Turned Pretty", + "type": "series", + "year": "2022–" + }, + { + "_id": "5c24fd47173739c9f4618358", + "imdb_id": "tt3114358", + "name": "Non Non Biyori", + "type": "series", + "year": "2013–2021" + }, + { + "_id": "53677ef9847ccc8123a13a43", + "imdb_id": "tt0493093", + "name": "Hannah Montana", + "type": "series", + "year": "2006–2011" + }, + { + "_id": "5810b268d7e549298241342b", + "imdb_id": "tt5651844", + "type": "series", + "name": "Travelers", + "year": "2016–2018" + }, + { + "_id": "53677f19847ccc8123a1b448", + "imdb_id": "tt0060018", + "name": "The Rat Patrol", + "type": "series", + "year": "1966–1968" + }, + { + "_id": "608b9ea464ec43ef98ba8210", + "imdb_id": "tt11041132", + "name": "The Mosquito Coast", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "53677efa847ccc8123a146c2", + "imdb_id": "tt0071042", + "name": "The Rockford Files", + "type": "series", + "year": "1974–1980" + }, + { + "_id": "53677f68847ccc8123a22c9c", + "imdb_id": "tt0108847", + "name": "The Magic School Bus", + "type": "series", + "year": "1994–1997" + }, + { + "_id": "53677ef9847ccc8123a13a3a", + "imdb_id": "tt1561755", + "name": "Bob's Burgers", + "type": "series", + "year": "2011–" + }, + { + "_id": "6002d5775424253341d08e18", + "imdb_id": "tt13650480", + "name": "Marvel Studios: Legends", + "type": "series", + "year": "2021–" + }, + { + "_id": "5abb0898e0a43c01da219380", + "imdb_id": "tt6492236", + "type": "series", + "name": "Splitting Up Together", + "year": "2018–2019" + }, + { + "_id": "5c0c356a173739c9f459a9a2", + "imdb_id": "tt0284712", + "name": "Captain Caveman and the Teen Angels", + "type": "series", + "year": "1977–1980" + }, + { + "_id": "5e252d93c4ccb5dd92cea584", + "imdb_id": "tt10323338", + "name": "9-1-1: Lone Star", + "type": "series", + "year": "2020–" + }, + { + "_id": "53677f00847ccc8123a1630c", + "imdb_id": "tt0096686", + "name": "Ranma ½", + "type": "series", + "year": "1989" + }, + { + "_id": "5c216ec5173739c9f405656c", + "imdb_id": "tt3204810", + "name": "On Cinema", + "type": "series", + "year": "2012–" + }, + { + "_id": "53677f0c847ccc8123a190f0", + "imdb_id": "tt0055662", + "name": "The Beverly Hillbillies", + "type": "series", + "year": "1962–1971" + }, + { + "_id": "53677f68847ccc8123a22ce3", + "imdb_id": "tt3306838", + "name": "Hozuki's Coolheadedness", + "type": "series", + "year": "2014–" + }, + { + "_id": "5a0e9a2d543165dcd84f2400", + "imdb_id": "tt5675620", + "type": "series", + "name": "The Punisher", + "year": "2017–2019" + }, + { + "_id": "55075d66711bd19c92addccc", + "imdb_id": "tt1356878", + "name": "Hetalia: Axis Powers", + "year": "2009–2016", + "type": "series" + }, + { + "_id": "6225838964ec43ef98030049", + "imdb_id": "tt10244600", + "name": "Winning Time: The Rise of the Lakers Dynasty", + "type": "series", + "year": "2022–2023" + }, + { + "_id": "6436f70564ec43ef98dd26c2", + "imdb_id": "tt21030032", + "name": "?Oshi No Ko?", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677ef9847ccc8123a13dd4", + "imdb_id": "tt0472023", + "name": "So You Think You Can Dance", + "type": "series", + "year": "2005–" + }, + { + "_id": "53677f09847ccc8123a185fd", + "imdb_id": "tt0178132", + "name": "Don Matteo", + "type": "series", + "year": "2000–" + }, + { + "_id": "53677ef9847ccc8123a13f85", + "imdb_id": "tt0758737", + "name": "Brothers & Sisters", + "type": "series", + "year": "2006–2011" + }, + { + "_id": "53677f02847ccc8123a1697c", + "imdb_id": "tt2919910", + "name": "Whose Line Is It Anyway?", + "type": "series", + "year": "2013–2023" + }, + { + "_id": "53677efc847ccc8123a14d26", + "imdb_id": "tt0421357", + "name": "Fullmetal Alchemist", + "type": "series", + "year": "2003–2004" + }, + { + "_id": "5a1ae83d543165dcd8ef63b6", + "imdb_id": "tt1043813", + "name": "Titans", + "year": "2018–2023", + "type": "series" + }, + { + "_id": "5ba9a45b173739c9f423e861", + "imdb_id": "tt8421350", + "name": "Manifest", + "type": "series", + "year": "2018–2023" + }, + { + "_id": "5542dff0b0c9284285037694", + "imdb_id": "tt0092484", + "name": "Wiseguy", + "year": "1987–1990", + "type": "series" + }, + { + "_id": "53677f00847ccc8123a1646e", + "imdb_id": "tt0051301", + "name": "Peter Gunn", + "type": "series", + "year": "1958–1961" + }, + { + "_id": "5b988e86173739c9f4237517", + "imdb_id": "tt7660730", + "name": "Black Earth Rising", + "type": "series", + "year": "2018" + }, + { + "_id": "62adf34b64ec43ef98c51cd7", + "imdb_id": "tt15792808", + "name": "Aoashi", + "type": "series", + "year": "2022" + }, + { + "_id": "53677f12847ccc8123a19f11", + "imdb_id": "tt0063929", + "name": "Monty Python's Flying Circus", + "type": "series", + "year": "1969–1974" + }, + { + "_id": "6001bb7f5424253341169581", + "imdb_id": "tt12598008", + "name": "So I'm a Spider, So What?", + "type": "series", + "year": "2021–" + }, + { + "_id": "5c1165f3173739c9f46c5d03", + "imdb_id": "tt0261492", + "name": "Sheena", + "type": "series", + "year": "2000–2002" + }, + { + "_id": "5dbdbad3c4ccb5dd924d79c7", + "imdb_id": "tt7772588", + "name": "For All Mankind", + "type": "series", + "year": "2019–" + }, + { + "_id": "53677ef9847ccc8123a14304", + "imdb_id": "tt0275140", + "name": "Law & Order: Criminal Intent", + "type": "series", + "year": "2001–2011" + }, + { + "_id": "5e54cbabc4ccb5dd92b4602e", + "imdb_id": "tt11034066", + "name": "Welcome to Demon-School, Iruma-kun", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "5c12fcb5173739c9f460d99e", + "imdb_id": "tt1407599", + "name": "Queen's Blade: The Exiled Virgin", + "type": "series", + "year": "2009" + }, + { + "_id": "53677f1c847ccc8123a1bb1f", + "imdb_id": "tt0088612", + "name": "Spenser: For Hire", + "type": "series", + "year": "1985–1988" + }, + { + "_id": "53677ef9847ccc8123a13c84", + "imdb_id": "tt1954347", + "name": "Continuum", + "type": "series", + "year": "2012–2015" + }, + { + "_id": "53677f2c847ccc8123a1e095", + "imdb_id": "tt0144701", + "name": "Barney & Friends", + "type": "series", + "year": "1992–2010" + }, + { + "_id": "53677f0f847ccc8123a19a4d", + "imdb_id": "tt0098900", + "name": "Avonlea", + "type": "series", + "year": "1990–1996" + }, + { + "_id": "57e329a6d7e54929823e7940", + "imdb_id": "tt5592146", + "name": "Speechless", + "type": "series", + "year": "2016–2019" + }, + { + "_id": "53677f0f847ccc8123a19995", + "imdb_id": "tt0106017", + "name": "Grace Under Fire", + "type": "series", + "year": "1993–1998" + }, + { + "_id": "53677f2c847ccc8123a1e231", + "imdb_id": "tt2368645", + "name": "Hit the Floor", + "type": "series", + "year": "2013–2018" + }, + { + "_id": "5f803df654242533412b4d3e", + "imdb_id": "tt7423322", + "name": "The Right Stuff", + "type": "series", + "year": "2020" + }, + { + "_id": "5c1e6490173739c9f487f806", + "imdb_id": "tt9159144", + "name": "Dark Side of the Ring", + "type": "series", + "year": "2019–" + }, + { + "_id": "53677f02847ccc8123a16b8b", + "imdb_id": "tt1140100", + "name": "Chowder", + "type": "series", + "year": "2007–2010" + }, + { + "_id": "53677ef9847ccc8123a13eeb", + "imdb_id": "tt1213218", + "name": "Batman: The Brave and the Bold", + "type": "series", + "year": "2008–2011" + }, + { + "_id": "5ad066edf51dd22f67a61a7b", + "imdb_id": "tt5232792", + "type": "series", + "name": "Lost in Space", + "year": "2018–2021" + }, + { + "_id": "53677f0c847ccc8123a18fcc", + "imdb_id": "tt1515996", + "name": "A Certain Scientific Railgun", + "type": "series", + "year": "2009–2020" + }, + { + "_id": "53677f0a847ccc8123a18c86", + "imdb_id": "tt0805905", + "name": "My Friends Tigger & Pooh", + "type": "series", + "year": "2007–2010" + }, + { + "_id": "53677f2c847ccc8123a1e22c", + "imdb_id": "tt1856010", + "name": "House of Cards", + "type": "series", + "year": "2013–2018" + }, + { + "_id": "553693e0cc9eee85bb52e82e", + "imdb_id": "tt4129004", + "name": "School of Rock", + "year": "2016–2018", + "type": "series" + }, + { + "_id": "6192292b64ec43ef98f984ec", + "imdb_id": "tt11712058", + "name": "Mayor of Kingstown", + "type": "series", + "year": "2021–" + }, + { + "_id": "55072f7a711bd19c92add880", + "imdb_id": "tt0081858", + "name": "Falcon Crest", + "year": "1981–1990", + "type": "series" + }, + { + "_id": "53677f08847ccc8123a18430", + "imdb_id": "tt0081954", + "name": "Urusei yatsura", + "type": "series", + "year": "1981–1986" + }, + { + "_id": "55075d4e711bd19c92addc16", + "imdb_id": "tt0808082", + "name": "Magical Girl Lyrical Nanoha", + "year": "2004–", + "type": "series" + }, + { + "_id": "5c119392173739c9f4cd8db0", + "imdb_id": "tt8773420", + "name": "Expats", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677efa847ccc8123a147f9", + "imdb_id": "tt0066625", + "name": "Alias Smith and Jones", + "type": "series", + "year": "1971–1973" + }, + { + "_id": "5c2b6213173739c9f4814a6d", + "imdb_id": "tt9140560", + "name": "WandaVision", + "type": "series", + "year": "2021" + }, + { + "_id": "53677ef9847ccc8123a13dc2", + "imdb_id": "tt1216222", + "name": "To LOVE-Ru", + "type": "series", + "year": "2008–2010" + }, + { + "_id": "53677efc847ccc8123a153b1", + "imdb_id": "tt0066722", + "name": "Upstairs, Downstairs", + "type": "series", + "year": "1971–1975" + }, + { + "_id": "5c2f48b1173739c9f47865ee", + "imdb_id": "tt7899522", + "name": "Gegege no Kitaro", + "type": "series", + "year": "2018–2020" + }, + { + "_id": "5c26770f173739c9f40876e2", + "imdb_id": "tt1783822", + "name": "Babar and the Adventures of Badou", + "type": "series", + "year": "2010–" + }, + { + "_id": "5c0c5f2b173739c9f4b12c8d", + "imdb_id": "tt1806294", + "name": "Kaizoku Sentai Gokaiger", + "type": "series", + "year": "2011–2012" + }, + { + "_id": "5d89820cc4ccb5dd92a71e0e", + "imdb_id": "tt10329042", + "name": "All Rise", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "53677ef9847ccc8123a13b95", + "imdb_id": "tt0115147", + "name": "The Daily Show", + "type": "series", + "year": "1996–" + }, + { + "_id": "54fc0921711bd19c92ad4954", + "imdb_id": "tt0068792", + "name": "Gatchaman", + "year": "1972–1974", + "type": "series" + }, + { + "_id": "59b5d4a71712e0f4dd2507d0", + "imdb_id": "tt5691552", + "type": "series", + "name": "The Orville", + "year": "2017–2022" + }, + { + "_id": "5c109b60173739c9f4017b30", + "imdb_id": "tt6185782", + "name": "Miss Kobayashi's Dragon Maid", + "type": "series", + "year": "2017–2022" + }, + { + "_id": "53677eff847ccc8123a15d18", + "imdb_id": "tt2363624", + "name": "Yu-Gi-Oh! Zexal", + "type": "series", + "year": "2011–2014" + }, + { + "_id": "53677ef9847ccc8123a13e2e", + "imdb_id": "tt0934814", + "name": "Chuck", + "type": "series", + "year": "2007–2012" + }, + { + "_id": "53677f51847ccc8123a20ea2", + "imdb_id": "tt0078622", + "name": "Hart to Hart", + "type": "series", + "year": "1979–1984" + }, + { + "_id": "53677ef9847ccc8123a140fd", + "imdb_id": "tt0094535", + "name": "Red Dwarf", + "type": "series", + "year": "1988–" + }, + { + "_id": "53677ef9847ccc8123a13b0d", + "imdb_id": "tt0758745", + "name": "Friday Night Lights", + "type": "series", + "year": "2006–2011" + }, + { + "_id": "53677f3d847ccc8123a1f2fd", + "imdb_id": "tt0103405", + "name": "Dr. Quinn, Medicine Woman", + "type": "series", + "year": "1993–1998" + }, + { + "_id": "5c47d54ed582b2575687fe53", + "imdb_id": "tt3703050", + "name": "Duck Quacks Don't Echo", + "type": "series", + "year": "2014–2017" + }, + { + "_id": "5c0b9ed6173739c9f426feca", + "imdb_id": "tt4163486", + "name": "Bee and PuppyCat", + "type": "series", + "year": "2013–2018" + }, + { + "_id": "5c140cac173739c9f434f715", + "imdb_id": "tt9184820", + "name": "Star Trek: Lower Decks", + "type": "series", + "year": "2020–" + }, + { + "_id": "53677efa847ccc8123a14a9b", + "imdb_id": "tt1442065", + "name": "Rookie Blue", + "type": "series", + "year": "2010–2015" + }, + { + "_id": "53677ef9847ccc8123a139ba", + "imdb_id": "tt0141842", + "name": "The Sopranos", + "type": "series", + "year": "1999–2007" + }, + { + "_id": "5baaf6f6173739c9f452c281", + "imdb_id": "tt7491982", + "name": "FBI", + "type": "series", + "year": "2018–" + }, + { + "_id": "55198016cc9eee85bb52dd7d", + "imdb_id": "tt3225270", + "name": "Noragami", + "year": "2014–2015", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13c57", + "imdb_id": "tt0379632", + "name": "Hustle", + "type": "series", + "year": "2004–2012" + }, + { + "_id": "5c1aff33173739c9f49ae093", + "imdb_id": "tt5817158", + "name": "To Tell the Truth", + "type": "series", + "year": "2016–2022" + }, + { + "_id": "53677ef9847ccc8123a13b78", + "imdb_id": "tt0965394", + "name": "Sanctuary", + "type": "series", + "year": "2008–2011" + }, + { + "_id": "5f29b0eb5424253341a05778", + "imdb_id": "tt10394706", + "name": "Deathstroke: Knights & Dragons", + "type": "series", + "year": "2020" + }, + { + "_id": "60e6b8b964ec43ef98cdfec6", + "imdb_id": "tt10653784", + "name": "Gossip Girl", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "5c3e5e72d582b257563bd122", + "imdb_id": "tt2309408", + "name": "Little Busters!", + "type": "series", + "year": "2012–2013" + }, + { + "_id": "5c181a27173739c9f44570f0", + "imdb_id": "tt1294009", + "name": "Only Connect", + "type": "series", + "year": "2008–" + }, + { + "_id": "53677ef9847ccc8123a1422f", + "imdb_id": "tt0412175", + "name": "Medium", + "type": "series", + "year": "2005–2011" + }, + { + "_id": "53677efa847ccc8123a1484c", + "imdb_id": "tt1600199", + "name": "Franklin & Bash", + "type": "series", + "year": "2011–2014" + }, + { + "_id": "614a90f864ec43ef98060cc9", + "imdb_id": "tt14449470", + "name": "FBI: International", + "type": "series", + "year": "2021–" + }, + { + "_id": "5c3fa828d582b25756e50929", + "imdb_id": "tt3755768", + "name": "Ninku", + "type": "series", + "year": "1994–1996" + }, + { + "_id": "5c139638173739c9f44da51a", + "imdb_id": "tt5240222", + "name": "God Eater", + "type": "series", + "year": "2015–" + }, + { + "_id": "53677efc847ccc8123a14d04", + "imdb_id": "tt1530541", + "name": "Offspring", + "type": "series", + "year": "2010–2017" + }, + { + "_id": "5c1ea640173739c9f40ebbda", + "imdb_id": "tt8528256", + "name": "Dragon Pilot: Hisone and Masotan", + "type": "series", + "year": "2018" + }, + { + "_id": "567c8a03bb83c664989a1832", + "imdb_id": "tt4209256", + "name": "Colony", + "year": "2016–2018", + "type": "series" + }, + { + "_id": "53677f68847ccc8123a22c68", + "imdb_id": "tt0058791", + "name": "The Big Valley", + "type": "series", + "year": "1965–1969" + }, + { + "_id": "65a489adbd36726cbb8758ba", + "imdb_id": "tt29218693", + "name": "Baddies East", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677f22847ccc8123a1cc10", + "imdb_id": "tt0055657", + "name": "The Alfred Hitchcock Hour", + "type": "series", + "year": "1962–1965" + }, + { + "_id": "53677efa847ccc8123a14b80", + "imdb_id": "tt1888075", + "name": "Death in Paradise", + "type": "series", + "year": "2011–" + }, + { + "_id": "5e1f72cac4ccb5dd92c4df5e", + "imdb_id": "tt11428630", + "name": "Bofuri: I Don't Want to Get Hurt, So I'll Max Out My Defense", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "53677ef9847ccc8123a1399c", + "imdb_id": "tt1870479", + "name": "The Newsroom", + "type": "series", + "year": "2012–2014" + }, + { + "_id": "53677ef9847ccc8123a1384c", + "imdb_id": "tt1442550", + "name": "Shark Tank", + "type": "series", + "year": "2009–" + }, + { + "_id": "5c104377173739c9f45db810", + "imdb_id": "tt0220189", + "name": "The Unfettered Shogun", + "type": "series", + "year": "1978–2008" + }, + { + "_id": "53677f7c847ccc8123a23e85", + "imdb_id": "tt0108787", + "name": "Ghostwriter", + "type": "series", + "year": "1992–1995" + }, + { + "_id": "605e891d54242533410c19b3", + "imdb_id": "tt7939768", + "name": "The Mighty Ducks: Game Changers", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "53677f7c847ccc8123a23f00", + "imdb_id": "tt3530232", + "name": "Last Week Tonight with John Oliver", + "type": "series", + "year": "2014–" + }, + { + "_id": "53677ef9847ccc8123a14170", + "imdb_id": "tt0367367", + "name": "Max & Ruby", + "type": "series", + "year": "2002–2021" + }, + { + "_id": "5d89d6bfc4ccb5dd9209a351", + "imdb_id": "tt10327354", + "name": "Prodigal Son", + "type": "series", + "year": "2019–2021" + }, + { + "_id": "53677efa847ccc8123a14531", + "imdb_id": "tt0759364", + "name": "America's Got Talent", + "type": "series", + "year": "2006–" + }, + { + "_id": "5c0a14db173739c9f4792c78", + "imdb_id": "tt3069742", + "name": "Captain Tsubasa: Road to 2002", + "type": "series", + "year": "2001–2002" + }, + { + "_id": "596ffb8e1635517fbf56e954", + "imdb_id": "tt6517102", + "name": "Castlevania", + "type": "series", + "year": "2017–2021" + }, + { + "_id": "53677f4f847ccc8123a20b75", + "imdb_id": "tt2114184", + "name": "The High Fructose Adventures of Annoying Orange", + "type": "series", + "year": "2012–2014" + }, + { + "_id": "53677efa847ccc8123a14688", + "imdb_id": "tt2543796", + "name": "Girl Meets World", + "type": "series", + "year": "2014–2017" + }, + { + "_id": "53677efc847ccc8123a153d3", + "imdb_id": "tt1365047", + "name": "Who Do You Think You Are?", + "type": "series", + "year": "2010–" + }, + { + "_id": "5fca055b542425334114064a", + "imdb_id": "tt11252090", + "name": "The Hardy Boys", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "548061968527d2e0cb4fc323", + "imdb_id": "tt2618986", + "name": "Wayward Pines", + "type": "series", + "year": "2015–2016" + }, + { + "_id": "5c3003a4173739c9f4f7e19b", + "imdb_id": "tt5059866", + "name": "Himouto! Umaru-chan", + "type": "series", + "year": "2015–2017" + }, + { + "_id": "53677efa847ccc8123a147de", + "imdb_id": "tt0476042", + "name": "Gunslinger Girl", + "type": "series", + "year": "2003–2004" + }, + { + "_id": "53677ef9847ccc8123a14199", + "imdb_id": "tt1710308", + "name": "Regular Show", + "type": "series", + "year": "2010–2017" + }, + { + "_id": "53677ef9847ccc8123a13920", + "imdb_id": "tt0844441", + "name": "True Blood", + "type": "series", + "year": "2008–2014" + }, + { + "_id": "53677f00847ccc8123a1647f", + "imdb_id": "tt0055701", + "name": "The Saint", + "type": "series", + "year": "1962–1969" + }, + { + "_id": "581c3b7055f8aab460cfd369", + "imdb_id": "tt4786824", + "name": "The Crown", + "type": "series", + "year": "2016–2023" + }, + { + "_id": "5c0e192c173739c9f481385a", + "imdb_id": "tt9140554", + "name": "Loki", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "5d899e42c4ccb5dd92c5162a", + "imdb_id": "tt10329024", + "name": "Bob Hearts Abishola", + "type": "series", + "year": "2019–2024" + }, + { + "_id": "5900197e1635517fbf56e7b5", + "imdb_id": "tt4955480", + "name": "Great News", + "type": "series", + "year": "2017–2018" + }, + { + "_id": "53677f17847ccc8123a1ab44", + "imdb_id": "tt0465353", + "name": "Sleeper Cell", + "type": "series", + "year": "2005–2006" + }, + { + "_id": "53677f05847ccc8123a17c99", + "imdb_id": "tt1584000", + "name": "Durarara!!", + "type": "series", + "year": "2010" + }, + { + "_id": "5cf145175111f1a8a31cd11f", + "imdb_id": "tt7137906", + "name": "When They See Us", + "type": "series", + "year": "2019" + }, + { + "_id": "5c0c1f74173739c9f42913da", + "imdb_id": "tt0488477", + "name": "XXXHOLiC", + "type": "series", + "year": "2006–2011" + }, + { + "_id": "607b183664ec43ef9804f856", + "imdb_id": "tt12635162", + "name": "Don't Toy with Me, Miss Nagatoro", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "59b10bed1712e0f4dd547e2f", + "imdb_id": "tt4998350", + "type": "series", + "name": "The Deuce", + "year": "2017–2019" + }, + { + "_id": "5a0addf7543165dcd8b97387", + "imdb_id": "tt5363912", + "name": "The Last O.G.", + "year": "2018–2021", + "type": "series" + }, + { + "_id": "550787f3711bd19c92ade21f", + "imdb_id": "tt0370194", + "name": "Reno 911!", + "year": "2003–", + "type": "series" + }, + { + "_id": "53677f09847ccc8123a18626", + "imdb_id": "tt0994314", + "name": "Code Geass", + "type": "series", + "year": "2006–2008" + }, + { + "_id": "53677f45847ccc8123a1ff5d", + "imdb_id": "tt0111945", + "name": "The Drew Carey Show", + "type": "series", + "year": "1995–2004" + }, + { + "_id": "53677efa847ccc8123a148c1", + "imdb_id": "tt0174378", + "name": "Becker", + "type": "series", + "year": "1998–2004" + }, + { + "_id": "5c2cc4da173739c9f4041733", + "imdb_id": "tt2362887", + "name": "Uta no prince-sama - maji love 1000%", + "type": "series", + "year": "2011–" + }, + { + "_id": "53677ef5847ccc8123a13778", + "imdb_id": "tt1843230", + "name": "Once Upon a Time", + "type": "series", + "year": "2011–2018" + }, + { + "_id": "599b6c193e5e4b900ae85c52", + "imdb_id": "tt6311972", + "name": "Raven's Home", + "type": "series", + "year": "2017–" + }, + { + "_id": "54fb5f4b711bd19c92ad4433", + "imdb_id": "tt1163560", + "name": "Maria Watches Over Us", + "year": "2004–", + "type": "series" + }, + { + "_id": "5c1a6d24173739c9f472dcc9", + "imdb_id": "tt0098767", + "name": "Earth Squadron Fiveman", + "type": "series", + "year": "1990–1991" + }, + { + "_id": "53677ef9847ccc8123a137b1", + "imdb_id": "tt1358522", + "name": "White Collar", + "type": "series", + "year": "2009–2014" + }, + { + "_id": "6548d64abd36726cbb376e5e", + "imdb_id": "tt13966962", + "name": "Echo", + "type": "series", + "year": "2023–2024" + }, + { + "_id": "60e28f2664ec43ef9815c6f0", + "imdb_id": "tt5556656", + "name": "Kabaneri of the Iron Fortress", + "type": "series", + "year": "2016" + }, + { + "_id": "5810ef17d7e549298241386d", + "imdb_id": "tt4047038", + "name": "Dirk Gently's Holistic Detective Agency", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "53677f02847ccc8123a1715b", + "imdb_id": "tt0115231", + "name": "Kenan & Kel", + "type": "series", + "year": "1996–2023" + }, + { + "_id": "56c0c506f6b914c6c681d727", + "imdb_id": "tt5444412", + "name": "Bunnicula", + "year": "2016–2019", + "type": "series" + }, + { + "_id": "53677f0a847ccc8123a186ae", + "imdb_id": "tt0057793", + "name": "12 O'Clock High", + "type": "series", + "year": "1964–1967" + }, + { + "_id": "53677eff847ccc8123a15d90", + "imdb_id": "tt2377452", + "name": "K", + "type": "series", + "year": "2012–" + }, + { + "_id": "5c0ad564173739c9f4d56c12", + "imdb_id": "tt7165904", + "name": "Big City Greens", + "type": "series", + "year": "2018–" + }, + { + "_id": "53677ef9847ccc8123a13cf4", + "imdb_id": "tt0115108", + "name": "Beast Wars: Transformers", + "type": "series", + "year": "1996–1999" + }, + { + "_id": "6186946264ec43ef98e4b950", + "imdb_id": "tt11041332", + "name": "Yellowjackets", + "type": "series", + "year": "2021–" + }, + { + "_id": "550819d6711bd19c92ade40b", + "imdb_id": "tt3441810", + "name": "Some Assembly Required", + "year": "2014–2016", + "type": "series" + }, + { + "_id": "5c1a405f173739c9f41b87d5", + "imdb_id": "tt1494569", + "name": "WWF Challenge", + "type": "series", + "year": "1986–" + }, + { + "_id": "559503f3bf6c900d1838933a", + "imdb_id": "tt0054531", + "name": "The Defenders", + "year": "1961–1965", + "type": "series" + }, + { + "_id": "53677f4f847ccc8123a20b5e", + "imdb_id": "tt0062591", + "name": "The Name of the Game", + "type": "series", + "year": "1968–1971" + }, + { + "_id": "5bc0612e173739c9f47909b4", + "imdb_id": "tt6763664", + "name": "The Haunting of Hill House", + "type": "series", + "year": "2018" + }, + { + "_id": "53677f5a847ccc8123a21bca", + "imdb_id": "tt1146333", + "name": "Shark Week", + "type": "series", + "year": "1987–" + }, + { + "_id": "54c0f5788527d2e0cb509789", + "imdb_id": "tt0399977", + "name": "Ich bin ein Star - Holt mich hier raus!", + "type": "series", + "year": "2004–" + }, + { + "_id": "5378cbfc847ccc8123ad3847", + "imdb_id": "tt3288518", + "name": "Younger", + "type": "series", + "year": "2015–2021" + }, + { + "_id": "5c31de8e173739c9f418cecf", + "imdb_id": "tt6460600", + "name": "BanG Dream!", + "type": "series", + "year": "2017–2020" + }, + { + "_id": "53677f21847ccc8123a1cb30", + "imdb_id": "tt3281796", + "name": "Power", + "type": "series", + "year": "2014–2020" + }, + { + "_id": "53677efd847ccc8123a154a2", + "imdb_id": "tt2089467", + "name": "Talking Dead", + "type": "series", + "year": "2011–" + }, + { + "_id": "53677ef9847ccc8123a13e54", + "imdb_id": "tt0784896", + "name": "Mickey Mouse Clubhouse", + "type": "series", + "year": "2006–2016" + }, + { + "_id": "53677ef9847ccc8123a138d9", + "imdb_id": "tt1195935", + "name": "The Cleveland Show", + "type": "series", + "year": "2009–2013" + }, + { + "_id": "5c0b1b36173739c9f46358fc", + "imdb_id": "tt6740188", + "name": "Sakura Quest", + "type": "series", + "year": "2017–" + }, + { + "_id": "642874a864ec43ef988cba8d", + "imdb_id": "tt22817632", + "name": "Heavenly Delusion", + "type": "series", + "year": "2023" + }, + { + "_id": "6358e57864ec43ef98572c62", + "imdb_id": "tt20723374", + "name": "Tales of the Jedi", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677f6d847ccc8123a230ce", + "imdb_id": "tt0387719", + "name": "Astro Boy", + "type": "series", + "year": "2003–2004" + }, + { + "_id": "53677ef9847ccc8123a1380e", + "imdb_id": "tt1943524", + "name": "The Finder", + "type": "series", + "year": "2012" + }, + { + "_id": "53677ef9847ccc8123a144e7", + "imdb_id": "tt0050032", + "name": "Leave It to Beaver", + "type": "series", + "year": "1957–1963" + }, + { + "_id": "54e3249ce573cadcfa1fdb80", + "imdb_id": "tt0482855", + "name": "Blood+", + "type": "series", + "year": "2005–2006" + }, + { + "_id": "53677f2c847ccc8123a1e127", + "imdb_id": "tt2329077", + "name": "Beware the Batman", + "type": "series", + "year": "2013–2014" + }, + { + "_id": "61447f9764ec43ef9883bb4a", + "imdb_id": "tt10731840", + "name": "The Premise", + "type": "series", + "year": "2021" + }, + { + "_id": "579622e0f0b6c53b3c7942c3", + "imdb_id": "tt4574334", + "name": "Stranger Things", + "year": "2016–2025", + "type": "series" + }, + { + "_id": "578935e8f0b6c53b3c787521", + "imdb_id": "tt5574490", + "name": "Animal Kingdom", + "year": "2016–2022", + "type": "series" + }, + { + "_id": "53677f02847ccc8123a16d74", + "imdb_id": "tt2281375", + "name": "Nashville", + "type": "series", + "year": "2012–2018" + }, + { + "_id": "54e60054fc2ab98b66971c24", + "imdb_id": "tt0132666", + "name": "The Wonderful World of Disney", + "type": "series", + "year": "1997–2023" + }, + { + "_id": "5c1c283e173739c9f4a41d44", + "imdb_id": "tt0367414", + "name": "Soreike! Anpanman", + "type": "series", + "year": "1988–" + }, + { + "_id": "53677ef9847ccc8123a13a57", + "imdb_id": "tt1615919", + "name": "Raising Hope", + "type": "series", + "year": "2010–2014" + }, + { + "_id": "53677efc847ccc8123a14d30", + "imdb_id": "tt0386950", + "name": "Air Crash Investigation", + "type": "series", + "year": "2003–" + }, + { + "_id": "53677ef9847ccc8123a14489", + "imdb_id": "tt1830491", + "name": "Austin & Ally", + "type": "series", + "year": "2011–2016" + }, + { + "_id": "53677f51847ccc8123a20e26", + "imdb_id": "tt0106102", + "name": "Pie in the Sky", + "type": "series", + "year": "1994–1997" + }, + { + "_id": "53677f0c847ccc8123a194dc", + "imdb_id": "tt0103484", + "name": "Mad About You", + "type": "series", + "year": "1992–2019" + }, + { + "_id": "6345aa4d64ec43ef989b6337", + "imdb_id": "tt13616990", + "name": "Chainsaw Man", + "type": "series", + "year": "2022" + }, + { + "_id": "53677f26847ccc8123a1d87e", + "imdb_id": "tt0072519", + "name": "The Jeffersons", + "type": "series", + "year": "1975–1985" + }, + { + "_id": "53677f00847ccc8123a16182", + "imdb_id": "tt0433309", + "name": "Numb3rs", + "type": "series", + "year": "2005–2010" + }, + { + "_id": "53677f14847ccc8123a1a4dc", + "imdb_id": "tt0065329", + "name": "The Odd Couple", + "type": "series", + "year": "1970–1975" + }, + { + "_id": "53677efd847ccc8123a15928", + "imdb_id": "tt0103520", + "name": "The Real World", + "type": "series", + "year": "1992–" + }, + { + "_id": "56090a626c6a1c0b815c7993", + "imdb_id": "tt4428122", + "name": "Quantico", + "year": "2015–2018", + "type": "series" + }, + { + "_id": "53677ef5847ccc8123a13780", + "imdb_id": "tt0386676", + "name": "The Office", + "type": "series", + "year": "2005–2013" + }, + { + "_id": "53677f17847ccc8123a1aaf7", + "imdb_id": "tt0092468", + "name": "Tour of Duty", + "type": "series", + "year": "1987–1990" + }, + { + "_id": "5c18e931173739c9f4936db1", + "imdb_id": "tt7772600", + "name": "The Adventures of Paddington", + "type": "series", + "year": "2019–" + }, + { + "_id": "53677f48847ccc8123a202f5", + "imdb_id": "tt0149413", + "name": "Almost Live!", + "type": "series", + "year": "1984–1999" + }, + { + "_id": "53677f14847ccc8123a1a503", + "imdb_id": "tt0103512", + "name": "Picket Fences", + "type": "series", + "year": "1992–1996" + }, + { + "_id": "5690d0dfbb83c664989c1705", + "imdb_id": "tt0300839", + "name": "A Place in the Sun", + "year": "2000–", + "type": "series" + }, + { + "_id": "5decfdbdc4ccb5dd926f1193", + "imdb_id": "tt7661384", + "name": "The L Word: Generation Q", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "557a9fa4bf6c900d18355af9", + "imdb_id": "tt3593432", + "name": "Another Period", + "year": "2013–2018", + "type": "series" + }, + { + "_id": "5d8af0b8c4ccb5dd92b10101", + "imdb_id": "tt10276062", + "name": "Mixed-ish", + "type": "series", + "year": "2019–2021" + }, + { + "_id": "53677f14847ccc8123a1a438", + "imdb_id": "tt0367345", + "name": "Joan of Arcadia", + "type": "series", + "year": "2003–2005" + }, + { + "_id": "53677f45847ccc8123a1fc87", + "imdb_id": "tt0111875", + "name": "All That", + "type": "series", + "year": "1994–2020" + }, + { + "_id": "53677f04847ccc8123a174d1", + "imdb_id": "tt1657563", + "name": "Check It Out! with Dr. Steve Brule", + "type": "series", + "year": "2010–2017" + }, + { + "_id": "6166be2d64ec43ef987c7d40", + "imdb_id": "tt0048916", + "name": "Zane Grey Theatre", + "type": "series", + "year": "1956–1961" + }, + { + "_id": "53677f5e847ccc8123a222ef", + "imdb_id": "tt1685078", + "name": "Ek Veer Stree Ki Kahaani... Jhansi Ki Rani", + "type": "series", + "year": "2009–2011" + }, + { + "_id": "541c1363a8f27b1bb90cb4f4", + "imdb_id": "tt0318895", + "name": "Hamtaro", + "type": "series", + "year": "2000–2006" + }, + { + "_id": "53677f14847ccc8123a1a5d8", + "imdb_id": "tt0108927", + "name": "Sister, Sister", + "type": "series", + "year": "1994–1999" + }, + { + "_id": "5c0b0dca173739c9f4481845", + "imdb_id": "tt6396082", + "name": "Carpool Karaoke", + "type": "series", + "year": "2017–" + }, + { + "_id": "53677f6d847ccc8123a23154", + "imdb_id": "tt0115157", + "name": "Dexter's Laboratory", + "type": "series", + "year": "1996–2003" + }, + { + "_id": "5e72edf4c4ccb5dd92d7aa77", + "imdb_id": "tt9900092", + "name": "Motherland: Fort Salem", + "type": "series", + "year": "2020–2022" + }, + { + "_id": "555af066bf6c900d1833d57b", + "imdb_id": "tt0108850", + "name": "Marmalade Boy", + "year": "1994–2005", + "type": "series" + }, + { + "_id": "53677f29847ccc8123a1ddd1", + "imdb_id": "tt2608368", + "name": "Real Husbands of Hollywood", + "type": "series", + "year": "2013–" + }, + { + "_id": "53677f54847ccc8123a212f9", + "imdb_id": "tt0463826", + "name": "Merlin's Apprentice", + "type": "series", + "year": "2006" + }, + { + "_id": "5c0ce44a173739c9f4667eae", + "imdb_id": "tt8496638", + "name": "Boarding School Juliet", + "type": "series", + "year": "2018" + }, + { + "_id": "53677ef9847ccc8123a142de", + "imdb_id": "tt1797404", + "name": "House of Lies", + "type": "series", + "year": "2012–2016" + }, + { + "_id": "53677f07847ccc8123a17e22", + "imdb_id": "tt0965547", + "name": "Slam Dunk", + "type": "series", + "year": "1993–1996" + }, + { + "_id": "537500c6847ccc8123ad0a11", + "imdb_id": "tt2707408", + "name": "Narcos", + "type": "series", + "year": "2015–2017" + }, + { + "_id": "53677f05847ccc8123a17685", + "imdb_id": "tt0120570", + "name": "From the Earth to the Moon", + "type": "series", + "year": "1998" + }, + { + "_id": "53677f45847ccc8123a1fca5", + "imdb_id": "tt2273734", + "name": "Crash & Bernstein", + "type": "series", + "year": "2012–2014" + }, + { + "_id": "53677efd847ccc8123a1555e", + "imdb_id": "tt0086817", + "name": "The Transformers", + "type": "series", + "year": "1984–1987" + }, + { + "_id": "5c09a23d173739c9f4bd7dd5", + "imdb_id": "tt5839732", + "name": "Orange", + "type": "series", + "year": "2016" + }, + { + "_id": "53677ef9847ccc8123a139d6", + "imdb_id": "tt1124373", + "name": "Sons of Anarchy", + "type": "series", + "year": "2008–2014" + }, + { + "_id": "53677ef9847ccc8123a138f1", + "imdb_id": "tt0796264", + "name": "Eureka", + "type": "series", + "year": "2006–2012" + }, + { + "_id": "53677f00847ccc8123a165bd", + "imdb_id": "tt0118437", + "name": "The Practice", + "type": "series", + "year": "1997–2004" + }, + { + "_id": "633dd75264ec43ef98b417b7", + "imdb_id": "tt14115938", + "name": "The Eminence in Shadow", + "type": "series", + "year": "2022–2023" + }, + { + "_id": "53677ef9847ccc8123a13a50", + "imdb_id": "tt0397442", + "name": "Gossip Girl", + "type": "series", + "year": "2007–2012" + }, + { + "_id": "5c163f12173739c9f40a4b5a", + "imdb_id": "tt0157222", + "name": "Dr. Slump", + "type": "series", + "year": "1997–1999" + }, + { + "_id": "589cda0a1635517fbf56d91c", + "imdb_id": "tt5114356", + "name": "Legion", + "type": "series", + "year": "2017–2019" + }, + { + "_id": "5c2ac8fc173739c9f494f850", + "imdb_id": "tt7482186", + "name": "Cosmic Disclosure", + "type": "series", + "year": "2015–" + }, + { + "_id": "5d97f0ddc4ccb5dd9259fab5", + "imdb_id": "tt8914012", + "name": "The Last Kids on Earth", + "type": "series", + "year": "2019–2021" + }, + { + "_id": "53677f5c847ccc8123a21f7e", + "imdb_id": "tt0224455", + "name": "Angela Anaconda", + "type": "series", + "year": "1999–2002" + }, + { + "_id": "5c593300d582b25756573ab7", + "imdb_id": "tt9646546", + "name": "Dimension 20", + "type": "series", + "year": "2018–" + }, + { + "_id": "53677f40847ccc8123a1f736", + "imdb_id": "tt0103488", + "name": "Martin", + "type": "series", + "year": "1992–1997" + }, + { + "_id": "5c1bf569173739c9f43e172f", + "imdb_id": "tt0051267", + "name": "The Donna Reed Show", + "type": "series", + "year": "1958–1966" + }, + { + "_id": "5c16cdfa173739c9f42f47da", + "imdb_id": "tt0400998", + "name": "Democracy Now!", + "type": "series", + "year": "2001–" + }, + { + "_id": "53e129b8a8f27b1bb90be13b", + "imdb_id": "tt0348952", + "name": "The File of Young Kindaichi", + "type": "series", + "year": "1997–2000" + }, + { + "_id": "5c323eb4173739c9f4d8daec", + "imdb_id": "tt6591406", + "name": "After the Rain", + "type": "series", + "year": "2018" + }, + { + "_id": "54fc0938711bd19c92ad49ad", + "imdb_id": "tt3114376", + "name": "Beyond the Boundary", + "year": "2013–2014", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13aba", + "imdb_id": "tt1693592", + "name": "Vera", + "type": "series", + "year": "2011–" + }, + { + "_id": "53677f17847ccc8123a1af88", + "imdb_id": "tt0367409", + "name": "Shaman King", + "type": "series", + "year": "2001–2005" + }, + { + "_id": "5a577f41543165dcd8c3c7da", + "imdb_id": "tt6987476", + "type": "series", + "name": "Burden of Truth", + "year": "2018–2021" + }, + { + "_id": "6326eb1164ec43ef989d38a3", + "imdb_id": "tt0271894", + "name": "48 Hours", + "type": "series", + "year": "1988–" + }, + { + "_id": "65928125bd36726cbb78ad53", + "imdb_id": "tt5611024", + "name": "Fool Me Once", + "type": "series", + "year": "2024" + }, + { + "_id": "53677ef9847ccc8123a138f3", + "imdb_id": "tt1183865", + "name": "Alphas", + "type": "series", + "year": "2011–2012" + }, + { + "_id": "5e3d3318c4ccb5dd92aefb1e", + "imdb_id": "tt3007572", + "name": "Locke & Key", + "type": "series", + "year": "2020–2022" + }, + { + "_id": "54c92d1ce573cadcfa1f770f", + "imdb_id": "tt1930123", + "name": "Web Therapy", + "type": "series", + "year": "2011–2015" + }, + { + "_id": "5bc0612e173739c9f4790a4a", + "imdb_id": "tt8619822", + "name": "Light as a Feather", + "type": "series", + "year": "2018–2019" + }, + { + "_id": "53677ef9847ccc8123a143d4", + "imdb_id": "tt1612578", + "name": "$#*! My Dad Says", + "type": "series", + "year": "2010–2011" + }, + { + "_id": "621b44ea64ec43ef98d8632c", + "imdb_id": "tt11173006", + "name": "Super Pumped", + "type": "series", + "year": "2022–" + }, + { + "_id": "5e71b2a6c4ccb5dd92887639", + "imdb_id": "tt8089592", + "name": "Little Fires Everywhere", + "type": "series", + "year": "2020" + }, + { + "_id": "5c24cce6173739c9f40253d8", + "imdb_id": "tt7200884", + "name": "Let's Go Luna!", + "type": "series", + "year": "2018–2022" + }, + { + "_id": "5c240c42173739c9f4c6195f", + "imdb_id": "tt0196050", + "name": "Nobody's Boy: Remi", + "type": "series", + "year": "1977–1978" + }, + { + "_id": "576c59c6f0b6c53b3c76ac05", + "imdb_id": "tt3908868", + "name": "Decker", + "year": "2014–2017", + "type": "series" + }, + { + "_id": "65082c74bd36726cbbe151be", + "imdb_id": "tt17220216", + "name": "Monarch: Legacy of Monsters", + "type": "series", + "year": "2023–" + }, + { + "_id": "5c18308e173739c9f470fcb0", + "imdb_id": "tt1276525", + "name": "Chi's Sweet Home", + "type": "series", + "year": "2008" + }, + { + "_id": "53677ef9847ccc8123a13918", + "imdb_id": "tt1552112", + "name": "The Glades", + "type": "series", + "year": "2010–2013" + }, + { + "_id": "53eb359ea8f27b1bb90c0855", + "imdb_id": "tt0177455", + "name": "Oh Yeah! Cartoons", + "type": "series", + "year": "1998–2002" + }, + { + "_id": "5c3e62ffd582b257563fbaa2", + "imdb_id": "tt3247300", + "name": "2 Days 1 Night", + "type": "series", + "year": "2007–" + }, + { + "_id": "53677ef9847ccc8123a13f06", + "imdb_id": "tt0851851", + "name": "Terminator: The Sarah Connor Chronicles", + "type": "series", + "year": "2008–2009" + }, + { + "_id": "53677f29847ccc8123a1ded7", + "imdb_id": "tt3061046", + "name": "Steven Universe", + "type": "series", + "year": "2013–2019" + }, + { + "_id": "53677ef9847ccc8123a1418c", + "imdb_id": "tt0421030", + "name": "Big Love", + "type": "series", + "year": "2006–2011" + }, + { + "_id": "5e96f0ea512025562c1bcc9f", + "imdb_id": "tt9244556", + "name": "Mrs. America", + "type": "series", + "year": "2020" + }, + { + "_id": "589e2cbd1635517fbf56db31", + "imdb_id": "tt5212822", + "name": "Imposters", + "type": "series", + "year": "2017–2018" + }, + { + "_id": "53677efa847ccc8123a147b8", + "imdb_id": "tt1094229", + "name": "Heartland", + "type": "series", + "year": "2007–" + }, + { + "_id": "55075db3711bd19c92ade076", + "imdb_id": "tt4219258", + "name": "The Testament of Sister New Devil", + "year": "2015–2016", + "type": "series" + }, + { + "_id": "53677f20847ccc8123a1c68f", + "imdb_id": "tt0073965", + "name": "The Bionic Woman", + "type": "series", + "year": "1976–1978" + }, + { + "_id": "62da2c6d64ec43ef9826e8b3", + "imdb_id": "tt15975122", + "name": "Call of the Night", + "type": "series", + "year": "2022" + }, + { + "_id": "5e22502fc4ccb5dd9238a907", + "imdb_id": "tt8000674", + "name": "Little America", + "type": "series", + "year": "2020–2022" + }, + { + "_id": "5c1e292d173739c9f416af9e", + "imdb_id": "tt8740790", + "name": "Bridgerton", + "type": "series", + "year": "2020–" + }, + { + "_id": "5c1d5ad2173739c9f4bd300a", + "imdb_id": "tt0059999", + "name": "Jericho", + "type": "series", + "year": "1966–1967" + }, + { + "_id": "5c0d7185173739c9f481efc5", + "imdb_id": "tt8134470", + "name": "The Undoing", + "type": "series", + "year": "2020" + }, + { + "_id": "5c15183b173739c9f40255a4", + "imdb_id": "tt0092492", + "name": "Thirtysomething", + "type": "series", + "year": "1987–1991" + }, + { + "_id": "53677f3f847ccc8123a1f4cb", + "imdb_id": "tt2543378", + "name": "Married to Medicine", + "type": "series", + "year": "2013–" + }, + { + "_id": "5c37afe0d582b25756b62b9f", + "imdb_id": "tt0170994", + "name": "The Paul Daniels Magic Show", + "type": "series", + "year": "1979–1994" + }, + { + "_id": "53677f0c847ccc8123a18fb0", + "imdb_id": "tt0473578", + "name": "Genshiken", + "type": "series", + "year": "2004–2007" + }, + { + "_id": "55a20eafbf6c900d183a68de", + "imdb_id": "tt1502749", + "name": "The Chase", + "year": "2009–", + "type": "series" + }, + { + "_id": "590043b21635517fbf56e7bd", + "imdb_id": "tt4508686", + "name": "Ghost in the Shell Arise: Alternative Architecture", + "type": "series", + "year": "2015" + }, + { + "_id": "53677f0c847ccc8123a193df", + "imdb_id": "tt0247102", + "name": "Girlfriends", + "type": "series", + "year": "2000–2008" + }, + { + "_id": "601d870f54242533416e5ac3", + "imdb_id": "tt3592032", + "name": "Ping Pong the Animation", + "type": "series", + "year": "2014" + }, + { + "_id": "5c2490d7173739c9f48dad35", + "imdb_id": "tt0306365", + "name": "Nintama Rantarô", + "type": "series", + "year": "1993–" + }, + { + "_id": "53677f3d847ccc8123a1f489", + "imdb_id": "tt0047750", + "name": "The Life and Legend of Wyatt Earp", + "type": "series", + "year": "1955–1961" + }, + { + "_id": "6026a81b54242533415ddfe6", + "imdb_id": "tt13714610", + "name": "Steven Universe Future", + "type": "series", + "year": "2019–2020" + }, + { + "_id": "53677efd847ccc8123a1597c", + "imdb_id": "tt1657081", + "name": "Law & Order: LA", + "type": "series", + "year": "2010–2011" + }, + { + "_id": "53677f03847ccc8123a17232", + "imdb_id": "tt3006802", + "name": "Outlander", + "type": "series", + "year": "2014–" + }, + { + "_id": "53677f23847ccc8123a1d155", + "imdb_id": "tt0059982", + "name": "Family Affair", + "type": "series", + "year": "1966–1971" + }, + { + "_id": "54ac200f8527d2e0cb504bf9", + "imdb_id": "tt0096591", + "name": "Nadia: The Secret of Blue Water", + "type": "series", + "year": "1990–2003" + }, + { + "_id": "616adf4164ec43ef9881274b", + "imdb_id": "tt10684374", + "name": "The Ghost and Molly McGee", + "type": "series", + "year": "2021–" + }, + { + "_id": "642b503564ec43ef98d2e0a9", + "imdb_id": "tt7088332", + "name": "Isekai wa smartphone to tomo ni.", + "type": "series", + "year": "2017–2023" + }, + { + "_id": "53677f19847ccc8123a1b45f", + "imdb_id": "tt1799631", + "name": "Blue Exorcist", + "type": "series", + "year": "2011" + }, + { + "_id": "5c0c5c4f173739c9f4ab3e83", + "imdb_id": "tt8456094", + "name": "Scooby-Doo and Guess Who?", + "type": "series", + "year": "2019–2021" + }, + { + "_id": "581919a555f8aab460cfa0d3", + "imdb_id": "tt5057130", + "name": "Medici", + "type": "series", + "year": "2016–2019" + }, + { + "_id": "53677ef9847ccc8123a139af", + "imdb_id": "tt0149460", + "name": "Futurama", + "type": "series", + "year": "1999–" + }, + { + "_id": "53677f21847ccc8123a1c983", + "imdb_id": "tt0167742", + "name": "Where on Earth Is Carmen Sandiego?", + "type": "series", + "year": "1994–1999" + }, + { + "_id": "53677ef9847ccc8123a14383", + "imdb_id": "tt1343865", + "name": "Web Therapy", + "type": "series", + "year": "2008–2014" + }, + { + "_id": "5b8f5553173739c9f4cdfba9", + "imdb_id": "tt6110648", + "name": "The Purge", + "type": "series", + "year": "2018–2019" + }, + { + "_id": "53677f1d847ccc8123a1bda9", + "imdb_id": "tt0062551", + "name": "The Champions", + "type": "series", + "year": "1968–1969" + }, + { + "_id": "5378cc15847ccc8123ad4dd3", + "imdb_id": "tt3551796", + "name": "American Odyssey", + "type": "series", + "year": "2015" + }, + { + "_id": "53677f26847ccc8123a1d742", + "imdb_id": "tt0043194", + "name": "Dragnet", + "type": "series", + "year": "1951–1959" + }, + { + "_id": "54ac200b8527d2e0cb504ad6", + "imdb_id": "tt3807022", + "name": "All Hail King Julien", + "type": "series", + "year": "2014–2017" + }, + { + "_id": "53677f1b847ccc8123a1b90e", + "imdb_id": "tt1443631", + "name": "Jungle Junction", + "type": "series", + "year": "2009–" + }, + { + "_id": "53677ef9847ccc8123a13843", + "imdb_id": "tt1637727", + "name": "The Killing", + "type": "series", + "year": "2011–2014" + }, + { + "_id": "53677efa847ccc8123a14a70", + "imdb_id": "tt0318883", + "name": "Everwood", + "type": "series", + "year": "2002–2006" + }, + { + "_id": "53677f54847ccc8123a21374", + "imdb_id": "tt0380113", + "name": "Charcoal Feather Federation", + "type": "series", + "year": "2002" + }, + { + "_id": "53677efc847ccc8123a14e77", + "imdb_id": "tt0874936", + "name": "Life", + "type": "series", + "year": "2007–2009" + }, + { + "_id": "536907ea847ccc8123acdd85", + "imdb_id": "tt0083412", + "name": "Fame", + "type": "series", + "year": "1982–1987" + }, + { + "_id": "53677ef9847ccc8123a137c6", + "imdb_id": "tt1442449", + "name": "Spartacus", + "type": "series", + "year": "2010–2013" + }, + { + "_id": "53677f0f847ccc8123a19a19", + "imdb_id": "tt0083413", + "name": "Family Ties", + "type": "series", + "year": "1982–1989" + }, + { + "_id": "53677efa847ccc8123a14829", + "imdb_id": "tt1299368", + "name": "Southland", + "type": "series", + "year": "2009–2013" + }, + { + "_id": "53677f68847ccc8123a22b14", + "imdb_id": "tt0398413", + "name": "#DUPE#", + "type": "series", + "year": "2002–" + }, + { + "_id": "53677f1c847ccc8123a1bc6f", + "imdb_id": "tt1118804", + "name": "Clannad", + "type": "series", + "year": "2007–2008" + }, + { + "_id": "53677ef9847ccc8123a1414d", + "imdb_id": "tt0290988", + "name": "Trailer Park Boys", + "type": "series", + "year": "2001–2018" + }, + { + "_id": "53677f79847ccc8123a23afc", + "imdb_id": "tt0055689", + "name": "McHale's Navy", + "type": "series", + "year": "1962–1966" + }, + { + "_id": "53677f0e847ccc8123a19583", + "imdb_id": "tt0050079", + "name": "Zorro", + "type": "series", + "year": "1957–1959" + }, + { + "_id": "53677f00847ccc8123a165d6", + "imdb_id": "tt0098762", + "name": "The Adventures of Super Mario Bros. 3", + "type": "series", + "year": "1990" + }, + { + "_id": "57dd11dad7e54929823e232a", + "imdb_id": "tt5028002", + "name": "StartUp", + "year": "2016–2018", + "type": "series" + }, + { + "_id": "53677f1b847ccc8123a1ba11", + "imdb_id": "tt2701582", + "name": "Endeavour", + "type": "series", + "year": "2012–2023" + }, + { + "_id": "55078808711bd19c92ade258", + "imdb_id": "tt0156220", + "name": "Macross 7", + "year": "1994–1995", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a1385e", + "imdb_id": "tt0460649", + "name": "How I Met Your Mother", + "type": "series", + "year": "2005–2014" + }, + { + "_id": "560cebeb6c6a1c0b815c9ba2", + "imdb_id": "tt4816364", + "name": "BattleBots", + "year": "2015–", + "type": "series" + }, + { + "_id": "53677f29847ccc8123a1ddd3", + "imdb_id": "tt2660806", + "name": "Mom", + "type": "series", + "year": "2013–2021" + }, + { + "_id": "5c0b13ae173739c9f4541d0e", + "imdb_id": "tt7908628", + "name": "What We Do in the Shadows", + "type": "series", + "year": "2019–2024" + }, + { + "_id": "561c7bc9ec193d5e9826ded0", + "imdb_id": "tt4094300", + "name": "Crazy Ex-Girlfriend", + "year": "2015–2019", + "type": "series" + }, + { + "_id": "53677f35847ccc8123a1e9c8", + "imdb_id": "tt0086734", + "name": "Hunter", + "type": "series", + "year": "1984–1991" + }, + { + "_id": "547b3ce4c174e3b3ed251dc9", + "imdb_id": "tt3517010", + "name": "Is the Order a Rabbit?", + "type": "series", + "year": "2014–" + }, + { + "_id": "536907f4847ccc8123acde18", + "imdb_id": "tt0061248", + "name": "Dragnet 1967", + "type": "series", + "year": "1967–1970" + }, + { + "_id": "53677f0f847ccc8123a198c1", + "imdb_id": "tt0053479", + "name": "The Andy Griffith Show", + "type": "series", + "year": "1960–1968" + }, + { + "_id": "5c0c755c173739c9f4d26b72", + "imdb_id": "tt0386993", + "name": "Xiaolin Showdown", + "type": "series", + "year": "2003–2006" + }, + { + "_id": "55089967711bd19c92ade521", + "imdb_id": "tt0115128", + "name": "The Spooktacular New Adventures of Casper", + "year": "1996–1998", + "type": "series" + }, + { + "_id": "53677f63847ccc8123a2289c", + "imdb_id": "tt0122834", + "name": "Samurai Pizza Cats", + "type": "series", + "year": "1990–1991" + }, + { + "_id": "53677f00847ccc8123a164d7", + "imdb_id": "tt0270761", + "name": "Candy Candy", + "type": "series", + "year": "1976–1979" + }, + { + "_id": "5c21ea7f173739c9f4b7290d", + "imdb_id": "tt3909210", + "name": "The Fruit of Grisaia", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "5c2cb6c4173739c9f4e80778", + "imdb_id": "tt6517320", + "name": "Too Old to Die Young", + "type": "series", + "year": "2019" + }, + { + "_id": "53677f03847ccc8123a172cc", + "imdb_id": "tt0108988", + "name": "Weird Science", + "type": "series", + "year": "1994–1998" + }, + { + "_id": "628bc9a464ec43ef98e11218", + "imdb_id": "tt10857160", + "name": "She-Hulk: Attorney at Law", + "type": "series", + "year": "2022" + }, + { + "_id": "53677efa847ccc8123a14a57", + "imdb_id": "tt0465315", + "name": "8 Out of 10 Cats", + "type": "series", + "year": "2005–" + }, + { + "_id": "59c857bb1712e0f4dd08f4fb", + "imdb_id": "tt5171438", + "type": "series", + "name": "Star Trek: Discovery", + "year": "2017–2024" + }, + { + "_id": "53677ef9847ccc8123a13a34", + "imdb_id": "tt0090390", + "name": "ALF", + "type": "series", + "year": "1986–2004" + }, + { + "_id": "5c303ed2173739c9f447152d", + "imdb_id": "tt0086742", + "name": "Kate & Allie", + "type": "series", + "year": "1984–1989" + }, + { + "_id": "53677eff847ccc8123a160bc", + "imdb_id": "tt0197182", + "name": "Third Watch", + "type": "series", + "year": "1999–2005" + }, + { + "_id": "625feb4f64ec43ef982215b6", + "imdb_id": "tt13706018", + "name": "Spy x Family", + "type": "series", + "year": "2022–" + }, + { + "_id": "5fe0c8965424253341943c68", + "imdb_id": "tt11328872", + "name": "In/Spectre", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "53677efd847ccc8123a156fd", + "imdb_id": "tt0862583", + "name": "How Do They Do It?", + "type": "series", + "year": "2006–" + }, + { + "_id": "53677ef9847ccc8123a13826", + "imdb_id": "tt0804503", + "name": "Mad Men", + "type": "series", + "year": "2007–2015" + }, + { + "_id": "5c37dc65d582b25756dd15ed", + "imdb_id": "tt6556992", + "name": "Hot Ones", + "type": "series", + "year": "2015–" + }, + { + "_id": "53677f1e847ccc8123a1c2ab", + "imdb_id": "tt0096542", + "name": "Baywatch", + "type": "series", + "year": "1989–2001" + }, + { + "_id": "5e60cfaac4ccb5dd921d100b", + "imdb_id": "tt8531222", + "name": "Dave", + "type": "series", + "year": "2020–" + }, + { + "_id": "53677efa847ccc8123a145fe", + "imdb_id": "tt0290223", + "name": "Inuyasha", + "type": "series", + "year": "2000–2004" + }, + { + "_id": "53677f6b847ccc8123a22ff7", + "imdb_id": "tt3502172", + "name": "Mozart in the Jungle", + "type": "series", + "year": "2014–2018" + }, + { + "_id": "53677f29847ccc8123a1dbaa", + "imdb_id": "tt0069576", + "name": "Doraemon", + "type": "series", + "year": "1979–2005" + }, + { + "_id": "5c0f5b0f173739c9f4ab8831", + "imdb_id": "tt0262973", + "name": "Elvira's Movie Macabre", + "type": "series", + "year": "1981–1993" + }, + { + "_id": "592fc3701635517fbf56e8c8", + "imdb_id": "tt5722298", + "name": "Private Eyes", + "type": "series", + "year": "2016–2021" + }, + { + "_id": "55c88b8cbf6c900d183db660", + "imdb_id": "tt0040053", + "type": "series", + "year": "1948–1971", + "name": "The Ed Sullivan Show" + }, + { + "_id": "53677f3d847ccc8123a1f2e1", + "imdb_id": "tt0810614", + "name": "ECW on Sci-Fi", + "type": "series", + "year": "2006–2010" + }, + { + "_id": "53677eff847ccc8123a16097", + "imdb_id": "tt0086765", + "name": "Murder, She Wrote", + "type": "series", + "year": "1984–1996" + }, + { + "_id": "619817e264ec43ef9862f14d", + "imdb_id": "tt13409432", + "name": "Ranking of Kings", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "53677ef9847ccc8123a13ae8", + "imdb_id": "tt1626038", + "name": "The Avengers: Earth's Mightiest Heroes", + "type": "series", + "year": "2010–2012" + }, + { + "_id": "57e329a6d7e54929823e793f", + "imdb_id": "tt5164196", + "type": "series", + "name": "Lethal Weapon", + "year": "2016–2019" + }, + { + "_id": "542fde99a8f27b1bb90d006e", + "imdb_id": "tt0247882", + "name": "Forensic Files", + "type": "series", + "year": "1996–2011" + }, + { + "_id": "551acfd2cc9eee85bb52df79", + "imdb_id": "tt0367413", + "name": "Sonic X", + "year": "2003–2006", + "type": "series" + }, + { + "_id": "53677efa847ccc8123a14793", + "imdb_id": "tt1225901", + "name": "90210", + "type": "series", + "year": "2008–2013" + }, + { + "_id": "53677f02847ccc8123a16c60", + "imdb_id": "tt0108783", + "name": "Gargoyles", + "type": "series", + "year": "1994–1997" + }, + { + "_id": "53677f25847ccc8123a1d5c4", + "imdb_id": "tt0061266", + "name": "Ironside", + "type": "series", + "year": "1967–1975" + }, + { + "_id": "548f0c978527d2e0cb4ff963", + "imdb_id": "tt0051308", + "name": "The Rifleman", + "type": "series", + "year": "1958–1963" + }, + { + "_id": "53677efa847ccc8123a14a9d", + "imdb_id": "tt0443370", + "name": "Dragons' Den", + "type": "series", + "year": "2005–" + }, + { + "_id": "53677f0f847ccc8123a19a44", + "imdb_id": "tt0130417", + "name": "The New Tom & Jerry Show", + "type": "series", + "year": "1975–1977" + }, + { + "_id": "5f87498354242533413d03d4", + "imdb_id": "tt12415504", + "name": "Kuma Kuma Kuma Bear", + "type": "series", + "year": "2020–" + }, + { + "_id": "58947b581635517fbf56cb90", + "imdb_id": "tt4422950", + "name": "I'm a Celebrity, Get Me Out of Here!", + "type": "series", + "year": "2015–" + }, + { + "_id": "53677f17847ccc8123a1ab30", + "imdb_id": "tt0115226", + "name": "The Real Adventures of Jonny Quest", + "type": "series", + "year": "1996–1997" + }, + { + "_id": "53677f02847ccc8123a16937", + "imdb_id": "tt0075472", + "name": "All Creatures Great and Small", + "type": "series", + "year": "1978–1990" + }, + { + "_id": "53677ef9847ccc8123a14325", + "imdb_id": "tt1676701", + "name": "Let's Stay Together", + "type": "series", + "year": "2011–2014" + }, + { + "_id": "53677ef9847ccc8123a1403e", + "imdb_id": "tt0835434", + "name": "In Treatment", + "type": "series", + "year": "2008–2021" + }, + { + "_id": "53677f1c847ccc8123a1bcb4", + "imdb_id": "tt1942683", + "name": "The Amazing World of Gumball", + "type": "series", + "year": "2011–2019" + }, + { + "_id": "53677f15847ccc8123a1a70a", + "imdb_id": "tt0108895", + "name": "The Pink Panther", + "type": "series", + "year": "1993–1996" + }, + { + "_id": "53677f29847ccc8123a1de5b", + "imdb_id": "tt3056472", + "name": "Total Divas", + "type": "series", + "year": "2013–2019" + }, + { + "_id": "53677f17847ccc8123a1ad0f", + "imdb_id": "tt2712612", + "name": "Drunk History", + "type": "series", + "year": "2013–2019" + }, + { + "_id": "53677f4d847ccc8123a20a0c", + "imdb_id": "tt0088618", + "name": "Street Hawk", + "type": "series", + "year": "1985" + }, + { + "_id": "53677f68847ccc8123a22bb0", + "imdb_id": "tt0068126", + "name": "The Rookies", + "type": "series", + "year": "1972–1976" + }, + { + "_id": "5446aeeca8f27b1bb90d5e87", + "imdb_id": "tt3816666", + "name": "Running Wild with Bear Grylls", + "type": "series", + "year": "2014–" + }, + { + "_id": "5aa3158253336c1ba83f914c", + "imdb_id": "tt7053188", + "name": "Station 19", + "year": "2018–2024", + "type": "series" + }, + { + "_id": "53677f0f847ccc8123a19c86", + "imdb_id": "tt0071054", + "name": "The Six Million Dollar Man", + "type": "series", + "year": "1974–1978" + }, + { + "_id": "5c0baaeb173739c9f43e44dc", + "imdb_id": "tt0106110", + "name": "Ready or Not", + "type": "series", + "year": "1993–1997" + }, + { + "_id": "53677f6a847ccc8123a22d9e", + "imdb_id": "tt3042608", + "name": "Uncle Grandpa", + "type": "series", + "year": "2010–2017" + }, + { + "_id": "53677efd847ccc8123a159eb", + "imdb_id": "tt0375355", + "name": "Joey", + "type": "series", + "year": "2004–2006" + }, + { + "_id": "53677f45847ccc8123a1fd71", + "imdb_id": "tt0127994", + "name": "Figure It Out", + "type": "series", + "year": "1997–2013" + }, + { + "_id": "53677ef9847ccc8123a1425d", + "imdb_id": "tt0244365", + "name": "Star Trek: Enterprise", + "type": "series", + "year": "2001–2005" + }, + { + "_id": "53677efd847ccc8123a15b5b", + "imdb_id": "tt0358856", + "name": "Little Britain", + "type": "series", + "year": "2003–2006" + }, + { + "_id": "53677f22847ccc8123a1cda3", + "imdb_id": "tt2432604", + "name": "Toast of London", + "type": "series", + "year": "2012–2020" + }, + { + "_id": "53677f72847ccc8123a23614", + "imdb_id": "tt2720144", + "name": "Peter Rabbit", + "type": "series", + "year": "2012–2016" + }, + { + "_id": "5ffb746b5424253341ef80c8", + "imdb_id": "tt13293588", + "name": "Mushoku Tensei: Jobless Reincarnation", + "type": "series", + "year": "2021–" + }, + { + "_id": "5c1adfd4173739c9f45bdd4f", + "imdb_id": "tt6881158", + "name": "Corner Gas Animated", + "type": "series", + "year": "2018–2021" + }, + { + "_id": "53677f04847ccc8123a1739f", + "imdb_id": "tt1528406", + "name": "Fairy Tail", + "type": "series", + "year": "2009–2019" + }, + { + "_id": "5a81a13b543165dcd85a3bfa", + "imdb_id": "tt0426666", + "type": "series", + "name": "Cold Case Files", + "year": "1999–" + }, + { + "_id": "53677ef5847ccc8123a1376e", + "imdb_id": "tt0324679", + "name": "Fifth Gear", + "type": "series", + "year": "2002–" + }, + { + "_id": "5985aa872abbe633c58e7aac", + "imdb_id": "tt6048596", + "name": "The Sinner", + "type": "series", + "year": "2017–2021" + }, + { + "_id": "57dd11d9d7e54929823e2321", + "imdb_id": "tt5137338", + "name": "Victoria", + "year": "2016–2019", + "type": "series" + }, + { + "_id": "536907eb847ccc8123acdda1", + "imdb_id": "tt0247120", + "name": "Night Visions", + "type": "series", + "year": "2001–2002" + }, + { + "_id": "56d1d2e6f6aa5b2a5344d0ba", + "imdb_id": "tt3986586", + "name": "Fuller House", + "year": "2016–2020", + "type": "series" + }, + { + "_id": "53d3d592a8f27b1bb90bae1c", + "imdb_id": "tt0292407", + "name": "The Glass House", + "type": "series", + "year": "2001–2006" + }, + { + "_id": "60cb12c964ec43ef9884d634", + "imdb_id": "tt13657062", + "name": "iCarly", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "5c0a27bc173739c9f48d8578", + "imdb_id": "tt8080054", + "name": "Patriot Act with Hasan Minhaj", + "type": "series", + "year": "2018–2020" + }, + { + "_id": "53677ef9847ccc8123a139a4", + "imdb_id": "tt1659175", + "name": "Transformers Prime", + "type": "series", + "year": "2010–2013" + }, + { + "_id": "5f93d89154242533412a84f7", + "imdb_id": "tt10048342", + "name": "The Queen's Gambit", + "type": "series", + "year": "2020" + }, + { + "_id": "53677f12847ccc8123a19cf1", + "imdb_id": "tt0057742", + "name": "Daniel Boone", + "type": "series", + "year": "1964–1970" + }, + { + "_id": "5a326b01543165dcd86b0a2c", + "imdb_id": "tt7235466", + "name": "9-1-1", + "year": "2018–", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a138d3", + "imdb_id": "tt1266020", + "name": "Parks and Recreation", + "type": "series", + "year": "2009–2015" + }, + { + "_id": "53677efd847ccc8123a15921", + "imdb_id": "tt0118421", + "name": "Oz", + "type": "series", + "year": "1997–2003" + }, + { + "_id": "54497386a8f27b1bb90d6c45", + "imdb_id": "tt0078714", + "name": "You Can't Do That on Television", + "type": "series", + "year": "1979–2004" + }, + { + "_id": "5c3946f8d582b257569655b7", + "imdb_id": "tt2090883", + "name": "Hubert ohne Staller", + "type": "series", + "year": "2011–" + }, + { + "_id": "53677f0a847ccc8123a18be1", + "imdb_id": "tt0118266", + "name": "The New Batman Adventures", + "type": "series", + "year": "1997–1999" + }, + { + "_id": "5c3a4d9dd582b257561da6d8", + "imdb_id": "tt0431577", + "name": "Tout le monde en parle", + "type": "series", + "year": "2004–" + }, + { + "_id": "53677f00847ccc8123a1651e", + "imdb_id": "tt0168366", + "name": "Pokémon", + "type": "series", + "year": "1997–2023" + }, + { + "_id": "53677ef9847ccc8123a13f7d", + "imdb_id": "tt1586676", + "name": "Fairly Legal", + "type": "series", + "year": "2011–2012" + }, + { + "_id": "5c2285fd173739c9f4f4381c", + "imdb_id": "tt1352421", + "name": "Natsume's Book of Friends", + "type": "series", + "year": "2008–2017" + }, + { + "_id": "658ea7fabd36726cbb85ccd2", + "imdb_id": "tt16288804", + "name": "Berlin", + "type": "series", + "year": "2023–" + }, + { + "_id": "54ff1ce4711bd19c92adce91", + "imdb_id": "tt0972713", + "name": "Shakugan No Shana", + "year": "2005–2010", + "type": "series" + }, + { + "_id": "541fe588a8f27b1bb90cc39f", + "imdb_id": "tt3501074", + "name": "Madam Secretary", + "type": "series", + "year": "2014–2019" + }, + { + "_id": "53677f22847ccc8123a1cd03", + "imdb_id": "tt0426719", + "name": "Hunter x Hunter", + "type": "series", + "year": "1999–2001" + }, + { + "_id": "5c1043cb173739c9f45e6e66", + "imdb_id": "tt6994156", + "name": "Close Enough", + "type": "series", + "year": "2020–2022" + }, + { + "_id": "5a4f6c18543165dcd83348a1", + "imdb_id": "tt5180504", + "name": "The Witcher", + "year": "2019–", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a137d2", + "imdb_id": "tt1826940", + "name": "New Girl", + "type": "series", + "year": "2011–2018" + }, + { + "_id": "6125145c64ec43ef98e7fb16", + "imdb_id": "tt11093718", + "name": "Establishment: Osman", + "type": "series", + "year": "2019–" + }, + { + "_id": "61c5bf0c64ec43ef98f594ac", + "imdb_id": "tt15758116", + "name": "Dragons: The Nine Realms", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "615f67c064ec43ef98df4488", + "imdb_id": "tt13676300", + "name": "Platinum End", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "543150fda8f27b1bb90d0602", + "imdb_id": "tt3663490", + "name": "The Librarians", + "type": "series", + "year": "2014–2018" + }, + { + "_id": "53677ef9847ccc8123a13c63", + "imdb_id": "tt1492179", + "name": "Strike Back", + "type": "series", + "year": "2010–2020" + }, + { + "_id": "53677f04847ccc8123a173ff", + "imdb_id": "tt0055710", + "name": "The Virginian", + "type": "series", + "year": "1962–1971" + }, + { + "_id": "53677ef9847ccc8123a13bbc", + "imdb_id": "tt2222135", + "name": "Dog with a Blog", + "type": "series", + "year": "2012–2015" + }, + { + "_id": "53677efc847ccc8123a15191", + "imdb_id": "tt0085033", + "name": "Inspector Gadget", + "type": "series", + "year": "1983–2023" + }, + { + "_id": "53677f0c847ccc8123a192b7", + "imdb_id": "tt0108967", + "name": "A Touch of Frost", + "type": "series", + "year": "1992–2010" + }, + { + "_id": "53677f0a847ccc8123a189f3", + "imdb_id": "tt0053502", + "name": "The Flintstones", + "type": "series", + "year": "1960–1966" + }, + { + "_id": "53677f07847ccc8123a18081", + "imdb_id": "tt0051327", + "name": "Wanted: Dead or Alive", + "type": "series", + "year": "1958–1961" + }, + { + "_id": "53677f3a847ccc8123a1ee2e", + "imdb_id": "tt2341339", + "name": "Randy Cunningham: 9th Grade Ninja", + "type": "series", + "year": "2012–2015" + }, + { + "_id": "53677f07847ccc8123a180e6", + "imdb_id": "tt0364151", + "name": "American Masters", + "type": "series", + "year": "1985–" + }, + { + "_id": "63d265fb64ec43ef980bd6f5", + "imdb_id": "tt14269590", + "name": "Poker Face", + "type": "series", + "year": "2023–" + }, + { + "_id": "54fa1bb4711bd19c92accf0f", + "imdb_id": "tt1280627", + "name": "The Rachel Maddow Show", + "year": "2008–", + "type": "series" + }, + { + "_id": "5f852e5e54242533413e8c24", + "imdb_id": "tt12402550", + "name": "Sleepy Princess in the Demon Castle", + "type": "series", + "year": "2020" + }, + { + "_id": "53677f29847ccc8123a1db82", + "imdb_id": "tt0101206", + "name": "Golden Years", + "type": "series", + "year": "1991" + }, + { + "_id": "549483b28527d2e0cb500b3d", + "imdb_id": "tt0220265", + "name": "Iron Chef", + "type": "series", + "year": "1993–2002" + }, + { + "_id": "53677f61847ccc8123a224b1", + "imdb_id": "tt0053540", + "name": "Surfside 6", + "type": "series", + "year": "1960–1962" + }, + { + "_id": "5c50bfabd582b25756382700", + "imdb_id": "tt0096534", + "name": "Anything But Love", + "type": "series", + "year": "1989–1992" + }, + { + "_id": "53677f3a847ccc8123a1f0c2", + "imdb_id": "tt0284718", + "name": "Crossing Jordan", + "type": "series", + "year": "2001–2007" + }, + { + "_id": "536907eb847ccc8123acdd97", + "imdb_id": "tt1694038", + "name": "Seitokai yakuindomo", + "type": "series", + "year": "2010–2020" + }, + { + "_id": "5c2a64fa173739c9f4d0b6b0", + "imdb_id": "tt7126178", + "name": "HeartCatch PreCure!", + "type": "series", + "year": "2010–2011" + }, + { + "_id": "6234c99064ec43ef984ab9c0", + "imdb_id": "tt11447470", + "name": "Welcome to Flatch", + "type": "series", + "year": "2022–2023" + }, + { + "_id": "53677f25847ccc8123a1d643", + "imdb_id": "tt0045406", + "name": "The Life of Riley", + "type": "series", + "year": "1953–1958" + }, + { + "_id": "54e70d47417d39942847ac8f", + "imdb_id": "tt1899047", + "name": "Toriko", + "type": "series", + "year": "2009–2014" + }, + { + "_id": "6580409fbd36726cbbdd614e", + "imdb_id": "tt26225038", + "name": "Death's Game", + "type": "series", + "year": "2023–" + }, + { + "_id": "5c312930173739c9f40318f4", + "imdb_id": "tt4716268", + "name": "Beat Bugs", + "type": "series", + "year": "2016–2018" + }, + { + "_id": "550787c9711bd19c92ade1b4", + "imdb_id": "tt0047756", + "name": "Matinee Theatre", + "year": "1955–1958", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a14153", + "imdb_id": "tt1800864", + "name": "Gold Rush", + "type": "series", + "year": "2010–" + }, + { + "_id": "53677efc847ccc8123a14dd2", + "imdb_id": "tt0063878", + "name": "The Brady Bunch", + "type": "series", + "year": "1969–1974" + }, + { + "_id": "5c17d24d173739c9f4c29154", + "imdb_id": "tt7316998", + "name": "Richard Osman's House of Games", + "type": "series", + "year": "2017–" + }, + { + "_id": "53677f1f847ccc8123a1c4e6", + "imdb_id": "tt2216577", + "name": "Fred: The Show", + "type": "series", + "year": "2012–2023" + }, + { + "_id": "53677f0f847ccc8123a19a76", + "imdb_id": "tt0072472", + "name": "Barney Miller", + "type": "series", + "year": "1975–1982" + }, + { + "_id": "53677f23847ccc8123a1d03a", + "imdb_id": "tt2427220", + "name": "Crossing Lines", + "type": "series", + "year": "2013–2015" + }, + { + "_id": "5505f59b711bd19c92add68b", + "imdb_id": "tt2426288", + "name": "Q&A", + "year": "2008–", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a142fd", + "imdb_id": "tt1001558", + "name": "Raising the Bar", + "type": "series", + "year": "2008–2009" + }, + { + "_id": "53677f4a847ccc8123a20544", + "imdb_id": "tt1410218", + "name": "K-On!", + "type": "series", + "year": "2009–2010" + }, + { + "_id": "53677ef9847ccc8123a14006", + "imdb_id": "tt0373732", + "name": "The Boondocks", + "type": "series", + "year": "2005–2014" + }, + { + "_id": "5c13fe4c173739c9f416c280", + "imdb_id": "tt0409548", + "name": "Devilman Lady", + "type": "series", + "year": "1998–1999" + }, + { + "_id": "53677eff847ccc8123a16130", + "imdb_id": "tt0083395", + "name": "Cagney & Lacey", + "type": "series", + "year": "1981–1988" + }, + { + "_id": "53677f6b847ccc8123a22f84", + "imdb_id": "tt3426342", + "name": "Jodha Akbar", + "type": "series", + "year": "2013–2015" + }, + { + "_id": "53677f51847ccc8123a20eb7", + "imdb_id": "tt0168334", + "name": "Furandâsu no inu", + "type": "series", + "year": "1975" + }, + { + "_id": "53677f2e847ccc8123a1e37b", + "imdb_id": "tt2266639", + "name": "1600 Penn", + "type": "series", + "year": "2012–2013" + }, + { + "_id": "5c433281d582b25756e19943", + "imdb_id": "tt0972735", + "name": "SoltyRei", + "type": "series", + "year": "2005–2006" + }, + { + "_id": "53677f17847ccc8123a1ae2c", + "imdb_id": "tt1131751", + "name": "True Jackson, VP", + "type": "series", + "year": "2008–2011" + }, + { + "_id": "53677efa847ccc8123a14887", + "imdb_id": "tt0144700", + "name": "101 Dalmatians: The Series", + "type": "series", + "year": "1997–1998" + }, + { + "_id": "55086ee4711bd19c92ade4aa", + "imdb_id": "tt0108937", + "name": "Space Ghost Coast to Coast", + "year": "1993–2012", + "type": "series" + }, + { + "_id": "5c104569173739c9f461c385", + "imdb_id": "tt0190106", + "name": "Undressed", + "type": "series", + "year": "1999–2002" + }, + { + "_id": "5c5abdfed582b257565b9447", + "imdb_id": "tt2230531", + "name": "Senki Zessho Symphogear", + "type": "series", + "year": "2012" + }, + { + "_id": "53677f1b847ccc8123a1b757", + "imdb_id": "tt0284713", + "name": "The Care Bears", + "type": "series", + "year": "1986–1988" + }, + { + "_id": "53677eff847ccc8123a15fe9", + "imdb_id": "tt0877057", + "name": "Death Note", + "type": "series", + "year": "2006–2007" + }, + { + "_id": "5c0ab0a4173739c9f48b55d7", + "imdb_id": "tt1196094", + "name": "Yu-Gi-Oh! 5D's", + "type": "series", + "year": "2008–2011" + }, + { + "_id": "53677f04847ccc8123a174f9", + "imdb_id": "tt1761811", + "name": "Pound Puppies", + "type": "series", + "year": "2010–2013" + }, + { + "_id": "644676b264ec43ef98771ee0", + "imdb_id": "tt13064902", + "name": "FUBAR", + "type": "series", + "year": "2023–" + }, + { + "_id": "5a4115b9543165dcd8f19ee7", + "imdb_id": "tt7326322", + "type": "series", + "name": "The Ancient Magus' Bride", + "year": "2017–" + }, + { + "_id": "5c2b35d2173739c9f430a5e4", + "imdb_id": "tt1687093", + "name": "The Story of Saiunkoku", + "type": "series", + "year": "2006–2008" + }, + { + "_id": "53677f2c847ccc8123a1df58", + "imdb_id": "tt3402548", + "name": "Comedy Nights with Kapil", + "type": "series", + "year": "2013–2016" + }, + { + "_id": "53677f21847ccc8123a1cb88", + "imdb_id": "tt0046600", + "name": "Father Knows Best", + "type": "series", + "year": "1954–1960" + }, + { + "_id": "53677ef9847ccc8123a13bbf", + "imdb_id": "tt0098924", + "name": "TaleSpin", + "type": "series", + "year": "1990–1991" + }, + { + "_id": "53677efc847ccc8123a15374", + "imdb_id": "tt0976192", + "name": "The Spectacular Spider-Man", + "type": "series", + "year": "2008–2009" + }, + { + "_id": "5c0edd5c173739c9f4e52df5", + "imdb_id": "tt7263328", + "name": "Classroom of the Elite", + "type": "series", + "year": "2017–" + }, + { + "_id": "5c0ce757173739c9f46bf06c", + "imdb_id": "tt0115221", + "name": "The Jamie Foxx Show", + "type": "series", + "year": "1996–2023" + }, + { + "_id": "53677ef9847ccc8123a13bf8", + "imdb_id": "tt1728102", + "name": "Alcatraz", + "type": "series", + "year": "2012" + }, + { + "_id": "53677f0c847ccc8123a194f7", + "imdb_id": "tt0495247", + "name": "The Apprentice: You're Fired!", + "type": "series", + "year": "2006–" + }, + { + "_id": "53677efd847ccc8123a1588f", + "imdb_id": "tt0429318", + "name": "The Biggest Loser", + "type": "series", + "year": "2004–" + }, + { + "_id": "5be4dc7a173739c9f4f56b70", + "imdb_id": "tt4687882", + "name": "Patriot", + "type": "series", + "year": "2015–2018" + }, + { + "_id": "5c1bf01a173739c9f433ac07", + "imdb_id": "tt0314975", + "name": "The Adventures of Paddington Bear", + "type": "series", + "year": "1997–2000" + }, + { + "_id": "5b337fc416f4806c2a072e72", + "imdb_id": "tt7784442", + "type": "series", + "name": "Captain Tsubasa", + "year": "2018–2023" + }, + { + "_id": "5ab881b853336c1ba820e30d", + "imdb_id": "tt2708480", + "type": "series", + "name": "The Terror", + "year": "2018–2019" + }, + { + "_id": "5c100ed0173739c9f4f0c9cd", + "imdb_id": "tt3950084", + "name": "Amagi Brilliant Park", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "53677f07847ccc8123a180c0", + "imdb_id": "tt0103359", + "name": "Batman: The Animated Series", + "type": "series", + "year": "1992–1995" + }, + { + "_id": "55be4c99bf6c900d183c3ad0", + "imdb_id": "tt4591680", + "name": "Bunk'd", + "year": "2015–2024", + "type": "series" + }, + { + "_id": "5c3beecad582b25756039b80", + "imdb_id": "tt0807675", + "name": "Girls Bravo", + "type": "series", + "year": "2004–2005" + }, + { + "_id": "53677f22847ccc8123a1cc16", + "imdb_id": "tt0094481", + "name": "Home and Away", + "type": "series", + "year": "1988–" + }, + { + "_id": "5c537788d582b25756efb21a", + "imdb_id": "tt9170108", + "name": "Raised by Wolves", + "type": "series", + "year": "2020–2022" + }, + { + "_id": "5c4deee3d582b25756a1edee", + "imdb_id": "tt0479783", + "name": "Yakitate!! Japan", + "type": "series", + "year": "2004–2006" + }, + { + "_id": "6333978164ec43ef98a80ebe", + "imdb_id": "tt18076310", + "name": "The Rookie: Feds", + "type": "series", + "year": "2022–2023" + }, + { + "_id": "53677f3d847ccc8123a1f388", + "imdb_id": "tt0047763", + "name": "The Phil Silvers Show", + "type": "series", + "year": "1955–1959" + }, + { + "_id": "555cc303bf6c900d1833dfc1", + "imdb_id": "tt0096565", + "name": "The Detectives", + "year": "1993–1997", + "type": "series" + }, + { + "_id": "64aad14abd36726cbba1cd50", + "imdb_id": "tt25811262", + "name": "Zom 100: Bucket List of the Dead", + "type": "series", + "year": "2023" + }, + { + "_id": "609d062c64ec43ef981a8089", + "imdb_id": "tt11815682", + "name": "Hacks", + "type": "series", + "year": "2021–" + }, + { + "_id": "63a2cad264ec43ef98787eb1", + "imdb_id": "tt13961348", + "name": "Sonic Prime", + "type": "series", + "year": "2022–" + }, + { + "_id": "5a58a6bb543165dcd82a0d37", + "imdb_id": "tt6045840", + "name": "Black Lightning", + "year": "2017–2021", + "type": "series" + }, + { + "_id": "5f1b43975424253341d90325", + "imdb_id": "tt12464182", + "name": "Uzaki-chan Wants to Hang Out!", + "type": "series", + "year": "2020–2022" + }, + { + "_id": "60b9ffd564ec43ef9820cda3", + "imdb_id": "tt12809988", + "name": "Sweet Tooth", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677ef9847ccc8123a14273", + "imdb_id": "tt0839188", + "name": "Metalocalypse", + "type": "series", + "year": "2006–2013" + }, + { + "_id": "53677ef9847ccc8123a13f53", + "imdb_id": "tt0112167", + "name": "Sliders", + "type": "series", + "year": "1995–2000" + }, + { + "_id": "5a0b081b543165dcd8bfe57f", + "imdb_id": "tt4975856", + "type": "series", + "name": "Future Man", + "year": "2017–2020" + }, + { + "_id": "53677f07847ccc8123a18176", + "imdb_id": "tt0948103", + "name": "Gurren Lagann", + "type": "series", + "year": "2007" + }, + { + "_id": "5dd613d7c4ccb5dd927b90e4", + "imdb_id": "tt10937602", + "name": "Ahiru no Sora", + "type": "series", + "year": "2019–" + }, + { + "_id": "53677ef9847ccc8123a13e71", + "imdb_id": "tt0472954", + "name": "It's Always Sunny in Philadelphia", + "type": "series", + "year": "2005–" + }, + { + "_id": "53677f05847ccc8123a17ac0", + "imdb_id": "tt2049116", + "name": "Gomorrah", + "type": "series", + "year": "2014–2021" + }, + { + "_id": "53677ef9847ccc8123a13e28", + "imdb_id": "tt0418372", + "name": "The Block", + "type": "series", + "year": "2003–" + }, + { + "_id": "5505f5fb711bd19c92add6bd", + "imdb_id": "tt3874528", + "name": "The Irregular at Magic High School", + "year": "2014–", + "type": "series" + }, + { + "_id": "550bfc09cc9eee85bb52d83e", + "imdb_id": "tt0181260", + "name": "This Is Your Life", + "year": "1955–2003", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13f76", + "imdb_id": "tt0081933", + "name": "The Smurfs", + "type": "series", + "year": "1981–1989" + }, + { + "_id": "555a43a3bf6c900d1833cddc", + "imdb_id": "tt4450826", + "name": "Minority Report", + "year": "2015", + "type": "series" + }, + { + "_id": "53677f07847ccc8123a18091", + "imdb_id": "tt0268094", + "name": "Special Unit 2", + "type": "series", + "year": "2001–2002" + }, + { + "_id": "53677ef9847ccc8123a13c2c", + "imdb_id": "tt0759475", + "name": "'Til Death", + "type": "series", + "year": "2006–2010" + }, + { + "_id": "53677f1c847ccc8123a1bbbd", + "imdb_id": "tt0315081", + "name": "Tripping the Rift", + "type": "series", + "year": "2004–2007" + }, + { + "_id": "5c35ea0c173739c9f4291de5", + "imdb_id": "tt8228732", + "name": "Kakuriyo: Bed & Breakfast for Spirits", + "type": "series", + "year": "2018" + }, + { + "_id": "53677f48847ccc8123a20326", + "imdb_id": "tt0058808", + "name": "Green Acres", + "type": "series", + "year": "1965–1971" + }, + { + "_id": "5bb2cae9173739c9f41e6044", + "imdb_id": "tt7942794", + "name": "The Neighborhood", + "type": "series", + "year": "2018–" + }, + { + "_id": "53677f0c847ccc8123a191e3", + "imdb_id": "tt0096688", + "name": "Rescue 911", + "type": "series", + "year": "1989–1996" + }, + { + "_id": "53677efa847ccc8123a1481e", + "imdb_id": "tt0238784", + "name": "Gilmore Girls", + "type": "series", + "year": "2000–2007" + }, + { + "_id": "53677f08847ccc8123a183f8", + "imdb_id": "tt1334722", + "name": "Baccano!", + "type": "series", + "year": "2007–2008" + }, + { + "_id": "65a023c8bd36726cbbd3e4d3", + "imdb_id": "tt16156736", + "name": "Mato Seihei no Slave", + "type": "series", + "year": "2024–" + }, + { + "_id": "53677f24847ccc8123a1d1a9", + "imdb_id": "tt2191148", + "name": "Blue", + "type": "series", + "year": "2012–2014" + }, + { + "_id": "53677ef9847ccc8123a13bc1", + "imdb_id": "tt0461622", + "name": "Criss Angel Mindfreak", + "type": "series", + "year": "2005–2010" + }, + { + "_id": "5c5caefdd582b25756107e46", + "imdb_id": "tt0101153", + "name": "The New WKRP in Cincinnati", + "type": "series", + "year": "1991–1993" + }, + { + "_id": "53677efc847ccc8123a14fb5", + "imdb_id": "tt1660055", + "name": "Scooby-Doo! Mystery Incorporated", + "type": "series", + "year": "2010–2013" + }, + { + "_id": "53677f2e847ccc8123a1e342", + "imdb_id": "tt2731624", + "name": "Plebs", + "type": "series", + "year": "2013–2019" + }, + { + "_id": "53677efc847ccc8123a14d5f", + "imdb_id": "tt0086814", + "name": "Tales from the Darkside", + "type": "series", + "year": "1983–1988" + }, + { + "_id": "5c40e7e8d582b25756a88cd9", + "imdb_id": "tt2632044", + "name": "Gargantia on the Verdurous Planet", + "type": "series", + "year": "2013–" + }, + { + "_id": "53677f05847ccc8123a176ad", + "imdb_id": "tt2085059", + "name": "Black Mirror", + "type": "series", + "year": "2011–" + }, + { + "_id": "5c15b54a173739c9f4437370", + "imdb_id": "tt5955168", + "name": "Classic Albums", + "type": "series", + "year": "1997–" + }, + { + "_id": "55199632cc9eee85bb52de16", + "imdb_id": "tt0257294", + "name": "Betterman", + "year": "1999", + "type": "series" + }, + { + "_id": "5fafb20e5424253341adf1fe", + "imdb_id": "tt0115243", + "name": "Lexx", + "type": "series", + "year": "1996–2002" + }, + { + "_id": "53677f02847ccc8123a16b7a", + "imdb_id": "tt0178149", + "name": "#DUPE#", + "type": "series", + "year": "1996–2002" + }, + { + "_id": "53677f66847ccc8123a22aa5", + "imdb_id": "tt0237987", + "name": "The Weekenders", + "type": "series", + "year": "2000–2004" + }, + { + "_id": "53677ef9847ccc8123a13871", + "imdb_id": "tt0411008", + "name": "Lost", + "type": "series", + "year": "2004–2010" + }, + { + "_id": "56c06e89f6b914c6c681ca36", + "imdb_id": "tt3186130", + "name": "Vinyl", + "year": "2016", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13eac", + "imdb_id": "tt0090466", + "name": "L.A. Law", + "type": "series", + "year": "1986–1994" + }, + { + "_id": "54fb5f64711bd19c92ad4578", + "imdb_id": "tt1424037", + "name": "Kenichi: The Mightiest Disciple", + "year": "2006–2014", + "type": "series" + }, + { + "_id": "5c58b672d582b25756c21eea", + "imdb_id": "tt8879940", + "name": "Mythic Quest", + "type": "series", + "year": "2020–" + }, + { + "_id": "5c0ab2f2173739c9f48fd1d3", + "imdb_id": "tt1674928", + "name": "Beyblade: Metal Fusion", + "type": "series", + "year": "2009–2013" + }, + { + "_id": "53677eff847ccc8123a15e11", + "imdb_id": "tt2980110", + "name": "First Dates", + "type": "series", + "year": "2013–" + }, + { + "_id": "53677f52847ccc8123a20f7d", + "imdb_id": "tt0284722", + "name": "Reba", + "type": "series", + "year": "2001–2007" + }, + { + "_id": "53677f0f847ccc8123a19699", + "imdb_id": "tt0281432", + "name": "The Dead Zone", + "type": "series", + "year": "2002–2007" + }, + { + "_id": "53677ef9847ccc8123a138cb", + "imdb_id": "tt0285370", + "name": "The Guardian", + "type": "series", + "year": "2001–2004" + }, + { + "_id": "6036fbf054242533416c6c31", + "imdb_id": "tt10813940", + "name": "Ginny & Georgia", + "type": "series", + "year": "2021–" + }, + { + "_id": "6162eea564ec43ef9818cb04", + "imdb_id": "tt15192340", + "name": "Senpai ga Uzai Kouhai no Hanashi", + "type": "series", + "year": "2021" + }, + { + "_id": "53677f1d847ccc8123a1bd56", + "imdb_id": "tt0081859", + "name": "The Fall Guy", + "type": "series", + "year": "1981–1986" + }, + { + "_id": "53677efd847ccc8123a15600", + "imdb_id": "tt1091909", + "name": "Murdoch Mysteries", + "type": "series", + "year": "2008–" + }, + { + "_id": "5985aa872abbe633c58e7aad", + "imdb_id": "tt6467294", + "name": "Somewhere Between", + "type": "series", + "year": "2017" + }, + { + "_id": "53677ef9847ccc8123a13937", + "imdb_id": "tt0813715", + "name": "Heroes", + "type": "series", + "year": "2006–2010" + }, + { + "_id": "53677ef9847ccc8123a1378f", + "imdb_id": "tt1604113", + "name": "Friends with Benefits", + "type": "series", + "year": "2011" + }, + { + "_id": "53677f29847ccc8123a1dede", + "imdb_id": "tt2545498", + "name": "Instant Mom", + "type": "series", + "year": "2013–2015" + }, + { + "_id": "53677f07847ccc8123a17e0a", + "imdb_id": "tt0074035", + "name": "The Onedin Line", + "type": "series", + "year": "1971–1980" + }, + { + "_id": "53677f0c847ccc8123a194d8", + "imdb_id": "tt0047758", + "name": "The Millionaire", + "type": "series", + "year": "1955–1960" + }, + { + "_id": "562d6b864da0a59d21473eea", + "imdb_id": "tt0112115", + "name": "The Parent 'Hood", + "year": "1995–1999", + "type": "series" + }, + { + "_id": "65422153bd36726cbb70d403", + "imdb_id": "tt0484918", + "name": "Ulice", + "type": "series", + "year": "2005–" + }, + { + "_id": "53677efd847ccc8123a15589", + "imdb_id": "tt0259733", + "name": "Waking the Dead", + "type": "series", + "year": "2000–2011" + }, + { + "_id": "546391d3b5100012646bf5d4", + "imdb_id": "tt3904078", + "name": "100 Things to Do Before High School", + "type": "series", + "year": "2014–2016" + }, + { + "_id": "53677ef9847ccc8123a1411b", + "imdb_id": "tt0387764", + "name": "Peep Show", + "type": "series", + "year": "2003–2015" + }, + { + "_id": "5801b75fd7e54929824034c3", + "imdb_id": "tt4687880", + "type": "series", + "name": "Goliath", + "year": "2016–2021" + }, + { + "_id": "60a3be6464ec43ef9877af9d", + "imdb_id": "tt14403784", + "name": "Biography: WWE Legends", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "53677efa847ccc8123a1465f", + "imdb_id": "tt0925266", + "name": "Pushing Daisies", + "type": "series", + "year": "2007–2009" + }, + { + "_id": "5c578c82d582b257565b780b", + "imdb_id": "tt0090407", + "name": "Supernova Flashman", + "type": "series", + "year": "1986–1987" + }, + { + "_id": "5c195a66173739c9f4731dea", + "imdb_id": "tt8788458", + "name": "The Promised Neverland", + "type": "series", + "year": "2019–2021" + }, + { + "_id": "53677f3c847ccc8123a1f1a8", + "imdb_id": "tt0129692", + "name": "Liberty! The American Revolution", + "type": "series", + "year": "1997–" + }, + { + "_id": "5c4cdf22d582b25756522f21", + "imdb_id": "tt0122811", + "name": "The Adventures of Teddy Ruxpin", + "type": "series", + "year": "1987–1988" + }, + { + "_id": "5c094a2c173739c9f40e7bd8", + "imdb_id": "tt8747928", + "name": "SSSS.Gridman", + "type": "series", + "year": "2018" + }, + { + "_id": "64cfc2e6bd36726cbb47fe0f", + "imdb_id": "tt18271440", + "name": "Bill Russell: Legend", + "type": "series", + "year": "2023" + }, + { + "_id": "539c4866a8f27b1bb90afef3", + "imdb_id": "tt1870073", + "name": "Justin Time", + "type": "series", + "year": "2011–2017" + }, + { + "_id": "57e3cb67d7e54929823e7da3", + "imdb_id": "tt0207275", + "name": "The 10th Kingdom", + "year": "2000", + "type": "series" + }, + { + "_id": "5c13d468173739c9f4c3e867", + "imdb_id": "tt7632608", + "name": "Enemigo Íntimo", + "type": "series", + "year": "2018–" + }, + { + "_id": "54b28a0d8527d2e0cb506234", + "imdb_id": "tt3910690", + "name": "Inspector Gadget", + "type": "series", + "year": "2015–2018" + }, + { + "_id": "53677f23847ccc8123a1cfa9", + "imdb_id": "tt0096597", + "name": "Goede tijden, slechte tijden", + "type": "series", + "year": "1990–" + }, + { + "_id": "5b8e9330173739c9f47d67c3", + "imdb_id": "tt5363918", + "name": "Disenchantment", + "type": "series", + "year": "2018–2023" + }, + { + "_id": "53677f7c847ccc8123a23e19", + "imdb_id": "tt3592718", + "name": "Signed, Sealed, Delivered", + "type": "series", + "year": "2013–2014" + }, + { + "_id": "53677efa847ccc8123a14c94", + "imdb_id": "tt0210418", + "name": "Digimon: Digital Monsters", + "type": "series", + "year": "1999–2007" + }, + { + "_id": "53677ef9847ccc8123a1434f", + "imdb_id": "tt0098800", + "name": "The Fresh Prince of Bel-Air", + "type": "series", + "year": "1990–1996" + }, + { + "_id": "53677f05847ccc8123a17ae1", + "imdb_id": "tt0086827", + "name": "Who's the Boss?", + "type": "series", + "year": "1984–1992" + }, + { + "_id": "539c4866a8f27b1bb90afed7", + "imdb_id": "tt2402061", + "name": "Murder in the First", + "type": "series", + "year": "2014–2016" + }, + { + "_id": "561a16cfec193d5e9826b3aa", + "imdb_id": "tt4179452", + "name": "The Last Kingdom", + "year": "2015–2022", + "type": "series" + }, + { + "_id": "603439315424253341dd9e08", + "imdb_id": "tt11192306", + "name": "Superman & Lois", + "type": "series", + "year": "2021–2024" + }, + { + "_id": "53677efc847ccc8123a151b7", + "imdb_id": "tt0154061", + "name": "CatDog", + "type": "series", + "year": "1998–2005" + }, + { + "_id": "53677f08847ccc8123a1843c", + "imdb_id": "tt0058812", + "name": "Hogan's Heroes", + "type": "series", + "year": "1965–1971" + }, + { + "_id": "537500ca847ccc8123ad0af1", + "imdb_id": "tt0165598", + "name": "That '70s Show", + "type": "series", + "year": "1998–2006" + }, + { + "_id": "53677f4f847ccc8123a20d6b", + "imdb_id": "tt0068138", + "name": "The New Temperatures Rising Show", + "type": "series", + "year": "1972–1974" + }, + { + "_id": "5c09a0c8173739c9f4ba7fa2", + "imdb_id": "tt8433216", + "name": "Super Dragon Ball Heroes", + "type": "series", + "year": "2018–" + }, + { + "_id": "5c0d59e4173739c9f44ea620", + "imdb_id": "tt0083475", + "name": "Scooby-Doo and Scrappy-Doo", + "type": "series", + "year": "1979–1983" + }, + { + "_id": "53677ef9847ccc8123a141aa", + "imdb_id": "tt1593823", + "name": "The Cape", + "type": "series", + "year": "2011" + }, + { + "_id": "5c5638e0d582b257569d3ee3", + "imdb_id": "tt0094446", + "name": "Day by Day", + "type": "series", + "year": "1988–1989" + }, + { + "_id": "60f3b83064ec43ef985e1d32", + "imdb_id": "tt11761176", + "name": "Power Book III: Raising Kanan", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677efa847ccc8123a14bc4", + "imdb_id": "tt1553656", + "name": "Under the Dome", + "type": "series", + "year": "2013–2015" + }, + { + "_id": "53677f23847ccc8123a1d08a", + "imdb_id": "tt0283724", + "name": "Doc", + "type": "series", + "year": "2001–2004" + }, + { + "_id": "53677f0c847ccc8123a1909f", + "imdb_id": "tt0080297", + "name": "Tinker Tailor Soldier Spy", + "type": "series", + "year": "1979" + }, + { + "_id": "5c0fb216173739c9f43d470f", + "imdb_id": "tt0185066", + "name": "Galaxy Express 999", + "type": "series", + "year": "1978–1981" + }, + { + "_id": "5c311006173739c9f4cc7026", + "imdb_id": "tt4847134", + "name": "Mighty Magiswords", + "type": "series", + "year": "2015–2018" + }, + { + "_id": "5381e72b847ccc8123ad762a", + "imdb_id": "tt2769458", + "name": "Sheriff Callie's Wild West", + "type": "series", + "year": "2013–2017" + }, + { + "_id": "53677f79847ccc8123a23c19", + "imdb_id": "tt2374744", + "name": "The Next Step", + "type": "series", + "year": "2013–" + }, + { + "_id": "5db1f0e6c4ccb5dd92b1b9cf", + "imdb_id": "tt10973152", + "name": "Assassins Pride", + "type": "series", + "year": "2019" + }, + { + "_id": "53677ef9847ccc8123a13862", + "imdb_id": "tt1837654", + "name": "The Secret Circle", + "type": "series", + "year": "2011–2012" + }, + { + "_id": "6262980e64ec43ef98ea0c77", + "imdb_id": "tt15978212", + "name": "Ya Boy Kongming!", + "type": "series", + "year": "2022" + }, + { + "_id": "5c55faf3d582b25756376226", + "imdb_id": "tt2595474", + "name": "Encouragement of Climb", + "type": "series", + "year": "2013–2018" + }, + { + "_id": "53677f07847ccc8123a18079", + "imdb_id": "tt0129723", + "name": "Z Cars", + "type": "series", + "year": "1962–1978" + }, + { + "_id": "5c1b186b173739c9f4c8db32", + "imdb_id": "tt6763304", + "name": "Monster Hunter Stories: Ride On", + "type": "series", + "year": "2016–2018" + }, + { + "_id": "53677f25847ccc8123a1d5a2", + "imdb_id": "tt0106053", + "name": "Late Show with David Letterman", + "type": "series", + "year": "1993–2015" + }, + { + "_id": "550fb93dcc9eee85bb52da53", + "imdb_id": "tt0058817", + "name": "Kimba the White Lion", + "year": "1965–1967", + "type": "series" + }, + { + "_id": "5e13fd1ac4ccb5dd9220077c", + "imdb_id": "tt9024590", + "name": "Nurses", + "type": "series", + "year": "2020–2021" + }, + { + "_id": "53f6326fa8f27b1bb90c33b8", + "imdb_id": "tt2379308", + "name": "Psycho-Pass", + "type": "series", + "year": "2012–2019" + }, + { + "_id": "5985aa862abbe633c58e7aaa", + "imdb_id": "tt5464086", + "name": "Midnight, Texas", + "type": "series", + "year": "2017–2018" + }, + { + "_id": "53677f07847ccc8123a1802e", + "imdb_id": "tt0381740", + "name": "Clean House", + "type": "series", + "year": "2003–2011" + }, + { + "_id": "53677f02847ccc8123a17002", + "imdb_id": "tt2176287", + "name": "Comedy Bang! Bang!", + "type": "series", + "year": "2012–2016" + }, + { + "_id": "53677f1a847ccc8123a1b6eb", + "imdb_id": "tt2183641", + "name": "Ripper Street", + "type": "series", + "year": "2012–2016" + }, + { + "_id": "53c58b47a8f27b1bb90b7d15", + "imdb_id": "tt1509677", + "name": "Pointless", + "type": "series", + "year": "2009–" + }, + { + "_id": "53677f00847ccc8123a16509", + "imdb_id": "tt0096633", + "name": "Legend of the Galactic Heroes", + "type": "series", + "year": "1988–1997" + }, + { + "_id": "57e3e788d7e54929823e7eb0", + "imdb_id": "tt5562056", + "name": "Easy", + "year": "2016–2019", + "type": "series" + }, + { + "_id": "5c0c80c3173739c9f4e16d57", + "imdb_id": "tt0115215", + "name": "The Incredible Hulk", + "type": "series", + "year": "1996–1998" + }, + { + "_id": "5484ade08527d2e0cb4fd695", + "imdb_id": "tt0058819", + "name": "Laredo", + "type": "series", + "year": "1965–1967" + }, + { + "_id": "53677f29847ccc8123a1db75", + "imdb_id": "tt0078680", + "name": "Rumpole of the Bailey", + "type": "series", + "year": "1978–1992" + }, + { + "_id": "64a2929dbd36726cbb9de3ce", + "imdb_id": "tt0296361", + "name": "Die Johannes B. Kerner Show", + "type": "series", + "year": "1998–" + }, + { + "_id": "53677f2c847ccc8123a1e130", + "imdb_id": "tt2871832", + "name": "Cedar Cove", + "type": "series", + "year": "2013–2015" + }, + { + "_id": "541463a1a8f27b1bb90c9967", + "imdb_id": "tt3645318", + "name": "If Loving You Is Wrong", + "type": "series", + "year": "2014–2020" + }, + { + "_id": "53677f3a847ccc8123a1f01c", + "imdb_id": "tt0118300", + "name": "Dawson's Creek", + "type": "series", + "year": "1998–2003" + }, + { + "_id": "53677ef9847ccc8123a1380b", + "imdb_id": "tt1489428", + "name": "Justified", + "type": "series", + "year": "2010–2015" + }, + { + "_id": "53677f13847ccc8123a1a377", + "imdb_id": "tt0460631", + "name": "Close to Home", + "type": "series", + "year": "2005–2007" + }, + { + "_id": "53677f07847ccc8123a18130", + "imdb_id": "tt1138475", + "name": "The Guild", + "type": "series", + "year": "2007–2013" + }, + { + "_id": "55071066711bd19c92add7db", + "imdb_id": "tt2425098", + "name": "Magi: The Labyrinth of Magic", + "year": "2012–2014", + "type": "series" + }, + { + "_id": "53677f1e847ccc8123a1c0af", + "imdb_id": "tt0052490", + "name": "The Many Loves of Dobie Gillis", + "type": "series", + "year": "1959–1963" + }, + { + "_id": "53677efa847ccc8123a14af3", + "imdb_id": "tt0094525", + "name": "Poirot", + "type": "series", + "year": "1989–2013" + }, + { + "_id": "53677efa847ccc8123a145f5", + "imdb_id": "tt0239195", + "name": "Survivor", + "type": "series", + "year": "2000–" + }, + { + "_id": "53677ef9847ccc8123a14507", + "imdb_id": "tt1480684", + "name": "The League", + "type": "series", + "year": "2009–2015" + }, + { + "_id": "616499d964ec43ef9845634e", + "imdb_id": "tt15026576", + "name": "The Fruit of Evolution: Before I Knew It, My Life Had It Made", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "642ac38864ec43ef9892c18b", + "imdb_id": "tt14586350", + "name": "Love & Death", + "type": "series", + "year": "2023" + }, + { + "_id": "57e4c19ed7e54929823e8acb", + "imdb_id": "tt5197820", + "type": "series", + "name": "Van Helsing", + "year": "2016–2021" + }, + { + "_id": "53677ef9847ccc8123a13eb5", + "imdb_id": "tt0455275", + "name": "Prison Break", + "type": "series", + "year": "2005–2017" + }, + { + "_id": "5530eddbcc9eee85bb52e4ee", + "imdb_id": "tt1470837", + "name": "The Garfield Show", + "year": "2008–2016", + "type": "series" + }, + { + "_id": "62be25c664ec43ef9874fcde", + "imdb_id": "tt17736234", + "name": "Bastard!! Heavy Metal, Dark Fantasy", + "type": "series", + "year": "2022–2023" + }, + { + "_id": "57f30454d7e54929823f578b", + "imdb_id": "tt5511582", + "type": "series", + "name": "Timeless", + "year": "2016–2018" + }, + { + "_id": "53677ef9847ccc8123a13bf1", + "imdb_id": "tt0363307", + "name": "America's Next Top Model", + "type": "series", + "year": "2003–2018" + }, + { + "_id": "5c15922e173739c9f4042b59", + "imdb_id": "tt0489974", + "name": "Carnival Row", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "5c12dfc3173739c9f4274d0a", + "imdb_id": "tt7712598", + "name": "Blood & Treasure", + "type": "series", + "year": "2019–2022" + }, + { + "_id": "53677f05847ccc8123a1797f", + "imdb_id": "tt2202488", + "name": "Mountain Men", + "type": "series", + "year": "2012–" + }, + { + "_id": "53677f0e847ccc8123a19566", + "imdb_id": "tt0261463", + "name": "Ceres: Celestial Legend", + "type": "series", + "year": "2000" + }, + { + "_id": "53677f43847ccc8123a1fb33", + "imdb_id": "tt0088470", + "name": "227", + "type": "series", + "year": "1985–1990" + }, + { + "_id": "5c377ab6d582b2575686effb", + "imdb_id": "tt0112186", + "name": "The Sylvester & Tweety Mysteries", + "type": "series", + "year": "1995–2002" + }, + { + "_id": "5c0d820a173739c9f4a572dd", + "imdb_id": "tt6488862", + "name": "Eternal Love", + "type": "series", + "year": "2017" + }, + { + "_id": "53677ef9847ccc8123a143e7", + "imdb_id": "tt1235547", + "name": "Better Off Ted", + "type": "series", + "year": "2009–2010" + }, + { + "_id": "6057ebf254242533415940ac", + "imdb_id": "tt11173298", + "name": "Tournament of Champions", + "type": "series", + "year": "2020–" + }, + { + "_id": "53677eff847ccc8123a1607f", + "imdb_id": "tt0066626", + "name": "All in the Family", + "type": "series", + "year": "1971–1979" + }, + { + "_id": "5c0bf99a173739c9f4dbdd7e", + "imdb_id": "tt0062570", + "name": "Here's Lucy", + "type": "series", + "year": "1968–1974" + }, + { + "_id": "5b15abcd16f4806c2a9f656a", + "imdb_id": "tt7660850", + "type": "series", + "name": "Succession", + "year": "2018–2023" + }, + { + "_id": "5c0c26bd173739c9f4399acc", + "imdb_id": "tt0185070", + "name": "UFO Robo Grendizer", + "type": "series", + "year": "1975–1977" + }, + { + "_id": "5bcf266c173739c9f407a564", + "imdb_id": "tt7406320", + "name": "Eli Roth's History of Horror", + "type": "series", + "year": "2018–2021" + }, + { + "_id": "606f33135424253341e633ed", + "imdb_id": "tt9214684", + "name": "Home Economics", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "53677f02847ccc8123a16f41", + "imdb_id": "tt2401256", + "name": "The Night Of", + "type": "series", + "year": "2016" + }, + { + "_id": "53677f05847ccc8123a17875", + "imdb_id": "tt1409055", + "name": "Dragon Ball Z Kai", + "type": "series", + "year": "2009–2015" + }, + { + "_id": "53677f19847ccc8123a1b393", + "imdb_id": "tt0068128", + "name": "Sanford and Son", + "type": "series", + "year": "1972–1978" + }, + { + "_id": "5c1bf929173739c9f446f0fb", + "imdb_id": "tt2403776", + "name": "Shadow and Bone", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "53677f40847ccc8123a1f84c", + "imdb_id": "tt0118289", + "name": "Cow and Chicken", + "type": "series", + "year": "1997–1999" + }, + { + "_id": "5c5d4f37d582b25756e004b7", + "imdb_id": "tt0081907", + "name": "Never the Twain", + "type": "series", + "year": "1981–1991" + }, + { + "_id": "5ba4aee2173739c9f4ed963c", + "imdb_id": "tt5580146", + "name": "Maniac", + "type": "series", + "year": "2018" + }, + { + "_id": "53677f4c847ccc8123a2076b", + "imdb_id": "tt0242192", + "name": "Between the Lions", + "type": "series", + "year": "1999–2011" + }, + { + "_id": "5c0d6f77173739c9f47d84e8", + "imdb_id": "tt0486539", + "name": "The Megan Mullally Show", + "type": "series", + "year": "2006–2007" + }, + { + "_id": "624daa9e64ec43ef98908fa5", + "imdb_id": "tt15447890", + "name": "The Greatest Demon Lord Is Reborn as a Typical Nobody", + "type": "series", + "year": "2022" + }, + { + "_id": "5c5f0160d582b2575631d828", + "imdb_id": "tt0043204", + "name": "Goodyear Playhouse", + "type": "series", + "year": "1951–1957" + }, + { + "_id": "53677ef9847ccc8123a13894", + "imdb_id": "tt0830900", + "name": "Saving Grace", + "type": "series", + "year": "2007–2010" + }, + { + "_id": "53677f1d847ccc8123a1bddf", + "imdb_id": "tt0273855", + "name": "My Wife and Kids", + "type": "series", + "year": "2000–2024" + }, + { + "_id": "53677f4f847ccc8123a20baa", + "imdb_id": "tt0084978", + "name": "Automan", + "type": "series", + "year": "1983–1984" + }, + { + "_id": "5c0b1b51173739c9f4638bed", + "imdb_id": "tt1190429", + "name": "Popolocrois monogatari", + "type": "series", + "year": "1998–1999" + }, + { + "_id": "5ff7d19f5424253341f2bdaf", + "imdb_id": "tt10662034", + "name": "Mr. Mayor", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "53677ef9847ccc8123a13bfa", + "imdb_id": "tt1604099", + "name": "Victorious", + "type": "series", + "year": "2010–2013" + }, + { + "_id": "610bd2f764ec43ef9813d500", + "imdb_id": "tt10168312", + "name": "What If...?", + "type": "series", + "year": "2021–" + }, + { + "_id": "53f7285da8f27b1bb90c3740", + "imdb_id": "tt2644032", + "name": "Barbie: Life in the Dreamhouse", + "type": "series", + "year": "2012–2015" + }, + { + "_id": "53677f07847ccc8123a17fd0", + "imdb_id": "tt0472252", + "name": "Transformers: Cybertron", + "type": "series", + "year": "2005" + }, + { + "_id": "53677ef9847ccc8123a140f3", + "imdb_id": "tt0088634", + "name": "The Twilight Zone", + "type": "series", + "year": "1985–1989" + }, + { + "_id": "599b6c193e5e4b900ae85c51", + "imdb_id": "tt5618256", + "name": "Manhunt", + "type": "series", + "year": "2017–2020" + }, + { + "_id": "53677ef9847ccc8123a1419d", + "imdb_id": "tt1991564", + "name": "Lab Rats", + "type": "series", + "year": "2012–2016" + }, + { + "_id": "53677f0c847ccc8123a193b2", + "imdb_id": "tt0086662", + "name": "Airwolf", + "type": "series", + "year": "1984–1986" + }, + { + "_id": "53677ef9847ccc8123a13c30", + "imdb_id": "tt0112095", + "name": "NewsRadio", + "type": "series", + "year": "1995–1999" + }, + { + "_id": "53677ef9847ccc8123a14471", + "imdb_id": "tt1621748", + "name": "Ugly Americans", + "type": "series", + "year": "2010–2012" + }, + { + "_id": "5c1ada1e173739c9f44f32f6", + "imdb_id": "tt6286394", + "name": "WWE: 205 Live", + "type": "series", + "year": "2016–2022" + }, + { + "_id": "62880a6864ec43ef98e00a0f", + "imdb_id": "tt16341212", + "name": "Aharen-san wa hakarenai", + "type": "series", + "year": "2022" + }, + { + "_id": "5c340b93173739c9f41500a8", + "imdb_id": "tt8708280", + "name": "State of the Union", + "type": "series", + "year": "2019–2022" + }, + { + "_id": "6270647364ec43ef98158b1d", + "imdb_id": "tt19869844", + "name": "American Idol", + "type": "series", + "year": "2018–" + }, + { + "_id": "54e600a5fc2ab98b66971c3b", + "imdb_id": "tt0252399", + "name": "Dumbo's Circus", + "type": "series", + "year": "1985–1986" + }, + { + "_id": "53677efd847ccc8123a15531", + "imdb_id": "tt0108717", + "name": "Mystery!: Cadfael", + "type": "series", + "year": "1994–1998" + }, + { + "_id": "5b3614b516f4806c2aac30c3", + "imdb_id": "tt7965802", + "type": "series", + "name": "Megalo Box", + "year": "2018–2021" + }, + { + "_id": "5817dd1955f8aab460cf8baa", + "imdb_id": "tt4695530", + "name": "People of Earth", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "53677f02847ccc8123a16ccb", + "imdb_id": "tt0103522", + "name": "Red Shoe Diaries", + "type": "series", + "year": "1992–1999" + }, + { + "_id": "539173bca8f27b1bb90ade62", + "imdb_id": "tt0101198", + "name": "Silk Stalkings", + "type": "series", + "year": "1991–1999" + }, + { + "_id": "59fd9257543165dcd8886b2f", + "imdb_id": "tt2580046", + "type": "series", + "name": "Miraculous: Tales of Ladybug & Cat Noir", + "year": "2015–" + }, + { + "_id": "62332c5564ec43ef9844e1f3", + "imdb_id": "tt11947418", + "name": "Minx", + "type": "series", + "year": "2022–2023" + }, + { + "_id": "53677efd847ccc8123a1595b", + "imdb_id": "tt1400819", + "name": "Horrible Histories", + "type": "series", + "year": "2009–2023" + }, + { + "_id": "5c0ef351173739c9f40f6eca", + "imdb_id": "tt2445666", + "name": "Studio C", + "type": "series", + "year": "2012–" + }, + { + "_id": "53677ef9847ccc8123a13905", + "imdb_id": "tt0051311", + "name": "Sea Hunt", + "type": "series", + "year": "1958–1961" + }, + { + "_id": "5c39d26cd582b25756d98683", + "imdb_id": "tt0182633", + "name": "Sergeant Preston of the Yukon", + "type": "series", + "year": "1955–1958" + }, + { + "_id": "5378cc37847ccc8123ad565d", + "imdb_id": "tt3487382", + "name": "Forever", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "53677f08847ccc8123a1852a", + "imdb_id": "tt0857277", + "name": "Back at the Barnyard", + "type": "series", + "year": "2007–2011" + }, + { + "_id": "53677f17847ccc8123a1aaaf", + "imdb_id": "tt2443340", + "name": "Motive", + "type": "series", + "year": "2013–2016" + }, + { + "_id": "53677f35847ccc8123a1ebd7", + "imdb_id": "tt0092339", + "name": "A Different World", + "type": "series", + "year": "1987–1993" + }, + { + "_id": "53677eff847ccc8123a15ea7", + "imdb_id": "tt0096626", + "name": "The Kids in the Hall", + "type": "series", + "year": "1988–2021" + }, + { + "_id": "586d4c931635517fbf5677ad", + "imdb_id": "tt5638056", + "name": "The Mick", + "type": "series", + "year": "2017–2018" + }, + { + "_id": "5c0e5ae2173739c9f4eee7ca", + "imdb_id": "tt4831392", + "name": "Monster Musume: Everyday Life with Monster Girls", + "type": "series", + "year": "2015–2017" + }, + { + "_id": "5c1ecba4173739c9f45cc34f", + "imdb_id": "tt3850598", + "name": "BMF", + "type": "series", + "year": "2021–" + }, + { + "_id": "5c25e5e2173739c9f4e8d8a3", + "imdb_id": "tt2377276", + "name": "We Got Married", + "type": "series", + "year": "2008–" + }, + { + "_id": "53677f00847ccc8123a16814", + "imdb_id": "tt0101205", + "name": "Step by Step", + "type": "series", + "year": "1991–1998" + }, + { + "_id": "53677f03847ccc8123a1720b", + "imdb_id": "tt1817311", + "name": "64 Zoo Lane", + "type": "series", + "year": "1999–2013" + }, + { + "_id": "568d6cd1bb83c664989bbd02", + "imdb_id": "tt4270492", + "name": "Billions", + "year": "2016–2023", + "type": "series" + }, + { + "_id": "53677f0a847ccc8123a188d8", + "imdb_id": "tt0466352", + "name": "The Prince of Tennis", + "type": "series", + "year": "2001–2005" + }, + { + "_id": "53677efc847ccc8123a14e9a", + "imdb_id": "tt2006005", + "name": "Trollied", + "type": "series", + "year": "2011–2018" + }, + { + "_id": "5c0b59c6173739c9f4bc8c06", + "imdb_id": "tt0105559", + "name": "Tenchi Muyo!", + "type": "series", + "year": "1992–2005" + }, + { + "_id": "55fa7ed3bf6c900d1841f471", + "imdb_id": "tt4422836", + "name": "Limitless", + "year": "2015–2016", + "type": "series" + }, + { + "_id": "53677efc847ccc8123a15220", + "imdb_id": "tt0058815", + "name": "I Dream of Jeannie", + "type": "series", + "year": "1965–1970" + }, + { + "_id": "53677f0c847ccc8123a1918e", + "imdb_id": "tt0090410", + "name": "Crime Story", + "type": "series", + "year": "1986–1988" + }, + { + "_id": "53677f02847ccc8123a17000", + "imdb_id": "tt0955346", + "name": "Moonlight", + "type": "series", + "year": "2007–2008" + }, + { + "_id": "53677eff847ccc8123a15d75", + "imdb_id": "tt0259141", + "name": "Jackie Chan Adventures", + "type": "series", + "year": "2000–2005" + }, + { + "_id": "53677ef9847ccc8123a1383a", + "imdb_id": "tt1606375", + "name": "Downton Abbey", + "type": "series", + "year": "2010–2015" + }, + { + "_id": "54fb5f32711bd19c92ad4345", + "imdb_id": "tt2622982", + "name": "The Devil Is a Part-Timer!", + "year": "2013–2023", + "type": "series" + }, + { + "_id": "5c5f5cfad582b25756c3c687", + "imdb_id": "tt8697870", + "name": "The Nevers", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "53677f0a847ccc8123a189ac", + "imdb_id": "tt0260615", + "name": "The Forsyte Saga", + "type": "series", + "year": "2002–2003" + }, + { + "_id": "5c155cdc173739c9f492ed6f", + "imdb_id": "tt5330088", + "name": "The $100,000 Pyramid", + "type": "series", + "year": "2016–" + }, + { + "_id": "63d3471264ec43ef9859d0d9", + "imdb_id": "tt15677150", + "name": "Shrinking", + "type": "series", + "year": "2023–" + }, + { + "_id": "54edea533a9a6f404a162e35", + "imdb_id": "tt4136774", + "name": "The Ministry of Time", + "year": "2015–2020", + "type": "series" + }, + { + "_id": "53677f17847ccc8123a1ac5d", + "imdb_id": "tt0409630", + "name": "Texhnolyze", + "type": "series", + "year": "2003" + }, + { + "_id": "53677f08847ccc8123a18574", + "imdb_id": "tt0098878", + "name": "Northern Exposure", + "type": "series", + "year": "1990–1995" + }, + { + "_id": "6348f8c464ec43ef987f4492", + "imdb_id": "tt21929358", + "name": "Akiba Maid War", + "type": "series", + "year": "2022" + }, + { + "_id": "5c0cd610173739c9f44c1241", + "imdb_id": "tt6782014", + "name": "Mystery Science Theater 3000", + "type": "series", + "year": "2017–2022" + }, + { + "_id": "5c0bab0c173739c9f43e820a", + "imdb_id": "tt0086787", + "name": "Punky Brewster", + "type": "series", + "year": "1984–1988" + }, + { + "_id": "5c099da3173739c9f4b44b9b", + "imdb_id": "tt0328738", + "name": "Fruits Basket", + "type": "series", + "year": "2001" + }, + { + "_id": "53677f43847ccc8123a1fabf", + "imdb_id": "tt2474952", + "name": "Bravest Warriors", + "type": "series", + "year": "2009–2018" + }, + { + "_id": "53677f24847ccc8123a1d268", + "imdb_id": "tt0115326", + "name": "PSI Factor: Chronicles of the Paranormal", + "type": "series", + "year": "1996–2000" + }, + { + "_id": "58c984c81635517fbf56e5fe", + "imdb_id": "tt5052460", + "name": "Taken", + "type": "series", + "year": "2017–2018" + }, + { + "_id": "5c15d691173739c9f469cc3e", + "imdb_id": "tt0115144", + "name": "Cosby", + "type": "series", + "year": "1996–2000" + }, + { + "_id": "5c5165ead582b257560e984a", + "imdb_id": "tt8323628", + "name": "My Life with the Walter Boys", + "type": "series", + "year": "2023–" + }, + { + "_id": "54250887a8f27b1bb90cd79b", + "imdb_id": "tt2112923", + "name": "Celebrity Name Game", + "type": "series", + "year": "2014–2017" + }, + { + "_id": "53677f0c847ccc8123a18fed", + "imdb_id": "tt0434725", + "name": "Detective School Q", + "type": "series", + "year": "2003–2004" + }, + { + "_id": "53677efa847ccc8123a1464a", + "imdb_id": "tt0060028", + "name": "Star Trek", + "type": "series", + "year": "1966–1969" + }, + { + "_id": "53677f15847ccc8123a1a9e8", + "imdb_id": "tt0092379", + "name": "Inspector Morse", + "type": "series", + "year": "1987–2000" + }, + { + "_id": "53677ef9847ccc8123a13c90", + "imdb_id": "tt0330251", + "name": "The L Word", + "type": "series", + "year": "2004–2009" + }, + { + "_id": "5c09b7c0173739c9f4e956fe", + "imdb_id": "tt8699270", + "name": "Ultraman", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "53677f37847ccc8123a1ed99", + "imdb_id": "tt0068040", + "name": "Are You Being Served?", + "type": "series", + "year": "1972–1985" + }, + { + "_id": "5c3338b8173739c9f476d359", + "imdb_id": "tt9471404", + "name": "The Chosen", + "type": "series", + "year": "2017–" + }, + { + "_id": "5378cc15847ccc8123ad4d22", + "imdb_id": "tt3560084", + "name": "NCIS: New Orleans", + "type": "series", + "year": "2014–2021" + }, + { + "_id": "5c0be08d173739c9f4a7f9f1", + "imdb_id": "tt7817856", + "name": "The Crown of the Kings", + "type": "series", + "year": "2018–" + }, + { + "_id": "53677efd847ccc8123a159fc", + "imdb_id": "tt0084972", + "name": "Alvin & the Chipmunks", + "type": "series", + "year": "1983–1990" + }, + { + "_id": "53677f19847ccc8123a1b253", + "imdb_id": "tt1733785", + "name": "The Bridge", + "type": "series", + "year": "2011–2018" + }, + { + "_id": "59cc5a4c067c4652104aa54c", + "imdb_id": "tt6473344", + "type": "series", + "name": "SEAL Team", + "year": "2017–2024" + }, + { + "_id": "53677ef9847ccc8123a13b0a", + "imdb_id": "tt1694423", + "name": "MasterChef USA", + "type": "series", + "year": "2010–" + }, + { + "_id": "5c3628e9d582b25756447d0e", + "imdb_id": "tt0090479", + "name": "Maison Ikkoku", + "type": "series", + "year": "1986–1988" + }, + { + "_id": "53677f1f847ccc8123a1c552", + "imdb_id": "tt0112221", + "name": "Wedding Peach", + "type": "series", + "year": "1995–1996" + }, + { + "_id": "5c0b9ef8173739c9f4273c33", + "imdb_id": "tt8146754", + "name": "Infinity Train", + "type": "series", + "year": "2019–2021" + }, + { + "_id": "53677efc847ccc8123a14f5a", + "imdb_id": "tt0098740", + "name": "America's Funniest Home Videos", + "type": "series", + "year": "1989–" + }, + { + "_id": "6534d3c9bd36726cbb4497c3", + "imdb_id": "tt26743760", + "name": "The Apothecary Diaries", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677f17847ccc8123a1ae75", + "imdb_id": "tt0259795", + "name": "The Old Grey Whistle Test", + "type": "series", + "year": "1971–2018" + }, + { + "_id": "5c0c8b86173739c9f4ef0698", + "imdb_id": "tt8362852", + "name": "Swamp Thing", + "type": "series", + "year": "2019" + }, + { + "_id": "5884c0e81635517fbf569dd1", + "imdb_id": "tt5994364", + "name": "Guardian: The Lonely and Great God", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "53677f20847ccc8123a1c6d2", + "imdb_id": "tt0089008", + "name": "Deceptions", + "type": "series", + "year": "1985–" + }, + { + "_id": "53677ef9847ccc8123a13b5e", + "imdb_id": "tt1235099", + "name": "Lie to Me", + "type": "series", + "year": "2009–2011" + }, + { + "_id": "53677f12847ccc8123a19fa1", + "imdb_id": "tt0096569", + "name": "Doogie Howser, M.D.", + "type": "series", + "year": "1989–1993" + }, + { + "_id": "53677efd847ccc8123a15a11", + "imdb_id": "tt0377260", + "name": "Shameless", + "type": "series", + "year": "2004–2013" + }, + { + "_id": "53677f19847ccc8123a1b279", + "imdb_id": "tt0145628", + "name": "Popeye the Sailor", + "type": "series", + "year": "1960–1962" + }, + { + "_id": "53677efc847ccc8123a14f75", + "imdb_id": "tt0960136", + "name": "Dirty Sexy Money", + "type": "series", + "year": "2007–2009" + }, + { + "_id": "5c447b69d582b25756110f85", + "imdb_id": "tt0108889", + "name": "One West Waikiki", + "type": "series", + "year": "1994–1996" + }, + { + "_id": "53677efc847ccc8123a15075", + "imdb_id": "tt1971245", + "name": "The Voice UK", + "type": "series", + "year": "2012–" + }, + { + "_id": "5432d88fa8f27b1bb90d0cb4", + "imdb_id": "tt0439341", + "name": "6Teen", + "type": "series", + "year": "2004–2010" + }, + { + "_id": "5c472dbbd582b257568f38c8", + "imdb_id": "tt0111914", + "name": "C.P.W.", + "type": "series", + "year": "1995–1996" + }, + { + "_id": "53677f40847ccc8123a1f53e", + "imdb_id": "tt0080221", + "name": "Galactica 1980", + "type": "series", + "year": "1980" + }, + { + "_id": "537500ca847ccc8123ad0ad6", + "imdb_id": "tt2777882", + "name": "El Señor de los Cielos", + "type": "series", + "year": "2013–" + }, + { + "_id": "56183accec193d5e98269973", + "imdb_id": "tt4215734", + "name": "Be Cool, Scooby-Doo!", + "year": "2015–2018", + "type": "series" + }, + { + "_id": "5c20043b173739c9f486c4a3", + "imdb_id": "tt0054545", + "name": "Hazel", + "type": "series", + "year": "1961–1966" + }, + { + "_id": "53677f22847ccc8123a1ce53", + "imdb_id": "tt0396991", + "name": "LazyTown", + "type": "series", + "year": "2002–2014" + }, + { + "_id": "53677f23847ccc8123a1cf71", + "imdb_id": "tt2292621", + "name": "Burning Love", + "type": "series", + "year": "2012–2013" + }, + { + "_id": "5c3f1bafd582b257569776c6", + "imdb_id": "tt7671598", + "name": "Messiah", + "type": "series", + "year": "2020" + }, + { + "_id": "5c0aad5c173739c9f4852a8d", + "imdb_id": "tt8416494", + "name": "Doom Patrol", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "53677f1e847ccc8123a1c1fb", + "imdb_id": "tt1409383", + "name": "Big Windup!", + "type": "series", + "year": "2007–2010" + }, + { + "_id": "5c3da367d582b25756e34459", + "imdb_id": "tt0112233", + "name": "Zenki", + "type": "series", + "year": "1995–" + }, + { + "_id": "5c0c3f99173739c9f46e9f7e", + "imdb_id": "tt4858114", + "name": "Hotel Transylvania: The Series", + "type": "series", + "year": "2017–2020" + }, + { + "_id": "651d9d0cbd36726cbb4dbc71", + "imdb_id": "tt28685497", + "name": "Berserk of Gluttony", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677ef9847ccc8123a138d1", + "imdb_id": "tt1628033", + "name": "Top Gear", + "type": "series", + "year": "2002–" + }, + { + "_id": "5401f968a8f27b1bb90c5b0b", + "imdb_id": "tt3973820", + "name": "Red Oaks", + "type": "series", + "year": "2014–2017" + }, + { + "_id": "55070fe8711bd19c92add786", + "imdb_id": "tt0388585", + "name": "CentoVetrine", + "year": "2001–", + "type": "series" + }, + { + "_id": "62f7296564ec43ef9890d5a0", + "imdb_id": "tt15669534", + "name": "Tales of the Walking Dead", + "type": "series", + "year": "2022" + }, + { + "_id": "641c255864ec43ef98403a5f", + "imdb_id": "tt13918776", + "name": "The Night Agent", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677f3a847ccc8123a1ef34", + "imdb_id": "tt2548200", + "name": "Slugterra", + "type": "series", + "year": "2012–2016" + }, + { + "_id": "5378cbf3847ccc8123ad31e2", + "imdb_id": "tt3358020", + "name": "Parasyte: The Maxim", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "53677efd847ccc8123a15b1e", + "imdb_id": "tt1639109", + "name": "Angel Beats!", + "type": "series", + "year": "2010" + }, + { + "_id": "53677f74847ccc8123a2375e", + "imdb_id": "tt0098919", + "name": "Swamp Thing", + "type": "series", + "year": "1990–1993" + }, + { + "_id": "53677f72847ccc8123a235b2", + "imdb_id": "tt1299440", + "name": "Fanboy & Chum Chum", + "type": "series", + "year": "2009–2014" + }, + { + "_id": "646d5f7fbd36726cbbeeb560", + "imdb_id": "tt14028208", + "name": "Clone High", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677f22847ccc8123a1cd62", + "imdb_id": "tt0149490", + "name": "Meet the Press", + "type": "series", + "year": "1947–" + }, + { + "_id": "6182992764ec43ef98531e65", + "imdb_id": "tt13368190", + "name": "Judy Justice", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677f6c847ccc8123a2302d", + "imdb_id": "tt0056774", + "name": "Mr. Novak", + "type": "series", + "year": "1963–1965" + }, + { + "_id": "53677f1d847ccc8123a1bf11", + "imdb_id": "tt0181935", + "name": "Norm", + "type": "series", + "year": "1999–2001" + }, + { + "_id": "5811ba24d7e549298241449f", + "imdb_id": "tt0247081", + "name": "Boston Public", + "type": "series", + "year": "2000–2006" + }, + { + "_id": "53677f45847ccc8123a1ff60", + "imdb_id": "tt0247144", + "name": "Yes, Dear", + "type": "series", + "year": "2000–2006" + }, + { + "_id": "5c157d38173739c9f4d86984", + "imdb_id": "tt8741290", + "name": "Tales from the Loop", + "type": "series", + "year": "2020" + }, + { + "_id": "5543c7c2d728d29134b6e4f7", + "imdb_id": "tt4524056", + "name": "Vis a vis", + "year": "2015–2019", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13e29", + "imdb_id": "tt0859592", + "name": "Army Wives", + "type": "series", + "year": "2007–2013" + }, + { + "_id": "5c0ee953173739c9f4fc1831", + "imdb_id": "tt9252156", + "name": "Departure", + "type": "series", + "year": "2019–2022" + }, + { + "_id": "5c0f4ca3173739c9f49c6263", + "imdb_id": "tt0307427", + "name": "s-CRY-ed", + "type": "series", + "year": "2001" + }, + { + "_id": "63443b8464ec43ef988a7684", + "imdb_id": "tt19406880", + "name": "Shinmai renkinjutsushi no tenpo keiei", + "type": "series", + "year": "2022" + }, + { + "_id": "61bf074c64ec43ef9855018c", + "imdb_id": "tt13991232", + "name": "1883", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "5c0a3f6d173739c9f4b7964b", + "imdb_id": "tt6025022", + "name": "Justice League Unlimited", + "type": "series", + "year": "2004–2006" + }, + { + "_id": "63e5151464ec43ef98ab12f4", + "imdb_id": "tt13433814", + "name": "My Dad the Bounty Hunter", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677f48847ccc8123a202d8", + "imdb_id": "tt0169438", + "name": "Dream Team", + "type": "series", + "year": "1997–2007" + }, + { + "_id": "6289ea0c64ec43ef9834724d", + "imdb_id": "tt15686254", + "name": "Summer Time Rendering", + "type": "series", + "year": "2022" + }, + { + "_id": "5819ad5655f8aab460cfa87b", + "imdb_id": "tt5679720", + "name": "Bungo Stray Dogs", + "type": "series", + "year": "2016–" + }, + { + "_id": "5c26b302173739c9f4834fbb", + "imdb_id": "tt1085074", + "name": "Black Cat", + "type": "series", + "year": "2005–2006" + }, + { + "_id": "62c5f85164ec43ef980e367f", + "imdb_id": "tt13628870", + "name": "Harem in the Labyrinth of Another World", + "type": "series", + "year": "2022" + }, + { + "_id": "5bfe18bd173739c9f4e2a479", + "imdb_id": "tt5015548", + "name": "Agatha Raisin", + "type": "series", + "year": "2014–" + }, + { + "_id": "5c0dd1f0173739c9f4311dd0", + "imdb_id": "tt0303503", + "name": "Magical DoReMi", + "type": "series", + "year": "1999–2004" + }, + { + "_id": "53677efc847ccc8123a15135", + "imdb_id": "tt1242441", + "name": "Men of a Certain Age", + "type": "series", + "year": "2009–2011" + }, + { + "_id": "5c240ab8173739c9f4c2c510", + "imdb_id": "tt7520794", + "name": "Russian Doll", + "type": "series", + "year": "2019–" + }, + { + "_id": "53677f14847ccc8123a1a4bd", + "imdb_id": "tt0423731", + "name": "Samurai Champloo", + "type": "series", + "year": "2004–2005" + }, + { + "_id": "53677f5e847ccc8123a22213", + "imdb_id": "tt0387714", + "name": "All Grown Up!", + "type": "series", + "year": "2003–2008" + }, + { + "_id": "5c5de778d582b25756aa258b", + "imdb_id": "tt1206627", + "name": "Misutâ ajikko", + "type": "series", + "year": "1987–1989" + }, + { + "_id": "5c3b8aafd582b25756c86bc1", + "imdb_id": "tt0096635", + "name": "Life Goes On", + "type": "series", + "year": "1989–1993" + }, + { + "_id": "642ed49e64ec43ef98ae237f", + "imdb_id": "tt11127388", + "name": "Grease: Rise of the Pink Ladies", + "type": "series", + "year": "2023" + }, + { + "_id": "53677efc847ccc8123a152f6", + "imdb_id": "tt0083455", + "name": "Newhart", + "type": "series", + "year": "1982–1990" + }, + { + "_id": "5c17b109173739c9f487808f", + "imdb_id": "tt0218775", + "name": "Monster Rancher", + "type": "series", + "year": "1999–2001" + }, + { + "_id": "5378cbfe847ccc8123ad3944", + "imdb_id": "tt3305096", + "name": "Galavant", + "type": "series", + "year": "2015–2016" + }, + { + "_id": "5c1f2b67173739c9f4e83378", + "imdb_id": "tt4584326", + "name": "Seraph of the End", + "type": "series", + "year": "2015" + }, + { + "_id": "53677f3d847ccc8123a1f259", + "imdb_id": "tt0075561", + "name": "The Professionals", + "type": "series", + "year": "1977–1983" + }, + { + "_id": "53677f05847ccc8123a1797d", + "imdb_id": "tt1134000", + "name": "Mobile Suit Gundam 00", + "type": "series", + "year": "2007–2009" + }, + { + "_id": "53677f3a847ccc8123a1ef47", + "imdb_id": "tt0429305", + "name": "American Dragon: Jake Long", + "type": "series", + "year": "2005–2007" + }, + { + "_id": "53677f03847ccc8123a17268", + "imdb_id": "tt1699440", + "name": "The Cat in the Hat Knows a Lot About That!", + "type": "series", + "year": "2010–2018" + }, + { + "_id": "585846791635517fbf561d74", + "imdb_id": "tt4635282", + "name": "The OA", + "type": "series", + "year": "2016–2019" + }, + { + "_id": "5eabd6275424253341d630e2", + "imdb_id": "tt9827854", + "name": "Hollywood", + "type": "series", + "year": "2020" + }, + { + "_id": "54f5b396451edcfca9b1c57c", + "imdb_id": "tt3906732", + "name": "Good Witch", + "year": "2015–2021", + "type": "series" + }, + { + "_id": "5e156ba7c4ccb5dd92bd6aa6", + "imdb_id": "tt9742936", + "name": "FBI: Most Wanted", + "type": "series", + "year": "2020–" + }, + { + "_id": "53677f79847ccc8123a23ce4", + "imdb_id": "tt3559912", + "name": "The Carbonaro Effect", + "type": "series", + "year": "2014–" + }, + { + "_id": "56c0c506f6b914c6c681d729", + "imdb_id": "tt4905554", + "name": "Jack Irish", + "year": "2016–2021", + "type": "series" + }, + { + "_id": "53677efa847ccc8123a14786", + "imdb_id": "tt0348914", + "name": "Deadwood", + "type": "series", + "year": "2004–2006" + }, + { + "_id": "55a648a6bf6c900d183ad16a", + "imdb_id": "tt4384306", + "name": "Sound! Euphonium", + "year": "2015–", + "type": "series" + }, + { + "_id": "578e1b38f0b6c53b3c78c740", + "imdb_id": "tt4971144", + "name": "Greenleaf", + "year": "2016–2020", + "type": "series" + }, + { + "_id": "6228edc364ec43ef98f8f7a7", + "imdb_id": "tt15170340", + "name": "Orient", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677f63847ccc8123a22858", + "imdb_id": "tt0061240", + "name": "The Carol Burnett Show", + "type": "series", + "year": "1967–1978" + }, + { + "_id": "5dbc2ffac4ccb5dd927d512f", + "imdb_id": "tt7949218", + "name": "See", + "type": "series", + "year": "2019–2022" + }, + { + "_id": "53677f05847ccc8123a17ce1", + "imdb_id": "tt0280277", + "name": "Mr. Bean: The Animated Series", + "type": "series", + "year": "2002–2019" + }, + { + "_id": "5c48c89bd582b25756cc30d7", + "imdb_id": "tt2649756", + "name": "The Idolm@ster", + "type": "series", + "year": "2011" + }, + { + "_id": "5c5c0797d582b25756259edb", + "imdb_id": "tt5828144", + "name": "Rainbow Ruby", + "type": "series", + "year": "2016–2020" + }, + { + "_id": "54fbb445711bd19c92ad490b", + "imdb_id": "tt0437018", + "name": "Krypto the Superdog", + "year": "2005–2006", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13a97", + "imdb_id": "tt0487831", + "name": "The IT Crowd", + "type": "series", + "year": "2006–2013" + }, + { + "_id": "5c156057173739c9f49a227e", + "imdb_id": "tt6632666", + "type": "series", + "name": "Project Blue Book", + "year": "2019–2020" + }, + { + "_id": "63b9c77e64ec43ef98d2d940", + "imdb_id": "tt18311412", + "name": "NieR:Automata Ver1.1a", + "type": "series", + "year": "2023–" + }, + { + "_id": "5c09e344173739c9f43e1599", + "imdb_id": "tt9304350", + "name": "Fruits Basket", + "type": "series", + "year": "2019–2021" + }, + { + "_id": "601d873a54242533416eb14a", + "imdb_id": "tt1847445", + "name": "The Tatami Galaxy", + "type": "series", + "year": "2010" + }, + { + "_id": "53677efd847ccc8123a155e5", + "imdb_id": "tt0361227", + "name": "Punk'd", + "type": "series", + "year": "2003–2015" + }, + { + "_id": "55a648abbf6c900d183ad16b", + "imdb_id": "tt4584754", + "name": "RIN-NE", + "year": "2015–2017", + "type": "series" + }, + { + "_id": "5c27f682173739c9f4b019a7", + "imdb_id": "tt0105988", + "name": "Droopy: Master Detective", + "type": "series", + "year": "1993–1994" + }, + { + "_id": "53677efa847ccc8123a14890", + "imdb_id": "tt0131179", + "name": "Detective Conan", + "type": "series", + "year": "1996–" + }, + { + "_id": "5c1233bb173739c9f4d635ee", + "imdb_id": "tt0175863", + "name": "Lucky Luke", + "type": "series", + "year": "1983–1984" + }, + { + "_id": "6138ed5d64ec43ef9877132d", + "imdb_id": "tt12225230", + "name": "Doogie Kamealoha, M.D.", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "53677f2f847ccc8123a1e65e", + "imdb_id": "tt2834032", + "name": "Love Thy Neighbor", + "type": "series", + "year": "2013–" + }, + { + "_id": "53677f0c847ccc8123a18f45", + "imdb_id": "tt1129029", + "name": "Satisfaction", + "type": "series", + "year": "2007–2010" + }, + { + "_id": "5378cc09847ccc8123ad45fa", + "imdb_id": "tt3576794", + "name": "Red Band Society", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "53677f07847ccc8123a1813a", + "imdb_id": "tt0086770", + "name": "Night Court", + "type": "series", + "year": "1984–1992" + }, + { + "_id": "53677f5a847ccc8123a21ac8", + "imdb_id": "tt0052442", + "name": "One Step Beyond", + "type": "series", + "year": "1959–1961" + }, + { + "_id": "5f89425554242533410f49d0", + "imdb_id": "tt10266874", + "name": "Helstrom", + "type": "series", + "year": "2020" + }, + { + "_id": "58ff46731635517fbf56e7a1", + "imdb_id": "tt5673782", + "name": "Genius", + "type": "series", + "year": "2017–" + }, + { + "_id": "53677f3a847ccc8123a1f053", + "imdb_id": "tt0472642", + "name": "Amar en tiempos revueltos", + "type": "series", + "year": "2005–2024" + }, + { + "_id": "63e4dcd064ec43ef985f07f0", + "imdb_id": "tt18250904", + "name": "Not Dead Yet", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677f2c847ccc8123a1e171", + "imdb_id": "tt0472989", + "name": "Wild 'N Out", + "type": "series", + "year": "2005–" + }, + { + "_id": "537afa15847ccc8123ad61fe", + "imdb_id": "tt0077013", + "name": "Future Boy Conan", + "type": "series", + "year": "1978" + }, + { + "_id": "57dd2352d7e54929823e23c9", + "imdb_id": "tt5151816", + "name": "Chesapeake Shores", + "year": "2016–2022", + "type": "series" + }, + { + "_id": "53677f37847ccc8123a1ed26", + "imdb_id": "tt0075513", + "name": "The Hardy Boys/Nancy Drew Mysteries", + "type": "series", + "year": "1977–1979" + }, + { + "_id": "5c0ad5f5173739c9f4d68e82", + "imdb_id": "tt8526988", + "name": "Total DramaRama", + "type": "series", + "year": "2018–2023" + }, + { + "_id": "53677f3a847ccc8123a1f166", + "imdb_id": "tt0169414", + "name": "Arthur", + "type": "series", + "year": "1996–2022" + }, + { + "_id": "5c2bff13173739c9f4d0c140", + "imdb_id": "tt0233033", + "name": "The Berenstain Bears", + "type": "series", + "year": "1985–2004" + }, + { + "_id": "53677ef9847ccc8123a13a47", + "imdb_id": "tt1772752", + "name": "A.N.T. Farm", + "type": "series", + "year": "2011–2014" + }, + { + "_id": "53677f5e847ccc8123a220bf", + "imdb_id": "tt3114390", + "name": "KILL la KILL", + "type": "series", + "year": "2013–2014" + }, + { + "_id": "5c60ca76d582b25756b54b85", + "imdb_id": "tt2188535", + "name": "Tokumei Sentai Go-Busters", + "type": "series", + "year": "2012–2013" + }, + { + "_id": "53677ef9847ccc8123a138a1", + "imdb_id": "tt0437005", + "name": "Hell's Kitchen", + "type": "series", + "year": "2005–" + }, + { + "_id": "53677f17847ccc8123a1ac21", + "imdb_id": "tt0414766", + "name": "Rebelde", + "type": "series", + "year": "2004–2006" + }, + { + "_id": "5c1f1d23173739c9f4d7caa8", + "imdb_id": "tt2235759", + "name": "The Great", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "56687423bb83c664989838e0", + "imdb_id": "tt4226226", + "name": "Holiday Baking Championship", + "year": "2014–", + "type": "series" + }, + { + "_id": "5e7c93c6733826cd9f6b3153", + "imdb_id": "tt10364808", + "name": "Mao Mao: Heroes of Pure Heart", + "type": "series", + "year": "2014–2024" + }, + { + "_id": "55c8a058bf6c900d183dc183", + "imdb_id": "tt4905966", + "name": "Valerie's Home Cooking", + "year": "2015–2023", + "type": "series" + }, + { + "_id": "5c292c45173739c9f4bd988b", + "imdb_id": "tt9179552", + "name": "Dr. Death", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "5c255be9173739c9f4253112", + "imdb_id": "tt5778326", + "name": "Black Jack", + "type": "series", + "year": "1993–2018" + }, + { + "_id": "53677f66847ccc8123a22a09", + "imdb_id": "tt0247902", + "name": "Yu-Gi-Oh! Duel Monsters", + "type": "series", + "year": "2000–2004" + }, + { + "_id": "541463a1a8f27b1bb90c996b", + "imdb_id": "tt0162796", + "name": "Bump in the Night", + "type": "series", + "year": "1994–1995" + }, + { + "_id": "5c2945fe173739c9f4f42546", + "imdb_id": "tt5737466", + "name": "The History of Comedy", + "type": "series", + "year": "2017–2018" + }, + { + "_id": "53677f2e847ccc8123a1e377", + "imdb_id": "tt2217759", + "name": "Monday Mornings", + "type": "series", + "year": "2013" + }, + { + "_id": "53677ef9847ccc8123a1433f", + "imdb_id": "tt0362192", + "name": "State of Play", + "type": "series", + "year": "2003" + }, + { + "_id": "53677f79847ccc8123a23cb7", + "imdb_id": "tt2772104", + "name": "Mischievous Kiss: Love in Tokyo", + "type": "series", + "year": "2013–2015" + }, + { + "_id": "53b176e0a8f27b1bb90b4078", + "imdb_id": "tt0805960", + "name": "Speed Grapher", + "type": "series", + "year": "2005" + }, + { + "_id": "6432754464ec43ef9899d2bf", + "imdb_id": "tt21423786", + "name": "The Dangers in My Heart", + "type": "series", + "year": "2023–" + }, + { + "_id": "5401f968a8f27b1bb90c5afb", + "imdb_id": "tt0115420", + "name": "Wind at My Back", + "type": "series", + "year": "1996–2001" + }, + { + "_id": "53677f0a847ccc8123a18824", + "imdb_id": "tt0086681", + "name": "Charles in Charge", + "type": "series", + "year": "1984–1990" + }, + { + "_id": "53677efd847ccc8123a15b83", + "imdb_id": "tt1181917", + "name": "The Suite Life on Deck", + "type": "series", + "year": "2008–2011" + }, + { + "_id": "547726d987010db6f207f53e", + "imdb_id": "tt0077058", + "name": "The Paper Chase", + "type": "series", + "year": "1978–1986" + }, + { + "_id": "53677efa847ccc8123a14a33", + "imdb_id": "tt0176095", + "name": "The Challenge", + "type": "series", + "year": "1998–" + }, + { + "_id": "53677f0a847ccc8123a186a5", + "imdb_id": "tt2177491", + "name": "Ben and Kate", + "type": "series", + "year": "2012–2013" + }, + { + "_id": "539c4866a8f27b1bb90afede", + "imdb_id": "tt2399794", + "name": "Chasing Life", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "5c26864d173739c9f426c778", + "imdb_id": "tt0184169", + "name": "Ultraseven", + "type": "series", + "year": "1967–1968" + }, + { + "_id": "53677f04847ccc8123a17414", + "imdb_id": "tt2406376", + "name": "The Bridge", + "type": "series", + "year": "2013–2014" + }, + { + "_id": "5c56b62dd582b257561d682b", + "imdb_id": "tt9340526", + "name": "P-Valley", + "type": "series", + "year": "2020–" + }, + { + "_id": "53677f08847ccc8123a1835d", + "imdb_id": "tt0108684", + "name": "Aaahh!!! Real Monsters", + "type": "series", + "year": "1994–1997" + }, + { + "_id": "5c27f892173739c9f4b4583a", + "imdb_id": "tt8633518", + "name": "Weird City", + "type": "series", + "year": "2019" + }, + { + "_id": "53677f19847ccc8123a1b5ce", + "imdb_id": "tt0327386", + "name": "The Twelve Kingdoms", + "type": "series", + "year": "2002–2003" + }, + { + "_id": "54e9bb50417d39942847b67e", + "imdb_id": "tt0118484", + "name": "Sunset Beach", + "type": "series", + "year": "1997–1999" + }, + { + "_id": "53677f1b847ccc8123a1b96f", + "imdb_id": "tt0841961", + "name": "Kingdom", + "type": "series", + "year": "2007–2009" + }, + { + "_id": "53677eff847ccc8123a16026", + "imdb_id": "tt0112111", + "name": "The Outer Limits", + "type": "series", + "year": "1995–2002" + }, + { + "_id": "53677f00847ccc8123a1652d", + "imdb_id": "tt0922037", + "name": "La que se avecina", + "type": "series", + "year": "2007–" + }, + { + "_id": "53677efd847ccc8123a157ab", + "imdb_id": "tt0760437", + "name": "Ben 10", + "type": "series", + "year": "2005–2008" + }, + { + "_id": "5378cbe4847ccc8123ad28f9", + "imdb_id": "tt3148266", + "name": "12 Monkeys", + "type": "series", + "year": "2015–2018" + }, + { + "_id": "55ed9310bf6c900d18414d84", + "imdb_id": "tt4307902", + "name": "The Carmichael Show", + "year": "2015–2017", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13d57", + "imdb_id": "tt0462128", + "name": "The New Adventures of Old Christine", + "type": "series", + "year": "2006–2023" + }, + { + "_id": "53677eff847ccc8123a15d07", + "imdb_id": "tt0112047", + "name": "Life with Louie", + "type": "series", + "year": "1994–1998" + }, + { + "_id": "6265215a64ec43ef98f2b152", + "imdb_id": "tt14396202", + "name": "Love After World Domination", + "type": "series", + "year": "2022" + }, + { + "_id": "54c92d1ae573cadcfa1f7701", + "imdb_id": "tt0108876", + "name": "New York Undercover", + "type": "series", + "year": "1994–2024" + }, + { + "_id": "59d2e3bd067c465210833606", + "imdb_id": "tt4396630", + "type": "series", + "name": "The Gifted", + "year": "2017–2019" + }, + { + "_id": "5f3622cb5424253341f5aa02", + "imdb_id": "tt10986410", + "name": "Ted Lasso", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "5c26d135173739c9f4bdf6b0", + "imdb_id": "tt0085109", + "name": "Webster", + "type": "series", + "year": "1983–1989" + }, + { + "_id": "60fa738a64ec43ef98f874d8", + "imdb_id": "tt10826054", + "name": "Masters of the Universe: Revelation", + "type": "series", + "year": "2021" + }, + { + "_id": "58e4edbb1635517fbf56e6b3", + "imdb_id": "tt5788792", + "name": "The Marvelous Mrs. Maisel", + "type": "series", + "year": "2017–2023" + }, + { + "_id": "54df8d65e573cadcfa1fcf3f", + "imdb_id": "tt3138604", + "name": "Thunderbirds Are Go", + "type": "series", + "year": "2015–2020" + }, + { + "_id": "53677ef9847ccc8123a13b63", + "imdb_id": "tt1796960", + "name": "Homeland", + "type": "series", + "year": "2011–2020" + }, + { + "_id": "53677f17847ccc8123a1b00b", + "imdb_id": "tt0362404", + "name": "All of Us", + "type": "series", + "year": "2003–2023" + }, + { + "_id": "5c2763aa173739c9f48c4981", + "imdb_id": "tt7537488", + "name": "Sagrada Reset", + "type": "series", + "year": "2017" + }, + { + "_id": "53677f1c847ccc8123a1bc01", + "imdb_id": "tt0112166", + "name": "The Slayers", + "type": "series", + "year": "1995–2009" + }, + { + "_id": "5bad640e173739c9f4489d7f", + "imdb_id": "tt7845644", + "name": "Single Parents", + "type": "series", + "year": "2018–2020" + }, + { + "_id": "56cff851f6aa5b2a5344a5f1", + "imdb_id": "tt4264096", + "name": "Those Who Can't", + "year": "2016–2019", + "type": "series" + }, + { + "_id": "53677efd847ccc8123a159c5", + "imdb_id": "tt0365969", + "name": "10-8: Officers on Duty", + "type": "series", + "year": "2003–2004" + }, + { + "_id": "53677f40847ccc8123a1f850", + "imdb_id": "tt0202741", + "name": "The Man Show", + "type": "series", + "year": "1999–2014" + }, + { + "_id": "5bf85dd5173739c9f4848e22", + "imdb_id": "tt7544016", + "name": "The Russell Howard Hour", + "type": "series", + "year": "2017–" + }, + { + "_id": "5f7f920654242533411fe10a", + "imdb_id": "tt12331342", + "name": "Akudama Drive", + "type": "series", + "year": "2020" + }, + { + "_id": "53677efa847ccc8123a146c6", + "imdb_id": "tt0094512", + "name": "Monsters", + "type": "series", + "year": "1988–1990" + }, + { + "_id": "5414639ca8f27b1bb90c984f", + "imdb_id": "tt3293184", + "name": "Penn Zero: Part-Time Hero", + "type": "series", + "year": "2014–2017" + }, + { + "_id": "5c4df4d8d582b25756aa9cd2", + "imdb_id": "tt0983985", + "name": "Sugar Sugar Rune", + "type": "series", + "year": "2005–2006" + }, + { + "_id": "5ec0f0605424253341cc62c0", + "imdb_id": "tt10204658", + "name": "Sing "Yesterday" for Me", + "type": "series", + "year": "2020" + }, + { + "_id": "57fdfad5d7e54929823ff840", + "imdb_id": "tt4934214", + "name": "Taskmaster", + "year": "2015–", + "type": "series" + }, + { + "_id": "53677eff847ccc8123a1612c", + "imdb_id": "tt0112197", + "name": "Timon & Pumbaa", + "type": "series", + "year": "1995–1999" + }, + { + "_id": "5bb7eeae173739c9f40b1115", + "imdb_id": "tt7134908", + "name": "Elite", + "type": "series", + "year": "2018–2024" + }, + { + "_id": "5c0ad5a1173739c9f4d5e345", + "imdb_id": "tt8019790", + "name": "Apple & Onion", + "type": "series", + "year": "2016–2021" + }, + { + "_id": "53677f07847ccc8123a18219", + "imdb_id": "tt0279570", + "name": "Love Hina", + "type": "series", + "year": "2000–2001" + }, + { + "_id": "53677f68847ccc8123a22cd5", + "imdb_id": "tt0065333", + "name": "The Partridge Family", + "type": "series", + "year": "1970–1974" + }, + { + "_id": "53677f42847ccc8123a1f8b2", + "imdb_id": "tt1402156", + "name": "The League of Super Evil", + "type": "series", + "year": "2009–2012" + }, + { + "_id": "628bc9a464ec43ef98e11256", + "imdb_id": "tt11743610", + "name": "The Terminal List", + "type": "series", + "year": "2022–" + }, + { + "_id": "5c1ff1be173739c9f46028fc", + "imdb_id": "tt0300859", + "name": "Madame Peppermint", + "type": "series", + "year": "1983–1984" + }, + { + "_id": "53677f6f847ccc8123a232ac", + "imdb_id": "tt1710310", + "name": "T.U.F.F. Puppy", + "type": "series", + "year": "2010–2015" + }, + { + "_id": "550d26b4cc9eee85bb52d8e9", + "imdb_id": "tt3520702", + "name": "Bloodline", + "year": "2015–2017", + "type": "series" + }, + { + "_id": "53677f02847ccc8123a16bdb", + "imdb_id": "tt0437043", + "name": "Untold Stories of the ER", + "type": "series", + "year": "2004–2020" + }, + { + "_id": "53677f1d847ccc8123a1bfa7", + "imdb_id": "tt0058853", + "name": "The Wednesday Play", + "type": "series", + "year": "1964–1970" + }, + { + "_id": "53677f17847ccc8123a1ab49", + "imdb_id": "tt0086730", + "name": "Highway to Heaven", + "type": "series", + "year": "1984–1989" + }, + { + "_id": "53677f13847ccc8123a1a2ff", + "imdb_id": "tt0115322", + "name": "Profiler", + "type": "series", + "year": "1996–2000" + }, + { + "_id": "53677f52847ccc8123a20fa3", + "imdb_id": "tt0166420", + "name": "Belphegor", + "type": "series", + "year": "1965" + }, + { + "_id": "53677f05847ccc8123a17c9d", + "imdb_id": "tt1674117", + "name": "Hero 108", + "type": "series", + "year": "2010–2012" + }, + { + "_id": "53677f12847ccc8123a19f5a", + "imdb_id": "tt0096725", + "name": "War and Remembrance", + "type": "series", + "year": "1988–1989" + }, + { + "_id": "53677f0a847ccc8123a1894e", + "imdb_id": "tt0985344", + "name": "Claymore", + "type": "series", + "year": "2007" + }, + { + "_id": "596c4aa11635517fbf56e947", + "imdb_id": "tt6170874", + "name": "Salvation", + "type": "series", + "year": "2017–2018" + }, + { + "_id": "53eb359ba8f27b1bb90c073b", + "imdb_id": "tt3742982", + "name": "Akame ga Kill!", + "type": "series", + "year": "2014" + }, + { + "_id": "53677efd847ccc8123a15868", + "imdb_id": "tt1491299", + "name": "Kourtney & Kim Take Miami", + "type": "series", + "year": "2009–2013" + }, + { + "_id": "53677ef9847ccc8123a13e33", + "imdb_id": "tt0866442", + "name": "Eastbound & Down", + "type": "series", + "year": "2009–2013" + }, + { + "_id": "53677ef9847ccc8123a13bc5", + "imdb_id": "tt1841108", + "name": "Femme Fatales", + "type": "series", + "year": "2011–2012" + }, + { + "_id": "53677f74847ccc8123a23660", + "imdb_id": "tt2191991", + "name": "Billy on the Street", + "type": "series", + "year": "2011–" + }, + { + "_id": "5b59111f898916810fd9ad8b", + "imdb_id": "tt6548228", + "type": "series", + "name": "Castle Rock", + "year": "2018–2019" + }, + { + "_id": "5c0bdcb2173739c9f49f6a62", + "imdb_id": "tt7833624", + "name": "Butterbean's Café", + "type": "series", + "year": "2018–2020" + }, + { + "_id": "54fdebc4711bd19c92adc317", + "imdb_id": "tt0042098", + "name": "Danger", + "year": "1950–1955", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13932", + "imdb_id": "tt1320080", + "name": "Celebrity Ghost Stories", + "type": "series", + "year": "2008–" + }, + { + "_id": "5aea4667f51dd22f67d30979", + "imdb_id": "tt7221388", + "type": "series", + "name": "Cobra Kai", + "year": "2018–2024" + }, + { + "_id": "5519963dcc9eee85bb52de1c", + "imdb_id": "tt0143007", + "name": "King of the Braves GaoGaiGar", + "year": "1997–1998", + "type": "series" + }, + { + "_id": "59ebb804067c465210283797", + "imdb_id": "tt4378376", + "type": "series", + "name": "Babylon Berlin", + "year": "2017–" + }, + { + "_id": "53677efc847ccc8123a14e71", + "imdb_id": "tt0496356", + "name": "My Boys", + "type": "series", + "year": "2006–2010" + }, + { + "_id": "53677f00847ccc8123a1618c", + "imdb_id": "tt0383795", + "name": "The Joy of Painting", + "type": "series", + "year": "1983–1994" + }, + { + "_id": "63bfef1b64ec43ef98a8de62", + "imdb_id": "tt14153790", + "name": "Velma", + "type": "series", + "year": "2023–" + }, + { + "_id": "5ff287c754242533414050ca", + "imdb_id": "tt9140632", + "name": "The Great North", + "type": "series", + "year": "2021–" + }, + { + "_id": "5bb9413e173739c9f4ee2125", + "imdb_id": "tt8690728", + "name": "Goblin Slayer", + "type": "series", + "year": "2018–" + }, + { + "_id": "57dd11dad7e54929823e232b", + "imdb_id": "tt4370596", + "name": "Better Things", + "year": "2016–2022", + "type": "series" + }, + { + "_id": "617e892d64ec43ef98d5ae94", + "imdb_id": "tt13352232", + "name": "High-Rise Invasion", + "type": "series", + "year": "2021–" + }, + { + "_id": "5c4fc1c8d582b25756eedc2c", + "imdb_id": "tt0177458", + "name": "Road Rules", + "type": "series", + "year": "1995–2007" + }, + { + "_id": "5e4d66afc4ccb5dd92751784", + "imdb_id": "tt10850932", + "name": "Crash Landing on You", + "type": "series", + "year": "2019–2020" + }, + { + "_id": "53677efd847ccc8123a15789", + "imdb_id": "tt0213338", + "name": "Cowboy Bebop", + "type": "series", + "year": "1998–1999" + }, + { + "_id": "53677ef9847ccc8123a13d6e", + "imdb_id": "tt1486217", + "name": "Archer", + "type": "series", + "year": "2009–2023" + }, + { + "_id": "53677efa847ccc8123a148d4", + "imdb_id": "tt0417373", + "name": "The Venture Bros.", + "type": "series", + "year": "2003–2018" + }, + { + "_id": "5d38b4465111f1a8a363acc4", + "imdb_id": "tt10584446", + "name": "My Life Is Murder", + "type": "series", + "year": "2019–" + }, + { + "_id": "5a155be3543165dcd828f3d2", + "imdb_id": "tt5516154", + "type": "series", + "name": "Godless", + "year": "2017" + }, + { + "_id": "56aee56bbb83c664989ea6fb", + "imdb_id": "tt3799566", + "name": "Steve Austin's Broken Skull Challenge", + "year": "2014–", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a14001", + "imdb_id": "tt0388629", + "name": "One Piece", + "type": "series", + "year": "1999–" + }, + { + "_id": "5737155b890e549c9a5b774b", + "imdb_id": "tt4488724", + "name": "Stuck in the Middle", + "year": "2016–2018", + "type": "series" + }, + { + "_id": "54ac20028527d2e0cb504a12", + "imdb_id": "tt0103369", + "name": "Sailor Moon", + "type": "series", + "year": "1992–1997" + }, + { + "_id": "5c3a014fd582b25756f15ae8", + "imdb_id": "tt1216124", + "name": "Kanokon", + "type": "series", + "year": "2008" + }, + { + "_id": "53677ef9847ccc8123a14051", + "imdb_id": "tt0092455", + "name": "Star Trek: The Next Generation", + "type": "series", + "year": "1987–1994" + }, + { + "_id": "53677f00847ccc8123a1633e", + "imdb_id": "tt0096707", + "name": "The Super Mario Bros. Super Show!", + "type": "series", + "year": "1989" + }, + { + "_id": "541463a0a8f27b1bb90c98bc", + "imdb_id": "tt0108981", + "name": "The Vicar of Dibley", + "type": "series", + "year": "1994–2020" + }, + { + "_id": "5f76f80154242533410f2729", + "imdb_id": "tt8962124", + "name": "Emily in Paris", + "type": "series", + "year": "2020–" + }, + { + "_id": "53677ef9847ccc8123a13eec", + "imdb_id": "tt0092312", + "name": "21 Jump Street", + "type": "series", + "year": "1987–1991" + }, + { + "_id": "53677efc847ccc8123a150a4", + "imdb_id": "tt0810705", + "name": "Nana", + "type": "series", + "year": "2006–2007" + }, + { + "_id": "53677f04847ccc8123a1739c", + "imdb_id": "tt0142055", + "name": "Teletubbies", + "type": "series", + "year": "1997–2001" + }, + { + "_id": "5c0b78c3173739c9f4e05c09", + "imdb_id": "tt6069250", + "name": "Uchu Sentai Kyuranger", + "type": "series", + "year": "2017–2018" + }, + { + "_id": "53677f68847ccc8123a22b02", + "imdb_id": "tt2392179", + "name": "Pac-Man and the Ghostly Adventures", + "type": "series", + "year": "2013–2016" + }, + { + "_id": "5c24e04c173739c9f428207b", + "imdb_id": "tt5330856", + "name": "Divine Gate", + "type": "series", + "year": "2016–" + }, + { + "_id": "53677ef9847ccc8123a13e62", + "imdb_id": "tt1819022", + "name": "Mrs. Brown's Boys", + "type": "series", + "year": "2011–" + }, + { + "_id": "5c1283b5173739c9f46c094a", + "imdb_id": "tt9208876", + "name": "The Falcon and the Winter Soldier", + "type": "series", + "year": "2021" + }, + { + "_id": "648af0e0bd36726cbbfc7dcb", + "imdb_id": "tt18546730", + "name": "The Walking Dead: Dead City", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677ef9847ccc8123a1387e", + "imdb_id": "tt0306414", + "name": "The Wire", + "type": "series", + "year": "2002–2008" + }, + { + "_id": "59a49aeb3e5e4b900ae85c54", + "imdb_id": "tt5540054", + "name": "The Tick", + "type": "series", + "year": "2016–2019" + }, + { + "_id": "54df8d64e573cadcfa1fceda", + "imdb_id": "tt3314218", + "name": "UnREAL", + "type": "series", + "year": "2015–2018" + }, + { + "_id": "587fc2531635517fbf569600", + "imdb_id": "tt3647998", + "name": "Taboo", + "type": "series", + "year": "2017" + }, + { + "_id": "53677efa847ccc8123a149df", + "imdb_id": "tt3489184", + "name": "Constantine", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "551bf65fcc9eee85bb52e0d7", + "imdb_id": "tt1261559", + "name": "Gemini Division", + "year": "2008", + "type": "series" + }, + { + "_id": "590066de1635517fbf56e7d0", + "imdb_id": "tt5834204", + "name": "The Handmaid's Tale", + "type": "series", + "year": "2017–" + }, + { + "_id": "5d43f812c4ccb5dd92cbad87", + "imdb_id": "tt8050740", + "name": "Amphibia", + "type": "series", + "year": "2019–2022" + }, + { + "_id": "58cf9c781635517fbf56e633", + "imdb_id": "tt5037914", + "name": "Crashing", + "type": "series", + "year": "2017–2019" + }, + { + "_id": "5c431de4d582b25756d65084", + "imdb_id": "tt1409058", + "name": "Guin sâga", + "type": "series", + "year": "2009–" + }, + { + "_id": "53677efa847ccc8123a14998", + "imdb_id": "tt1767256", + "name": "Winners & Losers", + "type": "series", + "year": "2011–2016" + }, + { + "_id": "6265ae5964ec43ef98b00d6d", + "imdb_id": "tt11639300", + "name": "Grace", + "type": "series", + "year": "2021–" + }, + { + "_id": "625fcf1964ec43ef98c5cc36", + "imdb_id": "tt12327578", + "name": "Star Trek: Strange New Worlds", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677f47847ccc8123a200a9", + "imdb_id": "tt0288918", + "name": "Big Brother's Little Brother", + "type": "series", + "year": "2001–" + }, + { + "_id": "53677ef9847ccc8123a13f2e", + "imdb_id": "tt0288937", + "name": "Degrassi: The Next Generation", + "type": "series", + "year": "2001–2015" + }, + { + "_id": "56cb645bf6aa5b2a5344447a", + "imdb_id": "tt1399664", + "name": "The Night Manager", + "year": "2016", + "type": "series" + }, + { + "_id": "53677f4f847ccc8123a20cfe", + "imdb_id": "tt0318871", + "name": "Berserk", + "type": "series", + "year": "1997–1998" + }, + { + "_id": "5c2be6c8173739c9f49b5a86", + "imdb_id": "tt1051943", + "name": "Montana Jones", + "type": "series", + "year": "1994–1995" + }, + { + "_id": "64ca97ebbd36726cbbcd7a91", + "imdb_id": "tt19869172", + "name": "My Happy Marriage", + "type": "series", + "year": "2023–" + }, + { + "_id": "617a4c3664ec43ef98391e73", + "imdb_id": "tt9795876", + "name": "Star Trek: Prodigy", + "type": "series", + "year": "2021–2024" + }, + { + "_id": "53f6326fa8f27b1bb90c33a0", + "imdb_id": "tt0062569", + "name": "Here Come the Brides", + "type": "series", + "year": "1968–1970" + }, + { + "_id": "53677f12847ccc8123a19f28", + "imdb_id": "tt0429434", + "name": "Snapped", + "type": "series", + "year": "2004–" + }, + { + "_id": "53677f51847ccc8123a20e38", + "imdb_id": "tt2392261", + "name": "The Lizzie Bennet Diaries", + "type": "series", + "year": "2012–" + }, + { + "_id": "53677f4b847ccc8123a206e5", + "imdb_id": "tt0103408", + "name": "Eek! The Cat", + "type": "series", + "year": "1992–1997" + }, + { + "_id": "5c50f9c3d582b2575690adcd", + "imdb_id": "tt6240606", + "name": "The ZhuZhus", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "5c292017173739c9f4a4d81e", + "imdb_id": "tt0353867", + "name": "Peacemakers", + "type": "series", + "year": "2003" + }, + { + "_id": "5c5b6e74d582b257565874da", + "imdb_id": "tt0199356", + "name": "Beggars and Choosers", + "type": "series", + "year": "1999–2001" + }, + { + "_id": "53677efa847ccc8123a14b0e", + "imdb_id": "tt0094540", + "name": "Roseanne", + "type": "series", + "year": "1988–2018" + }, + { + "_id": "53677f02847ccc8123a16fe3", + "imdb_id": "tt0094517", + "name": "Mystery Science Theater 3000", + "type": "series", + "year": "1988–1999" + }, + { + "_id": "53677f05847ccc8123a17703", + "imdb_id": "tt0088582", + "name": "Night Heat", + "type": "series", + "year": "1985–1989" + }, + { + "_id": "53677f35847ccc8123a1eb56", + "imdb_id": "tt0169473", + "name": "Mazinger Z", + "type": "series", + "year": "1972–1974" + }, + { + "_id": "544bbf39a8f27b1bb90d7771", + "imdb_id": "tt0092386", + "name": "Kimagure Orange Road", + "type": "series", + "year": "1985–1988" + }, + { + "_id": "5508198e711bd19c92ade389", + "imdb_id": "tt0112086", + "name": "Murder One", + "year": "1995–1997", + "type": "series" + }, + { + "_id": "6400c76864ec43ef98885fce", + "imdb_id": "tt17221100", + "name": "Kaina of the Great Snow Sea", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677ef9847ccc8123a14390", + "imdb_id": "tt0830851", + "name": "The Gadget Show", + "type": "series", + "year": "2004–2023" + }, + { + "_id": "61b0294b64ec43ef98e52524", + "imdb_id": "tt14218830", + "name": "Abbott Elementary", + "type": "series", + "year": "2021–" + }, + { + "_id": "65856b90bd36726cbb8512cd", + "imdb_id": "tt22352854", + "name": "Gyeongseong Creature", + "type": "series", + "year": "2023–" + }, + { + "_id": "54fb89e0711bd19c92ad48df", + "imdb_id": "tt3945802", + "name": "The Stanley Dynamic", + "year": "2014–2017", + "type": "series" + }, + { + "_id": "53677f40847ccc8123a1f54d", + "imdb_id": "tt0061259", + "name": "The Guns of Will Sonnett", + "type": "series", + "year": "1967–1969" + }, + { + "_id": "5baa69e2173739c9f44c244d", + "imdb_id": "tt7472896", + "name": "Mr Inbetween", + "type": "series", + "year": "2018–2021" + }, + { + "_id": "53677f05847ccc8123a17b0d", + "imdb_id": "tt0477543", + "name": "Reservoir Chronicle: Tsubasa", + "type": "series", + "year": "2005–2010" + }, + { + "_id": "53677ef9847ccc8123a138ea", + "imdb_id": "tt0054518", + "name": "The Avengers", + "type": "series", + "year": "1961–1969" + }, + { + "_id": "643d733b64ec43ef982a0ac1", + "imdb_id": "tt27489241", + "name": "Dead Mount Death Play", + "type": "series", + "year": "2023–" + }, + { + "_id": "5381e72c847ccc8123ad7692", + "imdb_id": "tt2543312", + "name": "Halt and Catch Fire", + "type": "series", + "year": "2014–2017" + }, + { + "_id": "5ec4958e5424253341b7a4b1", + "imdb_id": "tt9077540", + "name": "Sweet Magnolias", + "type": "series", + "year": "2020–" + }, + { + "_id": "53677ef9847ccc8123a1408a", + "imdb_id": "tt1759761", + "name": "Veep", + "type": "series", + "year": "2012–2019" + }, + { + "_id": "53677eff847ccc8123a1602f", + "imdb_id": "tt0279550", + "name": "Celebrity Big Brother", + "type": "series", + "year": "2001–" + }, + { + "_id": "53677ef9847ccc8123a138de", + "imdb_id": "tt0773262", + "name": "Dexter", + "type": "series", + "year": "2006–2013" + }, + { + "_id": "53677f02847ccc8123a16c29", + "imdb_id": "tt0086687", + "name": "The Cosby Show", + "type": "series", + "year": "1984–1992" + }, + { + "_id": "53677efc847ccc8123a14e55", + "imdb_id": "tt0914387", + "name": "Damages", + "type": "series", + "year": "2007–2012" + }, + { + "_id": "5c42352ed582b257565363e9", + "imdb_id": "tt0112035", + "name": "Kotikatu", + "type": "series", + "year": "1995–2012" + }, + { + "_id": "5aa8858353336c1ba87aea04", + "imdb_id": "tt6487416", + "type": "series", + "name": "Rise", + "year": "2018" + }, + { + "_id": "53677ef9847ccc8123a14196", + "imdb_id": "tt0108757", + "name": "ER", + "type": "series", + "year": "1994–2009" + }, + { + "_id": "53677efd847ccc8123a15b64", + "imdb_id": "tt1718438", + "name": "Mad", + "type": "series", + "year": "2010–2022" + }, + { + "_id": "53677efa847ccc8123a14b7d", + "imdb_id": "tt0108968", + "name": "Touched by an Angel", + "type": "series", + "year": "1994–2003" + }, + { + "_id": "53677efc847ccc8123a152ed", + "imdb_id": "tt1596561", + "name": "Spliced", + "type": "series", + "year": "2009–" + }, + { + "_id": "53677f00847ccc8123a16689", + "imdb_id": "tt0072500", + "name": "Fawlty Towers", + "type": "series", + "year": "1975–1979" + }, + { + "_id": "5c17ab98173739c9f47d6647", + "imdb_id": "tt7678620", + "name": "Bluey", + "type": "series", + "year": "2018–" + }, + { + "_id": "53677f04847ccc8123a1735b", + "imdb_id": "tt1077173", + "name": "Guns", + "type": "series", + "year": "2008–2009" + }, + { + "_id": "53677ef9847ccc8123a14231", + "imdb_id": "tt0286486", + "name": "The Shield", + "type": "series", + "year": "2002–2008" + }, + { + "_id": "53677ef9847ccc8123a14453", + "imdb_id": "tt0200276", + "name": "The West Wing", + "type": "series", + "year": "1999–2006" + }, + { + "_id": "5c19be15173739c9f43d819e", + "imdb_id": "tt6197170", + "name": "Scum's Wish", + "type": "series", + "year": "2017" + }, + { + "_id": "53677ef9847ccc8123a13864", + "imdb_id": "tt0458253", + "name": "The Closer", + "type": "series", + "year": "2005–2012" + }, + { + "_id": "5c1ed26d173739c9f46a4442", + "imdb_id": "tt0047702", + "name": "The 20th Century-Fox Hour", + "type": "series", + "year": "1955–1957" + }, + { + "_id": "5c100e8f173739c9f4f040c4", + "imdb_id": "tt2340841", + "name": "Hyouka", + "type": "series", + "year": "2012" + }, + { + "_id": "53677efd847ccc8123a159c7", + "imdb_id": "tt0062552", + "name": "Dad's Army", + "type": "series", + "year": "1968–1977" + }, + { + "_id": "536907f3847ccc8123acddfb", + "imdb_id": "tt0081869", + "name": "Gimme a Break!", + "type": "series", + "year": "1981–1987" + }, + { + "_id": "5c34af09173739c9f40071cd", + "imdb_id": "tt0078562", + "name": "Archie Bunker's Place", + "type": "series", + "year": "1979–1983" + }, + { + "_id": "5378cc0d847ccc8123ad4859", + "imdb_id": "tt3475734", + "name": "Agent Carter", + "type": "series", + "year": "2015–2016" + }, + { + "_id": "53677f0f847ccc8123a19866", + "imdb_id": "tt0455295", + "name": "Zatch Bell!", + "type": "series", + "year": "2003–2013" + }, + { + "_id": "53677f35847ccc8123a1eb50", + "imdb_id": "tt0285341", + "name": "The Bernie Mac Show", + "type": "series", + "year": "2001–2023" + }, + { + "_id": "53677f19847ccc8123a1b19e", + "imdb_id": "tt0057782", + "name": "The Rogues", + "type": "series", + "year": "1964–1965" + }, + { + "_id": "5a760a09543165dcd8b276b1", + "imdb_id": "tt6663476", + "type": "series", + "name": "Mama June: From Not to Hot", + "year": "2017–" + }, + { + "_id": "53677f00847ccc8123a16564", + "imdb_id": "tt2076610", + "name": "Project Runway All Stars", + "type": "series", + "year": "2012–" + }, + { + "_id": "5a1bf362543165dcd80fb666", + "imdb_id": "tt7230846", + "type": "series", + "name": "No Activity", + "year": "2017–2021" + }, + { + "_id": "5c0dc84e173739c9f425503b", + "imdb_id": "tt5637108", + "name": "Twin Star Exorcists", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "53677f05847ccc8123a17640", + "imdb_id": "tt1765622", + "name": "Kickin' It", + "type": "series", + "year": "2011–2015" + }, + { + "_id": "5c2e4de9173739c9f4ca53df", + "imdb_id": "tt6410184", + "name": "Triage X", + "type": "series", + "year": "2015" + }, + { + "_id": "54d4d7dde573cadcfa1fa6a8", + "imdb_id": "tt0118381", + "name": "The Last Don", + "type": "series", + "year": "1997" + }, + { + "_id": "53677f48847ccc8123a2031c", + "imdb_id": "tt2674806", + "name": "Inside No. 9", + "type": "series", + "year": "2014–" + }, + { + "_id": "54c0f5798527d2e0cb5097d7", + "imdb_id": "tt3596178", + "name": "Bella and the Bulldogs", + "type": "series", + "year": "2015–2016" + }, + { + "_id": "53677f04847ccc8123a175b7", + "imdb_id": "tt0328739", + "name": "Full Metal Panic!", + "type": "series", + "year": "2002–2006" + }, + { + "_id": "53677f05847ccc8123a17863", + "imdb_id": "tt0108970", + "name": "Tre kronor", + "type": "series", + "year": "1994–1999" + }, + { + "_id": "53677ef9847ccc8123a13a2e", + "imdb_id": "tt1599357", + "name": "The Gates", + "type": "series", + "year": "2010" + }, + { + "_id": "53677ef9847ccc8123a13b9d", + "imdb_id": "tt0955322", + "name": "Reaper", + "type": "series", + "year": "2007–2009" + }, + { + "_id": "53677efc847ccc8123a1534b", + "imdb_id": "tt2400129", + "name": "The Soul Man", + "type": "series", + "year": "2012–2016" + }, + { + "_id": "624b3e3364ec43ef98a96990", + "imdb_id": "tt11198330", + "name": "House of the Dragon", + "type": "series", + "year": "2022–" + }, + { + "_id": "5c0aa5fa173739c9f4763aba", + "imdb_id": "tt5628740", + "name": "Yu-Gi-Oh! Vrains", + "type": "series", + "year": "2017–2019" + }, + { + "_id": "56191493ec193d5e9826b2f1", + "imdb_id": "tt4662888", + "name": "WWE 24", + "year": "2015–", + "type": "series" + }, + { + "_id": "625e7db664ec43ef9852c6d6", + "imdb_id": "tt3613454", + "name": "Terror in Resonance", + "type": "series", + "year": "2014" + }, + { + "_id": "57dd11d9d7e54929823e2329", + "imdb_id": "tt4288182", + "name": "Atlanta", + "year": "2016–2022", + "type": "series" + }, + { + "_id": "611bd06964ec43ef9874bad0", + "imdb_id": "tt10862280", + "name": "Spidey and His Amazing Friends", + "type": "series", + "year": "2021–" + }, + { + "_id": "5b49b10a16f4806c2aa46351", + "imdb_id": "tt7741830", + "type": "series", + "name": "The Epic Tales of Captain Underpants", + "year": "2018–2019" + }, + { + "_id": "5c5877a8d582b25756655d6f", + "imdb_id": "tt0068148", + "name": "Wait Till Your Father Gets Home", + "type": "series", + "year": "1972–1974" + }, + { + "_id": "62469d8164ec43ef9886c4c8", + "imdb_id": "tt5875444", + "name": "Slow Horses", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677f12847ccc8123a1a14c", + "imdb_id": "tt0182629", + "name": "Rurouni Kenshin", + "type": "series", + "year": "1996–1998" + }, + { + "_id": "54c268c72cbd12081b8df483", + "imdb_id": "tt4197508", + "name": "Blunt Talk", + "type": "series", + "year": "2015–2016" + }, + { + "_id": "53677ef9847ccc8123a137cc", + "imdb_id": "tt1949012", + "name": "The Firm", + "type": "series", + "year": "2012" + }, + { + "_id": "53677f02847ccc8123a16d2b", + "imdb_id": "tt0074042", + "name": "Quincy M.E.", + "type": "series", + "year": "1976–1983" + }, + { + "_id": "53677f0e847ccc8123a19609", + "imdb_id": "tt0412148", + "name": "The Inside", + "type": "series", + "year": "2005–2006" + }, + { + "_id": "559e53f4bf6c900d1839e33e", + "imdb_id": "tt3864034", + "name": "The Spoils Before Dying", + "year": "2015", + "type": "series" + }, + { + "_id": "53677f1b847ccc8123a1b960", + "imdb_id": "tt0824043", + "name": "Mai-HiME", + "type": "series", + "year": "2004–2005" + }, + { + "_id": "53677f29847ccc8123a1def5", + "imdb_id": "tt2310212", + "name": "Mr Selfridge", + "type": "series", + "year": "2013–2016" + }, + { + "_id": "5a02ae28543165dcd8bda36c", + "imdb_id": "tt5247622", + "type": "series", + "name": "Knowing Bros", + "year": "2015–" + }, + { + "_id": "5bf1a521173739c9f4a51e55", + "imdb_id": "tt6866266", + "name": "Escape at Dannemora", + "type": "series", + "year": "2018" + }, + { + "_id": "53677efc847ccc8123a14d9b", + "imdb_id": "tt2714046", + "name": "Bad Teacher", + "type": "series", + "year": "2014" + }, + { + "_id": "53677f04847ccc8123a17466", + "imdb_id": "tt0209069", + "name": "Judging Amy", + "type": "series", + "year": "1999–2005" + }, + { + "_id": "5c3ca0d9d582b2575655dba0", + "imdb_id": "tt4197638", + "name": "India's Got Talent", + "type": "series", + "year": "2009–" + }, + { + "_id": "557f0946bf6c900d183584d1", + "imdb_id": "tt4051832", + "name": "Lovesick", + "year": "2014–2018", + "type": "series" + }, + { + "_id": "53677f08847ccc8123a18522", + "imdb_id": "tt0108954", + "name": "Tekkaman Blade", + "type": "series", + "year": "1992–" + }, + { + "_id": "64c79fe7bd36726cbb724ecf", + "imdb_id": "tt13062500", + "name": "The Walking Dead: Daryl Dixon", + "type": "series", + "year": "2023–" + }, + { + "_id": "5ba37886173739c9f4ef4268", + "imdb_id": "tt0295072", + "name": "Burger Quiz", + "type": "series", + "year": "2001–2020" + }, + { + "_id": "5cf504cf5111f1a8a3639b11", + "imdb_id": "tt8912384", + "name": "Perpetual Grace, LTD", + "type": "series", + "year": "2019" + }, + { + "_id": "5385c00a847ccc8123ad85b6", + "imdb_id": "tt0108949", + "name": "Sweet Valley High", + "type": "series", + "year": "1994–1998" + }, + { + "_id": "5c099c0a173739c9f4b11e9e", + "imdb_id": "tt7671068", + "name": "Grand Hotel", + "type": "series", + "year": "2019" + }, + { + "_id": "5b8eab8b173739c9f495d38c", + "imdb_id": "tt6149182", + "name": "Heathers", + "type": "series", + "year": "2018" + }, + { + "_id": "53677f71847ccc8123a234a7", + "imdb_id": "tt0103417", + "name": "Forever Knight", + "type": "series", + "year": "1992–1996" + }, + { + "_id": "53677efd847ccc8123a15b9c", + "imdb_id": "tt0874608", + "name": "Inspector Lewis", + "type": "series", + "year": "2006–2015" + }, + { + "_id": "5c4cc191d582b257562418df", + "imdb_id": "tt9584920", + "name": "The Quintessential Quintuplets", + "type": "series", + "year": "2019–2021" + }, + { + "_id": "5c0beb62173739c9f4be9425", + "imdb_id": "tt4958580", + "name": "Gate", + "type": "series", + "year": "2015–2016" + }, + { + "_id": "53677ef9847ccc8123a13838", + "imdb_id": "tt1592154", + "name": "Nikita", + "type": "series", + "year": "2010–2013" + }, + { + "_id": "53b176e2a8f27b1bb90b40c4", + "imdb_id": "tt0105982", + "name": "Dave's World", + "type": "series", + "year": "1993–1997" + }, + { + "_id": "5c1fc645173739c9f4044f17", + "imdb_id": "tt0111973", + "name": "Fushigi Yûgi - The Mysterious Play", + "type": "series", + "year": "1995–2002" + }, + { + "_id": "53677f42847ccc8123a1f9d4", + "imdb_id": "tt0411024", + "name": "Complete Savages", + "type": "series", + "year": "2004–2005" + }, + { + "_id": "649972fbbd36726cbb2f76ea", + "imdb_id": "tt11737520", + "name": "One Piece", + "type": "series", + "year": "2023–" + }, + { + "_id": "63118a0264ec43ef9864227f", + "imdb_id": "tt11680642", + "name": "Pantheon", + "type": "series", + "year": "2022–2023" + }, + { + "_id": "54250887a8f27b1bb90cd7a7", + "imdb_id": "tt0329938", + "name": "Transformers: Armada", + "type": "series", + "year": "2002–2003" + }, + { + "_id": "6218bc6564ec43ef98b9a2a4", + "imdb_id": "tt11311302", + "name": "Vikings: Valhalla", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677ef9847ccc8123a13815", + "imdb_id": "tt1819509", + "name": "Don't Trust the B---- in Apartment 23", + "type": "series", + "year": "2012–2013" + }, + { + "_id": "53677ef9847ccc8123a1401a", + "imdb_id": "tt0368479", + "name": "Cold Case", + "type": "series", + "year": "2003–2010" + }, + { + "_id": "5c1ec500173739c9f44f56eb", + "imdb_id": "tt0365991", + "name": "Canadian Idol", + "type": "series", + "year": "2003–" + }, + { + "_id": "5c2bcdc8173739c9f4633302", + "imdb_id": "tt1785869", + "name": "Dennis & Gnasher", + "type": "series", + "year": "2009–2013" + }, + { + "_id": "54b586208527d2e0cb506d5e", + "imdb_id": "tt0419315", + "name": "Camp Lazlo!", + "type": "series", + "year": "2005–2008" + }, + { + "_id": "53677efc847ccc8123a14f30", + "imdb_id": "tt1865769", + "name": "Jessie", + "type": "series", + "year": "2011–2015" + }, + { + "_id": "53677efa847ccc8123a1451c", + "imdb_id": "tt1783495", + "name": "NTSF:SD:SUV", + "type": "series", + "year": "2011–2013" + }, + { + "_id": "5c3d34a5d582b25756b3be0b", + "imdb_id": "tt1245698", + "name": "Birdy the Mighty Decode", + "type": "series", + "year": "2008–2009" + }, + { + "_id": "53de7d2ea8f27b1bb90bd566", + "imdb_id": "tt0179618", + "name": "The Twisted Tales of Felix the Cat", + "type": "series", + "year": "1995–1997" + }, + { + "_id": "5b9630a0173739c9f424a586", + "imdb_id": "tt7335184", + "name": "You", + "type": "series", + "year": "2018–2024" + }, + { + "_id": "58a559241635517fbf56e544", + "imdb_id": "tt5370118", + "name": "Konosuba: God's Blessing on This Wonderful World!", + "type": "series", + "year": "2016–2023" + }, + { + "_id": "558401aabf6c900d1837111d", + "imdb_id": "tt3530726", + "name": "The Astronaut Wives Club", + "year": "2015", + "type": "series" + }, + { + "_id": "53677f2c847ccc8123a1dfa5", + "imdb_id": "tt2136138", + "name": "Sofia the First", + "type": "series", + "year": "2012–2018" + }, + { + "_id": "5c243023173739c9f40f1e60", + "imdb_id": "tt1746043", + "name": "Princess Jellyfish", + "type": "series", + "year": "2010" + }, + { + "_id": "53677ef9847ccc8123a139d1", + "imdb_id": "tt0077053", + "name": "Mork & Mindy", + "type": "series", + "year": "1978–1982" + }, + { + "_id": "5c1d191b173739c9f439d540", + "imdb_id": "tt7555294", + "name": "L.A.'s Finest", + "type": "series", + "year": "2019–2020" + }, + { + "_id": "53677f05847ccc8123a1795f", + "imdb_id": "tt1583638", + "name": "Mr. Sunshine", + "type": "series", + "year": "2011–2012" + }, + { + "_id": "5c0c7488173739c9f4d16a7c", + "imdb_id": "tt0063887", + "name": "The Courtship of Eddie's Father", + "type": "series", + "year": "1969–1972" + }, + { + "_id": "53677f72847ccc8123a23629", + "imdb_id": "tt1166893", + "name": "Law & Order: UK", + "type": "series", + "year": "2009–2014" + }, + { + "_id": "53677efd847ccc8123a15a0f", + "imdb_id": "tt0251439", + "name": "Trigun", + "type": "series", + "year": "1998" + }, + { + "_id": "53677f72847ccc8123a2363d", + "imdb_id": "tt0062597", + "name": "The Outsider", + "type": "series", + "year": "1968–1969" + }, + { + "_id": "62a20c9264ec43ef98e8c5a2", + "imdb_id": "tt15830678", + "name": "Tomodachi Game", + "type": "series", + "year": "2022" + }, + { + "_id": "5c2e09af173739c9f44578a3", + "imdb_id": "tt1163573", + "name": "Mord mit Aussicht", + "type": "series", + "year": "2008–2024" + }, + { + "_id": "53677f66847ccc8123a229f7", + "imdb_id": "tt2758950", + "name": "Helix", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "5c09ffc5173739c9f46179c1", + "imdb_id": "tt4864850", + "name": "For My Man", + "type": "series", + "year": "2015–" + }, + { + "_id": "5c0aa765173739c9f478f7ac", + "imdb_id": "tt3446786", + "name": "Neste sommer", + "type": "series", + "year": "2014–" + }, + { + "_id": "53677ef9847ccc8123a1387d", + "imdb_id": "tt0383126", + "name": "MythBusters", + "type": "series", + "year": "2003–2018" + }, + { + "_id": "54b6a80a8527d2e0cb507182", + "imdb_id": "tt3526078", + "name": "Schitt's Creek", + "type": "series", + "year": "2015–2020" + }, + { + "_id": "5c1903ff173739c9f4c54d27", + "imdb_id": "tt0446584", + "name": "Ragnarok: The Animation", + "type": "series", + "year": "2003–2004" + }, + { + "_id": "53677f0a847ccc8123a18881", + "imdb_id": "tt0284770", + "name": "One on One", + "type": "series", + "year": "2001–2006" + }, + { + "_id": "53677ef9847ccc8123a13d55", + "imdb_id": "tt0787490", + "name": "Life on Mars", + "type": "series", + "year": "2008–2009" + }, + { + "_id": "53677ef9847ccc8123a141f2", + "imdb_id": "tt1661326", + "name": "Shake It Up", + "type": "series", + "year": "2010–2013" + }, + { + "_id": "5378cbf2847ccc8123ad30c0", + "imdb_id": "tt3228904", + "name": "Empire", + "type": "series", + "year": "2015–2020" + }, + { + "_id": "63b7b0ea64ec43ef98ef20ca", + "imdb_id": "tt15428778", + "name": "Mayfair Witches", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677efa847ccc8123a14be7", + "imdb_id": "tt0068098", + "name": "M*A*S*H", + "type": "series", + "year": "1972–1983" + }, + { + "_id": "57df7b29d7e54929823e4ca1", + "imdb_id": "tt0078509", + "name": "A Woman Called Moses", + "year": "1978", + "type": "series" + }, + { + "_id": "5ad2531df51dd22f67ef0332", + "imdb_id": "tt7978710", + "type": "series", + "name": "Sword Art Online Alternative: Gun Gale Online", + "year": "2018" + }, + { + "_id": "5d9170c9c4ccb5dd922f01f4", + "imdb_id": "tt9068332", + "name": "Bless the Harts", + "type": "series", + "year": "2019–2021" + }, + { + "_id": "53677f14847ccc8123a1a57c", + "imdb_id": "tt0043208", + "name": "I Love Lucy", + "type": "series", + "year": "1951–1957" + }, + { + "_id": "536907ea847ccc8123acdd6a", + "imdb_id": "tt1594381", + "name": "Team Umizoomi", + "type": "series", + "year": "2010–2015" + }, + { + "_id": "5c2d7894173739c9f460497d", + "imdb_id": "tt0075471", + "name": "ABC Weekend Specials", + "type": "series", + "year": "1977–1995" + }, + { + "_id": "63042a9964ec43ef98234285", + "imdb_id": "tt15238968", + "name": "Darby and Joan", + "type": "series", + "year": "2022–" + }, + { + "_id": "550dfc6dcc9eee85bb52d928", + "imdb_id": "tt0169477", + "name": "The New Adventures of He-Man", + "year": "1990–1991", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13dc3", + "imdb_id": "tt0491738", + "name": "Psych", + "type": "series", + "year": "2006–2014" + }, + { + "_id": "596ffb8d1635517fbf56e953", + "imdb_id": "tt6439752", + "name": "Snowfall", + "type": "series", + "year": "2017–2023" + }, + { + "_id": "53677efc847ccc8123a15150", + "imdb_id": "tt0398417", + "name": "The Batman", + "type": "series", + "year": "2004–2008" + }, + { + "_id": "53677efc847ccc8123a15294", + "imdb_id": "tt0078607", + "name": "The Dukes of Hazzard", + "type": "series", + "year": "1979–1985" + }, + { + "_id": "5c2eb01c173739c9f4937c9e", + "imdb_id": "tt0111959", + "name": "Faust", + "type": "series", + "year": "1994–1997" + }, + { + "_id": "5c55ad6bd582b25756c18e2f", + "imdb_id": "tt0493094", + "name": "Harry and His Bucket Full of Dinosaurs", + "type": "series", + "year": "2005–2008" + }, + { + "_id": "57e4f9d5d7e54929823e8bc6", + "imdb_id": "tt5672036", + "name": "Chelsea", + "year": "2016–2017", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13ca4", + "imdb_id": "tt0459159", + "name": "The Thick of It", + "type": "series", + "year": "2005–2012" + }, + { + "_id": "5c0c3a4a173739c9f463d064", + "imdb_id": "tt9251798", + "name": "Ragnarok", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "53677f19847ccc8123a1b398", + "imdb_id": "tt2122656", + "name": "Guilty Crown", + "type": "series", + "year": "2011–2012" + }, + { + "_id": "63f30a6c64ec43ef98224b91", + "imdb_id": "tt18412092", + "name": "The Company You Keep", + "type": "series", + "year": "2023" + }, + { + "_id": "5c2e5c13173739c9f4e5be26", + "imdb_id": "tt0442722", + "name": "The Doodlebops", + "type": "series", + "year": "2004–2007" + }, + { + "_id": "5c09c19d173739c9f4fd4232", + "imdb_id": "tt5475704", + "name": "Dream Corp LLC", + "type": "series", + "year": "2016–" + }, + { + "_id": "53677ef9847ccc8123a13cf1", + "imdb_id": "tt0904208", + "name": "Californication", + "type": "series", + "year": "2007–2014" + }, + { + "_id": "5bfff84b173739c9f4fd71f5", + "imdb_id": "tt7817930", + "name": "Ruyi's Royal Love in the Palace", + "type": "series", + "year": "2018" + }, + { + "_id": "5c454a5cd582b25756396d21", + "imdb_id": "tt7186588", + "type": "series", + "name": "I Am the Night", + "year": "2019" + }, + { + "_id": "5368e83b847ccc8123acdbfd", + "imdb_id": "tt0809815", + "name": "Tenjo Tenge", + "type": "series", + "year": "2004" + }, + { + "_id": "64c79fe7bd36726cbb724ed0", + "imdb_id": "tt13159924", + "name": "Gen V", + "type": "series", + "year": "2023–" + }, + { + "_id": "5c1a78de173739c9f48ae3e7", + "imdb_id": "tt0101133", + "name": "Lightning Force", + "type": "series", + "year": "1991–1992" + }, + { + "_id": "5c57674fd582b257562842d4", + "imdb_id": "tt0062567", + "name": "The Good Guys", + "type": "series", + "year": "1968–1970" + }, + { + "_id": "62a772e064ec43ef9873f5cb", + "imdb_id": "tt13443470", + "name": "Wednesday", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677efa847ccc8123a14b00", + "imdb_id": "tt0380136", + "name": "QI", + "type": "series", + "year": "2003–" + }, + { + "_id": "5c438a57d582b2575624cada", + "imdb_id": "tt9532342", + "name": "Layton Mystery Tanteisha: Katori no Nazotoki File", + "type": "series", + "year": "2018–2019" + }, + { + "_id": "53677efc847ccc8123a15103", + "imdb_id": "tt1408430", + "name": "30 for 30", + "type": "series", + "year": "2009–" + }, + { + "_id": "53677ef9847ccc8123a13b96", + "imdb_id": "tt1199099", + "name": "Merlin", + "type": "series", + "year": "2008–2012" + }, + { + "_id": "53677f0f847ccc8123a19779", + "imdb_id": "tt0098784", + "name": "E.N.G.", + "type": "series", + "year": "1989–1994" + }, + { + "_id": "5c220f57173739c9f4fc2fe4", + "imdb_id": "tt4302062", + "name": "Paradise City", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677f0c847ccc8123a19383", + "imdb_id": "tt0352110", + "name": "TV Burp", + "type": "series", + "year": "2001–2012" + }, + { + "_id": "54b6a80a8527d2e0cb50717c", + "imdb_id": "tt2348803", + "name": "Kuroko's Basketball", + "type": "series", + "year": "2012–2015" + }, + { + "_id": "5c0be707173739c9f4b5800f", + "imdb_id": "tt0341985", + "name": "Ultimate Muscle: The Kinnikuman Legacy", + "type": "series", + "year": "2002–2004" + }, + { + "_id": "5902ef561635517fbf56e839", + "imdb_id": "tt5707802", + "name": "Dear White People", + "type": "series", + "year": "2017–2021" + }, + { + "_id": "5e74795dc4ccb5dd92bbc13c", + "imdb_id": "tt6157190", + "name": "Dr. Romantic", + "type": "series", + "year": "2016–2023" + }, + { + "_id": "6127999364ec43ef98bdfdc1", + "imdb_id": "tt12882132", + "name": "Hitori No Shita - The Outcast", + "type": "series", + "year": "2015–2023" + }, + { + "_id": "53677f26847ccc8123a1d9db", + "imdb_id": "tt1124358", + "name": "Yattâman", + "type": "series", + "year": "2008–" + }, + { + "_id": "53677f2c847ccc8123a1e136", + "imdb_id": "tt2401525", + "name": "Upper Middle Bogan", + "type": "series", + "year": "2013–2016" + }, + { + "_id": "5c3eeda0d582b25756857f5e", + "imdb_id": "tt6511722", + "name": "School of Roars", + "type": "series", + "year": "2017–" + }, + { + "_id": "5c437259d582b25756077f06", + "imdb_id": "tt0112028", + "name": "Saint Tail", + "type": "series", + "year": "1995–1996" + }, + { + "_id": "53677f22847ccc8123a1cbc8", + "imdb_id": "tt0092469", + "name": "The Tracey Ullman Show", + "type": "series", + "year": "1987–1990" + }, + { + "_id": "548061988527d2e0cb4fc358", + "imdb_id": "tt3061830", + "name": "Togetherness", + "type": "series", + "year": "2015–2016" + }, + { + "_id": "5432dae8a8f27b1bb90d0ce0", + "imdb_id": "tt2699110", + "name": "The Affair", + "type": "series", + "year": "2014–2019" + }, + { + "_id": "553019c0cc9eee85bb52e4a9", + "imdb_id": "tt3895150", + "name": "Your Lie in April", + "year": "2014–2018", + "type": "series" + }, + { + "_id": "53677f47847ccc8123a20027", + "imdb_id": "tt0499383", + "name": "Dancing on Ice", + "type": "series", + "year": "2006–" + }, + { + "_id": "53677f0e847ccc8123a19593", + "imdb_id": "tt0092357", + "name": "Friday the 13th: The Series", + "type": "series", + "year": "1987–1990" + }, + { + "_id": "5c23c6fb173739c9f432606d", + "imdb_id": "tt9140108", + "name": "Carol's Second Act", + "type": "series", + "year": "2019–2020" + }, + { + "_id": "6066d0895424253341d04d4a", + "imdb_id": "tt12502782", + "name": "Shaman King", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "5c167948173739c9f47e790e", + "imdb_id": "tt0118378", + "name": "Coast Guard", + "type": "series", + "year": "1997–2016" + }, + { + "_id": "53677f08847ccc8123a18496", + "imdb_id": "tt0978553", + "name": "The Familiar of Zero", + "type": "series", + "year": "2006" + }, + { + "_id": "55199655cc9eee85bb52de33", + "imdb_id": "tt0813711", + "name": "Guy's Big Bite", + "year": "2006–", + "type": "series" + }, + { + "_id": "53677f03847ccc8123a17295", + "imdb_id": "tt1159996", + "name": "Less Than Kind", + "type": "series", + "year": "2008–2013" + }, + { + "_id": "62ff34f864ec43ef98baef8f", + "imdb_id": "tt21230432", + "name": "The Yakuza's Guide to Babysitting", + "type": "series", + "year": "2022" + }, + { + "_id": "53677f1b847ccc8123a1b7cd", + "imdb_id": "tt0111970", + "name": "Freakazoid!", + "type": "series", + "year": "1995–1997" + }, + { + "_id": "5c19be45173739c9f43ddcc4", + "imdb_id": "tt1356884", + "name": "White Album", + "type": "series", + "year": "2009" + }, + { + "_id": "53677ef9847ccc8123a137b4", + "imdb_id": "tt1475582", + "name": "Sherlock", + "type": "series", + "year": "2010–2017" + }, + { + "_id": "5c149a08173739c9f42d933d", + "imdb_id": "tt8819906", + "name": "Love Island", + "type": "series", + "year": "2019–" + }, + { + "_id": "54f9481f711bd19c92accdbd", + "imdb_id": "tt0235916", + "name": "ChalkZone", + "year": "2002–2009", + "type": "series" + }, + { + "_id": "53677f0f847ccc8123a19c0f", + "imdb_id": "tt3158246", + "name": "Space Dandy", + "type": "series", + "year": "2014" + }, + { + "_id": "53677efa847ccc8123a14cfc", + "imdb_id": "tt0118276", + "name": "Buffy the Vampire Slayer", + "type": "series", + "year": "1997–2003" + }, + { + "_id": "5991bd823e5e4b900ae85c2f", + "imdb_id": "tt6315640", + "name": "Atypical", + "type": "series", + "year": "2017–2021" + }, + { + "_id": "5c294be8173739c9f4007bab", + "imdb_id": "tt0056778", + "name": "The Patty Duke Show", + "type": "series", + "year": "1963–1966" + }, + { + "_id": "53677f40847ccc8123a1f7f9", + "imdb_id": "tt0062601", + "name": "Rowan & Martin's Laugh-In", + "type": "series", + "year": "1967–1973" + }, + { + "_id": "53677f07847ccc8123a18109", + "imdb_id": "tt0173548", + "name": "Fort Boyard", + "type": "series", + "year": "1990–" + }, + { + "_id": "64e5c0fcbd36726cbb4e9cdf", + "imdb_id": "tt0101223", + "name": "The Torkelsons", + "type": "series", + "year": "1991–1992" + }, + { + "_id": "53677ef9847ccc8123a144d8", + "imdb_id": "tt1843323", + "name": "Up All Night", + "type": "series", + "year": "2011–2012" + }, + { + "_id": "5c3f388ad582b25756a557f0", + "imdb_id": "tt5839706", + "name": "91 Days", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "59b920671712e0f4dd96a361", + "imdb_id": "tt6483836", + "type": "series", + "name": "Gone", + "year": "2017–" + }, + { + "_id": "60e03d5264ec43ef984b13c3", + "imdb_id": "tt14664414", + "name": "Young Royals", + "type": "series", + "year": "2021–" + }, + { + "_id": "5576e6b9bf6c900d183543ba", + "imdb_id": "tt4324796", + "name": "Odd Mom Out", + "year": "2015–2017", + "type": "series" + }, + { + "_id": "53677f79847ccc8123a23c4e", + "imdb_id": "tt3451870", + "name": "Captain Earth", + "type": "series", + "year": "2014" + }, + { + "_id": "5c1f90f1173739c9f49a0423", + "imdb_id": "tt2321542", + "name": "Love, Chunibyo & Other Delusions", + "type": "series", + "year": "2012–2014" + }, + { + "_id": "5c0db4e4173739c9f40c9c1d", + "imdb_id": "tt0111890", + "name": "Band of Gold", + "type": "series", + "year": "1995–1997" + }, + { + "_id": "5c4dc4a9d582b2575663d9c6", + "imdb_id": "tt0074072", + "name": "When the Boat Comes In", + "type": "series", + "year": "1976–1981" + }, + { + "_id": "53677f0f847ccc8123a19a67", + "imdb_id": "tt0184111", + "name": "Ed, Edd n Eddy", + "type": "series", + "year": "1999–2008" + }, + { + "_id": "53677f40847ccc8123a1f78f", + "imdb_id": "tt0105943", + "name": "As Time Goes By", + "type": "series", + "year": "1992–2005" + }, + { + "_id": "53677f66847ccc8123a229e8", + "imdb_id": "tt0054557", + "name": "Mister Ed", + "type": "series", + "year": "1961–1966" + }, + { + "_id": "5c2eae41173739c9f48fcaca", + "imdb_id": "tt8948436", + "name": "Douluo Dalu", + "type": "series", + "year": "2018–2023" + }, + { + "_id": "53677f29847ccc8123a1deac", + "imdb_id": "tt0118346", + "name": "The Hunger", + "type": "series", + "year": "1997–2000" + }, + { + "_id": "55075d64711bd19c92addcb7", + "imdb_id": "tt1690397", + "name": "Tomorrow's Joe", + "year": "1970–1971", + "type": "series" + }, + { + "_id": "5c0fd7ea173739c9f4847f0d", + "imdb_id": "tt0813971", + "name": "Witchblade", + "type": "series", + "year": "2006" + }, + { + "_id": "5c1c5905173739c9f4033f84", + "imdb_id": "tt0429363", + "name": "Get Backers", + "type": "series", + "year": "2002–2003" + }, + { + "_id": "55072f75711bd19c92add860", + "imdb_id": "tt0437700", + "name": "America's Test Kitchen", + "year": "2000–", + "type": "series" + }, + { + "_id": "5feccde954242533410dae8c", + "imdb_id": "tt10723804", + "name": "A Miracle", + "type": "series", + "year": "2019–2021" + }, + { + "_id": "53677f5b847ccc8123a21d01", + "imdb_id": "tt1409066", + "name": "#DUPE#", + "type": "series", + "year": "2008–2015" + }, + { + "_id": "5c13ac0d173739c9f475cc7f", + "imdb_id": "tt0928099", + "name": "Nodame kantâbire", + "type": "series", + "year": "2007–2010" + }, + { + "_id": "5381e72c847ccc8123ad7670", + "imdb_id": "tt1882240", + "name": "Beelzebub", + "type": "series", + "year": "2011–2012" + }, + { + "_id": "5aba43b8e0a43c01da06652e", + "imdb_id": "tt7651892", + "type": "series", + "name": "One Strange Rock", + "year": "2018" + }, + { + "_id": "5c1fc86d173739c9f408a74f", + "imdb_id": "tt1514753", + "name": "Three Kingdoms", + "type": "series", + "year": "2010–" + }, + { + "_id": "53677ef9847ccc8123a14195", + "imdb_id": "tt1596356", + "name": "Hellcats", + "type": "series", + "year": "2010–2011" + }, + { + "_id": "5c33d7fb173739c9f4b61bcd", + "imdb_id": "tt0062561", + "name": "The First Lady", + "type": "series", + "year": "1968–1969" + }, + { + "_id": "60e62bbc64ec43ef98002f1d", + "imdb_id": "tt13311344", + "name": "Tsukimichi: Moonlit Fantasy", + "type": "series", + "year": "2021–2024" + }, + { + "_id": "5a782e79543165dcd8429908", + "imdb_id": "tt5249462", + "type": "series", + "name": "Erased", + "year": "2016" + }, + { + "_id": "53677efc847ccc8123a14f7b", + "imdb_id": "tt0061263", + "name": "The High Chaparral", + "type": "series", + "year": "1967–1971" + }, + { + "_id": "5c24f408173739c9f44fd21a", + "imdb_id": "tt7462410", + "name": "The Wheel of Time", + "type": "series", + "year": "2021–" + }, + { + "_id": "6334956a64ec43ef98ee120f", + "imdb_id": "tt21958588", + "name": "Cake Week", + "type": "series", + "year": "2022" + }, + { + "_id": "5b42b71916f4806c2aadc7b8", + "imdb_id": "tt2649356", + "type": "series", + "name": "Sharp Objects", + "year": "2018" + }, + { + "_id": "61b474c564ec43ef98ce444f", + "imdb_id": "tt15790598", + "name": "Queen of the Universe", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "63aaf2a764ec43ef98d28193", + "imdb_id": "tt22443832", + "name": "Arknights: Prelude to Dawn", + "type": "series", + "year": "2022" + }, + { + "_id": "55e3faf2bf6c900d18409c15", + "imdb_id": "tt4481322", + "name": "The Grinder", + "year": "2015–2016", + "type": "series" + }, + { + "_id": "53677f37847ccc8123a1ec0a", + "imdb_id": "tt0098888", + "name": "Parker Lewis Can't Lose", + "type": "series", + "year": "1990–1993" + }, + { + "_id": "53677ef9847ccc8123a13ed6", + "imdb_id": "tt1720601", + "name": "The Real Housewives of Beverly Hills", + "type": "series", + "year": "2010–" + }, + { + "_id": "53677efd847ccc8123a159b7", + "imdb_id": "tt1625724", + "name": "Love/Hate", + "type": "series", + "year": "2010–2014" + }, + { + "_id": "53677ef9847ccc8123a13a5f", + "imdb_id": "tt0898266", + "name": "The Big Bang Theory", + "type": "series", + "year": "2007–2019" + }, + { + "_id": "5f8429c05424253341c17b1b", + "imdb_id": "tt10970552", + "type": "series", + "name": "The Haunting of Bly Manor", + "year": "2020" + }, + { + "_id": "5c1c6981173739c9f4176f7a", + "imdb_id": "tt0103434", + "name": "Gute Zeiten, schlechte Zeiten", + "type": "series", + "year": "1992–" + }, + { + "_id": "5c378179d582b257568cb53b", + "imdb_id": "tt2450588", + "name": "Football Night in America", + "type": "series", + "year": "2006–" + }, + { + "_id": "53677efc847ccc8123a1542a", + "imdb_id": "tt0386180", + "name": "Drawn Together", + "type": "series", + "year": "2004–2007" + }, + { + "_id": "5c0c2075173739c9f42b3bc9", + "imdb_id": "tt3390892", + "name": "The Last Tycoon", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "53677f05847ccc8123a17cc9", + "imdb_id": "tt0068135", + "name": "The Streets of San Francisco", + "type": "series", + "year": "1972–1977" + }, + { + "_id": "55271a0acc9eee85bb52e275", + "imdb_id": "tt0163929", + "name": "Blue's Clues", + "year": "1995–2007", + "type": "series" + }, + { + "_id": "5c48f0abd582b2575608abe3", + "imdb_id": "tt0260662", + "name": "The Zeta Project", + "type": "series", + "year": "2001–2003" + }, + { + "_id": "55fb4ec4bf6c900d18422fa4", + "imdb_id": "tt4671682", + "name": "Ties That Bind", + "year": "2015", + "type": "series" + }, + { + "_id": "5c1a83d5173739c9f4a090cc", + "imdb_id": "tt0181255", + "name": "So Graham Norton", + "type": "series", + "year": "1998–2002" + }, + { + "_id": "5c1db6ae173739c9f4675782", + "imdb_id": "tt5141800", + "name": "Nirvana in Fire", + "type": "series", + "year": "2015–2018" + }, + { + "_id": "53677f0a847ccc8123a18784", + "imdb_id": "tt0294023", + "name": "Captain Tsubasa", + "type": "series", + "year": "1983–1995" + }, + { + "_id": "5c16b5ee173739c9f4fd1d12", + "imdb_id": "tt2531336", + "name": "Lupin", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677ef9847ccc8123a14386", + "imdb_id": "tt0133302", + "name": "Frontline", + "type": "series", + "year": "1983–" + }, + { + "_id": "53677f60847ccc8123a22377", + "imdb_id": "tt0159933", + "name": "Ronin Warriors", + "type": "series", + "year": "1988–1995" + }, + { + "_id": "55f2e4cabf6c900d18419b7e", + "imdb_id": "tt3787754", + "name": "Total Drama Presents: The Ridonculous Race", + "year": "2015", + "type": "series" + }, + { + "_id": "53677f1d847ccc8123a1be5d", + "imdb_id": "tt0098957", + "name": "Zorro", + "type": "series", + "year": "1990–1993" + }, + { + "_id": "53677f32847ccc8123a1e737", + "imdb_id": "tt0048848", + "name": "Broken Arrow", + "type": "series", + "year": "1956–1958" + }, + { + "_id": "5c416e51d582b25756f0af19", + "imdb_id": "tt0285371", + "name": "Heathcliff & the Catillac Cats", + "type": "series", + "year": "1984–1987" + }, + { + "_id": "5c434df7d582b25756f1af27", + "imdb_id": "tt0074002", + "name": "3000 Leagues in Search of Mother", + "type": "series", + "year": "1976" + }, + { + "_id": "53677f0a847ccc8123a18ca9", + "imdb_id": "tt1441480", + "name": "AIBOU: Tokyo Detective Duo", + "type": "series", + "year": "2000–" + }, + { + "_id": "53677ef9847ccc8123a13b7b", + "imdb_id": "tt0096563", + "name": "Cops", + "type": "series", + "year": "1989–2023" + }, + { + "_id": "53677f02847ccc8123a16948", + "imdb_id": "tt0441059", + "name": "Kaamelott", + "type": "series", + "year": "2004–2009" + }, + { + "_id": "5c18e870173739c9f491fc37", + "imdb_id": "tt6369836", + "name": "Documental", + "type": "series", + "year": "2016–" + }, + { + "_id": "5c0a6af1173739c9f4063006", + "imdb_id": "tt6601082", + "name": "Rise of the Teenage Mutant Ninja Turtles", + "type": "series", + "year": "2018–2020" + }, + { + "_id": "55a20f7dbf6c900d183a6ae5", + "imdb_id": "tt4192782", + "name": "Glitch", + "year": "2015–2019", + "type": "series" + }, + { + "_id": "5c0b5cd6173739c9f4bfdf88", + "imdb_id": "tt7736544", + "type": "series", + "name": "3Below: Tales of Arcadia", + "year": "2018–2019" + }, + { + "_id": "53677efd847ccc8123a1587a", + "imdb_id": "tt0115167", + "name": "Everybody Loves Raymond", + "type": "series", + "year": "1996–2005" + }, + { + "_id": "5c26bceb173739c9f49706e9", + "imdb_id": "tt0181923", + "name": "The Great Grape Ape Show", + "type": "series", + "year": "1975" + }, + { + "_id": "620d37a364ec43ef9858eafc", + "imdb_id": "tt14599438", + "name": "Jeen-yuhs: A Kanye Trilogy", + "type": "series", + "year": "2022" + }, + { + "_id": "5c107ca3173739c9f4d1f9b9", + "imdb_id": "tt0456029", + "name": "Blue Water High", + "type": "series", + "year": "2005–2008" + }, + { + "_id": "53677f1a847ccc8123a1b6bf", + "imdb_id": "tt0050069", + "name": "Tombstone Territory", + "type": "series", + "year": "1957–1960" + }, + { + "_id": "54fb5f68711bd19c92ad45ac", + "imdb_id": "tt1458518", + "name": "Olivia", + "year": "2009–2015", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13c56", + "imdb_id": "tt0772137", + "name": "The Game", + "type": "series", + "year": "2006–2015" + }, + { + "_id": "5c0f1a52173739c9f45a1bc3", + "imdb_id": "tt5502900", + "name": "The Real Marigold Hotel", + "type": "series", + "year": "2016–" + }, + { + "_id": "5a212b53543165dcd8f53dfe", + "imdb_id": "tt5753856", + "type": "series", + "name": "Dark", + "year": "2017–2020" + }, + { + "_id": "53677eff847ccc8123a16006", + "imdb_id": "tt2104664", + "name": "The Heart, She Holler", + "type": "series", + "year": "2011–2014" + }, + { + "_id": "5c0a00c9173739c9f4636a62", + "imdb_id": "tt9288848", + "name": "Pacific Rim: The Black", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "53677efc847ccc8123a15205", + "imdb_id": "tt0085017", + "name": "Fraggle Rock", + "type": "series", + "year": "1983–1987" + }, + { + "_id": "5c0ef165173739c9f40bb65d", + "imdb_id": "tt6928178", + "name": "Monster High", + "type": "series", + "year": "2010–2017" + }, + { + "_id": "611f3a9464ec43ef981f7cdb", + "imdb_id": "tt13851952", + "name": "The Aquatope on White Sand", + "type": "series", + "year": "2021–" + }, + { + "_id": "620fa3cc64ec43ef9817de45", + "imdb_id": "tt10611608", + "name": "The Cuphead Show!", + "type": "series", + "year": "2022" + }, + { + "_id": "5c427ef4d582b257567ff007", + "imdb_id": "tt1050880", + "name": "George of the Jungle", + "type": "series", + "year": "2007–2008" + }, + { + "_id": "5c28184f173739c9f4f57c52", + "imdb_id": "tt0081837", + "name": "Bret Maverick", + "type": "series", + "year": "1981–1982" + }, + { + "_id": "59b043451712e0f4dd1febb9", + "imdb_id": "tt6688750", + "name": "Puppy Dog Pals", + "year": "2017–2023", + "type": "series" + }, + { + "_id": "53677f4f847ccc8123a20b3c", + "imdb_id": "tt0287196", + "name": "Big Brother", + "type": "series", + "year": "2001–2023" + }, + { + "_id": "5a7df30b543165dcd8032284", + "imdb_id": "tt7948268", + "type": "series", + "name": "Celebrity Big Brother", + "year": "2018–" + }, + { + "_id": "56f4c9aff6aa5b2a534758a6", + "imdb_id": "tt5127574", + "name": "LEGO Nexo Knights", + "year": "2015–2017", + "type": "series" + }, + { + "_id": "5c109d43173739c9f4039677", + "imdb_id": "tt1831804", + "name": "The Stand", + "type": "series", + "year": "2020–2021" + }, + { + "_id": "53677efd847ccc8123a1592e", + "imdb_id": "tt1114705", + "name": "Celebrity Rehab with Dr. Drew", + "type": "series", + "year": "2008–" + }, + { + "_id": "5c164d8e173739c9f426567e", + "imdb_id": "tt7380366", + "name": "True Lies", + "type": "series", + "year": "2023" + }, + { + "_id": "65229026bd36726cbbb2f6c7", + "imdb_id": "tt28776190", + "name": "Shangri-La Frontier", + "type": "series", + "year": "2023" + }, + { + "_id": "61b86ba964ec43ef9883a208", + "imdb_id": "tt11717610", + "name": "American Auto", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "53677eff847ccc8123a15cac", + "imdb_id": "tt0154094", + "name": "Where the Heart Is", + "type": "series", + "year": "1997–2006" + }, + { + "_id": "5c3f8096d582b25756cf2c1d", + "imdb_id": "tt0083431", + "name": "It Takes Two", + "type": "series", + "year": "1982–1983" + }, + { + "_id": "5c5a0958d582b257567acc88", + "imdb_id": "tt0115283", + "name": "The Mystery Files of Shelby Woo", + "type": "series", + "year": "1996–1999" + }, + { + "_id": "568fc86abb83c664989bf6f0", + "imdb_id": "tt1051220", + "name": "The Shannara Chronicles", + "year": "2016–2017", + "type": "series" + }, + { + "_id": "53677f3a847ccc8123a1ef1b", + "imdb_id": "tt0426711", + "name": "Hikaru no Go", + "type": "series", + "year": "2001–2003" + }, + { + "_id": "53d3d591a8f27b1bb90badd1", + "imdb_id": "tt0096543", + "name": "Beetlejuice", + "type": "series", + "year": "1989–1991" + }, + { + "_id": "6066b45354242533419fd683", + "imdb_id": "tt11116204", + "name": "United States of Al", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "5c21b80d173739c9f47cbf6a", + "imdb_id": "tt8060322", + "name": "Littlest Pet Shop: A World of Our Own", + "type": "series", + "year": "2017–" + }, + { + "_id": "6568f159bd36726cbbb2e72b", + "imdb_id": "tt22485826", + "name": "Bookie", + "type": "series", + "year": "2023–" + }, + { + "_id": "5c42f698d582b25756bcc78b", + "imdb_id": "tt2800436", + "name": "The Laughing Salesman", + "type": "series", + "year": "1989–1992" + }, + { + "_id": "53677f1c847ccc8123a1bc87", + "imdb_id": "tt1985299", + "name": "Bade Achhe Lagte Hain", + "type": "series", + "year": "2011–2014" + }, + { + "_id": "5c0c7810173739c9f4d628a0", + "imdb_id": "tt0115372", + "name": "The Steve Harvey Show", + "type": "series", + "year": "1996–2002" + }, + { + "_id": "53677f04847ccc8123a17369", + "imdb_id": "tt0460651", + "name": "Invasion", + "type": "series", + "year": "2005–2006" + }, + { + "_id": "5c155b7a173739c9f48fc2b1", + "imdb_id": "tt0276732", + "name": "State of Grace", + "type": "series", + "year": "2001–2004" + }, + { + "_id": "53677f0e847ccc8123a1959c", + "imdb_id": "tt2326517", + "name": "Finding Your Roots with Henry Louis Gates, Jr.", + "type": "series", + "year": "2012–" + }, + { + "_id": "5c23de90173739c9f4630636", + "imdb_id": "tt8496508", + "name": "The Heights", + "type": "series", + "year": "2019–2020" + }, + { + "_id": "5c409e8ed582b257567ee469", + "imdb_id": "tt1291491", + "name": "Princess Resurrection", + "type": "series", + "year": "2007–2008" + }, + { + "_id": "53677f05847ccc8123a17674", + "imdb_id": "tt0235119", + "name": "Casshern Sins", + "type": "series", + "year": "2008–2009" + }, + { + "_id": "5924c2ee1635517fbf56e872", + "imdb_id": "tt5650650", + "name": "Jamestown", + "type": "series", + "year": "2017–2019" + }, + { + "_id": "542d1637a8f27b1bb90cf467", + "imdb_id": "tt0056752", + "name": "The Doctors", + "type": "series", + "year": "1963–1982" + }, + { + "_id": "53677f74847ccc8123a2385f", + "imdb_id": "tt0068072", + "name": "Fat Albert and the Cosby Kids", + "type": "series", + "year": "1972–1985" + }, + { + "_id": "5c290dfe173739c9f47e88a4", + "imdb_id": "tt2360110", + "name": "Senran Kagura: Ninja Flash!", + "type": "series", + "year": "2013" + }, + { + "_id": "53677f0c847ccc8123a19260", + "imdb_id": "tt0075525", + "name": "The Life and Times of Grizzly Adams", + "type": "series", + "year": "1977–1978" + }, + { + "_id": "5c113304173739c9f4045aea", + "imdb_id": "tt6932244", + "name": "Hanna", + "type": "series", + "year": "2019–2021" + }, + { + "_id": "5c40fcd5d582b25756b598dd", + "imdb_id": "tt8129446", + "name": "Lights Out with David Spade", + "type": "series", + "year": "2019–" + }, + { + "_id": "649ac498bd36726cbbe2393f", + "imdb_id": "tt26693803", + "name": "King the Land", + "type": "series", + "year": "2023–" + }, + { + "_id": "5378cc0e847ccc8123ad48f5", + "imdb_id": "tt3484406", + "name": "The Jim Gaffigan Show", + "type": "series", + "year": "2015–2016" + }, + { + "_id": "53677f29847ccc8123a1dc22", + "imdb_id": "tt0084987", + "name": "The Bill", + "type": "series", + "year": "1984–2010" + }, + { + "_id": "53677f35847ccc8123a1eb73", + "imdb_id": "tt1524993", + "name": "Dinosaur King", + "type": "series", + "year": "2007–2009" + }, + { + "_id": "53677f0a847ccc8123a189fa", + "imdb_id": "tt0208614", + "name": "Celebrity Deathmatch", + "type": "series", + "year": "1998–2007" + }, + { + "_id": "56904d99bb83c664989c0e19", + "imdb_id": "tt3323254", + "name": "Bordertown", + "year": "2016", + "type": "series" + }, + { + "_id": "53677f02847ccc8123a16bfb", + "imdb_id": "tt2733252", + "name": "The Musketeers", + "type": "series", + "year": "2014–2016" + }, + { + "_id": "53677ef5847ccc8123a1376b", + "imdb_id": "tt1059475", + "name": "Flashpoint", + "type": "series", + "year": "2008–2012" + }, + { + "_id": "55d78a85bf6c900d183f3518", + "imdb_id": "tt1152296", + "name": "Who Do You Think You Are?", + "year": "2008–", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a137bb", + "imdb_id": "tt1119644", + "name": "Fringe", + "type": "series", + "year": "2008–2013" + }, + { + "_id": "53677f32847ccc8123a1e851", + "imdb_id": "tt0063948", + "name": "Room 222", + "type": "series", + "year": "1969–1974" + }, + { + "_id": "53677f13847ccc8123a1a21a", + "imdb_id": "tt1349600", + "name": "Les petits meurtres d'Agatha Christie", + "type": "series", + "year": "2009–" + }, + { + "_id": "5bc6fe2f173739c9f44a5296", + "imdb_id": "tt3600266", + "name": "Super Wings!", + "type": "series", + "year": "2015–" + }, + { + "_id": "53677f0a847ccc8123a18a8f", + "imdb_id": "tt0115369", + "name": "Spin City", + "type": "series", + "year": "1996–2002" + }, + { + "_id": "617143fd64ec43ef98dd3dea", + "imdb_id": "tt14626352", + "name": "Komi Can't Communicate", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "53677f00847ccc8123a163f0", + "imdb_id": "tt0426371", + "name": "The Suite Life of Zack & Cody", + "type": "series", + "year": "2005–2008" + }, + { + "_id": "5c27f363173739c9f4a9b721", + "imdb_id": "tt0353048", + "name": "Champs-Elysées", + "type": "series", + "year": "1982–2013" + }, + { + "_id": "53677f68847ccc8123a22d10", + "imdb_id": "tt2222352", + "name": "Cuckoo", + "type": "series", + "year": "2012–" + }, + { + "_id": "53677f07847ccc8123a182e8", + "imdb_id": "tt0460673", + "name": "Rock Star: INXS", + "type": "series", + "year": "2005–" + }, + { + "_id": "5c44fa01d582b25756e2eda4", + "imdb_id": "tt0168371", + "name": "Romeo and the Black Brothers", + "type": "series", + "year": "1995" + }, + { + "_id": "5e71cf1ac4ccb5dd929f752a", + "imdb_id": "tt8610082", + "name": "Monsters at Work", + "type": "series", + "year": "2021–" + }, + { + "_id": "63204e2264ec43ef98f5400a", + "imdb_id": "tt12590266", + "name": "Cyberpunk: Edgerunners", + "type": "series", + "year": "2022" + }, + { + "_id": "53677f18847ccc8123a1b039", + "imdb_id": "tt0476918", + "name": "Loonatics Unleashed", + "type": "series", + "year": "2005–2007" + }, + { + "_id": "61262afd64ec43ef98951129", + "imdb_id": "tt7797662", + "name": "One Room", + "type": "series", + "year": "2017–2020" + }, + { + "_id": "6016ffc35424253341c968bb", + "imdb_id": "tt13186542", + "name": "Kemono Jihen", + "type": "series", + "year": "2021" + }, + { + "_id": "54ac200f8527d2e0cb504c19", + "imdb_id": "tt0805448", + "name": "Saint Seiya: The Hades Chapter - Sanctuary", + "type": "series", + "year": "2002–2008" + }, + { + "_id": "53677f1c847ccc8123a1bba8", + "imdb_id": "tt0088571", + "name": "Moonlighting", + "type": "series", + "year": "1985–1989" + }, + { + "_id": "59bf55781712e0f4ddedac8e", + "imdb_id": "tt5711280", + "type": "series", + "name": "Electric Dreams", + "year": "2017–2018" + }, + { + "_id": "5c61c4d6d582b25756e0ffa2", + "imdb_id": "tt0115202", + "name": "High Incident", + "type": "series", + "year": "1996–1997" + }, + { + "_id": "5c575349d582b257560abf5f", + "imdb_id": "tt1441939", + "name": "Titan Maximum", + "type": "series", + "year": "2009" + }, + { + "_id": "5c34c032173739c9f41ee61c", + "imdb_id": "tt0071032", + "name": "Petrocelli", + "type": "series", + "year": "1974–1976" + }, + { + "_id": "53677efc847ccc8123a152ae", + "imdb_id": "tt2295809", + "name": "Mistresses", + "type": "series", + "year": "2013–2016" + }, + { + "_id": "536907f1847ccc8123acddb7", + "imdb_id": "tt0092332", + "name": "The Charmings", + "type": "series", + "year": "1987–1988" + }, + { + "_id": "53677f20847ccc8123a1c813", + "imdb_id": "tt0126158", + "name": "He-Man and the Masters of the Universe", + "type": "series", + "year": "1983–1985" + }, + { + "_id": "53677f6f847ccc8123a232d9", + "imdb_id": "tt0060025", + "name": "Skippy", + "type": "series", + "year": "1968–1970" + }, + { + "_id": "53677f05847ccc8123a17735", + "imdb_id": "tt0213327", + "name": "Andromeda", + "type": "series", + "year": "2000–2005" + }, + { + "_id": "53677f0f847ccc8123a19bdc", + "imdb_id": "tt2303687", + "name": "Line of Duty", + "type": "series", + "year": "2012–2021" + }, + { + "_id": "536907ea847ccc8123acdd7d", + "imdb_id": "tt0074016", + "name": "Laverne & Shirley", + "type": "series", + "year": "1976–1983" + }, + { + "_id": "53677f1a847ccc8123a1b639", + "imdb_id": "tt0123816", + "name": "Earth: Final Conflict", + "type": "series", + "year": "1997–2002" + }, + { + "_id": "5c428744d582b2575683cc5b", + "imdb_id": "tt0843548", + "name": "Kaiketsu Zoro", + "type": "series", + "year": "1994–1997" + }, + { + "_id": "53677f23847ccc8123a1cf27", + "imdb_id": "tt2660734", + "name": "The Tomorrow People", + "type": "series", + "year": "2013–2014" + }, + { + "_id": "54cb9986e573cadcfa1f8098", + "imdb_id": "tt0433723", + "name": "Mr. Men and Little Miss", + "type": "series", + "year": "1995–1998" + }, + { + "_id": "53677f42847ccc8123a1fa50", + "imdb_id": "tt0083377", + "name": "Nine to Five", + "type": "series", + "year": "1982–1988" + }, + { + "_id": "53677f14847ccc8123a1a4e1", + "imdb_id": "tt0175738", + "name": "Histeria!", + "type": "series", + "year": "1998–2000" + }, + { + "_id": "55435a03b0c9284285038c85", + "imdb_id": "tt3894916", + "name": "Terra Formars", + "year": "2014–2016", + "type": "series" + }, + { + "_id": "557c1f8cbf6c900d18356aa5", + "imdb_id": "tt4159076", + "name": "Dark Matter", + "year": "2015–2017", + "type": "series" + }, + { + "_id": "53677f5a847ccc8123a21aaa", + "imdb_id": "tt0423713", + "name": "Plus belle la vie", + "type": "series", + "year": "2004–2022" + }, + { + "_id": "53677ef9847ccc8123a13a07", + "imdb_id": "tt0096684", + "name": "Quantum Leap", + "type": "series", + "year": "1989–1993" + }, + { + "_id": "58d37c681635517fbf56e66e", + "imdb_id": "tt5093452", + "name": "Shots Fired", + "type": "series", + "year": "2017" + }, + { + "_id": "640f111c64ec43ef98a8e37c", + "imdb_id": "tt14688458", + "name": "Silo", + "type": "series", + "year": "2023–" + }, + { + "_id": "5c0d39be173739c9f40bce18", + "imdb_id": "tt0217941", + "name": "Jayce and the Wheeled Warriors", + "type": "series", + "year": "1985–1986" + }, + { + "_id": "61debe4a64ec43ef981f04b3", + "imdb_id": "tt13956466", + "name": "The Genius Prince's Guide to Raising a Nation Out of Debt", + "type": "series", + "year": "2022" + }, + { + "_id": "5e4a1843c4ccb5dd929f31c8", + "imdb_id": "tt9073898", + "name": "Duncanville", + "type": "series", + "year": "2020–2022" + }, + { + "_id": "53677f6a847ccc8123a22e98", + "imdb_id": "tt0106014", + "name": "Goodnight Sweetheart", + "type": "series", + "year": "1993–2016" + }, + { + "_id": "536907e7847ccc8123acdcfc", + "imdb_id": "tt0071003", + "name": "Kolchak: The Night Stalker", + "type": "series", + "year": "1974–1975" + }, + { + "_id": "53677ef5847ccc8123a13760", + "imdb_id": "tt0105950", + "name": "Beavis and Butt-Head", + "type": "series", + "year": "1993–2011" + }, + { + "_id": "62d0017464ec43ef98ae4888", + "imdb_id": "tt19848112", + "name": "My Stepmom's Daughter Is My Ex", + "type": "series", + "year": "2022" + }, + { + "_id": "5c16cdde173739c9f42f0e31", + "imdb_id": "tt6425462", + "name": "Hanazuki: Full of Treasures", + "type": "series", + "year": "2017–2019" + }, + { + "_id": "53677f08847ccc8123a1839e", + "imdb_id": "tt1786209", + "name": "Så mycket bättre", + "type": "series", + "year": "2010–" + }, + { + "_id": "53677f0c847ccc8123a19398", + "imdb_id": "tt3279494", + "name": "@midnight", + "type": "series", + "year": "2013–2017" + }, + { + "_id": "578bb69ff0b6c53b3c789f67", + "imdb_id": "tt4168956", + "name": "Wrecked", + "year": "2016–2018", + "type": "series" + }, + { + "_id": "5fde28f1542425334161edf2", + "imdb_id": "tt11612120", + "name": "Sweet Home", + "type": "series", + "year": "2020–" + }, + { + "_id": "581c498355f8aab460cfd39e", + "imdb_id": "tt5787720", + "name": "Dead Silent", + "type": "series", + "year": "2016–" + }, + { + "_id": "5c33f657173739c9f4f2b3af", + "imdb_id": "tt2334330", + "name": "Tegami Bachi Reverse", + "type": "series", + "year": "2010–2011" + }, + { + "_id": "53677f0f847ccc8123a19c4c", + "imdb_id": "tt0426745", + "name": "Maya & Miguel", + "type": "series", + "year": "2004–2009" + }, + { + "_id": "5c1afcd4173739c9f4961bfa", + "imdb_id": "tt3105452", + "name": "Golden Time", + "type": "series", + "year": "2013–2014" + }, + { + "_id": "55c21813bf6c900d183c94da", + "imdb_id": "tt4406352", + "name": "Endangered Species", + "year": "2014–2015", + "type": "series" + }, + { + "_id": "5c1cdd07173739c9f4c73013", + "imdb_id": "tt2703720", + "name": "My Teen Romantic Comedy SNAFU", + "type": "series", + "year": "2013–2023" + }, + { + "_id": "5ea3ce6b5424253341fc456c", + "imdb_id": "tt11187480", + "name": "RuPaul's Secret Celebrity Drag Race", + "type": "series", + "year": "2020–" + }, + { + "_id": "5f95bb185424253341438b28", + "imdb_id": "tt12831098", + "name": "Moriarty the Patriot", + "type": "series", + "year": "2020–2022" + }, + { + "_id": "5c4db36dd582b257564ba9d6", + "imdb_id": "tt0305095", + "name": "Die Rosenheim-Cops", + "type": "series", + "year": "2002–" + }, + { + "_id": "53677f05847ccc8123a175e2", + "imdb_id": "tt1339238", + "name": "Sekirei", + "type": "series", + "year": "2008–2010" + }, + { + "_id": "5c0f477b173739c9f4965aef", + "imdb_id": "tt0159193", + "name": "Mobile Suit Gundam Wing", + "type": "series", + "year": "1995–1996" + }, + { + "_id": "53677f23847ccc8123a1d014", + "imdb_id": "tt3037520", + "name": "Hollywood Game Night", + "type": "series", + "year": "2013–2020" + }, + { + "_id": "53677f23847ccc8123a1cf26", + "imdb_id": "tt2293002", + "name": "Ben 10: Omniverse", + "type": "series", + "year": "2012–2014" + }, + { + "_id": "54bacf638527d2e0cb50815d", + "imdb_id": "tt3807034", + "name": "The Adventures of Puss in Boots", + "type": "series", + "year": "2015–2018" + }, + { + "_id": "53677ef9847ccc8123a13e43", + "imdb_id": "tt0159206", + "name": "Sex and the City", + "type": "series", + "year": "1998–2004" + }, + { + "_id": "5fcda80254242533414f1613", + "imdb_id": "tt10795658", + "name": "Alice in Borderland", + "type": "series", + "year": "2020–" + }, + { + "_id": "53677f1d847ccc8123a1be25", + "imdb_id": "tt0320808", + "name": "The Adventures of Jimmy Neutron, Boy Genius", + "type": "series", + "year": "2002–2006" + }, + { + "_id": "5cf0634b5111f1a8a3f25436", + "imdb_id": "tt1869454", + "name": "Good Omens", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "5b9df59d173739c9f4b8041d", + "imdb_id": "tt8673610", + "name": "Cells at Work!", + "type": "series", + "year": "2018–2021" + }, + { + "_id": "55fada67bf6c900d1842157e", + "imdb_id": "tt4218618", + "name": "The Bastard Executioner", + "year": "2015", + "type": "series" + }, + { + "_id": "53677f08847ccc8123a182f8", + "imdb_id": "tt0290983", + "name": "Spider-Man", + "type": "series", + "year": "2003" + }, + { + "_id": "5c0ac693173739c9f4b6c4af", + "imdb_id": "tt6352180", + "name": "Little Witch Academia", + "type": "series", + "year": "2017" + }, + { + "_id": "5530edd5cc9eee85bb52e4ec", + "imdb_id": "tt0465327", + "name": "The Emperor's New School", + "year": "2006–2008", + "type": "series" + }, + { + "_id": "6201dfec64ec43ef986ef369", + "imdb_id": "tt11092482", + "name": "AEW Dark", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "53677ef9847ccc8123a13a9b", + "imdb_id": "tt2187850", + "name": "Pablo Escobar: El Patrón del Mal", + "type": "series", + "year": "2012" + }, + { + "_id": "610db99864ec43ef984fc938", + "imdb_id": "tt14809614", + "name": "Hart to Heart", + "type": "series", + "year": "2021–" + }, + { + "_id": "5368e83b847ccc8123acdc18", + "imdb_id": "tt3322314", + "name": "Luke Cage", + "type": "series", + "year": "2016–2018" + }, + { + "_id": "53677f24847ccc8123a1d323", + "imdb_id": "tt0056768", + "name": "Kraft Suspense Theatre", + "type": "series", + "year": "1963–1965" + }, + { + "_id": "53677f3c847ccc8123a1f1bd", + "imdb_id": "tt0111964", + "name": "Flipper", + "type": "series", + "year": "1995–2000" + }, + { + "_id": "5c22b7a6173739c9f4628751", + "imdb_id": "tt0062577", + "name": "Lancer", + "type": "series", + "year": "1968–1970" + }, + { + "_id": "53677efa847ccc8123a14baf", + "imdb_id": "tt0058855", + "name": "The Wild Wild West", + "type": "series", + "year": "1965–1969" + }, + { + "_id": "53677f74847ccc8123a2381f", + "imdb_id": "tt3463606", + "name": "Welcome to Sweden", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "64a74cb3bd36726cbbf5e74e", + "imdb_id": "tt22249034", + "name": "Rurouni Kenshin", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677f45847ccc8123a1ffc3", + "imdb_id": "tt0098763", + "name": "Captain Planet and the Planeteers", + "type": "series", + "year": "1990–1996" + }, + { + "_id": "55075dd1711bd19c92ade169", + "imdb_id": "tt2069441", + "name": "The Future Diary", + "year": "2011–2013", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13b98", + "imdb_id": "tt1641349", + "name": "Terra Nova", + "type": "series", + "year": "2011" + }, + { + "_id": "53677f0a847ccc8123a1886a", + "imdb_id": "tt0115317", + "name": "Poltergeist: The Legacy", + "type": "series", + "year": "1996–1999" + }, + { + "_id": "53677f15847ccc8123a1aa25", + "imdb_id": "tt1765510", + "name": "R.L. Stine's the Haunting Hour", + "type": "series", + "year": "2010–2014" + }, + { + "_id": "53677ef9847ccc8123a14465", + "imdb_id": "tt1771072", + "name": "Common Law", + "type": "series", + "year": "2012" + }, + { + "_id": "53677f29847ccc8123a1dc18", + "imdb_id": "tt2345459", + "name": "8 Out of 10 Cats Does Countdown", + "type": "series", + "year": "2012–" + }, + { + "_id": "53677f17847ccc8123a1afb0", + "imdb_id": "tt0094433", + "name": "China Beach", + "type": "series", + "year": "1988–1991" + }, + { + "_id": "5d8c0ac1c4ccb5dd9251ab02", + "imdb_id": "tt10313066", + "name": "Stumptown", + "type": "series", + "year": "2019–2020" + }, + { + "_id": "634b9dd464ec43ef987245dd", + "imdb_id": "tt21345944", + "name": "Beast Tamer", + "type": "series", + "year": "2022" + }, + { + "_id": "588497131635517fbf569d8a", + "imdb_id": "tt5809150", + "name": "Ransom", + "type": "series", + "year": "2017–2019" + }, + { + "_id": "53677f29847ccc8123a1de54", + "imdb_id": "tt2799012", + "name": "Ravenswood", + "type": "series", + "year": "2013–2014" + }, + { + "_id": "592db27d1635517fbf56e897", + "imdb_id": "tt4326894", + "name": "F Is for Family", + "type": "series", + "year": "2015–2021" + }, + { + "_id": "53677f23847ccc8123a1d054", + "imdb_id": "tt3212600", + "name": "Mahabharat", + "type": "series", + "year": "2013–2014" + }, + { + "_id": "5c19e4fb173739c9f47a5e11", + "imdb_id": "tt0434670", + "name": "Chrono Crusade", + "type": "series", + "year": "2003–2004" + }, + { + "_id": "5c2ffa20173739c9f4e4c867", + "imdb_id": "tt0090444", + "name": "Head of the Class", + "type": "series", + "year": "1986–1991" + }, + { + "_id": "53677f20847ccc8123a1c715", + "imdb_id": "tt0056747", + "name": "The Dakotas", + "type": "series", + "year": "1962–1963" + }, + { + "_id": "55091930711bd19c92ade63c", + "imdb_id": "tt3501016", + "name": "One Big Happy", + "year": "2015", + "type": "series" + }, + { + "_id": "632859d264ec43ef98af4c3e", + "imdb_id": "tt17047510", + "name": "The Santa Clauses", + "type": "series", + "year": "2022–2023" + }, + { + "_id": "6345e2c364ec43ef98fc7a3b", + "imdb_id": "tt21345876", + "name": "Shinobi no Ittoki", + "type": "series", + "year": "2022" + }, + { + "_id": "54ff6a66711bd19c92add0dc", + "imdb_id": "tt0845738", + "name": "When They Cry", + "year": "2006", + "type": "series" + }, + { + "_id": "53677f72847ccc8123a23537", + "imdb_id": "tt2141913", + "name": "Review", + "type": "series", + "year": "2014–2017" + }, + { + "_id": "536907ea847ccc8123acdd74", + "imdb_id": "tt0161952", + "name": "Saint Seiya: Knights of the Zodiac", + "type": "series", + "year": "1986–1989" + }, + { + "_id": "53677f24847ccc8123a1d361", + "imdb_id": "tt0166910", + "name": "Dennis the Menace", + "type": "series", + "year": "1986–1988" + }, + { + "_id": "53677ef9847ccc8123a1397e", + "imdb_id": "tt1963853", + "name": "South Beach Tow", + "type": "series", + "year": "2011–" + }, + { + "_id": "5c19d378173739c9f465ad24", + "imdb_id": "tt0219446", + "name": "The Oblongs", + "type": "series", + "year": "2001–2002" + }, + { + "_id": "56fe8e05f6aa5b2a53480a55", + "imdb_id": "tt4789576", + "name": "The Path", + "year": "2016–2018", + "type": "series" + }, + { + "_id": "5c1c24db173739c9f49d6d79", + "imdb_id": "tt2349912", + "name": "Doctor X", + "type": "series", + "year": "2012–" + }, + { + "_id": "5c1bf45c173739c9f43bf732", + "imdb_id": "tt1177054", + "name": "Der Bergdoktor", + "type": "series", + "year": "2008–" + }, + { + "_id": "5bceb591173739c9f454d2e1", + "imdb_id": "tt7153034", + "name": "The Bureau of Magical Things", + "type": "series", + "year": "2018–2021" + }, + { + "_id": "53677f40847ccc8123a1f780", + "imdb_id": "tt0255734", + "name": "Grounded for Life", + "type": "series", + "year": "2001–2005" + }, + { + "_id": "5d0473295111f1a8a3783733", + "imdb_id": "tt8594276", + "name": "Jett", + "type": "series", + "year": "2019" + }, + { + "_id": "576c5a65f0b6c53b3c76ac24", + "imdb_id": "tt5016504", + "name": "Preacher", + "year": "2016–2019", + "type": "series" + }, + { + "_id": "53677f02847ccc8123a16acb", + "imdb_id": "tt0078692", + "name": "Star Blazers", + "type": "series", + "year": "1979–1984" + }, + { + "_id": "53677f6f847ccc8123a23366", + "imdb_id": "tt2781848", + "name": "Mushibugyo", + "type": "series", + "year": "2013–2015" + }, + { + "_id": "55084476711bd19c92ade464", + "imdb_id": "tt4341500", + "name": "Wet Hot American Summer: First Day of Camp", + "year": "2015", + "type": "series" + }, + { + "_id": "53677f4c847ccc8123a207c0", + "imdb_id": "tt0052506", + "name": "Riverboat", + "type": "series", + "year": "1959–1961" + }, + { + "_id": "6458d1cd64ec43ef98272319", + "imdb_id": "tt14261112", + "name": "Twisted Metal", + "type": "series", + "year": "2023–" + }, + { + "_id": "5c0b5650173739c9f4b88bcc", + "imdb_id": "tt0108921", + "name": "The Secret World of Alex Mack", + "type": "series", + "year": "1994–1998" + }, + { + "_id": "5c0a1796173739c9f47bfdbd", + "imdb_id": "tt2198870", + "name": "Red Table Talk", + "type": "series", + "year": "2018–2022" + }, + { + "_id": "54ff1e79711bd19c92adcf77", + "imdb_id": "tt3532752", + "name": "Trinity Seven", + "year": "2014–2015", + "type": "series" + }, + { + "_id": "642fee0964ec43ef9825fe66", + "imdb_id": "tt22074164", + "name": "Jury Duty", + "type": "series", + "year": "2023–" + }, + { + "_id": "536907f2847ccc8123acddda", + "imdb_id": "tt1735517", + "name": "Ask Rhod Gilbert", + "type": "series", + "year": "2010–2011" + }, + { + "_id": "53677f57847ccc8123a216e7", + "imdb_id": "tt2934286", + "name": "Halo", + "type": "series", + "year": "2022–" + }, + { + "_id": "5c50e413d582b25756709a51", + "imdb_id": "tt9077530", + "name": "Virgin River", + "type": "series", + "year": "2019–" + }, + { + "_id": "53677f23847ccc8123a1cee9", + "imdb_id": "tt0063941", + "name": "Please Sir!", + "type": "series", + "year": "1968–1972" + }, + { + "_id": "5d26d82e5111f1a8a3bac9d9", + "imdb_id": "tt9153270", + "name": "Family Reunion", + "type": "series", + "year": "2019–2022" + }, + { + "_id": "53677f3a847ccc8123a1eefb", + "imdb_id": "tt0163438", + "name": "C.O.P.S.", + "type": "series", + "year": "1988–1989" + }, + { + "_id": "5c394eb2d582b257569b5a8c", + "imdb_id": "tt8042500", + "name": "Y: The Last Man", + "type": "series", + "year": "2021" + }, + { + "_id": "54fc0952711bd19c92ad4a0c", + "imdb_id": "tt1751305", + "name": "Ore no imouto ga konna ni kawaii wake ga nai", + "year": "2010–2013", + "type": "series" + }, + { + "_id": "567d5bf5bb83c664989a2579", + "imdb_id": "tt4378456", + "name": "Second Chance", + "year": "2016", + "type": "series" + }, + { + "_id": "5c24deb0173739c9f425044a", + "imdb_id": "tt0274279", + "name": "Leipzig Homicide", + "type": "series", + "year": "2001–" + }, + { + "_id": "594053ab1635517fbf56e925", + "imdb_id": "tt5640558", + "name": "Claws", + "type": "series", + "year": "2017–2022" + }, + { + "_id": "55072fb5711bd19c92add983", + "imdb_id": "tt1655610", + "name": "Baka and Test", + "year": "2010–2011", + "type": "series" + }, + { + "_id": "63cc769a64ec43ef98ac57a0", + "imdb_id": "tt21608762", + "name": "Saving 80,000 Gold in Another World for my Retirement", + "type": "series", + "year": "2023" + }, + { + "_id": "53677efa847ccc8123a1456b", + "imdb_id": "tt0976014", + "name": "Greek", + "type": "series", + "year": "2007–2011" + }, + { + "_id": "63c4c51464ec43ef981f5bcf", + "imdb_id": "tt21844644", + "name": "Handyman Saitou in another world", + "type": "series", + "year": "2023" + }, + { + "_id": "550787d0711bd19c92ade1d8", + "imdb_id": "tt0305046", + "name": "Android Kikaider: The Animation", + "year": "2000–2001", + "type": "series" + }, + { + "_id": "53677f5c847ccc8123a21dd2", + "imdb_id": "tt0222518", + "name": "Adventures of Sonic the Hedgehog", + "type": "series", + "year": "1993" + }, + { + "_id": "659167afbd36726cbbd87938", + "imdb_id": "tt29899652", + "name": "Night Has Come", + "type": "series", + "year": "2023–" + }, + { + "_id": "63317f7d64ec43ef98b42013", + "imdb_id": "tt13444912", + "name": "The Midnight Club", + "type": "series", + "year": "2022" + }, + { + "_id": "5c0e9e8c173739c9f46b21e1", + "imdb_id": "tt4574736", + "name": "Charlotte", + "type": "series", + "year": "2015–2016" + }, + { + "_id": "5c170dbc173739c9f493d8d8", + "imdb_id": "tt7243884", + "name": "Catherine the Great", + "type": "series", + "year": "2019" + }, + { + "_id": "5c59386fd582b257565b22f9", + "imdb_id": "tt0790397", + "name": "VH-1 Where Are They Now?", + "type": "series", + "year": "1999–2004" + }, + { + "_id": "57dee079d7e54929823e410b", + "imdb_id": "tt5607616", + "name": "Re: Zero, Starting Life in Another World", + "year": "2016–", + "type": "series" + }, + { + "_id": "652c2326bd36726cbb36e284", + "imdb_id": "tt28919914", + "name": "The 100 Girlfriends Who Really, Really, Really, Really, REALLY Love You", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677ef9847ccc8123a137cf", + "imdb_id": "tt1319735", + "name": "Royal Pains", + "type": "series", + "year": "2009–2016" + }, + { + "_id": "53677f1f847ccc8123a1c5ac", + "imdb_id": "tt0288987", + "name": "Magical Angel Creamy Mami", + "type": "series", + "year": "1983–1984" + }, + { + "_id": "621ad42164ec43ef986a7b7c", + "imdb_id": "tt15407098", + "name": "Sister Boniface Mysteries", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677f02847ccc8123a16fcf", + "imdb_id": "tt0098882", + "name": "One Foot in the Grave", + "type": "series", + "year": "1990–2001" + }, + { + "_id": "53677ef9847ccc8123a1393e", + "imdb_id": "tt0297494", + "name": "Aqua Teen Hunger Force", + "type": "series", + "year": "2000–2023" + }, + { + "_id": "53677f0c847ccc8123a190ad", + "imdb_id": "tt0305033", + "name": "Grimm's Fairy Tale Classics", + "type": "series", + "year": "1987–1989" + }, + { + "_id": "53677f02847ccc8123a170ab", + "imdb_id": "tt0169247", + "name": "So Weird", + "type": "series", + "year": "1999–2001" + }, + { + "_id": "53677efd847ccc8123a15553", + "imdb_id": "tt0108992", + "name": "Wycliffe", + "type": "series", + "year": "1993–1998" + }, + { + "_id": "64f9a83cbd36726cbbf4d525", + "imdb_id": "tt27974068", + "name": "Destined with You", + "type": "series", + "year": "2023–" + }, + { + "_id": "5c0a0bbf173739c9f46f7078", + "imdb_id": "tt7736558", + "name": "Wizards", + "type": "series", + "year": "2020" + }, + { + "_id": "53677ef9847ccc8123a140f0", + "imdb_id": "tt0081912", + "name": "Only Fools and Horses", + "type": "series", + "year": "1981–2003" + }, + { + "_id": "5893e07e1635517fbf56cadf", + "imdb_id": "tt5083928", + "name": "Powerless", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "5fff6b6a54242533415a628f", + "imdb_id": "tt13370404", + "name": "Redo of Healer", + "type": "series", + "year": "2021" + }, + { + "_id": "59cdf21c067c46521001d2cc", + "imdb_id": "tt4379632", + "type": "series", + "name": "Blood Blockade Battlefront", + "year": "2015–2017" + }, + { + "_id": "53677f57847ccc8123a21643", + "imdb_id": "tt0096679", + "name": "Press Gang", + "type": "series", + "year": "1989–1993" + }, + { + "_id": "551bcc5acc9eee85bb52e0ce", + "imdb_id": "tt2320220", + "name": "Kamisama Kiss", + "year": "2012–2016", + "type": "series" + }, + { + "_id": "5c1c1ee5173739c9f4917570", + "imdb_id": "tt0144050", + "name": "Hinter Gittern - Der Frauenknast", + "type": "series", + "year": "1997–2010" + }, + { + "_id": "5ea690815424253341d2fe3b", + "imdb_id": "tt10062292", + "name": "Never Have I Ever", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "5c2a50f3173739c9f4aa264a", + "imdb_id": "tt0338614", + "name": "House Doctor", + "type": "series", + "year": "1998–" + }, + { + "_id": "53677efd847ccc8123a1558f", + "imdb_id": "tt0115286", + "name": "Never Mind the Buzzcocks", + "type": "series", + "year": "1996–2023" + }, + { + "_id": "53677ef9847ccc8123a13f78", + "imdb_id": "tt1344204", + "name": "Blue Mountain State", + "type": "series", + "year": "2010–2011" + }, + { + "_id": "6562e52dbd36726cbb960e9b", + "imdb_id": "tt29569035", + "name": "My Demon", + "type": "series", + "year": "2023–" + }, + { + "_id": "53de7d2ea8f27b1bb90bd50f", + "imdb_id": "tt0807832", + "name": "Mushi-Shi", + "type": "series", + "year": "2005–2014" + }, + { + "_id": "53677ef9847ccc8123a13c0e", + "imdb_id": "tt0108758", + "name": "Earth 2", + "type": "series", + "year": "1994–1995" + }, + { + "_id": "623c2b6664ec43ef98c5396a", + "imdb_id": "tt18314214", + "name": "Is It Cake?", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677f0a847ccc8123a18887", + "imdb_id": "tt0098749", + "name": "Beverly Hills, 90210", + "type": "series", + "year": "1990–2000" + }, + { + "_id": "5c265231173739c9f4bed263", + "imdb_id": "tt5747326", + "name": "The Kapil Sharma Show", + "type": "series", + "year": "2016–" + }, + { + "_id": "63514ae064ec43ef98952cc4", + "imdb_id": "tt18566706", + "name": "Immoral Guild", + "type": "series", + "year": "2022" + }, + { + "_id": "5c23419f173739c9f42e1045", + "imdb_id": "tt8878996", + "name": "The Hills: New Beginnings", + "type": "series", + "year": "2019–2021" + }, + { + "_id": "5c4cfa81d582b257567af4c0", + "imdb_id": "tt0052501", + "name": "Philip Marlowe", + "type": "series", + "year": "1959–1960" + }, + { + "_id": "536907f4847ccc8123acde1e", + "imdb_id": "tt0450373", + "name": "Bobobo-bo Bo-bobo", + "type": "series", + "year": "2003–2005" + }, + { + "_id": "557ebe06bf6c900d1835836a", + "imdb_id": "tt4122068", + "name": "Humans", + "year": "2015–2018", + "type": "series" + }, + { + "_id": "56183acdec193d5e98269975", + "imdb_id": "tt4458594", + "name": "Blaze and the Monster Machines", + "year": "2014–2023", + "type": "series" + }, + { + "_id": "53677f66847ccc8123a229b4", + "imdb_id": "tt0054539", + "name": "Follow the Sun", + "type": "series", + "year": "1961–1962" + }, + { + "_id": "53677ef9847ccc8123a13b05", + "imdb_id": "tt0805669", + "name": "Ugly Betty", + "type": "series", + "year": "2006–2010" + }, + { + "_id": "53677f03847ccc8123a17241", + "imdb_id": "tt0060034", + "name": "That Girl", + "type": "series", + "year": "1966–1971" + }, + { + "_id": "60659a445424253341a195d7", + "imdb_id": "tt7808566", + "name": "Made for Love", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "53677f22847ccc8123a1cccb", + "imdb_id": "tt3503520", + "name": "Ronja, the Robber's Daughter", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "53677f1f847ccc8123a1c374", + "imdb_id": "tt0086696", + "name": "Double Trouble", + "type": "series", + "year": "1984–1985" + }, + { + "_id": "543d5216a8f27b1bb90d38f6", + "imdb_id": "tt2465992", + "name": "Gunshi Kanbee", + "type": "series", + "year": "2014" + }, + { + "_id": "62caef7364ec43ef98337432", + "imdb_id": "tt18574004", + "name": "Parallel World Pharmacy", + "type": "series", + "year": "2022" + }, + { + "_id": "5e865fa405bdfe7d18c1da35", + "imdb_id": "tt11833388", + "name": "Danger Force", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "552de977cc9eee85bb52e390", + "imdb_id": "tt0045373", + "name": "The Bob Hope Show", + "year": "1950–", + "type": "series" + }, + { + "_id": "6468512bbd36726cbb9721a4", + "imdb_id": "tt13373182", + "name": "Unicorn: Warriors Eternal", + "type": "series", + "year": "2023–" + }, + { + "_id": "578935e8f0b6c53b3c787523", + "imdb_id": "tt5363766", + "name": "Feed the Beast", + "year": "2016", + "type": "series" + }, + { + "_id": "620b585964ec43ef984171a8", + "imdb_id": "tt14321914", + "name": "The Chelsea Detective", + "type": "series", + "year": "2022–" + }, + { + "_id": "62e80f6d64ec43ef98eea0b8", + "imdb_id": "tt14921986", + "name": "Interview with the Vampire", + "type": "series", + "year": "2022–" + }, + { + "_id": "5c0a6506173739c9f4fb5ff1", + "imdb_id": "tt7836688", + "name": "A Place Further Than the Universe", + "type": "series", + "year": "2018" + }, + { + "_id": "55948f29bf6c900d183890ce", + "imdb_id": "tt3295542", + "name": "Have You Been Paying Attention?", + "year": "2013–", + "type": "series" + }, + { + "_id": "54fdebf2711bd19c92adc379", + "imdb_id": "tt0108845", + "name": "Madison", + "year": "1993–1997", + "type": "series" + }, + { + "_id": "57e04e3ad7e54929823e5673", + "imdb_id": "tt5725682", + "name": "Ozzy & Jack's World Detour", + "year": "2016–", + "type": "series" + }, + { + "_id": "5c3681e7d582b2575695edb4", + "imdb_id": "tt3196310", + "name": "Outbreak Company", + "type": "series", + "year": "2013" + }, + { + "_id": "53677ef9847ccc8123a13e06", + "imdb_id": "tt0920448", + "name": "Flikken Maastricht", + "type": "series", + "year": "2007–" + }, + { + "_id": "61ff73a364ec43ef986c7a11", + "imdb_id": "tt11761194", + "name": "Power Book IV: Force", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677f0e847ccc8123a1959d", + "imdb_id": "tt0806901", + "name": "Police Call 110", + "type": "series", + "year": "1971–" + }, + { + "_id": "5543fb55d728d29134b6e5a4", + "imdb_id": "tt1216159", + "name": "Nabari no Ou", + "year": "2008", + "type": "series" + }, + { + "_id": "5c34ae23173739c9f4fee162", + "imdb_id": "tt0319987", + "name": "Dragnet", + "type": "series", + "year": "2003–2004" + }, + { + "_id": "576c5a05f0b6c53b3c76ac11", + "imdb_id": "tt4229954", + "name": "Outcast", + "year": "2016–2017", + "type": "series" + }, + { + "_id": "5b9c6a6c173739c9f44f1ca6", + "imdb_id": "tt2177461", + "name": "A Discovery of Witches", + "type": "series", + "year": "2018–2022" + }, + { + "_id": "53677ef9847ccc8123a14000", + "imdb_id": "tt1548850", + "name": "Misfits", + "type": "series", + "year": "2009–2013" + }, + { + "_id": "605c55d55424253341ee51bf", + "imdb_id": "tt14069590", + "name": "Dota: Dragon's Blood", + "type": "series", + "year": "2021–" + }, + { + "_id": "59bbb5571712e0f4dd91f618", + "imdb_id": "tt5669272", + "type": "series", + "name": "Wet Hot American Summer: Ten Years Later", + "year": "2017" + }, + { + "_id": "5c245e86173739c9f44a9ee8", + "imdb_id": "tt0057741", + "name": "Crossroads", + "type": "series", + "year": "1964–1988" + }, + { + "_id": "53677f47847ccc8123a20014", + "imdb_id": "tt0264970", + "name": "Crossroads", + "type": "series", + "year": "2001–2003" + }, + { + "_id": "5c1f2bd1173739c9f4e92f45", + "imdb_id": "tt6128376", + "name": "The Gong Show", + "type": "series", + "year": "2017–2018" + }, + { + "_id": "53677f68847ccc8123a22bf9", + "imdb_id": "tt2375692", + "name": "Black Sails", + "type": "series", + "year": "2014–2017" + }, + { + "_id": "53677f60847ccc8123a22304", + "imdb_id": "tt0070991", + "name": "Good Times", + "type": "series", + "year": "1974–1979" + }, + { + "_id": "64b6cd0ebd36726cbb6bbf17", + "imdb_id": "tt13111078", + "name": "Special Ops: Lioness", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677f3a847ccc8123a1f082", + "imdb_id": "tt2551252", + "name": "It's a Date", + "type": "series", + "year": "2013–2014" + }, + { + "_id": "5c33c6f5173739c9f492b6f8", + "imdb_id": "tt0054568", + "name": "Tales of the Wizard of Oz", + "type": "series", + "year": "1961–" + }, + { + "_id": "55fa7ed3bf6c900d1841f472", + "imdb_id": "tt4452630", + "name": "Code Black", + "year": "2015–2018", + "type": "series" + }, + { + "_id": "5c493af9d582b2575671ba8c", + "imdb_id": "tt0086744", + "name": "Kids Incorporated", + "type": "series", + "year": "1984–1993" + }, + { + "_id": "53677f24847ccc8123a1d172", + "imdb_id": "tt0055666", + "name": "Combat!", + "type": "series", + "year": "1962–1967" + }, + { + "_id": "5c09a6b0173739c9f4c672d1", + "imdb_id": "tt0165593", + "name": "BBC Play of the Month", + "type": "series", + "year": "1965–1983" + }, + { + "_id": "5ab881b853336c1ba820e2e1", + "imdb_id": "tt5664952", + "type": "series", + "name": "Trust", + "year": "2018" + }, + { + "_id": "633870e664ec43ef98304f3a", + "imdb_id": "tt15533960", + "name": "I'm the Villainess, So I'm Taming the Final Boss", + "type": "series", + "year": "2022" + }, + { + "_id": "5c2933ee173739c9f4cd4a12", + "imdb_id": "tt1762503", + "name": "Carpool", + "type": "series", + "year": "2010–2011" + }, + { + "_id": "5c26c580173739c9f4a7e0ec", + "imdb_id": "tt5194792", + "name": "NOS4A2", + "type": "series", + "year": "2019–2020" + }, + { + "_id": "53677f1f847ccc8123a1c48b", + "imdb_id": "tt0072511", + "name": "Secret Squadron Gorenger", + "type": "series", + "year": "1975–1977" + }, + { + "_id": "53677efd847ccc8123a1566b", + "imdb_id": "tt0077031", + "name": "The Incredible Hulk", + "type": "series", + "year": "1977–1982" + }, + { + "_id": "53677ef9847ccc8123a143da", + "imdb_id": "tt0823333", + "name": "Blade: The Series", + "type": "series", + "year": "2006" + }, + { + "_id": "5c426644d582b2575671b271", + "imdb_id": "tt2291137", + "name": "Folktales from Japan", + "type": "series", + "year": "2012–" + }, + { + "_id": "54fc0929711bd19c92ad496d", + "imdb_id": "tt0405520", + "name": "Best Week Ever with Paul F. Tompkins", + "year": "2004–", + "type": "series" + }, + { + "_id": "5c0bd9c1173739c9f499848e", + "imdb_id": "tt6964748", + "name": "Alex Rider", + "type": "series", + "year": "2020–" + }, + { + "_id": "5378cbe6847ccc8123ad2a32", + "imdb_id": "tt3186138", + "name": "Finding Carter", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "53677efa847ccc8123a149ce", + "imdb_id": "tt1727387", + "name": "GCB", + "type": "series", + "year": "2012" + }, + { + "_id": "54b28a0b8527d2e0cb50620f", + "imdb_id": "tt0112057", + "name": "Magic Knight Rayearth", + "type": "series", + "year": "1994–1995" + }, + { + "_id": "635cdd1d64ec43ef986b9607", + "imdb_id": "tt21991254", + "name": "Romantic Killer", + "type": "series", + "year": "2022" + }, + { + "_id": "6072f1a3542425334181628f", + "imdb_id": "tt13196080", + "name": "Tokyo Revengers", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677f0c847ccc8123a18e82", + "imdb_id": "tt0103477", + "name": "The Little Mermaid", + "type": "series", + "year": "1992–1994" + }, + { + "_id": "541463a1a8f27b1bb90c9975", + "imdb_id": "tt0085088", + "name": "Scarecrow and Mrs. King", + "type": "series", + "year": "1983–1987" + }, + { + "_id": "53677f0c847ccc8123a18ff0", + "imdb_id": "tt0272988", + "name": "Phantom Thief Jeanne", + "type": "series", + "year": "1999–" + }, + { + "_id": "62d8307a64ec43ef981d2c4e", + "imdb_id": "tt15219320", + "name": "Uncle from Another World", + "type": "series", + "year": "2022–2023" + }, + { + "_id": "53677f15847ccc8123a1a7e1", + "imdb_id": "tt0069599", + "name": "Kojak", + "type": "series", + "year": "1973–1978" + }, + { + "_id": "53677ef9847ccc8123a13d1c", + "imdb_id": "tt0844653", + "name": "Legend of the Seeker", + "type": "series", + "year": "2008–2010" + }, + { + "_id": "651bf68fbd36726cbbb216c8", + "imdb_id": "tt10551640", + "name": "The Longest Day in Chang'an", + "type": "series", + "year": "2019" + }, + { + "_id": "570f058b890e549c9a5833f5", + "imdb_id": "tt4903242", + "name": "The Detour", + "year": "2016–2019", + "type": "series" + }, + { + "_id": "6307407764ec43ef986b2064", + "imdb_id": "tt14674086", + "name": "Welcome to Wrexham", + "type": "series", + "year": "2022–" + }, + { + "_id": "550787e0711bd19c92ade1fc", + "imdb_id": "tt0115417", + "name": "Water Rats", + "year": "1996–2001", + "type": "series" + }, + { + "_id": "53677f07847ccc8123a180ae", + "imdb_id": "tt0126171", + "name": "She-Ra: Princess of Power", + "type": "series", + "year": "1985–1987" + }, + { + "_id": "53677efa847ccc8123a14a77", + "imdb_id": "tt0262150", + "name": "Black Books", + "type": "series", + "year": "2000–2004" + }, + { + "_id": "5bfd6f75173739c9f4a8138c", + "imdb_id": "tt7945720", + "name": "Dirty John", + "type": "series", + "year": "2018–2020" + }, + { + "_id": "53677f0c847ccc8123a19149", + "imdb_id": "tt0108903", + "name": "ReBoot", + "type": "series", + "year": "1994–2001" + }, + { + "_id": "5c0f0582173739c9f4326b1a", + "imdb_id": "tt7814574", + "name": "Junji Itô: Korekushon", + "type": "series", + "year": "2018–" + }, + { + "_id": "624419cc64ec43ef98aa4cac", + "imdb_id": "tt10234724", + "name": "Moon Knight", + "type": "series", + "year": "2022" + }, + { + "_id": "56cd7161f6aa5b2a534468ce", + "imdb_id": "tt4816626", + "name": "Outsiders", + "year": "2016–2017", + "type": "series" + }, + { + "_id": "5c0f5547173739c9f4a570fa", + "imdb_id": "tt8328460", + "name": "Busted!", + "type": "series", + "year": "2018–2021" + }, + { + "_id": "5c0d0dbc173739c9f4b3b250", + "imdb_id": "tt6461346", + "name": "Stranger", + "type": "series", + "year": "2017–" + }, + { + "_id": "5c6099e2d582b257566eba7f", + "imdb_id": "tt0285342", + "name": "Bob Patterson", + "type": "series", + "year": "2001" + }, + { + "_id": "625feb4f64ec43ef98221617", + "imdb_id": "tt15723722", + "name": "I'm Quitting Heroing", + "type": "series", + "year": "2022" + }, + { + "_id": "53677f05847ccc8123a179ab", + "imdb_id": "tt2912216", + "name": "Fatal Attraction", + "type": "series", + "year": "2013–" + }, + { + "_id": "53677f05847ccc8123a17ae8", + "imdb_id": "tt0318997", + "name": "Angels in America", + "type": "series", + "year": "2003" + }, + { + "_id": "59b03ef21712e0f4dd1e6b30", + "imdb_id": "tt4571004", + "name": "Meurtres à...", + "year": "2013–", + "type": "series" + }, + { + "_id": "5c2a939a173739c9f42c32c5", + "imdb_id": "tt8388390", + "name": "Chucky", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677efa847ccc8123a14b26", + "imdb_id": "tt0115227", + "name": "Judge Judy", + "type": "series", + "year": "1996–2021" + }, + { + "_id": "543d5216a8f27b1bb90d38c3", + "imdb_id": "tt2301643", + "name": "Halloween Wars", + "type": "series", + "year": "2011–" + }, + { + "_id": "53677f38847ccc8123a1ee17", + "imdb_id": "tt0235911", + "name": "As Told by Ginger", + "type": "series", + "year": "2000–2009" + }, + { + "_id": "5c1c1c63173739c9f48cb4c4", + "imdb_id": "tt5603140", + "name": "The Restaurant", + "type": "series", + "year": "2017–" + }, + { + "_id": "53677f0c847ccc8123a1904c", + "imdb_id": "tt0364863", + "name": "RahXephon", + "type": "series", + "year": "2002" + }, + { + "_id": "53677f0f847ccc8123a1987b", + "imdb_id": "tt0204087", + "name": "Those Who Hunt Elves", + "type": "series", + "year": "1996–1997" + }, + { + "_id": "53677f04847ccc8123a17345", + "imdb_id": "tt2693776", + "name": "Intelligence", + "type": "series", + "year": "2014" + }, + { + "_id": "5c12b3e3173739c9f4cc1a71", + "imdb_id": "tt2301807", + "name": "Naruto SD: Rock Lee & His Ninja Pals", + "type": "series", + "year": "2012–2013" + }, + { + "_id": "576c5a7df0b6c53b3c76ac2f", + "imdb_id": "tt5376862", + "name": "Guilt", + "year": "2016", + "type": "series" + }, + { + "_id": "53677f20847ccc8123a1c67e", + "imdb_id": "tt1447723", + "name": "The Fresh Beat Band", + "type": "series", + "year": "2009–2013" + }, + { + "_id": "643453a864ec43ef983658f0", + "imdb_id": "tt27417996", + "name": "I Got a Cheat Skill in Another World and Became Unrivaled in the Real World, Too", + "type": "series", + "year": "2023" + }, + { + "_id": "5c17ea15173739c9f4ede08f", + "imdb_id": "tt6074794", + "name": "March Comes in Like a Lion", + "type": "series", + "year": "2016–2018" + }, + { + "_id": "5c0a7c0f173739c9f425f4e7", + "imdb_id": "tt6354518", + "name": "The Disastrous Life of Saiki K.", + "type": "series", + "year": "2016–2018" + }, + { + "_id": "53677f22847ccc8123a1ce40", + "imdb_id": "tt0075596", + "name": "Three's Company", + "type": "series", + "year": "1976–1984" + }, + { + "_id": "53677f29847ccc8123a1dde4", + "imdb_id": "tt0103511", + "name": "Phoenix", + "type": "series", + "year": "1992–1993" + }, + { + "_id": "536907e8847ccc8123acdd31", + "imdb_id": "tt1382157", + "name": "That Metal Show", + "type": "series", + "year": "2008–2015" + }, + { + "_id": "5c0fc241173739c9f45c563d", + "imdb_id": "tt0247729", + "name": "Static Shock", + "type": "series", + "year": "2000–2004" + }, + { + "_id": "53a5820aa8f27b1bb90b1c86", + "imdb_id": "tt0361140", + "name": ".hack//SIGN", + "type": "series", + "year": "2002–2003" + }, + { + "_id": "62f5d6c164ec43ef98511661", + "imdb_id": "tt3283594", + "name": "Five Days at Memorial", + "type": "series", + "year": "2022" + }, + { + "_id": "55075d94711bd19c92addf42", + "imdb_id": "tt2902582", + "name": "Danganronpa: The Animation", + "year": "2013", + "type": "series" + }, + { + "_id": "53677ef9847ccc8123a13c47", + "imdb_id": "tt1192169", + "name": "Ben 10: Alien Force", + "type": "series", + "year": "2008–2010" + }, + { + "_id": "5bf4bafe173739c9f4cfd159", + "imdb_id": "tt5924572", + "name": "Deadly Class", + "type": "series", + "year": "2018–2019" + }, + { + "_id": "5c3b49f4d582b25756a20699", + "imdb_id": "tt0108800", + "name": "Heartbreak High", + "type": "series", + "year": "1994–1999" + }, + { + "_id": "5c0bbf14173739c9f464a399", + "imdb_id": "tt0073974", + "name": "City of Angels", + "type": "series", + "year": "1976–" + }, + { + "_id": "53677eff847ccc8123a15ffc", + "imdb_id": "tt0058814", + "name": "Honey West", + "type": "series", + "year": "1965–1966" + }, + { + "_id": "53677f2c847ccc8123a1e13b", + "imdb_id": "tt2384811", + "name": "Utopia", + "type": "series", + "year": "2013–2014" + }, + { + "_id": "53677f19847ccc8123a1b3a9", + "imdb_id": "tt0052485", + "name": "Lock Up", + "type": "series", + "year": "1959–1961" + }, + { + "_id": "582f4439b0a40c25066cc743", + "imdb_id": "tt4118466", + "name": "Incorporated", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "53677ef9847ccc8123a13867", + "imdb_id": "tt1332030", + "name": "Make It or Break It", + "type": "series", + "year": "2009–2012" + }, + { + "_id": "53677ef9847ccc8123a13d2e", + "imdb_id": "tt0914829", + "name": "Bad Girls Club", + "type": "series", + "year": "2006–" + }, + { + "_id": "554359c7b0c9284285038c20", + "imdb_id": "tt2309320", + "name": "From the New World", + "year": "2012–2013", + "type": "series" + }, + { + "_id": "5d503945c4ccb5dd924b2c72", + "imdb_id": "tt9698520", + "name": "A Black Lady Sketch Show", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "62ca29e964ec43ef98a8e500", + "imdb_id": "tt16755706", + "name": "Lycoris Recoil", + "type": "series", + "year": "2022" + }, + { + "_id": "652ab4ffbd36726cbb0b0ee4", + "imdb_id": "tt29171919", + "name": "The Vexations of a Shut-In Vampire Princess", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677efc847ccc8123a1537b", + "imdb_id": "tt2191567", + "name": "Wicked Tuna", + "type": "series", + "year": "2012–" + }, + { + "_id": "5c28cab5173739c9f4f8aaaf", + "imdb_id": "tt0094434", + "name": "Chouju Sentai Liveman", + "type": "series", + "year": "1988–1989" + }, + { + "_id": "55dec9cebf6c900d183fa369", + "imdb_id": "tt0081961", + "name": "Wetten, dass..?", + "year": "1981–", + "type": "series" + }, + { + "_id": "53677f1c847ccc8123a1ba9e", + "imdb_id": "tt1910272", + "name": "Steins;Gate", + "type": "series", + "year": "2011–2015" + }, + { + "_id": "5378cbf8847ccc8123ad34da", + "imdb_id": "tt3230780", + "name": "The Returned", + "type": "series", + "year": "2015" + }, + { + "_id": "53677f21847ccc8123a1cafa", + "imdb_id": "tt0077082", + "name": "The South Bank Show", + "type": "series", + "year": "1978–" + }, + { + "_id": "53677f00847ccc8123a163f8", + "imdb_id": "tt1344970", + "name": "Rob Dyrdek's Fantasy Factory", + "type": "series", + "year": "2009–" + }, + { + "_id": "53677f02847ccc8123a16c0d", + "imdb_id": "tt1780262", + "name": "Is this a Zombie?", + "type": "series", + "year": "2011–2012" + }, + { + "_id": "53677f2f847ccc8123a1e606", + "imdb_id": "tt0481440", + "name": "Britain's Next Top Model", + "type": "series", + "year": "2005–" + }, + { + "_id": "5c0ea739173739c9f47c0fa1", + "imdb_id": "tt0101115", + "name": "Herman's Head", + "type": "series", + "year": "1991–1994" + }, + { + "_id": "57eb3d86d7e54929823ee933", + "imdb_id": "tt5797772", + "type": "series", + "name": "Aftermath", + "year": "2016" + }, + { + "_id": "6262437c64ec43ef98851005", + "imdb_id": "tt13223570", + "name": "The First Lady", + "type": "series", + "year": "2022" + }, + { + "_id": "5c0cd442173739c9f448a7cf", + "imdb_id": "tt2953250", + "name": "Shining Girls", + "type": "series", + "year": "2022" + }, + { + "_id": "55c392abbf6c900d183cafba", + "imdb_id": "tt4380272", + "name": "Gamer's Guide to Pretty Much Everything", + "year": "2015–2017", + "type": "series" + }, + { + "_id": "53677f05847ccc8123a17cc7", + "imdb_id": "tt1295036", + "name": "Seth MacFarlane's Cavalcade of Cartoon Comedy", + "type": "series", + "year": "2008–2010" + }, + { + "_id": "5c1585f4173739c9f4ea828d", + "imdb_id": "tt6428088", + "name": "Charlie Golf One", + "type": "series", + "year": "2016–2020" + }, + { + "_id": "613c32e064ec43ef9833ce7d", + "imdb_id": "tt12994356", + "name": "The Cleaner", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677f23847ccc8123a1cf59", + "imdb_id": "tt0874679", + "name": "Son of the Dragon", + "type": "series", + "year": "2006" + }, + { + "_id": "6182b55a64ec43ef985e2d88", + "imdb_id": "tt7492014", + "name": "Fairfax", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "53677f0c847ccc8123a193bd", + "imdb_id": "tt0112090", + "name": "The Naked Truth", + "type": "series", + "year": "1995–1998" + }, + { + "_id": "53677eff847ccc8123a15dfb", + "imdb_id": "tt0419326", + "name": "Foster's Home for Imaginary Friends", + "type": "series", + "year": "2004–2009" + }, + { + "_id": "5c0ae374173739c9f4f3176d", + "imdb_id": "tt0101068", + "name": "Cluedo", + "type": "series", + "year": "1990–1993" + }, + { + "_id": "53677f03847ccc8123a17326", + "imdb_id": "tt0112123", + "name": "Pinky and the Brain", + "type": "series", + "year": "1995–1998" + }, + { + "_id": "635650afe49da23b4660db4d", + "name": "Beavis and Butt-Head", + "imdb_id": "tt20859904", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677f51847ccc8123a20e46", + "imdb_id": "tt0500092", + "name": "Serial Experiments Lain", + "type": "series", + "year": "1998" + }, + { + "_id": "53677f22847ccc8123a1ccc6", + "imdb_id": "tt0084976", + "name": "Aura Battler Dunbine", + "type": "series", + "year": "1983–1984" + }, + { + "_id": "53677ef9847ccc8123a13876", + "imdb_id": "tt0445912", + "name": "The Ultimate Fighter", + "type": "series", + "year": "2005–" + }, + { + "_id": "5c0be6f3173739c9f4b55b10", + "imdb_id": "tt0178148", + "name": "Kinnikuman", + "type": "series", + "year": "1983–1986" + }, + { + "_id": "53677f40847ccc8123a1f660", + "imdb_id": "tt1198372", + "name": "Mujeres asesinas", + "type": "series", + "year": "2008–" + }, + { + "_id": "55072f71711bd19c92add84d", + "imdb_id": "tt0429416", + "name": "Project ARMS", + "year": "2001–2002", + "type": "series" + }, + { + "_id": "53677f15847ccc8123a1a8bc", + "imdb_id": "tt0118475", + "name": "Spawn", + "type": "series", + "year": "1997–1999" + }, + { + "_id": "53677f13847ccc8123a1a2df", + "imdb_id": "tt0075578", + "name": "SCTV", + "type": "series", + "year": "1976–1981" + }, + { + "_id": "54f8f399711bd19c92accdb2", + "imdb_id": "tt3560060", + "name": "CSI: Cyber", + "year": "2015–2016", + "type": "series" + }, + { + "_id": "54c92d23e573cadcfa1f7761", + "imdb_id": "tt0434693", + "name": "Sergeant Keroro", + "type": "series", + "year": "2004–2011" + }, + { + "_id": "5c449e05d582b2575647fad0", + "imdb_id": "tt9547400", + "name": "Magia Record: Puella Magi Madoka Magica Side Story", + "type": "series", + "year": "2020–2022" + }, + { + "_id": "5f5d0ae254242533418b4d3c", + "imdb_id": "tt12432936", + "name": "The Misfit of Demon King Academy", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "53677f61847ccc8123a2244d", + "imdb_id": "tt2703708", + "name": "Ginga Kikoutai: Majestic Prince", + "type": "series", + "year": "2013–" + }, + { + "_id": "53eb359ea8f27b1bb90c0817", + "imdb_id": "tt3781836", + "name": "Botched", + "type": "series", + "year": "2014–" + }, + { + "_id": "53677f1e847ccc8123a1c123", + "imdb_id": "tt0899258", + "name": "D.Gray-man", + "type": "series", + "year": "2006–2008" + }, + { + "_id": "53677efd847ccc8123a15b5f", + "imdb_id": "tt0081871", + "name": "The Greatest American Hero", + "type": "series", + "year": "1981–1983" + }, + { + "_id": "53677efc847ccc8123a15242", + "imdb_id": "tt1695360", + "name": "The Legend of Korra", + "type": "series", + "year": "2012–2014" + }, + { + "_id": "5aa2cf0353336c1ba8ef7fa3", + "imdb_id": "tt6470396", + "type": "series", + "name": "Champions", + "year": "2018" + }, + { + "_id": "5c3f9357d582b25756d89188", + "imdb_id": "tt6889072", + "name": "The Best Hit", + "type": "series", + "year": "2017" + }, + { + "_id": "53677f19847ccc8123a1b559", + "imdb_id": "tt1329466", + "name": "Sukippu bîto!", + "type": "series", + "year": "2008–2009" + }, + { + "_id": "5c2280af173739c9f4e91855", + "imdb_id": "tt0085075", + "name": "Reading Rainbow", + "type": "series", + "year": "1983–2006" + }, + { + "_id": "53677f0a847ccc8123a18789", + "imdb_id": "tt1634208", + "name": "Maid Sama!", + "type": "series", + "year": "2010–2011" + }, + { + "_id": "5c5ee358d582b2575606f15e", + "imdb_id": "tt8466564", + "name": "Obi-Wan Kenobi", + "type": "series", + "year": "2022" + }, + { + "_id": "53677f5e847ccc8123a222db", + "imdb_id": "tt0101059", + "name": "Chances", + "type": "series", + "year": "1991–1992" + }, + { + "_id": "53677f03847ccc8123a17252", + "imdb_id": "tt0108761", + "name": "Ellen", + "type": "series", + "year": "1994–1998" + }, + { + "_id": "53677f0a847ccc8123a1895f", + "imdb_id": "tt0118303", + "name": "Dharma & Greg", + "type": "series", + "year": "1997–2002" + }, + { + "_id": "56701a6dbb83c6649898e672", + "imdb_id": "tt3793630", + "name": "The Lion Guard", + "year": "2015–2019", + "type": "series" + }, + { + "_id": "6261b65564ec43ef98ebfbbe", + "imdb_id": "tt15766292", + "name": "Mahoutsukai Reimeiki", + "type": "series", + "year": "2022–" + }, + { + "_id": "5c2188b3173739c9f43919a4", + "imdb_id": "tt0122813", + "name": "Bob and Margaret", + "type": "series", + "year": "1993–2001" + }, + { + "_id": "53677f4a847ccc8123a204d9", + "imdb_id": "tt0072504", + "name": "Get Some In!", + "type": "series", + "year": "1975–1978" + }, + { + "_id": "593196611635517fbf56e8e5", + "imdb_id": "tt6905508", + "name": "Growing Up Hip Hop: Atlanta", + "type": "series", + "year": "2017–" + }, + { + "_id": "53677efc847ccc8123a14d01", + "imdb_id": "tt0799922", + "name": "Wizards of Waverly Place", + "type": "series", + "year": "2007–2012" + }, + { + "_id": "53677ef9847ccc8123a1424e", + "imdb_id": "tt2334429", + "name": "The Voice", + "type": "series", + "year": "2012–" + }, + { + "_id": "53677eff847ccc8123a15cd7", + "imdb_id": "tt1807824", + "name": "Wakfu", + "type": "series", + "year": "2008–2017" + }, + { + "_id": "5f64e3bb54242533411e7cb7", + "imdb_id": "tt7294498", + "name": "Frankie Boyle's New World Order", + "type": "series", + "year": "2017–2022" + }, + { + "_id": "5c4244aad582b257565df2d6", + "imdb_id": "tt0086660", + "name": "1st & Ten", + "type": "series", + "year": "1984–1991" + }, + { + "_id": "5c0c13a8173739c9f41024cf", + "imdb_id": "tt6300838", + "name": "Tiger Mask W", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "582f4b41b0a40c25066cc7f0", + "imdb_id": "tt4181172", + "name": "Shooter", + "type": "series", + "year": "2016–2018" + }, + { + "_id": "6425d15c64ec43ef9859cc72", + "imdb_id": "tt22059768", + "name": "Digman!", + "type": "series", + "year": "2023–" + }, + { + "_id": "55c8a056bf6c900d183dc17d", + "imdb_id": "tt4677934", + "name": "Documentary Now!", + "year": "2015–", + "type": "series" + }, + { + "_id": "5c0b0cab173739c9f445cc04", + "imdb_id": "tt6922826", + "name": "Once", + "type": "series", + "year": "2017–2019" + }, + { + "_id": "5c09bc2d173739c9f4f25c08", + "imdb_id": "tt7529770", + "name": "Miracle Workers", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "53677f07847ccc8123a17df7", + "imdb_id": "tt0094559", + "name": "Superboy", + "type": "series", + "year": "1988–1992" + }, + { + "_id": "5bc68d57173739c9f49846f2", + "imdb_id": "tt8595140", + "name": "The Conners", + "type": "series", + "year": "2018–" + }, + { + "_id": "5d559e45c4ccb5dd92ab7447", + "imdb_id": "tt9054904", + "name": "Why Women Kill", + "type": "series", + "year": "2019–2021" + }, + { + "_id": "53677f66847ccc8123a22ad9", + "imdb_id": "tt0204777", + "name": "The Secret Files of the SpyDogs", + "type": "series", + "year": "1998–1999" + }, + { + "_id": "570f05b3890e549c9a5833fa", + "imdb_id": "tt5269594", + "name": "Marcella", + "year": "2016–2021", + "type": "series" + }, + { + "_id": "5c3592da173739c9f49b8315", + "imdb_id": "tt0249313", + "name": "Resurrection Blvd.", + "type": "series", + "year": "2000–2002" + }, + { + "_id": "53677f1e847ccc8123a1c0d9", + "imdb_id": "tt1101237", + "name": "Imagination Movers", + "type": "series", + "year": "2008–2013" + }, + { + "_id": "53677ef9847ccc8123a139bd", + "imdb_id": "tt0065314", + "name": "The Mary Tyler Moore Show", + "type": "series", + "year": "1970–1977" + }, + { + "_id": "5433a646a8f27b1bb90d1074", + "imdb_id": "tt3747572", + "name": "Grantchester", + "type": "series", + "year": "2014–2023" + }, + { + "_id": "5455eb37a8f27b1bb90da50a", + "imdb_id": "tt0080242", + "name": "The Martian Chronicles", + "type": "series", + "year": "1980" + }, + { + "_id": "53677ef9847ccc8123a13f8a", + "imdb_id": "tt1593756", + "name": "Outsourced", + "type": "series", + "year": "2010–2011" + }, + { + "_id": "61e852ff64ec43ef98d395ef", + "imdb_id": "tt14506186", + "name": "In the Land of Leadale", + "type": "series", + "year": "2022" + }, + { + "_id": "5c2ef15d173739c9f4ebb806", + "imdb_id": "tt0309221", + "name": "Tom Stone", + "type": "series", + "year": "2002–2003" + }, + { + "_id": "53677f03847ccc8123a171b1", + "imdb_id": "tt0101178", + "name": "The Ren & Stimpy Show", + "type": "series", + "year": "1991–1996" + }, + { + "_id": "53677f02847ccc8123a1694c", + "imdb_id": "tt0387736", + "name": "Farscape: The Peacekeeper Wars", + "type": "series", + "year": "2004" + }, + { + "_id": "53677f48847ccc8123a20357", + "imdb_id": "tt0118492", + "name": "Timecop", + "type": "series", + "year": "1997–1998" + }, + { + "_id": "59b100bf1712e0f4dd4a74f0", + "imdb_id": "tt0078701", + "type": "series", + "name": "This Old House", + "year": "1979–" + }, + { + "_id": "53677f2c847ccc8123a1e188", + "imdb_id": "tt0115285", + "name": "Nash Bridges", + "type": "series", + "year": "1996–2001" + }, + { + "_id": "5c60538cd582b25756029c23", + "imdb_id": "tt0385411", + "name": "A Wonderful Country", + "type": "series", + "year": "2003–" + }, + { + "_id": "5378cc0a847ccc8123ad46df", + "imdb_id": "tt3594982", + "name": "Sex & Drugs & Rock & Roll", + "type": "series", + "year": "2015–2016" + }, + { + "_id": "5c0acd30173739c9f4c478fd", + "imdb_id": "tt7431994", + "name": "The Pit", + "type": "series", + "year": "2016–2021" + }, + { + "_id": "5c235bfc173739c9f45ea32b", + "imdb_id": "tt4721442", + "name": "Tanglin", + "type": "series", + "year": "2015–" + }, + { + "_id": "53677f1b847ccc8123a1b848", + "imdb_id": "tt0131664", + "name": "The Angry Beavers", + "type": "series", + "year": "1997–2001" + }, + { + "_id": "5c35e878173739c9f4264157", + "imdb_id": "tt5334364", + "name": "Undefeated Bahamut Chronicle", + "type": "series", + "year": "2016" + }, + { + "_id": "5c1adb10173739c9f4511bcc", + "imdb_id": "tt0293741", + "name": "Shinzo", + "type": "series", + "year": "2000–2001" + }, + { + "_id": "53677f0a847ccc8123a18766", + "imdb_id": "tt1842715", + "name": "CSI: Crime Scene Talks", + "type": "series", + "year": "2011–" + }, + { + "_id": "53677ef9847ccc8123a13bf5", + "imdb_id": "tt0453422", + "name": "Doctor Who Confidential", + "type": "series", + "year": "2005–2011" + }, + { + "_id": "5c0eaa0b173739c9f4813472", + "imdb_id": "tt7767422", + "type": "series", + "name": "Sex Education", + "year": "2019–2023" + }, + { + "_id": "6530fab0bd36726cbbc0f4e2", + "imdb_id": "tt18347622", + "name": "Bodies", + "type": "series", + "year": "2023" + }, + { + "_id": "5c24dd3d173739c9f42240b8", + "imdb_id": "tt2294764", + "name": "De slimste mens ter wereld", + "type": "series", + "year": "2012–" + }, + { + "_id": "53677f07847ccc8123a17f7c", + "imdb_id": "tt0122336", + "name": "Captain Future", + "type": "series", + "year": "1978–1979" + }, + { + "_id": "634b493b64ec43ef98144644", + "imdb_id": "tt12464204", + "name": "Peter Grill to Kenja no Jikan", + "type": "series", + "year": "2020–" + }, + { + "_id": "53677f15847ccc8123a1a7c1", + "imdb_id": "tt1893520", + "name": "C", + "type": "series", + "year": "2011–" + }, + { + "_id": "659fb334bd36726cbb93c407", + "imdb_id": "tt21153032", + "name": "The Scooby-Doo Show", + "type": "series", + "year": "1978–2021" + }, + { + "_id": "60f2859f64ec43ef9879fda9", + "imdb_id": "tt13463778", + "name": "Girlfriend, Girlfriend", + "type": "series", + "year": "2021–" + }, + { + "_id": "6367555864ec43ef98da0744", + "imdb_id": "tt11755260", + "name": "The Daily Life of the Immortal King", + "type": "series", + "year": "2020–" + }, + { + "_id": "5c1d5677173739c9f4b4b214", + "imdb_id": "tt2404499", + "name": "Kingdom", + "type": "series", + "year": "2012–" + }, + { + "_id": "53677f26847ccc8123a1d73a", + "imdb_id": "tt0896667", + "name": "Donna Leon", + "type": "series", + "year": "2000–" + }, + { + "_id": "54fb89a1711bd19c92ad484d", + "imdb_id": "tt0440987", + "name": "Fafner", + "year": "2004", + "type": "series" + }, + { + "_id": "5c0ceef9173739c9f479f599", + "imdb_id": "tt8354062", + "name": "One Of Us Is Lying", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "5c308ea6173739c9f4c4dda1", + "imdb_id": "tt0423730", + "name": "SOKO Wismar", + "type": "series", + "year": "2004–" + }, + { + "_id": "53677f54847ccc8123a2149f", + "imdb_id": "tt1188927", + "name": "Criminal Justice", + "type": "series", + "year": "2008–2009" + }, + { + "_id": "53677efa847ccc8123a14871", + "imdb_id": "tt1170858", + "name": "Dragons' Den", + "type": "series", + "year": "2006–" + }, + { + "_id": "5f676d1354242533417474e7", + "imdb_id": "tt11710130", + "name": "I Can See Your Voice", + "type": "series", + "year": "2020–" + }, + { + "_id": "615ef99564ec43ef980fb3fa", + "imdb_id": "tt13241650", + "name": "Ada Twist, Scientist", + "type": "series", + "year": "2021–" + }, + { + "_id": "5c3473c7173739c9f499062f", + "imdb_id": "tt0103426", + "name": "The Golden Palace", + "type": "series", + "year": "1992–1993" + }, + { + "_id": "5e748bc6ee95f208ea3ebff2", + "imdb_id": "tt11405370", + "name": "Nekopara", + "type": "series", + "year": "2020–" + }, + { + "_id": "5c54459cd582b25756ef3048", + "imdb_id": "tt1741602", + "name": "Natholdet - med Anders Breinholt", + "type": "series", + "year": "2010–" + }, + { + "_id": "61138d7c64ec43ef98bc70ed", + "imdb_id": "tt13784584", + "name": "Fantasy Island", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "5c2dfa82173739c9f428a1e1", + "imdb_id": "tt3612626", + "name": "Saekano: How to Raise a Boring Girlfriend", + "type": "series", + "year": "2015–2017" + }, + { + "_id": "53677f29847ccc8123a1dc8f", + "imdb_id": "tt0272376", + "name": "The Division", + "type": "series", + "year": "2001–2004" + }, + { + "_id": "5f89d6845424253341f41240", + "imdb_id": "tt12457334", + "name": "Wandering Witch: The Journey of Elaina", + "type": "series", + "year": "2020–" + }, + { + "_id": "5897f8c81635517fbf56d41c", + "imdb_id": "tt5345490", + "name": "24: Legacy", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "53677f12847ccc8123a19fb7", + "imdb_id": "tt0168375", + "name": "A Little Princess Sara", + "type": "series", + "year": "1985" + }, + { + "_id": "5a184531543165dcd875d624", + "imdb_id": "tt6468322", + "type": "series", + "name": "Money Heist", + "year": "2017–2021" + }, + { + "_id": "53677f0c847ccc8123a192d0", + "imdb_id": "tt0200369", + "name": "Redwall", + "type": "series", + "year": "1999–2002" + }, + { + "_id": "53677f21847ccc8123a1c9fe", + "imdb_id": "tt2226342", + "name": "Devious Maids", + "type": "series", + "year": "2013–2016" + }, + { + "_id": "543ad2fca8f27b1bb90d2d1a", + "imdb_id": "tt0190178", + "name": "Denver, the Last Dinosaur", + "type": "series", + "year": "1988–1990" + }, + { + "_id": "5c1304a2173739c9f47091a0", + "imdb_id": "tt8271124", + "name": "The Adventures of Rocky and Bullwinkle", + "type": "series", + "year": "2018–2019" + }, + { + "_id": "53677ef9847ccc8123a14155", + "imdb_id": "tt0808013", + "name": "Blood Ties", + "type": "series", + "year": "2007" + }, + { + "_id": "53677f0a847ccc8123a1865d", + "imdb_id": "tt0376390", + "name": "Duck Dodgers", + "type": "series", + "year": "2003–2005" + }, + { + "_id": "5c0c4210173739c9f473dc48", + "imdb_id": "tt0159178", + "name": "Maigret", + "type": "series", + "year": "1959–1963" + }, + { + "_id": "53677f3a847ccc8123a1f0cf", + "imdb_id": "tt0275848", + "name": "Lloyd in Space", + "type": "series", + "year": "2001–2004" + }, + { + "_id": "606c8cb9542425334140d5c2", + "imdb_id": "tt7475590", + "name": "Kung Fu", + "type": "series", + "year": "2021–2023" + }, + { + "_id": "536907e6847ccc8123acdcd2", + "imdb_id": "tt0283744", + "name": "James Bond Jr.", + "type": "series", + "year": "1991–1992" + }, + { + "_id": "5811c12cd7e54929824144e0", + "imdb_id": "tt6015808", + "name": "Doctor Doctor", + "type": "series", + "year": "2016–2021" + }, + { + "_id": "63ca43e064ec43ef9841533f", + "imdb_id": "tt11349866", + "name": "Sorcerous Stabber Orphen: Battle of Kimluck", + "type": "series", + "year": "2020–" + }, + { + "_id": "5ab0283653336c1ba8e424ef", + "imdb_id": "tt6461824", + "type": "series", + "name": "The Crossing", + "year": "2018" + }, + { + "_id": "58199f4555f8aab460cfa82c", + "imdb_id": "tt0106056", + "name": "Living Single", + "type": "series", + "year": "1993–1998" + }, + { + "_id": "548f0c978527d2e0cb4ff996", + "imdb_id": "tt0149534", + "name": "Thuis", + "type": "series", + "year": "1995–" + }, + { + "_id": "53677f02847ccc8123a16bbe", + "imdb_id": "tt1991410", + "name": "Dance Moms", + "type": "series", + "year": "2011–2019" + }, + { + "_id": "5a155be3543165dcd828f406", + "imdb_id": "tt5311790", + "type": "series", + "name": "The A Word", + "year": "2016–" + }, + { + "_id": "53677ef9847ccc8123a13dc6", + "imdb_id": "tt1279972", + "name": "Treme", + "type": "series", + "year": "2010–2013" + }, + { + "_id": "5aa5114953336c1ba887f73b", + "imdb_id": "tt0320970", + "name": "Still Standing", + "year": "2002–2006", + "type": "series" + }, + { + "_id": "5c570fe6d582b257569b1e28", + "imdb_id": "tt1727444", + "name": "Panty & Stocking with Garterbelt", + "type": "series", + "year": "2010–2011" + }, + { + "_id": "5c09b3b2173739c9f4e13131", + "imdb_id": "tt7865962", + "name": "Run BTS!", + "type": "series", + "year": "2015–" + }, + { + "_id": "53677ef9847ccc8123a1418f", + "imdb_id": "tt1832668", + "name": "How the Universe Works", + "type": "series", + "year": "2010–" + }, + { + "_id": "53eb359ca8f27b1bb90c0794", + "imdb_id": "tt3589872", + "name": "Black Jesus", + "type": "series", + "year": "2014–2019" + }, + { + "_id": "53677f60847ccc8123a22320", + "imdb_id": "tt1898069", + "name": "American Gods", + "type": "series", + "year": "2017–2021" + }, + { + "_id": "5c617f20d582b2575681f45d", + "imdb_id": "tt5659248", + "name": "The Daltons", + "type": "series", + "year": "2010–2016" + }, + { + "_id": "548f0c958527d2e0cb4ff924", + "imdb_id": "tt0211882", + "name": "Watership Down", + "type": "series", + "year": "1999–2001" + }, + { + "_id": "65978fecbd36726cbb24025f", + "imdb_id": "tt21621494", + "name": "Delicious in Dungeon", + "type": "series", + "year": "2024–" + }, + { + "_id": "54fc094a711bd19c92ad49f5", + "imdb_id": "tt0791163", + "name": "Trinity Blood", + "year": "2005", + "type": "series" + }, + { + "_id": "602c9ac95424253341132438", + "imdb_id": "tt10312854", + "name": "Kenan", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "5aaf1d0853336c1ba8b5266b", + "imdb_id": "tt4124758", + "type": "series", + "name": "Instinct", + "year": "2018–2019" + }, + { + "_id": "53677efd847ccc8123a1554f", + "imdb_id": "tt0476922", + "name": "Moral Orel", + "type": "series", + "year": "2005–2009" + }, + { + "_id": "53677f66847ccc8123a22acb", + "imdb_id": "tt2578560", + "name": "Broad City", + "type": "series", + "year": "2014–2019" + }, + { + "_id": "5c0b0b3a173739c9f442f79a", + "imdb_id": "tt8515016", + "name": "Banana Fish", + "type": "series", + "year": "2018" + }, + { + "_id": "53677f79847ccc8123a23c1f", + "imdb_id": "tt1666209", + "name": "Dong Yi", + "type": "series", + "year": "2010" + }, + { + "_id": "61d9e5db64ec43ef98732168", + "imdb_id": "tt15765670", + "name": "My Dress-Up Darling", + "type": "series", + "year": "2022" + }, + { + "_id": "63bf0e0464ec43ef989710f0", + "imdb_id": "tt21210326", + "name": "Tomo-chan Is a Girl!", + "type": "series", + "year": "2023" + }, + { + "_id": "60570a325424253341b61fd8", + "imdb_id": "tt13129190", + "name": "SK8 the Infinity", + "type": "series", + "year": "2021" + }, + { + "_id": "53677efc847ccc8123a14f7a", + "imdb_id": "tt1055335", + "name": "Transformers: Animated", + "type": "series", + "year": "2007–2009" + }, + { + "_id": "5b45925916f4806c2ac6e8eb", + "imdb_id": "tt7612548", + "type": "series", + "name": "The Outpost", + "year": "2018–2021" + }, + { + "_id": "577abf11f0b6c53b3c778799", + "imdb_id": "tt4113078", + "name": "Westside", + "year": "2015–", + "type": "series" + }, + { + "_id": "53677f48847ccc8123a20252", + "imdb_id": "tt0052462", + "name": "The Deputy", + "type": "series", + "year": "1959–1961" + }, + { + "_id": "53677ef9847ccc8123a13902", + "imdb_id": "tt0146386", + "name": "National Geographic Explorer", + "type": "series", + "year": "1985–" + }, + { + "_id": "604b0a0f5424253341ec3696", + "imdb_id": "tt10115054", + "name": "Lost Treasures of Egypt", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "53677ef9847ccc8123a13c60", + "imdb_id": "tt0086661", + "name": "The Adventures of Sherlock Holmes", + "type": "series", + "year": "1984–1985" + }, + { + "_id": "5d9649c2c4ccb5dd927e9bda", + "imdb_id": "tt9780442", + "name": "RuPaul's Drag Race UK", + "type": "series", + "year": "2019–" + }, + { + "_id": "53677f68847ccc8123a22b39", + "imdb_id": "tt0096545", + "name": "Birds of a Feather", + "type": "series", + "year": "1989–2020" + }, + { + "_id": "5c161165173739c9f4b33c47", + "imdb_id": "tt8435344", + "name": "ThunderCats Roar", + "type": "series", + "year": "2020" + }, + { + "_id": "5ac23acaa5989fb32186c6b6", + "imdb_id": "tt6882202", + "type": "series", + "name": "The Detail", + "year": "2018" + }, + { + "_id": "5c2248f6173739c9f46da940", + "imdb_id": "tt3588312", + "name": "The Comic Artist and Assistants", + "type": "series", + "year": "2014–" + }, + { + "_id": "5c0db445173739c9f40bd398", + "imdb_id": "tt0124228", + "name": "Astro Boy", + "type": "series", + "year": "1980–2004" + }, + { + "_id": "53677f23847ccc8123a1cf28", + "imdb_id": "tt0041038", + "name": "The Lone Ranger", + "type": "series", + "year": "1949–1957" + }, + { + "_id": "53677f12847ccc8123a19fb4", + "imdb_id": "tt0138967", + "name": "Hercules", + "type": "series", + "year": "1998–1999" + }, + { + "_id": "53677f66847ccc8123a229e4", + "imdb_id": "tt3455408", + "name": "The Curse of Oak Island", + "type": "series", + "year": "2014–" + }, + { + "_id": "5abd8f79e0a43c01da2769a7", + "imdb_id": "tt5615700", + "type": "series", + "name": "Siren", + "year": "2018–2020" + }, + { + "_id": "6433e31964ec43ef98879466", + "imdb_id": "tt13622776", + "name": "Ahsoka", + "type": "series", + "year": "2023–" + }, + { + "_id": "5c3ba9d0d582b25756dc9407", + "imdb_id": "tt0182632", + "name": "Seiju Sentai Gingaman", + "type": "series", + "year": "1998–1999" + }, + { + "_id": "5c309b7d173739c9f4dec668", + "imdb_id": "tt7535706", + "name": "Anime-Gataris", + "type": "series", + "year": "2017" + }, + { + "_id": "56b8dfe8f6b914c6c680fe9e", + "imdb_id": "tt2184186", + "name": "A League of Their Own", + "year": "2010–", + "type": "series" + }, + { + "_id": "551bcc56cc9eee85bb52e0cc", + "imdb_id": "tt2305660", + "name": "Ixion Saga DT", + "year": "2012–2013", + "type": "series" + }, + { + "_id": "5c3d2562d582b25756ab3416", + "imdb_id": "tt0050022", + "name": "The Gumby Show", + "type": "series", + "year": "1956–1969" + }, + { + "_id": "53677eff847ccc8123a15cda", + "imdb_id": "tt2372162", + "name": "Orange Is the New Black", + "type": "series", + "year": "2013–2019" + }, + { + "_id": "5c34c6b2173739c9f42a812d", + "imdb_id": "tt1718249", + "name": "BlackBoxTV", + "type": "series", + "year": "2010–2015" + }, + { + "_id": "53677efc847ccc8123a1505b", + "imdb_id": "tt0088631", + "name": "Thundercats", + "type": "series", + "year": "1985–1989" + }, + { + "_id": "53677f3a847ccc8123a1efa2", + "imdb_id": "tt0050053", + "name": "The Real McCoys", + "type": "series", + "year": "1957–1963" + }, + { + "_id": "58401d39b0a40c25066dccef", + "imdb_id": "tt6112556", + "name": "Yuri!!! On Ice", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "642dbb3b64ec43ef98c039e6", + "imdb_id": "tt27329086", + "name": "Konosuba: An Explosion on This Wonderful World!", + "type": "series", + "year": "2023" + }, + { + "_id": "539c4866a8f27b1bb90afe67", + "imdb_id": "tt0086689", + "name": "A Country Practice", + "type": "series", + "year": "1981–1993" + }, + { + "_id": "5c0c3c26173739c9f467997e", + "imdb_id": "tt4917066", + "name": "Prison School", + "type": "series", + "year": "2015–2016" + }, + { + "_id": "53677ef9847ccc8123a13d02", + "imdb_id": "tt0972412", + "name": "Private Practice", + "type": "series", + "year": "2007–2013" + }, + { + "_id": "54fc0934711bd19c92ad499a", + "imdb_id": "tt0444953", + "name": "Kaleido Star", + "year": "2003–2004", + "type": "series" + }, + { + "_id": "5c0a0532173739c9f4686644", + "imdb_id": "tt4925000", + "name": "Descendants of the Sun", + "type": "series", + "year": "2016" + }, + { + "_id": "588b6ae11635517fbf56aa12", + "imdb_id": "tt0085050", + "name": "Mama's Family", + "type": "series", + "year": "1983–1990" + }, + { + "_id": "5c0d7d49173739c9f49b2824", + "imdb_id": "tt0058829", + "name": "Mister Roberts", + "type": "series", + "year": "1965–" + }, + { + "_id": "55075d8a711bd19c92addee1", + "imdb_id": "tt2250034", + "name": "Kokoro Connect", + "year": "2012", + "type": "series" + }, + { + "_id": "53677f07847ccc8123a18275", + "imdb_id": "tt0057773", + "name": "The Munsters", + "type": "series", + "year": "1964–1966" + }, + { + "_id": "5fa9107e542425334132c8be", + "imdb_id": "tt11273012", + "name": "Bruh", + "type": "series", + "year": "2019–" + }, + { + "_id": "5c0f1eeb173739c9f463089a", + "imdb_id": "tt1577461", + "name": "So You Think You Can Dance", + "type": "series", + "year": "2010–" + }, + { + "_id": "53677f66847ccc8123a229f5", + "imdb_id": "tt2741950", + "name": "Enlisted", + "type": "series", + "year": "2014" + }, + { + "_id": "5c1ac922173739c9f42d0260", + "imdb_id": "tt7187044", + "name": "City on a Hill", + "type": "series", + "year": "2019–2022" + }, + { + "_id": "610aa58264ec43ef9837a607", + "imdb_id": "tt10516496", + "name": "Chip 'N' Dale: Park Life", + "type": "series", + "year": "2021–" + }, + { + "_id": "55435a0cb0c9284285038c9c", + "imdb_id": "tt4009874", + "name": "Souten Kouro (Los Tres Reinos)", + "year": "2009–", + "type": "series" + }, + { + "_id": "55075f80711bd19c92ade17e", + "imdb_id": "tt1300170", + "name": "Xam'd: Lost Memories", + "year": "2008–", + "type": "series" + }, + { + "_id": "55075da7711bd19c92addffc", + "imdb_id": "tt3052798", + "name": "Packages from Planet X", + "year": "2013–2014", + "type": "series" + }, + { + "_id": "53677f17847ccc8123a1ab33", + "imdb_id": "tt3010520", + "name": "Turbo FAST", + "type": "series", + "year": "2013–2016" + }, + { + "_id": "53677f7c847ccc8123a23f02", + "imdb_id": "tt2628232", + "name": "Penny Dreadful", + "type": "series", + "year": "2014–2016" + }, + { + "_id": "53677f21847ccc8123a1cb0d", + "imdb_id": "tt0119189", + "name": "George Wallace", + "type": "series", + "year": "1997" + }, + { + "_id": "53677f19847ccc8123a1b34d", + "imdb_id": "tt0098948", + "name": "Wings", + "type": "series", + "year": "1990–1997" + }, + { + "_id": "5a4edf70543165dcd88c09a6", + "imdb_id": "tt7369770", + "type": "series", + "name": "Ellen's Game of Games", + "year": "2017–2021" + }, + { + "_id": "53677f19847ccc8123a1b367", + "imdb_id": "tt0182621", + "name": "The PJs", + "type": "series", + "year": "1999–2001" + }, + { + "_id": "5c3a4c83d582b257561cef51", + "imdb_id": "tt0320053", + "name": "Life with Bonnie", + "type": "series", + "year": "2002–2004" + }, + { + "_id": "60c7e0fc64ec43ef9864fce1", + "imdb_id": "tt9257258", + "name": "Kevin Can F**k Himself", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "53677efd847ccc8123a1548d", + "imdb_id": "tt0278191", + "name": "Fear Factor", + "type": "series", + "year": "2001–2012" + }, + { + "_id": "53677f00847ccc8123a165bf", + "imdb_id": "tt1442552", + "name": "The Marriage Ref", + "type": "series", + "year": "2010–2011" + }, + { + "_id": "5c252913173739c9f4ba592b", + "imdb_id": "tt0305051", + "name": "Kiteretsu Daihyakka", + "type": "series", + "year": "1988–1996" + }, + { + "_id": "5c170798173739c9f48ccf26", + "imdb_id": "tt3673480", + "name": "The Good Lord Bird", + "type": "series", + "year": "2020" + }, + { + "_id": "53677f08847ccc8123a184ee", + "imdb_id": "tt0044283", + "name": "My Little Margie", + "type": "series", + "year": "1952–1955" + }, + { + "_id": "5b90fde4173739c9f47cfb90", + "imdb_id": "tt0369081", + "name": "Ask This Old House", + "type": "series", + "year": "2002–" + }, + { + "_id": "551ad00bcc9eee85bb52dfa9", + "imdb_id": "tt1137419", + "name": "The Alan Titchmarsh Show", + "year": "2007–2014", + "type": "series" + }, + { + "_id": "53677f47847ccc8123a2014b", + "imdb_id": "tt0346314", + "name": "Ghost in the Shell: Stand Alone Complex", + "type": "series", + "year": "2002–2005" + }, + { + "_id": "53677f25847ccc8123a1d68a", + "imdb_id": "tt1739796", + "name": "My Bride Is a Mermaid", + "type": "series", + "year": "2007" + }, + { + "_id": "592ddcb01635517fbf56e8a0", + "imdb_id": "tt5014882", + "name": "The Durrells", + "type": "series", + "year": "2016–2019" + }, + { + "_id": "53677eff847ccc8123a15dfd", + "imdb_id": "tt0052463", + "name": "The Detectives", + "type": "series", + "year": "1959–1962" + }, + { + "_id": "53677f57847ccc8123a217e3", + "imdb_id": "tt0115674", + "name": "BeetleBorgs", + "type": "series", + "year": "1996–1998" + }, + { + "_id": "53677f02847ccc8123a16cd9", + "imdb_id": "tt0203254", + "name": "Franklin", + "type": "series", + "year": "1997–2006" + }, + { + "_id": "626755e764ec43ef989fef86", + "imdb_id": "tt14192504", + "name": "We Own This City", + "type": "series", + "year": "2022" + }, + { + "_id": "53ac6496a8f27b1bb90b2fc7", + "imdb_id": "tt2084712", + "name": "Young & Hungry", + "type": "series", + "year": "2014–2018" + }, + { + "_id": "55075d31711bd19c92addb83", + "imdb_id": "tt0132652", + "name": "Buffalo Bill, Jr.", + "year": "1955–1956", + "type": "series" + }, + { + "_id": "5c583dd3d582b25756134de1", + "imdb_id": "tt0928095", + "name": "Kiba", + "type": "series", + "year": "2006–2007" + }, + { + "_id": "55353f1bcc9eee85bb52e700", + "imdb_id": "tt1161684", + "name": "Rosario + Vampire", + "year": "2008", + "type": "series" + }, + { + "_id": "55197ffacc9eee85bb52dd20", + "imdb_id": "tt1821149", + "name": "#DUPE#", + "year": "2008", + "type": "series" + }, + { + "_id": "5c1bce49173739c9f4f194af", + "imdb_id": "tt5897818", + "name": "Days", + "type": "series", + "year": "2016" + }, + { + "_id": "5c5c61e2d582b25756a15462", + "imdb_id": "tt0101111", + "name": "Good Sports", + "type": "series", + "year": "1991–" + }, + { + "_id": "5b8e9330173739c9f47d6733", + "imdb_id": "tt5057054", + "name": "Tom Clancy's Jack Ryan", + "type": "series", + "year": "2018–2023" + }, + { + "_id": "619d0c7d64ec43ef983fc3d0", + "imdb_id": "tt15766736", + "name": "The Center Seat: 55 Years of Star Trek", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "5c1bb80c173739c9f4c66c58", + "imdb_id": "tt0101187", + "name": "The Royal Family", + "type": "series", + "year": "1991–1992" + }, + { + "_id": "5e3cfaa6c4ccb5dd9299e5b5", + "imdb_id": "tt9686380", + "name": "Indebted", + "type": "series", + "year": "2020" + }, + { + "_id": "5c0bef15173739c9f4c68dbc", + "imdb_id": "tt1312171", + "name": "The Umbrella Academy", + "type": "series", + "year": "2019–2024" + }, + { + "_id": "53677efd847ccc8123a15530", + "imdb_id": "tt0075488", + "name": "CHiPs", + "type": "series", + "year": "1977–1983" + }, + { + "_id": "542d1638a8f27b1bb90cf498", + "imdb_id": "tt0075473", + "name": "The All-New Super Friends Hour", + "type": "series", + "year": "1977–1978" + }, + { + "_id": "6296ced564ec43ef98a78c9a", + "imdb_id": "tt13475676", + "name": "Tom Swift", + "type": "series", + "year": "2022" + }, + { + "_id": "5c1442ac173739c9f4a64b37", + "imdb_id": "tt6905542", + "name": "The Dark Crystal: Age of Resistance", + "type": "series", + "year": "2019" + }, + { + "_id": "53677f60847ccc8123a22309", + "imdb_id": "tt0775407", + "name": "Wonder Pets!", + "type": "series", + "year": "2006–2016" + }, + { + "_id": "5c493c4ed582b257567380aa", + "imdb_id": "tt0066716", + "name": "The Smith Family", + "type": "series", + "year": "1971–1972" + }, + { + "_id": "5c60cabed582b25756b5a1be", + "imdb_id": "tt2388184", + "name": "Zyuden Sentai Kyoryuger", + "type": "series", + "year": "2013–2014" + }, + { + "_id": "53677f02847ccc8123a16853", + "imdb_id": "tt1299729", + "name": "Delocated", + "type": "series", + "year": "2009–2013" + }, + { + "_id": "5c0c7b6d173739c9f4dad095", + "imdb_id": "tt5603356", + "name": "Ace Attorney", + "type": "series", + "year": "2016–2019" + }, + { + "_id": "55912f26bf6c900d183846c3", + "imdb_id": "tt4677846", + "name": "Lost in Oz", + "year": "2015–2018", + "type": "series" + }, + { + "_id": "53677f4a847ccc8123a205c9", + "imdb_id": "tt0853174", + "name": "Gogoriki", + "type": "series", + "year": "2003–2012" + }, + { + "_id": "53677efd847ccc8123a15889", + "imdb_id": "tt1592254", + "name": "The Defenders", + "type": "series", + "year": "2010–2011" + }, + { + "_id": "5c09a793173739c9f4c8318a", + "imdb_id": "tt3644692", + "name": "Banshee Origins", + "type": "series", + "year": "2013–2016" + }, + { + "_id": "6096df0364ec43ef98e3e099", + "imdb_id": "tt13851958", + "name": "Vivy: Fluorite Eye's Song", + "type": "series", + "year": "2021" + }, + { + "_id": "53677f74847ccc8123a2377d", + "imdb_id": "tt0127569", + "name": "Ghostbusters", + "type": "series", + "year": "1986–1987" + }, + { + "_id": "5834f3b3b0a40c25066d27c6", + "imdb_id": "tt6233538", + "name": "Roman Empire", + "type": "series", + "year": "2016–2019" + }, + { + "_id": "53677efc847ccc8123a14f19", + "imdb_id": "tt1596786", + "name": "American Pickers", + "type": "series", + "year": "2010–" + }, + { + "_id": "5bbf2acd173739c9f4b74912", + "imdb_id": "tt7414406", + "name": "All American", + "type": "series", + "year": "2018–" + }, + { + "_id": "54fb5f34711bd19c92ad435d", + "imdb_id": "tt0816401", + "name": "The Replacements", + "year": "2006–2022", + "type": "series" + }, + { + "_id": "595803361635517fbf56e93d", + "imdb_id": "tt5936448", + "name": "Riviera", + "type": "series", + "year": "2017–2020" + }, + { + "_id": "5c0cdc9e173739c9f457ca8c", + "imdb_id": "tt6256484", + "name": "While You Were Sleeping", + "type": "series", + "year": "2017" + }, + { + "_id": "6226108d64ec43ef986638ba", + "imdb_id": "tt14819828", + "name": "Business Proposal", + "type": "series", + "year": "2022" + }, + { + "_id": "53677f1c847ccc8123a1bb13", + "imdb_id": "tt2177954", + "name": "Polar Bear's Café", + "type": "series", + "year": "2012–2013" + }, + { + "_id": "6528b9f6bd36726cbb286505", + "imdb_id": "tt13911628", + "name": "Lessons in Chemistry", + "type": "series", + "year": "2023" + }, + { + "_id": "5d680182c4ccb5dd92ac0aad", + "imdb_id": "tt8107988", + "name": "Carole & Tuesday", + "type": "series", + "year": "2019" + }, + { + "_id": "53677efd847ccc8123a15896", + "imdb_id": "tt0080240", + "name": "Magnum, P.I.", + "type": "series", + "year": "1980–1988" + }, + { + "_id": "5c19bf45173739c9f43fdc0b", + "imdb_id": "tt4903514", + "name": "Inside the Factory", + "type": "series", + "year": "2015–" + }, + { + "_id": "53677f18847ccc8123a1b081", + "imdb_id": "tt0075512", + "name": "Grange Hill", + "type": "series", + "year": "1978–2008" + }, + { + "_id": "658d01bfbd36726cbbc37a05", + "imdb_id": "tt3881914", + "name": "Blossoms Shanghai", + "type": "series", + "year": "2023–" + }, + { + "_id": "541463a1a8f27b1bb90c9987", + "imdb_id": "tt1745240", + "name": "Kimi ni Todoke: From Me to You", + "type": "series", + "year": "2009–2011" + }, + { + "_id": "53677f4f847ccc8123a20d98", + "imdb_id": "tt1215996", + "name": "Blassreiter", + "type": "series", + "year": "2008" + }, + { + "_id": "615fb03764ec43ef98616c1a", + "imdb_id": "tt11379026", + "name": "Ghosts", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677f0c847ccc8123a19371", + "imdb_id": "tt0054572", + "name": "Top Cat", + "type": "series", + "year": "1961–1962" + }, + { + "_id": "6118d71864ec43ef9881dfb1", + "imdb_id": "tt12779780", + "name": "Fena: Pirate Princess", + "type": "series", + "year": "2021" + }, + { + "_id": "53677f05847ccc8123a179fb", + "imdb_id": "tt1996607", + "name": "Dream High", + "type": "series", + "year": "2011–2012" + }, + { + "_id": "53677f05847ccc8123a17985", + "imdb_id": "tt1190931", + "name": "American Greed", + "type": "series", + "year": "2007–2023" + }, + { + "_id": "6102ee7964ec43ef98f489a9", + "imdb_id": "tt13409388", + "name": "The Idaten Deities Know Only Peace", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677f7b847ccc8123a23d3e", + "imdb_id": "tt0147772", + "name": "Here's Boomer", + "type": "series", + "year": "1980–1982" + }, + { + "_id": "63ba8c7464ec43ef98d3cd2f", + "imdb_id": "tt25809288", + "name": "The Reincarnation of the Strongest Exorcist in Another World", + "type": "series", + "year": "2023" + }, + { + "_id": "637b5aa164ec43ef9805810b", + "imdb_id": "tt18335752", + "name": "1923", + "type": "series", + "year": "2022–2023" + }, + { + "_id": "53677f2c847ccc8123a1e27f", + "imdb_id": "tt2433738", + "name": "Wentworth", + "type": "series", + "year": "2013–2021" + }, + { + "_id": "5aa7ceb453336c1ba8b1d7be", + "imdb_id": "tt6987788", + "type": "series", + "name": "Nailed It!", + "year": "2018–" + }, + { + "_id": "53677f0a847ccc8123a1871d", + "imdb_id": "tt0115378", + "name": "Superman: The Animated Series", + "type": "series", + "year": "1996–2000" + }, + { + "_id": "58cf9c791635517fbf56e636", + "imdb_id": "tt1984119", + "name": "Feud", + "type": "series", + "year": "2017–" + }, + { + "_id": "53677f07847ccc8123a17e4c", + "imdb_id": "tt0965404", + "name": "Bubble Guppies", + "type": "series", + "year": "2011–2023" + }, + { + "_id": "53677f4a847ccc8123a2044f", + "imdb_id": "tt0278876", + "name": "The Saddle Club", + "type": "series", + "year": "2001–2009" + }, + { + "_id": "59e07530067c465210c4381c", + "imdb_id": "tt5290382", + "type": "series", + "name": "Mindhunter", + "year": "2017–2019" + }, + { + "_id": "5c111f17173739c9f4dc7ef5", + "imdb_id": "tt8086718", + "name": "Grand Blue", + "type": "series", + "year": "2018" + }, + { + "_id": "5c28ca3d173739c9f4f7c484", + "imdb_id": "tt0991047", + "name": "Gun x Sword", + "type": "series", + "year": "2005" + }, + { + "_id": "6066ecbe5424253341069cce", + "imdb_id": "tt12677870", + "name": "Law & Order: Organized Crime", + "type": "series", + "year": "2021–" + }, + { + "_id": "5c0b5539173739c9f4b752b9", + "imdb_id": "tt0200337", + "name": "Family Law", + "type": "series", + "year": "1999–2002" + }, + { + "_id": "5c19bf65173739c9f4401bf6", + "imdb_id": "tt8010544", + "name": "Persona 5: The Animation", + "type": "series", + "year": "2018–2019" + }, + { + "_id": "53677f42847ccc8123a1fa4e", + "imdb_id": "tt0044263", + "name": "Four Star Playhouse", + "type": "series", + "year": "1952–1956" + }, + { + "_id": "53677f23847ccc8123a1cfde", + "imdb_id": "tt2022713", + "name": "Brickleberry", + "type": "series", + "year": "2012–2015" + }, + { + "_id": "53677ef9847ccc8123a138ce", + "imdb_id": "tt0248654", + "name": "Six Feet Under", + "type": "series", + "year": "2001–2005" + }, + { + "_id": "6263961c64ec43ef981d440f", + "imdb_id": "tt15527326", + "name": "The Creature Cases", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677f04847ccc8123a173d3", + "imdb_id": "tt0058806", + "name": "Gidget", + "type": "series", + "year": "1965–1966" + }, + { + "_id": "53677f18847ccc8123a1b089", + "imdb_id": "tt0372650", + "name": "Cyborg 009", + "type": "series", + "year": "2001–2002" + }, + { + "_id": "53677efc847ccc8123a14fdf", + "imdb_id": "tt1591468", + "name": "Chaos", + "type": "series", + "year": "2011" + }, + { + "_id": "53677f00847ccc8123a16336", + "imdb_id": "tt1029248", + "name": "Moribito: Guardian of the Spirit", + "type": "series", + "year": "2007" + }, + { + "_id": "53677f35847ccc8123a1eb42", + "imdb_id": "tt0103559", + "name": "Street Sharks", + "type": "series", + "year": "1994–1997" + }, + { + "_id": "5c2fe99a173739c9f4c205fe", + "imdb_id": "tt5724688", + "name": "Stolen Life", + "type": "series", + "year": "2016–" + }, + { + "_id": "608d0d4064ec43ef982f6c62", + "imdb_id": "tt14192040", + "name": "RuPaul's Drag Race Down Under", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677efd847ccc8123a15725", + "imdb_id": "tt0147746", + "name": "Batman Beyond", + "type": "series", + "year": "1999–2001" + }, + { + "_id": "5c0b3544173739c9f48fdfca", + "imdb_id": "tt0066707", + "name": "Sabrina the Teenage Witch", + "type": "series", + "year": "1971–1974" + }, + { + "_id": "53677f72847ccc8123a23546", + "imdb_id": "tt0409637", + "name": "Washington Week", + "type": "series", + "year": "1967–" + }, + { + "_id": "55072f9c711bd19c92add931", + "imdb_id": "tt0111877", + "name": "Almost Perfect", + "year": "1995–1996", + "type": "series" + }, + { + "_id": "5c3a763dd582b2575636cc2e", + "imdb_id": "tt0042111", + "name": "The George Burns and Gracie Allen Show", + "type": "series", + "year": "1950–1958" + }, + { + "_id": "5c1f4513173739c9f408d02d", + "imdb_id": "tt4616700", + "name": "Ore Monogatari!!", + "type": "series", + "year": "2015" + }, + { + "_id": "5c0a90df173739c9f44d76aa", + "imdb_id": "tt5223426", + "name": "Food: Fact or Fiction?", + "type": "series", + "year": "2015–" + }, + { + "_id": "53677efc847ccc8123a15322", + "imdb_id": "tt0460637", + "name": "Everybody Hates Chris", + "type": "series", + "year": "2005–2024" + }, + { + "_id": "5672c5babb83c66498991c42", + "imdb_id": "tt4254242", + "name": "The Magicians", + "year": "2015–2020", + "type": "series" + }, + { + "_id": "5a61ef23543165dcd87c3bd7", + "imdb_id": "tt5932548", + "type": "series", + "name": "Britannia", + "year": "2017–2021" + }, + { + "_id": "5c3d92bed582b25756dcdff0", + "imdb_id": "tt4219136", + "name": "THE IDOLM@STER CINDERELLA GIRLS", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "53677efd847ccc8123a159e7", + "imdb_id": "tt0063950", + "name": "Scooby Doo, Where Are You!", + "type": "series", + "year": "1969–1978" + }, + { + "_id": "5819ad5655f8aab460cfa87c", + "imdb_id": "tt0108755", + "name": "Duckman: Private Dick/Family Man", + "type": "series", + "year": "1994–1997" + }, + { + "_id": "53677f74847ccc8123a2389b", + "imdb_id": "tt0065296", + "name": "The Goodies", + "type": "series", + "year": "1970–1982" + }, + { + "_id": "62aed4ed64ec43ef988dabee", + "imdb_id": "tt10011306", + "name": "Spriggan", + "type": "series", + "year": "2022" + }, + { + "_id": "5378cc70847ccc8123ad59b2", + "imdb_id": "tt0088500", + "name": "Count Duckula", + "type": "series", + "year": "1988–1993" + }, + { + "_id": "54d7b484e573cadcfa1fb288", + "imdb_id": "tt3488298", + "name": "American Crime", + "type": "series", + "year": "2015–2017" + }, + { + "_id": "5a8ae9ce53336c1ba80f5241", + "imdb_id": "tt6317068", + "type": "series", + "name": "Final Space", + "year": "2018–2021" + }, + { + "_id": "5c1a41e3173739c9f41e5321", + "imdb_id": "tt8425308", + "name": "Magic for Humans", + "type": "series", + "year": "2018–2020" + }, + { + "_id": "55075d6d711bd19c92addd0d", + "imdb_id": "tt2595486", + "name": "Love Live!: School Idol Project", + "year": "2013–2014", + "type": "series" + }, + { + "_id": "6433aad264ec43ef983f445f", + "imdb_id": "tt27404658", + "name": "The Aristocrat's Otherworldly Adventure: Serving Gods Who Go Too Far", + "type": "series", + "year": "2023" + }, + { + "_id": "53677f1a847ccc8123a1b6ee", + "imdb_id": "tt0142183", + "name": "Super Dimension Fortress Macross", + "type": "series", + "year": "1982–2002" + }, + { + "_id": "53677f05847ccc8123a17676", + "imdb_id": "tt0907702", + "name": "Wallander", + "type": "series", + "year": "2005–2013" + }, + { + "_id": "5c1e836a173739c9f4c736bb", + "imdb_id": "tt8310612", + "name": "The Other Two", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "5c0c5715173739c9f4a05212", + "imdb_id": "tt5637544", + "name": "Guidance", + "type": "series", + "year": "2015–2017" + }, + { + "_id": "5c23bfc0173739c9f424a678", + "imdb_id": "tt0112193", + "name": "They Think It's All Over", + "type": "series", + "year": "1995–2011" + }, + { + "_id": "53677f4a847ccc8123a206be", + "imdb_id": "tt0094519", + "name": "The New Statesman", + "type": "series", + "year": "1987–1994" + }, + { + "_id": "607b6cd664ec43ef989e1461", + "imdb_id": "tt11945774", + "name": "Wahl Street", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "53677ef9847ccc8123a143be", + "imdb_id": "tt0090481", + "name": "Matlock", + "type": "series", + "year": "1986–1995" + }, + { + "_id": "5e9e7eda5424253341e6489b", + "imdb_id": "tt12057106", + "name": "Tower of God", + "type": "series", + "year": "2020" + }, + { + "_id": "53677f15847ccc8123a1a756", + "imdb_id": "tt1740718", + "name": "The Talk", + "type": "series", + "year": "2010–" + }, + { + "_id": "53677f5a847ccc8123a21b75", + "imdb_id": "tt1128052", + "name": "WordGirl", + "type": "series", + "year": "2007–2015" + }, + { + "_id": "53677f4a847ccc8123a206ab", + "imdb_id": "tt0047773", + "name": "Soldiers of Fortune", + "type": "series", + "year": "1955–1957" + }, + { + "_id": "5388b7bfa8f27b1bb90abf54", + "imdb_id": "tt2788780", + "name": "Undateable", + "type": "series", + "year": "2014–2016" + }, + { + "_id": "54fb5f50711bd19c92ad445a", + "imdb_id": "tt3062788", + "name": "Kate and Mim-Mim", + "year": "2014–", + "type": "series" + }, + { + "_id": "53677f57847ccc8123a21623", + "imdb_id": "tt0061280", + "name": "The Mothers-In-Law", + "type": "series", + "year": "1967–1969" + }, + { + "_id": "5c0a619f173739c9f4f53c0c", + "imdb_id": "tt6901486", + "name": "Seven Mortal Sins", + "type": "series", + "year": "2017" + }, + { + "_id": "53677f0c847ccc8123a1928a", + "imdb_id": "tt0083483", + "name": "St. Elsewhere", + "type": "series", + "year": "1982–1988" + }, + { + "_id": "57e09487d7e54929823e5b55", + "imdb_id": "tt5462720", + "type": "series", + "name": "Kevin Can Wait", + "year": "2016–2018" + }, + { + "_id": "5c037f30173739c9f402585f", + "imdb_id": "tt7645192", + "name": "Baby", + "type": "series", + "year": "2018–2020" + }, + { + "_id": "5c16c760173739c9f4212daa", + "imdb_id": "tt7005920", + "name": "Ready, Steady, Wiggle!", + "type": "series", + "year": "2013–2023" + }, + { + "_id": "53677f54847ccc8123a213d1", + "imdb_id": "tt0111932", + "name": "Cybill", + "type": "series", + "year": "1995–1998" + }, + { + "_id": "5c206db4173739c9f42c3611", + "imdb_id": "tt0051283", + "name": "The Huckleberry Hound Show", + "type": "series", + "year": "1958–1962" + }, + { + "_id": "542d1638a8f27b1bb90cf4b4", + "imdb_id": "tt3640276", + "name": "The Brokenwood Mysteries", + "type": "series", + "year": "2014–" + }, + { + "_id": "53677f0a847ccc8123a1887f", + "imdb_id": "tt0052472", + "name": "Hawaiian Eye", + "type": "series", + "year": "1959–1963" + }, + { + "_id": "5c153e69173739c9f45272cd", + "imdb_id": "tt8236528", + "name": "Wok of Love", + "type": "series", + "year": "2018" + }, + { + "_id": "5c32bacd173739c9f4bd72da", + "imdb_id": "tt0353078", + "name": "The Monkey King", + "type": "series", + "year": "2002–" + }, + { + "_id": "633f29d464ec43ef98c138cb", + "imdb_id": "tt14367168", + "name": "Let the Right One In", + "type": "series", + "year": "2022" + }, + { + "_id": "53677f40847ccc8123a1f543", + "imdb_id": "tt1723760", + "name": "Dallas", + "type": "series", + "year": "2012–2014" + }, + { + "_id": "53677f17847ccc8123a1b026", + "imdb_id": "tt0138956", + "name": "Beyond Belief: Fact or Fiction", + "type": "series", + "year": "1997–2024" + }, + { + "_id": "635678bd64ec43ef98ddf7a6", + "imdb_id": "tt16358384", + "name": "Tulsa King", + "type": "series", + "year": "2022–" + }, + { + "_id": "5c11d797173739c9f4551f61", + "imdb_id": "tt8269398", + "name": "Come and Hug Me", + "type": "series", + "year": "2018" + }, + { + "_id": "53c6f7daa8f27b1bb90b80ed", + "imdb_id": "tt0115275", + "name": "Moesha", + "type": "series", + "year": "1996–2001" + }, + { + "_id": "53677ef9847ccc8123a13802", + "imdb_id": "tt1582350", + "name": "Episodes", + "type": "series", + "year": "2011–2017" + }, + { + "_id": "53677f04847ccc8123a17517", + "imdb_id": "tt0908454", + "name": "Gavin & Stacey", + "type": "series", + "year": "2007–2019" + }, + { + "_id": "5c0c43e0173739c9f4779b88", + "imdb_id": "tt0080199", + "name": "The Big Show", + "type": "series", + "year": "1980" + }, + { + "_id": "53677f17847ccc8123a1ae5b", + "imdb_id": "tt0061281", + "name": "Mr. Terrific", + "type": "series", + "year": "1966–1967" + }, + { + "_id": "53677f14847ccc8123a1a55b", + "imdb_id": "tt0081831", + "name": "Bergerac", + "type": "series", + "year": "1981–1991" + }, + { + "_id": "53677ef9847ccc8123a13c13", + "imdb_id": "tt1703925", + "name": "Wilfred", + "type": "series", + "year": "2011–2014" + }, + { + "_id": "53677efa847ccc8123a148a2", + "imdb_id": "tt0112175", + "name": "Spider-Man: The Animated Series", + "type": "series", + "year": "1994–1998" + }, + { + "_id": "62ef55dd64ec43ef9854868d", + "imdb_id": "tt15303180", + "name": "Lang leve de liefde", + "type": "series", + "year": "2020–" + }, + { + "_id": "568fc965bb83c664989bf8d1", + "imdb_id": "tt4118584", + "name": "Shades of Blue", + "year": "2016–2018", + "type": "series" + }, + { + "_id": "53677f00847ccc8123a167a1", + "imdb_id": "tt0106115", + "name": "Rocko's Modern Life", + "type": "series", + "year": "1993–1996" + }, + { + "_id": "5c5a56add582b25756e49b52", + "imdb_id": "tt1132201", + "name": "Bokura no", + "type": "series", + "year": "2007" + }, + { + "_id": "53677f1f847ccc8123a1c493", + "imdb_id": "tt0085108", + "name": "We Got It Made", + "type": "series", + "year": "1983–1988" + }, + { + "_id": "53677f47847ccc8123a2016f", + "imdb_id": "tt0229889", + "name": "El Chavo del Ocho", + "type": "series", + "year": "1972–1983" + }, + { + "_id": "53677ef9847ccc8123a13c36", + "imdb_id": "tt0337792", + "name": "Wire in the Blood", + "type": "series", + "year": "2002–2008" + }, + { + "_id": "53677f5e847ccc8123a222e1", + "imdb_id": "tt1518542", + "name": "Sarabhai V/S Sarabhai", + "type": "series", + "year": "2004–2017" + }, + { + "_id": "59ca0bab1712e0f4ddef875f", + "imdb_id": "tt7305166", + "type": "series", + "name": "The Opposition with Jordan Klepper", + "year": "2017–2018" + }, + { + "_id": "53677f40847ccc8123a1f71a", + "imdb_id": "tt0050055", + "name": "The Restless Gun", + "type": "series", + "year": "1957–1959" + }, + { + "_id": "5c1c6da8173739c9f41c5a2f", + "imdb_id": "tt0374366", + "name": "Steve Harvey's Big Time Challenge", + "type": "series", + "year": "2003–2005" + }, + { + "_id": "53677f2c847ccc8123a1e333", + "imdb_id": "tt2155025", + "name": "Please Like Me", + "type": "series", + "year": "2013–2016" + }, + { + "_id": "53677f29847ccc8123a1db40", + "imdb_id": "tt0108829", + "name": "Kommissar Rex", + "type": "series", + "year": "1994–2004" + }, + { + "_id": "55eefe62bf6c900d18416d94", + "imdb_id": "tt0108719", + "name": "Cardiac Arrest", + "year": "1994–1996", + "type": "series" + }, + { + "_id": "5507329e711bd19c92adda9b", + "imdb_id": "tt0202748", + "name": "Popular", + "year": "1999–2001", + "type": "series" + }, + { + "_id": "654632cbbd36726cbbdd8c01", + "imdb_id": "tt29366100", + "name": "Only for Love", + "type": "series", + "year": "2022–" + }, + { + "_id": "5c25f82c173739c9f40cc62e", + "imdb_id": "tt8372010", + "name": "Tsugumomo", + "type": "series", + "year": "2017–2020" + }, + { + "_id": "53677f08847ccc8123a182fe", + "imdb_id": "tt0450357", + "name": "Wonder Showzen", + "type": "series", + "year": "2000–2007" + }, + { + "_id": "53677f08847ccc8123a18540", + "imdb_id": "tt0363328", + "name": "Drake & Josh", + "type": "series", + "year": "2004–2007" + }, + { + "_id": "622b5a2f64ec43ef981f39d2", + "imdb_id": "tt14432384", + "name": "Theodosia", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677f00847ccc8123a163b1", + "imdb_id": "tt1685397", + "name": "Amagami SS", + "type": "series", + "year": "2010–2011" + }, + { + "_id": "5503a5c4711bd19c92add623", + "imdb_id": "tt4354880", + "name": "Mr. Mercedes", + "year": "2017–2019", + "type": "series" + }, + { + "_id": "5a7ffb5b543165dcd86d63dc", + "imdb_id": "tt7369974", + "type": "series", + "name": "Step Up: High Water", + "year": "2018–2022" + }, + { + "_id": "5da69794c4ccb5dd92d36e05", + "imdb_id": "tt8289480", + "name": "Treadstone", + "type": "series", + "year": "2019" + }, + { + "_id": "5fbe747954242533417f160e", + "imdb_id": "tt11032396", + "name": "Saved by the Bell", + "type": "series", + "year": "2020–2021" + }, + { + "_id": "554c85b816e3a4523a768a24", + "imdb_id": "tt4086030", + "name": "The Henry Ford Innovation Nation with Mo Rocca", + "year": "2014–", + "type": "series" + }, + { + "_id": "5c5dc9cbd582b257567b9905", + "imdb_id": "tt9615014", + "name": "Lego Masters", + "type": "series", + "year": "2020–" + }, + { + "_id": "5c32b5f2173739c9f4b78303", + "imdb_id": "tt8134186", + "name": "Devs", + "type": "series", + "year": "2020" + }, + { + "_id": "53677ef9847ccc8123a1420c", + "imdb_id": "tt1319598", + "name": "Meet the Browns", + "type": "series", + "year": "2009–2012" + }, + { + "_id": "5c291707173739c9f49170c0", + "imdb_id": "tt9458372", + "name": "Boogiepop and Others", + "type": "series", + "year": "2019" + }, + { + "_id": "5b49cd2b16f4806c2ac47c15", + "imdb_id": "tt5916218", + "type": "series", + "name": "Skylanders Academy", + "year": "2016–2018" + }, + { + "_id": "53677ef9847ccc8123a14363", + "imdb_id": "tt1112285", + "name": "Fear Itself", + "type": "series", + "year": "2008–2009" + }, + { + "_id": "603dd0aa5424253341c8981f", + "imdb_id": "tt11640020", + "name": "Debris", + "type": "series", + "year": "2021" + }, + { + "_id": "654e010fbd36726cbb0ac369", + "imdb_id": "tt13623608", + "name": "The Curse", + "type": "series", + "year": "2023–" + }, + { + "_id": "5c0a26e5173739c9f48ca2b3", + "imdb_id": "tt1074206", + "type": "series", + "name": "The Passage", + "year": "2019" + }, + { + "_id": "54fb899a711bd19c92ad483a", + "imdb_id": "tt0877507", + "name": "Buso Renkin", + "year": "2006–2007", + "type": "series" + }, + { + "_id": "5c17c1e7173739c9f4a539f1", + "imdb_id": "tt0108964", + "name": "Toen was geluk heel gewoon", + "type": "series", + "year": "1994–2009" + }, + { + "_id": "53677f17847ccc8123a1ac81", + "imdb_id": "tt0140644", + "name": "Space Battleship Yamato", + "type": "series", + "year": "1974–1975" + }, + { + "_id": "53677f4a847ccc8123a2066e", + "imdb_id": "tt0112196", + "name": "The Tick", + "type": "series", + "year": "1994–1997" + }, + { + "_id": "53677ef9847ccc8123a139aa", + "imdb_id": "tt0439100", + "name": "Weeds", + "type": "series", + "year": "2005–2012" + }, + { + "_id": "53677f15847ccc8123a1a6b9", + "imdb_id": "tt2560140", + "name": "Attack on Titan", + "type": "series", + "year": "2013–2023" + }, + { + "_id": "53677f5a847ccc8123a21bb3", + "imdb_id": "tt0280240", + "name": "The Big O", + "type": "series", + "year": "1999–2023" + }, + { + "_id": "54fb5f36711bd19c92ad4384", + "imdb_id": "tt0088507", + "name": "Dirty Pair", + "year": "1985–1988", + "type": "series" + }, + { + "_id": "54fb899a711bd19c92ad4837", + "imdb_id": "tt0185655", + "name": "Spaceketeers", + "year": "1978–1979", + "type": "series" + }, + { + "_id": "53677f2c847ccc8123a1e2df", + "imdb_id": "tt1494191", + "name": "The Untold History of the United States", + "type": "series", + "year": "2012–2013" + }, + { + "_id": "53677ef9847ccc8123a13850", + "imdb_id": "tt1643266", + "name": "Ancient Aliens", + "type": "series", + "year": "2009–" + }, + { + "_id": "64bfd142bd36726cbbb78ef4", + "imdb_id": "tt21844490", + "name": "Dark Gathering", + "type": "series", + "year": "2023–" + }, + { + "_id": "589d216d1635517fbf56d91d", + "imdb_id": "tt5651762", + "name": "The Quad", + "type": "series", + "year": "2017–2018" + }, + { + "_id": "53677efd847ccc8123a15653", + "imdb_id": "tt0068049", + "name": "The Bob Newhart Show", + "type": "series", + "year": "1972–1978" + }, + { + "_id": "61630ae964ec43ef984ecdcd", + "imdb_id": "tt10635210", + "name": "Science Fell in Love, So I Tried to Prove It", + "type": "series", + "year": "2020–2022" + }, + { + "_id": "53677ef9847ccc8123a1441c", + "imdb_id": "tt0475047", + "name": "Hotel Babylon", + "type": "series", + "year": "2006–2009" + }, + { + "_id": "54df8d6ce573cadcfa1fcf78", + "imdb_id": "tt3957196", + "name": "Yona of the Dawn", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "61de4d8364ec43ef98a58188", + "imdb_id": "tt13624900", + "name": "Naomi", + "type": "series", + "year": "2022" + }, + { + "_id": "53677f1d847ccc8123a1bf0b", + "imdb_id": "tt0844203", + "name": "The One Show", + "type": "series", + "year": "2006–" + }, + { + "_id": "53677f0c847ccc8123a19175", + "imdb_id": "tt0094516", + "name": "My Secret Identity", + "type": "series", + "year": "1988–1991" + }, + { + "_id": "53677efa847ccc8123a14a2f", + "imdb_id": "tt1727434", + "name": "My Babysitter's a Vampire", + "type": "series", + "year": "2011–2012" + }, + { + "_id": "60d964b964ec43ef980ffe62", + "imdb_id": "tt10199718", + "name": "Gold Diggers", + "type": "series", + "year": "2019–" + }, + { + "_id": "5bec7726173739c9f4624dbc", + "imdb_id": "tt7801780", + "name": "Origin", + "type": "series", + "year": "2018" + }, + { + "_id": "5c1b5ff5173739c9f4269ff6", + "imdb_id": "tt8199790", + "name": "Joe Pera Talks with You", + "type": "series", + "year": "2018–2021" + }, + { + "_id": "53677f23847ccc8123a1cf85", + "imdb_id": "tt2836308", + "name": "Adam Devine's House Party", + "type": "series", + "year": "2013–" + }, + { + "_id": "642874a864ec43ef988cba8e", + "imdb_id": "tt13911284", + "name": "Hell's Paradise: Jigokuraku", + "type": "series", + "year": "2023–" + }, + { + "_id": "536907e7847ccc8123acdcd7", + "imdb_id": "tt0139803", + "name": "Top of the Pops", + "type": "series", + "year": "1964–2022" + }, + { + "_id": "53677f12847ccc8123a19ecb", + "imdb_id": "tt0220880", + "name": "Courage the Cowardly Dog", + "type": "series", + "year": "1999–2002" + }, + { + "_id": "5c0db572173739c9f40d4aa6", + "imdb_id": "tt0098818", + "name": "Harry and the Hendersons", + "type": "series", + "year": "1991–1993" + }, + { + "_id": "5c601a59d582b25756b3bb23", + "imdb_id": "tt0069632", + "name": "Sigmund and the Sea Monsters", + "type": "series", + "year": "1973–1975" + }, + { + "_id": "551bcc58cc9eee85bb52e0cd", + "imdb_id": "tt2312036", + "name": "East Los High", + "year": "2013–2017", + "type": "series" + }, + { + "_id": "5f033fec5424253341e857c7", + "imdb_id": "tt12227418", + "name": "The God of High School", + "type": "series", + "year": "2020" + }, + { + "_id": "5c517344d582b25756201533", + "imdb_id": "tt0190897", + "name": "The All-New Popeye Hour", + "type": "series", + "year": "1978–1983" + }, + { + "_id": "54f466ac451edcfca9b1c576", + "imdb_id": "tt3516878", + "name": "Secrets and Lies", + "year": "2015–2016", + "type": "series" + }, + { + "_id": "5c1b07ed173739c9f4aba645", + "imdb_id": "tt5827092", + "name": "Macross Delta", + "type": "series", + "year": "2015–2016" + }, + { + "_id": "5c0b59d3173739c9f4bc9af3", + "imdb_id": "tt4046242", + "name": "Ai Tenchi Muyo!", + "type": "series", + "year": "2014" + }, + { + "_id": "53677efd847ccc8123a1547e", + "imdb_id": "tt0103466", + "name": "The Larry Sanders Show", + "type": "series", + "year": "1992–1998" + }, + { + "_id": "5c0c05ce173739c9f4f43989", + "imdb_id": "tt6157148", + "name": "Weightlifting Fairy Kim Bok-Joo", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "53677f1d847ccc8123a1be84", + "imdb_id": "tt0950721", + "name": "Back to You", + "type": "series", + "year": "2007–2008" + }, + { + "_id": "54cb9995e573cadcfa1f80a6", + "imdb_id": "tt3498622", + "name": "Fortitude", + "type": "series", + "year": "2015–2018" + }, + { + "_id": "5c0a30dc173739c9f49d5318", + "imdb_id": "tt9059350", + "name": "Warrior Nun", + "type": "series", + "year": "2020–2022" + }, + { + "_id": "64313fb964ec43ef98f4ba6a", + "imdb_id": "tt14648592", + "name": "Magical Destroyers", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677ef9847ccc8123a137ab", + "imdb_id": "tt0840196", + "name": "Skins", + "type": "series", + "year": "2007–2013" + }, + { + "_id": "536907e6847ccc8123acdcce", + "imdb_id": "tt0205195", + "name": "Ladies Man", + "type": "series", + "year": "1999–2001" + }, + { + "_id": "6260f0b064ec43ef9844cf4d", + "imdb_id": "tt15791630", + "name": "The Kardashians", + "type": "series", + "year": "2022–" + }, + { + "_id": "53677f00847ccc8123a16501", + "imdb_id": "tt1842127", + "name": "Mortal Kombat: Legacy", + "type": "series", + "year": "2011–2013" + }, + { + "_id": "53677f02847ccc8123a16d40", + "imdb_id": "tt0077064", + "name": "Prisoner", + "type": "series", + "year": "1979–1986" + }, + { + "_id": "5c119b62173739c9f4de0d70", + "imdb_id": "tt0075528", + "name": "Lou Grant", + "type": "series", + "year": "1977–1982" + }, + { + "_id": "5b1e9fff16f4806c2a295c8d", + "imdb_id": "tt7562112", + "type": "series", + "name": "Pose", + "year": "2018–2021" + }, + { + "_id": "5f0f08bc54242533419e3243", + "imdb_id": "tt9814116", + "name": "Brave New World", + "type": "series", + "year": "2020" + }, + { + "_id": "53677efa847ccc8123a14af1", + "imdb_id": "tt0103584", + "name": "X-Men: The Animated Series", + "type": "series", + "year": "1992–1997" + }, + { + "_id": "53677f66847ccc8123a229ab", + "imdb_id": "tt1675276", + "name": "Dan Vs.", + "type": "series", + "year": "2011–2013" + }, + { + "_id": "53690806847ccc8123acdea0", + "imdb_id": "tt2127216", + "name": "Un-Go", + "type": "series", + "year": "2011" + }, + { + "_id": "53677f1d847ccc8123a1be14", + "imdb_id": "tt0118364", + "name": "Just Shoot Me!", + "type": "series", + "year": "1997–2003" + }, + { + "_id": "5e3cde70c4ccb5dd928c71aa", + "imdb_id": "tt10327412", + "name": "Tommy", + "type": "series", + "year": "2020" + }, + { + "_id": "53677f1b847ccc8123a1ba01", + "imdb_id": "tt2666270", + "name": "About a Boy", + "type": "series", + "year": "2014–2015" + }, + { + "_id": "53677f47847ccc8123a20181", + "imdb_id": "tt0050067", + "name": "The Thin Man", + "type": "series", + "year": "1957–1959" + }, + { + "_id": "5c277c8a173739c9f4bae84d", + "imdb_id": "tt5120600", + "name": "Danger & Eggs", + "type": "series", + "year": "2015–2017" + }, + { + "_id": "53677ef9847ccc8123a13cae", + "imdb_id": "tt0388595", + "name": "Extreme Makeover: Home Edition", + "type": "series", + "year": "2003–2020" + }, + { + "_id": "581246ced7e5492982414bcb", + "imdb_id": "tt3655448", + "name": "The Young Pope", + "type": "series", + "year": "2016" + }, + { + "_id": "5c143613173739c9f48ca042", + "imdb_id": "tt7056766", + "name": "Reunited Worlds", + "type": "series", + "year": "2017" + }, + { + "_id": "54fb8993711bd19c92ad4822", + "imdb_id": "tt0159883", + "name": "Patlabor: The TV Series", + "year": "1989–1990", + "type": "series" + }, + { + "_id": "612dc4b964ec43ef9806e79e", + "imdb_id": "tt12851524", + "name": "Only Murders in the Building", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677f02847ccc8123a16bf6", + "imdb_id": "tt2654580", + "name": "Almost Human", + "type": "series", + "year": "2013–2014" + }, + { + "_id": "53677f71847ccc8123a234e8", + "imdb_id": "tt0324692", + "name": "Ant & Dec's Saturday Night Takeaway", + "type": "series", + "year": "2002–2023" + }, + { + "_id": "59c7a0eb1712e0f4dd3ca3b3", + "imdb_id": "tt6423364", + "type": "series", + "name": "Bad Blood", + "year": "2017–2018" + }, + { + "_id": "53677f08847ccc8123a182ef", + "imdb_id": "tt0235923", + "name": "Invader ZIM", + "type": "series", + "year": "2001–2006" + }, + { + "_id": "5c18e64c173739c9f48dfb97", + "imdb_id": "tt0417306", + "name": "CMT Crossroads", + "type": "series", + "year": "2002–" + }, + { + "_id": "53677efc847ccc8123a14fcd", + "imdb_id": "tt0238793", + "name": "Monarch of the Glen", + "type": "series", + "year": "2000–2005" + }, + { + "_id": "5c198d5b173739c9f4db45b4", + "imdb_id": "tt6562134", + "name": "VeggieTales in the City", + "type": "series", + "year": "2017" + }, + { + "_id": "55a648adbf6c900d183ad16c", + "imdb_id": "tt4731072", + "name": "Food Wars: Shokugeki no Soma", + "year": "2015–2020", + "type": "series" + }, + { + "_id": "5ef016445424253341d72e30", + "imdb_id": "tt2077823", + "name": "Perry Mason", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "5c1d4986173739c9f499861f", + "imdb_id": "tt0480499", + "name": "Team Galaxy", + "type": "series", + "year": "2006–2008" + }, + { + "_id": "5c0d7363173739c9f485ec8f", + "imdb_id": "tt1209393", + "name": "Vampire Knight", + "type": "series", + "year": "2008" + }, + { + "_id": "64c51881bd36726cbb3285b7", + "imdb_id": "tt11691774", + "name": "Only Murders in the Building", + "type": "series", + "year": "2021–" + }, + { + "_id": "5c1a8f6e173739c9f4b7b7f6", + "imdb_id": "tt0293994", + "name": "Zillion", + "type": "series", + "year": "1987" + }, + { + "_id": "53677ef9847ccc8123a13a86", + "imdb_id": "tt1297754", + "name": "Republic of Doyle", + "type": "series", + "year": "2010–2014" + }, + { + "_id": "5f548d0a542425334184b998", + "imdb_id": "tt10732104", + "name": "Power Book II: Ghost", + "type": "series", + "year": "2020–" + }, + { + "_id": "53677f09847ccc8123a185e1", + "imdb_id": "tt3443306", + "name": "The Qwaser of Stigmata II", + "type": "series", + "year": "2010–2011" + }, + { + "_id": "55075d8b711bd19c92addee2", + "imdb_id": "tt2250100", + "name": "The Ambition of Oda Nobuna", + "year": "2012–", + "type": "series" + }, + { + "_id": "5c1fa77c173739c9f4c70c8e", + "imdb_id": "tt0061294", + "name": "Shazzan", + "type": "series", + "year": "1967–1969" + }, + { + "_id": "5c4e6a36d582b257564a631c", + "imdb_id": "tt5363872", + "name": "Bajillion Dollar Propertie$", + "type": "series", + "year": "2016–2019" + }, + { + "_id": "5db1d4b1c4ccb5dd9278c022", + "imdb_id": "tt10752770", + "name": "Sistas", + "type": "series", + "year": "2019–" + }, + { + "_id": "5bf77c35173739c9f4a34c17", + "imdb_id": "tt6052530", + "name": "Quotidien", + "type": "series", + "year": "2016–" + }, + { + "_id": "53677f29847ccc8123a1de18", + "imdb_id": "tt2659152", + "name": "WWE Main Event", + "type": "series", + "year": "2012–" + }, + { + "_id": "5c152007173739c9f4119097", + "imdb_id": "tt7406334", + "name": "Black Monday", + "type": "series", + "year": "2019–2021" + }, + { + "_id": "5c60cab9d582b25756b59c1a", + "imdb_id": "tt0108880", + "name": "Ninja Sentai Kakuranger", + "type": "series", + "year": "1994–1995" + }, + { + "_id": "53677ef9847ccc8123a13cde", + "imdb_id": "tt0485301", + "name": "Torchwood", + "type": "series", + "year": "2006–2011" + }, + { + "_id": "5c52205bd582b257561d8a55", + "imdb_id": "tt9067020", + "name": "The I-Land", + "type": "series", + "year": "2019" + }, + { + "_id": "659e291fbd36726cbb9a8c21", + "imdb_id": "tt21088136", + "name": "Criminal Record", + "type": "series", + "year": "2024–" + }, + { + "_id": "5c30d477173739c9f450aaf3", + "imdb_id": "tt6283624", + "name": "Radio Star", + "type": "series", + "year": "2007–" + }, + { + "_id": "61ee0cfe64ec43ef9866f075", + "imdb_id": "tt11958610", + "name": "Trigger Point", + "type": "series", + "year": "2022–" + }, + { + "_id": "5887457a1635517fbf56a29d", + "imdb_id": "tt5339440", + "name": "One Day at a Time", + "type": "series", + "year": "2017–2020" + }, + { + "_id": "53677f40847ccc8123a1f5a7", + "imdb_id": "tt0218769", + "name": "I Am Weasel", + "type": "series", + "year": "1997–1999" + }, + { + "_id": "5c4d0f04d582b25756991874", + "imdb_id": "tt0387775", + "name": "Sakigake!! Cromartie Kôkô", + "type": "series", + "year": "2003–2004" + }, + { + "_id": "62cd94c264ec43ef980ddedd", + "imdb_id": "tt18561422", + "name": "Vermeil in Gold: A Desperate Magician Barges Into the Magical World Alongside the Strongest Calamity", + "type": "series", + "year": "2022" + }, + { + "_id": "53677f54847ccc8123a2139e", + "imdb_id": "tt0052441", + "name": "The Alaskans", + "type": "series", + "year": "1959–1960" + }, + { + "_id": "5c45a8f6d582b2575698fabd", + "imdb_id": "tt8026448", + "name": "Tacoma FD", + "type": "series", + "year": "2019–" + }, + { + "_id": "5c11cdae173739c9f444fb8c", + "imdb_id": "tt5743796", + "name": "Warrior", + "type": "series", + "year": "2019–2023" + }, + { + "_id": "5bfae6a8173739c9f43fcc53", + "imdb_id": "tt5830254", + "name": "Das Boot", + "type": "series", + "year": "2018–" + }, + { + "_id": "53677f19847ccc8123a1b3ec", + "imdb_id": "tt2402207", + "name": "The Last Ship", + "type": "series", + "year": "2014–2018" + }, + { + "_id": "53677f5a847ccc8123a21c2c", + "imdb_id": "tt0247087", + "name": "The District", + "type": "series", + "year": "2000–2004" + }, + { + "_id": "606da77e54242533412bd9f0", + "imdb_id": "tt12439466", + "name": "Love Is in the Air", + "type": "series", + "year": "2020–2021" + }, + { + "_id": "5c61b465d582b25756c962ae", + "imdb_id": "tt1227046", + "name": "Shadow Star Narutaru", + "type": "series", + "year": "2003–" + }, + { + "_id": "57df8232d7e54929823e4cc2", + "imdb_id": "tt0310416", + "name": "Australian Survivor", + "year": "2002–", + "type": "series" + }, + { + "_id": "5446aeeda8f27b1bb90d5ee5", + "imdb_id": "tt2294048", + "name": "Blast of Tempest", + "type": "series", + "year": "2012–2013" + }, + { + "_id": "5c19f679173739c9f48edf4d", + "imdb_id": "tt9421868", + "name": "Selena: The Series", + "type": "series", + "year": "2020–2021" + }, + { + "_id": "6340ed2864ec43ef982ee380", + "imdb_id": "tt16098700", + "name": "Fire Country", + "type": "series", + "year": "2022–" + }, + { + "_id": "64cfc2e6bd36726cbb47fdc0", + "imdb_id": "tt27729024", + "name": "100 Years of Warner Bros.", + "type": "series", + "year": "2023" + }, + { + "_id": "5fc1a64254242533413b5e44", + "imdb_id": "tt13218362", + "name": "Kongen befaler", + "type": "series", + "year": "2019–" + }, + { + "_id": "53677ef9847ccc8123a13795", + "imdb_id": "tt1798274", + "name": "The Lying Game", + "type": "series", + "year": "2011–2013" + }, + { + "_id": "607720f964ec43ef980e4903", + "imdb_id": "tt13049906", + "name": "The Saint's Magic Power Is Omnipotent", + "type": "series", + "year": "2021–" + }, + { + "_id": "6221a86e64ec43ef98b220fe", + "imdb_id": "tt16350094", + "name": "The Boys Presents: Diabolical", + "type": "series", + "year": "2022" + }, + { + "_id": "542ed14ca8f27b1bb90cfc52", + "imdb_id": "tt0213377", + "name": "Widget, the World Watcher", + "type": "series", + "year": "1990–" + }, + { + "_id": "5b8e9330173739c9f47d687d", + "imdb_id": "tt6487482", + "name": "Insatiable", + "type": "series", + "year": "2018–2019" + }, + { + "_id": "53677f05847ccc8123a179aa", + "imdb_id": "tt1548669", + "name": "Gravity", + "type": "series", + "year": "2010" + }, + { + "_id": "5c0c6575173739c9f4be2989", + "imdb_id": "tt1208358", + "name": "Blade of the Immortal", + "type": "series", + "year": "2008" + }, + { + "_id": "53677ef9847ccc8123a139d2", + "imdb_id": "tt1319900", + "name": "Ghost Adventures", + "type": "series", + "year": "2008–" + }, + { + "_id": "53677f02847ccc8123a16931", + "imdb_id": "tt0044231", + "name": "Adventures of Superman", + "type": "series", + "year": "1952–1958" + }, + { + "_id": "5c4b86c1d582b2575694da43", + "imdb_id": "tt0462653", + "name": "Xabungle", + "type": "series", + "year": "1982–1983" + }, + { + "_id": "5c09b541173739c9f4e44eec", + "imdb_id": "tt0406429", + "name": "Law & Order: Trial by Jury", + "type": "series", + "year": "2005–2006" + }, + { + "_id": "55fa7ed4bf6c900d1841f473", + "imdb_id": "tt4474310", + "name": "The Player", + "year": "2015", + "type": "series" + }, + { + "_id": "53677f22847ccc8123a1ce68", + "imdb_id": "tt0053522", + "name": "The Famous Adventures of Mr. Magoo", + "type": "series", + "year": "1964–1965" + }, + { + "_id": "5c223749173739c9f4499a9c", + "imdb_id": "tt1394286", + "name": "Chrome Shelled Regios", + "type": "series", + "year": "2009" + }, + { + "_id": "53677f32847ccc8123a1e83c", + "imdb_id": "tt0366027", + "name": "I'm with Her", + "type": "series", + "year": "2003–2004" + }, + { + "_id": "53677f6d847ccc8123a231a3", + "imdb_id": "tt0086727", + "name": "The Henderson Kids", + "type": "series", + "year": "1985–1986" + }, + { + "_id": "53677f0f847ccc8123a19c42", + "imdb_id": "tt0988820", + "name": "The Inspector Lynley Mysteries", + "type": "series", + "year": "2001–2007" + }, + { + "_id": "53677efe847ccc8123a15bcd", + "imdb_id": "tt0057729", + "name": "The Addams Family", + "type": "series", + "year": "1964–1966" + }, + { + "_id": "5c280129173739c9f4c67efc", + "imdb_id": "tt0159855", + "name": "Voltes Five", + "type": "series", + "year": "1977–1978" + }, + { + "_id": "53677f02847ccc8123a16f10", + "imdb_id": "tt1158671", + "name": "Spice and Wolf", + "type": "series", + "year": "2008–2009" + }, + { + "_id": "5c11319f173739c9f4019f94", + "imdb_id": "tt0217910", + "name": "The Amanda Show", + "type": "series", + "year": "1999–2002" + }, + { + "_id": "5c267179173739c9f4fcf689", + "imdb_id": "tt0925436", + "name": "Idaten Jump", + "type": "series", + "year": "2005–2006" + }, + { + "_id": "640f111c64ec43ef98a8e309", + "imdb_id": "tt9794044", + "name": "Citadel", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677ef9847ccc8123a13b51", + "imdb_id": "tt1319636", + "name": "Dark Blue", + "type": "series", + "year": "2009–2010" + }, + { + "_id": "5c243d18173739c9f41f7d23", + "imdb_id": "tt1639471", + "name": "Arakawa Under the Bridge", + "type": "series", + "year": "2010" + }, + { + "_id": "5c5335b7d582b257568d904d", + "imdb_id": "tt0045411", + "name": "The Man Behind the Badge", + "type": "series", + "year": "1953–1955" + }, + { + "_id": "53677ef9847ccc8123a13d7c", + "imdb_id": "tt0463827", + "name": "Mock the Week", + "type": "series", + "year": "2005–2022" + }, + { + "_id": "656b94d9bd36726cbb5c37ce", + "imdb_id": "tt28348835", + "name": "Castaway Diva", + "type": "series", + "year": "2023–" + }, + { + "_id": "53677f4a847ccc8123a206a1", + "imdb_id": "tt0411003", + "name": "LAX", + "type": "series", + "year": "2004–2005" + }, + { + "_id": "53677efa847ccc8123a14763", + "imdb_id": "tt1492966", + "name": "Louie", + "type": "series", + "year": "2010–2015" + }, + { + "_id": "53677f6f847ccc8123a232e2", + "imdb_id": "tt2322158", + "name": "Crisis", + "type": "series", + "year": "2014" + }, + { + "_id": "5ff5b9b9542425334178ada9", + "imdb_id": "tt13273826", + "name": "The Uncanny Counter", + "type": "series", + "year": "2020–2023" + }, + { + "_id": "53677eff847ccc8123a160df", + "imdb_id": "tt0144069", + "name": "Street Fighter II: V", + "type": "series", + "year": "1995" + }, + { + "_id": "53677f72847ccc8123a23535", + "imdb_id": "tt3496994", + "name": "Saint George", + "type": "series", + "year": "2014" + }, + { + "_id": "53677f12847ccc8123a19eac", + "imdb_id": "tt3322312", + "name": "Daredevil", + "type": "series", + "year": "2015–2018" + }, + { + "_id": "5c0f2328173739c9f46b3c8e", + "imdb_id": "tt8434720", + "name": "A Love So Beautiful", + "type": "series", + "year": "2017" + }, + { + "_id": "55c4bfcbbf6c900d183cce55", + "imdb_id": "tt4680240", + "name": "Club de Cuervos", + "year": "2015–2019", + "type": "series" + }, + { + "_id": "5d970f2bc4ccb5dd92b1d1bb", + "imdb_id": "tt7826108", + "name": "Raising Dion", + "type": "series", + "year": "2019–2022" + }, + { + "_id": "53677f1f847ccc8123a1c583", + "imdb_id": "tt0398617", + "name": "Zoids: Fuzors", + "type": "series", + "year": "2003–2005" + }, + { + "_id": "60b1319564ec43ef9886c1c6", + "imdb_id": "tt13405062", + "name": "Back Arrow", + "type": "series", + "year": "2021" + }, + { + "_id": "53677f6f847ccc8123a232f0", + "imdb_id": "tt0165592", + "name": "Play for Today", + "type": "series", + "year": "1970–1984" + }, + { + "_id": "53677eff847ccc8123a15e3f", + "imdb_id": "tt0391666", + "name": "Morangos com Açúcar", + "type": "series", + "year": "2003–2012" + }, + { + "_id": "5c2f4b1b173739c9f47d32a7", + "imdb_id": "tt0081852", + "name": "Dr. Slump", + "type": "series", + "year": "1981–1986" + }, + { + "_id": "633ac17764ec43ef984143e2", + "imdb_id": "tt14932528", + "name": "Don't Hug Me I'm Scared", + "type": "series", + "year": "2022–" + }, + { + "_id": "54fdec2d711bd19c92adc454", + "imdb_id": "tt0985492", + "name": "Toward the Terra", + "year": "2007", + "type": "series" + }, + { + "_id": "53677f6d847ccc8123a23279", + "imdb_id": "tt2832756", + "name": "Love Child", + "type": "series", + "year": "2014–2017" + }, + { + "_id": "5a28ce05543165dcd8fa10ce", + "imdb_id": "tt2452242", + "type": "series", + "name": "Happy!", + "year": "2017–2019" + }, + { + "_id": "53677f1e847ccc8123a1c1e7", + "imdb_id": "tt0096531", + "name": "Alien Nation", + "type": "series", + "year": "1989–1990" + }, + { + "_id": "583c367cb0a40c25066d909f", + "imdb_id": "tt4659174", + "name": "Ice", + "type": "series", + "year": "2016–" + }, + { + "_id": "615dceeb64ec43ef98f26ff9", + "imdb_id": "tt13483212", + "name": "Banished from the Hero's Party, I Decided to Live a Quiet Life in the Countryside", + "type": "series", + "year": "2021–" + }, + { + "_id": "57fdd0a1d7e54929823ff76d", + "imdb_id": "tt4422756", + "name": "The Real O'Neals", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "5c2ba894173739c9f412e5a9", + "imdb_id": "tt6220550", + "name": "Hip Whip Girl: Keijo!!!!!!", + "type": "series", + "year": "2016–2017" + }, + { + "_id": "65299b4ebd36726cbb6b953e", + "imdb_id": "tt28774702", + "name": "The Kingdoms of Ruin", + "type": "series", + "year": "2023–" + }, + { + "_id": "5c251eb0173739c9f4a41061", + "imdb_id": "tt2374683", + "name": "Empresses in the Palace", + "type": "series", + "year": "2011–2012" + }, + { + "_id": "5c2bc2cc173739c9f44b39b4", + "imdb_id": "tt0111994", + "name": "Hang Time", + "type": "series", + "year": "1995–2000" + }, + { + "_id": "53677efa847ccc8123a145d2", + "imdb_id": "tt1149608", + "name": "Being Erica", + "type": "series", + "year": "2009–2011" + }, + { + "_id": "5c0c5f3c173739c9f4b14ebe", + "imdb_id": "tt0103463", + "name": "Dinosaur Squadron Zyuranger", + "type": "series", + "year": "1992–1993" + }, + { + "_id": "6097841c64ec43ef98d506c7", + "imdb_id": "tt13362302", + "name": "Shadows House", + "type": "series", + "year": "2021–2022" + }, + { + "_id": "53677ef9847ccc8123a13fe5", + "imdb_id": "tt1741256", + "name": "Suburgatory", + "type": "series", + "year": "2011–2014" + }, + { + "_id": "536907e9847ccc8123acdd3d", + "imdb_id": "tt0065317", + "name": "McCloud", + "type": "series", + "year": "1970–1977" + }, + { + "_id": "617241b264ec43ef9892f305", + "imdb_id": "tt9737326", + "name": "Invasion", + "type": "series", + "year": "2021–" + }, + { + "_id": "53677f0f847ccc8123a19871", + "imdb_id": "tt0203248", + "name": "Bad Girls", + "type": "series", + "year": "1999–2006" + }, + { + "_id": "53677efd847ccc8123a15695", + "imdb_id": "tt0273026", + "name": "Timewatch", + "type": "series", + "year": "1982–" + }, + { + "_id": "53677f4f847ccc8123a20d55", + "imdb_id": "tt0291672", + "name": "Time Squad", + "type": "series", + "year": "2001–2003" + } + ] +} \ No newline at end of file diff --git a/src/node/consumer/test/mock-responses/assets/flash-episode-list.json b/src/node/consumer/test/mock-responses/assets/flash-episode-list.json new file mode 100644 index 0000000..0b4878e --- /dev/null +++ b/src/node/consumer/test/mock-responses/assets/flash-episode-list.json @@ -0,0 +1,232 @@ +{ + "meta": { + "status": "Ended", + "videos": [ + { + "name": "Pilot", + "season": 1, + "number": 0, + "firstAired": "1990-09-20T00:00:00.000Z", + "rating": "6.6", + "id": "tt0098798:1:0", + "overview": "", + "imdb_id": "tt0099580" + }, + { + "name": "Out of Control", + "season": 1, + "number": 1, + "firstAired": "1990-09-26T00:00:00.000Z", + "rating": "6.8", + "id": "tt0098798:1:1", + "overview": "", + "imdb_id": "tt0579962" + }, + { + "name": "Watching the Detectives", + "season": 1, + "number": 2, + "firstAired": "1990-10-17T00:00:00.000Z", + "rating": "6.9", + "id": "tt0098798:1:2", + "overview": "", + "imdb_id": "tt0579971" + }, + { + "name": "Honor Among Thieves", + "season": 1, + "number": 3, + "firstAired": "1990-10-25T00:00:00.000Z", + "rating": "6.8", + "id": "tt0098798:1:3", + "overview": "", + "imdb_id": "tt0579961" + }, + { + "name": "Double Vision", + "season": 1, + "number": 4, + "firstAired": "1990-11-01T00:00:00.000Z", + "rating": "6.6", + "id": "tt0098798:1:4", + "overview": "", + "imdb_id": "tt0579957" + }, + { + "name": "Sins of the Father", + "season": 1, + "number": 5, + "firstAired": "1990-11-08T00:00:00.000Z", + "rating": "6.9", + "id": "tt0098798:1:5", + "overview": "", + "imdb_id": "tt0579965" + }, + { + "name": "Child's Play", + "season": 1, + "number": 6, + "firstAired": "1990-11-15T00:00:00.000Z", + "rating": "6.8", + "id": "tt0098798:1:6", + "overview": "", + "imdb_id": "tt0579955" + }, + { + "name": "Shroud of Death", + "season": 1, + "number": 7, + "firstAired": "1990-11-29T00:00:00.000Z", + "rating": "7.1", + "id": "tt0098798:1:7", + "overview": "", + "imdb_id": "tt0579963" + }, + { + "name": "Ghost in the Machine", + "season": 1, + "number": 8, + "firstAired": "1990-12-13T00:00:00.000Z", + "rating": "7.7", + "id": "tt0098798:1:8", + "overview": "", + "imdb_id": "tt0579959" + }, + { + "name": "Sight Unseen", + "season": 1, + "number": 9, + "firstAired": "1991-01-10T00:00:00.000Z", + "rating": "7", + "id": "tt0098798:1:9", + "overview": "", + "imdb_id": "tt0579964" + }, + { + "name": "Beat the Clock", + "season": 1, + "number": 10, + "firstAired": "1991-01-31T00:00:00.000Z", + "rating": "7", + "id": "tt0098798:1:10", + "overview": "", + "imdb_id": "tt0579953" + }, + { + "name": "The Trickster", + "season": 1, + "number": 11, + "firstAired": "1991-02-07T00:00:00.000Z", + "rating": "7.7", + "id": "tt0098798:1:11", + "overview": "", + "imdb_id": "tt0579969" + }, + { + "name": "Tina, Is That You?", + "season": 1, + "number": 12, + "firstAired": "1991-02-14T00:00:00.000Z", + "rating": "6.8", + "id": "tt0098798:1:12", + "overview": "", + "imdb_id": "tt0579967" + }, + { + "name": "Be My Baby", + "season": 1, + "number": 13, + "firstAired": "1991-02-20T00:00:00.000Z", + "rating": "6.5", + "id": "tt0098798:1:13", + "overview": "", + "imdb_id": "tt0579952" + }, + { + "name": "Fast Forward", + "season": 1, + "number": 14, + "firstAired": "1991-02-27T00:00:00.000Z", + "rating": "7.9", + "id": "tt0098798:1:14", + "overview": "", + "imdb_id": "tt0579958" + }, + { + "name": "Deadly Nightshade", + "season": 1, + "number": 15, + "firstAired": "1991-03-28T00:00:00.000Z", + "rating": "7.7", + "id": "tt0098798:1:15", + "overview": "", + "imdb_id": "tt0579966" + }, + { + "name": "Captain Cold", + "season": 1, + "number": 16, + "firstAired": "1991-04-05T00:00:00.000Z", + "rating": "7.7", + "id": "tt0098798:1:16", + "overview": "", + "imdb_id": "tt0579954" + }, + { + "name": "Twin Streaks", + "season": 1, + "number": 17, + "firstAired": "1991-04-12T00:00:00.000Z", + "rating": "7.1", + "id": "tt0098798:1:17", + "overview": "", + "imdb_id": "tt0579970" + }, + { + "name": "Done with Mirrors", + "season": 1, + "number": 18, + "firstAired": "1991-04-27T00:00:00.000Z", + "rating": "7.3", + "id": "tt0098798:1:18", + "overview": "", + "imdb_id": "tt0579956" + }, + { + "name": "Good Night, Central City", + "season": 1, + "number": 19, + "firstAired": "1991-05-04T00:00:00.000Z", + "rating": "7.1", + "id": "tt0098798:1:19", + "overview": "", + "imdb_id": "tt0579960" + }, + { + "name": "Alpha", + "season": 1, + "number": 20, + "firstAired": "1991-05-11T00:00:00.000Z", + "rating": "7.5", + "id": "tt0098798:1:20", + "overview": "", + "imdb_id": "tt0579951" + }, + { + "name": "Trial of the Trickster", + "season": 1, + "number": 21, + "firstAired": "1991-05-18T00:00:00.000Z", + "rating": "7.9", + "id": "tt0098798:1:21", + "overview": "", + "imdb_id": "tt0579968" + } + ], + "id": "tt0098798", + "behaviorHints": { + "defaultVideoId": null, + "hasScheduledVideos": false + } + } +} \ No newline at end of file diff --git a/src/node/consumer/test/mock-responses/assets/kitsu-naruto-full.json b/src/node/consumer/test/mock-responses/assets/kitsu-naruto-full.json new file mode 100644 index 0000000..61e2073 --- /dev/null +++ b/src/node/consumer/test/mock-responses/assets/kitsu-naruto-full.json @@ -0,0 +1,2491 @@ +{ + "meta": { + "id": "kitsu:11", + "kitsu_id": "11", + "type": "series", + "animeType": "TV", + "name": "Naruto", + "slug": "naruto", + "aliases": [ + "Naruto" + ], + "genres": [ + "Action", + "Comedy", + "Martial Arts", + "Super Power" + ], + "logo": "https://assets.fanart.tv/fanart/tv/78857/hdtvlogo/naruto-50667b3780bf2.png", + "poster": "https://media.kitsu.io/anime/11/poster_image/medium-410cee5d114a5f70d69e795755e8348a.jpeg", + "background": "https://assets.fanart.tv/fanart/tv/78857/showbackground/naruto-53b827ea97f87.jpg", + "description": "Moments prior to Naruto Uzumaki's birth, a huge demon known as the Kyuubi, the Nine-Tailed Fox, attacked Konohagakure, the Hidden Leaf Village, and wreaked havoc. In order to put an end to the Kyuubi's rampage, the leader of the village, the Fourth Hokage, sacrificed his life and sealed the monstrous beast inside the newborn Naruto.\nNow, Naruto is a hyperactive and knuckle-headed ninja still living in Konohagakure. Shunned because of the Kyuubi inside him, Naruto struggles to find his place in the village, while his burning desire to become the Hokage of Konohagakure leads him not only to some great new friends, but also some deadly foes.\n[Written by MAL Rewrite]", + "releaseInfo": "2002-2007", + "year": "2002-2007", + "imdbRating": "8.0", + "userCount": 156026, + "status": "finished", + "runtime": "23 min", + "trailers": [ + { + "source": "j2hiC9BmJlQ", + "type": "Trailer" + } + ], + "videos": [ + { + "id": "kitsu:11:1", + "title": "Enter: Naruto Uzumaki!", + "released": "2002-10-03T00:00:00.000Z", + "season": 1, + "episode": 1, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/451/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 1 + }, + { + "id": "kitsu:11:2", + "title": "My Name is Konohamaru!", + "released": "2002-10-10T00:00:00.000Z", + "season": 1, + "episode": 2, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/452/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 2 + }, + { + "id": "kitsu:11:3", + "title": "Sasuke and Sakura: Friends or Foes?", + "released": "2002-10-17T00:00:00.000Z", + "season": 1, + "episode": 3, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/453/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 3 + }, + { + "id": "kitsu:11:4", + "title": "Pass or Fail: Survival Test", + "released": "2002-10-24T00:00:00.000Z", + "season": 1, + "episode": 4, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/454/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 4 + }, + { + "id": "kitsu:11:5", + "title": "You Failed! Kakashi's Final Decision", + "released": "2002-10-31T00:00:00.000Z", + "season": 1, + "episode": 5, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/455/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 5 + }, + { + "id": "kitsu:11:6", + "title": "A Dangerous Mission! Journey to the Land of Waves!", + "released": "2002-11-07T00:00:00.000Z", + "season": 1, + "episode": 6, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/456/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 6 + }, + { + "id": "kitsu:11:7", + "title": "The Assassin of the Mist!", + "released": "2002-11-14T00:00:00.000Z", + "season": 1, + "episode": 7, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/457/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 7 + }, + { + "id": "kitsu:11:8", + "title": "The Oath of Pain", + "released": "2002-11-21T00:00:00.000Z", + "season": 1, + "episode": 8, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/458/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 8 + }, + { + "id": "kitsu:11:9", + "title": "Kakashi: Sharingan Warrior", + "released": "2002-11-28T00:00:00.000Z", + "season": 1, + "episode": 9, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/459/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 9 + }, + { + "id": "kitsu:11:10", + "title": "The Forest of Chakra", + "released": "2002-12-05T00:00:00.000Z", + "season": 1, + "episode": 10, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/460/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 10 + }, + { + "id": "kitsu:11:11", + "title": "The Land Where a Hero Once Lived", + "released": "2002-12-12T00:00:00.000Z", + "season": 1, + "episode": 11, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/461/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 11 + }, + { + "id": "kitsu:11:12", + "title": "Battle on the Bridge! Zabuza Returns!!", + "released": "2002-12-19T00:00:00.000Z", + "season": 1, + "episode": 12, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/462/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 12 + }, + { + "id": "kitsu:11:13", + "title": "Haku's Secret Jutsu: Crystal Ice Mirrors", + "released": "2002-12-26T00:00:00.000Z", + "season": 1, + "episode": 13, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/463/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 13 + }, + { + "id": "kitsu:11:14", + "title": "The Number One Hyperactive, Knucklehead Ninja Joins the Fight!!", + "released": "2003-01-09T00:00:00.000Z", + "season": 1, + "episode": 14, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/464/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 14 + }, + { + "id": "kitsu:11:15", + "title": "Zero Visibility: The Sharingan Shatters", + "released": "2003-01-16T00:00:00.000Z", + "season": 1, + "episode": 15, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/465/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 15 + }, + { + "id": "kitsu:11:16", + "title": "The Broken Seal", + "released": "2003-01-23T00:00:00.000Z", + "season": 1, + "episode": 16, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/466/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 16 + }, + { + "id": "kitsu:11:17", + "title": "White Past: Hidden Ambition", + "released": "2003-01-30T00:00:00.000Z", + "season": 1, + "episode": 17, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/467/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 17 + }, + { + "id": "kitsu:11:18", + "title": "The Weapons Known as Shinobi", + "released": "2003-02-06T00:00:00.000Z", + "season": 1, + "episode": 18, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/468/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 18 + }, + { + "id": "kitsu:11:19", + "title": "The Demon in the Snow", + "released": "2003-02-13T00:00:00.000Z", + "season": 1, + "episode": 19, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/469/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 19 + }, + { + "id": "kitsu:11:20", + "title": "A New Chapter Begins: The Chunin Exam!", + "released": "2003-02-20T00:00:00.000Z", + "season": 1, + "episode": 20, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/470/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 20 + }, + { + "id": "kitsu:11:21", + "title": "Identify Yourself: Powerful New Rivals", + "released": "2003-02-27T00:00:00.000Z", + "season": 1, + "episode": 21, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/471/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 21 + }, + { + "id": "kitsu:11:22", + "title": "Chunin Challenge: Rock Lee vs. Sasuke!", + "released": "2003-03-06T00:00:00.000Z", + "season": 1, + "episode": 22, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/472/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 22 + }, + { + "id": "kitsu:11:23", + "title": "Genin Takedown! All Nine Rookies Face Off!", + "released": "2003-03-13T00:00:00.000Z", + "season": 1, + "episode": 23, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/473/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 23 + }, + { + "id": "kitsu:11:24", + "title": "Start Your Engines: The Chunin Exam Begins!", + "released": "2003-03-20T00:00:00.000Z", + "season": 1, + "episode": 24, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/474/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 24 + }, + { + "id": "kitsu:11:25", + "title": "The Tenth Question: All or Nothing!", + "released": "2003-03-27T00:00:00.000Z", + "season": 1, + "episode": 25, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/475/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 25 + }, + { + "id": "kitsu:11:26", + "title": "Special Report: Live from the Forest of Death!", + "released": "2003-04-02T00:00:00.000Z", + "season": 1, + "episode": 26, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/476/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 26 + }, + { + "id": "kitsu:11:27", + "title": "The Chunin Exam Stage 2: The Forest of Death", + "released": "2003-04-02T00:00:00.000Z", + "season": 1, + "episode": 27, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/477/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 27 + }, + { + "id": "kitsu:11:28", + "title": "Eat or be Eaten: Panic in the Forest", + "released": "2003-04-09T00:00:00.000Z", + "season": 1, + "episode": 28, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/478/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 28 + }, + { + "id": "kitsu:11:29", + "title": "Naruto's Counterattack: Never Give In!", + "released": "2003-04-16T00:00:00.000Z", + "season": 1, + "episode": 29, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/479/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 29 + }, + { + "id": "kitsu:11:30", + "title": "The Sharingan Revived: Dragon-Flame Jutsu!", + "released": "2003-04-23T00:00:00.000Z", + "season": 1, + "episode": 30, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/480/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 30 + }, + { + "id": "kitsu:11:31", + "title": "Bushy Brow's Pledge: Undying Love and Protection!", + "released": "2003-04-30T00:00:00.000Z", + "season": 1, + "episode": 31, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/481/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 31 + }, + { + "id": "kitsu:11:32", + "title": "Sakura Blossoms!", + "released": "2003-05-07T00:00:00.000Z", + "season": 1, + "episode": 32, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/482/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 32 + }, + { + "id": "kitsu:11:33", + "title": "Battle Formation: Ino-Shika-Cho!", + "released": "2003-05-14T00:00:00.000Z", + "season": 1, + "episode": 33, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/483/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 33 + }, + { + "id": "kitsu:11:34", + "title": "Akamaru Trembles: Gaara's Cruel Strength!", + "released": "2003-05-21T00:00:00.000Z", + "season": 1, + "episode": 34, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/484/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 34 + }, + { + "id": "kitsu:11:35", + "title": "The Scroll's Secret: No Peeking Allowed", + "released": "2003-05-28T00:00:00.000Z", + "season": 1, + "episode": 35, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/485/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 1, + "imdbEpisode": 35 + }, + { + "id": "kitsu:11:36", + "title": "Clone vs. Clone: Mine are Better than Yours!", + "released": "2003-06-04T00:00:00.000Z", + "season": 1, + "episode": 36, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/172591/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 1 + }, + { + "id": "kitsu:11:37", + "title": "Surviving the Cut! The Rookie Nine Together Again!", + "released": "2003-06-11T00:00:00.000Z", + "season": 1, + "episode": 37, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/172592/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 2 + }, + { + "id": "kitsu:11:38", + "title": "Narrowing the Field: Sudden Death Elimination!", + "released": "2003-06-18T00:00:00.000Z", + "season": 1, + "episode": 38, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/172593/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 3 + }, + { + "id": "kitsu:11:39", + "title": "Bushy Brow's Jealousy: Lions Barrage Unleashed!", + "released": "2003-07-02T00:00:00.000Z", + "season": 1, + "episode": 39, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/172594/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 4 + }, + { + "id": "kitsu:11:40", + "title": "Kakashi and Orochimaru: Face-to-Face!", + "released": "2003-07-09T00:00:00.000Z", + "season": 1, + "episode": 40, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/172595/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 5 + }, + { + "id": "kitsu:11:41", + "title": "Kunoichi Rumble: The Rivals Get Serious!", + "released": "2003-07-16T00:00:00.000Z", + "season": 1, + "episode": 41, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/172596/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 6 + }, + { + "id": "kitsu:11:42", + "title": "The Ultimate Battle: Cha!", + "released": "2003-07-23T00:00:00.000Z", + "season": 1, + "episode": 42, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/172597/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 7 + }, + { + "id": "kitsu:11:43", + "title": "Killer Kunoichi and a Shaky Shikamaru", + "released": "2003-07-30T00:00:00.000Z", + "season": 1, + "episode": 43, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/172598/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 8 + }, + { + "id": "kitsu:11:44", + "title": "Akamaru Unleashed! Who's Top Dog Now?", + "released": "2003-08-06T00:00:00.000Z", + "season": 1, + "episode": 44, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/172599/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 9 + }, + { + "id": "kitsu:11:45", + "title": "Surprise Attack! Naruto's Secret Weapon!", + "released": "2003-08-20T00:00:00.000Z", + "season": 1, + "episode": 45, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/172600/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 10 + }, + { + "id": "kitsu:11:46", + "title": "Byakugan Battle: Hinata Grows Bold!", + "released": "2003-08-20T00:00:00.000Z", + "season": 1, + "episode": 46, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/172601/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 11 + }, + { + "id": "kitsu:11:47", + "title": "A Failure Stands Tall!", + "released": "2003-08-27T00:00:00.000Z", + "season": 1, + "episode": 47, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/172602/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 12 + }, + { + "id": "kitsu:11:48", + "title": "Gaara vs. Rock Lee: The Power of Youth Explodes!", + "released": "2003-09-03T00:00:00.000Z", + "season": 1, + "episode": 48, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/172603/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 13 + }, + { + "id": "kitsu:11:49", + "title": "Lee's Hidden Strength: Forbidden Secret Jutsu!", + "released": "2003-09-10T00:00:00.000Z", + "season": 1, + "episode": 49, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/499/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 14 + }, + { + "id": "kitsu:11:50", + "title": "The Fifth Gate: A Splendid Ninja is Born", + "released": "2003-09-17T00:00:00.000Z", + "season": 1, + "episode": 50, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/500/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 15 + }, + { + "id": "kitsu:11:51", + "title": "A Shadow in Darkness: Danger Approaches Sasuke", + "released": "2003-09-24T00:00:00.000Z", + "season": 1, + "episode": 51, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/501/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 16 + }, + { + "id": "kitsu:11:52", + "title": "Ebisu Returns: Naruto's Toughest Training Yet!", + "released": "2003-10-01T00:00:00.000Z", + "season": 1, + "episode": 52, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/502/original.jpeg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 17 + }, + { + "id": "kitsu:11:53", + "title": "Long Time No See: Jiraiya Returns!", + "released": "2003-10-08T00:00:00.000Z", + "season": 1, + "episode": 53, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167771/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 18 + }, + { + "id": "kitsu:11:54", + "title": "The Summoning Jutsu: Wisdom of the Toad Sage!", + "released": "2003-10-15T00:00:00.000Z", + "season": 1, + "episode": 54, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167772/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 19 + }, + { + "id": "kitsu:11:55", + "title": "A Feeling of Yearning, A Flower Full of Hope", + "released": "2003-10-22T00:00:00.000Z", + "season": 1, + "episode": 55, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167773/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 20 + }, + { + "id": "kitsu:11:56", + "title": "Live or Die: Risk it All to Win it All!", + "released": "2003-10-29T00:00:00.000Z", + "season": 1, + "episode": 56, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167774/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 21 + }, + { + "id": "kitsu:11:57", + "title": "He Flies! He Jumps! He Lurks! Chief Toad Appears!", + "released": "2003-11-05T00:00:00.000Z", + "season": 1, + "episode": 57, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167775/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 22 + }, + { + "id": "kitsu:11:58", + "title": "Hospital Besieged: The Evil Hand Revealed!", + "released": "2003-11-12T00:00:00.000Z", + "season": 1, + "episode": 58, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167776/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 23 + }, + { + "id": "kitsu:11:59", + "title": "The Final Rounds: Rush to the Battle Arena!", + "released": "2003-11-19T00:00:00.000Z", + "season": 1, + "episode": 59, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167777/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 24 + }, + { + "id": "kitsu:11:60", + "title": "Byakugan vs. Shadow Clone", + "released": "2003-11-26T00:00:00.000Z", + "season": 1, + "episode": 60, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167778/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 25 + }, + { + "id": "kitsu:11:61", + "title": "Ultimate Defense: Zero Blind Spot!", + "released": "2003-12-03T00:00:00.000Z", + "season": 1, + "episode": 61, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167779/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 26 + }, + { + "id": "kitsu:11:62", + "title": "A Failure's True Power", + "released": "2003-12-10T00:00:00.000Z", + "season": 1, + "episode": 62, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167780/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 27 + }, + { + "id": "kitsu:11:63", + "title": "Hit it or Quit it: The Final Rounds Get Complicated!", + "released": "2003-12-17T00:00:00.000Z", + "season": 1, + "episode": 63, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167781/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 28 + }, + { + "id": "kitsu:11:64", + "title": "Zero Motivation: The Guy with Cloud Envy!", + "released": "2003-12-24T00:00:00.000Z", + "season": 1, + "episode": 64, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167782/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 29 + }, + { + "id": "kitsu:11:65", + "title": "Dancing Leaf, Squirming Sand", + "released": "2004-01-07T00:00:00.000Z", + "season": 1, + "episode": 65, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167783/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 30 + }, + { + "id": "kitsu:11:66", + "title": "Bushy Brow's Jutsu: Sasuke Style!", + "released": "2004-01-14T00:00:00.000Z", + "season": 1, + "episode": 66, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167784/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 31 + }, + { + "id": "kitsu:11:67", + "title": "Late for the Show, But Ready to Go! The Ultimate Secret Technique is Born!", + "released": "2004-01-14T00:00:00.000Z", + "season": 1, + "episode": 67, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167785/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 32 + }, + { + "id": "kitsu:11:68", + "title": "Zero Hour! The Destruction of the Hidden Leaf Village Begins!", + "released": "2004-01-28T00:00:00.000Z", + "season": 1, + "episode": 68, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167786/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 33 + }, + { + "id": "kitsu:11:69", + "title": "Village in Distress: A New A-Ranked Mission!", + "released": "2004-02-04T00:00:00.000Z", + "season": 1, + "episode": 69, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167787/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 34 + }, + { + "id": "kitsu:11:70", + "title": "A Shirker's Call to Action: A Layabout No More!", + "released": "2004-02-11T00:00:00.000Z", + "season": 1, + "episode": 70, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167788/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 35 + }, + { + "id": "kitsu:11:71", + "title": "An Unrivaled Match: Hokage Battle Royale!", + "released": "2004-02-18T00:00:00.000Z", + "season": 1, + "episode": 71, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167789/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 36 + }, + { + "id": "kitsu:11:72", + "title": "A Mistake from the Past: A Face Revealed!", + "released": "2004-02-25T00:00:00.000Z", + "season": 1, + "episode": 72, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167790/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 37 + }, + { + "id": "kitsu:11:73", + "title": "Forbidden Secret Technique: Reaper Death Seal!", + "released": "2004-03-03T00:00:00.000Z", + "season": 1, + "episode": 73, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167791/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 38 + }, + { + "id": "kitsu:11:74", + "title": "Astonishing Truth! Gaara's Identity Emerges!", + "released": "2004-03-10T00:00:00.000Z", + "season": 1, + "episode": 74, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167792/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 39 + }, + { + "id": "kitsu:11:75", + "title": "Sasuke's Decision: Pushed to the Edge!", + "released": "2004-03-17T00:00:00.000Z", + "season": 1, + "episode": 75, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167793/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 40 + }, + { + "id": "kitsu:11:76", + "title": "Assassin of the Moonlit Night", + "released": "2004-03-24T00:00:00.000Z", + "season": 1, + "episode": 76, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167794/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 41 + }, + { + "id": "kitsu:11:77", + "title": "Light vs. Dark: The Two Faces of Gaara", + "released": "2004-03-31T00:00:00.000Z", + "season": 1, + "episode": 77, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167795/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 42 + }, + { + "id": "kitsu:11:78", + "title": "Naruto's Ninja Handbook", + "released": "2004-04-07T00:00:00.000Z", + "season": 1, + "episode": 78, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167796/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 43 + }, + { + "id": "kitsu:11:79", + "title": "Beyond the Limit of Darkness and Light", + "released": "2004-04-14T00:00:00.000Z", + "season": 1, + "episode": 79, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167797/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 44 + }, + { + "id": "kitsu:11:80", + "title": "The Third Hokage, Forever...", + "released": "2004-04-21T00:00:00.000Z", + "season": 1, + "episode": 80, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167798/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 45 + }, + { + "id": "kitsu:11:81", + "title": "Return of the Morning Mist", + "released": "2004-04-28T00:00:00.000Z", + "season": 1, + "episode": 81, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167799/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 46 + }, + { + "id": "kitsu:11:82", + "title": "Eye to Eye: Sharingan vs. Sharingan!", + "released": "2004-05-05T00:00:00.000Z", + "season": 1, + "episode": 82, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167800/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 47 + }, + { + "id": "kitsu:11:83", + "title": "Jiraiya: Naruto's Potential Disaster!", + "released": "2004-05-12T00:00:00.000Z", + "season": 1, + "episode": 83, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167801/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 2, + "imdbEpisode": 48 + }, + { + "id": "kitsu:11:84", + "title": "Roar, Chidori! Brother vs. Brother!", + "released": "2004-05-19T00:00:00.000Z", + "season": 1, + "episode": 84, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167802/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 1 + }, + { + "id": "kitsu:11:85", + "title": "Hate Among the Uchihas: The Last of the Clan!", + "released": "2004-05-26T00:00:00.000Z", + "season": 1, + "episode": 85, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167803/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 2 + }, + { + "id": "kitsu:11:86", + "title": "A New Training Begins: I Will Be Strong!", + "released": "2004-06-02T00:00:00.000Z", + "season": 1, + "episode": 86, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167804/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 3 + }, + { + "id": "kitsu:11:87", + "title": "Keep on Training: Pop Goes the Water Balloon!", + "released": "2004-06-09T00:00:00.000Z", + "season": 1, + "episode": 87, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167805/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 4 + }, + { + "id": "kitsu:11:88", + "title": "Focal Point: The Mark of the Leaf", + "released": "2004-06-16T00:00:00.000Z", + "season": 1, + "episode": 88, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/486/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 5 + }, + { + "id": "kitsu:11:89", + "title": "An Impossible Choice: The Pain Within Tsunade's Heart", + "released": "2004-06-23T00:00:00.000Z", + "season": 1, + "episode": 89, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/487/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 6 + }, + { + "id": "kitsu:11:90", + "title": "Unforgivable! A Total Lack of Respect!", + "released": "2004-07-07T00:00:00.000Z", + "season": 1, + "episode": 90, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/488/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 7 + }, + { + "id": "kitsu:11:91", + "title": "Inheritence! The Necklace of Death!", + "released": "2004-07-14T00:00:00.000Z", + "season": 1, + "episode": 91, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/489/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 8 + }, + { + "id": "kitsu:11:92", + "title": "A Dubious Offer! Tsunade's Choice!", + "released": "2004-07-21T00:00:00.000Z", + "season": 1, + "episode": 92, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/490/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 9 + }, + { + "id": "kitsu:11:93", + "title": "Breakdown! The Deal is Off!", + "released": "2004-07-28T00:00:00.000Z", + "season": 1, + "episode": 93, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/491/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 10 + }, + { + "id": "kitsu:11:94", + "title": "Attack! Fury of the Rasengan!", + "released": "2004-08-04T00:00:00.000Z", + "season": 1, + "episode": 94, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/492/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 11 + }, + { + "id": "kitsu:11:95", + "title": "The Fifth Hokage! A Life on the Line!", + "released": "2004-08-11T00:00:00.000Z", + "season": 1, + "episode": 95, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/493/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 12 + }, + { + "id": "kitsu:11:96", + "title": "Deadlock! Sannin Showdown!", + "released": "2004-08-11T00:00:00.000Z", + "season": 1, + "episode": 96, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/494/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 13 + }, + { + "id": "kitsu:11:97", + "title": "Kidnapped! Naruto's Hot Spring Adventure!", + "released": "2004-08-18T00:00:00.000Z", + "season": 1, + "episode": 97, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/495/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 14 + }, + { + "id": "kitsu:11:98", + "title": "Tsunade's Warning: Ninja No More!", + "released": "2004-08-25T00:00:00.000Z", + "season": 1, + "episode": 98, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/496/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 15 + }, + { + "id": "kitsu:11:99", + "title": "The Will of Fire Still Burns!", + "released": "2004-09-01T00:00:00.000Z", + "season": 1, + "episode": 99, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/497/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 16 + }, + { + "id": "kitsu:11:100", + "title": "Sensei and Student: The Bond of the Shinobi", + "released": "2004-09-08T00:00:00.000Z", + "season": 1, + "episode": 100, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/498/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 17 + }, + { + "id": "kitsu:11:101", + "title": "Gotta See! Gotta Know! Kakashi-Sensei's True Face!", + "released": "2004-09-15T00:00:00.000Z", + "season": 1, + "episode": 101, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167807/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 18 + }, + { + "id": "kitsu:11:102", + "title": "Mission: Help an Old Friend in the Land of Tea", + "released": "2004-09-22T00:00:00.000Z", + "season": 1, + "episode": 102, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167808/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 19 + }, + { + "id": "kitsu:11:103", + "title": "The Race is on! Trouble on the High Seas!", + "released": "2004-09-29T00:00:00.000Z", + "season": 1, + "episode": 103, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167810/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 20 + }, + { + "id": "kitsu:11:104", + "title": "Run Idate Run! Nagi Island Awaits!", + "released": "2004-10-13T00:00:00.000Z", + "season": 1, + "episode": 104, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167811/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 21 + }, + { + "id": "kitsu:11:105", + "title": "A Fierce Battle of Rolling Thunder!", + "released": "2004-10-20T00:00:00.000Z", + "season": 1, + "episode": 105, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167813/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 22 + }, + { + "id": "kitsu:11:106", + "title": "The Last Leg: A Final Act of Desperation", + "released": "2004-10-27T00:00:00.000Z", + "season": 1, + "episode": 106, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167816/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 23 + }, + { + "id": "kitsu:11:107", + "title": "The Battle Begins: Naruto vs. Sasuke", + "released": "2004-11-03T00:00:00.000Z", + "season": 1, + "episode": 107, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167818/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 24 + }, + { + "id": "kitsu:11:108", + "title": "Bitter Rivals and Broken Bonds", + "released": "2004-11-10T00:00:00.000Z", + "season": 1, + "episode": 108, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167820/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 25 + }, + { + "id": "kitsu:11:109", + "title": "An Invitation from the Sound", + "released": "2004-11-17T00:00:00.000Z", + "season": 1, + "episode": 109, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167822/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 26 + }, + { + "id": "kitsu:11:110", + "title": "Formation! The Sasuke Retrieval Squad", + "released": "2004-11-24T00:00:00.000Z", + "season": 1, + "episode": 110, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167824/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 27 + }, + { + "id": "kitsu:11:111", + "title": "Sound vs. Leaf", + "released": "2004-11-24T00:00:00.000Z", + "season": 1, + "episode": 111, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167828/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 28 + }, + { + "id": "kitsu:11:112", + "title": "Squad Mutiny: Everything Falls Apart!", + "released": "2004-12-01T00:00:00.000Z", + "season": 1, + "episode": 112, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167830/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 29 + }, + { + "id": "kitsu:11:113", + "title": "Full Throttle Power! Choji, Ablaze!", + "released": "2004-12-08T00:00:00.000Z", + "season": 1, + "episode": 113, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167831/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 30 + }, + { + "id": "kitsu:11:114", + "title": "Good-bye Old Friend...! I'll Always Believe in You!", + "released": "2004-12-15T00:00:00.000Z", + "season": 1, + "episode": 114, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167835/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 31 + }, + { + "id": "kitsu:11:115", + "title": "Your Opponent Is Me!", + "released": "2004-12-22T00:00:00.000Z", + "season": 1, + "episode": 115, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167837/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 32 + }, + { + "id": "kitsu:11:116", + "title": "360 Degrees of Vision: The Byakugan's Blind Spot", + "released": "2005-01-05T00:00:00.000Z", + "season": 1, + "episode": 116, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167840/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 33 + }, + { + "id": "kitsu:11:117", + "title": "Losing is Not an Option!", + "released": "2005-01-05T00:00:00.000Z", + "season": 1, + "episode": 117, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167843/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 34 + }, + { + "id": "kitsu:11:118", + "title": "The Vessel Arrives Too Late", + "released": "2005-01-12T00:00:00.000Z", + "season": 1, + "episode": 118, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167848/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 35 + }, + { + "id": "kitsu:11:119", + "title": "Miscalculation: A New Enemy Appears!", + "released": "2005-01-19T00:00:00.000Z", + "season": 1, + "episode": 119, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167851/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 36 + }, + { + "id": "kitsu:11:120", + "title": "Roar and Howl! The Ultimate Tag Team", + "released": "2005-02-02T00:00:00.000Z", + "season": 1, + "episode": 120, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167854/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 37 + }, + { + "id": "kitsu:11:121", + "title": "To Each His Own Battle", + "released": "2005-02-09T00:00:00.000Z", + "season": 1, + "episode": 121, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167857/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 38 + }, + { + "id": "kitsu:11:122", + "title": "Fakeout: Shikamaru's Comeback!", + "released": "2005-02-16T00:00:00.000Z", + "season": 1, + "episode": 122, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167860/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 39 + }, + { + "id": "kitsu:11:123", + "title": "The Leaf's Handsome Devil!", + "released": "2005-02-23T00:00:00.000Z", + "season": 1, + "episode": 123, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167863/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 40 + }, + { + "id": "kitsu:11:124", + "title": "The Beast Within", + "released": "2005-03-02T00:00:00.000Z", + "season": 1, + "episode": 124, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167864/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 41 + }, + { + "id": "kitsu:11:125", + "title": "The Sand Shinobi: Allies of the Leaf", + "released": "2005-03-09T00:00:00.000Z", + "season": 1, + "episode": 125, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167866/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 42 + }, + { + "id": "kitsu:11:126", + "title": "Showdown: Gaara vs. Kimimaro!", + "released": "2005-03-16T00:00:00.000Z", + "season": 1, + "episode": 126, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167869/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 43 + }, + { + "id": "kitsu:11:127", + "title": "Vengeful Strike! The Bracken Dance", + "released": "2005-03-30T00:00:00.000Z", + "season": 1, + "episode": 127, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167872/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 44 + }, + { + "id": "kitsu:11:128", + "title": "A Cry on Deaf Ears", + "released": "2005-03-30T00:00:00.000Z", + "season": 1, + "episode": 128, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167875/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 45 + }, + { + "id": "kitsu:11:129", + "title": "Brothers: Distance Among the Uchiha", + "released": "2005-04-06T00:00:00.000Z", + "season": 1, + "episode": 129, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167878/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 46 + }, + { + "id": "kitsu:11:130", + "title": "Father and Son, the Broken Crest", + "released": "2005-04-13T00:00:00.000Z", + "season": 1, + "episode": 130, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167881/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 47 + }, + { + "id": "kitsu:11:131", + "title": "The Secrets of the Mangekyo Sharingan!", + "released": "2005-04-20T00:00:00.000Z", + "season": 1, + "episode": 131, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167885/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 3, + "imdbEpisode": 48 + }, + { + "id": "kitsu:11:132", + "title": "For a Friend", + "released": "2005-04-27T00:00:00.000Z", + "season": 1, + "episode": 132, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167886/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 1 + }, + { + "id": "kitsu:11:133", + "title": "A Plea From a Friend", + "released": "2005-05-04T00:00:00.000Z", + "season": 1, + "episode": 133, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167891/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 2 + }, + { + "id": "kitsu:11:134", + "title": "The End of Tears", + "released": "2005-05-11T00:00:00.000Z", + "season": 1, + "episode": 134, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167894/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 3 + }, + { + "id": "kitsu:11:135", + "title": "The Promise That Could Not Be Kept", + "released": "2005-05-18T00:00:00.000Z", + "season": 1, + "episode": 135, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167896/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 4 + }, + { + "id": "kitsu:11:136", + "title": "Deep Cover!? A Super S-Ranked Mission!", + "released": "2005-05-25T00:00:00.000Z", + "season": 1, + "episode": 136, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167898/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 5 + }, + { + "id": "kitsu:11:137", + "title": "A Town of Outlaws, the Shadow of the Fuma Clan", + "released": "2005-06-01T00:00:00.000Z", + "season": 1, + "episode": 137, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167900/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 6 + }, + { + "id": "kitsu:11:138", + "title": "Pure Betrayal, and a Fleeting Plea!", + "released": "2005-06-08T00:00:00.000Z", + "season": 1, + "episode": 138, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167901/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 7 + }, + { + "id": "kitsu:11:139", + "title": "Pure Terror! The House of Orochimaru", + "released": "2005-06-15T00:00:00.000Z", + "season": 1, + "episode": 139, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167903/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 8 + }, + { + "id": "kitsu:11:140", + "title": "Two Heartbeats: Kabuto's Trap", + "released": "2005-06-22T00:00:00.000Z", + "season": 1, + "episode": 140, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167905/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 9 + }, + { + "id": "kitsu:11:141", + "title": "Sakura's Determination", + "released": "2005-06-29T00:00:00.000Z", + "season": 1, + "episode": 141, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167906/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 10 + }, + { + "id": "kitsu:11:142", + "title": "The Three Villains from the Maximum Security Prison", + "released": "2005-07-06T00:00:00.000Z", + "season": 1, + "episode": 142, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167908/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 11 + }, + { + "id": "kitsu:11:143", + "title": "Tonton! I'm Counting on You!", + "released": "2005-07-13T00:00:00.000Z", + "season": 1, + "episode": 143, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167910/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 12 + }, + { + "id": "kitsu:11:144", + "title": "A New Squad! Two People and a Dog?!", + "released": "2005-07-20T00:00:00.000Z", + "season": 1, + "episode": 144, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167912/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 13 + }, + { + "id": "kitsu:11:145", + "title": "A New Formation: Ino-Shika-Cho!", + "released": "2005-07-27T00:00:00.000Z", + "season": 1, + "episode": 145, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167914/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 14 + }, + { + "id": "kitsu:11:146", + "title": "Orochimaru's Shadow", + "released": "2005-08-10T00:00:00.000Z", + "season": 1, + "episode": 146, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167915/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 15 + }, + { + "id": "kitsu:11:147", + "title": "A Clash of Fate: You Can't Bring Me Down", + "released": "2005-08-17T00:00:00.000Z", + "season": 1, + "episode": 147, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167918/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 16 + }, + { + "id": "kitsu:11:148", + "title": "Search for the Rare Bikochu Beetle", + "released": "2005-08-17T00:00:00.000Z", + "season": 1, + "episode": 148, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167920/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 17 + }, + { + "id": "kitsu:11:149", + "title": "What's the Difference? Don't All Insects Look Alike?", + "released": "2005-08-24T00:00:00.000Z", + "season": 1, + "episode": 149, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167921/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 18 + }, + { + "id": "kitsu:11:150", + "title": "A Battle of Bugs: The Deceivers and the Deceived", + "released": "2005-08-31T00:00:00.000Z", + "season": 1, + "episode": 150, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167923/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 19 + }, + { + "id": "kitsu:11:151", + "title": "Blaze Away Byakugan: This Is My Ninja Way", + "released": "2005-09-14T00:00:00.000Z", + "season": 1, + "episode": 151, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167924/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 20 + }, + { + "id": "kitsu:11:152", + "title": "Funeral March for the Living", + "released": "2005-09-21T00:00:00.000Z", + "season": 1, + "episode": 152, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167926/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 21 + }, + { + "id": "kitsu:11:153", + "title": "A Lesson Learned: The Iron Fist of Love", + "released": "2005-09-28T00:00:00.000Z", + "season": 1, + "episode": 153, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167928/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 22 + }, + { + "id": "kitsu:11:154", + "title": "The Enemy of the Byakugan", + "released": "2005-10-05T00:00:00.000Z", + "season": 1, + "episode": 154, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167930/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 23 + }, + { + "id": "kitsu:11:155", + "title": "The Dark Creeping Clouds", + "released": "2005-10-12T00:00:00.000Z", + "season": 1, + "episode": 155, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167931/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 24 + }, + { + "id": "kitsu:11:156", + "title": "Raiga's Counterattack", + "released": "2005-10-19T00:00:00.000Z", + "season": 1, + "episode": 156, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167933/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 25 + }, + { + "id": "kitsu:11:157", + "title": "Run! The Curry of Life", + "released": "2005-10-26T00:00:00.000Z", + "season": 1, + "episode": 157, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167934/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 26 + }, + { + "id": "kitsu:11:158", + "title": "Follow My Lead! The Great Survival Challenge", + "released": "2005-11-02T00:00:00.000Z", + "season": 1, + "episode": 158, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167936/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 27 + }, + { + "id": "kitsu:11:159", + "title": "Bounty Hunter from the Wilderness", + "released": "2005-11-09T00:00:00.000Z", + "season": 1, + "episode": 159, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167939/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 28 + }, + { + "id": "kitsu:11:160", + "title": "Hunt or Be Hunted?! Showdown at the O.K. Temple!", + "released": "2005-11-16T00:00:00.000Z", + "season": 1, + "episode": 160, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167942/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 29 + }, + { + "id": "kitsu:11:161", + "title": "The Appearance of Strange Visitors", + "released": "2005-11-23T00:00:00.000Z", + "season": 1, + "episode": 161, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167943/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 30 + }, + { + "id": "kitsu:11:162", + "title": "The Cursed Warrior", + "released": "2005-11-30T00:00:00.000Z", + "season": 1, + "episode": 162, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167944/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 31 + }, + { + "id": "kitsu:11:163", + "title": "The Tactician's Intent", + "released": "2005-12-07T00:00:00.000Z", + "season": 1, + "episode": 163, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167945/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 32 + }, + { + "id": "kitsu:11:164", + "title": "Too Late for Help", + "released": "2005-12-14T00:00:00.000Z", + "season": 1, + "episode": 164, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167946/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 33 + }, + { + "id": "kitsu:11:165", + "title": "The Death of Naruto", + "released": "2005-12-21T00:00:00.000Z", + "season": 1, + "episode": 165, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167947/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 34 + }, + { + "id": "kitsu:11:166", + "title": "When Time Stands Still", + "released": "2006-01-04T00:00:00.000Z", + "season": 1, + "episode": 166, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167948/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 35 + }, + { + "id": "kitsu:11:167", + "title": "When Egrets Flap Their Wings", + "released": "2006-01-04T00:00:00.000Z", + "season": 1, + "episode": 167, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167949/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 36 + }, + { + "id": "kitsu:11:168", + "title": "Mix It, Stretch It, Boil It Up! Burn, Copper Pot, Burn!", + "released": "2006-01-18T00:00:00.000Z", + "season": 1, + "episode": 168, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167950/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 37 + }, + { + "id": "kitsu:11:169", + "title": "Remembrance: The Lost Page", + "released": "2006-01-25T00:00:00.000Z", + "season": 1, + "episode": 169, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167951/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 38 + }, + { + "id": "kitsu:11:170", + "title": "The Closed Door", + "released": "2006-02-01T00:00:00.000Z", + "season": 1, + "episode": 170, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167952/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 39 + }, + { + "id": "kitsu:11:171", + "title": "Infiltration: The Set-Up!", + "released": "2006-02-08T00:00:00.000Z", + "season": 1, + "episode": 171, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167953/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 40 + }, + { + "id": "kitsu:11:172", + "title": "Despair: A Fractured Heart", + "released": "2006-02-15T00:00:00.000Z", + "season": 1, + "episode": 172, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167954/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 41 + }, + { + "id": "kitsu:11:173", + "title": "The Battle at Sea: The Power Unleashed!", + "released": "2006-02-22T00:00:00.000Z", + "season": 1, + "episode": 173, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167955/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 42 + }, + { + "id": "kitsu:11:174", + "title": "Impossible! Celebrity Ninja Art - Money Style Jutsu!", + "released": "2006-03-01T00:00:00.000Z", + "season": 1, + "episode": 174, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167956/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 43 + }, + { + "id": "kitsu:11:175", + "title": "The Treasure Hunt is On!", + "released": "2006-03-08T00:00:00.000Z", + "season": 1, + "episode": 175, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167957/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 44 + }, + { + "id": "kitsu:11:176", + "title": "Run, Dodge, Zigzag! Chase or Be Chased!", + "released": "2006-03-15T00:00:00.000Z", + "season": 1, + "episode": 176, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167958/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 45 + }, + { + "id": "kitsu:11:177", + "title": "Please, Mr. Postman!", + "released": "2006-03-22T00:00:00.000Z", + "season": 1, + "episode": 177, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167959/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 46 + }, + { + "id": "kitsu:11:178", + "title": "Encounter! The Boy with a Star's Name", + "released": "2006-03-29T00:00:00.000Z", + "season": 1, + "episode": 178, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167960/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 47 + }, + { + "id": "kitsu:11:179", + "title": "The Remembered Lullaby", + "released": "2006-04-05T00:00:00.000Z", + "season": 1, + "episode": 179, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167961/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 4, + "imdbEpisode": 48 + }, + { + "id": "kitsu:11:180", + "title": "Hidden Jutsu: The Price of The Ninja Art: Kujaku", + "released": "2006-04-12T00:00:00.000Z", + "season": 1, + "episode": 180, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167962/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 1 + }, + { + "id": "kitsu:11:181", + "title": "Hoshikage, The Buried Truth", + "released": "2006-04-19T00:00:00.000Z", + "season": 1, + "episode": 181, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167963/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 2 + }, + { + "id": "kitsu:11:182", + "title": "Reunion, The Remaining time", + "released": "2006-04-26T00:00:00.000Z", + "season": 1, + "episode": 182, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167964/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 3 + }, + { + "id": "kitsu:11:183", + "title": "The Star's Radiance", + "released": "2006-05-03T00:00:00.000Z", + "season": 1, + "episode": 183, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167965/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 4 + }, + { + "id": "kitsu:11:184", + "title": "Kiba's Long Day!", + "released": "2006-05-10T00:00:00.000Z", + "season": 1, + "episode": 184, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167966/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 5 + }, + { + "id": "kitsu:11:185", + "title": "A Legend from the Hidden Leaf: The Onbaa!", + "released": "2006-05-17T00:00:00.000Z", + "season": 1, + "episode": 185, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167967/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 6 + }, + { + "id": "kitsu:11:186", + "title": "Laughing Shino", + "released": "2006-05-24T00:00:00.000Z", + "season": 1, + "episode": 186, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167968/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 7 + }, + { + "id": "kitsu:11:187", + "title": "Open for Business! The Leaf Moving Service", + "released": "2006-05-31T00:00:00.000Z", + "season": 1, + "episode": 187, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167969/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 8 + }, + { + "id": "kitsu:11:188", + "title": "Mystery of the Targeted Merchants", + "released": "2006-06-07T00:00:00.000Z", + "season": 1, + "episode": 188, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167970/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 9 + }, + { + "id": "kitsu:11:189", + "title": "A Limitless Supply of Ninja Tools", + "released": "2006-06-14T00:00:00.000Z", + "season": 1, + "episode": 189, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167971/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 10 + }, + { + "id": "kitsu:11:190", + "title": "The Byakugan Sees the Blind Spot", + "released": "2006-06-21T00:00:00.000Z", + "season": 1, + "episode": 190, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167972/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 11 + }, + { + "id": "kitsu:11:191", + "title": "Forecast: Death! Cloudy with Chance of Sun", + "released": "2006-06-28T00:00:00.000Z", + "season": 1, + "episode": 191, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167973/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 12 + }, + { + "id": "kitsu:11:192", + "title": "Ino Screams! Chubby Paradise!", + "released": "2006-07-05T00:00:00.000Z", + "season": 1, + "episode": 192, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167975/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 13 + }, + { + "id": "kitsu:11:193", + "title": "Viva Dojo Challenge! Youth Is All About Passion!", + "released": "2006-07-12T00:00:00.000Z", + "season": 1, + "episode": 193, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167976/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 14 + }, + { + "id": "kitsu:11:194", + "title": "The Mysterious Curse of the Haunted Castle", + "released": "2006-07-19T00:00:00.000Z", + "season": 1, + "episode": 194, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167977/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 15 + }, + { + "id": "kitsu:11:195", + "title": "The Third Super-Beast!", + "released": "2006-07-26T00:00:00.000Z", + "season": 1, + "episode": 195, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167978/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 16 + }, + { + "id": "kitsu:11:196", + "title": "Hot-Blooded Confrontation: Student vs. Sensei", + "released": "2006-08-09T00:00:00.000Z", + "season": 1, + "episode": 196, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167979/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 17 + }, + { + "id": "kitsu:11:197", + "title": "Crisis! The Hidden Leaf 11 Gather!", + "released": "2006-08-16T00:00:00.000Z", + "season": 1, + "episode": 197, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167980/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 18 + }, + { + "id": "kitsu:11:198", + "title": "The ANBU Gives Up? Naruto's Recollection", + "released": "2006-08-23T00:00:00.000Z", + "season": 1, + "episode": 198, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167981/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 19 + }, + { + "id": "kitsu:11:199", + "title": "The Missed Target", + "released": "2006-08-30T00:00:00.000Z", + "season": 1, + "episode": 199, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167982/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 20 + }, + { + "id": "kitsu:11:200", + "title": "The Powerful Helper", + "released": "2006-09-13T00:00:00.000Z", + "season": 1, + "episode": 200, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167983/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 21 + }, + { + "id": "kitsu:11:201", + "title": "Multiple Traps! Countdown to Destruction", + "released": "2006-09-20T00:00:00.000Z", + "season": 1, + "episode": 201, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167984/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 22 + }, + { + "id": "kitsu:11:202", + "title": "The Top 5 Ninja Battles", + "released": "2006-09-27T00:00:00.000Z", + "season": 1, + "episode": 202, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167985/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 23 + }, + { + "id": "kitsu:11:203", + "title": "Kurenai's Decision, Squad 8 Left Behind", + "released": "2006-10-05T00:00:00.000Z", + "season": 1, + "episode": 203, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167986/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 24 + }, + { + "id": "kitsu:11:204", + "title": "Yakumo's Sealed Ability", + "released": "2006-10-05T00:00:00.000Z", + "season": 1, + "episode": 204, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167987/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 25 + }, + { + "id": "kitsu:11:205", + "title": "Kurenai's Top-Secret Mission: The Promise With the Third Hokage", + "released": "2006-10-05T00:00:00.000Z", + "season": 1, + "episode": 205, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167988/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 26 + }, + { + "id": "kitsu:11:206", + "title": "Genjutsu or Reality?", + "released": "2006-10-19T00:00:00.000Z", + "season": 1, + "episode": 206, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167989/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 27 + }, + { + "id": "kitsu:11:207", + "title": "The Supposed Sealed Ability", + "released": "2006-10-26T00:00:00.000Z", + "season": 1, + "episode": 207, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167990/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 28 + }, + { + "id": "kitsu:11:208", + "title": "The Weight of the Prized Artifact!", + "released": "2006-11-02T00:00:00.000Z", + "season": 1, + "episode": 208, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167991/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 29 + }, + { + "id": "kitsu:11:209", + "title": "The Enemy: Ninja Dropouts", + "released": "2006-11-09T00:00:00.000Z", + "season": 1, + "episode": 209, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167992/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 30 + }, + { + "id": "kitsu:11:210", + "title": "The Bewildering Forest", + "released": "2006-11-16T00:00:00.000Z", + "season": 1, + "episode": 210, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167993/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 31 + }, + { + "id": "kitsu:11:211", + "title": "Memory of Flames", + "released": "2006-11-30T00:00:00.000Z", + "season": 1, + "episode": 211, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167994/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 32 + }, + { + "id": "kitsu:11:212", + "title": "To Each His Own Path", + "released": "2006-12-07T00:00:00.000Z", + "season": 1, + "episode": 212, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167995/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 33 + }, + { + "id": "kitsu:11:213", + "title": "Vanished Memories", + "released": "2006-12-14T00:00:00.000Z", + "season": 1, + "episode": 213, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167996/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 34 + }, + { + "id": "kitsu:11:214", + "title": "Bringing Back Reality", + "released": "2006-12-21T00:00:00.000Z", + "season": 1, + "episode": 214, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167997/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 35 + }, + { + "id": "kitsu:11:215", + "title": "A Past to Be Erased", + "released": "2006-12-21T00:00:00.000Z", + "season": 1, + "episode": 215, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167998/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 36 + }, + { + "id": "kitsu:11:216", + "title": "The Targeted Shukaku", + "released": "2007-01-11T00:00:00.000Z", + "season": 1, + "episode": 216, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/167999/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 37 + }, + { + "id": "kitsu:11:217", + "title": "Sand Alliance With The Leaf Shinobi", + "released": "2007-01-18T00:00:00.000Z", + "season": 1, + "episode": 217, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/168000/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 38 + }, + { + "id": "kitsu:11:218", + "title": "The Counterattack!", + "released": "2007-01-25T00:00:00.000Z", + "season": 1, + "episode": 218, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/168001/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 39 + }, + { + "id": "kitsu:11:219", + "title": "The Ultimate Weapon Reborn", + "released": "2007-02-01T00:00:00.000Z", + "season": 1, + "episode": 219, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/168002/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 40 + }, + { + "id": "kitsu:11:220", + "title": "Departure", + "released": "2007-02-08T00:00:00.000Z", + "season": 1, + "episode": 220, + "thumbnail": "https://media.kitsu.io/episodes/thumbnails/168003/original.jpg", + "imdb_id": "tt0409591", + "imdbSeason": 5, + "imdbEpisode": 41 + } + ], + "links": [ + { + "name": "8.0", + "category": "imdb", + "url": "https://kitsu.io/anime/naruto" + }, + { + "name": "Sequel: Naruto: Shippuuden", + "category": "Franchise", + "url": "stremio:///detail/series/kitsu:1555" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Comedy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Comedy" + }, + { + "name": "Martial Arts", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Martial Arts" + }, + { + "name": "Super Power", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Super Power" + } + ], + "imdb_id": "tt0409591" + }, + "cacheMaxAge": 43200 +} \ No newline at end of file diff --git a/src/node/consumer/test/mock-responses/assets/name-to-imdb-flash.json b/src/node/consumer/test/mock-responses/assets/name-to-imdb-flash.json new file mode 100644 index 0000000..73a7dd7 --- /dev/null +++ b/src/node/consumer/test/mock-responses/assets/name-to-imdb-flash.json @@ -0,0 +1,111 @@ +{ + "d": [ + { + "i": [ + "https://m.media-amazon.com/images/M/MV5BMTQ2MTc0MTAtN2VlYi00N2ZkLTlhNmUtMjcyZDg0YzNiYjEyXkEyXkFqcGdeQXVyMzU3MTc5OTE@._V1_.jpg", + 680, + 1000 + ], + "id": "tt0098798", + "l": "The Flash", + "q": "TV series", + "qid": "tvSeries", + "s": "John Wesley Shipp, Amanda Pays", + "y": 1990, + "yr": "1990-1991" + }, + { + "i": [ + "https://m.media-amazon.com/images/M/MV5BMGU2OGMyNzUtM2Q5NS00ZTdhLThmNjItODRiZDQ5MGMzZGNmXkEyXkFqcGdeQXVyMjQzMzQzODY@._V1_.jpg", + 766, + 1023 + ], + "id": "tt0100678", + "l": "Stan the Flasher", + "q": "feature", + "qid": "movie", + "s": "Claude Berri, Aurore Clément", + "y": 1990 + }, + { + "i": [ + "https://m.media-amazon.com/images/M/MV5BMDlmNTQ3NzctMGUzYi00MjEyLWIzNmUtNjhjYzZlMDQ5OTE3XkEyXkFqcGdeQXVyMzY4ODk0Nw@@._V1_.jpg", + 800, + 600 + ], + "id": "tt27750546", + "l": "The Flash: Video News Release", + "q": "TV special", + "qid": "tvSpecial", + "s": "John Wesley Shipp, Amanda Pays", + "y": 1990 + }, + { + "i": [ + "https://m.media-amazon.com/images/M/MV5BMjViZmVlMmUtNzljNS00NjhjLTk5ODMtNTZiZWRlOWRkMWU5XkEyXkFqcGdeQXVyMDA1NzM3OA@@._V1_.jpg", + 1500, + 2000 + ], + "id": "tt8408320", + "l": "Shenzhen Flash", + "q": "short", + "qid": "short", + "s": "", + "y": 1990 + }, + { + "i": [ + "https://m.media-amazon.com/images/M/MV5BODU4YmIxYzItYTdjYy00NmQ3LWJkYmQtM2UwZGZjNjZhMjYwXkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_.jpg", + 1991, + 2931 + ], + "id": "tt0097365", + "l": "Flesh Gordon Meets the Cosmic Cheerleaders", + "q": "feature", + "qid": "movie", + "s": "Vince Murdocco, Robyn Kelly", + "y": 1990 + }, + { + "i": [ + "https://m.media-amazon.com/images/M/MV5BYjMwMjgwNjAtZjllYi00Y2QyLWI2MzUtOGIwMDJjNWQ3YjQxL2ltYWdlL2ltYWdlXkEyXkFqcGdeQXVyNjg3MTAzODM@._V1_.jpg", + 3183, + 2015 + ], + "id": "tt2356508", + "l": "Arrow Flash", + "q": "video game", + "qid": "videoGame", + "s": "Action, Sci-Fi", + "y": 1990 + }, + { + "i": [ + "https://m.media-amazon.com/images/M/MV5BNTZkNzU2MzEtNzUwMS00NTFmLTgxY2EtZTk1ZTI3NDUzN2M1XkEyXkFqcGdeQXVyMTgwMDI4MTc@._V1_.jpg", + 299, + 230 + ], + "id": "tt0444569", + "l": "Clash!", + "q": "TV series", + "qid": "tvSeries", + "s": "Billy Kimball, Dave Levin", + "y": 1990 + }, + { + "i": [ + "https://m.media-amazon.com/images/M/MV5BNGNkZTYwNTYtNTc2Mi00ODFjLTg3MjctNTRiMGQwMDc4MjBkXkEyXkFqcGdeQXVyMzU0NzkwMDg@._V1_.jpg", + 1152, + 1548 + ], + "id": "tt0099584", + "l": "Of Flesh and Blood", + "q": "feature", + "qid": "movie", + "s": "Breon, Dick Bangham", + "y": 1990 + } + ], + "q": "the_flash%201990", + "v": 1 +} \ No newline at end of file diff --git a/src/node/consumer/test/mock-responses/assets/test-cinemata-theflash.json b/src/node/consumer/test/mock-responses/assets/test-cinemata-theflash.json new file mode 100644 index 0000000..c2791b4 --- /dev/null +++ b/src/node/consumer/test/mock-responses/assets/test-cinemata-theflash.json @@ -0,0 +1,373 @@ +{ + "meta": { + "awards": "Nominated for 2 Primetime Emmys. 4 nominations total", + "cast": [ + "John Wesley Shipp", + "Amanda Pays", + "Alex Désert" + ], + "country": "United States", + "description": "A police forensic scientist, Barry Allen, battles crimes as the super-fast superhero \"The Flash.\"", + "director": null, + "dvdRelease": "2011-01-25T00:00:00.000Z", + "genre": [ + "Action", + "Crime", + "Fantasy" + ], + "imdbRating": "7.1", + "imdb_id": "tt0098798", + "name": "The Flash", + "popularity": 0.987, + "poster": "https://images.metahub.space/poster/small/tt0098798/img", + "released": "1990-09-20T00:00:00.000Z", + "runtime": "2 min", + "status": "Ended", + "tvdb_id": "78650", + "type": "series", + "writer": [ + "Danny Bilson", + "Paul De Meo" + ], + "year": "1990–1991", + "popularities": { + "moviedb": 57.842, + "trakt": 2, + "stremio": 0.987, + "stremio_lib": 0 + }, + "background": "https://images.metahub.space/background/medium/tt0098798/img", + "logo": "https://images.metahub.space/logo/medium/tt0098798/img", + "moviedb_id": 236, + "slug": "series/the-flash-0098798", + "id": "tt0098798", + "genres": [ + "Action", + "Crime", + "Fantasy" + ], + "releaseInfo": "1990–1991", + "videos": [ + { + "name": "Pilot", + "season": 1, + "number": 1, + "firstAired": "1990-09-20T00:00:00.000Z", + "tvdb_id": 335168, + "rating": "7.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/1/w780.jpg", + "id": "tt0098798:1:1", + "released": "1990-09-20T00:00:00.000Z", + "episode": 1 + }, + { + "name": "Out of Control", + "season": 1, + "number": 2, + "firstAired": "1990-09-27T00:00:00.000Z", + "tvdb_id": 291041, + "rating": "7.5", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/2/w780.jpg", + "id": "tt0098798:1:2", + "released": "1990-09-27T00:00:00.000Z", + "episode": 2 + }, + { + "name": "Watching the Detectives", + "season": 1, + "number": 3, + "firstAired": "1990-10-18T00:00:00.000Z", + "tvdb_id": 291042, + "rating": "7.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/3/w780.jpg", + "id": "tt0098798:1:3", + "released": "1990-10-18T00:00:00.000Z", + "episode": 3 + }, + { + "name": "Honor Among Thieves", + "season": 1, + "number": 4, + "firstAired": "1990-10-25T00:00:00.000Z", + "tvdb_id": 291043, + "rating": "7.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/4/w780.jpg", + "id": "tt0098798:1:4", + "released": "1990-10-25T00:00:00.000Z", + "episode": 4 + }, + { + "name": "Double Vision", + "season": 1, + "number": 5, + "firstAired": "1990-11-01T00:00:00.000Z", + "tvdb_id": 291044, + "rating": "7.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/5/w780.jpg", + "id": "tt0098798:1:5", + "released": "1990-11-01T00:00:00.000Z", + "episode": 5 + }, + { + "name": "Sins of the Father", + "season": 1, + "number": 6, + "firstAired": "1990-11-08T00:00:00.000Z", + "tvdb_id": 291045, + "rating": "7.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/6/w780.jpg", + "id": "tt0098798:1:6", + "released": "1990-11-08T00:00:00.000Z", + "episode": 6 + }, + { + "name": "Child's Play", + "season": 1, + "number": 7, + "firstAired": "1990-11-15T00:00:00.000Z", + "tvdb_id": 291046, + "rating": "7.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/7/w780.jpg", + "id": "tt0098798:1:7", + "released": "1990-11-15T00:00:00.000Z", + "episode": 7 + }, + { + "name": "Shroud of Death", + "season": 1, + "number": 8, + "firstAired": "1990-11-29T00:00:00.000Z", + "tvdb_id": 291047, + "rating": "7.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/8/w780.jpg", + "id": "tt0098798:1:8", + "released": "1990-11-29T00:00:00.000Z", + "episode": 8 + }, + { + "name": "Ghost in the Machine", + "season": 1, + "number": 9, + "firstAired": "1990-12-13T00:00:00.000Z", + "tvdb_id": 291048, + "rating": "7.5", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/9/w780.jpg", + "id": "tt0098798:1:9", + "released": "1990-12-13T00:00:00.000Z", + "episode": 9 + }, + { + "name": "Sight Unseen", + "season": 1, + "number": 10, + "firstAired": "1991-01-10T00:00:00.000Z", + "tvdb_id": 291049, + "rating": "7.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/10/w780.jpg", + "id": "tt0098798:1:10", + "released": "1991-01-10T00:00:00.000Z", + "episode": 10 + }, + { + "name": "Beat the Clock", + "season": 1, + "number": 11, + "firstAired": "1991-01-31T00:00:00.000Z", + "tvdb_id": 291050, + "rating": "6.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/11/w780.jpg", + "id": "tt0098798:1:11", + "released": "1991-01-31T00:00:00.000Z", + "episode": 11 + }, + { + "name": "The Trickster", + "season": 1, + "number": 12, + "firstAired": "1991-02-07T00:00:00.000Z", + "tvdb_id": 291051, + "rating": "7.5", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/12/w780.jpg", + "id": "tt0098798:1:12", + "released": "1991-02-07T00:00:00.000Z", + "episode": 12 + }, + { + "name": "Tina, Is That You?", + "season": 1, + "number": 13, + "firstAired": "1991-02-14T00:00:00.000Z", + "tvdb_id": 291052, + "rating": "7.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/13/w780.jpg", + "id": "tt0098798:1:13", + "released": "1991-02-14T00:00:00.000Z", + "episode": 13 + }, + { + "name": "Be My Baby", + "season": 1, + "number": 14, + "firstAired": "1991-02-21T00:00:00.000Z", + "tvdb_id": 291053, + "rating": "7.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/14/w780.jpg", + "id": "tt0098798:1:14", + "released": "1991-02-21T00:00:00.000Z", + "episode": 14 + }, + { + "name": "Fast Forward", + "season": 1, + "number": 15, + "firstAired": "1991-02-27T00:00:00.000Z", + "tvdb_id": 291054, + "rating": "6.5", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/15/w780.jpg", + "id": "tt0098798:1:15", + "released": "1991-02-27T00:00:00.000Z", + "episode": 15 + }, + { + "name": "Deadly Nightshade", + "season": 1, + "number": 16, + "firstAired": "1991-03-30T00:00:00.000Z", + "tvdb_id": 291055, + "rating": "7.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/16/w780.jpg", + "id": "tt0098798:1:16", + "released": "1991-03-30T00:00:00.000Z", + "episode": 16 + }, + { + "name": "Captain Cold", + "season": 1, + "number": 17, + "firstAired": "1991-04-06T00:00:00.000Z", + "tvdb_id": 291056, + "rating": "7.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/17/w780.jpg", + "id": "tt0098798:1:17", + "released": "1991-04-06T00:00:00.000Z", + "episode": 17 + }, + { + "name": "Twin Streaks", + "season": 1, + "number": 18, + "firstAired": "1991-04-13T00:00:00.000Z", + "tvdb_id": 291057, + "rating": "6.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/18/w780.jpg", + "id": "tt0098798:1:18", + "released": "1991-04-13T00:00:00.000Z", + "episode": 18 + }, + { + "name": "Done with Mirrors", + "season": 1, + "number": 19, + "firstAired": "1991-04-27T00:00:00.000Z", + "tvdb_id": 291058, + "rating": "7.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/19/w780.jpg", + "id": "tt0098798:1:19", + "released": "1991-04-27T00:00:00.000Z", + "episode": 19 + }, + { + "name": "Good Night, Central City", + "season": 1, + "number": 20, + "firstAired": "1991-05-04T00:00:00.000Z", + "tvdb_id": 291059, + "rating": "7.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/20/w780.jpg", + "id": "tt0098798:1:20", + "released": "1991-05-04T00:00:00.000Z", + "episode": 20 + }, + { + "name": "Alpha", + "season": 1, + "number": 21, + "firstAired": "1991-05-11T00:00:00.000Z", + "tvdb_id": 291060, + "rating": "7.0", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/21/w780.jpg", + "id": "tt0098798:1:21", + "released": "1991-05-11T00:00:00.000Z", + "episode": 21 + }, + { + "name": "The Trial of the Trickster", + "season": 1, + "number": 22, + "firstAired": "1991-05-18T00:00:00.000Z", + "tvdb_id": 291061, + "rating": "7.5", + "thumbnail": "https://episodes.metahub.space/tt0098798/1/22/w780.jpg", + "id": "tt0098798:1:22", + "released": "1991-05-18T00:00:00.000Z", + "episode": 22 + } + ], + "links": [ + { + "name": "7.1", + "category": "imdb", + "url": "https://imdb.com/title/tt0098798" + }, + { + "name": "The Flash", + "category": "share", + "url": "https://www.strem.io/s/series/the-flash-0098798" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fv3-cinemeta.strem.io%2Fmanifest.json/series/top?genre=Action" + }, + { + "name": "Crime", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fv3-cinemeta.strem.io%2Fmanifest.json/series/top?genre=Crime" + }, + { + "name": "Fantasy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fv3-cinemeta.strem.io%2Fmanifest.json/series/top?genre=Fantasy" + }, + { + "name": "John Wesley Shipp", + "category": "Cast", + "url": "stremio:///search?search=John%20Wesley%20Shipp" + }, + { + "name": "Amanda Pays", + "category": "Cast", + "url": "stremio:///search?search=Amanda%20Pays" + }, + { + "name": "Alex Désert", + "category": "Cast", + "url": "stremio:///search?search=Alex%20D%C3%A9sert" + }, + { + "name": "Danny Bilson", + "category": "Writers", + "url": "stremio:///search?search=Danny%20Bilson" + }, + { + "name": "Paul De Meo", + "category": "Writers", + "url": "stremio:///search?search=Paul%20De%20Meo" + } + ], + "behaviorHints": { + "defaultVideoId": null, + "hasScheduledVideos": true + } + } +} \ No newline at end of file diff --git a/src/node/consumer/test/mock-responses/assets/test-kitsu-search-id-naruto.json b/src/node/consumer/test/mock-responses/assets/test-kitsu-search-id-naruto.json new file mode 100644 index 0000000..1ff7631 --- /dev/null +++ b/src/node/consumer/test/mock-responses/assets/test-kitsu-search-id-naruto.json @@ -0,0 +1,1060 @@ +{ + "metas": [ + { + "id": "kitsu:11", + "type": "series", + "animeType": "TV", + "name": "Naruto", + "aliases": [ + "Naruto" + ], + "description": "Moments prior to Naruto Uzumaki's birth, a huge demon known as the Kyuubi, the Nine-Tailed Fox, attacked Konohagakure, the Hidden Leaf Village, and wreaked havoc. In order to put an end to the Kyuubi's rampage, the leader of the village, the Fourth Hokage, sacrificed his life and sealed the monstrous beast inside the newborn Naruto.\nNow, Naruto is a hyperactive and knuckle-headed ninja still living in Konohagakure. Shunned because of the Kyuubi inside him, Naruto struggles to find his place in the village, while his burning desire to become the Hokage of Konohagakure leads him not only to some great new friends, but also some deadly foes.\n[Written by MAL Rewrite]", + "releaseInfo": "2002-2007", + "runtime": "23 min", + "imdbRating": "8.0", + "genres": [ + "Action", + "Comedy", + "Martial Arts", + "Super Power" + ], + "logo": "https://assets.fanart.tv/fanart/tv/78857/hdtvlogo/naruto-50667b3780bf2.png", + "poster": "https://media.kitsu.io/anime/11/poster_image/medium-410cee5d114a5f70d69e795755e8348a.jpeg", + "background": "https://assets.fanart.tv/fanart/tv/78857/showbackground/naruto-53b827ea97f87.jpg", + "trailers": [ + { + "source": "j2hiC9BmJlQ", + "type": "Trailer" + } + ], + "links": [ + { + "name": "8.0", + "category": "imdb", + "url": "https://kitsu.io/anime/naruto" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Comedy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Comedy" + }, + { + "name": "Martial Arts", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Martial Arts" + }, + { + "name": "Super Power", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Super Power" + } + ] + }, + { + "id": "kitsu:1555", + "type": "series", + "animeType": "TV", + "name": "Naruto: Shippuuden", + "aliases": [ + "Naruto: Shippuden", + "Naruto: Shippuuden", + "Naruto Hurricane Chronicles" + ], + "description": "It has been two and a half years since Naruto Uzumaki left Konohagakure, the Hidden Leaf Village, for intense training following events which fueled his desire to be stronger. Now Akatsuki, the mysterious organization of elite rogue ninja, is closing in on their grand plan which may threaten the safety of the entire shinobi world.\n\nAlthough Naruto is older and sinister events loom on the horizon, he has changed little in personality—still rambunctious and childish—though he is now far more confident and possesses an even greater determination to protect his friends and home. Come whatever may, Naruto will carry on with the fight for what is important to him, even at the expense of his own body, in the continuation of the saga about the boy who wishes to become Hokage.\n\n(Source: MAL Rewrite)", + "releaseInfo": "2007-2017", + "runtime": "23 min", + "imdbRating": "8.4", + "genres": [ + "Action", + "Comedy", + "Martial Arts", + "Super Power", + "Adventure" + ], + "logo": "https://assets.fanart.tv/fanart/tv/79824/hdtvlogo/naruto-shippuuden-540cc2d768e14.png", + "poster": "https://media.kitsu.io/anime/poster_images/1555/medium.jpg", + "background": "https://assets.fanart.tv/fanart/tv/79824/showbackground/naruto-shippuuden-53d6e20630860.jpg", + "trailers": [ + { + "source": "1dy2zPPrKD0", + "type": "Trailer" + } + ], + "links": [ + { + "name": "8.4", + "category": "imdb", + "url": "https://kitsu.io/anime/naruto-shippuden" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Comedy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Comedy" + }, + { + "name": "Martial Arts", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Martial Arts" + }, + { + "name": "Super Power", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Super Power" + }, + { + "name": "Adventure", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Adventure" + } + ] + }, + { + "id": "kitsu:46581", + "type": "series", + "animeType": "special", + "name": "ROAD OF NARUTO", + "aliases": [ + "ROAD OF NARUTO", + "NARUTO - ナルト - 20 周年記念", + "NARUTO 20 Shuunenkinen", + "Naruto 20th Anniversary PV" + ], + "description": "A special animation to commemorate the 20th anniversary of the NARUTO anime.", + "releaseInfo": "2022", + "runtime": "10 min", + "imdbRating": "8.3", + "genres": [], + "poster": "https://media.kitsu.io/anime/46581/poster_image/medium-9ecc4e4e91f2e6b0012115e33104ba28.jpeg", + "background": "https://media.kitsu.io/anime/46581/cover_image/777c9d609b0fe4da063651a7b6c60708.jpg", + "trailers": [ + { + "source": "yKELA1qBAKA", + "type": "Trailer" + } + ], + "links": [ + { + "name": "8.3", + "category": "imdb", + "url": "https://kitsu.io/anime/road-of-naruto" + } + ] + }, + { + "id": "kitsu:549", + "type": "series", + "animeType": "special", + "name": "Naruto: Takigakure no Shitou - Ore ga Eiyuu Dattebayo!", + "aliases": [ + "Naruto: The Lost Story - Mission: Protect the Waterfall Village", + "Naruto: Takigakure no Shitou - Ore ga Eiyuu Dattebayo!", + "Battle at Hidden Falls. I am the Hero!", + "Naruto OVA 2", + "Naruto: Jump Festa 2004" + ], + "description": "A routine rank-C mission turned into a full-blown battle as the Hidden Fall village is attacked by enemy ninjas. Now Naruto, Sasuke and Sakura must help the leader of the Hidden Fall, Shibuki, protect his village and show him what being a hero is all about.\n(Source: ANN)", + "releaseInfo": "2003", + "runtime": "40 min", + "imdbRating": "6.6", + "genres": [ + "Action", + "Adventure", + "Comedy", + "Super Power" + ], + "poster": "https://media.kitsu.io/anime/poster_images/549/medium.jpg", + "background": "https://media.kitsu.io/anime/cover_images/549/original.jpg", + "trailers": [], + "links": [ + { + "name": "6.6", + "category": "imdb", + "url": "https://kitsu.io/anime/naruto-takigakure-no-shitou-ore-ga-eiyuu-dattebayo" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Adventure", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Adventure" + }, + { + "name": "Comedy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Comedy" + }, + { + "name": "Super Power", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Super Power" + } + ] + }, + { + "id": "kitsu:7008", + "type": "movie", + "animeType": "movie", + "name": "Naruto: Shippuuden Movie 6 - Road to Ninja", + "aliases": [ + "Road to Ninja: Naruto the Movie", + "Naruto: Shippuuden Movie 6 - Road to Ninja", + "Naruto Movie 9" + ], + "description": "Ten years ago, a gigantic demon beast known as the Nine-Tailed Demon Fox was released from its jinchuuriki by an unknown shinobi wearing a mask. The village of Konohagakure was close to destruction by the attack of the Nine-Tails, but the village was saved by its leader. Minato Namikaze and his wife Kushina Uzumaki—who was the jinchuuriki at the time of the attack—sealed away the demon inside their new born son: Naruto Uzumaki. However, this act of saving the village cost them their lives and they left the future of the ninja world to Naruto.\nWith the demon fox sealed away, things continued as normal. However, the peace of the village would not last long, for Pain, Konan, Itachi Uchiha, Kisame Hoshigaki, Sasori, Deidara, Hidan and Kakuzu—members of a dreaded shinobi group called the Akatsuki—attacked Konohagakure. Naruto narrowly manages to launch a counter-attack but why have these shinobi appeared when all of them were meant to have died? The mystery remains, but the shinobi are praised by heir families for completing such a dangerous mission. However, one of them who has never known the faces of his parents, Naruto, cannot help but feel lonely. At that exact time, suddenly, the masked man makes his appearance in Konoha. Naruto and his allies are both attacked by the man's mysterious new doujutsu.\n(Source: Naruto Wikia)", + "releaseInfo": "2012", + "runtime": "109 min", + "imdbRating": "7.8", + "genres": [ + "Action", + "Adventure", + "Martial Arts", + "Super Power" + ], + "logo": "https://assets.fanart.tv/fanart/movies/118406/hdmovielogo/naruto-shippuden-movie-6-road-to-ninja-51888cf79d03d.png", + "poster": "https://media.kitsu.io/anime/poster_images/7008/medium.jpg", + "background": "https://images.metahub.space/background/medium/tt2290828/img", + "trailers": [ + { + "source": "TDpYU8OmD-k", + "type": "Trailer" + } + ], + "links": [ + { + "name": "7.8", + "category": "imdb", + "url": "https://kitsu.io/anime/naruto-shippuden-movie-6-road-to-ninja" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Adventure", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Adventure" + }, + { + "name": "Martial Arts", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Martial Arts" + }, + { + "name": "Super Power", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Super Power" + } + ] + }, + { + "id": "kitsu:2036", + "type": "series", + "animeType": "special", + "name": "Naruto: Dai Katsugeki!! Yuki Hime Shinobu Houjou Dattebayo! Special: Konoha Annual Sports Festival", + "aliases": [ + "Hidden Leaf Village Grand Sports Festival", + "Naruto: Dai Katsugeki!! Yuki Hime Shinobu Houjou Dattebayo! Special: Konoha Annual Sports Festival", + "Gekijouban Naruto: Dai Katsugeki! Yuki Hime Ninpouchou Datte ba yo! - S1 Konoha Annual Sports Festival", + "Konoha no Sato no Daiun Douaki" + ], + "description": "The genin of Kohona are having a sports day filled with races, obstacle courses and of course the relay and the prize is a paid vacation for the winner. Unfortunately Naruto and his stomach are getting him into trouble again.\nNaruto really needs to go to the toilet but he has to wait for the line to the restroom is so long even the Akatsuki and Kabuto are in line! After the group race he runs to the toilet to find it closed for cleaning but then he tries to go to into the ladies room but Hinata pops by and tries to tell Naruto something but is interrupted by the speaker and then off to the obstacle course.\nNaruto needs to drink a whole liter of milk in this critical state. After that he sees some portable toilets, but they are wrecked by Choji's Human Boulder. Naruto tries to beat them up but Ino comes and drags him back. Finally the relay; Sakura passed it to Sasuke but on Naruto's turn the baton Sasuke was holding poked his butt. Out of desperation Naruto wins and finishes the race. He runs off to find a toilet but Shikamaru stops him. They cheer for him on the track but Naruto can't hold it anymore and let's it ALL go on the field with everyone standing around him. \n", + "releaseInfo": "2004", + "runtime": "11 min", + "imdbRating": "6.6", + "genres": [ + "Action", + "Comedy", + "Fantasy", + "Martial Arts", + "Sports" + ], + "poster": "https://media.kitsu.io/anime/poster_images/2036/medium.jpg", + "background": "https://media.kitsu.io/anime/cover_images/2036/original.jpg", + "trailers": [], + "links": [ + { + "name": "6.6", + "category": "imdb", + "url": "https://kitsu.io/anime/naruto-dai-katsugeki-yuki-hime-shinobu-houjou-dattebayo-special-konoha-annual-sports-festival" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Comedy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Comedy" + }, + { + "name": "Fantasy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Fantasy" + }, + { + "name": "Martial Arts", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Martial Arts" + }, + { + "name": "Sports", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Sports" + } + ] + }, + { + "id": "kitsu:2245", + "type": "movie", + "animeType": "movie", + "name": "Naruto: Shippuuden Movie 1", + "aliases": [ + "Naruto: Shippuden the Movie", + "Naruto: Shippuuden Movie 1", + "Naruto Shippuuden Movie", + "Naruto Movie 4", + "Gekijouban Naruto Shippuuden" + ], + "description": "Demons that once almost destroyed the world, are revived by someone. To prevent the world from being destroyed, the demon has to be sealed and the only one who can do it is the shrine maiden Shion from the country of demons, who has two powers; one is sealing demons and the other is predicting the deaths of humans. This time Naruto's mission is to guard Shion, but she predicts Naruto's death. The only way to escape it, is to get away from Shion, which would leave her unguarded, then the demon, whose only goal is to kill Shion will do so, thus meaning the end of the world. Naruto decides to challenge this \"prediction of death,\" but fails to prove Shion's prediction wrong and supposedly dies in vain.\n(Source: Wikipedia)", + "releaseInfo": "2007", + "runtime": "94 min", + "imdbRating": "7.3", + "genres": [ + "Action", + "Adventure", + "Comedy", + "Fantasy" + ], + "logo": "https://assets.fanart.tv/fanart/movies/20982/hdmovielogo/-naruto-----5bedd3e81eabf.png", + "poster": "https://media.kitsu.io/anime/poster_images/2245/medium.jpg", + "background": "https://images.metahub.space/background/medium/tt0988982/img", + "trailers": [], + "links": [ + { + "name": "7.3", + "category": "imdb", + "url": "https://kitsu.io/anime/naruto-shippuden-movie-1" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Adventure", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Adventure" + }, + { + "name": "Comedy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Comedy" + }, + { + "name": "Fantasy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Fantasy" + } + ] + }, + { + "id": "kitsu:3606", + "type": "movie", + "animeType": "movie", + "name": "Naruto: Shippuuden Movie 2 - Kizuna", + "aliases": [ + "Naruto: Shippuden the Movie 2 -Bonds-", + "Naruto: Shippuuden Movie 2 - Kizuna", + "Naruto Movie 5", + "Naruto Shippuuden Movie 2", + "Naruto Shippuuden: Bonds" + ], + "description": "A mysterious group of ninjas makes a surprise attack on the Konohagakure, which takes great damage. The nightmare of another Shinobi World War could become a reality. Sasuke, who left Konoha to kill his brother, Itachi, appears for the second time in front of Naruto at an unknown location to prevent it from coming to fruition.\n(Source: Wikipedia)", + "releaseInfo": "2008", + "runtime": "93 min", + "imdbRating": "7.2", + "genres": [ + "Action", + "Martial Arts", + "Supernatural" + ], + "logo": "https://assets.fanart.tv/fanart/movies/17581/hdmovielogo/naruto-shippuden-the-movie-bonds-5bec1ee26ec2c.png", + "poster": "https://media.kitsu.io/anime/poster_images/3606/medium.jpg", + "background": "https://images.metahub.space/background/medium/tt1160524/img", + "trailers": [ + { + "source": "OkI3ZCEbx_E", + "type": "Trailer" + } + ], + "links": [ + { + "name": "7.2", + "category": "imdb", + "url": "https://kitsu.io/anime/naruto-shippuden-movie-2-kizuna" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Martial Arts", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Martial Arts" + }, + { + "name": "Supernatural", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Supernatural" + } + ] + }, + { + "id": "kitsu:6861", + "type": "series", + "animeType": "TV", + "name": "Naruto SD: Rock Lee no Seishun Full-Power Ninden", + "aliases": [ + "NARUTO Spin-Off: Rock Lee & His Ninja Pals", + "Naruto SD: Rock Lee no Seishun Full-Power Ninden" + ], + "description": "Welcome to the Hidden Leaf Village. The village where Uzumaki Naruto, star of the TV show \"Naruto\" makes his home. Every day, countless powerful ninjas carry out missions and train to hone their skills. Our main character is one of these powerful ninjas...but it's not Naruto! It's the ninja who can't use ninjutsu, Rock Lee! In spite of his handicap, Lee has big dreams. He works hard every day to perfect his hand-to-hand combat skills and become a splendid ninja! And to achieve his dream, he puts in more effort than anyone else. Under the hot-blooded tutelage of his teacher Guy, he works alongside his teammates Tenten and Neji. Watch the Beautiful Green Beast Rock Lee train, go on missions, and have all sorts of adventures! \n(Source: Crunchyroll) ", + "releaseInfo": "2012-2013", + "runtime": "24 min", + "imdbRating": "6.7", + "genres": [ + "Action", + "Comedy", + "Parody" + ], + "logo": "https://assets.fanart.tv/fanart/tv/257837/hdtvlogo/rock-lee--his-ninja-pals-61ffa96d3a159.png", + "poster": "https://media.kitsu.io/anime/poster_images/6861/medium.jpg", + "background": "https://images.metahub.space/background/medium/tt2301807/img", + "trailers": [ + { + "source": "vAuU88KX8EA", + "type": "Trailer" + } + ], + "links": [ + { + "name": "6.7", + "category": "imdb", + "url": "https://kitsu.io/anime/rock-lee-no-seishun-full-power-ninden" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Comedy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Comedy" + }, + { + "name": "Parody", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Parody" + } + ] + }, + { + "id": "kitsu:3484", + "type": "series", + "animeType": "special", + "name": "Naruto Shippuuden: Shippuu! \"Konoha Gakuen\" Den", + "aliases": [ + "Naruto Shippuden: Konoha Gakuen - Special", + "Naruto Shippuuden: Shippuu! \"Konoha Gakuen\" Den", + "NARUTO Shippu Konoha Gakuen Den Special", + "Konoha High" + ], + "description": "Naruto school special.\nNaruto is a new cool student and when he meets Sasuke they start fighting.", + "releaseInfo": "2008", + "runtime": "8 min", + "imdbRating": "6.9", + "genres": [ + "Comedy" + ], + "poster": "https://media.kitsu.io/anime/poster_images/3484/medium.jpg", + "background": "https://media.kitsu.io/anime/cover_images/3484/original.jpg", + "trailers": [], + "links": [ + { + "name": "6.9", + "category": "imdb", + "url": "https://kitsu.io/anime/naruto-shippuden-konoha-gakuen-special" + }, + { + "name": "Comedy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Comedy" + } + ] + }, + { + "id": "kitsu:1941", + "type": "movie", + "animeType": "movie", + "name": "Naruto Movie 3: Dai Koufun! Mikazuki Jima no Animaru Panikku Dattebayo!", + "aliases": [ + "Naruto the Movie 3: Guardians of the Crescent Moon Kingdom", + "Naruto Movie 3: Dai Koufun! Mikazuki Jima no Animaru Panikku Dattebayo!", + "Naruto Movie Volume 3", + "Naruto: Gekijouban Naruto: Dai Koufun! Mikazuki-jima no Animal Panic Datte ba yo!" + ], + "description": "Naruto, Kakashi, Sakura, and Lee are sent to protect a prince during his trip around the world and see that he returns safely to his home in the Moon Country. The Moon Country happens to be really rich and as such the Prince tends to buy anything his heart desires, during his travels the Prince would come across a circus group that features a rare Sabre-toothed tiger that he just had to have. So he purchased the entire group. Suddenly a mission to protect just the spoiled prince that hardly listened to anything said, turns in to a mission to look after animals and a prince that doesn't listen to what they say, and in the end somehow get them all back safely to their home country. All the while there are three mysterious Ninja wielding some frightening jutsu waiting for them. Why are they attacking them? What do they want with Team Kakashi!?!\n(Source: NarutoFan)", + "releaseInfo": "2006", + "runtime": "94 min", + "imdbRating": "6.7", + "genres": [ + "Action", + "Adventure" + ], + "logo": "https://assets.fanart.tv/fanart/movies/18861/hdmovielogo/naruto-the-movie-guardians-of-the-crescent-moon-kingdom-5bedb85d66f02.png", + "poster": "https://media.kitsu.io/anime/poster_images/1941/medium.jpg", + "background": "https://images.metahub.space/background/medium/tt1071815/img", + "trailers": [], + "links": [ + { + "name": "6.7", + "category": "imdb", + "url": "https://kitsu.io/anime/naruto-movie-3-dai-koufun-mikazuki-jima-no-animaru-panikku-dattebayo" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Adventure", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Adventure" + } + ] + }, + { + "id": "kitsu:13051", + "type": "series", + "animeType": "TV", + "name": "Boruto: Naruto Next Generations", + "aliases": [ + "Boruto: Naruto Next Generations" + ], + "description": "Naruto was a young shinobi with an incorrigible knack for mischief. He achieved his dream to become the greatest ninja in the village and his face sits atop the Hokage monument. But this is not his story... A new generation of ninja are ready to take the stage, led by Naruto's own son, Boruto!\n\n(Source: VIZ Media)", + "releaseInfo": "2017-2023", + "runtime": "23 min", + "imdbRating": "6.4", + "genres": [ + "Adventure", + "Martial Arts", + "Super Power", + "Action" + ], + "logo": "https://assets.fanart.tv/fanart/tv/321285/hdtvlogo/boruto-naruto-next-generations-58e5152372f97.png", + "poster": "https://media.kitsu.io/anime/13051/poster_image/medium-16da0c0699ed8ccb42f8832a35791a00.jpeg", + "background": "https://assets.fanart.tv/fanart/tv/321285/showbackground/boruto-naruto-next-generations-5cc9deee6417c.jpg", + "trailers": [ + { + "source": "p3acMxaM7-g", + "type": "Trailer" + } + ], + "links": [ + { + "name": "6.4", + "category": "imdb", + "url": "https://kitsu.io/anime/boruto-naruto-next-generations" + }, + { + "name": "Adventure", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Adventure" + }, + { + "name": "Martial Arts", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Martial Arts" + }, + { + "name": "Super Power", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Super Power" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + } + ] + }, + { + "id": "kitsu:833", + "type": "movie", + "animeType": "movie", + "name": "Naruto Movie 2: Dai Gekitotsu! Maboroshi no Chiteiiseki Dattebayo!", + "aliases": [ + "Naruto the Movie 2: Legend of the Stone of Gelel", + "Naruto Movie 2: Dai Gekitotsu! Maboroshi no Chiteiiseki Dattebayo!", + "Naruto THE Movie vol.2", + "Naruto Movie 2", + "Gekijouban Naruto" + ], + "description": "Naruto, Shikamaru, and Sakura are executing their mission of delivering a lost pet to a certain village. However, right in the midst of things, troops led by the mysterious knight, Temujin, attack them. In the violent battle, the three become separated. Temujin challenges Naruto to a fight and at the end of the fierce battle, both fall together from a high cliff. Furthermore, Shikamaru, having been left behind, beholds a giant moving fortress as it appears before his very eyes. In order to get a grasp on the situation, he infiltrates the fortress by himself, however once there he witnesses a frightening sight... \n(Source: ANN)", + "releaseInfo": "2005", + "runtime": "96 min", + "imdbRating": "6.7", + "genres": [ + "Adventure", + "Comedy", + "Drama", + "Fantasy", + "Supernatural" + ], + "logo": "https://assets.fanart.tv/fanart/movies/16910/hdmovielogo/naruto-the-movie-2-legend-of-the-stone-of-gelel-5bedb846070cd.png", + "poster": "https://media.kitsu.io/anime/poster_images/833/medium.jpg", + "background": "https://images.metahub.space/background/medium/tt0791188/img", + "trailers": [], + "links": [ + { + "name": "6.7", + "category": "imdb", + "url": "https://kitsu.io/anime/naruto-movie-2-daigekitotsu-maboroshi-no-chiteiiseki-dattebayo" + }, + { + "name": "Adventure", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Adventure" + }, + { + "name": "Comedy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Comedy" + }, + { + "name": "Drama", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Drama" + }, + { + "name": "Fantasy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Fantasy" + }, + { + "name": "Supernatural", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Supernatural" + } + ] + }, + { + "id": "kitsu:5266", + "type": "movie", + "animeType": "movie", + "name": "Naruto: Shippuuden Movie 4 - The Lost Tower", + "aliases": [ + "Naruto: Shippuuden Movie 4 - The Lost Tower", + "Naruto Movie 7", + "Gekijouban Naruto Shippuuden: The Lost Tower" + ], + "description": "Assigned on a mission to capture Mukade, a missing-nin, Naruto Uzumaki sets out for the once glorious historic ruins of \"Ouran\", where he pursues and corners the rogue ninja. Mukade's goal is revealed to be a dormant leyline within the ruins; he unleashes the power of the leyline, causing a light to envelop Naruto, sending him into the past, 20 years before the series began. When Naruto awakens, he comes into contact with the Fourth Hokage, Minato Namikaze.\n(Source: Wikipedia) ", + "releaseInfo": "2010", + "runtime": "85 min", + "imdbRating": "7.4", + "genres": [ + "Action", + "Comedy", + "Martial Arts", + "Super Power" + ], + "logo": "https://assets.fanart.tv/fanart/movies/50723/hdmovielogo/naruto-shippuden-the-movie-the-lost-tower-520653a7df7ae.png", + "poster": "https://media.kitsu.io/anime/poster_images/5266/medium.jpg", + "background": "https://images.metahub.space/background/medium/tt1703048/img", + "trailers": [ + { + "source": "q4C4CZT8NTM", + "type": "Trailer" + } + ], + "links": [ + { + "name": "7.4", + "category": "imdb", + "url": "https://kitsu.io/anime/naruto-shippuden-movie-4-the-lost-tower" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Comedy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Comedy" + }, + { + "name": "Martial Arts", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Martial Arts" + }, + { + "name": "Super Power", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Super Power" + } + ] + }, + { + "id": "kitsu:4520", + "type": "movie", + "animeType": "movie", + "name": "Naruto: Shippuuden Movie 3 - Hi no Ishi wo Tsugu Mono", + "aliases": [ + "Naruto Shippuden the Movie: Will of Fire", + "Naruto: Shippuuden Movie 3 - Hi no Ishi wo Tsugu Mono", + "Naruto Shippuuden: Gekijouban Naruto Shippuuden: Hi no Ishi o Tsugu Mono", + "Naruto Shippuuden Movie 3", + "Naruto Movie 6", + "Naruto Shippuuden 3: Inheritors of Will of Fire" + ], + "description": "Ninjas with bloodline limits begin disappearing in all the countries and blame points toward the fire nation. By Tsunade's order, Kakashi is sacrificed to prevent an all out war. After inheriting charms left by Kakashi, Naruto fights through friends and foes to prevent his death while changing the minds of those who've inherited the will of fire.\n(Source: ANN)", + "releaseInfo": "2009", + "runtime": "95 min", + "imdbRating": "7.3", + "genres": [ + "Action", + "Comedy", + "Martial Arts", + "Super Power" + ], + "logo": "https://assets.fanart.tv/fanart/movies/36728/hdmovielogo/naruto-shippuden-the-movie-inheritors-of-the-will-of-fire-5beeac1a1b9a3.png", + "poster": "https://media.kitsu.io/anime/poster_images/4520/medium.jpg", + "background": "https://assets.fanart.tv/fanart/movies/36728/moviebackground/naruto-shippuden-the-movie-inheritors-of-the-will-of-fire-61eb010493d50.jpg", + "trailers": [ + { + "source": "dJ12XeF6S2Y", + "type": "Trailer" + } + ], + "links": [ + { + "name": "7.3", + "category": "imdb", + "url": "https://kitsu.io/anime/naruto-shippuden-movie-3-hi-no-ishi-wo-tsugu-mono" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Comedy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Comedy" + }, + { + "name": "Martial Arts", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Martial Arts" + }, + { + "name": "Super Power", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Super Power" + } + ] + }, + { + "id": "kitsu:7543", + "type": "movie", + "animeType": "movie", + "name": "The Last: Naruto the Movie", + "aliases": [ + "The Last: Naruto the Movie", + "Naruto Movie 10: Naruto the Movie: The Last,Naruto: Shippuuden Movie 7 - The Last", + "Naruto Movie 10: Naruto the Movie: The Last", + "Naruto: Shippuuden Movie 7 - The Last" + ], + "description": "The moon is beginning to fall, and at the rate it's going, it is doomed to fall on the Earth. The countdown for the survival of the planet begins. Among the havoc, Hinata's younger sister Hanabi is captured by the mysterious enemy, Toneri Ootsutsuki. Naruto must overcome great danger on a mission to save Hanabi and the world along with Hinata, Sai, Shikamaru, and Sakura is their final story. \"The final story is a first love.\"\n\n(Source: Anime News Network)", + "releaseInfo": "2014", + "runtime": "112 min", + "imdbRating": "8.0", + "genres": [ + "Action", + "Martial Arts", + "Super Power", + "Romance" + ], + "logo": "https://assets.fanart.tv/fanart/movies/317442/hdmovielogo/the-last-naruto-the-movie-553cbe16d6e54.png", + "poster": "https://media.kitsu.io/anime/7543/poster_image/medium-bb44bd1650f32d1c947e07eb073eb5e8.jpeg", + "background": "https://assets.fanart.tv/fanart/movies/317442/moviebackground/the-last-naruto-the-movie-56d5e9bdf1fa6.jpg", + "trailers": [ + { + "source": "tA3yE4_t6SY", + "type": "Trailer" + } + ], + "links": [ + { + "name": "8.0", + "category": "imdb", + "url": "https://kitsu.io/anime/the-last-naruto-the-movie" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Martial Arts", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Martial Arts" + }, + { + "name": "Super Power", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Super Power" + }, + { + "name": "Romance", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Romance" + } + ] + }, + { + "id": "kitsu:11771", + "type": "series", + "animeType": "special", + "name": "Boruto: Naruto the Movie - Naruto ga Hokage ni Natta Hi", + "aliases": [ + "Boruto: Naruto the Movie - Naruto ga Hokage ni Natta Hi", + "Boruto: Naruto the Movie - The Day Naruto Became the Hokage" + ], + "description": "Bundled with the limited edition of Blu-ray/DVD of Boruto: Naruto the Movie.", + "releaseInfo": "2016", + "runtime": "10 min", + "imdbRating": "7.5", + "genres": [ + "Action", + "Comedy", + "Martial Arts", + "Super Power" + ], + "poster": "https://media.kitsu.io/anime/poster_images/11771/medium.jpg", + "background": "https://media.kitsu.io/anime/cover_images/11771/original.jpg", + "trailers": [], + "links": [ + { + "name": "7.5", + "category": "imdb", + "url": "https://kitsu.io/anime/boruto-naruto-the-movie-naruto-ga-hokage-ni-natta-hi" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Comedy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Comedy" + }, + { + "name": "Martial Arts", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Martial Arts" + }, + { + "name": "Super Power", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Super Power" + } + ] + }, + { + "id": "kitsu:405", + "type": "movie", + "animeType": "movie", + "name": "Naruto the Movie: Ninja Clash in the Land of Snow", + "aliases": [ + "Naruto the Movie: Ninja Clash in the Land of Snow", + "Naruto Movie 1: Dai Katsugeki!! Yuki Hime Shinobu Houjou Dattebayo!", + "Naruto: Daikatsugeki! Yukihime Ninpocho Dattebayo!", + "Naruto: It's the Snow Princess' Ninja Art Book!" + ], + "description": "A land forever covered in ice... A princess missing for ten years... And one high-spirited ninja named Naruto! \nNaruto and the rest of Squad 7 take on a new mission: bring popular movie star Yukie Fujikaze to the Land of Snow, where they're filming the final scenes of her latest movie. Trouble is, she's even more headstrong than Naruto, and she doesn't want to go! Her reluctance may be connected to what else lies in wait for them--three rogue Snow ninja and a tyrannical ruler seeking the key to a mysterious treasure...\n(Source: VIZ Media)", + "releaseInfo": "2004", + "runtime": "82 min", + "imdbRating": "6.9", + "genres": [ + "Adventure", + "Comedy", + "Drama", + "Historical", + "Supernatural" + ], + "logo": "https://assets.fanart.tv/fanart/movies/16907/hdmovielogo/naruto-the-movie-ninja-clash-in-the-land-of-snow-5bedc89654867.png", + "poster": "https://media.kitsu.io/anime/poster_images/405/medium.jpg", + "background": "https://images.metahub.space/background/medium/tt0476680/img", + "trailers": [], + "links": [ + { + "name": "6.9", + "category": "imdb", + "url": "https://kitsu.io/anime/naruto-the-movie-ninja-clash-in-the-land-of-snow" + }, + { + "name": "Adventure", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Adventure" + }, + { + "name": "Comedy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Comedy" + }, + { + "name": "Drama", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Drama" + }, + { + "name": "Historical", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Historical" + }, + { + "name": "Supernatural", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Supernatural" + } + ] + }, + { + "id": "kitsu:6292", + "type": "movie", + "animeType": "movie", + "name": "Naruto: Honoo no Chuunin Shiken! Naruto vs. Konohamaru!!", + "aliases": [ + "Chunin Exam on Fire! and Naruto vs. Konohamaru!", + "Naruto: Honoo no Chuunin Shiken! Naruto vs. Konohamaru!!" + ], + "description": "Naruto faces off against his old pupil Konohamaru in a tournament during the chuunin entrance exams.", + "releaseInfo": "2011", + "runtime": "14 min", + "imdbRating": "7.1", + "genres": [ + "Action", + "Adventure", + "Martial Arts", + "Super Power" + ], + "poster": "https://media.kitsu.io/anime/6292/poster_image/medium-5aaa86a422ce294f2551e3387ca4edc9.jpeg", + "background": "https://media.kitsu.io/anime/cover_images/6292/original.jpg", + "trailers": [], + "links": [ + { + "name": "7.1", + "category": "imdb", + "url": "https://kitsu.io/anime/naruto-honoo-no-chuunin-shiken-naruto-vs-konohamaru" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Adventure", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Adventure" + }, + { + "name": "Martial Arts", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Martial Arts" + }, + { + "name": "Super Power", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Super Power" + } + ] + }, + { + "id": "kitsu:10089", + "type": "movie", + "animeType": "movie", + "name": "Boruto: Naruto the Movie", + "aliases": [ + "Boruto: Naruto the Movie", + "Gekijouban Naruto (2015)" + ], + "description": "Boruto Uzumaki has inherited the mischievous spirit and endless energy from his famous father, the 7th Hokage, Naruto. As he enters his Chunin exams, a harsh decision made by Naruto angers Boruto, causing their personalities to clash, awakening a fierce ambition within the young shinobi to surpass his father with his own skills and techniques. But in order to do so, he will need the help of none other than Uchiha Sasuke, Naruto's lifelong rival and childhood friend. Although Boruto has convinced himself that he has what it takes to surpass the 7th Hokage, he soon discovers that the road ahead is not nearly as simple as the young shinobi has envisioned.Boruto: Naruto the Movie opens the doors for a new generation of shinobi to put their abilities to the test, as they face a mysterious enemy and hope to restore peace to Konoha, and the hardships within their own families. The 7th Hokage certainly has an impressive battle history behind him, but on this occasion, he will need the strong teamwork of old friends and new talents in order to win.", + "releaseInfo": "2015", + "runtime": "95 min", + "imdbRating": "7.6", + "genres": [ + "Action", + "Comedy", + "Super Power", + "Martial Arts" + ], + "logo": "https://assets.fanart.tv/fanart/movies/347201/hdmovielogo/boruto-naruto-the-movie-56069e1a3f13f.png", + "poster": "https://media.kitsu.io/anime/10089/poster_image/medium-08ef5392ff25db376a86b040d242296d.jpeg", + "background": "https://images.metahub.space/background/medium/tt4618398/img", + "trailers": [ + { + "source": "Cvdv2GGnn0A", + "type": "Trailer" + } + ], + "links": [ + { + "name": "7.6", + "category": "imdb", + "url": "https://kitsu.io/anime/boruto-naruto-the-movie" + }, + { + "name": "Action", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Action" + }, + { + "name": "Comedy", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Comedy" + }, + { + "name": "Super Power", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Super Power" + }, + { + "name": "Martial Arts", + "category": "Genres", + "url": "stremio:///discover/https%3A%2F%2Fanime-kitsu.strem.fun%2Fmanifest.json/anime/kitsu-anime-popular?genre=Martial Arts" + } + ] + } + ], + "cacheMaxAge": 43200 +} \ No newline at end of file diff --git a/src/node/consumer/test/mock-responses/metadata_mock_responses.ts b/src/node/consumer/test/mock-responses/metadata_mock_responses.ts new file mode 100644 index 0000000..01eba04 --- /dev/null +++ b/src/node/consumer/test/mock-responses/metadata_mock_responses.ts @@ -0,0 +1,40 @@ +import {http, HttpResponse} from "msw"; +import cinemetaQuery from "./assets/cinemeta-query-response.json"; +import cinemetaFlashFull from "./assets/flash-episode-list.json"; +import kitsuNarutoFull from "./assets/kitsu-naruto-full.json"; +import imdbTheFlash from "./assets/name-to-imdb-flash.json"; +import kitsuNarutoSearchId from "./assets/test-kitsu-search-id-naruto.json"; + +const kitsuNarutoIdSearchTestResponse = http.get('https://anime-kitsu.strem.fun/catalog/series/kitsu-anime-list/search=naruto%202002%20S1.json', () => { + return HttpResponse.json(kitsuNarutoSearchId); +}); + +const kitsuNarutoMetaDataSearchTestResponse = http.get('https://anime-kitsu.strem.fun/meta/Series/kitsu:11.json', () => { + return HttpResponse.json(kitsuNarutoFull); +}); + +const nameToImdbTheFlash = http.get('https://sg.media-imdb.com/suggests/t/the%20flash%201990.json', () => { + const jsonpResponse = `/**/imdb$the_flash%201990(${JSON.stringify(imdbTheFlash)});`; + return HttpResponse.json(jsonpResponse); +}); + +const cinemetaQueryResponse = http.get('https://cinemeta.strem.io/stremioget/stremio/v1/q.json', () => { + return HttpResponse.json(cinemetaQuery); +}); + +const cinemetaFlashMetadataSearchTestResponse = http.get('https://v3-cinemeta.strem.io/meta/imdb/tt0098798.json', () => { + return HttpResponse.json(cinemetaFlashFull); +}); + +const checkIfImdbEpisode = http.get('https://www.imdb.com/title/tt0579968/', () => { + return HttpResponse.text(''); +}); + +export { + kitsuNarutoIdSearchTestResponse, + kitsuNarutoMetaDataSearchTestResponse, + nameToImdbTheFlash, + cinemetaQueryResponse, + cinemetaFlashMetadataSearchTestResponse, + checkIfImdbEpisode +} \ No newline at end of file diff --git a/src/node/consumer/test/mock-responses/trackers_mock_responses.ts b/src/node/consumer/test/mock-responses/trackers_mock_responses.ts new file mode 100644 index 0000000..ca4d68a --- /dev/null +++ b/src/node/consumer/test/mock-responses/trackers_mock_responses.ts @@ -0,0 +1,5 @@ +import {http, HttpResponse} from "msw"; + +export const trackerTestResponse = http.get('https://ngosang.github.io/trackerslist/trackers_all.txt', () => { + return HttpResponse.text('http://tracker1.com\nhttp://tracker2.com') +}); \ No newline at end of file diff --git a/src/node/consumer/test/services/cache_service.test.ts b/src/node/consumer/test/services/cache_service.test.ts new file mode 100644 index 0000000..6a5e8b6 --- /dev/null +++ b/src/node/consumer/test/services/cache_service.test.ts @@ -0,0 +1,124 @@ +import "reflect-metadata"; // required +import {ILoggingService} from '@interfaces/logging_service'; +import {CacheMethod, CacheService} from '@services/cache_service'; +import {IocTypes} from "@setup/ioc_types"; +import {Container} from "inversify"; + +jest.mock('@services/configuration_service', () => { + return { + configurationService: { + cacheConfig: { + MONGODB_HOST: 'localhost', + MONGODB_PORT: '27017', + MONGODB_DB: 'knightcrawler', + MONGO_INITDB_ROOT_USERNAME: 'mongo', + MONGO_INITDB_ROOT_PASSWORD: 'mongo', + NO_CACHE: false, + COLLECTION_NAME: 'knightcrawler_consumer_collection', + }, + } + } +}); + +jest.mock('@services/logging_service', () => { + return { + error: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + } +}) + +jest.mock('cache-manager', () => { + return { + createCache: jest.fn().mockReturnValue({ + wrap: jest.fn().mockImplementation((_, method) => method()), + }), + memoryStore: jest.fn(), + }; +}); + +jest.mock('@tirke/node-cache-manager-mongodb', () => { + return { + mongoDbStore: jest.fn(), + }; +}); + +describe('CacheService Tests', () => { + let cacheService: CacheService, + loggingService: ILoggingService, + cacheMethod: CacheMethod; + + beforeEach(() => { + jest.clearAllMocks(); + process.env.LOG_LEVEL = 'debug'; + cacheMethod = jest.fn().mockResolvedValue({}); + loggingService = jest.requireMock('@services/logging_service'); + const container = new Container(); + container.bind(CacheService).toSelf(); + container.bind(IocTypes.ILoggingService).toConstantValue(loggingService); + cacheService = container.get(CacheService); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should cacheWrapImdbId correctly', async () => { + const result = await cacheService.cacheWrapImdbId('testKey', cacheMethod); + expect(result).toBeDefined(); + expect(loggingService.debug).toHaveBeenCalledTimes(3); + }); + + it('should cacheWrapKitsuId correctly', async () => { + const result = await cacheService.cacheWrapKitsuId('testKey', cacheMethod); + expect(result).toBeDefined(); + expect(loggingService.debug).toHaveBeenCalledTimes(3); + }); + + it('should cacheWrapMetadata correctly', async () => { + const result = await cacheService.cacheWrapMetadata('testId', cacheMethod); + expect(result).toBeDefined(); + expect(loggingService.debug).toHaveBeenCalledTimes(3); + }); + + it('should cacheTrackers correctly', async () => { + const result = await cacheService.cacheTrackers(cacheMethod); + expect(result).toBeDefined(); + expect(loggingService.debug).toHaveBeenCalledTimes(3); + }); + + it('should handle error in cacheMethod for cacheWrapImdbId', async () => { + cacheMethod = jest.fn().mockRejectedValue(new Error('Test error')); + await expect(cacheService.cacheWrapImdbId('testKey', cacheMethod)).rejects.toThrow('Test error'); + }); + + it('should handle error in cacheMethod for cacheWrapKitsuId', async () => { + cacheMethod = jest.fn().mockRejectedValue(new Error('Test error')); + await expect(cacheService.cacheWrapKitsuId('testKey', cacheMethod)).rejects.toThrow('Test error'); + }); + + it('should handle error in cacheMethod for cacheWrapMetadata', async () => { + cacheMethod = jest.fn().mockRejectedValue(new Error('Test error')); + await expect(cacheService.cacheWrapMetadata('testId', cacheMethod)).rejects.toThrow('Test error'); + }); + + it('should handle error in cacheMethod for cacheTrackers', async () => { + cacheMethod = jest.fn().mockRejectedValue(new Error('Test error')); + await expect(cacheService.cacheTrackers(cacheMethod)).rejects.toThrow('Test error'); + }); + + it('should handle when cache is disabled', async () => { + jest.mock('@services/configuration_service', () => { + return { + configurationService: { + cacheConfig: { + NO_CACHE: true, + }, + } + } + }); + + const result = await cacheService.cacheWrapImdbId('testKey', cacheMethod); + expect(result).toBeDefined(); + }); +}); \ No newline at end of file diff --git a/src/node/consumer/test/services/configuration_service.test.ts b/src/node/consumer/test/services/configuration_service.test.ts new file mode 100644 index 0000000..a82cea5 --- /dev/null +++ b/src/node/consumer/test/services/configuration_service.test.ts @@ -0,0 +1,139 @@ +import "reflect-metadata"; // required + +describe('Configuration Tests', () => { + beforeEach(() => { + jest.resetModules(); + }); + it('should populate cacheConfig correctly', async () => { + process.env.MONGODB_HOST = 'test_mongodb'; + process.env.MONGODB_PORT = '27017'; + process.env.MONGODB_DB = 'knightcrawler'; + process.env.MONGO_INITDB_ROOT_USERNAME = 'mongo'; + process.env.MONGO_INITDB_ROOT_PASSWORD = 'mongo'; + process.env.NO_CACHE = 'false'; + process.env.MONGODB_COLLECTION = 'knightcrawler_consumer_collection'; + const {configurationService} = await import("@services/configuration_service"); + const {cacheConfig} = configurationService; + expect(cacheConfig.MONGODB_HOST).toBe('test_mongodb'); + expect(cacheConfig.MONGODB_PORT).toBe('27017'); + expect(cacheConfig.MONGODB_DB).toBe('knightcrawler'); + expect(cacheConfig.MONGO_INITDB_ROOT_USERNAME).toBe('mongo'); + expect(cacheConfig.MONGO_INITDB_ROOT_PASSWORD).toBe('mongo'); + expect(cacheConfig.NO_CACHE).toBe(false); + expect(cacheConfig.COLLECTION_NAME).toBe('knightcrawler_consumer_collection'); + expect(cacheConfig.MONGO_URI).toBe('mongodb://mongo:mongo@test_mongodb:27017/knightcrawler?authSource=admin'); + }); + + it('should populate databaseConfig correctly', async() => { + process.env.POSTGRES_HOST = 'postgres'; + process.env.POSTGRES_PORT = '5432'; + process.env.POSTGRES_DB = 'knightcrawler'; + process.env.POSTGRES_USER = 'postgres'; + process.env.POSTGRES_PASSWORD = 'postgres'; + process.env.AUTO_CREATE_AND_APPLY_MIGRATIONS = 'false'; + const {configurationService} = await import("@services/configuration_service"); + const {databaseConfig} = configurationService; + expect(databaseConfig.POSTGRES_HOST).toBe('postgres'); + expect(databaseConfig.POSTGRES_PORT).toBe(5432); + expect(databaseConfig.POSTGRES_DB).toBe('knightcrawler'); + expect(databaseConfig.POSTGRES_USER).toBe('postgres'); + expect(databaseConfig.POSTGRES_PASSWORD).toBe('postgres'); + expect(databaseConfig.AUTO_CREATE_AND_APPLY_MIGRATIONS).toBe(false); + expect(databaseConfig.POSTGRES_URI).toBe('postgres://postgres:postgres@postgres:5432/knightcrawler'); + }); + + it('should process boolean when true as true for migrations', async() => { + process.env.AUTO_CREATE_AND_APPLY_MIGRATIONS = 'true'; + const {configurationService} = await import("@services/configuration_service"); + const {databaseConfig} = configurationService; + expect(databaseConfig.AUTO_CREATE_AND_APPLY_MIGRATIONS).toBe(true); + }); + + it('should process boolean when 1 as true for migrations', async() => { + process.env.AUTO_CREATE_AND_APPLY_MIGRATIONS = '1'; + const {configurationService} = await import("@services/configuration_service"); + const {databaseConfig} = configurationService; + expect(databaseConfig.AUTO_CREATE_AND_APPLY_MIGRATIONS).toBe(true); + }); + + it('should process boolean when yes as true for migrations', async() => { + process.env.AUTO_CREATE_AND_APPLY_MIGRATIONS = 'yes'; + const {configurationService} = await import("@services/configuration_service"); + const {databaseConfig} = configurationService; + expect(databaseConfig.AUTO_CREATE_AND_APPLY_MIGRATIONS).toBe(true); + }); + + it('should process boolean when uppercase TRUE as true for migrations', async() => { + process.env.AUTO_CREATE_AND_APPLY_MIGRATIONS = 'TRUE'; + const {configurationService} = await import("@services/configuration_service"); + const {databaseConfig} = configurationService; + expect(databaseConfig.AUTO_CREATE_AND_APPLY_MIGRATIONS).toBe(true); + }); + + it('should process boolean when uppercase FALSE as false for migrations', async() => { + process.env.AUTO_CREATE_AND_APPLY_MIGRATIONS = 'FALSE'; + const {configurationService} = await import("@services/configuration_service"); + const {databaseConfig} = configurationService; + expect(databaseConfig.AUTO_CREATE_AND_APPLY_MIGRATIONS).toBe(false); + }); + + it('should process boolean when no as false for migrations', async() => { + process.env.AUTO_CREATE_AND_APPLY_MIGRATIONS = 'no'; + const {configurationService} = await import("@services/configuration_service"); + const {databaseConfig} = configurationService; + expect(databaseConfig.AUTO_CREATE_AND_APPLY_MIGRATIONS).toBe(false); + }); + + it('should process boolean when no as 0 for migrations', async () => { + process.env.AUTO_CREATE_AND_APPLY_MIGRATIONS = '0'; + const {configurationService} = await import("@services/configuration_service"); + const {databaseConfig} = configurationService; + expect(databaseConfig.AUTO_CREATE_AND_APPLY_MIGRATIONS).toBe(false); + }); + + it('should populate jobConfig correctly', async() => { + process.env.JOB_CONCURRENCY = '1'; + process.env.JOBS_ENABLED = 'true'; + const {configurationService} = await import("@services/configuration_service"); + const {jobConfig} = configurationService; + expect(jobConfig.JOB_CONCURRENCY).toBe(1); + expect(jobConfig.JOBS_ENABLED).toBe(true); + }); + + it('should populate metadataConfig correctly', async() => { + process.env.IMDB_CONCURRENT = '1'; + process.env.IMDB_INTERVAL_MS = '1000'; + const {configurationService} = await import("@services/configuration_service"); + const {metadataConfig} = configurationService; + expect(metadataConfig.IMDB_CONCURRENT).toBe(1); + expect(metadataConfig.IMDB_INTERVAL_MS).toBe(1000); + }); + + it('should populate rabbitConfig correctly', async () => { + process.env.RABBIT_URI = 'amqp://localhost'; + process.env.QUEUE_NAME = 'test-queue'; + const {configurationService} = await import("@services/configuration_service"); + const {rabbitConfig} = configurationService; + expect(rabbitConfig.RABBIT_URI).toBe('amqp://localhost'); + expect(rabbitConfig.QUEUE_NAME).toBe('test-queue'); + }); + + it('should populate torrentConfig correctly', async () => { + process.env.MAX_CONNECTIONS_PER_TORRENT = '20'; + process.env.TORRENT_TIMEOUT = '30000'; + const {configurationService} = await import("@services/configuration_service"); + const {torrentConfig} = configurationService; + expect(torrentConfig.MAX_CONNECTIONS_PER_TORRENT).toBe(20); + expect(torrentConfig.TIMEOUT).toBe(30000); + }); + + it('should populate trackerConfig correctly', async () => { + process.env.TRACKERS_URL = 'https://ngosang.github.io/trackerslist/trackers_all.txt'; + process.env.UDP_TRACKERS_ENABLED = 'false'; + const {configurationService} = await import("@services/configuration_service"); + const {trackerConfig} = configurationService; + expect(trackerConfig.TRACKERS_URL).toBe('https://ngosang.github.io/trackerslist/trackers_all.txt'); + expect(trackerConfig.UDP_ENABLED).toBe(false); + }); + +}); \ No newline at end of file diff --git a/src/node/consumer/test/services/logging_service.test.ts b/src/node/consumer/test/services/logging_service.test.ts new file mode 100644 index 0000000..975d45e --- /dev/null +++ b/src/node/consumer/test/services/logging_service.test.ts @@ -0,0 +1,46 @@ +import "reflect-metadata"; // required +import {LoggingService} from '@services/logging_service'; + +jest.mock('pino', () => { + const actualPino = jest.requireActual('pino'); + return { + ...actualPino, + pino: jest.fn().mockImplementation(() => ({ + info: jest.fn(), + error: jest.fn(), + debug: jest.fn(), + warn: jest.fn(), + })), + }; +}); + +describe('LoggingService Tests', () => { + let service: LoggingService, + mockLogger: any; + + beforeEach(() => { + jest.clearAllMocks(); + service = new LoggingService(); + mockLogger = (service as any).logger; + }); + + it('should log info', () => { + service.info('test message', {key: 'value'}); + expect(mockLogger.info).toHaveBeenCalledWith('test message', [{key: 'value'}]); + }); + + it('should log error', () => { + service.error('test message', {key: 'value'}); + expect(mockLogger.error).toHaveBeenCalledWith('test message', [{key: 'value'}]); + }); + + it('should log debug', () => { + service.debug('test message', {key: 'value'}); + expect(mockLogger.debug).toHaveBeenCalledWith('test message', [{key: 'value'}]); + }); + + it('should log warn', () => { + service.warn('test message', {key: 'value'}); + expect(mockLogger.warn).toHaveBeenCalledWith('test message', [{key: 'value'}]); + }) +}); \ No newline at end of file diff --git a/src/node/consumer/test/services/metadata_service.test.ts b/src/node/consumer/test/services/metadata_service.test.ts new file mode 100644 index 0000000..0b94220 --- /dev/null +++ b/src/node/consumer/test/services/metadata_service.test.ts @@ -0,0 +1,123 @@ +import "reflect-metadata"; // required +import {ICacheService} from "@interfaces/cache_service"; +import {IMetadataResponse} from "@interfaces/metadata_response"; +import {MetadataService} from "@services/metadata_service"; +import {IocTypes} from "@setup/ioc_types"; +import {Container} from "inversify"; +import {setupServer} from "msw/node"; +import * as responses from "../mock-responses/metadata_mock_responses"; + +jest.mock('@services/cache_service', () => { + return { + cacheWrapImdbId: jest.fn().mockImplementation(async (key, fn) => await fn()), + cacheWrapKitsuId: jest.fn().mockImplementation(async (key, fn) => await fn()), + cacheWrapMetadata: jest.fn().mockImplementation(async (key, fn) => await fn()), + } +}) + +const server = setupServer( + responses.cinemetaQueryResponse, + responses.cinemetaFlashMetadataSearchTestResponse, + responses.kitsuNarutoIdSearchTestResponse, + responses.kitsuNarutoMetaDataSearchTestResponse, + responses.nameToImdbTheFlash, + responses.checkIfImdbEpisode); + +beforeAll(() => server.listen()) +beforeEach(() => { + jest.clearAllMocks(); + jest.spyOn(Date, 'now').mockImplementation(() => 1234567890); +}) +afterEach(() => () => { + server.resetHandlers() + jest.spyOn(Date, 'now').mockRestore(); +}) +afterAll(() => server.close()) + +describe('MetadataService Tests', () => { + let metadataService: MetadataService, + mockCacheService: ICacheService; + + beforeEach(() => { + mockCacheService = jest.requireMock('@services/cache_service'); + const container = new Container(); + container.bind(MetadataService).toSelf(); + container.bind(IocTypes.ICacheService).toConstantValue(mockCacheService); + metadataService = container.get(MetadataService); + }); + + it("should get kitsu id", async () => { + const result = await metadataService.getKitsuId({ + title: 'Naruto', + year: 2002, + season: 1 + }); + expect(mockCacheService.cacheWrapKitsuId).toHaveBeenCalledWith('naruto 2002 S1', expect.any(Function)); + expect(result).not.toBeNull(); + expect(result).toEqual('11'); + }); + + it("should get kitsu metadata", async () => { + const result = await metadataService.getMetadata({ + id: 'kitsu:11', + type: 'series' + }); + + expect(mockCacheService.cacheWrapMetadata).toHaveBeenCalledWith('kitsu:11', expect.any(Function)); + expect(result).not.toBeNull(); + + const body = result as IMetadataResponse; + expect(body.videos).not.toBeNull(); + expect(body.videos.length).toBe(220); + }); + + it("should get imdb metadata", async () => { + const result = await metadataService.getMetadata({ + id: 'tt0098798', + type: 'series' + }); + + expect(mockCacheService.cacheWrapMetadata).toHaveBeenCalledWith('tt0098798', expect.any(Function)); + expect(result).not.toBeNull(); + + const body = result as IMetadataResponse; + expect(body.videos).not.toBeNull(); + expect(body.videos.length).toBe(22); + }); + + it("should get imdb id the flash 2014", async () => { + const result = await metadataService.getImdbId({ + title: 'The Flash', + year: 2014, + type: 'series' + }); + expect(mockCacheService.cacheWrapImdbId).toHaveBeenCalledWith('the flash_2014_series', expect.any(Function)); + expect(result).not.toBeNull(); + expect(result).toEqual('tt3107288'); + }); + + it("should return false if imdb id is not provided", async () => { + const result = await metadataService.isEpisodeImdbId(undefined); + expect(result).toBe(false); + }); + + it("should return false if kitsu id is provided", async () => { + const result = await metadataService.isEpisodeImdbId("kitsu:11"); + expect(result).toBe(false); + }); + + it("should escape title naruto, with year", () => { + const result = metadataService.escapeTitle('Naruto: Shippuden | 2002'); + expect(result).toEqual('naruto shippuden 2002'); + }); + + it("should check if imdb id is an episode: the flash 1990", async () => { + const result = await metadataService.isEpisodeImdbId('tt0579968'); + expect(result).toBe(true); + }); + + it("should escape title naruto, no year", () => { + const result = metadataService.escapeTitle('Naruto: Shippuden'); + expect(result).toEqual('naruto shippuden'); + }); +}); \ No newline at end of file diff --git a/src/node/consumer/test/services/process_torrent_job.test.ts b/src/node/consumer/test/services/process_torrent_job.test.ts new file mode 100644 index 0000000..9abcfba --- /dev/null +++ b/src/node/consumer/test/services/process_torrent_job.test.ts @@ -0,0 +1,137 @@ +import "reflect-metadata"; // required +import {ILoggingService} from '@interfaces/logging_service'; +import {ITorrentProcessingService} from '@interfaces/torrent_processing_service'; +import {ProcessTorrentsJob} from '@jobs/process_torrents_job'; +import {configurationService} from '@services/configuration_service'; +import {IocTypes} from "@setup/ioc_types"; +import client, {ConsumeMessage} from 'amqplib'; +import {Container} from "inversify"; + +jest.mock('@services/configuration_service', () => { + return { + configurationService: { + rabbitConfig: { + RABBIT_URI: 'amqp://localhost', + QUEUE_NAME: 'test_queue', + }, + jobConfig: { + JOBS_ENABLED: true, + JOB_CONCURRENCY: 1, + }, + } + } +}); + +jest.mock('amqplib', () => { + return { + connect: jest.fn().mockResolvedValue({ + createChannel: jest.fn().mockResolvedValue({ + assertQueue: jest.fn(), + prefetch: jest.fn(), + consume: jest.fn(), + ack: jest.fn(), + }), + }), + }; +}); + +jest.mock('@services/logging_service', () => { + return { + error: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + } +}) + +jest.mock('@services/torrent_processing_service', () => { + return { + processTorrentRecord: jest.fn().mockResolvedValue(undefined), + } +}) + +describe('ProcessTorrentsJob Tests', () => { + let processTorrentsJob: ProcessTorrentsJob, + loggingService: ILoggingService, + torrentProcessingService: ITorrentProcessingService; + + beforeEach(() => { + jest.clearAllMocks(); + loggingService = jest.requireMock('@services/logging_service'); + torrentProcessingService = jest.requireMock('@services/torrent_processing_service'); + + const container = new Container(); + container.bind(ProcessTorrentsJob).toSelf(); + container.bind(IocTypes.ILoggingService).toConstantValue(loggingService); + container.bind(IocTypes.ITorrentProcessingService).toConstantValue(torrentProcessingService); + processTorrentsJob = container.get(ProcessTorrentsJob); + }); + + afterEach(() => { + jest.clearAllMocks() + }) + + describe('listenToQueue', () => { + test('should connect to the rabbitmq server and create a channel', async () => { + await processTorrentsJob.listenToQueue(); + expect(client.connect).toHaveBeenCalledWith(configurationService.rabbitConfig.RABBIT_URI); + }); + + test('should log an error if connection or channel setup fails', async () => { + (client.connect as any).mockImplementationOnce(() => { + throw new Error('Connection error'); + }); + + await processTorrentsJob.listenToQueue(); + expect(loggingService.error).toHaveBeenCalledWith('Failed to connect and setup channel', expect.any(Error)); + }); + + test('should process messages from the queue', async () => { + const mockMessage = { + content: Buffer.from(JSON.stringify({ + message: { + name: 'test_name', + source: 'test_source', + category: 'test_category', + infoHash: 'test_hash', + size: 'test_size', + seeders: 0, + leechers: 0, + imdb: 'test_imdb', + processed: false, + } + })), + } as ConsumeMessage; + + (client.connect as jest.Mock).mockResolvedValue({ + createChannel: jest.fn().mockResolvedValue({ + assertQueue: jest.fn().mockResolvedValue({ + consumerCount: 1, + }), + prefetch: jest.fn(), + consume: jest.fn().mockImplementation((_, callback) => { + callback(mockMessage); + }), + ack: jest.fn(), + }), + }); + + await processTorrentsJob.listenToQueue(); + expect(loggingService.info).toHaveBeenCalledWith('Worker is running! Waiting for new torrents...'); + expect(client.connect).toHaveBeenCalledWith(configurationService.rabbitConfig.RABBIT_URI); + expect(loggingService.error).toBeCalledTimes(0); + + expect(torrentProcessingService.processTorrentRecord).toHaveBeenCalledWith({ + name: 'test_name', + source: 'test_source', + category: 'test_category', + infoHash: 'test_hash', + size: 'test_size', + seeders: 0, + leechers: 0, + imdb: 'test_imdb', + processed: false, + info_hash: 'test_hash' + }); + }); + }); +}); \ No newline at end of file diff --git a/src/node/consumer/test/services/torrent_download_service.test.ts b/src/node/consumer/test/services/torrent_download_service.test.ts new file mode 100644 index 0000000..1a1619e --- /dev/null +++ b/src/node/consumer/test/services/torrent_download_service.test.ts @@ -0,0 +1,148 @@ +import "reflect-metadata"; // required +import {ILoggingService} from '@interfaces/logging_service'; +import {IParsedTorrent} from "@interfaces/parsed_torrent"; +import {TorrentDownloadService} from '@services/torrent_download_service'; +import {IocTypes} from "@setup/ioc_types"; +import {Container} from "inversify"; +import torrentStream from 'torrent-stream'; + +jest.mock('@services/logging_service', () => { + return { + error: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + } +}) + +jest.mock('torrent-stream', () => { + return jest.fn().mockImplementation(() => ({ + on: jest.fn(), + files: [], + destroy: jest.fn(), + })); +}); + +describe('TorrentDownloadService', () => { + let torrentDownloadService: TorrentDownloadService, + mockLoggingService: ILoggingService; + + beforeEach(() => { + jest.clearAllMocks(); + mockLoggingService = jest.requireMock('@services/logging_service'); + + const container = new Container(); + container.bind(TorrentDownloadService).toSelf(); + container.bind(IocTypes.ILoggingService).toConstantValue(mockLoggingService); + torrentDownloadService = container.get(TorrentDownloadService); + }); + + it('should get torrent files', async () => { + const mockTorrent: IParsedTorrent = { + size: 123456789, + isPack: false, + imdbId: 'tt1234567', + kitsuId: 1234, + trackers: 'http://tracker1.com,http://tracker2.com', + provider: 'provider1', + infoHash: '1234567890abcdef', + type: 'movie', + uploadDate: new Date(), + seeders: 100, + torrentId: 'torrent1', + fileCollection: {}, + title: 'Test Movie', + year: 2020, + season: 1, + episode: 1, + resolution: '1080p', + codec: 'H.264', + audio: 'AAC', + group: 'GRP', + extended: false, + hardcoded: false, + proper: false, + repack: false, + container: 'mp4', + unrated: false, + }; + + const mockFiles = [ + { + name: 'file1.mp4', + path: '/path/to/file1.mp4', + length: 123456789, + fileIndex: 0, + select: jest.fn(), + deselect: jest.fn(), + createReadStream: jest.fn(), + }, + { + name: 'file2.srt', + path: '/path/to/file2.srt', + length: 987654321, + fileIndex: 1, + select: jest.fn(), + deselect: jest.fn(), + createReadStream: jest.fn(), + }, + ]; + + + const mockEngine = { + on: jest.fn((event, callback) => { + if (event === 'ready') { + callback(); + } + }), + files: mockFiles, + destroy: jest.fn(), + connect: jest.fn(), + disconnect: jest.fn(), + block: jest.fn(), + remove: jest.fn(), + listen: jest.fn(), + swarm: { + downloaded: 2, + }, + infoHash: 'mockInfoHash', + }; + + (torrentStream as jest.MockedFunction).mockReturnValue(mockEngine); + + + const result = await torrentDownloadService.getTorrentFiles(mockTorrent); + + expect(result).toEqual({ + contents: mockFiles.map(file => ({ + path: file.path, + fileIndex: file.fileIndex, + infoHash: mockTorrent.infoHash, + size: file.length + })), + videos: mockFiles.filter(file => file.name.endsWith('.mp4')).map(file => ({ + fileIndex: file.fileIndex, + infoHash: mockTorrent.infoHash, + path: file.path, + size: file.length, + title: file.name.split('.')[0], + extension: file.name.split('.')[1], + container: file.name.split('.')[1], + imdbId: mockTorrent.imdbId, + imdbSeason: mockTorrent.season, + imdbEpisode: mockTorrent.episode, + kitsuId: mockTorrent.kitsuId, + kitsuEpisode: mockTorrent.episode, + })), + subtitles: mockFiles.filter(file => file.name.endsWith('.srt')).map(file => ({ + fileIndex: file.fileIndex, + infoHash: mockTorrent.infoHash, + path: file.path, + title: file.name, + fileId: file.fileIndex, + })), + }); + + expect(torrentStream).toHaveBeenCalledWith(expect.any(String), expect.any(Object)); + expect(mockLoggingService.debug).toHaveBeenCalledWith(`Adding torrent with infoHash ${mockTorrent.infoHash} to torrent engine...`); + }); +}); \ No newline at end of file diff --git a/src/node/consumer/test/services/torrent_entries_service.test.ts b/src/node/consumer/test/services/torrent_entries_service.test.ts new file mode 100644 index 0000000..48dca8b --- /dev/null +++ b/src/node/consumer/test/services/torrent_entries_service.test.ts @@ -0,0 +1,360 @@ +import "reflect-metadata"; // required +import {TorrentType} from "@enums/torrent_types"; +import {ILoggingService} from "@interfaces/logging_service"; +import {IMetadataService} from "@interfaces/metadata_service"; +import {IParsedTorrent} from "@interfaces/parsed_torrent"; +import {ITorrentFileCollection} from "@interfaces/torrent_file_collection"; +import {ITorrentFileService} from "@interfaces/torrent_file_service"; +import {ITorrentSubtitleService} from "@interfaces/torrent_subtitle_service"; +import {IDatabaseRepository} from "@repository/interfaces/database_repository"; +import {IFileAttributes} from "@repository/interfaces/file_attributes"; +import {ITorrentCreationAttributes} from "@repository/interfaces/torrent_attributes"; +import {Torrent} from "@repository/models/torrent"; +import {TorrentEntriesService} from "@services/torrent_entries_service"; +import {IocTypes} from "@setup/ioc_types"; +import {Container} from "inversify"; + +jest.mock('@services/logging_service', () => { + return { + error: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + warn: jest.fn(), + } +}) + +jest.mock('@services/torrent_file_service', () => { + return { + parseTorrentFiles: jest.fn().mockResolvedValue(undefined), + isPackTorrent: jest.fn().mockResolvedValue(undefined), + } +}) + +jest.mock('@services/metadata_service', () => { + return { + getImdbId: jest.fn().mockResolvedValue(undefined), + getKitsuId: jest.fn().mockResolvedValue(undefined), + } +}) + +jest.mock('@services/torrent_subtitle_service', () => { + return { + assignSubtitles: jest.fn().mockResolvedValue(undefined), + } +}) + +jest.mock('@repository/database_repository', () => { + return { + createTorrent: jest.fn().mockResolvedValue(undefined), + createFile: jest.fn().mockResolvedValue(undefined), + createSkipTorrent: jest.fn().mockResolvedValue(undefined), + getSkipTorrent: jest.fn().mockResolvedValue(undefined), + getTorrent: jest.fn().mockResolvedValue(undefined), + setTorrentSeeders: jest.fn().mockResolvedValue(undefined), + getFiles: jest.fn().mockResolvedValue(undefined), + } +}) + +describe('TorrentEntriesService Tests', () => { + let torrentEntriesService: TorrentEntriesService, + mockLoggingService: ILoggingService, + mockFileService: ITorrentFileService, + mockMetadataService: IMetadataService, + mockSubtitleService: ITorrentSubtitleService, + mockDatabaseRepository: IDatabaseRepository; + + beforeEach(() => { + jest.clearAllMocks(); + + mockFileService = jest.requireMock('@services/torrent_file_service'); + mockMetadataService = jest.requireMock('@services/metadata_service'); + mockSubtitleService = jest.requireMock('@services/torrent_subtitle_service'); + mockLoggingService = jest.requireMock('@services/logging_service'); + mockDatabaseRepository = jest.requireMock('@repository/database_repository'); + + const container = new Container(); + container.bind(TorrentEntriesService).toSelf(); + container.bind(IocTypes.ILoggingService).toConstantValue(mockLoggingService); + container.bind(IocTypes.ITorrentFileService).toConstantValue(mockFileService); + container.bind(IocTypes.ITorrentSubtitleService).toConstantValue(mockSubtitleService); + container.bind(IocTypes.IDatabaseRepository).toConstantValue(mockDatabaseRepository); + container.bind(IocTypes.IMetadataService).toConstantValue(mockMetadataService); + torrentEntriesService = container.get(TorrentEntriesService); + }); + + it('should create a torrent entry', async () => { + const torrent: IParsedTorrent = { + title: 'Test title', + provider: 'Test provider', + infoHash: 'Test infoHash', + type: TorrentType.Movie, + }; + + const fileCollection: ITorrentFileCollection = { + videos: [{ + fileIndex: 0, + title: 'Test video', + size: 123456, + imdbId: 'tt1234567', + }], + contents: [], + subtitles: [], + }; + + const fileCollectionWithSubtitles: ITorrentFileCollection = { + ...fileCollection, + subtitles: [{ + fileId: 0, + title: 'Test subtitle', + fileIndex: 0, + path: 'Test path', + infoHash: 'Test infoHash', + }], + }; + + (mockMetadataService.getImdbId as jest.Mock).mockResolvedValue('tt1234567'); + (mockFileService.parseTorrentFiles as jest.Mock).mockResolvedValue(fileCollection); + (mockSubtitleService.assignSubtitles as jest.Mock).mockResolvedValue(fileCollectionWithSubtitles); + (mockDatabaseRepository.createTorrent as jest.Mock).mockResolvedValue(torrent); + + await torrentEntriesService.createTorrentEntry(torrent); + + expect(mockMetadataService.getImdbId).toHaveBeenCalledWith({ + title: 'Test title', + year: undefined, + type: TorrentType.Movie + }); + expect(mockFileService.parseTorrentFiles).toHaveBeenCalledWith(torrent); + expect(mockFileService.parseTorrentFiles).toHaveReturnedWith(Promise.resolve(fileCollection)); + expect(mockSubtitleService.assignSubtitles).toHaveBeenCalledWith(fileCollection); + expect(mockSubtitleService.assignSubtitles).toHaveReturnedWith(Promise.resolve(fileCollectionWithSubtitles)); + expect(mockDatabaseRepository.createTorrent).toHaveBeenCalledWith(expect.objectContaining(torrent)); + }); + + it('should assign imdbId correctly', async () => { + const torrent: IParsedTorrent = { + title: 'Test title', + provider: 'Test provider', + infoHash: 'Test infoHash', + type: TorrentType.Movie, + }; + + const fileCollection: ITorrentFileCollection = { + videos: [{ + fileIndex: 0, + title: 'Test video', + size: 123456, + imdbId: 'tt1234567', + }], + contents: [], + subtitles: [], + }; + + const fileCollectionWithSubtitles: ITorrentFileCollection = { + ...fileCollection, + subtitles: [{ + fileId: 0, + title: 'Test subtitle', + fileIndex: 0, + path: 'Test path', + infoHash: 'Test infoHash', + }], + }; + + (mockMetadataService.getImdbId as jest.Mock).mockResolvedValue('tt1234567'); + (mockFileService.parseTorrentFiles as jest.Mock).mockResolvedValue(fileCollection); + (mockSubtitleService.assignSubtitles as jest.Mock).mockResolvedValue(fileCollectionWithSubtitles); + (mockDatabaseRepository.createTorrent as jest.Mock).mockResolvedValue(torrent); + + await torrentEntriesService.createTorrentEntry(torrent); + + expect(torrent.imdbId).toEqual('tt1234567'); + expect(torrent.kitsuId).toEqual(undefined); + }); + + it('should assign kitsuId correctly', async () => { + const torrent: IParsedTorrent = { + title: 'Test title', + provider: 'Test provider', + infoHash: 'Test infoHash', + type: TorrentType.Anime, + }; + + const fileCollection: ITorrentFileCollection = { + videos: [{ + fileIndex: 0, + title: 'Test video', + size: 123456, + kitsuId: 11 + }], + contents: [], + subtitles: [], + }; + + const fileCollectionWithSubtitles: ITorrentFileCollection = { + ...fileCollection, + subtitles: [{ + fileId: 0, + title: 'Test subtitle', + fileIndex: 0, + path: 'Test path', + infoHash: 'Test infoHash', + }], + }; + + (mockMetadataService.getKitsuId as jest.Mock).mockResolvedValue(11); + (mockFileService.parseTorrentFiles as jest.Mock).mockResolvedValue(fileCollection); + (mockSubtitleService.assignSubtitles as jest.Mock).mockResolvedValue(fileCollectionWithSubtitles); + (mockDatabaseRepository.createTorrent as jest.Mock).mockResolvedValue(torrent); + + await torrentEntriesService.createTorrentEntry(torrent); + + expect(torrent.imdbId).toEqual(undefined); + expect(torrent.kitsuId).toEqual(11); + }); + + it('should create a skip torrent entry', async () => { + const torrent: ITorrentCreationAttributes = { + infoHash: 'Test infoHash', + provider: 'Test provider', + title: 'Test title', + type: TorrentType.Movie, + }; + + (mockDatabaseRepository.createSkipTorrent as jest.Mock).mockResolvedValue([torrent, null]); + + const result = await torrentEntriesService.createSkipTorrentEntry(torrent); + + expect(mockDatabaseRepository.createSkipTorrent).toHaveBeenCalledWith(torrent); + expect(result).toEqual([torrent, null]); + }); + + it('should get stored torrent entry', async () => { + const torrent = { + infoHash: 'Test infoHash', + provider: 'Test provider', + title: 'Test title', + type: TorrentType.Movie, + dataValues: { + infoHash: 'Test infoHash', + provider: 'Test provider', + title: 'Test title', + type: TorrentType.Movie, + } + } as Torrent; + + (mockDatabaseRepository.getSkipTorrent as jest.Mock).mockRejectedValue(undefined); + (mockDatabaseRepository.getTorrent as jest.Mock).mockResolvedValue(torrent); + + const result = await torrentEntriesService.getStoredTorrentEntry(torrent); + + expect(mockDatabaseRepository.getSkipTorrent).toHaveBeenCalledWith(torrent.infoHash); + expect(mockDatabaseRepository.getTorrent).toHaveBeenCalledWith(torrent.dataValues); + expect(result).toEqual(torrent); + }); + + it('should check and update torrent', async () => { + const torrent: IParsedTorrent = { + title: 'Test title', + provider: 'Test provider', + infoHash: 'Test infoHash', + type: TorrentType.Movie, + seeders: 1, + }; + + const files: IFileAttributes[] = [{ + infoHash: 'Test infoHash', + fileIndex: 0, + title: 'Test title', + path: 'Test path', + size: 123456, + }, { + infoHash: 'Test infoHash 2', + fileIndex: 1, + title: 'Test title 2', + path: 'Test path 2', + size: 234567, + }]; + + const torrentInstance = { + ...torrent, + dataValues: {...torrent}, + save: jest.fn().mockResolvedValue(torrent), + }; + + const filesInstance = { + ...files, + dataValues: {...files}, + save: jest.fn().mockResolvedValue(files), + }; + + const seedersResponse = [1]; + + (mockDatabaseRepository.getTorrent as jest.Mock).mockResolvedValue(torrentInstance); + + (mockDatabaseRepository.setTorrentSeeders as jest.Mock).mockResolvedValue(seedersResponse); + (mockDatabaseRepository.getFiles as jest.Mock).mockResolvedValue(filesInstance) + + const result = await torrentEntriesService.checkAndUpdateTorrent(torrent); + + expect(mockDatabaseRepository.getTorrent).toHaveBeenCalledWith({ + infoHash: torrent.infoHash, + provider: torrent.provider + }); + + expect(mockDatabaseRepository.getFiles).toHaveBeenCalledWith(torrent.infoHash); + expect(mockDatabaseRepository.setTorrentSeeders).toHaveBeenCalledWith(torrentInstance.dataValues, 1); + expect(result).toEqual(true); + }); + + it('should create torrent contents', async () => { + const torrent = { + infoHash: 'Test infoHash', + provider: 'Test provider', + title: 'Test title', + type: TorrentType.Movie, + dataValues: { + infoHash: 'Test infoHash', + provider: 'Test provider', + title: 'Test title', + type: TorrentType.Movie, + } + } as Torrent; + + const fileCollection: ITorrentFileCollection = { + videos: [{ + id: 1, + title: 'Test video', + size: 123456, + imdbId: 'tt1234567', + infoHash: 'Test infoHash', + }], + contents: [], + subtitles: [], + }; + + const fileCollectionWithContents: ITorrentFileCollection = { + ...fileCollection, + contents: [{ + size: 123456, + fileIndex: 0, + path: 'Test path', + infoHash: 'Test infoHash', + }], + }; + + (mockDatabaseRepository.getFiles as jest.Mock).mockResolvedValue(fileCollection.videos); + (mockFileService.parseTorrentFiles as jest.Mock).mockResolvedValue(fileCollectionWithContents); + (mockSubtitleService.assignSubtitles as jest.Mock).mockResolvedValue(fileCollectionWithContents); + (mockDatabaseRepository.createFile as jest.Mock).mockResolvedValue(Promise.resolve()); + (mockDatabaseRepository.createTorrent as jest.Mock).mockResolvedValue(torrent); + + await torrentEntriesService.createTorrentContents(torrent); + + const newTorrentFiles = await (mockDatabaseRepository.createTorrent as jest.Mock).mock.calls[0][0].files; + + newTorrentFiles.forEach(file => { + expect(mockDatabaseRepository.createFile).toHaveBeenCalledWith(file); + }); + }); +}); \ No newline at end of file diff --git a/src/node/consumer/test/services/torrent_file_service.test.ts b/src/node/consumer/test/services/torrent_file_service.test.ts new file mode 100644 index 0000000..f30ae00 --- /dev/null +++ b/src/node/consumer/test/services/torrent_file_service.test.ts @@ -0,0 +1,225 @@ +import "reflect-metadata"; // required +import {TorrentType} from "@enums/torrent_types"; +import {ILoggingService} from "@interfaces/logging_service"; +import {IMetadataService} from "@interfaces/metadata_service"; +import {IParsedTorrent} from "@interfaces/parsed_torrent"; +import {ITorrentDownloadService} from "@interfaces/torrent_download_service"; +import {TorrentFileService} from "@services/torrent_file_service"; +import {IocTypes} from "@setup/ioc_types"; +import {Container} from "inversify"; + +jest.mock('@services/logging_service', () => { + return { + error: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + } +}) + +jest.mock('@services/torrent_download_service', () => { + return { + getTorrentFiles: jest.fn().mockImplementation(() => Promise.resolve({ + contents: [], + videos: [], + subtitles: [], + })), + }; +}); + +jest.mock('@services/metadata_service', () => { + return { + getMetadata: jest.fn().mockImplementation(() => Promise.resolve(undefined)), + } +}); + +describe('TorrentFileService tests', () => { + let torrentFileService: TorrentFileService, + mockLoggingService: ILoggingService, + mockDownloadService: ITorrentDownloadService, + mockMetadataService: IMetadataService; + + beforeEach(() => { + jest.clearAllMocks(); + + mockLoggingService = jest.requireMock('@services/logging_service'); + mockDownloadService = jest.requireMock('@services/torrent_download_service'); + mockMetadataService = jest.requireMock('@services/metadata_service'); + + const container = new Container(); + container.bind(TorrentFileService).toSelf(); + container.bind(IocTypes.ILoggingService).toConstantValue(mockLoggingService); + container.bind(IocTypes.IMetadataService).toConstantValue(mockMetadataService); + container.bind(IocTypes.ITorrentDownloadService).toConstantValue(mockDownloadService); + torrentFileService = container.get(TorrentFileService); + }); + + + it('should parse torrent files correctly', () => { + const mockTorrent: IParsedTorrent = { + title: 'test', + kitsuId: 123, + type: TorrentType.Movie, + infoHash: '1234567890abcdef', + }; + + const result = torrentFileService.parseTorrentFiles(mockTorrent); + + expect(result).toBeInstanceOf(Promise); + + result.then(res => { + expect(res).toHaveProperty('videos'); + expect(res).toHaveProperty('subtitles'); + expect(res).toHaveProperty('contents'); + }); + }); + + it('should reject when torrent has no title', async () => { + const mockTorrent: IParsedTorrent = { + kitsuId: 123, + type: TorrentType.Movie, + infoHash: '1234567890abcdef', + }; + + await expect(torrentFileService.parseTorrentFiles(mockTorrent)).rejects.toThrow('Torrent title is missing'); + }); + + it('should handle torrent with no kitsuId', async () => { + const mockTorrent: IParsedTorrent = { + title: 'test', + type: TorrentType.Movie, + infoHash: '1234567890abcdef', + }; + + const result = await torrentFileService.parseTorrentFiles(mockTorrent); + + expect(result).toHaveProperty('videos'); + expect(result).toHaveProperty('subtitles'); + expect(result).toHaveProperty('contents'); + }); + + it('should handle torrent of type Series', async () => { + const mockTorrent: IParsedTorrent = { + title: 'test', + kitsuId: 123, + type: TorrentType.Series, + infoHash: '1234567890abcdef', + }; + + const result = await torrentFileService.parseTorrentFiles(mockTorrent); + + expect(result).toHaveProperty('videos'); + expect(result).toHaveProperty('subtitles'); + expect(result).toHaveProperty('contents'); + }); + + it('should reject when torrent has no infoHash', async () => { + const mockTorrent = { + title: 'test', + kitsuId: 123, + type: TorrentType.Movie, + } as IParsedTorrent; + + await expect(torrentFileService.parseTorrentFiles(mockTorrent)).rejects.toThrow('Torrent infoHash is missing'); + }); + + it('should handle torrent with no type', async () => { + const mockTorrent = { + title: 'test', + kitsuId: 123, + infoHash: '1234567890abcdef', + } as IParsedTorrent; + + const result = await torrentFileService.parseTorrentFiles(mockTorrent); + + expect(result).toHaveProperty('videos'); + expect(result).toHaveProperty('subtitles'); + expect(result).toHaveProperty('contents'); + }); + + it('should handle torrent of type Anime', async () => { + const mockTorrent: IParsedTorrent = { + title: 'test', + kitsuId: 123, + type: TorrentType.Anime, + infoHash: '1234567890abcdef', + }; + + const result = await torrentFileService.parseTorrentFiles(mockTorrent); + + expect(result).toHaveProperty('videos'); + expect(result).toHaveProperty('subtitles'); + expect(result).toHaveProperty('contents'); + }); + + it('should handle torrent with a single video', async () => { + const mockTorrent: IParsedTorrent = { + title: 'test', + kitsuId: 123, + type: TorrentType.Movie, + infoHash: '1234567890abcdef', + }; + + (mockDownloadService.getTorrentFiles as jest.Mock).mockImplementation(() => Promise.resolve({ + contents: [], + videos: [{ + title: 'video1', + path: 'path/to/video1', + size: 123456789, + fileIndex: 0, + }], + subtitles: [], + })); + + const result = await torrentFileService.parseTorrentFiles(mockTorrent); + + expect(result).toHaveProperty('videos'); + expect(result.videos).toHaveLength(1); + expect(result.videos[0]).toHaveProperty('title', 'video1'); + expect(result).toHaveProperty('subtitles'); + expect(result).toHaveProperty('contents'); + }); + + it('should handle torrent with multiple videos', async () => { + const mockTorrent: IParsedTorrent = { + title: 'test', + kitsuId: 123, + type: TorrentType.Movie, + infoHash: '1234567890abcdef', + }; + + (mockDownloadService.getTorrentFiles as jest.Mock).mockImplementation(() => Promise.resolve({ + contents: [], + videos: [ + { + title: 'video1', + path: 'path/to/video1', + size: 123456789, + fileIndex: 0, + }, + { + title: 'video2', + path: 'path/to/video2', + size: 123456789, + fileIndex: 1, + }, + { + title: 'video3', + path: 'path/to/video3', + size: 123456789, + fileIndex: 2, + } + ], + subtitles: [], + })); + + const result = await torrentFileService.parseTorrentFiles(mockTorrent); + + expect(result).toHaveProperty('videos'); + expect(result.videos).toHaveLength(3); + expect(result.videos[0]).toHaveProperty('title', 'video1'); + expect(result.videos[1]).toHaveProperty('title', 'video2'); + expect(result.videos[2]).toHaveProperty('title', 'video3'); + expect(result).toHaveProperty('subtitles'); + expect(result).toHaveProperty('contents'); + }); +}); \ No newline at end of file diff --git a/src/node/consumer/test/services/torrent_subtitle_service.test.ts b/src/node/consumer/test/services/torrent_subtitle_service.test.ts new file mode 100644 index 0000000..71b6dd9 --- /dev/null +++ b/src/node/consumer/test/services/torrent_subtitle_service.test.ts @@ -0,0 +1,102 @@ +import "reflect-metadata"; // required +import {ITorrentFileCollection} from "@interfaces/torrent_file_collection"; +import {TorrentSubtitleService} from "@services/torrent_subtitle_service"; + +describe('TorrentSubtitleService tests', () => { + let torrentSubtitleService: TorrentSubtitleService; + + beforeEach(() => { + jest.clearAllMocks(); + torrentSubtitleService = new TorrentSubtitleService(); + }); + + it('should assign subtitles to a single video', () => { + const fileCollection: ITorrentFileCollection = { + videos: [{title: 'Test video', size: 123456, imdbId: 'tt1234567', infoHash: 'Test infoHash'}], + contents: [], + subtitles: [{title: 'Test subtitle', fileIndex: 0, path: 'Test path', infoHash: 'Test infoHash'}], + }; + + const result = torrentSubtitleService.assignSubtitles(fileCollection); + + expect(result.videos[0].subtitles).toEqual(fileCollection.subtitles); + expect(result.subtitles).toEqual([]); + }); + + it('should not assign subtitles if there are no videos', () => { + const fileCollection: ITorrentFileCollection = { + videos: [], + contents: [], + subtitles: [{title: 'Test subtitle', fileIndex: 0, path: 'Test path', infoHash: 'Test infoHash'}], + }; + + const result = torrentSubtitleService.assignSubtitles(fileCollection); + + expect(result).toEqual(fileCollection); + }); + + it('should not assign subtitles if there are no subtitles', () => { + const fileCollection: ITorrentFileCollection = { + videos: [{title: 'Test video', size: 123456, imdbId: 'tt1234567', infoHash: 'Test infoHash'}], + contents: [], + subtitles: [], + }; + + const result = torrentSubtitleService.assignSubtitles(fileCollection); + + expect(result).toEqual(fileCollection); + }); + + it('should assign subtitles to multiple videos', () => { + const fileCollection: ITorrentFileCollection = { + videos: [ + {title: 'Test video S01E01', size: 123456, imdbId: 'tt1234567', infoHash: 'Test infoHash'}, + {title: 'Test video S01E02', size: 123456, imdbId: 'tt1234567', infoHash: 'Test infoHash'} + ], + contents: [], + subtitles: [ + {title: 'Test subtitle S01E01', fileIndex: 0, path: 'Test path', infoHash: 'Test infoHash'}, + {title: 'Test subtitle S01E02', fileIndex: 1, path: 'Test path', infoHash: 'Test infoHash'} + ], + }; + + const result = torrentSubtitleService.assignSubtitles(fileCollection); + + expect(result.videos[0].subtitles).toEqual([fileCollection.subtitles[0]]); + expect(result.videos[1].subtitles).toEqual([fileCollection.subtitles[1]]); + expect(result.subtitles).toEqual([]); + }); + + it('should not assign subtitles if there are no matching videos', () => { + const fileCollection: ITorrentFileCollection = { + videos: [{title: 'Test video', size: 123456, imdbId: 'tt1234567', infoHash: 'Test infoHash'}], + contents: [], + subtitles: [{title: 'Non-matching subtitle', fileIndex: 0, path: 'Test path', infoHash: 'Non-matching infoHash'}], + }; + + const result = torrentSubtitleService.assignSubtitles(fileCollection); + + expect(result.videos[0].subtitles).toEqual([]); + expect(result.subtitles).toEqual([fileCollection.subtitles[0]]); + }); + + it('should assign subtitles to the most probable videos based on filename, title, season, and episode', () => { + const fileCollection: ITorrentFileCollection = { + videos: [ + {title: 'Test video S01E01', size: 123456, imdbId: 'tt1234567', infoHash: 'Test infoHash'}, + {title: 'Test video S01E02', size: 123456, imdbId: 'tt1234567', infoHash: 'Test infoHash'} + ], + contents: [], + subtitles: [ + {title: 'Test subtitle S01E01', fileIndex: 0, path: 'Test path', infoHash: 'Test infoHash'}, + {title: 'Test subtitle S01E02', fileIndex: 1, path: 'Test path', infoHash: 'Test infoHash'} + ], + }; + + const result = torrentSubtitleService.assignSubtitles(fileCollection); + + expect(result.videos[0].subtitles).toEqual([fileCollection.subtitles[0]]); + expect(result.videos[1].subtitles).toEqual([fileCollection.subtitles[1]]); + expect(result.subtitles).toEqual([]); + }); +}); \ No newline at end of file diff --git a/src/node/consumer/test/services/tracker_service.test.ts b/src/node/consumer/test/services/tracker_service.test.ts new file mode 100644 index 0000000..4427817 --- /dev/null +++ b/src/node/consumer/test/services/tracker_service.test.ts @@ -0,0 +1,62 @@ +import "reflect-metadata"; // required +import {ICacheService} from '@interfaces/cache_service'; +import {ILoggingService} from '@interfaces/logging_service'; +import {TrackerService} from '@services/tracker_service'; +import {IocTypes} from "@setup/ioc_types"; +import {Container} from "inversify"; +import {setupServer} from 'msw/node'; +import * as responses from "../mock-responses/trackers_mock_responses"; + +const server = setupServer(responses.trackerTestResponse); + +jest.mock('@services/logging_service', () => { + return { + error: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + } +}) + +jest.mock('@services/cache_service', () => { + return { + cacheTrackers: jest.fn().mockImplementation((fn) => fn()), + } +}) + +beforeAll(() => server.listen()) +beforeEach(() => { + jest.clearAllMocks(); + jest.spyOn(Date, 'now').mockImplementation(() => 1234567890); +}) +afterEach(() => () => { + server.resetHandlers() + jest.spyOn(Date, 'now').mockRestore(); +}) +afterAll(() => server.close()) + +describe('TrackerService', () => { + let trackerService: TrackerService, + mockCacheService: ICacheService, + mockLoggingService: ILoggingService; + + beforeEach(() => { + mockCacheService = jest.requireMock('@services/cache_service'); + mockLoggingService = jest.requireMock('@services/logging_service'); + + const container = new Container(); + container.bind(TrackerService).toSelf(); + container.bind(IocTypes.ILoggingService).toConstantValue(mockLoggingService); + container.bind(IocTypes.ICacheService).toConstantValue(mockCacheService); + trackerService = container.get(TrackerService); + }); + + it('should get trackers', async () => { + const mockTrackers = ['http://tracker1.com', 'http://tracker2.com']; + + const result = await trackerService.getTrackers(); + + expect(result).toEqual(mockTrackers); + expect(mockLoggingService.info).toHaveBeenCalledWith(`Trackers updated at 1234567890: ${mockTrackers.length} trackers`); + + }); +}); \ No newline at end of file diff --git a/src/node/consumer/tsconfig.json b/src/node/consumer/tsconfig.json new file mode 100644 index 0000000..f1b203c --- /dev/null +++ b/src/node/consumer/tsconfig.json @@ -0,0 +1,64 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "target": "ESNext", + "lib": [ + "ESNext" + ], + "typeRoots": [ + "node_modules/@types" + ], + "allowSyntheticDefaultImports": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", + "module": "ESNext", + "pretty": true, + "sourceMap": true, + "declaration": true, + "outDir": "dist", + "allowJs": false, + "noEmit": false, + "esModuleInterop": true, + "resolveJsonModule": true, + "importHelpers": true, + "baseUrl": "src", + "paths": { + "@/*": [ + "*" + ], + "@enums/*": [ + "lib/enums/*" + ], + "@repository/*": [ + "lib/repository/*" + ], + "@interfaces/*": [ + "lib/interfaces/*" + ], + "@models/*": [ + "lib/models/*" + ], + "@services/*": [ + "lib/services/*" + ], + "@helpers/*": [ + "lib/helpers/*" + ], + "@jobs/*": [ + "lib/jobs/*" + ], + "@setup/*": [ + "setup/*" + ] + } + }, + "include": [ + "src", + "test" + ], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file